Which token scopes does the GitHub MCP server need?
Only the scopes for the tools you turn on. With a classic token, repo covers most repository, issue and pull request tools; add workflow, gist, notifications or read:org only when you need those tools. GitHub recommends a fine-grained token limited to selected repositories instead, but the server then shows every tool and leaves enforcement to the API.
Cite
CodeLifter Forum, "Which token scopes does the GitHub MCP server need?", https://codelifter.com/forum/posts/which-token-scopes-does-the-github-mcp-server-need/, accessed 2026-11-12.- CodeLifter editorsStaffStaff, CodeLifter ·
How the server reacts to each kind of token
The official server behaves differently depending on how you sign in. Its scope filtering document sets it out:
Token type Prefix What the server does Classic personal access token ghp_Reads your scopes at startup and hides tools your token cannot use OAuth (hosted server) none to set Shows all tools, then prompts you to grant a missing scope when a tool needs it Fine-grained personal access token github_pat_No filtering: "all tools shown, API enforces permissions" GitHub App installation token ghs_No filtering; permissions come from the app installation Two details catch people out. If the server cannot read your classic token's scopes (the document gives network issues or rate limiting as examples), it "logs a warning and continues without filtering." And read-only repository tools that only need
repoorpublic_repostay visible even without those scopes, because they work on public repositories.Scopes by job
The server's README lists the OAuth scopes each tool may ask for. The middle column below comes from that list. The right column gives the fine-grained permission named for the same resource in GitHub's personal access token documentation; that pairing is our reading, so confirm it against an API response (see the last section).
What you want the assistant to do Classic scope Closest fine-grained permission Read files, commits, issues and pull requests in private repos repoContents, Issues, Pull requests: read Open issues and add comments ( issue_write,add_issue_comment)repoIssues: write Push files, open and merge pull requests ( push_files,create_pull_request,merge_pull_request)repoContents and Pull requests: write Change a file under .github/workflows/repoplusworkflowWorkflows: write List or trigger Actions runs, read job logs ( actionstoolset, off by default)repoActions: read, or write to trigger Code scanning and Dependabot alerts security_events(included inrepo)Code scanning alerts, Dependabot alerts: read Create or update gists gistGists: write (account permission) List or dismiss notifications notificationsNo notifications permission appears in GitHub's fine-grained list Read teams and members ( get_teams,get_team_members)read:orgMembers (organization permission): read Delete a repository ( delete_repository)delete_repoplusrepoDo not grant it The scope filtering document notes that
workflowis requested "only when the call changes a workflow file." That scope is worth keeping off unless you need it, because a workflow file decides what GitHub Actions runs in that repository.The README's own "Token Security Best Practices" list
repo,read:packages(for "Docker image access") andread:orgas minimum scopes. The same README says the Docker image atghcr.io/github/github-mcp-serveris public, so test whether you needread:packagesbefore you add it.Set up a fine-grained token for one project
- On GitHub, open Settings, then Developer settings, then Personal access tokens, then Fine-grained tokens, and click Generate new token.
- Set an expiration. GitHub's documentation says infinite lifetimes "may be blocked by a maximum lifetime policy" in some organisations, and recommends an expiry in any case.
- Under Resource owner, pick your account or the organisation that owns the repository.
- Under Repository access, choose Only select repositories and pick the ones the assistant should touch. GitHub notes that tokens "always include read-only access to all public repositories on GitHub."
- Under Permissions, start with Contents: read, Issues: read and Pull requests: read. Add write permissions one at a time when a task fails for lack of them.
- Generate the token and store it in an environment variable, not in a committed file. The server reads it from
GITHUB_PERSONAL_ACCESS_TOKEN.
Because a fine-grained token disables the server's tool filtering, limit the tools on the server side too:
github-mcp-server stdio --toolsets=repos,issues,pull_requests --read-onlyThe server configuration guide says read-only mode disables write tools "even when explicitly requested," and that
--exclude-toolsremoves listed tools "regardless of any other configuration." If you allow writes, exclude the riskiest tools by name, for example--exclude-tools=merge_pull_request,delete_file.When a classic token is the only option
GitHub's documentation lists cases fine-grained tokens do not cover yet, including contributing to public repositories where you are not a member, working as an outside collaborator, and accessing several organisations at once. In those cases a classic token is needed. Remember that a classic token "will grant access to all repositories within the organizations that you have access to, as well as all personal repositories," so pair it with
--read-onlyor a short toolset list.Check what your token actually has
For a classic token, the scope filtering document gives this command:
curl -sI -H "Authorization: Bearer $GITHUB_PERSONAL_ACCESS_TOKEN" \ https://api.github.com/user | grep -i x-oauth-scopesFor a fine-grained token, GitHub's REST documentation says responses carry an
X-Accepted-GitHub-Permissionsheader naming the permissions an endpoint needs, which is the quickest way to settle a "Resource not accessible" error.Scopes are only half of the picture; where the server runs is the other half. See remote or local GitHub MCP server for that choice, and who is the author of a commit made through an MCP server for what happens to authorship once you allow writes. The CodeLifter GitHub MCP server page lists every toolset and what it can change.
Write something first.
Give people something to work with: at least 30 words on what happened and what you tried.
That is too long. Keep it under 6,000 characters.
Write the question as the title, 15 to 140 characters, no links.
Pick a category.
Add a name (2 to 40 characters, no links).
That email address does not look right.
That was quick. Read the thread, then try again.
The form expired. Reload the page and post again.
Something went wrong with the form. Reload and try again.
Please complete the check and post again.
Limit reached for now. Try again later.
This thread is closed to new replies.
This thread no longer accepts replies.
Something went wrong with the form. Reload and try again.
Post a reply or question first (name and email), then this browser can vote, edit and accept answers.
You cannot vote on your own post.
Only the author (within 30 days) or the forum team can do that.
That email already has an account. Use your sign-in link instead.
New accounts are paused for the moment. Try again later.
That was already posted.
2 answers
- CodeLifter editorsStaffStaff, CodeLifter ·
Can you use a GitHub App instead of a personal access token? Yes, and its tokens are shorter lived. A GitHub App authenticates as an installation by generating an installation access token. GitHub's installation token documentation says the token expires after 1 hour. When you request it, the
repositoriesorrepository_idsparameters can narrow it to specific repositories, up to 500, and thepermissionsparameter can narrow its permissions; without them it gets everything the installation was granted, and never more. The server's scope filtering document, quoted in the opening post, lists installation tokens by theirghs_prefix and says the server does no tool filtering for them, because permissions come from the installation. So the same advice applies as for fine-grained tokens: limit tools on the server with--toolsets,--read-onlyor--exclude-tools. The one-hour expiry is the real gain, since a leaked token stops working quickly. The cost is setup: you register an app, install it on the repositories, and something has to mint a fresh token every hour, which GitHub's Octokit SDKs can do for you. For one person on one laptop, a fine-grained token is usually simpler. - CodeLifter editorsStaffStaff, CodeLifter ·
What should you do if a GitHub token leaks? Revoke it first, then clean up. GitHub's secret scanning documentation says secret scanning checks your entire Git history on all branches for known credential formats, and that it is free on public repositories. Its advice when a credential is found is to rotate the affected credential immediately, and it notes that removing the secret from history is often unnecessary once the credential no longer works. In order: delete the token on GitHub under Settings, Developer settings, Personal access tokens, so it is dead whatever else happens. Generate a replacement with the narrowest repositories and permissions the work needs. Check the account's security log and the affected repositories for actions you did not make, paying particular attention to anything under
.github/workflows/. Then update the place the server reads it from, theGITHUB_PERSONAL_ACCESS_TOKENvariable or your client's input prompt, and restart the server. The README advice quoted in the opening post prevents the common cause: keep the token in an environment variable, add.envto.gitignore, runchmod 600on any config file that holds it, and use a separate token for agent work so you only revoke that one.