pr-review-agent
A locally-hosted LLM pull request reviewer that cannot overspend and cannot be summoned by a stranger.
A single Python asyncio daemon with a SQLite store, running on a private host. It polls on pull requests of a GitHub repository for exactly two events:
- a freshly opened pull request whose author is pre-approved;
- a comment containing
@claudewhose commenter is pre-approved.
and performs code review using Claude CLI and posts review comments on the pull request.
🚀 Quickstart
Requires: Python 3.10 – 3.14 and python virtualenv. Download latest release.
python -m venv .venv
source .venv/bin/activate
# install from pypi
pip install pr-review-agent
# or download the latest release
pip install pr_review_agent-<version>-py3-none-any.whl
pr-review-agent config generate # writes ./config.yaml
# update config; `config generate --full` writes the commented template
pr-review-agent config validate
# a fine-grained GitHub PAT scoped to this one repository, with
# Pull requests: read/write Issues: read/write Metadata: read
# (docs/TOKENS.md says why each one; classic-PAT `repo` also works)
GITHUB_TOKEN=xxxx pr-review-agent host check # can this host reach it all?
GITHUB_TOKEN=xxxx pr-review-agent daemon start # reads ./config.yaml
GITHUB_TOKEN=xxxx pr-review-agent daemon start --config /etc/pr-review-agent/config.yaml
Installing the package puts pr-review-agent on the path. Commands follow a
pr-review-agent <noun> <verb> grammar, grouped by the setup workflow:
config → host → daemon. --config is optional: without it a command
reads config.yaml from the directory it is started in, which is also where
state.db is written.
🗂 Documentation
The links below are relative, which is what works on GitHub and in the
documentation site. They are
not what PyPI gets: a relative target there resolves against pypi.org and
404s, so the release workflow builds from
scripts/pypi_readme.py's rewrite of this file,
with every target made absolute and pinned to the tag being released.
| Document | Answers |
|---|---|
| docs/CLI.md | What commands exist? Every <noun> <verb>, its options, the exit codes and the environment variables |
| docs/CONFIG.md | What settings exist, what does each accept, and why are unknown keys an error? |
| docs/TOKENS.md | Where do credentials live? The GitHub PAT and its scope, one token per repository, the allowlist, and rotation |
| docs/SERVICE.md | How is it deployed? The systemd user unit, why a user unit and not a system one, the three paths that must be absolute, lingering, and what systemctl reload reloads |
| docs/DESIGN.md | Why does this exist and why is it shaped like this? The four constraints, every alternative considered and rejected, the billing-mode question that is still open, and how prompt injection is handled |
| docs/ARCHITECTURE.md | What actually runs? The components, the path an event takes, the package layout, and which layer may import which |
| docs/TRIGGERS.md | What starts a review and what does not? Every reason code and its log level, what counts as a mention, the dedupe keys, and why identity is a number |
| docs/POLLER.md | How does it learn something happened without an inbound port? The three endpoints, the rate-limit arithmetic, the adaptive interval, the retry rules, and how a comment payload is mapped to a pull request |
| docs/DAEMON.md | What runs continuously, and what is it careful not to do? The cycle, the cold-start spend bound, the two watermark ordering rules, and how it shuts down |
| docs/QUEUE.md | Where does an accepted trigger wait, and what stops one review being paid for twice? Dedupe, the per-pull-request lease, why leases expire instead of renewing, and the retry bound |
| docs/STORAGE.md | What has to survive a restart, and what does a lost watermark actually cost? Why SQLite, and why a watermark only moves forward |
| docs/WORKSPACE.md | How does a pull request's code get onto disk, and why is none of it ever run? The bare mirror, the per-run worktree, the untrusted-tree hardening, and the diff-size caps |
| docs/BUDGET.md | The rolling windows and the share that guarantees human headroom, reserve-then-settle under concurrency, the degradation ladder, the circuit breaker, and what is still not built |
| docs/WORKER.md | What drains the queue? The claim-run-settle loop, what a failed run settles at and why, which failures retry and which are permanent, what a run leaves behind, the supervisor, and why not a process per review |
| docs/PUBLISHER.md | How does a review become visible, and what stops the agent approving anything? The 👀 at claim time, the live head_sha re-check, one comment per review, publish.dry_run, and why a failed publish never costs a second review |
| docs/ENGINE.md | How does a different coding agent plug in? The one swappable step, what an engine is given and must return, the capability record, and why every adapter is a CLI subprocess rather than an SDK |
| docs/STATUS.md | What is built, what is next, the acceptance checklist, and the known gaps |
| docs/LOGGING.md | What the daemon logs, where it goes, and what a record looks like? The single stderr stream, the global level and why it never moves httpx, the JSON record and the queries it allows, and the journald priority prefix |
| docs/FEATURE-ROADMAP.md | What could be built next, drawn from five neighbouring projects and a hardening review, each candidate with its cost |
| DEVELOPER.md | How do I set up, test, lint and build this? |
| DOCKER.md | How do I get all of that without installing any of it? The development container, what it carries, and the two things about it that are not obvious |
| CLAUDE.md | The behavioural guidelines applied to every change |
| AGENTS.md | The coding-assistant conventions |
Metadata
Release files for pr-review-agent 1.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pr_review_agent-1.4.0.tar.gz | 154.2 kB | With provenance | Details for pr_review_agent-1.4.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pr_review_agent-1.4.0-py3-none-any.whl | Python 3 | none | any | Details for pr_review_agent-1.4.0-py3-none-any.whl |
Total release size: 341.1 kB
Release files / pr_review_agent-1.4.0.tar.gz
| Download URL | pr_review_agent-1.4.0.tar.gz |
|---|---|
| Size | 154.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dde416be82782895a23084f3f93b5d7079300050b67f095dcb395004037669a8
|
|
BLAKE2b-256 checksum How to use checksums |
a3317a68cd497005f83180d182363e3a291feefe4fde4ffa42470e4f4a81565d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.
Transparency logRelease files / pr_review_agent-1.4.0-py3-none-any.whl
| Download URL | pr_review_agent-1.4.0-py3-none-any.whl |
|---|---|
| Size | 186.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f3e47323a979a193fff1b95bc044a4d65a9cc734023dce7f94dfea6feff25195
|
|
BLAKE2b-256 checksum How to use checksums |
851902549275b9d3eae7e647697f08ab39bb0738df5bea4384a8a6a7a718f151
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.
Transparency logSecurity for pr-review-agent 1.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for pr_review_agent-1.4.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.