AI-powered code review agent that posts inline comments on your GitHub PRs.
Powered by Claude · Grounded in real static analysis · Deployed in one click.
How It Works · Quick Start · CLI Usage · Deployment · Configuration
GitHub PR opened / pushed
|
v
+-----------+ +------------------+ +---------------+
| Webhook | --> | Filter & Budget | --> | Claude Agent |
| (FastAPI)| | skip lockfiles, | | (LangGraph) |
+-----------+ | cap tokens | +-------+-------+
+------------------+ |
tool calls
/ \
+-------+ +------+------+
| ruff | | post_review |
| check | | _comments |
+-------+ +------+------+
|
v
+-------------+
| GitHub API |
| inline |
| review |
+-------------+
- Webhook receives the PR event, validates the signature, returns
200immediately - Background task fetches the diff from GitHub
- File filter strips lockfiles, vendored code, binaries, and generated files
- Token budgets cap per-file and per-PR token usage to control costs
- LangGraph agent analyzes the diff with Claude, optionally running
rufffor Python static analysis - Inline review posts structured comments directly on the diff in GitHub
- Python 3.11+
- A GitHub App with
pull_requests: writepermission - An Anthropic API key
git clone https://github.com/ZsombiTech/PrSentry.git
cd PrSentry
python -m venv .venv
.venv/Scripts/activate # Windows
# source .venv/bin/activate # macOS/Linux
pip install -e .cp .env.example .envFill in the required values:
| Variable | Required | Description |
|---|---|---|
ANTHROPIC_API_KEY |
Yes | Your Claude API key |
GITHUB_APP_ID |
Yes | GitHub App ID |
GITHUB_PRIVATE_KEY_PATH |
Yes | Path to .pem file |
GITHUB_WEBHOOK_SECRET |
Yes | Webhook secret from GitHub App settings |
DATABASE_URL |
No | Postgres connection string for persistence |
LANGFUSE_SECRET_KEY |
No | Langfuse secret key for tracing |
LANGFUSE_PUBLIC_KEY |
No | Langfuse public key for tracing |
uvicorn prsentry.app:app --reload --port 8000Expose it with ngrok for local testing:
ngrok http 8000Set your GitHub App's webhook URL to https://<ngrok-url>/webhook.
Review any .diff file locally without a GitHub App:
# Human-readable output
prsentry-review path/to/changes.diff
# JSON output
prsentry-review path/to/changes.diff --format jsonExample output:
[CRITICAL] app/auth.py:8
SQL injection vulnerability — user input is interpolated directly into the query string.
[WARNING] app/auth.py:6
Plaintext password comparison. Use a proper hashing algorithm like bcrypt.
[SUGGESTION] app/auth.py:10
The database connection is never closed. Use a context manager.
The repo includes a render.yaml blueprint:
- Push to GitHub
- On Render: New > Blueprint and select your repo
- Add environment variables in the dashboard
- Upload your
.pemfile via Render's Secret Files to/etc/secrets/private-key.pem - Update your GitHub App webhook URL to
https://prsentry-xxxx.onrender.com/webhook
docker build -t prsentry .
docker run -p 8000:8000 --env-file .env prsentryDefined in src/prsentry/config.py. Files matching deny patterns are excluded from review:
| Category | Examples |
|---|---|
| Lock files | package-lock.json, yarn.lock, poetry.lock, Cargo.lock |
| Generated | vendor/, node_modules/, dist/, build/, __generated__/ |
| Binary/assets | .png, .jpg, .pdf, .woff2, .exe, .dll |
| Minified | .min.js, .min.css |
Add exceptions to ALLOW_PATTERNS to override.
| Setting | Default | Purpose |
|---|---|---|
MAX_TOKENS_PER_FILE |
8,000 | Truncates large file diffs |
MAX_TOKENS_PER_PR |
60,000 | Caps total tokens sent to Claude |
MAX_TOOL_STEPS |
5 | Limits agent tool-call loops |
The agent categorizes every finding:
| Level | Meaning |
|---|---|
| CRITICAL | Will break production or is a security vulnerability |
| WARNING | Likely bug or significant issue |
| SUGGESTION | Improvement worth considering |
| NITPICK | Style preference or minor issue |
Set LANGFUSE_SECRET_KEY and LANGFUSE_PUBLIC_KEY to enable tracing. Every agent run is captured with:
- Full LLM conversation history
- Tool calls and responses
- Token usage and latency
Set DATABASE_URL to enable persistence. Tables are auto-created on startup:
runs— one row per PR review (status, duration, token counts, errors)comments— every inline comment posted (file, line, severity, body)
src/prsentry/
app.py FastAPI server + lifespan
cli.py CLI entrypoint
config.py File filtering + token budgets
github_client.py GitHub API (diff, reviews, auth)
graph.py LangGraph agent workflow
models.py Pydantic models + state schema
storage.py Postgres persistence
tools.py Agent tools (ruff, post_review_comments)
tracing.py Langfuse integration
webhooks.py Webhook parsing + review orchestration
| Layer | Technology |
|---|---|
| LLM | Claude Sonnet 4.5 |
| Agent framework | LangGraph |
| Static analysis | Ruff |
| Web framework | FastAPI |
| Database | PostgreSQL |
| Observability | Langfuse |
| Deployment | Render / Docker |
Built by Zsombor Horvath
