Last updated: October 23, 2026
What is GitHub MCP, and how do you secure it? GitHub MCP is GitHub's official Model Context Protocol server, which lets AI agents read and change repositories, issues, pull requests and workflows. You secure it in layers: a narrow credential, a small toolset, read-only or lockdown mode where possible, and runtime inspection of what the agent reads and calls. This guide walks through each layer with the real settings.
TL;DR: Key Takeaways
- The GitHub MCP server documents 22 toolsets and 92 tools, and it loads 5 default toolsets unless you change the configuration (GitHub).
- On May 26, 2025, researchers showed that 1 malicious public issue could push an agent to expose private repository data in a public pull request (Simon Willison).
- Loading 3 to 10 tools instead of the default toolsets cut context window usage by about 60% to 90% in GitHub's own tests (GitHub Changelog).
- Lockdown mode, announced on December 10, 2025, is a best-effort content filter, not an authorization boundary (GitHub).
- 2 advisories in 2026 hit the server: a CVSS 7.5 denial of service fixed in 1.1.0 and a CVSS 6.0 lockdown flaw fixed in 1.1.2 (GitHub Security Advisories).
- GitHub lists 3 MCP audit views that do not exist yet, so MCP calls show up as ordinary API calls in the audit log (GitHub).
At a glance: the controls that matter most
Quick Answer
How do you secure GitHub MCP in production?
Start with a fine-grained token or per-user OAuth limited to the repositories the agent needs. Enable only the toolsets it uses, turn on read-only mode where writes are not required, and exclude merge and delete tools. Then inspect tool results for indirect prompt injection and mask secrets at runtime, because native filters are best-effort.
| Layer | Control | What it reduces | Limit |
|---|---|---|---|
| Identity | Fine-grained PAT, per-user OAuth or GitHub App | Blast radius of a stolen or abused token | PATs are user-scoped and not meant for production automation |
| Tool surface | Toolsets, single tools and excluded tools | Write paths the model can call | Does not inspect content |
| Write access | Read-only mode | Every write tool, even if requested | Reduces what the agent can do for you |
| Untrusted content | Lockdown mode | Public content from users without push access | Best-effort filter, not authorization |
| Patching | Version 1.1.2 or later | 2 known 2026 advisories | Fixes known bugs only |
| Runtime | Gateway policies and detectors | Injection in tool results and leaked secrets | Covers only traffic routed through a gateway |
What the GitHub MCP server can reach
The GitHub MCP server can reach whatever its credential can reach. GitHub's governance guide says users and apps cannot use it to access more than they could through the API. That ceiling is often high: a classic token with the repo scope grants full access to public and private repositories, including write access to code.
GitHub ships the server in two forms: the remote server runs at https://api.githubcopilot.com/mcp/ and is hosted by GitHub. The local server runs from the Docker image ghcr.io/github/github-mcp-server or from a binary on your machine.
The README documents a browser OAuth login for the local server, though GITHUB_PERSONAL_ACCESS_TOKEN takes precedence if set. The remote server supports OAuth, PATs and GitHub App installation tokens.
The tool catalog is large, and the README lists 22 toolsets and 92 tools for the local server, plus remote-only toolsets such as copilot_spaces. With no configuration, you get the default toolsets: context, issues, pull_requests, repos and users. That default already includes tools that write code and merge pull requests.
| Toolset | Example tools | Why it matters for security |
|---|---|---|
repos (default) | get_file_contents, push_files, create_or_update_file, delete_file, delete_repository | Reads private code and can change or delete it |
pull_requests (default) | create_pull_request, merge_pull_request, update_pull_request_branch | A public pull request is an easy exfiltration channel |
issues (default) | issue_read, issue_write, add_issue_comment | Issue text from strangers enters the model context |
actions | actions_run_trigger, get_job_logs | Triggers workflows and reads build output |
secret_protection, code_security, dependabot | list_secret_scanning_alerts, list_code_scanning_alerts, list_dependabot_alerts | Reveals where secrets and weaknesses live |
Two details from the docs are easy to miss. First, file writes request the workflow scope in addition to repo when a call changes a workflow file, so an agent with that scope can edit your CI. Second, tool filtering by scope only works with classic PATs. With fine-grained PATs, the server shows every tool and lets the GitHub API enforce permissions.
GitHub MCP risks: how a public issue reached private repos
The best documented GitHub MCP attack is a toxic agent flow, not a server bug. Simon Willison (2025) wrote that the server combines the lethal trifecta: access to private data, exposure to malicious instructions and the ability to exfiltrate information. One malicious issue in a public repository was enough to start the chain.
The proof of concept, credited to researchers Marco Milanta and Luca Beurer-Kellner, worked in four steps:
- An attacker filed an issue in a public repository owned by the victim.
- The issue asked the agent to add details about the author to the README and list "all other repos the user is working on".
- The victim asked the agent to take a look at the open issues, which pulled the attacker's text into context.
- The agent read private repositories with the victim's token and opened a public pull request that exposed their names.
No credential was stolen and no code was exploited, because the agent simply used legitimate tools with legitimate permissions in the wrong order.
In GitHub issue #844, opened in August 2025, a user reported reproducing the flow with both OAuth and personal access tokens.
GitHub (2026) states its mitigations in a maintainer reply on that issue. They include lockdown mode, secret scanning on every tools/call request that touches a public repository, read-only mode, OAuth 2.1 support and strict fine-grained tokens.
| Risk | How it shows up on GitHub | First control |
|---|---|---|
| Indirect prompt injection | Instructions hidden in issues, pull request comments or commit messages | Lockdown mode plus a tool-result detector |
| Over-scoped credentials | Classic token with repo or admin:org on every repository | Fine-grained PAT or per-user OAuth |
| Exfiltration through writes | Agent opens a public pull request, issue or comment with private data | Exclude or rate-limit write tools |
| Destructive actions | merge_pull_request, delete_file or delete_repository called by mistake | Read-only mode or excluded tools |
| Secret exposure | Tokens or keys inside files, logs or tool output | Secret scanning and data loss prevention |
Step 1: Pick the narrowest credential
Pick the credential first, because every other control sits on top of it. According to GitHub Docs (2026), you should use fine-grained personal access tokens instead of classic tokens whenever possible. Fine-grained tokens belong to one owner, can be limited to specific repositories and use granular permissions rather than broad scopes.
The governance guide adds a warning about PATs in general. They are user-scoped, they do not follow OAuth App policies or GitHub App installation controls, and GitHub does not recommend them for production automation. For a team, per-user OAuth or a GitHub App installation gives administrators more levers.
| Credential | Best fit | Strengths | Weaknesses |
|---|---|---|---|
| Fine-grained PAT | One developer, local server | Single owner, chosen repositories, granular permissions, optional org approval | User-scoped; the server shows all tools and relies on the API to refuse calls |
| OAuth (remote) | Teams using hosts with a registered app | Scope challenges on demand, OAuth App policies, SSO enforcement | Each host needs its own registered app |
| GitHub App installation | Org-wide automation | Admins choose repositories and permissions; enterprise-level install | More setup; SSO enforcement does not apply to installation tokens |
The scope you grant decides the damage. GitHub's OAuth scope reference says repo grants full access to public and private repositories, plus management of some organization resources such as team memberships and webhooks. The narrower public_repo scope limits access to public repositories.
According to MCP specification authors (2025), poor scope design increases token compromise impact. Their guidance is to start with a minimal scope set, request more only when a privileged call needs it, and avoid wildcard or omnibus scopes. The specification also forbids token passthrough, where a server forwards tokens that were not issued to it.
Apply these rules before connecting any agent:
- Create one token per agent and environment, never one token for everything.
- Limit fine-grained tokens to the repositories the agent works on, and grant read permissions unless writes are essential.
- Set an expiry and rotate tokens on a schedule, as the README recommends.
- In organizations, require approval for fine-grained tokens and disable classic tokens if you can.
Step 2: Shrink the tool surface with native controls
Native controls decide which tools exist in the session. They are composable, and GitHub documents clear precedence rules: read-only mode beats any other setting, and excluded tools beat toolsets and single tools. Use them to remove every capability an agent does not need before it ever sees a prompt.
| Control | Remote server | Local server | What it does |
|---|---|---|---|
| Toolsets | X-MCP-Toolsets header or /x/{toolset} URL | --toolsets or GITHUB_TOOLSETS | Loads only the named groups |
| Single tools | X-MCP-Tools header | --tools or GITHUB_TOOLS | Loads only the named tools |
| Excluded tools | X-MCP-Exclude-Tools header | --exclude-tools or GITHUB_EXCLUDE_TOOLS | Removes tools in all cases |
| Read-only | X-MCP-Readonly header or /readonly URL | --read-only or GITHUB_READ_ONLY | Disables every write tool |
| Lockdown | X-MCP-Lockdown header | --lockdown-mode or GITHUB_LOCKDOWN_MODE | Hides public content from users without push access |
Two starting recipes for the remote server follow. The first suits a triage agent that only reads:
The second suits a coding agent that opens pull requests but never merges or deletes:
Smaller tool lists also help the model. According to GitHub (2025), loading 3 to 10 of the most used tools cut context window usage by about 60% to 90% compared with the default toolsets. The same changelog says content sanitization against prompt injection is now on by default.
Lockdown mode only surfaces content in public repositories from users with push access, and private repositories are unaffected. GitHub describes it as a best-effort filter. It does not restrict what the credential can read or write, and withheld content may still be reachable through other tools.
As an intentional exception, content written by github-actions[bot] and copilot is always treated as safe. If a workflow copies outside text into a bot comment, that text will pass the filter. In HTTP mode, a server-side lockdown setting is an upper bound that a request header cannot relax.
Step 3: Patch, monitor and test
Treat the server like any other dependency on your attack surface. According to GitHub Security Advisories (2026), two flaws were fixed this year, and both matter most when you self-host the server in HTTP mode. The latest release on October 23, 2026 was v2.0.3, so there is no reason to run anything older than 1.1.2.
| Advisory | Severity | Affected versions | Fixed in | Impact |
|---|---|---|---|---|
| CVE-2026-47427 (GHSA-w4q6-qw23-4rg7) | High, CVSS 7.5 | Below 1.1.0 | 1.1.0 | A malformed completion/complete request crashes the server before any authentication |
| CVE-2026-48529 (GHSA-pjp5-fpmr-3349) | Medium, CVSS 6.0 | 0.22.0 to below 1.1.2 | 1.1.2 | In HTTP mode with lockdown, access checks ran with the first user's credentials for everyone |
Monitoring is the weaker spot, since GitHub's governance guide says MCP traffic appears in standard audit logs as normal API calls. It lists three views that are not available yet: a real-time list of active MCP connections, dashboards by tool or host app, and action-by-action audit logs. If you need per-tool visibility today, you need something in the request path.
Then test the controls with a harmless canary before you trust them:
- Create a public test repository and a private test repository with dummy content.
- File an issue in the public one that asks the agent to add the word "canary-7731" to a new comment and to list your other repositories.
- Point your agent at the issues with your production configuration.
- Confirm that no comment, pull request or file change appears, and that any runtime detector you use flags the issue text.
How we compared
We read the server's README, configuration guide and governance guide, the December 2025 changelog, GitHub's security advisories and the MCP specification's security guidance. The incident account comes from Simon Willison's write-up and GitHub issue #844. Console steps below come from TrustGate and TrustGuard product screens, not marketing pages.
Security and governance: runtime controls with NeuralTrust
Native controls decide which tools exist, but they do not read what flows through them. That gap is where a gateway helps. We recommend routing GitHub MCP traffic through the Agent Gateway (TrustGate), whose Registry shows an MCP tab with 203 entries. Add Agent Runtime Security (TrustGuard) for the detectors described below.
Register GitHub in the TrustGate Registry
- Go to Registry > MCP > GitHub and click Configure. The "New GitHub instance" panel opens, described as "Repos, issues, pull requests, and workflows on GitHub."
- Fill in Instance name, which is required. The hint reads "e.g. GitHub – Production".
- Under Authentication, pick User account, Shared account or API Key, then complete the fields for that option.
The help box is titled "Register TrustGate as an OAuth app in GitHub". Its first line reads "GitHub personal access token (PAT), sent as a Bearer token". Its second line reads "Add TrustGate's OAuth callback URL, then enter the client ID".
User account
The screen says this provider "requires a pre-registered OAuth app" and that "users still log in at runtime". Register an OAuth app in GitHub and add TrustGate's OAuth callback URL to it. Then enter its Client ID and, if applicable, the Client secret, which is marked optional. Click Done.
)
Shared account
The screen says "One OAuth identity is used by everyone granted this instance". The fields are the same: Client ID and Client secret (Optional). The button reads Create and connect. Give that one GitHub identity only the repositories and permissions the whole group needs.
)
API Key
The screen says "A key stored on the gateway is used for every call to this instance". The single field is labeled "GitHub personal access token (PAT), sent as a Bearer token". The note under it reads "Paste the value. Stored encrypted on the gateway". Click Done. GitHub Docs recommends fine-grained tokens limited to specific repositories, so create one for this instance with least-privilege permissions and an expiry.
)
Which authentication option should you choose?
| Option | Whose identity calls GitHub | What you enter | Good fit if you need |
|---|---|---|---|
| User account | Each user logs in at runtime | Client ID of a pre-registered OAuth app, Client secret (Optional) | Per-user permissions and accountability for every change |
| Shared account | One OAuth identity used by everyone granted this instance | Client ID, Client secret (Optional) | One GitHub identity for a small team on the same repositories |
| API Key | A key stored on the gateway, used for every call | GitHub personal access token (PAT) | Automation or service agents with no person logging in |
If individual accountability matters to you, consider User account. With Shared account or API Key, keep the shared GitHub identity or PAT as narrow as the work allows and rotate it on a schedule. GitHub's governance guide also does not recommend PATs for production automation, so treat API Key as a tightly scoped service credential.
Add policies that apply to MCP traffic
Open Policies > Library for your gateway; each card has an Add policy button. Four cards carry both the LLM and MCP badges: TrustGuard, Per-Tool Rate Limiter, Rate Limiter and Request Size Limiter. Others, such as LLM Budget or Prompt Template, carry only the LLM badge.
| Policy | What the card says | Where you might use it |
|---|---|---|
| TrustGuard | Inspects request or response content, blocks flagged material, masks data, has failure_mode | Issue, comment and file content in responses |
| Per-Tool Rate Limiter | Limits each real tool execution across LLM and native MCP traffic, fixed windows, gateway-wide | create_pull_request, push_files and add_issue_comment, the likely exfiltration tools |
| Rate Limiter | Sliding window | Runaway loops of GitHub calls |
| Request Size Limiter | Limits request size | Oversized payloads such as bulk file pushes |
The TrustGuard card lists a failure_mode setting, so review it before agents get write access.
Add detectors in TrustGuard
Open Detectors > Catalog in TrustGuard and use Add detector on two entries. The Indirect Prompt Injection card says it scores tool results, including MCP tool results, plus tool descriptions and parameter schemas from tools/list. A malicious issue reaches the agent as a tool result. The Data Loss Prevention card says it masks PII in flight and reports secrets such as API keys, access tokens and JWTs.
The Prompt Guard card says it does not score system prompts, tool definitions or MCP tool call argument values. For GitHub MCP, the injection lives in tool results, so Indirect Prompt Injection is the card that matches this risk.
The pricing page lists a Free plan with TrustGate and TrustGuard and 100,000 requests a month.
Which should you choose?
| Your situation | Credential | Native configuration | Runtime layer |
|---|---|---|---|
| Solo developer exploring locally | Fine-grained PAT on a few repositories | Default toolsets plus read-only | Optional |
| Triage agent on public repositories | Per-user OAuth | issues,pull_requests read-only with lockdown | Indirect Prompt Injection detector |
| Coding agent that opens pull requests | User account ("users still log in at runtime") | repos,pull_requests, merge and delete excluded | Detector, DLP and Per-Tool Rate Limiter |
| Org-wide automation bot | GitHub App installation | Named tools only through X-MCP-Tools | TrustGuard policy plus rate limits |
| Self-hosted HTTP server | Per-user tokens | Server-side lockdown, version 1.1.2 or later | Request Size Limiter and Rate Limiter |
Conclusion
Securing GitHub MCP is mostly about shrinking what one prompt can reach. Start with a fine-grained or per-user credential, load only the toolsets each agent needs, and use read-only mode, exclusions and lockdown where they fit. Then treat every issue, comment and file as untrusted input, because native filters are best-effort. Patch to 1.1.2 or later, test with a harmless canary, and add runtime detection for injection and secrets before agents get write access in production.
Secure GitHub MCP in Production with NeuralTrust
Route GitHub MCP through one gateway with a Per-Tool Rate Limiter, Indirect Prompt Injection and Data Loss Prevention detectors, starting on the Free plan.
Related reading
- MCP Security 101
- MCP Prompt Injection: Proof on Bedrock
- 6 Best MCP Gateways for Enterprise (2026)
- MCP Server Registries for UK Enterprises
FAQs about GitHub MCP
1. Is the GitHub MCP server safe to use?
It is as safe as the credential and tools you give it. The server enforces GitHub's normal permissions and sanitizes content by default, and GitHub fixed two 2026 advisories in versions 1.1.0 and 1.1.2. The main risk is prompt injection through issues and comments, which can steer an agent that holds broad access. Narrow tokens, fewer tools and runtime detection reduce that risk.
2. Does GitHub MCP have a read-only mode?
Yes. Set the X-MCP-Readonly header or use the /readonly URL on the remote server, or pass --read-only locally. Read-only mode disables every write tool, even tools you request explicitly, and it takes precedence over all other settings. It is the simplest way to run triage or research agents, although the agent can still read private data its token allows.
3. What permissions does a GitHub MCP token need?
Only the permissions the agent's tasks require. GitHub recommends fine-grained tokens limited to specific repositories with granular permissions. For classic tokens, the README lists repo, read:packages and read:org as typical scopes, but repo grants full access to every private repository. Start with read permissions and add write permissions per agent when a workflow truly needs them.
4. What is lockdown mode in the GitHub MCP server?
Lockdown mode hides content in public repositories from users without push access, which reduces prompt injection from strangers. It does not affect private repositories. GitHub calls it a best-effort content filter, not an authorization boundary, and content from github-actions[bot] and copilot is always allowed. Enable it with X-MCP-Lockdown or --lockdown-mode, and pair it with token scoping.
5. Can GitHub MCP leak private repositories?
Yes, if one agent session holds a token that reaches private repositories and also reads untrusted public content. A 2025 proof of concept showed a public issue steering an agent to expose private repository names in a public pull request. Separate tokens, read-only mode for triage, excluded write tools and an indirect prompt injection detector all reduce that path.
6. Should I use the remote or local GitHub MCP server?
Use the remote server if you work on github.com or GitHub Enterprise Cloud and want GitHub to operate it, with OAuth scope challenges. Use the local server for GitHub Enterprise Server or when you need full control over the runtime and its network path. If you self-host in HTTP mode, run version 1.1.2 or later and set lockdown on the server side.
7. Which GitHub MCP tools should I disable first?
Start with tools that cause irreversible or public effects. Good first candidates are merge_pull_request, delete_file, delete_repository and push_files, then actions_run_trigger if agents do not run workflows. Use X-MCP-Exclude-Tools or --exclude-tools, because exclusions win over any toolset you enable. Review the list again whenever you add a new toolset.
8. Does GitHub log what MCP agents do?
Partly. Underlying API calls appear in GitHub's audit log when available, but they look like normal API traffic. GitHub says a real-time list of MCP connections, per-tool dashboards and action-by-action MCP logs are not available yet. For per-tool visibility and limits today, route traffic through a gateway that sees each tool call.
9. Should I use User account, Shared account or API Key for GitHub MCP?
Consider User account if you need each person to act as their own GitHub identity; the screen says "users still log in at runtime". Consider Shared account if your team can work as "one OAuth identity". Consider API Key for automation; the screen says a key stored on the gateway is used for every call. Scope any shared identity or PAT to the fewest repositories.
About the Author
Roger Howroyd is Head of Global SEO and AI at NeuralTrust, where he leads the company's search strategy across SEO, AEO, GEO, and LLM optimization. He specializes in AI-powered search, content strategy, and SEM. Connect on LinkedIn.
NeuralTrust is the leading platform for securing and scaling AI agents. Named a Pioneer in the Gartner Emerging Market Quadrant for AI Application Security 2026, recognized across four Gartner Hype Cycle reports in 2026, and featured in the Gartner Market Guide for Guardian Agents 2026, the Gartner Market Guide for AI Gateways 2025 and the KuppingerCole Leadership Compass for Generative AI Defense 2025. Headquartered in Barcelona with offices in London and New York. ISO 27001 certified.
Sources
- GitHub, GitHub MCP Server (README), accessed October 23, 2026.
- GitHub, Server Configuration Guide, accessed October 23, 2026.
- GitHub, Policies and Governance for the GitHub MCP Server, accessed October 23, 2026.
- GitHub Changelog, The GitHub MCP Server adds support for tool-specific configuration, and more, December 10, 2025.
- Simon Willison, GitHub MCP Exploited: Accessing private repositories via MCP, May 26, 2025.
- GitHub, Issue #844: Exfiltrate information from private repositories, opened August 8, 2025; maintainer reply April 20, 2026.
- GitHub, Security advisories for github-mcp-server (GHSA-w4q6-qw23-4rg7, July 20, 2026; GHSA-pjp5-fpmr-3349, June 2026), accessed October 23, 2026.
- GitHub Docs, Managing your personal access tokens, accessed October 23, 2026.
- GitHub Docs, Scopes for OAuth apps, accessed October 23, 2026.
- Model Context Protocol, Security Best Practices (specification 2025-11-25), November 25, 2025.
)
)
)
)
)
)
)