PR Sentinel
Free, self-hosted AI code review for pull requests and merge requests. Point it at a free provider like Groq, Gemini, or a local Ollama model and it reads your diff, flags real problems, and leaves comments directly on GitHub or GitLab. No subscription, no seat-based pricing, no vendor lock-in.
If your team has a budget for a paid model, PR Sentinel works with your own OpenAI or Anthropic key too. Nothing here requires it.
Why this exists
Automated PR review tools are useful, but the well known ones are paid products with per-seat pricing. That is a real cost for a solo developer, a student project, or a small open source repository, even when the actual review only needs a handful of API calls per pull request. PR Sentinel is the same idea built as a small, auditable, self-hosted tool: you choose the model, you hold the API key (or use none at all with a local model), and the entire pipeline runs inside your own GitHub Actions job.
What it does
- Reads the diff for a pull request (or a local
git diff) and reviews only the changed lines, using surrounding context to understand intent. - Works on GitHub pull requests, GitLab merge requests, and Bitbucket pull requests.
- Flags bugs, security issues, performance problems, missing error handling, and missing tests, not personal style nitpicks. Where it can, it includes a drop-in code fix, not just an explanation.
- Posts a single summary comment on the pull request, plus inline comments on the specific lines with a problem, and updates that same comment on every push instead of piling up duplicates.
- Requests changes automatically when a critical issue is found, so it can act as a real merge gate if you want one.
- Also works as a pre-commit hook, reviewing staged changes before they are even pushed.
- Suggests a pull request title and description from a diff with
prsentinel summarize, if you would rather not write one by hand. - Reviews diff chunks concurrently, so larger pull requests finish faster, and retries transient rate limit or server errors automatically.
- Can write review comments in a language other than English.
- Can notify a Slack or Discord channel when something serious is found.
- Works from the command line too, so you can review a diff before you even open the pull request.
- Exports findings as SARIF for the GitHub Security tab, plain JSON for your own tooling, an HTML report, or JUnit XML for CI systems that render test reports.
- Caches results per diff chunk so re-running a workflow does not spend API quota reviewing the same lines twice.
Quickstart: GitHub Actions
Add this workflow at .github/workflows/pr-sentinel.yml:
name: PR Sentinel
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Lethe044/prsentinel@v1
with:
provider: groq
api-key: ${{ secrets.GROQ_API_KEY }}
Get a free Groq API key at console.groq.com/keys,
add it as a repository secret named GROQ_API_KEY, and every new pull
request gets reviewed automatically.
Quickstart: GitLab CI
Add this to .gitlab-ci.yml:
prsentinel:
image: python:3.12
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
- pip install prsentinel-cli
- prsentinel review --post-to-gitlab --provider groq
variables:
GROQ_API_KEY: $GROQ_API_KEY
Add GROQ_API_KEY and a GITLAB_TOKEN (a project access token with the
api scope) as masked CI/CD variables in your project settings, and every
merge request gets a summary note plus inline comments on the changed
lines.
Quickstart: Bitbucket Pipelines
Add this to bitbucket-pipelines.yml:
pipelines:
pull-requests:
'**':
- step:
name: PR Sentinel
image: python:3.12
script:
- pip install prsentinel-cli
- prsentinel review --post-to-bitbucket --provider groq
Create a repository access token with the pullrequest:write scope under
Repository settings > Security > Access tokens, then add it along with
GROQ_API_KEY as secured repository variables named BITBUCKET_TOKEN and
GROQ_API_KEY.
Quickstart: pre-commit hook
PR Sentinel also works as a pre-commit hook, so
you catch problems before they are even pushed. Add this to your
.pre-commit-config.yaml:
repos:
- repo: https://github.com/Lethe044/prsentinel
rev: v1.1.0
hooks:
- id: prsentinel
This reviews your staged changes every time you run git commit, using
whichever provider and API key you have configured locally.
Quickstart: command line
pip install prsentinel-cli
export GROQ_API_KEY=your-key-here
prsentinel review --base origin/main --head HEAD
This prints a table of findings straight to your terminal, before you even push. Combine it with a pre-push git hook if you want a check before code leaves your machine at all.
Choosing a provider
| Provider | Cost | Setup |
|---|---|---|
| groq | Free tier | API key from console.groq.com/keys, set GROQ_API_KEY |
| gemini | Free tier | API key from aistudio.google.com/apikey, set GEMINI_API_KEY |
| ollama | Free, fully local | Run ollama serve and pull a model, no key needed |
| openai | Paid, bring your own key | Set OPENAI_API_KEY |
| anthropic | Paid, bring your own key | Set ANTHROPIC_API_KEY |
Run prsentinel providers at any time to see this list along with the
default model used for each one.
Configuration
Run prsentinel init to write a starter .prsentinel.yml in your
repository root. Every field is optional and falls back to a sensible
default if the file does not exist at all. Pass --preset security,
--preset frontend, or --preset backend to pre-fill custom_rules with
a ready made rule set instead of starting from an empty list.
provider: groq
model:
severity_threshold: suggestion
fail_on: critical
max_files: 60
max_diff_lines_per_chunk: 350
ignore:
- "*.lock"
- "dist/**"
- "node_modules/**"
- "vendor/**"
include: []
custom_rules:
- "Flag any hardcoded API keys or secrets"
- "Require a docstring on every public function"
post_summary_comment: true
inline_comments: true
request_changes_on_critical: true
cache_enabled: true
max_workers: 4
show_footer: true
min_confidence: low
category_severity_floor:
security: warning
enable_suppression_comments: true
suggested_code: true
comment_language: english
min_request_interval: 0
notify_webhook_url:
notify_webhook_format: slack
notify_on: critical
custom_rules is where PR Sentinel becomes specific to your project. Add
plain English instructions and they get appended to every review prompt,
alongside the general review.
fail_on controls the exit code (and therefore whether your CI check goes
red). Set it to warning for a stricter gate, or suggestion for the
strictest possible one.
max_workers controls how many diff chunks are reviewed at the same time.
Raising it speeds up large pull requests, at the cost of hitting a free
tier rate limit sooner.
Run prsentinel validate-config at any time to check a .prsentinel.yml
file for typos or invalid values without running a full review, useful as
a quick sanity check in CI before the real review step runs.
Command line reference
prsentinel review Review a diff and report findings
prsentinel summarize Suggest a PR title and description from a diff
prsentinel init Write a starter .prsentinel.yml
prsentinel validate-config Check a .prsentinel.yml file for problems
prsentinel providers List providers and setup instructions
prsentinel clear-cache Delete the local review cache
prsentinel stats Show how much is stored in the local cache
Useful flags on review:
--base, --head Git refs to diff (defaults to origin/main...HEAD)
--staged Review staged changes instead of a branch diff
--diff-file Review a saved unified diff file instead of running git
--provider, --model Override the provider or model from config
--output terminal (default), json, sarif, html, or junit
--output-file Write json/sarif/html/junit output to a file
--post-to-github Post results as a review on the current GitHub Actions PR
--post-to-gitlab Post results as notes on the current GitLab CI merge request
--post-to-bitbucket Post results as comments on the current Bitbucket Pipelines PR
--only Only review files matching this glob (repeatable)
--dry-run Compute the review but do not post anything, just print it
--fail-on Override the fail_on threshold for this run
--no-cache Skip the local response cache for this run
Suggesting a PR title and description
prsentinel summarize --base origin/main --head HEAD
Reads the same kind of diff as review, but instead of finding problems it
proposes a conventional-commit style title, a short summary, and a few
highlights. Handy when you are about to open a pull request and would
rather not write the description from scratch.
Quickstart: Docker
If you would rather not install Python, a ready to use image is published on every release:
docker run --rm -v "$(pwd):/workspace" -e GROQ_API_KEY \
ghcr.io/lethe044/prsentinel:latest review --base origin/main --head HEAD
Mount your repository at /workspace and pass whichever provider key you
are using as an environment variable. This works the same way in any CI
system that can run a Docker image, not just GitHub Actions or GitLab CI.
Silencing a specific finding
Sometimes a flagged line is genuinely fine for reasons the model cannot see. Silence it the same way you would silence a linter, with a comment near the line:
eval(trusted_internal_config) # prsentinel-ignore-line
# prsentinel-ignore-next-line
eval(trusted_internal_config)
Add # prsentinel-ignore-file anywhere in a file to skip it entirely (for
example, a generated file that should never be reviewed). This works with
any comment syntax, since only the marker text itself is matched. Turn it
off globally with enable_suppression_comments: false in
.prsentinel.yml if you would rather not have this escape hatch at all.
Confidence and category severity floors
Every finding also carries a confidence level (low, medium, or high),
based on how sure the model is. Set min_confidence: high in
.prsentinel.yml if you only want the findings it is fairly certain about.
category_severity_floor forces a minimum severity for a category no
matter what the model assigned, which is on by default for security
findings (security: warning) so a model having an off day never quietly
downgrades a real security issue to a suggestion.
Focusing a review with include patterns
In a monorepo, you might only want PR Sentinel looking at one part of the
codebase. Set include in .prsentinel.yml, or pass --only on the
command line (repeatable):
prsentinel review --only "backend/**" --only "*.py"
An empty include list (the default) means every changed file that is
not ignored gets reviewed, same as before.
Token usage
Since this tool is built around free tier APIs, PR Sentinel reports how many tokens a review actually used, when the provider includes that in its response (Groq, Gemini, OpenAI, Anthropic, and Ollama all do):
Tokens used: 530 (450 prompt, 80 completion)
This also appears in --output json under a usage key, so you can track
it over time if you want to keep an eye on a free tier quota.
Drop-in code fixes
Where a finding maps to a small, well defined change, PR Sentinel asks the
model for a ready to paste fix alongside the explanation, shown as a code
block right under the finding. Set suggested_code: false in
.prsentinel.yml if you would rather only see explanations.
Reviewing in another language
Set comment_language in .prsentinel.yml (for example turkish,
spanish, or japanese) and PR Sentinel writes every explanation,
suggestion, and the output of prsentinel summarize in that language.
Category and severity values stay in English internally, so filtering and
fail_on behave exactly the same regardless of the language you choose.
Reliability on a free tier
Every provider automatically retries a rate limited or temporarily
unavailable request a few times with backoff, honoring the server's
Retry-After header when it sends one, before giving up. If you are
still hitting rate limits on a large pull request, set
min_request_interval in .prsentinel.yml to add a small pause between
the start of each chunk's request.
Notifications
Set notify_webhook_url to a Slack or Discord incoming webhook URL and
PR Sentinel posts a short summary there whenever a review finds something
at or above the notify_on severity (critical by default). Set
notify_webhook_format: discord if the URL is a Discord webhook.
CI systems without native support (JUnit XML)
Run with --output junit --output-file results.xml to get a JUnit XML
report, which Jenkins, CircleCI, Azure DevOps, and Bitbucket's own test
report tab all know how to render natively, without a GitHub or GitLab
integration.
Editor autocompletion for the config file
.prsentinel.yml files written by prsentinel init include a
yaml-language-server schema hint, so editors with the YAML extension
(VS Code, most JetBrains IDEs) autocomplete fields and flag typos as you
type. The schema itself lives at
prsentinel.schema.json in this repository.
How review comments look
PR Sentinel posts one summary comment with a small table of counts by
severity, followed by a breakdown per file, and inline comments on the
exact lines a finding refers to. If a critical issue is found and
request_changes_on_critical is enabled, the review is submitted as
"Request changes" instead of a plain comment, so it behaves like a real
review a teammate would leave.
Uploading findings to the GitHub Security tab
If you would rather see findings in GitHub's Security tab alongside your other code scanning results, export SARIF and upload it with the official action, as a step alongside (or instead of) the PR comment action:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: pip install prsentinel-cli
- run: |
prsentinel review --base origin/${{ github.base_ref }} --head HEAD \
--output sarif --output-file results.sarif --fail-on suggestion || true
env:
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: results.sarif
fetch-depth: 0 is needed so the base branch is available to diff
against. The || true keeps the step green even when findings are
reported, since the upload step is what should reflect them, not this
one. For most people the PR comments from the main action are enough on
their own; this is for teams that already have a Security tab workflow
and want PR Sentinel findings to show up there too.
Limitations, on purpose
PR Sentinel reviews diffs, not your entire codebase, and it does not
replace a human reviewer. Language models make mistakes, including missing
real issues and occasionally flagging something that is not actually a
problem. Treat its output the way you would treat a review from a
thorough but fallible colleague: worth reading, not worth merging blindly
on faith either way. custom_rules and the severity_threshold and
fail_on settings let you tune how much weight to give it in your
workflow.
Contributing
Bug reports, feature requests, and pull requests are welcome. See CONTRIBUTING.md for how to get set up locally, how the provider interface works, and what a good pull request looks like here.
License
MIT. See LICENSE.
Metadata
Release files for prsentinel-cli 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 | |
|---|---|---|---|---|
| prsentinel_cli-1.4.0.tar.gz | 57.3 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| prsentinel_cli-1.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 111.4 kB
Release files / prsentinel_cli-1.4.0.tar.gz
| Download URL | prsentinel_cli-1.4.0.tar.gz |
|---|---|
| Size | 57.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2d9d5efb77cdec0129e1961f87a19959d52e97bb460a97cdf31dd9b5e89e2799
|
|
BLAKE2b-256 checksum How to use checksums |
bd9308d2ca03ec0da9f5b20828deaeba4b44791210ebc1f0e8fab35772e4fea2
|
| 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 8, 2026.
Transparency logRelease files / prsentinel_cli-1.4.0-py3-none-any.whl
| Download URL | prsentinel_cli-1.4.0-py3-none-any.whl |
|---|---|
| Size | 54.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9653b2a9dd5905a4268b016bfbe34115406d61b43d76fc9db61095d3d5ba9a7a
|
|
BLAKE2b-256 checksum How to use checksums |
e44459b92c8be209a538f758ab5e0e2e0fb7442f079fcc417ed43ab3802d42c4
|
| 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 8, 2026.
Transparency logSecurity for prsentinel-cli 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
All 2 files in this release have been uploaded with provenance metadata.
Attestation for prsentinel_cli-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 8, 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.