github-pr-review
README.md
# GitHub PR Review MCP Server
> An MCP server that gives any LLM client the ability to list, read, review, and comment on GitHub pull requests — turning your AI assistant into a fully capable code reviewer.
---
## Overview
This server wraps the GitHub REST API using [FastMCP](https://gofastmcp.com), exposing pull request operations as tools any MCP-compatible client can call. Connect it to Claude Desktop and you can ask Claude to review your open PRs, read diffs, post inline comments, approve, or request changes — all without leaving your conversation.
The server maintains a single authenticated `httpx` client across its lifetime, initialised on startup and shared across all tool calls via FastMCP's lifespan context.
---
## Tools
| Tool | Description |
|---|---|
| `list_open_prs` | List all open PRs with author, title, draft status, and URL |
| `get_pr_diff` | Get file changes and unified diffs for a specific PR |
| `get_pr_comments` | Get all existing review comments on a PR |
| `post_review_comment` | Post an inline comment on a specific file and line |
| `approve_pr` | Approve a PR with an optional review message |
| `request_changes` | Request changes on a PR with a review message |
> **Note:** `approve_pr` and `request_changes` require the authenticated user to be different from the PR author. GitHub does not permit self-review.
---
## Project Structure
```
github-pr-mcp/
├── server.py # FastMCP instance, lifespan, tool registration
├── config.py # Environment variables and constants
├── tools/
│ ├── __init__.py
│ ├── prs.py # list_open_prs, get_pr_diff
│ └── reviews.py # get_pr_comments, post_review_comment, approve_pr, request_changes
├── .env # Your secrets (never committed)
├── .env.example # Template
├── requirements.txt
├── Dockerfile
└── README.md
```
---
## Requirements
- Python 3.11+
- [uv](https://docs.astral.sh/uv/getting-started/installation/)
- A GitHub Personal Access Token with `repo` scope
---
## Setup
**1. Clone the repository:**
```bash
git clone https://github.com/Festuskipkoech/github-pr-mcp.git
cd github-pr-mcp
```
**2. Install dependencies:**
```bash
uv sync
```
**3. Configure your environment:**
```bash
cp .env.example .env
```
Edit `.env` and fill in your values:
```
GITHUB_TOKEN=your_personal_access_token
GITHUB_OWNER=your_github_username
GITHUB_REPO=your_repository_name
```
Generate a token at **GitHub Settings → Developer Settings → Personal Access Tokens**. Enable full `repo` scope for read and write access.
---
## Running Locally
```bash
uv run python server.py
```
Or with the FastMCP CLI on Streamable HTTP transport:
```bash
fastmcp run server.py:mcp --transport streamable-http
```
---
## Testing with MCP Inspector
Start the server in one terminal:
```bash
fastmcp run server.py:mcp --transport streamable-http
```
Launch the Inspector in a second terminal:
```bash
npx -y @modelcontextprotocol/inspector
```
In the Inspector UI:
- **Transport:** Streamable HTTP
- **URL:** `http://127.0.0.1:8000/mcp`
- Click **Connect**
**Recommended test sequence:**
| Step | Tool | Input |
|---|---|---|
| 1 | `list_open_prs` | _(no arguments)_ |
| 2 | `get_pr_diff` | `{"pr_number": 1}` |
| 3 | `get_pr_comments` | `{"pr_number": 1}` |
| 4 | `post_review_comment` | `{"pr_number": 1, "body": "Looks good", "path": "file.py", "line": 1}` |
---
## Using with Claude Desktop
Add the following to `~/.config/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"github-pr-review": {
"command": "/home/your-user/.local/bin/uv",
"args": [
"run",
"--directory",
"/absolute/path/to/github-pr-mcp",
"python",
"server.py"
]
}
}
}
```
Use the full path to `uv` (find it with `which uv`). Credentials are read from the `.env` file automatically — no need to pass them in the config.
Restart Claude Desktop, then try:
```
List all open pull requests in my repo and show me the diff for PR number 1
```
Claude calls `list_open_prs` and `get_pr_diff` and returns structured results:

Full PR diff and file changes returned inline:

---
## Running with Docker
```bash
docker build -t github-pr-mcp .
docker run --env-file .env -p 8000:8000 github-pr-mcp
```
For Streamable HTTP transport, update `server.py` to run with:
```python
mcp.run(transport="streamable-http", host="0.0.0.0", port=8000)
```
---
## Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| `401 Unauthorized` | Invalid or expired token | Regenerate PAT on GitHub |
| `403 Forbidden` | Token lacks write scope | Enable full `repo` scope on your PAT |
| `404 Not Found` | Wrong owner or repo name | Check `.env` — use just the repo name, not the full URL |
| `422 Unprocessable` on approve | Self-review attempt | GitHub blocks approving your own PRs by design |TDQS
A3.6/5.0
Scored across 6 tools
Disambiguation5/5
Each tool has a clearly distinct purpose: listing PRs, getting diffs, getting comments, posting inline comments, approving, and requesting changes. No overlap in functionality.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern with underscores (e.g., approve_pr, get_pr_diff), making them predictable and easy to distinguish.
Tool Count5/5
Six tools is an ideal size for a focused PR review server, covering the essential actions without being overwhelming or sparse.
Completeness4/5
The set covers the core PR review workflow (list, diff, comments, approve, request changes) but lacks features like merging or dismissing reviews, which are minor gaps given the server's specific scope.
Maintenance
ActivityStale
ResponsivenessNo issues