Skip to main content
Agents reach the GitHub API through a brokered MCP server that auto proxies in front of a pinned deployment of GitHub’s own github-mcp-server. The agent sees familiar tools — create_pull_request, issue_write, get_file_contents — under the github alias, but every call is authorized, scoped, and attributed by the proxy, and GitHub credentials never enter the sandbox. This page covers the catalog, how the allowlist is computed, and the capability gates. Read it with the mounts reference, which owns the declaration syntax.

How access is provisioned

GitHub access is mount-backed. A session gets the github MCP server if and only if its agent has at least one kind: git mount with auth: { kind: githubApp } — the mounts are what the proxy mints tokens from. A kind: github tool declaration only tunes the tool list on top of that:
.auto/agents/pr-review.yaml
  • Mounts, no github tool: the server is wired anyway with the default allowlist.
  • github tool, no githubApp mount: the tool is a silent no-op — no server is wired, because every call would be rejected.
  • The alias defaults to github, so tools appear to the model as mcp__github__create_pull_request and the other names models already know.

The credential model

The sandbox holds only a session-scoped bearer token for the proxy endpoint. Per request, the proxy:
  1. Resolves the session’s githubApp mounts and rejects sessions that have none.
  2. Determines the target repository from the tool call’s arguments. The repo must be a mount or a repository the project is authorized to use — anything else is rejected with repository is not authorized for this project.
  3. Mints a fresh GitHub App installation token, down-scoped at mint time to the target repository and to the permission set derived from the mount’s capabilities.
  4. Forwards the single tools/call upstream with the tool allowlist enforced. The ghs_ token exists only between the proxy and the upstream server; it is never returned to the sandbox.
The upstream is pinned (github-mcp-server v1.3.0) running the repos, issues, pull_requests, and actions toolsets, so the catalog below is stable rather than tracking upstream releases silently.

The catalog

An agent’s kind: github tool may select from 49 names: 41 upstream tools plus 8 implemented by the proxy itself. Upstream (41): actions_get, actions_list, actions_run_trigger, add_comment_to_pending_review, add_issue_comment, add_reply_to_pull_request_comment, create_branch, create_or_update_file, create_pull_request, create_repository, delete_file, fork_repository, get_commit, get_file_contents, get_job_logs, get_label, get_latest_release, get_release_by_tag, get_tag, issue_read, issue_write, list_branches, list_commits, list_issue_types, list_issues, list_pull_requests, list_releases, list_repository_collaborators, list_tags, merge_pull_request, pull_request_read, pull_request_review_write, push_files, search_code, search_commits, search_issues, search_pull_requests, search_repositories, sub_issue_write, update_pull_request, update_pull_request_branch. Proxy-implemented (8): executed by auto itself with the same per-call minted token, injected into tools/list, never forwarded upstream: The proxy also extends pull_request_read with a labels sub-operation.

The default allowlist

Omitting tools: applies a curated 24-tool default: PR flow (create_pull_request, pull_request_read, update_pull_request, update_pull_request_branch, pull_request_review_write, add_comment_to_pending_review, add_reply_to_pull_request_comment), issue/comment flow (add_issue_comment, delete_issue_comment, upsert_issue_comment, download_comment_attachment, issue_read, issue_write), search (search_pull_requests, search_issues, search_code), repo content (get_file_contents, list_commits, create_branch, create_or_update_file, push_files), and Actions reads (actions_get, actions_list, get_job_logs). Deliberately excluded by default — name them explicitly to opt in: create_repository, fork_repository, delete_file, actions_run_trigger, rerun_failed_jobs, rerun_failed_jobs_for_pr_head, list_repository_collaborators, sub_issue_write, release/tag/label reads, search_repositories, search_commits. Merge and secrets tools work differently: they follow the mount capability, not the tool list — a mount granting merge: write or secrets: adds them on top of the curated default automatically, and without the grant they stay invisible even when named explicitly (merging with no human in the loop is an opt-in, not a default). Naming tools: replaces the default entirely — the effective list is exactly the names you give, still subject to the capability gates below.

Capability scoping from mounts

Each githubApp mount declares capability levels that become both the minted token’s GitHub permissions and the proxy’s gates: Every minted token also carries metadata: read. merge: write requires contents: write and pullRequests: write on the same mount — GitHub has no standalone merge permission, so an incoherent grant is rejected at apply time. Two tool families are double-gated — invisible and uncallable unless granted, even when an agent names them explicitly:
  • Merge tools (merge_pull_request, enable_pull_request_auto_merge): visible only when some mount grants merge: write; per call, the target repository’s own mount must grant it. A merge-granted session still cannot merge on its other, non-granted repositories.
  • Secrets tools: actions_secret_list needs secrets: read or better, actions_secret_write needs secrets: write — same two-level model, session visibility from the maximum across mounts, per-repo re-check against the called repo’s mount.
The failed-jobs rerun tools are more restrictive because rerunning production work is an operational mutation. The immutable session tool snapshot must name the chosen operation explicitly, the immutable mount snapshot for the target repository must grant actions: write, and the currently applied target mount must still grant actions: write when the token is minted. A later capability grant does not add the mutation to an already-running session, a later revocation stops the call, and broader bearer-token scopes cannot bypass either snapshot. Agents should use a rerun tool only with explicit human authority for the workflow run being rerun. rerun_failed_jobs_for_pr_head adds a point-of-use fence: immediately before the mutation, the proxy requires the PR to be open, both the live PR and run heads to match the expected full SHA, the run’s current attempt to match the expected attempt, and that attempt to be completed with conclusion failure. GitHub’s failed-jobs rerun endpoint has no conditional head or attempt parameter, so the live reads and POST are not provider-atomic. The residual race can rerun only the old workflow; downstream orchestration must still verify the current PR head and evidence cycle and must never count a stale rerun as current evidence. A called repository that is itself a mount uses that mount’s capabilities. A project-authorized repository that is not a mount gets the standard default capability set, with merge, secrets, and explicitly gated Actions mutations always denied.

Guardrails on write tools

Beyond scoping, the proxy enforces several invariants:
  • Visible attribution: covered write-tool bodies are stamped with an agent-attribution header derived from the session identity (never from tool arguments), linking back to the session page when project slugs resolve.
  • Artifact attribution: successful write-tool calls are recorded as artifact attributions — this is how a PR an agent opens auto-binds to its session on pull_request.opened (see triggers and sessions).
  • Commit-author verification at PR creation, so attributed authorship on PRs matches the platform’s records.
  • Comment substance guard: add_issue_comment rejects near-empty bodies before anything is minted or forwarded, so a stray placeholder can never land on an issue.
  • One tools/call per request: batched calls are rejected outright rather than partially attributed.
  • A tool outside the session’s allowlist fails with a tool-level error (unknown tool "…": not enabled for this session), which agents recover from far better than a transport error.

Example: a review agent’s GitHub surface

A PR-review agent that comments and manages checks but can never merge or push:
.auto/agents/pr-review.yaml
With contents: read, the minted tokens cannot push even through git; with no merge capability, merge tools do not exist for this session regardless of what any prompt asks for.