How to run the GitHub MCP server safely: read-only, toolsets and lockdown

The GitHub MCP server's default toolsets include write tools. Three switches and one token setting cut it down to what your agent needs. Here is each one, for the local and the remote server.

The short answer

Turn on read-only mode, list only the toolsets the agent needs, and give it a fine-grained personal access token limited to the repositories it works on. Locally that’s --read-only --toolsets repos,issues, or GITHUB_READ_ONLY=1 and GITHUB_TOOLSETS in Docker. Remotely it’s a /readonly URL or the X-MCP-Readonly header. Add lockdown mode if the agent reads public issues, but don’t count it as a security control.

Every MCP tool call goes through your rules first. Here a delete that doesn’t say which rows is stopped before it reaches the database. These are the rules deedglass init starts with; the call is made up.

What you get by default

With no toolsets named, the server loads its default toolset: context, repos, issues, pull_requests and users.2 That covers creating branches, pushing files, opening and merging pull requests, and commenting on issues, which is more than an agent that only needs to read code and triage issues should have.

The reason this matters is well documented. In May 2025, Invariant Labs showed a malicious issue in a public repository steering an agent with the GitHub server connected into copying data from the user’s private repositories into a public pull request. They called it an architectural problem at the agent level, not a flaw in the server code.4 Our write-up of that exploit goes through it step by step. This post is the setup side: which switches exist and what each one actually limits.

The four controls

Control Local flag Docker env var Remote What it limits
Read-only --read-only GITHUB_READ_ONLY=1 /readonly URL suffix or X-MCP-Readonly: true Only read tools are offered12
Toolsets --toolsets repos,issues GITHUB_TOOLSETS /mcp/x/<toolset> URL or X-MCP-Toolsets Which groups of tools load12
Lockdown --lockdown-mode GITHUB_LOCKDOWN_MODE=1 X-MCP-Lockdown Public content from people without push access12
Token scope the token you pass the token you pass your OAuth grant What the credential can reach at all3

Two precedence rules are worth knowing. Read-only wins over an explicit tool list: write tools are skipped under --read-only even if --tools names them. And GITHUB_TOOLSETS takes precedence over the --toolsets flag when both are set.1 For the remote server, a request header can turn lockdown on but can’t turn off lockdown the operator already set.2

The special toolset all enables every toolset.1 If you see it in a config, ask why.

Recipes

A local agent that reads code and issues, in Docker:

Code Data in JSON, the format software uses to pass records and settings.

{
  "mcpServers": {
    "github": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
        "-e", "GITHUB_READ_ONLY=1",
        "-e", "GITHUB_TOOLSETS=repos,issues",
        "ghcr.io/github/github-mcp-server"
      ]
    }
  }
}

The -e GITHUB_PERSONAL_ACCESS_TOKEN line with no value passes the variable through from your environment, so the token isn’t written into the file.

The remote server, read-only, issues only:

Code Data in JSON, the format software uses to pass records and settings.

{
  "mcpServers": {
    "github-issues": { "url": "https://api.githubcopilot.com/mcp/x/issues/readonly" }
  }
}

The remote server with headers instead of a URL:

Code Data in JSON, the format software uses to pass records and settings.

{
  "mcpServers": {
    "github": {
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": {
        "X-MCP-Toolsets": "repos,issues",
        "X-MCP-Readonly": "true",
        "X-MCP-Lockdown": "true"
      }
    }
  }
}

The headers key is accepted by clients that support HTTP headers for MCP servers; check your client’s format in our table of MCP config files.

What lockdown does, and doesn’t

Lockdown mode checks whether the author of each item in a public repository has push access, and withholds or errors on content from people who don’t. Content from github-actions[bot] and copilot is treated as safe. The README is explicit that it is not an authorization boundary: the credential’s access doesn’t change, and withheld content may still be reachable through other tools or the API with the same token.1

So lockdown narrows what untrusted text reaches the model. It doesn’t narrow what the agent can do once something does reach it. For an agent that reads public issues and holds a token with write access to private repositories, that’s still Simon Willison’s “lethal trifecta”: private data, untrusted content and a way to communicate externally.5 The fix is to remove a leg, usually the write access.

The token is the real boundary

Every switch above is a setting on the server. The token decides what’s possible. GitHub’s fine-grained personal access tokens can be limited to specific repositories and given specific permissions, and GitHub recommends the minimum access that meets your needs. They always include read access to all public repositories.3

A checklist for the token an agent uses:

  • Fine-grained, not classic.
  • Repository access set to “only select repositories”, naming the one or two the agent works on.
  • Contents: read-only, unless the agent must push.
  • Issues and pull requests: read-only, unless it must comment.
  • No administration, secrets, workflows or organization permissions.
  • An expiry date you’ll notice.

Invariant’s own advice after the exploit was to limit an agent to one repository per session.4 A token scoped to one repository enforces that even when the agent is persuaded to try otherwise.

Checking a config

If you run a config scanner over your MCP files, check what it does with GitHub. In our runs of deedglass 0.13.0’s scan, the GitHub server contributed no write paths to the grade, with or without read-only mode, because the scan’s catalog doesn’t classify that server’s tools.6 A good grade there doesn’t mean the GitHub entry was reviewed. Read it against the table above yourself.

Questions people ask

Does the GitHub MCP server have a read-only mode?

Yes. --read-only locally, GITHUB_READ_ONLY=1 in Docker, a /readonly URL suffix or the X-MCP-Readonly header remotely. It offers only read tools and overrides any explicit tool list.12

Is lockdown mode enough to stop prompt injection?

No. GitHub’s README calls it a best-effort content filter, not an authorization boundary; the token can still read and write what it could before.1

Which toolsets load if I don’t choose any?

The default toolset: context, repos, issues, pull_requests and users.2

For the broader picture, see prompt injection, the lethal trifecta explained, the MCP security checklist and the ten-minute MCP config audit.

To see everything else your agent setup can change, run npx deedglass scan in the repository (what the grade means), or watch the checks in the playground.

Written with AI assistance and checked against our claims register.

The takeaway

Read-only mode, a short toolset list and a fine-grained token do the real limiting; lockdown filters public content but isn't a boundary.

Read nextHow to audit an MCP config: a ten-minute review, server by server Try it: install in 7 s

Related on this site

More posts

Sources

  1. 1github/github-mcp-server README · github.com · checked 27 October 2026
  2. 2GitHub MCP server: remote server docs · github.com · checked 27 October 2026
  3. 3GitHub Docs: Managing your personal access tokens · docs.github.com · checked 26 October 2026
  4. 4Invariant Labs: GitHub MCP exploited (26 May 2025) · invariantlabs.ai · checked 26 October 2026
  5. 5Simon Willison: The lethal trifecta for AI agents · simonwillison.net · checked 14 October 2026
  6. 6Deedglass docs: scan · docs.deedglass.com · checked 27 October 2026

Published 27 October 2026, sources last checked 27 October 2026. If something here is out of date, write to hello@deedglass.com.

Try it on your own setup

npx deedglass scan

Grades only your own setup. Nothing is uploaded.

Pricing