Connect · Source and review

GitHub & GitHub Enterprise

Pull requests, reviews, comments, checks, labels, assignees, issues and projects on GitHub and GitHub Enterprise Server

Pull requests, reviews, comments, checks, labels, assignees, issues and Projects on GitHub.com and GitHub Enterprise Server, through the REST API and, for review threads, PR status, auto-merge, the merge queue, drafts and Projects, the GraphQL API. The two differ only in host, so they’re one area with a configurable baseUrl. Verification level: unit.

Supported versions: The oldest GitHub Enterprise Server version toil supports hasn’t been established. toil pins REST API version 2022-11-28 and uses GraphQL for review threads, PR status, auto-merge, the merge queue, drafts and Projects. GitHub.com is always current; no Enterprise Server release has been verified yet. The auto-merge and merge-queue commands need a release that has those features, and so do issue types, sub-issues and Projects (v2). A release without issue types just leaves type off each issue; one without sub-issues (issue get --sub-issues) or Projects (project …) gets UNSUPPORTED, saying so.

Credential

A fine-grained personal access token: Settings → Developer settings → Personal access tokens → Fine-grained tokens, with access to the repositories you work on (pull requests, issues, contents and checks, read or write as needed). toil sends it as Authorization: Bearer <token>, with Accept: application/vnd.github+json and X-GitHub-Api-Version: 2022-11-28. There is no OAuth app, username, password or browser login.

What each group of commands needs from the token:

CommandsFine-grained tokenClassic token
issue list, issue search, issue get, issue historyIssues: read, on the repositoryrepo (public_repo for public repositories only)
repo fileContents: read, on the repositoryrepo (public_repo for public repositories only)
project list, project fields, project itemsProjects: read, under the organization’s permissions. A fine-grained token can’t read a user’s own projectsread:project (plus repo to see items from private repositories)
Pull request, review, comment and check commandsPull requests, contents and checks, read or write as neededrepo

A token without the Projects permission gets AUTH from the project commands, naming the scope.

Configuration

KeyEnv varRequiredMeaning
baseUrlTOIL_GITHUB_BASE_URL, then GITHUB_API_URLyesThe REST API root: https://api.github.com, or https://ghe.imagile.dev/api/v3 for Enterprise Server
tokenTOIL_GITHUB_TOKEN, then GITHUB_TOKENyesFine-grained personal access token
ownerTOIL_GITHUB_OWNERnoDefault owner (user or org)
repoTOIL_GITHUB_REPOnoDefault repository name
targetBranchTOIL_GITHUB_TARGET_BRANCHnoDefault base branch for pr create (main when unset)
writesTOIL_GITHUB_WRITESnotrue lets write commands run (with --allow-write)

CI fallbacks: in GitHub Actions, the default connection takes its token from GITHUB_TOKEN when TOIL_GITHUB_TOKEN isn’t set, and its base URL from GITHUB_API_URL when TOIL_GITHUB_BASE_URL isn’t set. Each sits directly below its TOIL_GITHUB_* variable and above the config file.

The GraphQL endpoint is derived from baseUrl: a trailing /v3 is dropped and /graphql appended, so https://api.github.com uses https://api.github.com/graphql and https://ghe.imagile.dev/api/v3 uses https://ghe.imagile.dev/api/graphql.

Environment variables (CI, or a one-off shell):

export TOIL_GITHUB_BASE_URL=https://ghe.imagile.dev/api/v3
export TOIL_GITHUB_TOKEN=<your fine-grained token>

Or ~/.toil/config.json, with owner, repo and targetBranch usually set once under defaults.github:

{
  "version": 2,
  "connections": {
    "corp-github": { "area": "github", "baseUrl": "https://ghe.imagile.dev/api/v3" }
  },
  "defaults": { "github": { "connection": "corp-github", "owner": "imagile", "repo": "toil-probe" } }
}

The token never goes in this file; a plaintext one there is refused with CONFIG_INVALID. Run toil connections add corp-github --area github (or toil connections login corp-github for an existing connection) to keep it in the OS credential store, or set TOIL_GITHUB_TOKEN.

Owner and repository

Every command except repo create needs an owner and a repository, which come from, in order:

  1. --owner and --repo, before or after the command (toil github --owner imagile --repo toil-probe pr get 7); on pr create the ones after the command win
  2. the first of the working folder’s remotes whose host is this connection’s host, of any name, trying origin first (so a fork’s upstream counts) (api.github.com counts as github.com). git@host:o/r, ssh://git@host[:port]/o/r and https://host[:port]/o/r remotes are read, each with or without .git; an HTTPS remote with a user name in it isn’t
  3. the connection’s owner and repo (usually defaults.github)

With neither found, the command fails with “Could not determine GitHub owner/repo”. pr resolve needs them too, though it acts by thread id alone. repo create reads only an explicit --owner, always as an organization (POST /orgs/<owner>/repos); without it the repository is created under the token’s user.

Commands

Every command is toil github <resource> <action> [ids...], and its MCP tool is the path with underscores (github_pr_get, github_commit_checks). Numbers (<number>, <comment-id>, --line) are read as whole numbers from the start of the text, so 12abc is 12. Write commands need writes on the connection and --allow-write. The deletes (pr delete-comment, pr delete-review-comment, issue unlabel, pr remove-reviewers, issue unassign) run on the CLI only and are never MCP tools. Owner, repo, labels and refs go into request paths as typed; a value that would make a . or .. path segment is refused with INVALID_INPUT.

  • Repositories: repo create (--name, --description, --private, --auto-init), and repo file <path> (--ref), one file through the contents API: GitHub’s record plus text, the file decoded as UTF-8 (null, with a GITHUB_FILE_NOT_INLINED warning, over 1 MB). A folder is refused.
  • Issues: each issue is GitHub’s own, with the issue type in type, sub-issue counts in sub_issues_summary and the parent in parent_issue_url, where the server has them.
    • issue create (--title, --body or --body-file <path> with - for stdin, repeatable --label and --assignee).
    • issue list (--state open|closed|all, default open; repeatable --label, all of which must match; --assignee, --type with none or * too; --sort created|updated|comments, --direction asc|desc; --updated-since <iso>, GitHub’s since). The issues endpoint mixes pull requests in; toil leaves them out (pr list has them).
    • issue search --query <q> (GitHub search syntax; --sort, --order, --updated-since). toil adds is:issue, and updated:>=<iso> with --updated-since, but not --owner or --repo: scope the query with repo:, org: or user:. GitHub serves only the first 1,000 results of a search, so past that toil stops with a GITHUB_SEARCH_CAPPED warning; a search GitHub timed out part of gets GITHUB_SEARCH_INCOMPLETE.
    • issue get <number...>, up to 100 numbers. One number returns the issue itself. Several return { issues, errors }, read four at a time, where an issue GitHub can’t find or answers with an error goes into errors as { number, code, message }, with a GITHUB_ISSUES_FAILED warning; a bad token or a timeout still fails the call. --sub-issues adds sub_issues, each issue’s sub-issues, one more request per issue.
    • issue history <number>: the issue’s timeline, oldest first, as GitHub returns it: closed and reopened (with state_reason), labeled, assigned, issue_type_added and issue_type_changed, sub_issue_added, cross-referenced (the PRs that mention it), commented and the rest.
    • --updated-since reads a date the way --created-after does (a date alone is UTC midnight) and sends it as UTC to the second, 2025-01-31T00:00:00Z.
    • Labels and assignees, on an issue or a pull request by its number: issue label <number> (repeatable --label), issue unlabel <number> --label, issue assign <number> and issue unassign <number> (repeatable --assignee). pr label, pr unlabel, pr assign and pr unassign are the same commands.
  • Projects (v2): GitHub’s boards, read over GraphQL. They belong to an owner, so only --owner is read; <project> is the number in the project’s URL.
    • project list: the owner’s projects (id, number, title, url, closed, …).
    • project fields <project>: each field’s id, name and dataType, a single-select field’s options (Status), and an iteration field’s configuration with its iterations and completedIterations.
    • project items <project>: each item’s id, type (ISSUE, PULL_REQUEST, DRAFT_ISSUE), content (number, title, state, url and repository) and fieldValues, each with its field.name and value (text, number, date, a single-select name, or an iteration’s title and startDate). An item’s first 100 values are read, with a GITHUB_PROJECT_VALUES_TRUNCATED warning past that.
  • Pull requests (<number> is the pull request number): pr list (--state open|closed|all, default open; --head user:branch, --base; --author and --created-after/--created-before, ISO 8601, are filtered as each page comes in, the author case-insensitively; a date alone is UTC midnight, a date-time with no zone local time; --updated-since <iso> keeps pull requests updated at or after it, and asks GitHub for the most recently updated first, sort=updated&direction=desc, so reading stops after the page that reaches an older one), pr get <number> (--include reviews,checks,commits,files, any of them, adds included, an object holding only the lists asked for, each GitHub’s own records with every page read: reviews, checks (the check runs on the head commit, head.sha), commits and files; each list is one more request, more to page; GitHub serves at most 250 commits and 3000 files of a pull request, and a list that long gets a GITHUB_LIST_CAPPED warning; an unknown name is INVALID_INPUT), pr create (--title, --head, --base defaulting to targetBranch then main, --body/--body-file, --draft), pr update <number> (--title, --body, --base), pr merge <number> (--method merge|squash|rebase, default merge, always sent; --commit-title, --commit-message), pr close <number>, pr reopen <number>, pr draft <number>, pr ready <number>.
  • Merging: pr enable-auto-merge <number> and pr enqueue <number> (--method, --match-head-commit <sha>), pr disable-auto-merge <number>.
  • Comments: pr comments <number> and pr comment <number> --body (the general comments, which work on an issue’s number too; issue comments and issue comment are the same commands), pr review-comments <number>, pr comment-inline <number> (--commit, --file, --line, --body, --side LEFT|RIGHT, default RIGHT), pr reply <number> <comment-id> --body, pr delete-comment <comment-id>, pr delete-review-comment <comment-id>.
  • Diff and files: pr diff <number> returns { diff }, the unified diff as text; pr files <number>.
  • Reviews: pr reviews <number>, pr approve <number> (--body optional), pr request-changes <number> (--body required), pr reviewers <number>, pr threads <number> (thread ids for pr resolve; the first 100 threads with a GITHUB_REVIEW_THREADS_TRUNCATED warning past that, and the first 10 comments of each), pr resolve <thread-id>, pr add-reviewers <number> and pr remove-reviewers <number> (repeatable --reviewer and --team-reviewer, at least one).
  • Status: commit status <ref> (the combined status; GitHub’s first 30 statuses), commit checks <ref>, pr status <number> (review decision, mergeability, draft and auto-merge state, and the first 100 checks counted into checks.passed, failed, pending and other).

Lists page 100 at a time until a short page, and stop with an error after 1,000 pages. Every list (pr list, pr files, pr comments, pr review-comments, pr reviews, commit checks, issue list, issue search, issue history and the three project lists) reads every page by default. --limit <n> stops after n items and sets meta.page.nextCursor; pass it back as --cursor with the same --limit for the next n, until nextCursor is null. On pr list, --limit counts the pull requests that pass --author and the date filters, --updated-since included.

toil github issue list --state all --sort updated --direction asc --updated-since 2025-01-31T00:00:00Z --limit 100
toil github issue get 9 10 --sub-issues
toil github --owner imagile project items 3
toil github pr list --state all --author octo-dev
toil github pr list --state all --updated-since 2025-01-31T00:00:00Z --limit 50
toil github pr get 7 --include reviews,checks
toil github repo file .github/CODEOWNERS
toil github --owner imagile --repo toil-probe pr status 7
toil github pr create --title "Add the probe" --head feature --body-file pr.md --allow-write

Ticket the work

Before starting work no ticket covers, rank your open issues against it:

toil github issue search --query "repo:imagile/payments-web is:open assignee:@me" | toil util owi map | toil util owi similar --query "Card payments time out at checkout"

Then ask the person, as core.md, Ticket the work, says: attach the work to a match (nothing is written), create a sub-task under it, or create a new ticket. toil has no sub-issue command, so a sub-task is a new issue that names its parent in the body (Part of #12); a new ticket is toil github issue create --title "<text>" --allow-write, in the repository the dossier names. Both are writes, made only on the person’s yes.

Checking a dossier

check-dossier checks the call’s dossier: each owner it names (owner, per repo or not, and owners) is a user or organization, and each repository (repo) exists under its owner. It’s toil github check-dossier (--dossier <name|file>, or the dossier the folder resolves to), and it returns { dossier, connection, env, ok, checked, checks, unchecked }, one check per value with its key path. The CLI exits 1 when one is missing. A failure other than not-found (a bad token, an unreachable host) fails the command. Read only.

Settings at a glance

  • baseUrl required

    REST API root: https://api.github.com, or https://ghe.imagile.dev/api/v3 for Enterprise Server

    TOIL_GITHUB_BASE_URL orGITHUB_API_URL

  • token required secret

    Fine-grained personal access token

    TOIL_GITHUB_TOKEN orGITHUB_TOKEN

  • owner

    Default owner (user or org)

    TOIL_GITHUB_OWNER

  • repo

    Default repository name

    TOIL_GITHUB_REPO

  • targetBranch

    Default base branch for pr create (main when unset)

    TOIL_GITHUB_TARGET_BRANCH

Commands at a glance

  • toil github repo createwrite

    Create a new repository (personal or org)

    MCP github_repo_create--name <name>--description <desc>--private--auto-init--owner <owner>--repo <repo>--allow-write

  • toil github issue createwrite

    Create a GitHub issue

    MCP github_issue_create--title <title>--body <body>--body-file <path>--label <label>--assignee <login>--owner <owner>--repo <repo>--allow-write

  • toil github issue labelwritealso toil github pr label

    Add labels to an issue or pull request

    MCP github_issue_label<number>--label <label>--owner <owner>--repo <repo>--allow-write

  • toil github issue unlabelwriteCLI onlyalso toil github pr unlabel

    Remove a label from an issue or pull request

    <number>--label <label>--owner <owner>--repo <repo>--allow-write

  • toil github issue assignwritealso toil github pr assign

    Add assignees to an issue or pull request

    MCP github_issue_assign<number>--assignee <login>--owner <owner>--repo <repo>--allow-write

  • toil github issue unassignwriteCLI onlyalso toil github pr unassign

    Remove assignees from an issue or pull request

    <number>--assignee <login>--owner <owner>--repo <repo>--allow-write

  • toil github repo file

    Read one file from a repository

    MCP github_repo_file<path>--ref <ref>--owner <owner>--repo <repo>

  • toil github issue list

    List issues in a repository (pull requests left out)

    MCP github_issue_list--state <state>--label <label>--assignee <login>--type <type>--sort <field>--direction <dir>--updated-since <iso>--limit <n>--cursor <cursor>--owner <owner>--repo <repo>

  • toil github issue search

    Search issues with GitHub search syntax (is:issue is added)

    MCP github_issue_search--query <q>--sort <field>--order <order>--updated-since <iso>--limit <n>--cursor <cursor>--owner <owner>--repo <repo>

  • toil github issue get

    Get one or more issues by number (give several numbers to read several), with issue type and, on request, sub-issues

    MCP github_issue_get<number...>--sub-issues--owner <owner>--repo <repo>

  • toil github issue history

    List an issue's timeline: state changes, labels, assignments, issue types, sub-issues, cross-references and comments

    MCP github_issue_history<number>--limit <n>--cursor <cursor>--owner <owner>--repo <repo>

  • toil github project list

    List an owner's projects (v2)

    MCP github_project_list--limit <n>--cursor <cursor>--owner <owner>--repo <repo>

  • toil github project fields

    List a project's fields, with single-select options and iterations

    MCP github_project_fields<project>--limit <n>--cursor <cursor>--owner <owner>--repo <repo>

  • toil github project items

    List a project's items (issues, pull requests, drafts) with their field values

    MCP github_project_items<project>--limit <n>--cursor <cursor>--owner <owner>--repo <repo>

  • toil github pr list

    List pull requests

    MCP github_pr_list--state <state>--head <branch>--base <branch>--author <login>--created-after <date>--created-before <date>--updated-since <iso>--limit <n>--cursor <cursor>--owner <owner>--repo <repo>

  • toil github pr get

    Get a pull request by number, optionally with its reviews, checks, commits and files

    MCP github_pr_get<number>--include <list>--owner <owner>--repo <repo>

  • toil github pr createwrite

    Create a pull request

    MCP github_pr_create--title <title>--head <branch>--base <branch>--body <body>--body-file <path>--draft--owner <owner>--repo <repo>--owner <owner>--repo <repo>--allow-write

  • toil github pr updatewrite

    Update a pull request

    MCP github_pr_update<number>--title <title>--body <body>--base <branch>--owner <owner>--repo <repo>--allow-write

  • toil github pr mergewrite

    Merge a pull request (immediate merge — use pr enable-auto-merge for auto-merge)

    MCP github_pr_merge<number>--method <method>--commit-title <title>--commit-message <msg>--owner <owner>--repo <repo>--allow-write

  • toil github pr closewrite

    Close a pull request

    MCP github_pr_close<number>--owner <owner>--repo <repo>--allow-write

  • toil github pr reopenwrite

    Reopen a closed pull request

    MCP github_pr_reopen<number>--owner <owner>--repo <repo>--allow-write

  • toil github pr diff

    Get unified diff for a pull request

    MCP github_pr_diff<number>--owner <owner>--repo <repo>

  • toil github pr files

    List files changed in a pull request

    MCP github_pr_files<number>--limit <n>--cursor <cursor>--owner <owner>--repo <repo>

  • toil github pr enable-auto-mergewrite

    Enable auto-merge on a pull request (merges automatically when all requirements are met)

    MCP github_pr_enable_auto_merge<number>--method <method>--match-head-commit <sha>--owner <owner>--repo <repo>--allow-write

  • toil github pr disable-auto-mergewrite

    Disable auto-merge on a pull request

    MCP github_pr_disable_auto_merge<number>--owner <owner>--repo <repo>--allow-write

  • toil github pr enqueuewrite

    Add a pull request to the repository merge queue

    MCP github_pr_enqueue<number>--method <method>--match-head-commit <sha>--owner <owner>--repo <repo>--allow-write

  • toil github pr draftwrite

    Convert an open pull request to a draft

    MCP github_pr_draft<number>--owner <owner>--repo <repo>--allow-write

  • toil github pr readywrite

    Mark a draft pull request as ready for review

    MCP github_pr_ready<number>--owner <owner>--repo <repo>--allow-write

  • toil github pr status

    Aggregated PR status: review decision, checks, mergeability, draft state, and auto-merge

    MCP github_pr_status<number>--owner <owner>--repo <repo>

  • toil github pr commentsalso toil github issue comments

    List general comments on a pull request (or an issue, by its number)

    MCP github_pr_comments<number>--limit <n>--cursor <cursor>--owner <owner>--repo <repo>

  • toil github pr commentwritealso toil github issue comment

    Add a general comment to a pull request (or an issue, by its number)

    MCP github_pr_comment<number>--body <text>--owner <owner>--repo <repo>--allow-write

  • toil github pr review-comments

    List inline review comments on a pull request

    MCP github_pr_review_comments<number>--limit <n>--cursor <cursor>--owner <owner>--repo <repo>

  • toil github pr comment-inlinewrite

    Add an inline review comment to a file in a pull request

    MCP github_pr_comment_inline<number>--commit <sha>--file <path>--line <n>--body <text>--side <side>--owner <owner>--repo <repo>--allow-write

  • toil github pr replywrite

    Reply to a review comment on a pull request

    MCP github_pr_reply<number><comment-id>--body <text>--owner <owner>--repo <repo>--allow-write

  • toil github pr delete-commentwriteCLI only

    Delete a general issue comment

    <comment-id>--owner <owner>--repo <repo>--allow-write

  • toil github pr delete-review-commentwriteCLI only

    Delete an inline review comment

    <comment-id>--owner <owner>--repo <repo>--allow-write

  • toil github pr reviews

    List reviews on a pull request

    MCP github_pr_reviews<number>--limit <n>--cursor <cursor>--owner <owner>--repo <repo>

  • toil github pr approvewrite

    Approve a pull request

    MCP github_pr_approve<number>--body <text>--owner <owner>--repo <repo>--allow-write

  • toil github pr request-changeswrite

    Request changes on a pull request

    MCP github_pr_request_changes<number>--body <text>--owner <owner>--repo <repo>--allow-write

  • toil github pr reviewers

    List requested reviewers for a pull request

    MCP github_pr_reviewers<number>--owner <owner>--repo <repo>

  • toil github pr threads

    List review threads on a pull request (includes thread node IDs for pr resolve)

    MCP github_pr_threads<number>--owner <owner>--repo <repo>

  • toil github pr resolvewrite

    Mark a review thread as resolved (use pr threads to get the thread id)

    MCP github_pr_resolve<thread-id>--owner <owner>--repo <repo>--allow-write

  • toil github pr add-reviewerswrite

    Request reviewers on a pull request

    MCP github_pr_add_reviewers<number>--reviewer <login>--team-reviewer <slug>--owner <owner>--repo <repo>--allow-write

  • toil github pr remove-reviewerswriteCLI only

    Remove requested reviewers from a pull request

    <number>--reviewer <login>--team-reviewer <slug>--owner <owner>--repo <repo>--allow-write

  • toil github commit status

    Get combined commit status for a ref (branch, tag, or SHA)

    MCP github_commit_status<ref>--owner <owner>--repo <repo>

  • toil github commit checks

    List check runs for a ref (branch, tag, or SHA)

    MCP github_commit_checks<ref>--limit <n>--cursor <cursor>--owner <owner>--repo <repo>

  • toil github check-dossier

    Check the call's dossier against GitHub: its owners and repositories exist

    MCP github_check_dossier--owner <owner>--repo <repo>

Powershell Man · Esc pauses