Configuration

Configuration#

claude-review is configured with a single TOML file, passed via the --config flag (default: config.toml). Secrets can be overridden with environment variables.

Complete Annotated Example#

toml
# -----------------------------------------------------------------------
# Server
# -----------------------------------------------------------------------
[server]
listen = "0.0.0.0:3000"          # Bind address (default: "0.0.0.0:3000")
webhook_path = "/webhook"        # Webhook route (default: "/webhook")

# -----------------------------------------------------------------------
# GitHub App
# -----------------------------------------------------------------------
[github]
app_id = 123456                  # GitHub App ID (required)
private_key_path = "key.pem"     # Path to PEM private key (required unless GITHUB_APP_PRIVATE_KEY is set)
# api_base_url = "https://api.github.com"  # Override for GHES
# webhook_secret = "..."         # Prefer GITHUB_WEBHOOK_SECRET env var

# -----------------------------------------------------------------------
# LLM
# -----------------------------------------------------------------------
[llm]
provider = "claude"              # "claude", "anthropic", or "openai"
model = "claude-sonnet-4-6"
# api_key = "..."                # Prefer env var (ANTHROPIC_API_KEY, OPENAI_API_KEY, or LLM_API_KEY)
# base_url = "https://api.anthropic.com"  # Override for proxies / self-hosted
max_tokens = 4096                # Max output tokens (default: 4096)
# temperature = 0.2              # Sampling temperature (optional; ignored when extended thinking is on)

[llm.anthropic]                  # Anthropic-specific options (ignored for openai provider)
api_version = "2023-06-01"       # Anthropic API version header (default: "2023-06-01")
# betas = ["prompt-caching-2024-07-31"]  # Beta feature flags
prompt_caching = false           # Enable prompt caching (default: false)
extended_thinking = false        # Enable extended thinking (default: false)
# thinking_budget = 10000        # Token budget for thinking (default: 10000 when thinking is enabled)
# custom_headers = { "x-custom" = "value" }  # Extra headers sent with every request

# -----------------------------------------------------------------------
# Proxy (optional)
# -----------------------------------------------------------------------
# [proxy]
# http = "http://proxy:8080"
# https = "http://proxy:8080"
# socks5 = "socks5://proxy:1080"
# no_proxy = ["localhost", "127.0.0.1", "*.internal"]

# -----------------------------------------------------------------------
# Mention Trigger (@bot review)
# -----------------------------------------------------------------------
[mention_trigger]
enabled = false                  # Set to true to enable @mention triggers (default: false)
bot_name = "claude-review"       # Bot username to listen for (default: "claude-review")
ignore_bots = true               # Ignore comments from bot accounts (default: true)

# -----------------------------------------------------------------------
# Rate Limiting
# -----------------------------------------------------------------------
[rate_limit]
requests_per_hour = 60           # Token refill rate per repo (default: 60)
burst = 5                        # Max burst capacity (default: 5)
bypass_users = ["ci-bot"]        # Users exempt from rate limits

# -----------------------------------------------------------------------
# Whitelists (all empty = allow everything)
# -----------------------------------------------------------------------
[whitelist]
organizations = []               # Allowed GitHub orgs (empty = all)
users = []                       # Allowed users (empty = all)
repositories = []                # Allowed repos as "owner/repo" (empty = all)

# -----------------------------------------------------------------------
# Sandbox
# -----------------------------------------------------------------------
[sandbox]
enabled = true                   # Enable OS-level sandbox (default: true)
allowed_read_paths = []          # Extra paths mounted read-only in sandbox
allowed_write_paths = []         # Extra paths mounted read-write in sandbox
network_policy = "none"          # "none", "limited", or "full" (default: "none")
timeout_seconds = 300            # Process timeout in seconds (default: 300)

# -----------------------------------------------------------------------
# MCP Servers (optional)
# -----------------------------------------------------------------------
# [[mcp.servers]]
# name = "filesystem"
# type = "stdio"
# command = "npx"
# args = ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
# enabled = true
# [mcp.servers.env]
# NODE_ENV = "production"

# -----------------------------------------------------------------------
# Anti-injection
# -----------------------------------------------------------------------
[anti_injection]
max_title_length = 500           # Truncate PR titles beyond this length (default: 500)
max_description_length = 10000   # Truncate PR descriptions (default: 10000)
max_diff_length = 500000         # Truncate diffs (default: 500000)
max_comment_length = 5000        # Truncate individual comments (default: 5000)
suspicious_patterns = []         # Additional regex patterns to flag as suspicious

# -----------------------------------------------------------------------
# Rules (optional, repeatable)
# -----------------------------------------------------------------------
# [[rules]]
# name = "skip-generated"
# condition = 'file.path matches ".*\\.gen\\..*"'
# priority = 10
# [[rules.actions]]
# type = "skip_file"

Section Reference#

[server]#

Field
Type
Default
Description
listenstring"0.0.0.0:3000"Socket address to bind
webhook_pathstring"/webhook"HTTP path for GitHub webhook delivery

[github]#

Field
Type
Default
Env Override
Description
app_idintegerGitHub App ID (required)
private_key_pathpathGITHUB_APP_PRIVATE_KEY (base64)Path to the PEM private key file
api_base_urlstring"https://api.github.com"API base URL (set for GitHub Enterprise Server)
webhook_secretstringGITHUB_WEBHOOK_SECRETHMAC-SHA256 webhook secret

[llm]#

Field
Type
Default
Env Override
Description
providerstring"claude", "anthropic", or "openai" (required)
modelstringModel identifier (required)
api_keystringANTHROPIC_API_KEY, OPENAI_API_KEY, LLM_API_KEYAPI key
base_urlstringprovider defaultAPI base URL
max_tokensinteger4096Maximum output tokens
temperaturefloatSampling temperature (omit for provider default)

[llm.anthropic]#

Field
Type
Default
Description
api_versionstring"2023-06-01"anthropic-version header value
betasstring[][]Beta feature flags for anthropic-beta header
prompt_cachingboolfalseEnable prompt caching
extended_thinkingboolfalseEnable extended thinking
thinking_budgetinteger10000Token budget for thinking (only when extended thinking is enabled)
custom_headersmap{}Extra HTTP headers on every request

[proxy]#

Field
Type
Default
Description
httpstringHTTP proxy URL
httpsstringHTTPS proxy URL
socks5stringSOCKS5 proxy URL
no_proxystring[][]Hostnames/patterns excluded from proxying (sets NO_PROXY)

[mention_trigger]#

When enabled, users can comment @<bot_name> review on a pull request to trigger a review on demand. The same rate limits, whitelist rules, and deduplication apply. Requires subscribing to the Issue comment webhook event (requires Issues permission) in your GitHub App settings.

Field
Type
Default
Description
enabledboolfalseEnable @mention triggered reviews (opt-in)
bot_namestring"claude-review"Bot username to listen for (case-insensitive)
ignore_botsbooltrueIgnore comments from bot accounts (usernames containing [bot]) to prevent loops

[rate_limit]#

Field
Type
Default
Description
requests_per_hourinteger60Sustained request rate per repository
burstinteger5Maximum burst size (token bucket capacity)
bypass_usersstring[][]GitHub usernames exempt from rate limits

[whitelist]#

All three lists default to empty, which means everything is allowed. When any list is non-empty, only matching entries are permitted. The lists are evaluated with case-insensitive comparison.

Field
Type
Default
Description
organizationsstring[][]Allowed GitHub organization logins
usersstring[][]Allowed GitHub user logins
repositoriesstring[][]Allowed repositories as "owner/repo"

[sandbox]#

Field
Type
Default
Description
enabledbooltrueEnable OS-level sandboxing
allowed_read_pathspath[][]Additional paths mounted read-only
allowed_write_pathspath[][]Additional paths mounted read-write
network_policystring"none""none", "limited", or "full"
timeout_secondsinteger300Maximum execution time for sandboxed processes

[mcp]#

The mcp.servers key is an array of tables. Each entry defines one MCP server connection.

Field
Type
Default
Description
namestringUnique server name (used to prefix tool names)
typestringTransport: "stdio", "http", "sse", or "websocket" / "ws"
enabledbooltrueEnable/disable this server

Transport-specific fields are documented in MCP Integration.

[anti_injection]#

Field
Type
Default
Description
max_title_lengthinteger500Truncation limit for PR title
max_description_lengthinteger10000Truncation limit for PR body
max_diff_lengthinteger500000Truncation limit for the diff
max_comment_lengthinteger5000Truncation limit for individual comments
suspicious_patternsstring[][]Additional regex patterns appended to the built-in injection detectors

[[rules]]#

Rules are defined as an array of tables. See Rule Engine for the full expression language.

Field
Type
Default
Description
namestringHuman-readable rule name (required)
conditionstringExpression evaluated per file or per PR (required)
priorityinteger0Higher-priority rules are evaluated first
actionsarrayList of actions to execute when the condition is true

Environment Variable Precedence#

Environment variables override config file values. The resolution order for API keys is:

  1. LLM_API_KEY (highest priority, any provider)

  2. ANTHROPIC_API_KEY (for claude and anthropic providers)

  3. OPENAI_API_KEY (for openai provider)

  4. api_key in [llm] config (lowest priority)