.mikro/ directory inside the directory you run mikro from, usually your project root..mikro/ directorymikro init to scaffold the config directory. Choose a template with --template default (general-purpose) or --template code (code analysis).12345.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
| File | Purpose |
mikro.yaml | Model provider, budget limits, context loading, storage, and session settings |
SYSTEM.md | Override the default RLM paper system prompt — edit only if you know what you are doing |
CRITERIA.md | Output criteria appended to the system prompt (e.g., "Be concise", "Cite file paths") |
TOOLS.md | Custom Python functions injected into the REPL namespace |
.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:12mikro 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.mikro/. Run mikro init to scaffold one with inline comments.123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869# 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
| Field | Description |
provider | Provider name: google, anthropic, openai, etc. |
model | Model ID (provider-specific) |
sub-call-model | Optional model for llm_query() sub-calls. Defaults to model if omitted. |
--context points to a directory.| Field | Description |
extensions | File extensions to include (default: [".md"]) |
exclude | Directory/file patterns to skip (default: ["node_modules", ".git", "dist"]) |
| Field | Description |
max-cost | Maximum USD spend per run. null = unlimited. |
max-tokens | Maximum total tokens per run. null = unlimited. |
max-depth | Maximum recursive rlm_query nesting depth. null = unlimited. |
max-cost for production use.| Field | Description |
enabled | Enable caching. Can also use --cache flag per-invocation. |
retention | short or long (default): the cache retention mikro asks the provider for. |
ttl | Seconds. Shown in mikro cache output; mikro does not send it to the provider. |
expire-time | ISO 8601 timestamp. Accepted, but mikro does not send it to the provider. |
session-prefix | Prepended to the content hash for the cache session ID. |
pg_search(), pg_slice(), pg_sources(), pg_time(), pg_count() and pg_query(), and records its calls for mikro stats.| Field | Description |
enabled | auto (default) switches to storage mode when the context exceeds the provider limit; always uses it for every run; never turns it off. |
mode | persistent (default) keeps data on disk; memory keeps it in memory only. |
data-dir | Where pgserve stores data, and where mikro stats reads from. Default ~/.mikro/data. |
port | 0 (default) picks a free port. |
chunk-size | null (default) derives the chunk size from the model context window. |
chunk-utilization | Fraction of the context window to use per chunk, above 0 and up to 1. Default 0.6. |
chars-per-token | Character-to-token ratio for estimates. Default 4. |
thinking-level reaches any provider whose model supports a reasoning level; the other fields are opt-in and silently ignored on non-Google providers.| Field | Description |
thinking-level | Controls reasoning depth: minimal, low, medium, high. Despite the gemini prefix, it applies to every provider whose model accepts a reasoning level. |
google-search | Enable web_search() battery in REPL |
url-context | Enable fetch_url() battery in REPL |
code-execution | Enable server-side Python execution alongside local REPL |
media-resolution | Per-type token cost control for images, PDFs, and video |
FINAL() text parsing.~/.mikro/settings.json and managed with mikro config commands.1234567891011# 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
| Priority | Source | Example |
| 1 (highest) | CLI flags | --max-cost 0.10, --model openai/gpt-4o |
| 2 | Global settings, for the model keys | model.provider in ~/.mikro/settings.json |
| 3 | Project .mikro/mikro.yaml | budget.max-cost: 0.50 |
| 4 (lowest) | Hardcoded defaults | max-iterations: 30 |
~/.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 filesmikro.yaml. mikro loads them from .mikro/ whenever .mikro/mikro.yaml exists, and mikro.yaml has no keys for them.| File | Purpose |
SYSTEM.md | System prompt for the RLM loop |
TOOLS.md | Custom Python tools |
CRITERIA.md | Output criteria |
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.{custom_tools_section} placeholder that mikro replaces with your custom tool definitions. Without the placeholder, mikro appends them after the prompt.123- Be concise and direct - Cite specific file paths when referencing code - Use code blocks for code snippets
## heading with the function name, followed by a Python code block with its source:12345678910111213141516## 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}") ` ``
context, the loaded context variablellm_query(), to make LLM sub-callseval, exec, input, compile, globals and locals, which the REPL blocksmikro config set:| Variable | Provider |
GEMINI_API_KEY | Google Gemini |
ANTHROPIC_API_KEY | Anthropic |
OPENAI_API_KEY | OpenAI |
GROQ_API_KEY | Groq |
XAI_API_KEY | xAI |
OPENROUTER_API_KEY | OpenRouter |
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.