GitHub MCP with Claude Code: Setup and What You Can Do With It
Connect the GitHub MCP server to Claude Code with one command, confirm it connected, then run five real PR, issue, and CI workflows mapped to its tool names.

Made with DispatchSEO
On this page
claude mcp add-json github '{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":"Bearer <token>"}}' connects Claude Code straight to GitHub's official remote MCP server over a personal access token you already have - no Docker container, no browser sign-in. Once it's added, Claude can pull a pull request's diff, search code across a repo it's never cloned, or dig into why a CI run failed, without you copying any of that out of a browser tab first. Most pages on this topic skip the same things: the install command changed recently and older tutorials still show the wrong one, nobody shows what a rejected token actually looks like, and none of them map the server's 92 tools to what you'd reach for first.
TL;DR:
claude mcp add-json github '{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":"Bearer <token>"}}'connects the remote server with a GitHub personal access token, no OAuth step. Confirm withclaude mcp list. GitHub MCP ships 92 tools across 23 toolsets (44 if you stick with the default set: context, repos, issues, pull_requests, users) - this guide maps 5 real workflows to the exact ones they call. One hard limit: it doesn't work against GitHub Enterprise Server at all; Claude Code's own docs point GHES users at theghCLI instead.
The command Claude Code 2.1+ actually wants
GitHub's own install guide for Claude Code splits on version. For 2.1.1 and newer, it leads with the add-json form:
claude mcp add-json github '{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":"Bearer YOUR_GITHUB_PAT"}}'
For 2.1.0 or earlier, the older --transport flag syntax is what works:
claude mcp add --transport http github https://api.githubcopilot.com/mcp -H "Authorization: Bearer YOUR_GITHUB_PAT"
I ran both forms for real in a scratch project on Claude Code 2.1.278 (2026-09-21, current at publish) and they write an identical config entry - so if a tutorial you're following shows the older form, it still works, it's just not what GitHub leads with anymore. One older path to actively avoid: the npm package @modelcontextprotocol/server-github that a lot of still-indexed tutorials reference was deprecated in April 2025 in favor of this hosted server - don't npx it into a fresh setup.
Either command defaults to local scope, private to the current project. Add -s user at the end to make GitHub MCP available in every project without re-adding it - the same scope flag any MCP server in Claude Code uses.
Personal access token or Docker: picking an auth path
The remote server above isn't the only way to run GitHub MCP. GitHub also ships the same server as a local Docker image, with a real OAuth login instead of a token you generate yourself:
Remote (add-json, PAT) | Local Docker (OAuth) | Local Docker (PAT) | |
|---|---|---|---|
| Auth | A GitHub PAT you paste in | Browser sign-in on first use | A GitHub PAT you paste in |
| Runs where | GitHub's own infrastructure | A Docker container on your machine | A Docker container on your machine |
| Setup command | claude mcp add-json github '{"type":"http",...}' | claude mcp add github -e GITHUB_OAUTH_CALLBACK_PORT=8085 -- docker run -i --rm -p 127.0.0.1:8085:8085 -e GITHUB_OAUTH_CALLBACK_PORT ghcr.io/github/github-mcp-server | claude mcp add github -e GITHUB_PERSONAL_ACCESS_TOKEN=YOUR_PAT -- docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN ghcr.io/github/github-mcp-server |
| Use it for | github.com, no local process needed | You'd rather sign in than mint a token | GitHub Enterprise Server (GITHUB_HOST env var) |
Unless you're targeting GitHub Enterprise Server (more on that below), the remote PAT path is the right default - it's what GitHub's own docs lead with, and it's the one this guide tests end to end. A classic PAT needs at least the repo scope; fine-grained tokens need the equivalent repository permissions for whatever toolsets you enable. The MCP config generator builds this exact JSON block if you'd rather pick GitHub from a list than type the header by hand.
The gap between added and connected
Add, then confirm what a bad token actually says
claude mcp add-json github '{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":"Bearer <token>"}}'Added http MCP server github to local config
claude mcp listgithub: https://api.githubcopilot.com/mcp (HTTP) - ✘ Failed to connect - Server rejected the configured Authorization header (HTTP 401)
claude mcp get githubIssue: ...unauthorized: AuthenticateToken authentication failed. OAuth fallback is disabled when headers.Authorization is set.
Re-run for real in a scratch project on Claude Code 2.1.278, 2026-09-21, with a placeholder token on purpose: it captures the exact failure text a bad or expired PAT produces, which is what most people connecting this server actually hit first.
GitHub accepting the token is a separate question from Claude Code writing the config, and claude mcp list is the command that tells the two apart - worth running after adding any MCP server, from Playwright's syntax quirks to Sentry's OAuth flow. For this guide I ran the sequence in a scratch project with a placeholder token, on purpose, to see exactly what Claude Code says when GitHub rejects it. claude mcp add-json succeeds no matter what (Added http MCP server github to local config), since it only writes a file. claude mcp list is what actually asks the endpoint, and it came back ✘ Failed to connect - Server rejected the configured Authorization header (HTTP 401). claude mcp get github has the rest of the story: unauthorized: AuthenticateToken authentication failed, plus a line worth remembering - OAuth fallback is disabled when headers.Authorization is set. Once you've told Claude Code to send a specific token, it won't quietly fall back to a browser sign-in if that token turns out to be wrong; the error is all you get. Swap in a real, valid PAT scoped to repo and that same claude mcp list line reads ✓ Connected instead.
What you can do with it: real workflows mapped to real tools
Five workflows, and what they call
PR review
“Read PR #482 in owner/repo and flag anything risky before I approve it.”
pull_request_readadd_comment_to_pending_reviewIssue triage
“List open issues in owner/repo labeled bug, sorted by most recently updated.”
list_issuessearch_issuesCode search
“Find every place owner/repo still calls the old rate-limiter function.”
search_codeCI debugging
“Why did the last Actions run on main fail, and what job broke?”
actions_listget_job_logsMerging
“Once checks are green on PR #482, merge it with a squash commit.”
pull_request_readmerge_pull_requestTool names from github/github-mcp-server's own README, re-checked 2026-09-21.
These five aren't generic "ask Claude about GitHub" prompts - each one calls a specific tool name straight out of the server's own source code, not a guess at what it might be called.
- PR review starts with
pull_request_readfor the diff and description, thenadd_comment_to_pending_reviewto leave inline notes before you submit the review as a whole. - Issue triage splits between
list_issuesfor a straight filtered list andsearch_issueswhen you need GitHub's search syntax (label:bug is:open sort:updated). - Code search (
search_code) is the one people forget exists - it runs against GitHub's real code search index, not a local grep, so it works across repos you haven't even cloned. - CI debugging pairs
actions_list(find the failed run) withget_job_logs, which can return actual log content instead of just a URL if you ask for it. - Merging is deliberately the last step in the chain:
pull_request_readagain to confirm status checks are green, thenmerge_pull_request- Claude won't merge blind if you ask it to check first.
Every toolset it ships, and how many tools are in each
What's behind those 5 workflows
92 tools total
Repositories
20create_branch, search_code, push_files
Issues
10list_issues, search_issues, issue_write
Pull requests
10create_pull_request, merge_pull_request
Notifications
6list_notifications, dismiss_notification
Discussions
5get_discussion, discussion_comment_write
Actions
4actions_list, get_job_logs
Gists
4create_gist, update_gist
Governance & advisories
8create_repository_ruleset, security advisories
Everything else
25context, labels, projects, stargazers, code security...
Hand-counted from github/github-mcp-server's own README, 2026-09-21 - the remote server adds 5 more tools on top of this default set (2 more Copilot tools, Copilot Spaces, and GitHub's support-docs search).
Nowhere in GitHub's install guide does a tool count show up, so I pulled up github/github-mcp-server's own README and counted every one by hand. 92 tools land across 23 toolsets when every one of them is enabled with --toolsets all, but that's not what you get by default: connect without specifying anything and the server starts with just context, repos, issues, pull_requests, and users - 44 tools, less than half. Narrow it further with an allow-list, the same lever context-bloat guidance for any MCP server points at:
docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN -e GITHUB_TOOLSETS="repos,issues,pull_requests,actions,code_security" ghcr.io/github/github-mcp-server
The remote server takes the same idea through the URL instead of an env var - https://api.githubcopilot.com/mcp/x/actions scopes the connection to just the Actions toolset, and a --read-only flag (or X-MCP-Readonly header on the remote server) skips every write tool even if one gets explicitly requested. Even if you never touch it: security_advisories, secret_protection, and dependabot are each their own toolset, so a security-focused connection can skip pulling in the other 80-plus tools entirely.
Troubleshooting: the errors you'll actually hit
- 401 on a token that looks right. Covered above, but the short version: check the token hasn't expired, confirm it (or the fine-grained equivalent) carries the
reposcope, and remember Claude Code won't retry with OAuth once a header is set - fix the token and re-runadd-json. - Rate limits. A personal access token is capped at GitHub's standard 5,000 REST requests per hour, plus a secondary limit of roughly 900 points per minute to any single endpoint -
search_codeandsearch_issuesburn through that faster than single-resource reads, so a session doing heavy code search across a big org can hit it before an hour of normal use would. - It silently doesn't do what GHES needs. This is the one page 1 for this query buries in an unrelated admin page: GitHub's own README says the remote server (the
add-jsoncommand this guide leads with) doesn't support GitHub Enterprise Server at all. The local Docker server does, viaGITHUB_HOST=https://your-ghes-domain.exampleon the samedocker runcommand - but Claude Code's own GitHub Enterprise Server documentation currently skips GitHub MCP as an option entirely and tells GHES users to authenticate theghCLI instead. If you're on GHES, budget time to test the local Docker path yourself before assuming the setup above will just work.
Where a narrower tool already wins
If most of what you ask for is "open a PR" or "check out this branch," the gh CLI Claude Code already shells out to does the same job with zero extra tools loaded into context - GitHub MCP's real advantage is structured reads (a specific PR's review state, a filtered issue search, actual Actions log content) that would otherwise mean you copying text out of a browser tab. And every connected MCP server sends its full tool list into context on every turn it's active; the broader cost of that tradeoff is worth reading before you enable --toolsets all for a server this size when a narrower allow-list would do. On GitHub Enterprise Server, per the troubleshooting section above, skip this server for now and let Claude use gh directly.
FAQ
What's the exact command to connect GitHub MCP to Claude Code?
On Claude Code 2.1.1 and newer, claude mcp add-json github '{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":"Bearer <token>"}}' connects the official remote server over a GitHub personal access token - GitHub's own install guide leads with this form now. On 2.1.0 or earlier, use the older claude mcp add --transport http github https://api.githubcopilot.com/mcp -H "Authorization: Bearer <token>" syntax instead; both were tested for this guide on 2.1.278 and produce the identical result.
Does GitHub MCP need a personal access token, or does it support OAuth?
The remote HTTP server (the command above) authenticates with a GitHub personal access token you generate and pass as a Bearer header - there's no browser sign-in step. OAuth is only available through the local Docker server: claude mcp add github -e GITHUB_OAUTH_CALLBACK_PORT=8085 -- docker run -i --rm -p 127.0.0.1:8085:8085 -e GITHUB_OAUTH_CALLBACK_PORT ghcr.io/github/github-mcp-server opens a browser login on first use instead of asking for a token.
How many tools does GitHub MCP actually expose?
92 across 23 toolsets when every toolset is enabled, hand-counted from github/github-mcp-server's own README (2026-09-21) - repos alone accounts for 20, issues and pull requests 10 each. Connect without specifying --toolsets and you get the much smaller default set instead: just context, repos, issues, pull_requests, and users, 44 tools combined. The remote server adds 5 more tools on top of the 92, exclusive to it.
Why did my claude mcp list show a 401 even though my token looks right?
Tested for this guide: adding the server with any Authorization header at all, even a syntactically valid one, disables Claude Code's OAuth fallback, so a rejected token surfaces immediately as unauthorized: AuthenticateToken authentication failed instead of falling back to a sign-in prompt. Regenerate the PAT (classic PATs need at minimum the repo scope), confirm it hasn't expired, and re-run the add-json command with the new value.
Does GitHub MCP work with GitHub Enterprise Server?
Not the remote server - GitHub's own README says GitHub Enterprise Server doesn't support remote server hosting at all. The local Docker server does support it, via GITHUB_HOST=https://your-ghes-domain on the same docker run command used for github.com. Claude Code's own GitHub Enterprise Server docs currently skip GitHub MCP entirely though, and tell GHES users to authenticate the gh CLI instead.
The token is the only step that isn't automatic
Past that, everything here is just Claude reading and writing GitHub the way you already would through the UI, minus the tab-switching. Which server you connect first matters less than what you do with it afterward - the connector list ClockedCode actually vets, plus the tuned CLAUDE.md that ships alongside it, is where the rest of that setup happens.