Deployment config (mira.yaml)
The deployment-wide YAML loaded via `mira serve --config`. The main place Mira is configured, and the canonical schema reference for every llm / filter / review key.
mira.yaml is where you configure Mira. One file, three sections
(llm, filter, review), and every key is optional. Whatever you set
here applies to every PR Mira reviews, unless a repo overrides it in
.mira.yaml or the dashboard.
This page is the canonical reference for those three sections: every key, default, and what it does.
Loading
# Local CLI
mira serve --config /etc/mira/mira.yaml
# Docker — mount the file and point the env var at it
docker run -p 8000:8000 \
-v /etc/mira/mira.yaml:/app/mira.yaml:ro \
-e MIRA_CONFIG=/app/mira.yaml \
-e MIRA_GITHUB_APP_ID=123456 \
-e MIRA_GITHUB_PRIVATE_KEY="$(cat private-key.pem)" \
-e MIRA_WEBHOOK_SECRET=… \
-e OPENROUTER_API_KEY=sk-or-… \
ghcr.io/miracodeai/mira:latestSecrets stay in environment variables. mira.yaml is for defaults:
GitHub App ID, private key, webhook secret, OpenRouter key, database URL,
and admin password are all still env-var inputs. This is intentional:
most teams check mira.yaml into a git-managed config repo, and you don't
want secrets in there.
Full example
A complete mira.yaml showing every key at its default. Copy this, delete
anything you're happy with the default for, and you have your config.
# mira.yaml — deployment-wide defaults. Every key is optional.
llm:
provider: "openai" # openai | bedrock | codex-cli
model: "anthropic/claude-sonnet-4-6"
fallback_model: "anthropic/claude-haiku-4-5"
indexing_model: "anthropic/claude-haiku-4-5"
review_model: "anthropic/claude-sonnet-4-6"
security_model: "anthropic/claude-sonnet-4-6"
review_reasoning_effort: "off" # off | low | medium | high | xhigh | max
temperature: 0.2
max_tokens: 4096
max_context_tokens: 120000
# Point at any OpenAI-compatible endpoint — vLLM, Ollama, LiteLLM proxy,
# LocalAI, llama.cpp, Together, Fireworks, Groq, etc.
# Defaults to OpenRouter.
api_style: "chat" # chat | responses
base_url: "https://openrouter.ai/api/v1"
api_key_env: "OPENROUTER_API_KEY"
region: "us-east-1"
aws_profile: null
max_retries: 3
request_timeout: 120
retry_min_wait: 2
retry_max_wait: 30
codex_command: "codex"
codex_home: null
codex_sandbox: "read-only"
codex_timeout_seconds: 900
filter:
confidence_threshold: 0.7
category_confidence_thresholds: {}
max_comments: 5
min_severity: "nitpick"
exclude_deleted: true
max_files: 50
exclude_patterns:
- "*.lock"
- "package-lock.json"
- "*.min.js"
- "*.svg"
- "*.png"
# Only auto-review PRs from these authors (empty = review all).
allowed_authors: []
# Never auto-review PRs from these authors; wins over allowed_authors.
# "dependabot" also matches "dependabot[bot]".
blocked_authors: []
review:
context_lines: 3
max_diff_size: 250000
max_file_size: 50000
max_chunks_per_review: 5
include_summary: true
focus_only_on_problems: false
walkthrough: true
walkthrough_sequence_diagram: true
pr_summary: "disable" # disable | append | replace
code_context: true
context_token_budget: 8000
max_concurrent_chunks: 5
self_critique: true
security_pass: true
security_agentic: true
osv_scan: true
secrets_scan: true
agentic_tools: true
jit_java_go: true
blast_radius: true
ensemble_runs: 1
ensemble_temperature: 0.3
auto_resolve_conversations: true
review_on_synchronize: true
dependency_overlap: true
overlap:
enabled: true
max_candidates: 20
confidence_floor: 0.6
title_similarity_threshold: 0.4
index:
max_file_size: 1048576llm
Controls which model is used and how it's invoked.
| Key | Type | Default | Description |
|---|---|---|---|
provider | string | openai | Model backend: openai for OpenAI-compatible HTTP APIs, bedrock for AWS Bedrock, or codex-cli for a local Codex login. See Choosing a model. |
model | string | anthropic/claude-sonnet-4-6 | Default model for both indexing and review unless overridden. Any recognised model. |
fallback_model | string | unset | If the primary model errors, retry with this one. |
indexing_model | string | uses model | Override just for the indexing pass, usually a cheaper/faster model. |
review_model | string | uses model | Override just for the review pass, usually a stronger model. |
security_model | string | uses review_model, then model | Override the focused security pass. It never falls back to indexing_model. |
review_reasoning_effort | string | off | Review-only reasoning level: off, low, medium, high, xhigh, or max. Unsupported levels are dropped rather than failing the review. |
temperature | float | 0.2 | Sampling temperature. Reviews are mostly deterministic; raising this is rarely useful. |
max_tokens | int | 4096 | Cap on output tokens per LLM call. |
max_context_tokens | int | 120000 | How many input tokens Mira is willing to spend per call. Trims context to fit. |
api_style | string | chat | OpenAI-compatible protocol: chat for Chat Completions or responses for the Responses API. Ignored by Bedrock and Codex CLI. |
base_url | string | https://openrouter.ai/api/v1 | The OpenAI-compatible endpoint Mira sends requests to. Override for self-hosted models or alternative providers. See Custom endpoints below. |
api_key_env | string | OPENROUTER_API_KEY | Name of the environment variable Mira reads the API key from. Set to "" (empty string) for local endpoints that need no auth. |
region | string | us-east-1 | AWS region used by the Bedrock provider. |
aws_profile | string | unset | Optional named AWS profile for Bedrock; otherwise the standard credential chain is used. |
max_retries | int | 3 | Attempts per LLM call before giving up. Only transient failures retry (timeouts, network errors, 5xx/429); 4xx errors fail immediately. |
request_timeout | int (seconds) | 120 | Per-request timeout. Raise for flex-tier models or proxied endpoints that stall under load. |
retry_min_wait | int (seconds) | 2 | Lower bound of the exponential backoff between retries. |
retry_max_wait | int (seconds) | 30 | Upper bound of the backoff between retries. |
codex_command | string | codex | Codex executable name or absolute path. Arguments are not accepted. Deployment-only. |
codex_home | string | $CODEX_HOME | Directory containing the operator's auth.json. Deployment-only. |
codex_sandbox | string | read-only | Codex execution sandbox. read-only is the only accepted value. Deployment-only. |
codex_timeout_seconds | int | 900 | Timeout for one Codex invocation. Deployment-only. |
Custom endpoints
Any compatible Chat Completions API works. Endpoints that implement the OpenAI
Responses API can instead set llm.api_style: responses. Point llm.base_url at
the right URL and set llm.api_key_env to the env var holding the key. Mira looks
up a provider profile by base_url to apply any per-provider quirks
(attribution headers, whether the model id keeps its vendor/ prefix, reasoning
remapping); an endpoint with no profile gets the portable default — bare model
name, no extra headers — so most providers need nothing more than base_url +
api_key_env.
Ollama (local, no auth):
llm:
base_url: "http://localhost:11434/v1"
api_key_env: ""
model: "llama3.1:70b"vLLM (your own GPU server):
llm:
base_url: "http://vllm.internal:8000/v1"
api_key_env: "VLLM_API_KEY"
model: "meta-llama/Meta-Llama-3.1-70B-Instruct"LiteLLM proxy (route to many providers under one URL):
llm:
base_url: "http://litellm:4000/v1"
api_key_env: "LITELLM_MASTER_KEY"
model: "claude-sonnet-4-6"Together / Fireworks / Groq / Cerebras / Anyscale / LocalAI use the same
shape; set base_url to the provider's /v1 endpoint and api_key_env to the env
var holding your key.
Adding a provider profile
Profiles only matter when a provider needs a quirk the default doesn't cover
(ranking headers, keeping the vendor/model prefix, remapping a reasoning
level). The bundled set lives in src/mira/llm/providers.json; to add or
override one at runtime without forking, point MIRA_PROVIDERS_JSON_PATH at
your own file — the same override idiom as MIRA_MODELS_JSON_PATH for the model
registry. A profile is matched to a request by base_url:
{
"acme": {
"base_url": "https://llm.acme.ai/v1",
"api_key_env": "ACME_API_KEY",
"model_prefix": "keep",
"extra_headers": { "X-Acme-Project": "mira" },
"reasoning_effort_map": { "max": "xhigh" }
}
}Reviews require the model to support tool/function calling. Most hosted providers support it; for self-hosted models pick one with structured-output support (Llama 3.1, Mixtral 8x22B, Qwen 2.5, DeepSeek V3, etc.).
filter
Controls which comments get posted. Mira filters aggressively by default; the goal is "every comment is one you'd want to land."
| Key | Type | Default | Description |
|---|---|---|---|
confidence_threshold | float (0.0–1.0) | 0.7 | Drop comments the LLM rated below this confidence. Raise for less noise; lower for more coverage. |
category_confidence_thresholds | map | {} | Per-category floors layered over confidence_threshold (the higher wins). E.g. {security: 0.85} holds security findings to a stricter bar without raising the global floor. |
max_comments | int | 5 | Hard cap on inline comments per PR. The most severe + most confident N are kept. |
min_severity | string | nitpick | Drop comments below this severity. Levels: nitpick, suggestion, warning, blocker. |
exclude_patterns | string[] | lockfiles, minified, images, fonts, archives | Glob patterns of files Mira should never review. Also applied to indexing — a file matching one of these is skipped by both the reviewer and the indexer (on top of the built-in skip list). |
exclude_deleted | bool | true | Skip files removed by the diff; they aren't there to comment on. |
max_files | int | 50 | Cap on files reviewed in a single PR. PRs above this are partially reviewed; the skipped files appear in the walkthrough. |
allowed_authors | string[] | [] | If non-empty, only PRs from these authors are auto-reviewed. Empty = review all. Applies to PR events, @mention commands, and push-triggered indexing; an explicit @miracodeai review bypasses the filter. |
blocked_authors | string[] | [] | Never auto-review PRs from these authors. Takes precedence over allowed_authors. A trailing [bot] is stripped for matching, so dependabot matches dependabot[bot]. |
A blocker severity comment auto-clamps the overall confidence and forces a
"Do not merge" recommendation, regardless of the LLM's initial read. This is
intentional and not configurable.
review
Controls how Mira reviews: diff sizing, walkthrough behaviour, parallelism.
| Key | Type | Default | Description |
|---|---|---|---|
context_lines | int | 3 | Lines of unchanged code shown around each hunk. |
max_diff_size | int | 250000 | Total diff size budget (chars). Above this, Mira ranks files by priority and skips lowest-priority ones to fit. Skipped files are listed in the walkthrough; invoke @miracodeai review-rest to review them. |
max_file_size | int | 50000 | A single file larger than this is skipped before chunking starts (lockfiles, generated SDKs). |
max_chunks_per_review | int (1–20) | 5 | Hard ceiling on chunks reviewed in one pass. Above this, the top-priority N run; the rest are listed as skipped. |
include_summary | bool | true | Post a top-level summary comment in addition to inline comments. |
focus_only_on_problems | bool | false | If true, only flag bugs / blockers, with no improvement suggestions. |
walkthrough | bool | true | Generate a top-level walkthrough comment with file coverage and per-severity stats. |
walkthrough_sequence_diagram | bool | true | Include a Mermaid sequence diagram in the walkthrough where it adds value. |
pr_summary | string | disable | Write an AI-generated release-notes block into the PR/MR description. append preserves author text and idempotently updates Mira's marked block; replace replaces the whole body. Requires walkthrough: true. |
code_context | bool | true | Pull related symbols / files from the index to give the LLM project context, not just diff context. |
context_token_budget | int | 8000 | How many tokens of indexed context Mira may add per review. |
max_concurrent_chunks | int (1–20) | 5 | Parallelism for chunk reviews. Raise if your LLM provider can handle it. |
self_critique | bool | true | Second-pass LLM critique on each draft comment; failed ones are dropped. Disable for faster reviews. |
security_pass | bool | true | Dedicated security review pass (XSS, injection, auth bypass, CSRF, SSRF, deserialization, crypto) in parallel with the main review. Uses llm.security_model, falling back to review_model and then model. |
security_agentic | bool | true | Let the focused security pass use read_file / grep_repo to verify cross-file claims when agentic tools and a live source fetcher are available. |
osv_scan | bool | true | Query OSV.dev for packages added or upgraded in changed dependency manifests. One batch request per applicable PR; no LLM involved. |
secrets_scan | bool | true | Scan added lines for hardcoded keys, tokens, and passwords with regex and entropy checks. Local and deterministic; no network or LLM call. |
agentic_tools | bool | true | Give the main reviewer read_file / grep_repo tools for on-demand cross-file context on indexed and unindexed repos. |
jit_java_go | bool | true | JIT cross-file resolver attempts Java + Go imports. Go resolves deterministically when a go.mod is present; Java is heuristic. Toggle off to A/B test impact. |
blast_radius | bool | true | Include in-repository callers and cross-repository dependents of changed code in the walkthrough. |
ensemble_runs | int (1–5) | 1 | Thorough mode: review each chunk N times in parallel and keep only majority-vote findings. Variance-driven false positives flicker across runs; real findings recur. 1 = off. Token cost multiplies by N; wall clock stays roughly flat. |
ensemble_temperature | float (0.0–1.0) | 0.3 | Sampling temperature for the extra ensemble runs (the first run keeps llm.temperature). Mild diversity makes the vote meaningful. |
auto_resolve_conversations | bool | true | Auto-resolve bot review threads the LLM verifies as fixed on each review pass. Disable to leave all bot comments open until a human resolves them (user-initiated reject/resolve replies still work). |
review_on_synchronize | bool | true | Auto-review on every push to an open PR. Set false to review only on open/reopen — later commits wait for an explicit @bot review. Cuts tokens and noise when you batch commits before pushing. |
dependency_overlap | bool | true | Flag when a PR adds a dependency that duplicates one the repo already has. Runs only when the PR changes a manifest (package.json, pyproject.toml, go.mod, …); lockfiles are excluded. |
review.overlap
Cross-PR overlap detection — while reviewing a PR, Mira compares it against the repo's other open PRs and flags ones stepping on it in the walkthrough: same files (merge-conflict risk) or same goal (duplicate effort). A cheap deterministic pre-filter runs first, so only genuinely-overlapping candidates cost an LLM call; stacked branches and draft PRs are excluded.
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Turn overlap detection off entirely. |
max_candidates | int (1–100) | 20 | How many recently-updated open PRs to compare against — bounds API calls and LLM cost on busy repos. |
confidence_floor | float (0.0–1.0) | 0.6 | Overlap verdicts the LLM scores below this are dropped. |
title_similarity_threshold | float (0.0–1.0) | 0.4 | A candidate sharing no files/symbols with the PR is kept only if its title is at least this similar (the duplicate-effort lane). |
index
Controls the codebase indexing pass that powers cross-file review context. Indexing also honours filter.exclude_patterns (see above).
| Key | Type | Default | Description |
|---|---|---|---|
max_file_size | int (bytes) | 1048576 | Skip indexing any file larger than this. Generated SDKs, vendored bundles, and large test fixtures burn indexing tokens for little value; lower this to keep indexing cheap on big repos. 0 disables the limit. |
How merging works
For each PR, Mira merges layers in this order (later wins):
mira.yaml, this file..mira.yamlin the repo, or the repo's dashboard settings.- Env-var fallbacks (
MIRA_MODEL,DATABASE_URL) if nothing above set the value.
Merging is per-key. A repo that sets filter.confidence_threshold: 0.5
inherits everything else from mira.yaml. Most repos don't need a
.mira.yaml at all.
Validation
mira serve --config … validates the YAML at startup. A typo or a wrong
type (e.g. confidence_threshold: "high") fails the boot rather than
silently no-op'ing on the first PR. The error names the offending field.
Where to next
Configuration overview
How Mira layers a deployment-wide config file, optional per-repo .mira.yaml overrides, the admin Settings UI, and environment variables.
.mira.yaml overrides
The optional per-repo .mira.yaml file overrides the deployment-wide mira.yaml for a single repo. Same schema, scoped to one repo.

Mira