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. A finding is one issue the review reports. On a pull or merge request, lgtmaybe posts its findings as inline comments plus one summary. The CLI prints findings locally. Bedrock, Vertex, and Azure support keyless cloud auth.
📖 Full documentation: https://lgtmaybe.coles.codes/
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.
Each finding has a severity from info
to critical. A lens is one focused review
question for the model. The built-in lenses look for:
awaits, injection,
broken authorisation, leaked secrets, and CI configuration risks.What gets reviewed has the full scope and examples.
lgtmaybe skips generated files, lockfiles, vendored code, and binaries. It treats the diff as untrusted input. It redacts detected secrets before any model call. See Data and Privacy for what lgtmaybe sends to a provider and how it handles prompt injection.
Fast by default. A preset sets how
many model calls a review spends. The fast preset covers all ten everyday
categories in five model calls:
--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. 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 one
hunk (block of changed lines) at a time.
--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:
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 are comments such as /review that you post on a pull or merge
request:
/review and /improve refresh the review./ask <question> answers in the conversation./describe posts a structured description./diagram posts a change overview.The overview covers the
risk of change,
high impact areas, and a
Mermaid flowchart. It adds 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.
static_analysis, on by default, runs any installed tools (ruff, bandit,
mypy, semgrep, gitleaks, zizmor, ast-grep, osv-scanner) and feeds their results
to the model as hints to confirm or discard. See
Reduce review cost.
On a GitHub PR: an inline comment on the changed line. The same findings on the CLI:
A fuller walkthrough with example output is in What gets reviewed.
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 does four things:
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. It shows 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.
Three help commands show the options:
lgtmaybe --help lists every command with usage examples.lgtmaybe review --help shows the everyday options.lgtmaybe review --help-all adds the advanced tuning ones.To post reviews on real pull requests, set up the GitHub Action. On another host, use GitLab CI, Gitea Actions or Azure Pipelines. Getting Started has the full walkthrough, and Choose a review model compares models.
| 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 |
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: the same lenses, the same reflection pass (the model checks its own findings), and the 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 |
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
--profile printsExplanation: understand the design
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.
lgtmaybe runs the same review on GitLab, Gitea and Azure DevOps. Only the wiring changes:
lgtmaybe gitlab-ci, gated on merge request
pipelines. See Review on GitLab and
examples/gitlab/.examples/gitea/.lgtmaybe azure-pipelines,
added as a build validation branch policy. See
Review on Azure DevOps and
examples/azure-devops/.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 only admins. The example workflows default to trusted contributors (
OWNER,MEMBER,COLLABORATOR). A one-line change opens it up or tightens 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.
pip install lgtmaybebrew tap MattJColes/tap && brew trust MattJColes/tap && brew install lgtmaybe
(details; the brew trust step is required for third-party taps)winget install --id MattJColes.lgtmaybe --exact
(details)uses: MattJColes/lgtmaybe@v2Test-first, green CI, scope is the gate. See CONTRIBUTING.md.
MIT. See LICENSE.
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. A finding is one issue the review reports. On a pull or merge request, lgtmaybe posts its findings as inline comments plus one summary. The CLI prints findings locally. Bedrock, Vertex, and Azure support keyless cloud auth.
📖 Full documentation: https://lgtmaybe.coles.codes/
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.
Each finding has a severity from info
to critical. A lens is one focused review
question for the model. The built-in lenses look for:
awaits, injection,
broken authorisation, leaked secrets, and CI configuration risks.What gets reviewed has the full scope and examples.
lgtmaybe skips generated files, lockfiles, vendored code, and binaries. It treats the diff as untrusted input. It redacts detected secrets before any model call. See Data and Privacy for what lgtmaybe sends to a provider and how it handles prompt injection.
Fast by default. A preset sets how
many model calls a review spends. The fast preset covers all ten everyday
categories in five model calls:
--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. 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 one
hunk (block of changed lines) at a time.
--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:
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 are comments such as /review that you post on a pull or merge
request:
/review and /improve refresh the review./ask <question> answers in the conversation./describe posts a structured description./diagram posts a change overview.The overview covers the
risk of change,
high impact areas, and a
Mermaid flowchart. It adds 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.
static_analysis, on by default, runs any installed tools (ruff, bandit,
mypy, semgrep, gitleaks, zizmor, ast-grep, osv-scanner) and feeds their results
to the model as hints to confirm or discard. See
Reduce review cost.
On a GitHub PR: an inline comment on the changed line. The same findings on the CLI:
A fuller walkthrough with example output is in What gets reviewed.
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 does four things:
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. It shows 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.
Three help commands show the options:
lgtmaybe --help lists every command with usage examples.lgtmaybe review --help shows the everyday options.lgtmaybe review --help-all adds the advanced tuning ones.To post reviews on real pull requests, set up the GitHub Action. On another host, use GitLab CI, Gitea Actions or Azure Pipelines. Getting Started has the full walkthrough, and Choose a review model compares models.
| 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 |
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: the same lenses, the same reflection pass (the model checks its own findings), and the 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 |
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
--profile printsExplanation: understand the design
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.
lgtmaybe runs the same review on GitLab, Gitea and Azure DevOps. Only the wiring changes:
lgtmaybe gitlab-ci, gated on merge request
pipelines. See Review on GitLab and
examples/gitlab/.examples/gitea/.lgtmaybe azure-pipelines,
added as a build validation branch policy. See
Review on Azure DevOps and
examples/azure-devops/.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 only admins. The example workflows default to trusted contributors (
OWNER,MEMBER,COLLABORATOR). A one-line change opens it up or tightens 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.
pip install lgtmaybebrew tap MattJColes/tap && brew trust MattJColes/tap && brew install lgtmaybe
(details; the brew trust step is required for third-party taps)winget install --id MattJColes.lgtmaybe --exact
(details)uses: MattJColes/lgtmaybe@v2Test-first, green CI, scope is the gate. See CONTRIBUTING.md.
MIT. See LICENSE.