mcp-diff-system
by geek-o-geek
README.md
# mcp-diff-system
An MCP server that fetches, summarizes and reviews GitHub code diffs — built
with **FastMCP** and deployed on **AWS Fargate**, with an SQS worker plane so
that LLM calls never block the request/response cycle.
Built in phases. Each phase is tagged, runs on its own, and ends with something
demonstrable. See [ROADMAP.md](ROADMAP.md) for the full plan and
[docs/diagrams](docs/diagrams) for the target architecture.
> **Current phase: 1 — walking skeleton.**
> One tool, `get_diff`, hitting the real GitHub API. No auth, no AWS, no LLM.
---
## The core design decision
A large diff takes 30–90 seconds to summarize. ALB idle timeouts — and MCP
client patience — are both shorter than that.
So the summarize/review tools (Phase 3) don't call the LLM inline. They persist
the diff, enqueue a job, and return a `job_id` in ~50ms. A separate worker tier,
autoscaled on queue depth, does the slow work. One large diff can then never
hold a connection open or starve capacity for anyone else.
`get_diff` stays synchronous, because a GitHub API call is a fast network round
trip and the async job machinery would be overhead for no benefit.
---
## Phase 1: running it
Requires Python 3.11+.
```bash
pip install -e ".[dev]"
cp .env.example .env # optionally add a GitHub token
```
A token is optional for public repos, but without one GitHub allows only 60
requests/hour instead of 5000. You will hit that.
Start the server:
```bash
python -m src.api.server # HTTP transport on :8000
```
Or poke at the tools interactively:
```bash
fastmcp dev src/api/server.py # opens MCP Inspector
```
Then call `get_diff` with, say, `repo=psf/requests`, `base=v2.31.0`,
`head=v2.32.0`.
### Connecting Claude Desktop
```json
{
"mcpServers": {
"diff": {
"command": "python",
"args": ["-m", "src.api.server"],
"cwd": "/absolute/path/to/mcp-diff-system"
}
}
}
```
### Tests
```bash
pytest
ruff check src tests
```
---
## Two things about GitHub's diff API
Both are easy to get wrong, and both are pinned by tests in
`tests/test_github_client.py`:
1. **The diff media type goes in the `Accept` header, not a query parameter.**
Send `Accept: application/vnd.github.diff`. Get this wrong and GitHub
quietly returns JSON instead of a diff — no error, just garbage flowing
downstream.
2. **Rate limiting is a 403, not a 429.** The signal is
`x-ratelimit-remaining: 0`. Keying off that header beats string-matching the
response body.
---
## Roadmap
| Phase | Adds | Status |
|-------|------|--------|
| 0 | Repo skeleton, CI, lint, tests | Done |
| 1 | FastMCP server, `get_diff` | Done |
| 2 | S3 + DynamoDB + SQS job plane (stub worker, no LLM) | Next |
| 3 | Diff chunker + Anthropic client — real summaries | |
| 4 | Circuit breakers, retries, DLQ, idempotent claim | |
| 5 | JWT auth, atomic Redis rate limiting, payload guard | |
| 6 | Correlation IDs, CloudWatch metrics, X-Ray | |
| 7 | Terraform, dual ECS services, autoscaling, OIDC CI/CD | |
## License
MIT
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues