GitHub MCP Server
by maycwu
README.md
# GitHub MCP Server
A Model Context Protocol (MCP) server that connects Claude to your GitHub repositories. Query repos, review PRs, manage issues, search code, and automate GitHub workflows—all from Claude.
## Features
### Included Tools
- **list_repos** — List your repositories with metadata (stars, language, etc.)
- **read_file** — Read files from any repo (source code, docs, configs)
- **list_prs** — Fetch pull requests with filtering (open/closed/all)
- **get_pr** — Get PR details including full diff for code review
- **list_issues** — Search and filter issues by state, labels, etc.
- **create_issue** — File new issues programmatically
- **add_pr_comment** — Add review comments to pull requests
- **search_code** — Search code across repos using GitHub search syntax
- **get_repo_info** — Fetch repo metadata (description, stars, topics, etc.)
## Quick Start
### 1. Set Up Authentication
Create a GitHub Personal Access Token:
1. Go to [github.com/settings/personal-access-tokens](https://github.com/settings/personal-access-tokens)
2. Click **Generate new token** → **Generate new token (fine-grained)**
3. Name it `claude-mcp`
4. Under **Repository access**, select **All repositories** or specific repos
5. Under **Permissions**, grant:
- **Contents**: Read-only
- **Issues**: Read & write (if you want to create issues)
- **Pull requests**: Read & write (if you want to comment on PRs)
6. Click **Generate token** and copy it
### 2. Install Dependencies
```bash
cd /Users/maywu/Projects/github-mcp-server
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
### 3. Set Your GitHub Token
```bash
cp .env.example .env
# Edit .env and paste your token:
# GITHUB_TOKEN=ghp_xxxxx
```
Or set it directly:
```bash
export GITHUB_TOKEN="your_github_pat_here"
```
### 4. Connect to Claude Code
```bash
# From the project root:
claude mcp add --env GITHUB_TOKEN="your_github_pat_here" \
--transport stdio github \
-- python server.py
```
Verify it connected:
```bash
claude mcp list
```
You should see: `✓ github — 9 tools`
## Usage
Once connected, you can ask Claude to:
```
List my repositories
```
```
Review PR #456 and suggest improvements for anthropic/claude-code
```
```
Create an issue for the bug we just found in my-repo
```
```
Find all instances of TODO comments in my codebase
```
```
Read the CONTRIBUTING.md from owner/repo
```
```
List all open issues labeled 'bug' and 'critical' in my-org/my-repo
```
## Local Development & Testing
### Run the server directly (for debugging)
```bash
export GITHUB_TOKEN="your_token"
python server.py
```
You should see:
```
INFO:mcp.server:Started MCP server
```
If there are errors, you'll see them here.
### Test a tool manually
Once connected to Claude Code, run:
```bash
claude
```
Then in the session:
```
Use the github server to list my repos and show me the 5 most recently updated ones
```
Claude will call the `list_repos` tool and display results.
### Common Issues
**"Error: GITHUB_TOKEN environment variable not set"**
- Make sure your token is exported: `echo $GITHUB_TOKEN`
- If using Claude, pass it with `--env`: `claude mcp add --env GITHUB_TOKEN="token" ...`
**"Error: Unauthorized (401)"**
- Your token may have expired or insufficient permissions
- Generate a new token at github.com/settings/personal-access-tokens
- Check that the token has Contents and Issues scopes enabled
**"Timeout connecting to server"**
- The server may be crashing on startup. Run it directly to see errors: `python server.py`
- Try increasing the timeout: `MCP_TIMEOUT=60000 claude`
## Architecture
### Server Structure
```
server.py
├── list_tools() — Define all available tools
├── call_tool() — Route tool calls to handlers
└── _<tool_name>() — Handler for each tool (async)
```
### Adding New Tools
To add a new GitHub operation:
1. Add the tool definition in `list_tools()`:
```python
Tool(
name="my_new_tool",
description="What this tool does",
inputSchema={
"type": "object",
"properties": {...},
"required": [...]
}
)
```
2. Add a handler function:
```python
async def _my_new_tool(arguments: dict) -> list[ToolResult]:
# Your implementation here
return [ToolResult(content=[TextContent(text="result")])]
```
3. Add a route in `call_tool()`:
```python
elif name == "my_new_tool":
return await _my_new_tool(arguments)
```
## GitHub API Limits
- **Authenticated requests**: 5,000/hour
- **Unauthenticated**: 60/hour
This server always uses your token, so you get the 5,000/hour limit.
## Security
- Never commit your `.env` file or tokens to version control
- Use fine-grained personal access tokens (not classic tokens)
- Scope tokens to minimal required permissions
- Rotate tokens regularly
- If a token is leaked, revoke it immediately at github.com/settings/personal-access-tokens
## Troubleshooting
### Check server status
```bash
claude mcp list
```
Should show:
```
github (stdio)
✓ Connected
9 tools available
```
### View server logs
If running in Claude Code, check the MCP logs:
```bash
claude mcp logs github
```
### Test the API directly
```bash
curl -H "Authorization: Bearer $GITHUB_TOKEN" \
https://api.github.com/user/repos
```
## Next Steps
- **Share with teammates**: Commit `.env.example` and `server.py` to a project repo, have teammates set their own `GITHUB_TOKEN`
- **Deploy as a service**: Run on a server and use `--transport http` instead of `stdio`
- **Add more tools**: Extend with webhooks, actions, releases, discussions, etc.
- **Integrate with workflows**: Build Claude-assisted code review, release notes generation, or issue triage
## Resources
- [MCP Documentation](https://modelcontextprotocol.io)
- [GitHub API Docs](https://docs.github.com/en/rest)
- [Claude Code MCP Setup](https://code.claude.com/docs)
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues