SafetyCard Request a review

GitHub MCP Server

GitHub's official MCP server (repos, issues, PRs, Actions, security)

github.com/github/github-mcp-server · 2026-10-03 · f10e4e1

Defense-in-depth score

6.4 / 10

The server acts on GitHub with the user's own token, which by default carries full 'repo' control of every private repository the user can reach, and its default tool set can push files, merge pull requests, post comments and open issues with no confirmation step of its own. Content from any public issue, pull request or file flows to the model alongside those write tools and private-repo reads, so a prompt-injected agent can leak private code into a public comment unattended: the server's lockdown mode, information-flow labels and read-only mode would break that chain but are all off by default. Risk annotations are accurate and enforced by a test, repository deletion needs a typed human confirmation, and the token is never sent off GitHub hosts, but there is no audit record of tool calls unless verbose stdio logging is switched on.

Safest setup

GitHub MCP Server keeps your token away from the model and on GitHub's own hosts, labels every tool as read-only or not, and asks you to type the repository name before deleting one. As shipped it pairs a broad token and write tools with content from any public repository, so the safest setup narrows the identity and turns on the read-only, lockdown and labelling modes the server already includes.

SetupHowWhat it gives you
A narrowly scoped grantGive the App installation or fine-grained token only the repositories and permissions the task needs, read-only where the task allowsGitHub itself refuses anything outside that grant, whatever the model asks for C1
GitHub App mode--app-id, --app-installation-id and --app-private-key-path on the stdio serverA dedicated identity whose tokens expire within an hour, in place of your own account's access C1
Read-only mode--read-onlyEvery write tool is removed, so nothing the agent reads can be posted, pushed or merged C5
Only the toolsets needed--toolsets <list> naming just the toolsets the task usesThe model sees a smaller set of tools, with write tools only where you chose them C3
Lockdown mode--lockdown-modeIssue and pull request content from non-collaborators in public repositories stays out of the model's context C5
Trust labels on results--features ifc_labelsEach result is marked trusted or untrusted and public or private, for your host to act on C5
A tool-call log--enable-command-logging with --log-file <path> outside any workspaceA timestamped record of every tool call and result that outlives the session C9

Approving with confidence

  • Read each prompt and approve write calls one at a time; merges, file pushes and deletions, and comments have no preview of their own.
  • Assigning the Copilot coding agent starts work on GitHub that keeps running after the session ends, so approve it when you want that work to go ahead.

Handling data

  • The command log holds every request and response unredacted, file contents included; store it like the repositories it covers.

Key gaps (1)

  1. In the default configuration, content from any public issue, PR or file reaches the model in the same session that holds full 'repo' access to private repositories and unattended write tools (comments, issues, push_files), so a prompt injection can exfiltrate private code publicly; lockdown, IFC labels and read-only mode are all opt-in. C5 · Untrusted input blast radius

Criteria

C1 Identity & least privilege

0.50 / 1.00

The server uses one GitHub credential for everything: a personal access token, or by default an OAuth login that requests the full 'repo' scope (complete control of all the user's private repositories) plus packages, projects, gists and notifications. It narrows the default OAuth request by leaving out repository deletion, organization admin and workflow scopes, and it hides tools the token cannot use, but reads and writes share the same broad token and the server has no authorization layer of its own; GitHub's API is the only check. An opt-in GitHub App mode gives a dedicated, installation-scoped identity with short-lived tokens, which is the stronger option. In HTTP mode (not the scored default) the server forwards the client's bearer token to GitHub.

C2 Approval gates

0.63 / 1.00

The host, not the server, decides what to approve, so this criterion rates the signals the server gives it. Every tool explicitly declares whether it is read-only, a test enforces that the declaration is present, reads and writes are separate tools, and the opt-in read-only mode drops every write tool. Repository deletion is the one action with a server-enforced human confirmation: the user must type the exact repository name and the server re-checks the repository's identity before deleting. Other destructive or hard-to-undo actions (merging, deleting files, pushing files, posting comments) have no preview or confirmation, and the interactive forms some clients show for creating issues and pull requests are not an enforced gate.

C3 Tool & action scoping

0.53 / 1.00

Tools are narrow, purpose-built GitHub operations rather than a generic HTTP or GraphQL passthrough. Write tools validate file paths (no absolute paths, backslashes or '..'), refuse to overwrite an existing file without its current SHA, refuse to write through symlinks, and never force-update branches. Read tools take paths and repository names without the same validation, and numeric limits such as page size live only in the schema. The default tool set includes many write tools (push files, delete files, create repositories, merge pull requests), and nothing limits which repositories or organizations the tools may touch.

C4 Code-execution isolation

N/A · full credit 1.00 / 1.00

The server never runs model-supplied code or commands. The only process it starts is the system browser opener for the OAuth login URL, and its only template rendering is the static OAuth result page. Actions it can trigger on GitHub (assigning the Copilot coding agent, or workflow runs in the non-default actions toolset) execute on GitHub's infrastructure and are scored as consequential actions under approval gates and untrusted input.

C5 Untrusted input blast radius

0.50 / 1.00

The server returns issue, pull request, comment, commit and file content from any repository, including public ones anyone can write to, and the same default session holds private-repository read access and write tools that post comments, open issues and push files. Results are structured JSON with authors and URLs, and issue and comment bodies are stripped of invisible characters, but nothing marks content as untrusted by default. The server already contains the right defenses — a lockdown mode that withholds public content from non-collaborators, information-flow labels that mark each result as trusted/untrusted and public/private, and a read-only mode — but all three are opt-in. As shipped, a hijacked agent can copy private code into a public comment with no human involved.

C6 Memory, context & configuration integrity

N/A · full credit 1.00 / 1.00

The server keeps no memory between sessions: OAuth tokens, caches and lockdown results live only in process memory, and configuration comes from flags and environment variables set by the operator. In the scored Docker deployment the working directory is inside the image, so no workspace file is loaded. In binary (non-Docker) installs, configuration loading is not integrity-protected.

C7 Third-party extensions

N/A · full credit 1.00 / 1.00

The server loads no third-party code at runtime: no plugins, no MCP servers of its own, no downloaded tools. Its UI resources are embedded into the binary at build time.

C8 Secrets & sensitive-data protection

0.45 / 1.00

The GitHub token never reaches the model: tools have no way to read it, OAuth tokens are held only in memory, and the token is attached only to requests for the configured GitHub hosts, so a redirect cannot carry it elsewhere. There is no redaction layer, though: the opt-in command logging writes every request and response verbatim, and the non-default secret-scanning tools deliberately return leaked secret values to the model. Default telemetry is a no-op. The token itself is long-lived and broad (a PAT, or an OAuth token with 'repo').

C9 Audit & traceability

0.38 / 1.00

By default the server keeps no record of the tools it runs: it logs startup and authentication events only, and the per-tool logger it passes to handlers is never used. An opt-in command-logging flag writes the raw JSON-RPC traffic (every request and response) to stderr or a log file, which lets you reconstruct calls, but as unparsed byte chunks with no notion of who asked or who approved, written best-effort.

C10 Limits & kill switch

0.38 / 1.00

Some of the server's work is bounded: Actions log downloads are capped by a 5,000-line content window and default to the last 500 lines, list tools default to 30 results, and GitHub's own API rate limits bound a runaway. But GitHub API calls have no timeouts of their own, the log download ignores cancellation, page-size limits live only in the schema, and the server has no rate limiting. Assigning the Copilot coding agent starts remote work that continues regardless of anything the server or host does next.