Rightshold™ Sign up

Answers · MCP security

How do I give an MCP server least-privilege access to GitHub?

Short answer: Give the GitHub MCP server a credential that can reach only the repositories the agent works on, read-only by default, and make pushes and merges a separate, approved step. Use a fine-grained personal access token set to Only select repositories, with Contents and Pull requests read-only and an expiry date, or a GitHub App installed on just those repositories, whose installation tokens expire after an hour and can be narrowed further per request. Never use a classic token with the repo scope: it reaches every repository you can access. Then cut the tools down: GitHub's MCP server has a read-only mode (the /readonly URL or X-MCP-Readonly header remotely, GITHUB_READ_ONLY locally) and toolsets so you load only repos or issues. Finally, protect the branches: a ruleset that requires a pull request and an approval from someone other than the last pusher means even a write-enabled token can't land code on main by itself.

Checklist

  1. Pick the credential: a fine-grained personal access token for one person's agent, or a GitHub App for a team or a service. Avoid classic tokens; the repo scope covers every repository the account can reach, public and private.
  2. Limit repositories: set Repository access to Only select repositories (fine-grained token) or install the GitHub App on selected repositories only. Leave out private repositories the task doesn't touch.
  3. Read-only permissions by default: Contents read, Pull requests read, Issues read, plus Metadata read, which every token gets. Add write permissions only for a separate token or task that needs them.
  4. Set an expiry and rotate: give fine-grained tokens a short expiration; organization owners can require approval for fine-grained tokens and cap their lifetime. GitHub App installation tokens last one hour and can be minted for a subset of the installed repositories and permissions.
  5. Run the server read-only: remotely, use https://api.githubcopilot.com/mcp/readonly (or /x/<toolset>/readonly) or send X-MCP-Readonly: true; locally, set GITHUB_READ_ONLY=1 or --read-only. Load only the toolsets you need with X-MCP-Toolsets or GITHUB_TOOLSETS, for example repos,pull_requests.
  6. Separate approval for writes: use a second, write-enabled configuration only for tasks that push or open pull requests, keep the client's confirmation on for create, push, merge and delete tools, and show the full arguments.
  7. Protect the default branch: a ruleset or branch protection that requires a pull request, at least one approval, approval of the most recent push by someone other than the pusher, passing status checks, and blocks force pushes and deletions.
  8. Treat repository content as untrusted: issue bodies, comments and files can carry instructions. Don't give one session both access to private repositories and a way to publish to public ones; use one repository per session where you can.

Why repository scope matters as much as read-only

Fine-grained token or GitHub App

Ask Rightshold (free, no key)

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Before I connect the GitHub MCP server to my agent, is it a listed server, what tools does it expose, and have its tool definitions changed since they were recorded?”

One-click setup

{
  "tool": "precall_check",
  "arguments": {
    "url": "https://api.githubcopilot.com/mcp/readonly",
    "tool": "<optional tool name, for example get_file_contents>"
  }
}

Rightshold does not create GitHub tokens, install GitHub Apps or change your repository settings. Token scopes, read-only mode and branch rules are set in GitHub and your MCP client; Rightshold checks the MCP server's listing and tool definitions.

Sources

Related

Not legal advice. Updated 2026-10-29. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'