dshills/mcp-pr
If you are the rightful owner of mcp-pr and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
The MCP Code Review Server is an intelligent code review tool that leverages AI to analyze code for potential issues, providing developers with insights and suggestions for improvement.
MCP Code Review Server
An intelligent code review server implementing the Model Context Protocol (MCP) that provides AI-powered code analysis using Anthropic Claude, OpenAI GPT, or Google Gemini.
Quick Start
# Install
go build -o mcp-code-review ./cmd/mcp-code-review
# Set API key (choose one or more)
export ANTHROPIC_API_KEY="your-anthropic-key"
export OPENAI_API_KEY="your-openai-key"
export GOOGLE_API_KEY="your-google-key"
# Run (MCP server mode)
./mcp-code-review
The server runs as an MCP subprocess, waiting for JSON-RPC requests over stdio.
Table of Contents
- Installation
- Configuration
- Usage
- Tool Reference
- Response Format
- Examples
- Development
- Architecture
- Troubleshooting
Installation
Prerequisites
- Go 1.24+: Download Go
- Git: Required for git-based reviews
- API Keys: At least one LLM provider API key
Build from Source
# Clone repository
git clone https://github.com/dshills/mcp-pr.git
cd mcp-pr
# Build binary
go build -o mcp-code-review ./cmd/mcp-code-review
# Verify build
./mcp-code-review --version # (if version flag supported)
Install to GOPATH
go install github.com/dshills/mcp-pr/cmd/mcp-code-review@latest
The binary will be available at $GOPATH/bin/mcp-code-review.
Configuration
Required: API Keys
Set at least one provider API key as an environment variable:
# Anthropic Claude (recommended)
export ANTHROPIC_API_KEY="sk-ant-..."
# OpenAI GPT
export OPENAI_API_KEY="sk-..."
# Google Gemini
export GOOGLE_API_KEY="..."
Optional: Environment Variables
# Logging
export MCP_PR_LOG_LEVEL=info # debug|info|warn|error (default: info)
# Provider selection
export MCP_PR_DEFAULT_PROVIDER=anthropic # anthropic|openai|google (default: anthropic)
# Timeouts (increased defaults for reliability)
export MCP_PR_REVIEW_TIMEOUT=120s # Overall review timeout (default: 120s)
export ANTHROPIC_TIMEOUT=90s # Anthropic API timeout (default: 90s)
export OPENAI_TIMEOUT=90s # OpenAI API timeout (default: 90s)
export GOOGLE_TIMEOUT=90s # Google API timeout (default: 90s)
# Diff size limits
export MCP_PR_MAX_DIFF_SIZE=10000 # Max diff size in bytes (default: 10000)
MCP Client Configuration
If using Claude Desktop or another MCP client, add this server to your configuration:
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"code-review": {
"command": "/path/to/mcp-code-review",
"env": {
"ANTHROPIC_API_KEY": "your-key-here"
}
}
}
}
Migration from v0.x
Environment Variable Updates: In recent versions, we renamed environment variables to be project-specific to avoid conflicts with other MCP servers.
Variable Name Changes
| Old Name (Deprecated) | New Name | Status |
|---|---|---|
MCP_LOG_LEVEL | MCP_PR_LOG_LEVEL | ⚠️ Deprecated, will be removed in v1.0.0 |
MCP_DEFAULT_PROVIDER | MCP_PR_DEFAULT_PROVIDER | ⚠️ Deprecated, will be removed in v1.0.0 |
MCP_REVIEW_TIMEOUT | MCP_PR_REVIEW_TIMEOUT | ⚠️ Deprecated, will be removed in v1.0.0 |
MCP_MAX_DIFF_SIZE | MCP_PR_MAX_DIFF_SIZE | ⚠️ Deprecated, will be removed in v1.0.0 |
What You Need to Do
If you're upgrading from v0.x:
- Update your environment variable names from
MCP_*toMCP_PR_* - Old names still work but will log deprecation warnings
- New names take precedence if both are set
What Stays the Same:
- ✅ API key variables remain unchanged:
ANTHROPIC_API_KEY,OPENAI_API_KEY,GOOGLE_API_KEY - ✅ Provider-specific timeouts remain unchanged:
ANTHROPIC_TIMEOUT,OPENAI_TIMEOUT,GOOGLE_TIMEOUT
Example Migration:
# Old configuration (still works with warnings)
export MCP_LOG_LEVEL=info
export MCP_DEFAULT_PROVIDER=anthropic
# New configuration (recommended)
export MCP_PR_LOG_LEVEL=info
export MCP_PR_DEFAULT_PROVIDER=anthropic
Usage
The MCP server provides 4 tools for different code review workflows. Below are examples from simplest to most advanced.
Simple: Review Code Snippet
Review any code snippet without git dependency.
Tool: review_code
Example MCP Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "review_code",
"arguments": {
"code": "func divide(a, b int) int {\n return a / b\n}",
"language": "go"
}
}
}
Minimal Arguments:
code(required): Code to reviewlanguage(optional): Programming language hint (e.g., "go", "python", "javascript")
Optional Arguments:
provider: Choose LLM ("anthropic","openai","google")review_depth:"quick"or"thorough"(default:"quick")focus_areas: Array like["security", "performance"]
Example Response:
{
"findings": [
{
"category": "bug",
"severity": "critical",
"line": 2,
"description": "Division by zero possible when b=0",
"suggestion": "Add check: if b == 0 { return 0 } or return error"
}
],
"summary": "Found 1 critical issue: potential division by zero",
"provider": "anthropic",
"duration_ms": 1234,
"metadata": {
"source_type": "arbitrary",
"model": "claude-3-7-sonnet-20250219"
}
}
Git: Review Staged Changes
Review code staged for commit (pre-commit workflow).
Tool: review_staged
Use Case: Run before git commit to catch issues early.
Example Request:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "review_staged",
"arguments": {
"repository_path": "/path/to/your/repo"
}
}
}
Arguments:
repository_path(required): Absolute path to git repositoryprovider(optional): LLM provider to usereview_depth(optional):"quick"or"thorough"
What It Reviews: Output of git diff --staged (all staged changes)
Example Workflow:
# Make changes
echo "new code" >> main.go
# Stage changes
git add main.go
# Review via MCP client (e.g., Claude Desktop)
# Tool: review_staged
# Args: { "repository_path": "/Users/me/myproject" }
# If review passes, commit
git commit -m "Add feature"
Git: Review Unstaged Changes
Review working directory changes before staging (WIP feedback).
Tool: review_unstaged
Use Case: Get feedback on work-in-progress before staging.
Example Request:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "review_unstaged",
"arguments": {
"repository_path": "/path/to/your/repo",
"review_depth": "quick"
}
}
}
Arguments: Same as review_staged
What It Reviews: Output of git diff (unstaged changes in working directory)
Example Workflow:
# Make changes (don't stage yet)
vim server.go
# Get quick feedback via MCP
# Tool: review_unstaged
# Args: { "repository_path": "/Users/me/myproject" }
# Fix issues, then stage
git add server.go
Git: Review Specific Commit
Review a historical commit for audit or learning.
Tool: review_commit
Use Case: Understand what changed in a past commit, audit for security issues.
Example Request:
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "review_commit",
"arguments": {
"repository_path": "/path/to/your/repo",
"commit_sha": "a1b2c3d4e5f6",
"provider": "openai",
"review_depth": "thorough"
}
}
}
Arguments:
repository_path(required): Absolute path to git repositorycommit_sha(required): Git commit SHA (full or short)provider(optional): LLM providerreview_depth(optional): Review thoroughness
What It Reviews: Output of git show <commit_sha>
Example Workflow:
# Find suspicious commit
git log --oneline
# Review it via MCP
# Tool: review_commit
# Args: {
# "repository_path": "/Users/me/myproject",
# "commit_sha": "abc123"
# }
# Check for security issues in that commit
Tool Reference
review_code
Review arbitrary code text without git.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
code | string | ✅ | - | Code to review |
language | string | ❌ | auto-detect | Language hint (go, python, js, etc.) |
provider | string | ❌ | env default | anthropic, openai, or google |
review_depth | string | ❌ | quick | quick or thorough |
focus_areas | array | ❌ | all | ["bug", "security", "performance", "style", "best-practice"] |
review_staged
Review git staged changes (git diff --staged).
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
repository_path | string | ✅ | - | Absolute path to git repository |
provider | string | ❌ | env default | anthropic, openai, or google |
review_depth | string | ❌ | quick | quick or thorough |
review_unstaged
Review git unstaged changes (git diff).
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
repository_path | string | ✅ | - | Absolute path to git repository |
provider | string | ❌ | env default | anthropic, openai, or google |
review_depth | string | ❌ | quick | quick or thorough |
review_commit
Review specific commit (git show <sha>).
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
repository_path | string | ✅ | - | Absolute path to git repository |
commit_sha | string | ✅ | - | Git commit SHA (full or short) |
provider | string | ❌ | env default | anthropic, openai, or google |
review_depth | string | ❌ | quick | quick or thorough |
Response Format
All tools return JSON with this structure:
{
findings: Array<{
category: "bug" | "security" | "performance" | "style" | "best-practice",
severity: "critical" | "high" | "medium" | "low" | "info",
line?: number, // Line number (if applicable)
file_path?: string, // File path (for git reviews)
description: string, // What the issue is
suggestion: string, // How to fix it
code_snippet?: string // Relevant code excerpt
}>,
summary: string, // Overall assessment
provider: string, // Which LLM was used
duration_ms: number, // Review duration
metadata: {
source_type: string, // "arbitrary", "staged", "unstaged", "commit"
model: string, // LLM model name
file_count?: number, // Number of files (git reviews)
line_count?: number, // Total lines reviewed
lines_added?: number, // Lines added (git diffs)
lines_removed?: number // Lines removed (git diffs)
}
}
Finding Categories
- bug: Logic errors, crashes, incorrect behavior
- security: Vulnerabilities, injection risks, auth issues
- performance: Inefficiencies, memory leaks, slow algorithms
- style: Code formatting, naming conventions, readability
- best-practice: Design patterns, maintainability, testability
Severity Levels
- critical: Must fix immediately (security hole, crash)
- high: Should fix soon (data loss risk, major bug)
- medium: Fix when convenient (performance issue)
- low: Nice to have (minor style issue)
- info: Informational (suggestion, tip)
Examples
Example 1: Review Python Function
Code:
def fetch_user(user_id):
query = f"SELECT * FROM users WHERE id = {user_id}"
return db.execute(query)
MCP Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "review_code",
"arguments": {
"code": "def fetch_user(user_id):\n query = f\"SELECT * FROM users WHERE id = {user_id}\"\n return db.execute(query)",
"language": "python",
"focus_areas": ["security"]
}
}
}
Expected Findings:
- Security/Critical: SQL injection vulnerability
- Suggestion: Use parameterized queries
Example 2: Pre-Commit Hook Integration
Create a git hook to review staged changes before committing:
.git/hooks/pre-commit:
#!/bin/bash
# Review staged changes via MCP
REPO_PATH=$(git rev-parse --show-toplevel)
# Use MCP client to call review_staged
# (Implementation depends on your MCP client)
# Example with Claude Desktop CLI (if available)
mcp-client call code-review review_staged \
--repository_path "$REPO_PATH" \
--review_depth quick
# Exit with error if critical issues found
if [ $? -ne 0 ]; then
echo "❌ Code review found critical issues. Fix before committing."
exit 1
fi
Make it executable:
chmod +x .git/hooks/pre-commit
Example 3: CI/CD Integration
Review commits in GitHub Actions:
.github/workflows/code-review.yml:
name: AI Code Review
on: [pull_request]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.24'
- name: Install MCP Code Review
run: |
go install github.com/dshills/mcp-pr/cmd/mcp-code-review@latest
- name: Review Pull Request Changes
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
# Get changed files and review them
git diff origin/main...HEAD > changes.diff
# Call MCP server to review
# (Implement MCP client call here)
Development
Build
# Development build
go build -o mcp-code-review ./cmd/mcp-code-review
# Production build with optimizations
go build -ldflags="-s -w" -o mcp-code-review ./cmd/mcp-code-review
Test
# Run all tests
go test ./tests/...
# Run with coverage
go test -cover ./...
# Run specific test suite
go test ./tests/contract/... # Contract tests
go test ./tests/integration/... # Integration tests (requires API keys)
go test ./tests/unit/... # Unit tests
# Verbose output
go test -v ./tests/...
Integration Tests
Integration tests require API keys:
export ANTHROPIC_API_KEY="your-key"
export OPENAI_API_KEY="your-key"
export GOOGLE_API_KEY="your-key"
go test ./tests/integration/... -v
Linting
# Run linter
golangci-lint run ./...
# Fix auto-fixable issues
golangci-lint run --fix ./...
Code Coverage
# Generate coverage report
go test -coverprofile=coverage.out ./...
# View HTML report
go tool cover -html=coverage.out
# Target: ≥80% (per project constitution)
Architecture
Directory Structure
mcp-pr/
├── cmd/
│ └── mcp-code-review/ # Main server entry point
│ └── main.go
├── internal/
│ ├── config/ # Configuration loading
│ │ └── config.go
│ ├── git/ # Git operations
│ │ ├── client.go # Git command wrappers
│ │ └── diff.go # Diff parsing
│ ├── logging/ # Structured logging
│ │ └── logger.go
│ ├── mcp/ # MCP protocol
│ │ ├── server.go # Server initialization
│ │ └── tools.go # Tool handlers
│ ├── providers/ # LLM providers
│ │ ├── provider.go # Provider interface
│ │ ├── anthropic.go # Claude integration
│ │ ├── openai.go # GPT integration
│ │ └── google.go # Gemini integration
│ └── review/ # Review engine
│ ├── engine.go # Review orchestration
│ ├── request.go # Request models
│ └── response.go # Response models
├── tests/
│ ├── contract/ # Contract tests
│ ├── integration/ # Integration tests
│ └── unit/ # Unit tests
└── go.mod
Components
MCP Server (internal/mcp/)
- Implements JSON-RPC 2.0 over stdio
- Registers 4 tools (review_code, review_staged, review_unstaged, review_commit)
- Handles request parsing and response formatting
Review Engine (internal/review/)
- Orchestrates review workflow
- Manages provider selection and failover
- Implements retry logic (1 retry = 2 total attempts)
- Validates diff size limits before sending to LLM
- Populates code from git for git-based reviews
- Progress logging throughout review lifecycle
Git Client (internal/git/)
- Wraps git commands (diff, show, rev-parse) with context-aware timeouts
- 30s timeout for diff operations (prevents hanging on slow filesystems)
- 10s timeout for validation operations
- Parses unified diff format
- Extracts file paths, line numbers, and changes
Providers (internal/providers/)
- Common interface:
Review(ctx, Request) (*Response, error) - Anthropic: Claude 3.7 Sonnet
- OpenAI: GPT-4o
- Google: Gemini (deprecated SDK, may require migration)
Troubleshooting
"No API key found"
Problem: Server exits with "at least one provider API key required"
Solution: Set at least one API key:
export ANTHROPIC_API_KEY="sk-ant-..."
"Not a git repository"
Problem: Git tools fail with "fatal: not a git directory"
Solution: Ensure repository_path points to a valid git repository:
# Check if directory is a git repo
cd /path/to/repo
git rev-parse --git-dir # Should output .git
# If not, initialize it
git init
"Provider timeout" or "Operation timed out"
Problem: Review fails with timeout error after 90-120 seconds
Solution: The server now has improved timeout handling with these defaults:
- Provider API timeouts: 90s (up from 30s)
- Git operation timeouts: 30s (prevents hanging on slow filesystems)
- Overall review timeout: 120s (up from 30s)
If you still experience timeouts, you can increase them:
# Increase provider timeout to 180s
export ANTHROPIC_TIMEOUT=180s
export OPENAI_TIMEOUT=180s
export GOOGLE_TIMEOUT=180s
# Or increase overall review timeout
export MCP_REVIEW_TIMEOUT=300s
Alternative solutions:
- Use
quickreview depth for faster responses (default) - Review smaller diffs (break large changes into smaller commits)
- Increase
MCP_MAX_DIFF_SIZEif hitting size limits:export MCP_MAX_DIFF_SIZE=50000 # Increase from default 10000 bytes
Note: Git operations (diff, show) now have built-in 30s timeouts to prevent indefinite hangs on network filesystems or large repositories.
"Diff size exceeds maximum allowed size"
Problem: Review fails with "diff size (X bytes) exceeds maximum allowed size (10000 bytes)"
Solution: This is a safety limit to prevent timeouts on very large diffs. You have three options:
-
Increase the limit (recommended for legitimate large diffs):
export MCP_MAX_DIFF_SIZE=50000 # Increase to 50KB -
Break changes into smaller commits:
git add -p # Stage changes interactively in smaller chunks git commit -m "Part 1: ..." -
Review specific files separately using
review_codetool instead of git-based reviews
Note: Very large diffs (>50KB) may still cause timeouts even with increased limits. Consider reviewing critical files separately.
"Invalid commit SHA"
Problem: review_commit fails with "invalid commit SHA"
Solution: Verify commit exists:
git rev-parse --verify abc123 # Replace with your SHA
Use full or short SHA (minimum 7 characters):
{
"commit_sha": "a1b2c3d" // Short SHA (7+ chars)
}
"Empty diff / No changes to review"
Problem: Git reviews return empty results
Solution: Verify there are changes:
# For staged review
git diff --staged # Should show changes
# For unstaged review
git diff # Should show changes
# If no output, there are no changes to review
Integration Tests Fail
Problem: Tests fail with API errors
Solution: Ensure valid API keys are set:
export ANTHROPIC_API_KEY="valid-key"
export OPENAI_API_KEY="valid-key"
# Skip integration tests if keys unavailable
go test ./tests/unit/... # Run only unit tests
go test ./tests/contract/... # Run only contract tests
Performance Tips
Timeout Improvements (v1.1.0+)
The server now includes several optimizations to prevent timeouts:
- Increased default timeouts: Provider APIs now have 90s (up from 30s)
- Git operation timeouts: 30s limit prevents indefinite hangs on slow filesystems
- Reduced retry attempts: 1 retry (down from 3) minimizes worst-case delays
- Diff size validation: 10KB default limit prevents oversized requests
- Progress logging: Visibility into review stages for debugging
Best Practices
- Use
quickreview depth for faster feedback (default) - Choose faster providers: Anthropic Claude is generally fastest
- Review smaller diffs: Break large changes into smaller commits
# Stage files selectively git add file1.go file2.go git commit -m "Part 1: Core logic" git add file3.go file4.go git commit -m "Part 2: Tests" - Monitor diff sizes: Keep diffs under 10KB for best performance
- Increase timeouts for complex reviews: Use
thoroughdepth with longer timeouts:export ANTHROPIC_TIMEOUT=180s export MCP_REVIEW_TIMEOUT=300s
Security Considerations
- API Keys: Never commit API keys to version control
- Code Privacy: Code is sent to third-party LLM providers (Anthropic/OpenAI/Google)
- Local Git: Git operations are local; diffs are not sent anywhere except to the LLM
- Secrets in Code: Review may detect hardcoded secrets, but don't rely on it exclusively
Contributing
See for development guidelines.
Running Tests
# All tests
go test ./tests/... -v
# With coverage
go test -cover ./...
Code Quality
# Format code
go fmt ./...
# Vet code
go vet ./...
# Lint
golangci-lint run ./...
License
See file for details.
Links
Contributing
We welcome contributions! Please see for guidelines.
Code of Conduct
This project adheres to the . By participating, you are expected to uphold this code.
Security
For security vulnerabilities, please see our .
Support
For issues, questions, or feature requests, please open an issue on GitHub.
License
This project is licensed under the MIT License - see the file for details.
Built with ❤️ using Go and the Model Context Protocol