pr-agent-mcp
by kkmeteor
README.md
**English** | **[中文](README.zh-CN.md)**
# PR-Agent MCP Server
A MCP (Model Context Protocol) server that exposes [pr-agent](https://github.com/Codium-ai/pr-agent) CLI commands as MCP tools, with optional Gitea webhook integration for automatic PR review. Supports both SSE and StreamableHTTP transports, and can run locally or in Docker.
## Features
- **MCP Tools**: Expose pr-agent commands (`review`, `describe`, `improve`, `ask`, `reflect`, `update_changelog`, `generate_labels`) as MCP tools.
- **Transports**: SSE (`/sse`) and StreamableHTTP (`/mcp`), selectable via `--transport sse|streamable-http|both`.
- **Gitea Webhook**: Automatically trigger review, describe, and improve actions when a new PR is opened in Gitea.
- **HMAC Signature Verification**: Optional webhook signature validation for security.
- **Config Injection**: Automatically loads credentials from `~/.secrets.toml` and injects them into the pr-agent subprocess environment.
## Project Structure
```
pr-agent-mcp/
├── server.py # Main MCP server and webhook handler
├── run.ps1 # PowerShell startup script (local run)
├── requirements.txt # Python dependencies
├── Dockerfile # Multi-stage Docker image definition
├── docker-compose.yml # Docker Compose service definition
├── push.ps1 # Build & push image to registry
├── .dockerignore # Exclude files from Docker build context
├── buggy_samples.py # Intentional bug samples for pr-agent testing
├── test.http # HTTP test requests (VS Code REST Client / similar)
├── README.md
├── README.zh-CN.md
└── .gitignore
```
## Prerequisites
- **Docker** with Docker Compose (recommended) **or** Python 3.11+ (uses `tomllib`)
- Gitea instance (for webhook integration, optional)
- `~/.secrets.toml` with your provider credentials (see below)
## Configure credentials
Create `~/.secrets.toml` in your user home directory with your provider and LLM credentials:
```toml
[gitea]
url = "http://your-gitea-instance:3000"
token = "your-gitea-personal-access-token"
[openai]
key = "sk-your-openai-api-key"
```
> `SECRETS_TOML_PATH` environment variable overrides the default location (`~/.secrets.toml`). This is used by the Docker image to locate the bind-mounted file.
---
## Docker Deployment (recommended)
### 1. Build and start locally
```powershell
docker compose up -d --build
```
This will:
1. Build the image (multi-stage: installs `pr-agent` and `mcp` dependencies into a venv, installs `git` at runtime).
2. Mount your home directory read-only into the container at `/host-home` so it can read `~/.secrets.toml`.
3. Map host port `9000` to container port `9000`.
4. Start the server with both SSE and StreamableHTTP transports.
> The container mounts `${USERPROFILE}` (the whole home directory) instead of the single `.secrets.toml` file. Mounting a non-existent host file makes Docker create a directory instead, causing `IsADirectoryError` — mounting the parent directory avoids this pitfall.
### 2. Push image to a private registry
```powershell
# Build + tag + push to the default registry (10.10.11.194:1000/pr-agent-mcp:latest)
.\push.ps1
# Push to another registry / with a version tag / skip rebuild
.\push.ps1 -Registry "192.168.1.100:5000" -Tag "v1.0.0" -NoBuild
```
### 3. Run on another machine (e.g. a test server)
Copy `docker-compose.yml` to the target machine and change `build: .` to `image: 10.10.11.194:1000/pr-agent-mcp:latest`, then:
```powershell
docker pull 10.10.11.194:1000/pr-agent-mcp:latest
docker compose up -d
```
Or run directly without a compose file:
```powershell
docker run -d \
--name pr-agent-mcp \
-p 9000:9000 \
-v $env:USERPROFILE:/host-home:ro \
-e SECRETS_TOML_PATH=/host-home/.secrets.toml \
--restart unless-stopped \
10.10.11.194:1000/pr-agent-mcp:latest
```
### Manage the container
```powershell
# View logs
docker compose logs -f
# Stop & remove
docker compose down
# Restart
docker compose restart
```
---
## Local Run (without Docker)
### 1. Install dependencies
```powershell
python -m venv mcp_env
mcp_env\Scripts\activate
pip install -r requirements.txt
```
> `requirements.txt` only contains `mcp` (the MCP framework). **pr-agent is NOT a Python dependency of this server** — it is called as a subprocess via the path configured in `server.py` (or the `PR_AGENT_EXE` environment variable). Make sure pr-agent is already installed somewhere on the machine.
### 2. (Optional) Configure webhook secret
Set `WEBHOOK_SECRET` in `server.py` to the same secret configured in your Gitea webhook settings. Leave it empty to disable signature verification (not recommended for production).
### 3. Start the server
```powershell
.\run.ps1
```
Or directly:
```powershell
python server.py
python server.py --transport sse # SSE only
python server.py --transport streamable-http # StreamableHTTP only
```
## Endpoints
| Endpoint | Method | Description |
|--------------|--------|--------------------------------------------------|
| `/sse` | GET | MCP SSE connection endpoint for AI clients |
| `/mcp` | POST | MCP StreamableHTTP endpoint |
| `/messages/` | POST | MCP message transport (SSE mode) |
| `/webhook` | POST | Gitea webhook receiver for auto PR review |
## MCP Tools
| Tool | Description |
|--------------------|----------------------------------------------------------------|
| `review_pr` | Review a PR: summary and specific suggestions |
| `describe_pr` | Generate or update PR title and description |
| `improve_code` | Suggest code improvements as PR comments |
| `ask_question` | Ask a question about the PR |
| `reflect` | Ask the PR author questions about the PR |
| `update_changelog` | Update the changelog based on PR contents |
| `generate_labels` | Generate labels for the PR |
## Gitea Webhook Setup
1. In your Gitea repository, go to **Settings → Webhooks → Add Webhook**.
2. Set the target URL to `http://<your-server>:9000/webhook`.
3. Set the HTTP method to `POST` and content type to `application/json`.
4. Optionally set a secret (must match `WEBHOOK_SECRET` in `server.py`).
5. Select the **Pull Request** event with the **Opened** action.
When a PR is opened, the server will automatically run `review`, `describe`, and `improve` actions and post results as PR comments.
## Testing
Use the included `test.http` file with VS Code REST Client or a similar HTTP client to manually test the webhook endpoint.
`buggy_samples.py` contains intentional bugs across multiple categories (security, logic, concurrency, error handling) for testing pr-agent's code review detection capabilities.
## License
Private — internal use only.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues