Skip to main content
Configuration is a set of YAML files plus environment variables. The shipped files hold working defaults for a local stack: a deployment puts its secrets and the model key in .env, and changes the few settings it needs in one overlay file.

Configuration files

Later sources win: environment variables, then the overlay, then config.devices.yaml and config.llm.yaml, then config.yaml. A dictionary does not merge across files: a key set in the overlay replaces the whole value, so an overlay that sets EMAIL_PREDEFINE_CODES replaces the demo accounts rather than adding to them. ENV only selects which overlay loads and tags log lines; it carries no behaviour of its own. Production posture is the PRODUCTION switch below, not an environment name. In the overlay, a value whose name contains _KEY, _PASSWORD, _PASS, _PWD, _SECRET, _SK or _TOKEN is encrypted with CONFIG_ENCRYPTION_KEY from .env.

The model key

One key runs every surface. Put one of these in the .env next to compose.yaml, then apply it:
docker compose restart does not re-read .env; up -d does. Each key selects a model for four surfaces: chat (the model picker), vision (report photos and scanned pages), text (indicator extraction, file titles and summaries) and embeddings (indicator search). The table at the top of lists what each key selects and where each key is issued. DeepSeek and Anthropic serve no embedding model; with one of those keys alone, indicator search uses the lexical index. mirobody doctor prints the keys it found and the model each surface selected, and names the fix for a surface that has none:
The server and the worker log the same report at startup.

Changing a model

  • Point a surface at another entry. UTILS_VISION_MODEL, UTILS_TEXT_MODEL and UTILS_EMBEDDING_MODEL each take an entry name, a list of names (the first whose key is present wins), a provider/model string, or an inline entry. An environment variable of the same name overrides the file, for example UTILS_VISION_MODEL=qwen-utils.
  • Change the chat default. DEFAULT_MODEL names a MODELS entry; unset, the first entry whose key is present is the default.
  • Route a key through another gateway. <PREFIX>_BASE_URL in .env, where PREFIX is the key’s name without _API_KEY, redirects every entry that reads that key to another OpenAI-compatible endpoint, for example OPENROUTER_BASE_URL. ANTHROPIC_BASE_URL is also read by Anthropic’s own SDK, so a machine that already sets it for another tool redirects Mirobody too; mirobody doctor prints the endpoint each surface resolved.
  • Add a vendor. Add an entry to MODELS in config.llm.yaml with llm_type: openai, its base_url, model, and api_key set to the name of the .env variable that holds the secret. An entry used for vision must declare supports_image: true. Add it to config.llm.yaml itself: a MODELS block in the overlay would replace the whole table.
Changing the embedding model invalidates every vector already stored: vectors from different models are not comparable.

Deployment settings

The keys that decide how the agent behaves are described in The Agent.

Secrets

PG_ENCRYPTION_KEY is a separate value from CONFIG_ENCRYPTION_KEY: it encrypts stored content such as chat messages and uploaded files. DATABASE_DECRYPTION_KEY (hex) encrypts the device credentials the providers store. Do not copy either key between environments. Generating these secrets yourself and moving them to another host is described in Deploy on a Server.

Extension directories

The engine scans three lists of directories at startup. Adding one extends the engine without editing the package. An overlay that sets one of these replaces the list, so repeat the default entry beside your own. An installed package can extend the same three through the mirobody.tools, mirobody.agents and mirobody.providers entry points instead. The complete reference for every configuration key is .