Agent-readable docs index: /llms.txt. Full docs in one file: /llms-full.txt. Download /docs.zip to grep all markdown files locally.

Configuration

mikro uses a layered configuration system. Configuration lives in a .mikro/ directory inside the directory you run mikro from, usually your project root.

.mikro/ directory

Run mikro init to scaffold the config directory. Choose a template with --template default (general-purpose) or --template code (code analysis).
.mikro/ ├── mikro.yaml # Main configuration (model, budget, context, storage) ├── SYSTEM.md # System prompt used by the RLM loop ├── CRITERIA.md # Output criteria for quality checks └── TOOLS.md # Custom Python tools exposed to the RLM
FilePurpose
mikro.yamlModel provider, budget limits, context loading, storage, and session settings
SYSTEM.mdOverride the default RLM paper system prompt — edit only if you know what you are doing
CRITERIA.mdOutput criteria appended to the system prompt (e.g., "Be concise", "Cite file paths")
TOOLS.mdCustom Python functions injected into the REPL namespace

Projects set up before the rename

mikro was named rlmx until 2026-08-29. When .mikro/mikro.yaml is missing, mikro still reads a pre-rename rlmx.yaml in .rlmx/, together with the SYSTEM.md, CRITERIA.md and TOOLS.md beside it, and prints a warning on stderr. A query run (mikro "...") scaffolds a fresh .mikro/ before it loads config, and from then on the new directory wins over the old one. Rename the old directory before your first query:
mikro migrate # dry run: lists what it would change mikro migrate --apply # renames .rlmx/ to .mikro/ and rlmx.yaml to mikro.yaml
mikro migrate scans the current directory and your home directory. Once a .mikro/ exists beside the old directory, it only reports the old one for you to delete by hand.

mikro.yaml

The primary config file inside .mikro/. Run mikro init to scaffold one with inline comments.
# Model configuration model: provider: google # pi/ai provider: google, anthropic, openai, etc. model: gemini-3.1-flash-lite-preview # Model ID sub-call-model: gemini-3.1-flash-lite-preview # Model for llm_query() sub-calls (optional) # The system prompt, output criteria and custom tools live in SYSTEM.md, # CRITERIA.md and TOOLS.md beside this file. mikro.yaml has no system:, # criteria: or tools: keys. # Context loading configuration context: extensions: - .md - .ts - .js exclude: - node_modules - .git - dist # Budget limits (null = unlimited) budget: max-cost: null # Maximum USD per run max-tokens: null # Maximum total tokens per run max-depth: null # Maximum recursive rlm_query depth # Tool level: core, standard, or full tools-level: core # Cache/CAG configuration cache: enabled: false # Enable provider-level prompt caching retention: long # short | long, maps to the provider's cache retention ttl: 3600 # seconds; shown by `mikro cache`, not sent to the provider expire-time: "" # ISO 8601; accepted, not sent to the provider session-prefix: "" # Prepended to content hash for cache key # pgserve storage for contexts larger than the provider limit storage: enabled: auto # auto | always | never mode: persistent # persistent | memory data-dir: ~/.mikro/data # also where `mikro stats` reads from port: 0 # 0 picks a free port chunk-size: null # null derives it from the model context window chunk-utilization: 0.6 # fraction of the context window per chunk chars-per-token: 4 # ratio used for token estimates # Gemini 3 features. thinking-level applies to any provider whose model # supports a reasoning level; the other keys are ignored on non-Google providers. gemini: thinking-level: null # minimal | low | medium | high google-search: false # Enable web_search() battery in REPL url-context: false # Enable fetch_url() battery in REPL code-execution: false # Enable server-side Python execution media-resolution: images: auto # low | medium | high | auto pdfs: auto video: auto # Structured output (Gemini only — other providers use FINAL() fallback) output: schema: type: object properties: answer: type: string confidence: type: number

Config sections explained

model

Controls which LLM provider and model mikro uses. Supports any provider available in pi/ai.
FieldDescription
providerProvider name: google, anthropic, openai, etc.
modelModel ID (provider-specific)
sub-call-modelOptional model for llm_query() sub-calls. Defaults to model if omitted.

context

Controls how files are loaded when --context points to a directory.
FieldDescription
extensionsFile extensions to include (default: [".md"])
excludeDirectory/file patterns to skip (default: ["node_modules", ".git", "dist"])

budget

Safety limits to prevent runaway costs.
FieldDescription
max-costMaximum USD spend per run. null = unlimited.
max-tokensMaximum total tokens per run. null = unlimited.
max-depthMaximum recursive rlm_query nesting depth. null = unlimited.
Without budget limits, a complex query with recursive sub-calls can get expensive. Set max-cost for production use.

cache

Controls provider-level context caching (CAG mode). See Cache Mode for the end-to-end flow and Batch Mode for bulk usage patterns.
FieldDescription
enabledEnable caching. Can also use --cache flag per-invocation.
retentionshort or long (default): the cache retention mikro asks the provider for.
ttlSeconds. Shown in mikro cache output; mikro does not send it to the provider.
expire-timeISO 8601 timestamp. Accepted, but mikro does not send it to the provider.
session-prefixPrepended to the content hash for the cache session ID.

storage

pgserve-backed storage for contexts larger than the provider limit. A run in storage mode loads the context into Postgres, queries it from the REPL with pg_search(), pg_slice(), pg_sources(), pg_time(), pg_count() and pg_query(), and records its calls for mikro stats.
FieldDescription
enabledauto (default) switches to storage mode when the context exceeds the provider limit; always uses it for every run; never turns it off.
modepersistent (default) keeps data on disk; memory keeps it in memory only.
data-dirWhere pgserve stores data, and where mikro stats reads from. Default ~/.mikro/data.
port0 (default) picks a free port.
chunk-sizenull (default) derives the chunk size from the model context window.
chunk-utilizationFraction of the context window to use per chunk, above 0 and up to 1. Default 0.6.
chars-per-tokenCharacter-to-token ratio for estimates. Default 4.

gemini

Gemini 3 native features. thinking-level reaches any provider whose model supports a reasoning level; the other fields are opt-in and silently ignored on non-Google providers.
FieldDescription
thinking-levelControls reasoning depth: minimal, low, medium, high. Despite the gemini prefix, it applies to every provider whose model accepts a reasoning level.
google-searchEnable web_search() battery in REPL
url-contextEnable fetch_url() battery in REPL
code-executionEnable server-side Python execution alongside local REPL
media-resolutionPer-type token cost control for images, PDFs, and video

output.schema

JSON Schema for structured output. On Google providers, this is enforced via the API. On other providers, mikro falls back to FINAL() text parsing.

Global settings

Global settings are stored at ~/.mikro/settings.json and managed with mikro config commands.
# Set an API key mikro config set GEMINI_API_KEY your-key # Set a default provider mikro config set model.provider google # View all settings mikro config list # Show settings file path mikro config path
See the CLI Reference for the full list of config commands and keys.

Priority order

Settings are resolved highest-priority first:
PrioritySourceExample
1 (highest)CLI flags--max-cost 0.10, --model openai/gpt-4o
2Global settings, for the model keysmodel.provider in ~/.mikro/settings.json
3Project .mikro/mikro.yamlbudget.max-cost: 0.50
4 (lowest)Hardcoded defaultsmax-iterations: 30
From ~/.mikro/settings.json, mikro reads only API keys, model.provider, model.model, model.sub-call-model, and a providers block. Budgets, tool level, cache and Gemini options come from .mikro/mikro.yaml or a flag.

.mikro/ companion files

The prompt, the output criteria and custom tools live in Markdown files beside mikro.yaml. mikro loads them from .mikro/ whenever .mikro/mikro.yaml exists, and mikro.yaml has no keys for them.
FilePurpose
SYSTEM.mdSystem prompt for the RLM loop
TOOLS.mdCustom Python tools
CRITERIA.mdOutput criteria

SYSTEM.md

The system prompt sent to the LLM. mikro init writes the RLM paper prompt here, which includes research-backed guidance on decomposition, tool use, and iterative reasoning. Override it only if you have a specific need.
The system prompt supports a {custom_tools_section} placeholder that mikro replaces with your custom tool definitions. Without the placeholder, mikro appends them after the prompt.

CRITERIA.md

Quality and format criteria appended to the system prompt. Use this to control output style without touching the core system prompt.
- Be concise and direct - Cite specific file paths when referencing code - Use code blocks for code snippets

TOOLS.md format

Custom Python functions injected into the REPL namespace. Each tool is a ## heading with the function name, followed by a Python code block with its source:
## search_docs ` ``python def search_docs(keyword): """Search context for files matching keyword.""" matches = [item for item in context if keyword.lower() in item['content'].lower()] return [m['path'] for m in matches] ` `` ## summarize_chunk ` ``python def summarize_chunk(text, max_words=100): """Summarize a chunk using an LLM sub-call.""" return llm_query(f"Summarize in {max_words} words:\n{text}") ` ``
Custom tools have access to:
  • context, the loaded context variable
  • llm_query(), to make LLM sub-calls
  • Standard Python builtins, except eval, exec, input, compile, globals and locals, which the REPL blocks

Environment variables

API keys can also be set as environment variables instead of using mikro config set:
VariableProvider
GEMINI_API_KEYGoogle Gemini
ANTHROPIC_API_KEYAnthropic
OPENAI_API_KEYOpenAI
GROQ_API_KEYGroq
XAI_API_KEYxAI
OPENROUTER_API_KEYOpenRouter
Keys set via mikro config set are injected into process.env before any command runs, so they behave like environment variables. When the environment variable is already set, it wins over the stored key.