CodeSpy
An open-source AI reviewer that catches bugs, improves code quality, and integrates directly into your PR workflow, without sacrificing control or security.
- Table of Contents
- Why CodeSpy?
- Features
- Installation
- Quick Start
- Usage
- Configuration
- Output
- Architecture
- DSPy Signatures
- Supported Languages
- Development
- Contributors
- License
Most AI code reviewers are:
- β Black boxes
- β SaaS-only
- β Opaque about reasoning
- β Risky for sensitive codebases
CodeSpy is different:
- π Transparent reasoning
- π Self-hostable
- π§ Configurable review rules
- π Native PR integration
- π§© Extensible architecture
- π¦ 100% open-source
Built for engineering teams that care about correctness, security, and control.
- π Security Analysis - Detects common vulnerabilities (injection, auth issues, data exposure, etc.) with CWE references
- π Bug Detection - Identifies logic errors, null references, resource leaks, edge cases
- π Documentation Review - Checks for missing docstrings, outdated comments, incomplete docs
- π Intelligent Scope Detection - Automatically identifies code scopes (frontend, backend, infra, microservice in mono repo, etc...)
- π Smart Deduplication - LLM-powered issue deduplication across reviewers
- π° Cost Tracking - Track LLM calls, tokens, and costs per review
- π€ Model Agnostic - Works with OpenAI, AWS Bedrock, Anthropic, Ollama, and more via LiteLLM
- π³ Docker Ready - Run locally or in the cloud with Docker
GitHub & GitLab - Works with both platforms, auto-detects from URL- π₯οΈ Local Reviews - Review local git changes without GitHub/GitLab β diff against any branch, ref, or review uncommitted work
- π§© MCP Server - IDE integration via Model Context Protocol β trigger reviews from AI coding assistants like Cline without leaving your editor
- π GitHub Action - One-line integration for automatic PR reviews
pip install codespy-aibrew tap khezen/codespy
brew install codespy# Pull the pre-built image from GitHub Container Registry
docker pull ghcr.io/khezen/codespy:latest
# Or build locally
docker build -t codespy .# Clone the repository
git clone https://github.com/khezen/codespy.git
cd codespy
# Install dependencies
poetry install
# Or install only production dependencies
poetry install --only mainGet up and running in 30 seconds:
# 1. Set your Git token (or let codespy auto-discover from gh/glab CLI)
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx # For GitHub
# OR
export GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx # For GitLab
# 2. Set your LLM provider (example with Anthropic)
export DEFAULT_MODEL=anthropic/claude-opus-4-6
export ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxx
# 3. Review a PR or MR!
codespy review https://github.com/owner/repo/pull/123
# OR
codespy review https://gitlab.com/group/project/-/merge_requests/123codespy auto-discovers credentials from standard locations (~/.aws/credentials, gh auth token, glab auth token, etc.) - see Configuration for details.
# Review GitHub Pull Request
codespy review https://github.com/owner/repo/pull/123
# Review GitLab Merge Request
codespy review https://gitlab.com/group/project/-/merge_requests/123
# GitLab with nested groups
codespy review https://gitlab.com/group/subgroup/project/-/merge_requests/123
# Self-hosted GitLab
codespy review https://gitlab.mycompany.com/team/project/-/merge_requests/123
# Output as JSON
codespy review https://github.com/owner/repo/pull/123 --output json
# Use a specific model
codespy review https://github.com/owner/repo/pull/123 --model anthropic/claude-opus-4-6
# Use a custom config file
codespy review https://github.com/owner/repo/pull/123 --config path/to/config.yaml
codespy review https://github.com/owner/repo/pull/123 -f staging.yaml
# Disable stdout output (useful with --git-comment)
codespy review https://github.com/owner/repo/pull/123 --no-stdout
# Post review as GitHub/GitLab comment
codespy review https://github.com/owner/repo/pull/123 --git-comment
# Combine: only post to Git platform, no stdout
codespy review https://github.com/owner/repo/pull/123 --no-stdout --git-comment
# Show current configuration
codespy config
# Show configuration from a specific file
codespy config --config path/to/config.yaml
# Show version
codespy --version
# Review local git changes (no GitHub/GitLab needed)
codespy review-local # Review current dir vs main
codespy review-local /path/to/repo # Review specific repo
codespy review-local --base develop # Compare against develop
codespy review-local --base origin/main # Compare against origin/main
codespy review-local --base HEAD~5 # Compare against 5 commits back
# Review uncommitted changes (staged + unstaged)
codespy review-uncommitted # Review current dir
codespy review-uncommitted /path/to/repo
codespy review-uncommitted --output jsonCodeSpy can run as an MCP (Model Context Protocol) server for integration with AI coding assistants like Cline, enabling code reviews directly from your editor without leaving your workflow.
# Start the MCP server
codespy serve
# Use a custom config file
codespy serve --config path/to/config.yamlConfigure your IDE (example for Cline in VS Code):
Add to cline_mcp_settings.json:
{
"mcpServers": {
"codespy-reviewer": {
"command": "codespy",
"args": ["serve"],
"env": {
"DEFAULT_MODEL": "anthropic/claude-opus-4-6",
"ANTHROPIC_API_KEY": "your-key-here"
}
}
}
}Or for AWS Bedrock:
{
"mcpServers": {
"codespy-reviewer": {
"command": "codespy",
"args": ["serve"],
"env": {
"DEFAULT_MODEL": "bedrock/us.anthropic.claude-opus-4-6-v1",
"AWS_REGION": "us-east-1",
"AWS_ACCESS_KEY_ID": "your-access-key",
"AWS_SECRET_ACCESS_KEY": "your-secret-key"
}
}
}
}Available MCP Tools:
review_local_changes(repo_path, base_ref)β Review branch changes vs base (e.g., vsmain)review_uncommitted(repo_path)β Review staged + unstaged working tree changesreview_pr(mr_url)β Review a GitHub PR or GitLab MR by URL
Then ask your AI assistant: "Review my local changes" or "Review uncommitted work in /path/to/repo"
# With docker run (using GHCR image)
docker run --rm \
-e GITHUB_TOKEN=$GITHUB_TOKEN \
-e DEFAULT_MODEL=anthropic/claude-opus-4-6 \
-e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
ghcr.io/khezen/codespy:latest review https://github.com/owner/repo/pull/123
# Or use a specific version
docker run --rm \
-e GITHUB_TOKEN=$GITHUB_TOKEN \
-e DEFAULT_MODEL=anthropic/claude-opus-4-6 \
-e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
ghcr.io/khezen/codespy:0.2.1 review https://github.com/owner/repo/pull/123Add CodeSpy to your repository for automatic PR reviews:
Trigger on /codespy review comment:
# .github/workflows/codespy-review.yml
name: CodeSpy Code Review
on:
issue_comment:
types: [created]
jobs:
review:
# Only run on PR comments containing '/codespy review'
if: |
github.event.issue.pull_request &&
contains(github.event.comment.body, '/codespy review')
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Run CodeSpy Review
uses: khezen/codespy@v1
with:
model: 'anthropic/claude-opus-4-6'
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}Trigger automatically on every PR:
# .github/workflows/codespy-review.yml
name: CodeSpy Code Review
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Run CodeSpy Review
uses: khezen/codespy@v1
with:
model: 'anthropic/claude-opus-4-6'
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}See .github/workflows/codespy-review.yml.example for more examples.
codespy supports two configuration methods:
.envfile - Simple environment variables for basic setupcodespy.yaml- Full YAML configuration for advanced options (per-module settings)
Priority: cmd options > Environment Variables > YAML Config > Defaults
# Copy the example file
cp .env.example .envcodespy automatically detects the platform (GitHub or GitLab) from the URL and discovers tokens from multiple sources.
Auto-discovered from:
GITHUB_TOKENorGH_TOKENenvironment variables- GitHub CLI (
gh auth token) - Git credential helper
~/.netrcfile
Or create a token at https://github.com/settings/tokens with repo scope:
GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxTo disable auto-discovery:
GITHUB_AUTO_DISCOVER_TOKEN=falseAuto-discovered from:
GITLAB_TOKENorGITLAB_PRIVATE_TOKENenvironment variables- GitLab CLI (
glab auth token) - Git credential helper
~/.netrcfile- python-gitlab config files (
~/.python-gitlab.cfg,/etc/python-gitlab.cfg)
Or create a token at https://gitlab.com/-/user_settings/personal_access_tokens with api scope:
GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxxFor self-hosted GitLab:
GITLAB_URL=https://gitlab.mycompany.com
GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxxTo disable auto-discovery:
GITLAB_AUTO_DISCOVER_TOKEN=falsecodespy auto-discovers credentials for all providers:
Anthropic (auto-discovers from $ANTHROPIC_API_KEY, ~/.config/anthropic/, ~/.anthropic/):
DEFAULT_MODEL=anthropic/claude-opus-4-6
# Optional - set explicitly or let codespy auto-discover:
# ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxAWS Bedrock (auto-discovers from ~/.aws/credentials, AWS CLI, env vars):
DEFAULT_MODEL=bedrock/us.anthropic.claude-sonnet-4-5-20250929-v1:0
AWS_REGION=us-east-1
# Optional - uses ~/.aws/credentials by default, or set explicitly:
# AWS_ACCESS_KEY_ID=...
# AWS_SECRET_ACCESS_KEY=...OpenAI (auto-discovers from $OPENAI_API_KEY, ~/.config/openai/, ~/.openai/):
DEFAULT_MODEL=openai/gpt-5
# Optional - set explicitly or let codespy auto-discover:
# OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxGoogle Gemini (auto-discovers from $GEMINI_API_KEY, $GOOGLE_API_KEY, gcloud ADC):
DEFAULT_MODEL=gemini/gemini-2.5-pro
# Optional - set explicitly or let codespy auto-discover:
# GEMINI_API_KEY=xxxxxxxxxxxxxxxxxxxxLocal Ollama:
DEFAULT_MODEL=ollama/llama3To disable auto-discovery for specific providers:
AUTO_DISCOVER_AWS=false
AUTO_DISCOVER_OPENAI=false
AUTO_DISCOVER_ANTHROPIC=false
AUTO_DISCOVER_GEMINI=falseFor per-signature settings, use codespy.yaml. See codespy.yaml for all available options including:
- LLM provider settings and auto-discovery
- Git platform configuration (GitHub/GitLab)
- Per-signature model and iteration overrides
- Output format and destination settings
- Directory exclusions
Override YAML settings via environment variables using _ separator:
# Default settings
export DEFAULT_MODEL=anthropic/claude-opus-4-6
export DEFAULT_MAX_ITERS=20
# Per-signature settings (use signature name, not module name)
export CODE_REVIEW_MODEL=anthropic/claude-sonnet-4-5-20250929
# Output settings
export OUTPUT_STDOUT=false
export OUTPUT_GIT=trueSee codespy.yaml for full configuration options.
codespy uses a tiered model approach to balance review quality and cost:
| Tier | Role | Default | Recommended Model | Used By |
|---|---|---|---|---|
| π§ Smart | Core analysis & reasoning | DEFAULT_MODEL |
anthropic/claude-opus-4-6 |
Code & doc review, supply chain, scope identification |
| β‘ Mid-tier | Extraction & deduplication | Falls back to DEFAULT_MODEL |
anthropic/claude-sonnet-4-5-20250929 |
TwoStepAdapter field extraction, issue deduplication |
| π° Cheap | Summarization | Falls back to DEFAULT_MODEL |
anthropic/claude-haiku-4-5-20251001 |
PR summary generation |
By default, all models use DEFAULT_MODEL (anthropic/claude-opus-4-6). This works out of the box β just set your API credentials and go.
To optimize costs, override the mid-tier and cheap models:
# .env or environment variables
DEFAULT_MODEL=anthropic/claude-opus-4-6 # Smart tier (default)
EXTRACTION_MODEL=anthropic/claude-sonnet-4-5-20250929 # Mid-tier: field extraction
DEDUPLICATION_MODEL=anthropic/claude-sonnet-4-5-20250929 # Mid-tier: issue deduplication
SUMMARIZATION_MODEL=anthropic/claude-haiku-4-5-20251001 # Cheap tier: PR summaryOr in codespy.yaml:
default_model: anthropic/claude-opus-4-6
extraction_model: anthropic/claude-sonnet-4-5-20250929
signatures:
deduplication:
model: anthropic/claude-sonnet-4-5-20250929
summarization:
model: anthropic/claude-haiku-4-5-20251001# Code Review: Add user authentication
**PR:** [owner/repo#123](https://github.com/owner/repo/pull/123)
**Reviewed at:** 2024-01-15 10:30 UTC
**Model:** anthropic/claude-opus-4-6
## Summary
This PR implements user authentication with JWT tokens...
## Statistics
- **Total Issues:** 3
- **Critical:** 1
- **Security:** 1
- **Bugs:** 1
- **Documentation:** 1
## Issues
### π΄ Critical (1)
#### SQL Injection Vulnerability
**Location:** `src/auth/login.py:45`
**Category:** security
The user input is directly interpolated into the SQL query...
**Code:**
query = f"SELECT * FROM users WHERE username = '{username}'"
**Suggestion:**
Use parameterized queries instead...
**Reference:** [CWE-89](https://cwe.mitre.org/data/definitions/89.html)
CodeSpy can post reviews directly to GitHub PRs or GitLab MRs as native review comments with inline annotations.
Enable via CLI:
# GitHub
codespy review https://github.com/owner/repo/pull/123 --git-comment
# GitLab
codespy review https://gitlab.com/group/project/-/merge_requests/123 --git-comment
# Combine: only post to platform, no stdout
codespy review https://github.com/owner/repo/pull/123 --no-stdout --git-commentEnable via configuration:
# Environment variable
export OUTPUT_GIT=true
# Or in codespy.yaml
output_git: trueFeatures:
- π― Inline Comments - Issues are posted as review comments on the exact lines where they occur
- π Multi-line Support - Issues spanning multiple lines are annotated with start/end line ranges
- π΄π π‘π΅ Severity Indicators - Visual emoji markers for Critical, High, Medium, Low severity
- π¦ Collapsible Sections - Organized review body with expandable details:
- π Summary of changes
- π― Quality Assessment
- π Statistics table
- π° Cost breakdown per signature
- π‘ Recommendation
- π CWE References - Security issues link directly to MITRE CWE database
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β codespy CLI β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β review <pr_url> [--config ...] [--output json|md] [--model ...] β
ββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββ
β Git Platform Integration β
β - GitHub: Fetch PR diff, changed files, commit messages β
β - GitLab: Fetch MR diff, changed files, commit messages β
β - Auto-detects platform from URL β
β - Clone/access full repository for context β
ββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββ
β DSPy Review Pipeline β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Scope Identifier β β
β β (identifies code scopes: frontend, backend, infra, etc.) β β
β ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββ β
β β Parallel Review Modules β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββ β β
β β β Supply Chain β β Code β β Doc β β β
β β β Auditor β β Reviewer β β Reviewer β β β
β β β β β (bug+sec+ β β β β β
β β β β β smell) β β β β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββ β β
β ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββ β
β β Issue Deduplicator β β
β β (LLM-powered deduplication across reviewers) β β
β ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββ β
β β PR Summarizer β β
β β (generates summary, quality assessment, recommendation) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Cost Tracker (tokens, calls, $) β
ββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββ
β Tools Layer β
β ββββββββββββββ ββββββββββββββ ββββββββββββββ ββββββββββββββββ β
β β Filesystem β β Git β β Web β β Cyber/OSV β β
β β β β (GH + GL) β β β β β β
β ββββββββββββββ ββββββββββββββ ββββββββββββββ ββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Parsers β β
β β βββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββ β β
β β β Ripgrep β β Tree-sitter β β β
β β β (code search) β β (multi-language AST parsing) β β β
β β βββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββ
β LLM Backend (LiteLLM) β
β Bedrock | OpenAI | Anthropic | Ollama | Any OpenAI-compatible β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The review is powered by DSPy signatures that structure the LLM's analysis:
| Signature | Config Key | Description |
|---|---|---|
| ScopeIdentifierSignature | scope |
Identifies code scopes (frontend, backend, infra, microservice in mono repo, etc...) |
| CodeReviewSignature | code_review |
Detects verified bugs, security vulnerabilities, removed defensive code, and code smells |
| DocReviewSignature | doc |
Detects stale or wrong documentation caused by code changes |
| SupplyChainSecuritySignature | supply_chain |
Analyzes artifacts (Dockerfiles) and dependencies for supply chain security |
| IssueDeduplicationSignature | deduplication |
LLM-powered deduplication of issues across reviewers |
| MRSummarySignature | summarization |
Generates summary, quality assessment, and recommendation |
Tree-sitter based parsing for context-aware analysis:
| Language | Extensions | Features |
|---|---|---|
| Python | .py |
Functions, classes, imports |
| JavaScript | .js, .jsx |
Functions, classes, imports |
| TypeScript | .ts, .tsx |
Functions, classes, interfaces |
| Go | .go |
Functions, structs, interfaces |
| Java | .java |
Methods, classes, packages |
| Kotlin | .kt |
Functions, classes, objects |
| Swift | .swift |
Functions, classes, structs |
| Objective-C | .m, .h |
Methods, interfaces, protocols |
| Rust | .rs |
Functions, structs, traits, impl blocks |
| Terraform | .tf |
Resources, data sources, modules, variables |
All languages are supported for security, bug, and documentation analysis.
# Quick setup (creates .env and installs dependencies)
make setup
# Or manually with Poetry:
poetry install # Install all dependencies including dev
poetry lock # Update lock file
# Available make targets
make help
# Run commands with Poetry
make lint # Run ruff linter
make format # Format code with ruff
make typecheck # Run mypy type checker
make test # Run pytest tests
make build # Build package with Poetry
make clean # Clean build artifacts
# Or run directly:
poetry run codespy review https://github.com/owner/repo/pull/123
poetry run ruff check src/
poetry run mypy src/- @khezen
- @pranavsriram8
MIT
