Skip to content

AI providers

An AI provider is one endpoint mr-review sends the diff to. Providers are created in the app under Settings → AI Providers, not in the environment: there is no AI_PROVIDER, AI_API_KEY or AI_MODEL variable. The form calls POST /api/v1/ai-providers, and the provider is stored in ai_providers.yaml in the data directory, API key included.

Types

Three types, two backends:

Type Shown as Backend
claude Claude Anthropic Messages API, streamed. base_url is ignored
openai OpenAI OpenAI chat completions, streamed
openai_compat OpenAI-compat The same client, pointed elsewhere by base_url

openai and openai_compat behave identically — the distinction is a label for the reader.

Fields

Field Default What it does
name Display label
type One of the three above
api_key Sent to the endpoint. Stored in plain text in the data directory
base_url "" Empty means the backend's own default. Ignored by claude
models [] The models offered in the dispatch form
ssl_verify true false disables certificate verification entirely
timeout 60 Seconds, for the whole streamed response
max_concurrent unset Dispatches to this provider allowed in flight at once

The settings form covers all of these except models, which is edited on the provider row once it exists, and max_concurrent, which is set through the API or by editing ai_providers.yaml.

For a corporate CA, install it in the system trust store rather than turning ssl_verify off — the HTTP client reads the system store, not a bundled one.

Pointing at an endpoint

Endpoint Type base_url
Anthropic claude
OpenAI openai leave blank
Ollama on the same machine openai_compat http://localhost:11434/v1
Ollama, with mr-review in Docker openai_compat http://host.docker.internal:11434/v1
Groq, Together, LM Studio, a gateway openai_compat the endpoint's own /v1 URL

localhost inside the container is the container, not your machine — a local model reached from a container needs host.docker.internal (Docker Desktop) or the host's LAN address.

Choosing a model

GET /api/v1/ai-providers/{id}/models asks the endpoint itself which models it has; the app offers that list when you edit a provider. The first entry of models is used when a dispatch names no model of its own, and with an empty list the fallback is claude-opus-4-5 for claude and gpt-4o for the OpenAI backends.

For code review, models with large context windows do best. The diff, pinned lines, commit message and review brief all go into one prompt — large MRs can exceed 20k tokens, and the optional context toggles add more.

A dispatch may also carry temperature, reasoning_budget (extended thinking on Claude, which forces temperature=1) and reasoning_effort (low, medium or high, for OpenAI reasoning models).

Concurrency

Each provider has a cap on how many dispatches to it can be in flight at once: max_concurrent, falling back to MR_REVIEW__AI_THROTTLE__DEFAULT_MAX_CONCURRENT (4). It exists to keep a local model from being overwhelmed and to put a coarse ceiling on cloud usage.

max_concurrent has no field in the settings form: set it with POST/PATCH /api/v1/ai-providers, or edit ai_providers.yaml directly.

The cap is fixed at first use either way. The semaphore is created on the first dispatch to a provider and kept for the life of the process, so a changed max_concurrent takes effect on the next restart, not on the next dispatch.