Skip to main content

PR Sentinel

CI PyPI version Downloads Python versions Docker image License: MIT

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)

Source distribution for prsentinel-cli 1.4.0
File Size Uploaded Provenance
prsentinel_cli-1.4.0.tar.gz 57.3 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for prsentinel-cli 1.4.0
File Interpreter ABI Platform
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 log

Release 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 log

Security 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.

Select from 2 files

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 log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page