Skip to main content

lgtmaybe logo: a shrugging face with curly-brace arms

lgtmaybe

AI code review for GitHub, GitLab, Gitea, and Azure DevOps, or your local Git diff. Choose from seven hosted providers, ollama, or any OpenAI-compatible endpoint. On a pull or merge request, lgtmaybe posts inline findings and a summary; the CLI prints findings locally. Bedrock, Vertex, and Azure support keyless cloud auth.

📖 Full documentation: https://lgtmaybe.coles.codes/

What It Reviews

lgtmaybe fetches a pull or merge request's diff through the code host API, or reads your local Git diff. It reads surrounding lines for context and comments only on changed lines. It never checks out or runs pull request code.

Findings are graded from info to critical. The built-in lenses look for:

  • Correctness and security: logic errors, missed awaits, injection, broken authorisation, leaked secrets, and CI configuration risks.
  • Tests and documentation: missing coverage for changed behaviour, undocumented public APIs, and docs made stale by the change.
  • Code health: deprecated APIs, risky dependencies, performance regressions, and needless complexity.
  • Intent: changes that contradict the PR title, description, or commits, or leave promised behaviour unimplemented.
  • Ponytail: code that need not exist, including places where the standard library or a simpler approach would do.

What gets reviewed has the full scope and examples.

Generated files, lockfiles, vendored code, and binaries are skipped. The diff is treated as untrusted input, and detected secrets are redacted before any model call. See Data and Privacy for what is sent to a provider and how prompt injection is handled.

Fast by default. The fast preset covers all nine built-in categories in four model calls: security, correctness, code health, and artefacts (tests and documentation). --preset full runs each category separately for a deeper audit. A committed spec that matches the change adds one spec-review call. All calls share one concurrency limit, and providers that support prompt caching reuse the diff prefix. Add --profile to see time and token use.

Large changes stay bounded. The main controls are:

  • max_files (default 50) limits how many changed files are reviewed and reports the rest as skipped.
  • max_input_tokens (default 100k, fitted down to the model's context window when left unset) splits the diff into batches.
  • recursive (on by default) reviews an oversized file hunk by hunk; --no-recursive turns this off.
  • max_concurrency (default 6) limits simultaneous model calls. Local server settings also affect how many calls can run at once.
  • categories, min_severity, and path filters narrow what runs and what is reported. An explicit category list runs one call per selected lens.

See Configure .lgtmaybe.yml for every setting. For the measured recall and token cost of hunk-by-hunk review on a small local model, see the recursive-review benchmark.

What you get back. Each finding has a file, line, severity, title, explanation, and sometimes a suggested fix:

  • On a pull or merge request, findings appear on the changed lines, with one summary naming the model. A re-run on the same commit updates that summary, a new commit gets a new one, and findings already posted are not repeated. A clean review gets a 👍 LGTM!. GitHub and GitLab resolve a finding's conversation once a later run shows it fixed; Gitea cannot. See Where It Posts.
  • On the CLI, lgtmaybe review prints findings without posting them. Choose readable output (the default), JSON (--json), instructions for a coding agent (--format agent), or a SARIF log for GitHub code scanning (--format sarif).

Slash commands on a pull or merge request: /review and /improve refresh the review, /ask <question> answers in the conversation, /describe posts a structured description, and /diagram posts a change overview. The overview covers the risk of change, high-impact areas, and a Mermaid flowchart, plus a sequence diagram when the change alters a runtime flow. Run lgtmaybe diagram for a local text version. See Generate a change overview.

On GitHub and GitLab, a push triggers an incremental review of only the new commits. Optional triage_model lets a cheap model skip plainly non-substantive files. Optional static_analysis runs installed tools: ruff, bandit, mypy, and semgrep feed hints to the model, while gitleaks, zizmor, ast-grep, and osv-scanner post deterministic findings directly. See Reduce review cost.

An inline lgtmaybe review comment on a GitHub pull request flagging a [CRITICAL] SQL injection vulnerability, with an explanation and a suggested parameterised-query fix

On a GitHub PR: an inline comment on the changed line. The same findings on the CLI:

The lgtmaybe review command running in a terminal, printing a finding with its file, line, severity, and a summary line naming the model

A fuller walkthrough with example output is in What gets reviewed.

Quick Start (Local, No API Key)

Start ollama and pull a model as shown in Getting Started. Then, from a Git branch with changes, review the diff against the primary branch:

pip install lgtmaybe        # or Homebrew/WinGet: see docs/how-to/install-the-cli.md

lgtmaybe config init        # detects ollama or your API key, checks it, saves it
lgtmaybe review

config init finds a running ollama (and its pulled models) or a provider API key in your environment, suggests a current model, checks it with one tiny request, and saves the provider and model (never the key). You can skip it and pass --provider ollama --model qwen3.6:27b instead; with neither, review stops at once and says so rather than guessing a model.

You need no GitHub token and no pull request: lgtmaybe review reads your local git diff and prints the findings. lgtmaybe diagram takes the same flags and prints the change overview: what the change is, its high-impact areas, and a picture of the components it touches and the flow it alters. Run review then diagram before opening a pull request. See Generate a change overview. To run the review from your Git hooks on every push, use the pre-commit hooks.

lgtmaybe --help lists every command with usage examples, lgtmaybe review --help shows the everyday options, and lgtmaybe review --help-all adds the advanced tuning ones. To post reviews on real pull requests, set up the GitHub Action, or on another host, GitLab CI, Gitea Actions or Azure Pipelines. Getting Started has the full walkthrough, and Choose a review model compares models.

Providers

Provider Auth Guide
openai OPENAI_API_KEY OpenAI
anthropic ANTHROPIC_API_KEY Claude
openrouter OPENROUTER_API_KEY OpenRouter
zai ZAI_API_KEY for GLM / Zhipu AI models (glm-4.6, glm-4.7, glm-4.5-air, glm-5.x). Optional --api-base for the China / coding-plan endpoint z.ai (GLM)
bedrock Ambient AWS creds via GitHub OIDC, no static key Bedrock
vertex Ambient GCP creds via Workload Identity Federation, no key Vertex
azure Resource endpoint, plus AZURE_API_KEY or keyless Entra (Azure AD) creds via GitHub OIDC Azure
ollama None: local only, zero cost ollama
openai-compatible Any OpenAI /v1 endpoint via --api-base (DeepSeek, llama.cpp, LM Studio, vLLM). Key optional: --api-key / OPENAI_COMPATIBLE_API_KEY, or none for local servers Local & OpenAI-compatible

Where It Posts

The model provider and the code host are independent choices: any provider above works on any host below.

Host How it runs Token Guide
GitHub GitHub Action (MattJColes/lgtmaybe@v2) GITHUB_TOKEN GitHub Action
GitLab GitLab CI job (lgtmaybe gitlab-ci) GITLAB_TOKEN Review on GitLab
Gitea Gitea Actions (same container) GITEA_TOKEN Review on Gitea
Azure DevOps Azure Pipelines job (lgtmaybe azure-pipelines) SYSTEM_ACCESSTOKEN or AZURE_DEVOPS_TOKEN Review on Azure DevOps
None lgtmaybe review on your local diff n/a Install the CLI

The review is the same everywhere: same lenses, same reflection pass, same findings. What differs is what each host's API can do with the result:

GitHub GitLab Gitea Azure DevOps
Inline comments + summary ✅ ✅ ✅ ✅
Slash commands ✅ ✅ ✅ not yet
Auto-resolve a fixed finding ✅ ✅ ✗ no thread API not yet
Incremental re-review ✅ ✅ ✗ no compare diff not yet
Learn from 👎 on a finding ✅ reactions ✅ award emoji ✗ not yet
Keyless cloud auth (OIDC/WIF) ✅ ✗ use an API key ✗ use an API key ✗ use an API key

Documentation

Browse the rendered docs at https://lgtmaybe.coles.codes/, or read the Markdown sources below. For LLM agents, a curated llms.txt index and a whole-corpus llms-full.txt are published at the docs root.

Tutorial: learn by doing

How-to guides: task recipes

Reference: look things up

Explanation: understand the design

  • What gets reviewed: scope, caps, and what the output looks like
  • Risk of change: how the low/medium/high/critical verdict is reached
  • Architecture: ports and adapters, the review pipeline
  • Auth Model: why keyless cloud, how credential resolution works
  • Data and Privacy: what is sent where, secret redaction, ollama local mode
  • Trust and Cost: who reviews run for (everyone, trusted contributors, or admins) and what that costs

Use as a GitHub Action

Use lgtmaybe from the GitHub Marketplace. It is a GitHub Action, so its settings live in your workflow. In .github/workflows/lgtmaybe.yml, set provider, model, and the matching authentication input in the step's with: block. This complete example uses OpenAI and runs reviews only for trusted contributors:

name: lgtmaybe

on:
  pull_request_target:
  issue_comment:
    types: [created]

permissions:
  contents: read
  pull-requests: write

jobs:
  review:
    # Trusted authors only, and a comment starts a job only when it carries
    # one of lgtmaybe's slash commands (issue_comment fires on every comment).
    if: >-
      (github.event_name == 'pull_request_target' &&
       contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association)) ||
      (github.event.issue.pull_request &&
       contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) &&
       (contains(github.event.comment.body, '/review') ||
        contains(github.event.comment.body, '/improve') ||
        contains(github.event.comment.body, '/ask') ||
        contains(github.event.comment.body, '/describe') ||
        contains(github.event.comment.body, '/diagram')))
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7 # base repo only, for .lgtmaybe.yml
      - uses: MattJColes/lgtmaybe@v2
        with:
          provider: openai
          model: gpt-5.5
          api_key: ${{ secrets.OPENAI_API_KEY }}

Using a different model provider? Copy-paste workflows for every cloud and API-key provider live in examples/workflows/. Cloud providers (Bedrock, Vertex, Azure) are keyless: pass aws_role_arn, gcp_wif_provider, or azure_client_id and the action does the OIDC/WIF exchange for you (it needs id-token: write). See Use as a GitHub Action. ollama is local only, so run it through the CLI instead.

Not on GitHub?

lgtmaybe runs the same review on GitLab, Gitea and Azure DevOps. Only the wiring changes:

Keyless cloud auth is a GitHub Actions feature, so on the other hosts use an API-key provider, or ollama against a runner-local model for zero cost.

By default, reviews post as github-actions[bot]. To post as lgtmaybe[bot], install the public lgtmaybe App, grant the workflow id-token: write, and add github_identity: lgtmaybe beside the provider settings. You never receive or manage the App's private key. lgtmaybe still runs as the Action in your workflow; the App changes only the GitHub author identity. See Post as lgtmaybe[bot].

🔧 Choose who can trigger reviews. Reviews can run for everyone, trusted contributors, or just admins. The example workflows default to trusted contributors (OWNER, MEMBER, COLLABORATOR), and it's a one-line change to open it up or tighten it. With ollama this is free; on a hosted provider it also keeps token spend predictable. See Who can trigger a review and Trust and Cost.

Distribution

  • CLI (PyPI): pip install lgtmaybe
  • CLI (Homebrew): brew tap MattJColes/tap && brew trust MattJColes/tap && brew install lgtmaybe (details; the brew trust step is required for third-party taps)
  • CLI (WinGet, Windows x64): winget install --id MattJColes.lgtmaybe --exact (details)
  • GitHub Action: uses: MattJColes/lgtmaybe@v2

Contributing

Test-first, green CI, scope is the gate. See CONTRIBUTING.md.

Licence

MIT. See LICENSE.

Metadata

Release files for lgtmaybe 2.12.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 lgtmaybe 2.12.0
File Size Uploaded
lgtmaybe-2.12.0.tar.gz 4.5 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for lgtmaybe 2.12.0
File Interpreter ABI Platform
lgtmaybe-2.12.0-py3-none-any.whl Python 3 none any Details

Total release size: 4.9 MB

Release files / lgtmaybe-2.12.0.tar.gz

Download URL lgtmaybe-2.12.0.tar.gz
Size 4.5 MB
Tags Source
SHA-256 checksum
How to use checksums
00ab0865ccf3b731ada39de9f81a543aa21b8bf14f9dbbe1aa20015e7ad8d833
BLAKE2b-256 checksum
How to use checksums
2acc885741041f52ad9e5f41be58bcda71c0d3630fa4bf82767b16ee5c7293eb
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 Oct 13, 2026.

Transparency log

Release files / lgtmaybe-2.12.0-py3-none-any.whl

Download URL lgtmaybe-2.12.0-py3-none-any.whl
Size 437.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c1aea946d38fbf5235ccb051efe1e45d9ca0faa5abeb45f01170405a4f884a69
BLAKE2b-256 checksum
How to use checksums
15c18e2fc8bade987b0de40a154b31c96b283fd88f39af0bd91ff584a9f4d9dc
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 Oct 13, 2026.

Transparency log

Release history Release notifications | RSS feed

2.13.0

2 release files

This release

2.12.0 This release

2 release files

2.11.1

2 release files

2.11.0

2 release files

2.10.0

2 release files

2.9.1

2 release files

2.9.0

2 release files

2.8.5

2 release files

2.8.4

2 release files

2.8.3

2 release files

2.8.2

2 release files

2.8.1

2 release files

2.8.0

2 release files

2.7.0

2 release files

2.6.2

2 release files

2.6.1

2 release files

2.6.0

2 release files

2.5.1

2 release files

2.5.0

2 release files

2.4.0

2 release files

2.3.0

2 release files

2.2.0

2 release files

2.1.4

2 release files

2.1.3

2 release files

2.1.2

2 release files

2.1.1

2 release files

2.1.0

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.14.1

2 release files

1.14.0

2 release files

1.9.1

2 release files

1.9.0

2 release files

1.8.1

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.0

2 release files

1.5.5

2 release files

1.5.4

2 release files

1.5.3

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.13.1

2 release files

0.13.0

2 release files

0.12.2

2 release files

0.12.1

2 release files

0.12.0

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.1

2 release files

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