An MCP (Model Context Protocol) server that gives Claude access to one or more GitHub repositories — including private ones — directly from Claude Desktop or Claude Code.
Repositories are managed dynamically at runtime: just tell Claude to add or remove a repo and it's persisted immediately, with no config file editing required.
- Node.js 18 or later
- A GitHub Personal Access Token
npm install
npm run build- Go to GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
- Click Generate new token (classic)
- Give it a name (e.g.
claude-mcp) - Select the
reposcope (covers both public and private repositories) - Click Generate token and copy it
If you only need public repos, the
public_reposcope is sufficient.
Edit the config file at:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
Add this block inside "mcpServers":
{
"mcpServers": {
"github-context": {
"command": "node",
"args": ["path_to_repo/dist/index.js"],
"env": {
"GITHUB_TOKEN": "ghp_your_token_here"
}
}
}
}That's it — no repo list needed here. Restart Claude Desktop after saving.
Repos are managed through Claude itself at runtime. The list is stored in dist/repos.json and persists across sessions.
"Add the repo myorg/backend to GitHub context"
Claude calls add_repo → verifies the repo is accessible with your token → saves it to repos.json.
"Remove myorg/old-project from GitHub context"
Claude calls remove_repo → updates repos.json.
"What repos do you have access to?"
Claude calls list_repos → shows everything currently saved.
Changes take effect immediately — no restart needed.
| Tool | Description |
|---|---|
list_repos |
Show all saved repositories |
add_repo |
Add a repo (verifies access before saving) |
remove_repo |
Remove a repo from the list |
| Tool | Description |
|---|---|
get_repo_info |
Metadata: description, language, stars, default branch, visibility |
list_files |
Browse files and directories at any path |
get_file |
Read the full content of any file |
search_code |
Search code across a repo (GitHub search API) |
get_commits |
Recent commit history, optionally filtered by branch or file path |
get_branches |
List all branches (protected branches are marked) |
get_pull_requests |
List open, closed, or all pull requests |
get_issues |
List open, closed, or all issues |
repo—"owner/repo"format, must be in the saved listbranch— branch name, tag, or commit SHA (defaults to the repo's default branch)path— file or directory path inside the repomax_results— how many items to returnstate—"open","closed", or"all"(for PRs and issues)
Add the repo myorg/backend to GitHub context.
List all the files in the src/ directory of myorg/backend.
Read the file src/auth/middleware.ts from myorg/backend.
Search for "function authenticate" in myorg/backend.
Show me the last 10 commits on the main branch of myorg/frontend.
What open issues are there in myorg/backend?
Remove myorg/old-project from GitHub context.
By default repos are stored at dist/repos.json next to the built script. To use a custom path, set the REPOS_FILE env var in your Claude Desktop config:
"env": {
"GITHUB_TOKEN": "ghp_your_token_here",
"REPOS_FILE": "localpath/.config/github-mcp/repos.json"
}This is useful if you want the repo list to survive rebuilds or to share it across multiple projects.
Run without building (useful for local testing):
GITHUB_TOKEN=ghp_... npm run devRecompile after making source changes:
npm run buildThen restart Claude Desktop.
├── src/
│ └── index.ts # MCP server — all tools, repo persistence logic
├── dist/ # Compiled output (generated by npm run build)
│ ├── index.js
│ └── repos.json # Persisted repo list (auto-created on first add_repo)
├── package.json
├── tsconfig.json
├── .env.example
└── claude-desktop-config.example.json
- Your GitHub token is passed via environment variable and never logged or sent to Claude.
- Only repos explicitly added via
add_repoare accessible — Claude cannot reach other repos even if your token has broader access. add_repoverifies the repo exists and is accessible with your token before saving it.- File content is truncated at 100,000 characters to prevent context overflow.