Environment Variables Reference
Minerva reads environment variables from the process environment and, for user-managed secrets, from ~/.minerva/.env. Keep API keys, bot tokens, OAuth secrets, and other credentials in .env; prefer config.yaml for non-secret behaviour settings when a config key exists. Some variables below are process-only overrides or internal bridge variables and should not be committed to .env just because they are documented here.
This page covers the user-facing variables. Minerva also reads a long tail of internal bridge
and test-only variables that exist to carry a config.yaml setting across a process boundary;
those are deliberately undocumented and are not a supported configuration surface — set the
config.yaml key instead. To look one up anyway, search the source for its name.
LLM Providers
| Variable | Description |
|---|---|
OPENROUTER_API_KEY | OpenRouter API key (recommended for flexibility) |
OPENROUTER_BASE_URL | Override the OpenRouter-compatible base URL |
FIREWORKS_API_KEY | Fireworks AI API key (app.fireworks.ai). Configure endpoint overrides with model.base_url in config.yaml. |
CHUTES_API_KEY | Chutes (Bittensor SN64) API key (chutes.ai/app/settings/api-keys) — OpenAI-compatible, decentralised open-model inference |
CHUTES_BASE_URL | Override the Chutes base URL (default: https://llm.chutes.ai/v1) |
MINERVA_OPENROUTER_CACHE | Enable OpenRouter response caching (1/true/yes/on). Overrides openrouter.response_cache in config.yaml. See Response Caching. |
MINERVA_OPENROUTER_CACHE_TTL | Cache TTL in seconds (1-86400). Overrides openrouter.response_cache_ttl in config.yaml. |
OPENAI_API_KEY | API key for custom OpenAI-compatible endpoints (used with OPENAI_BASE_URL) |
OPENAI_BASE_URL | Base URL for custom endpoint (VLLM, SGLang, etc.) |
LM_API_KEY | API key for LM Studio (lmstudio provider). Often a placeholder for local servers |
LM_BASE_URL | LM Studio base URL (default: http://localhost:1234/v1) |
COPILOT_GITHUB_TOKEN | GitHub token for Copilot API — first priority (OAuth gho_* or fine-grained PAT github_pat_*; classic PATs ghp_* are not supported) |
GH_TOKEN | GitHub token — second priority for Copilot (also used by gh CLI) |
GITHUB_TOKEN | GitHub token — third priority for Copilot |
COPILOT_API_BASE_URL | Override the Copilot API base URL (copilot provider) |
GLM_API_KEY | z.ai / ZhipuAI GLM API key (z.ai) |
ZAI_API_KEY | Alias for GLM_API_KEY |
Z_AI_API_KEY | Alias for GLM_API_KEY |
GLM_BASE_URL | Override z.ai base URL (default: https://api.z.ai/api/paas/v4) |
KIMI_API_KEY | Kimi / Moonshot AI API key (moonshot.ai) |
KIMI_CODING_API_KEY | Alias key for the kimi-coding provider (accepted alongside KIMI_API_KEY) |
KIMI_BASE_URL | Override Kimi base URL (default: https://api.moonshot.ai/v1) |
KIMI_CN_API_KEY | Kimi / Moonshot China API key (moonshot.cn) |
MINIMAX_API_KEY | MiniMax API key — global endpoint (minimax.io). Not used by minimax-oauth (OAuth path uses browser login instead). |
MINIMAX_BASE_URL | Override MiniMax base URL (default: https://api.minimax.io/anthropic — Minerva uses MiniMax's Anthropic Messages-compatible endpoint). Not used by minimax-oauth. |
MINIMAX_CN_API_KEY | MiniMax API key — China endpoint (minimaxi.com). Not used by minimax-oauth (OAuth path uses browser login instead). |
MINIMAX_CN_BASE_URL | Override MiniMax China base URL (default: https://api.minimaxi.com/anthropic). Not used by minimax-oauth. |
XIAOMI_API_KEY | Xiaomi MiMo API key (platform.xiaomimimo.com) |
XIAOMI_BASE_URL | Override Xiaomi MiMo base URL (default: https://api.xiaomimimo.com/v1) |
TOKENHUB_API_KEY | Tencent TokenHub API key (tokenhub.tencentmaas.com) |
TOKENHUB_BASE_URL | Override Tencent TokenHub base URL (default: https://tokenhub.tencentmaas.com/v1) |
TOKENPLAN_API_KEY | Tencent TokenPlan API key (LKEAP; Anthropic Messages endpoint) |
TOKENPLAN_BASE_URL | Override Tencent TokenPlan base URL (default: https://api.lkeap.cloud.tencent.com/plan/anthropic) |
AZURE_ANTHROPIC_KEY | Azure Anthropic API key for provider: anthropic + base_url pointing at a Microsoft Foundry Claude deployment (alternative to ANTHROPIC_API_KEY when both Anthropic and Azure Anthropic are configured) |
HF_TOKEN | Hugging Face token for Inference Providers (huggingface.co/settings/tokens) |
HF_BASE_URL | Override Hugging Face base URL (default: https://router.huggingface.co/v1) |
GOOGLE_API_KEY | Google AI Studio API key (aistudio.google.com/app/apikey) |
GEMINI_API_KEY | Alias for GOOGLE_API_KEY |
GEMINI_BASE_URL | Override Google AI Studio base URL |
ANTHROPIC_API_KEY | Anthropic Console API key (console.anthropic.com) |
ANTHROPIC_BASE_URL | Override the Anthropic API base URL |
ANTHROPIC_TOKEN | Manual or legacy Anthropic OAuth/setup-token override |
DASHSCOPE_API_KEY | Qwen Cloud (Alibaba DashScope) API key for Qwen models (modelstudio.console.alibabacloud.com) |
DASHSCOPE_BASE_URL | Custom DashScope base URL (default: https://dashscope-intl.aliyuncs.com/compatible-mode/v1; use https://dashscope.aliyuncs.com/compatible-mode/v1 for mainland-China region) |
DASHSCOPE_CN_BASE_URL | Override the alibaba-cn mainland-China DashScope base URL |
ALIBABA_CODING_PLAN_API_KEY | Qwen Coding Plan API key (alibaba-coding-plan; also a fallback for alibaba-coding-plan-cn) |
ALIBABA_CODING_PLAN_CN_API_KEY | Qwen Coding Plan API key for the mainland-China alibaba-coding-plan-cn provider (checked before the shared key, so only the CN row lights up) |
ALIBABA_CODING_PLAN_BASE_URL | Override the Qwen Coding Plan base URL (international) |
ALIBABA_CODING_PLAN_CN_BASE_URL | Override the Qwen Coding Plan base URL (mainland China) |
ALIBABA_TOKEN_PLAN_API_KEY | Alibaba Model Studio Token Plan API key (alibaba-token-plan; also a fallback for alibaba-token-plan-cn) |
ALIBABA_TOKEN_PLAN_CN_API_KEY | Token Plan API key for the mainland-China alibaba-token-plan-cn provider (checked before the shared key) |
ALIBABA_TOKEN_PLAN_BASE_URL | Override the Token Plan base URL (international) |
ALIBABA_TOKEN_PLAN_CN_BASE_URL | Override the Token Plan base URL (mainland China) |
DEEPSEEK_API_KEY | DeepSeek API key for direct DeepSeek access (platform.deepseek.com) |
DEEPSEEK_BASE_URL | Custom DeepSeek API base URL |
DEEPINFRA_API_KEY | DeepInfra API key (deepinfra.com) |
DEEPINFRA_BASE_URL | DeepInfra base URL override |
NVIDIA_API_KEY | NVIDIA NIM API key — Nemotron and open models (build.nvidia.com) |
NVIDIA_BASE_URL | Override NVIDIA base URL (default: https://integrate.api.nvidia.com/v1; set to http://localhost:8000/v1 for a local NIM endpoint) |
STEPFUN_API_KEY | StepFun API key — Step-series models (platform.stepfun.com) |
STEPFUN_BASE_URL | Override StepFun base URL (default: https://api.stepfun.com/v1) |
OLLAMA_API_KEY | Ollama Cloud API key — managed Ollama catalog without local GPU (ollama.com/settings/keys) |
OLLAMA_BASE_URL | Override Ollama Cloud base URL (default: https://ollama.com/v1) |
XAI_API_KEY | xAI (Grok) API key for chat + TTS + web search (console.x.ai) |
XAI_BASE_URL | Override xAI base URL (default: https://api.x.ai/v1) |
MISTRAL_API_KEY | Mistral API key for Voxtral TTS and Voxtral STT (console.mistral.ai) |
MINERVA_QWEN_BASE_URL | Qwen Portal base URL override (default: https://portal.qwen.ai/v1) |
OPENCODE_ZEN_API_KEY | OpenCode Zen API key — pay-as-you-go access to curated models (opencode.ai) |
OPENCODE_ZEN_BASE_URL | Override OpenCode Zen base URL |
OPENCODE_GO_API_KEY | OpenCode Go API key — $10/month subscription for open models (opencode.ai) |
OPENCODE_GO_BASE_URL | Override OpenCode Go base URL |
CLAUDE_CODE_OAUTH_TOKEN | Explicit Claude Code token override if you export one manually |
MINERVA_MODEL | Override model name at process level (used by cron scheduler; prefer config.yaml for normal use) |
VOICE_TOOLS_OPENAI_KEY | Preferred OpenAI key for OpenAI speech-to-text and text-to-speech providers |
MINERVA_LOCAL_STT_COMMAND | Optional local speech-to-text command template. Supports {input_path}, {output_dir}, {language}, and {model} placeholders |
MINERVA_LOCAL_STT_LANGUAGE | Default language hint for STT. Used by the local (faster-whisper) provider, MINERVA_LOCAL_STT_COMMAND, the local whisper CLI fallback (default: en), Groq, and xAI when no per-provider language is set in config.yaml |
MINERVA_HOME | Override Minerva config directory (default: ~/.minerva). Also scopes the gateway PID file and systemd service name, so multiple installations can run concurrently |
MINERVA_GIT_BASH_PATH | Windows only. Override bash.exe discovery for the terminal tool. Points at any bash — full Git-for-Windows install, WSL bash via symlink, MSYS2, Cygwin. The installer sets this automatically to the PortableGit it provisioned. See the Windows (Native) Guide |
MINERVA_DISABLE_WINDOWS_UTF8 | Windows only. Set to 1 to disable the UTF-8 stdio shim (configure_windows_stdio()) and fall back to the console's locale code page. Useful for bisecting encoding bugs; rarely the right setting in normal operation |
MINERVA_KANBAN_HOME | Override the shared Minerva root that anchors the kanban board (db + workspaces + worker logs). Falls back to get_default_minerva_root() (the parent of any active profile). Useful for tests and unusual deployments |
MINERVA_KANBAN_BOARD | Pin the active kanban board for this process. Takes precedence over ~/.minerva/kanban/current; the dispatcher injects this into worker subprocess env so workers physically cannot see tasks on other boards. Defaults to default. Slug validation: lowercase alphanumerics + hyphens + underscores, 1-64 chars |
MINERVA_KANBAN_DB | Pin the kanban database file path directly (highest precedence; beats MINERVA_KANBAN_BOARD and MINERVA_KANBAN_HOME). The dispatcher injects this into worker subprocess env so profile workers converge on the dispatcher's board |
MINERVA_KANBAN_WORKSPACES_ROOT | Pin the kanban workspaces root directly (highest precedence for workspaces; beats MINERVA_KANBAN_HOME). The dispatcher injects this into worker subprocess env |
MINERVA_KANBAN_DISPATCH_IN_GATEWAY | Runtime override for kanban.dispatch_in_gateway. Set to 0, false, no, or off to keep the gateway from starting the embedded Kanban dispatcher; any other non-empty value enables it. Useful when a separate dispatcher process owns the board. |
Provider Auth (OAuth)
For native Anthropic auth, Minerva prefers Claude Code's own credential files when they exist because those credentials can refresh automatically. OAuth against Anthropic requires a Claude Max plan with purchased extra usage credits — Minerva routes as Claude Code, which only draws from the Max plan's extra/overage credits, not the base Max allowance, and does not work on Claude Pro. Without Max + extra credits, use an API key instead. Environment variables such as ANTHROPIC_TOKEN remain useful as manual overrides, but they are no longer the preferred path for Claude Max login.
| Variable | Description |
|---|---|
MINERVA_DUMP_REQUESTS | Dump API request payloads to log files (true/false) |
MINERVA_PREFILL_MESSAGES_FILE | Path to a JSON file of ephemeral prefill messages injected at API-call time |
MINERVA_TIMEZONE | IANA timezone override (for example America/New_York) |
Tool APIs
| Variable | Description |
|---|---|
PARALLEL_API_KEY | AI-native web search (parallel.ai) |
FIRECRAWL_API_KEY | Web scraping and cloud browser (firecrawl.dev) |
FIRECRAWL_API_URL | Custom Firecrawl API endpoint for self-hosted instances (optional) |
TAVILY_API_KEY | Optional Tavily API key for higher search/extract limits. After selecting Tavily as the web backend, keyless access works without it (app.tavily.com, keyless docs) |
TAVILY_BASE_URL | Override the Tavily API endpoint. Useful for corporate proxies and self-hosted Tavily-compatible search backends. Same pattern as GROQ_BASE_URL. |
PERPLEXITY_API_KEY | Perplexity Search API key for the perplexity web backend — ranked search results plus query-relevant page snippets for extract (perplexity.ai/account/api) |
PERPLEXITY_BASE_URL | Override the Perplexity API endpoint (default https://api.perplexity.ai) for proxies (optional) |
SEARXNG_URL | SearXNG instance URL for free self-hosted web search — no API key required (searxng.github.io) |
EXA_API_KEY | Exa API key for AI-native web search and contents (exa.ai) |
BRAVE_SEARCH_API_KEY | Brave Search API subscription token for web search (free tier available) (brave.com/search/api) |
BROWSERBASE_API_KEY | Browser automation (browserbase.com) |
BROWSERBASE_PROJECT_ID | Browserbase project ID |
BROWSER_USE_API_KEY | Browser Use cloud browser API key (browser-use.com) |
FIRECRAWL_BROWSER_TTL | Firecrawl browser session TTL in seconds (default: 300) |
BROWSER_CDP_URL | Chrome DevTools Protocol URL for local browser (set via /browser connect, e.g. ws://localhost:9222) |
CAMOFOX_URL | Camofox local anti-detection browser server address (default: http://localhost:9377). Address only — it does not select Camofox as the backend; pick Camofox in minerva tools (browser.cloud_provider: camofox) |
CAMOFOX_API_KEY | Optional bearer token sent as Authorization header to a remote/authenticated Camofox server |
CAMOFOX_USER_ID | Optional externally managed Camofox user ID for shared visible sessions |
CAMOFOX_SESSION_KEY | Optional Camofox session key used when creating tabs for CAMOFOX_USER_ID |
CAMOFOX_ADOPT_EXISTING_TAB | Set to true to reuse an existing Camofox tab before creating a new one |
BROWSER_INACTIVITY_TIMEOUT | Browser session inactivity timeout in seconds |
AGENT_BROWSER_ARGS | Extra Chromium launch flags (comma- or newline-separated). Minerva auto-injects --no-sandbox,--disable-dev-shm-usage when running as root or on AppArmor-restricted unprivileged user namespaces (Ubuntu 23.10+, DGX Spark, many container images); set this manually only to override or add other flags. |
AGENT_BROWSER_ENGINE | Local browser engine: auto (default — Chromium-family via CDP), lightpanda (Browser Use mode spawns lightpanda serve; the built-in tools pass --engine lightpanda to agent-browser), or chrome. Same as browser.engine in config.yaml. |
FAL_KEY | Image generation (fal.ai) |
KREA_API_KEY | Krea API key for Krea 2 image generation (krea.ai) |
GROQ_API_KEY | Groq Whisper STT API key (groq.com) |
ELEVENLABS_API_KEY | ElevenLabs premium TTS voices (elevenlabs.io) |
PORCUPINE_ACCESS_KEY | Picovoice Porcupine wake-word engine (console.picovoice.ai) — only for wake_word.provider: porcupine; the default openWakeWord and sherpa engines need no key |
STT_GROQ_MODEL | Override the Groq STT model (default: whisper-large-v3-turbo) |
GROQ_BASE_URL | Override the Groq OpenAI-compatible STT endpoint |
STT_OPENAI_MODEL | Override the OpenAI STT model (default: whisper-1) |
STT_OPENAI_BASE_URL | Override the OpenAI-compatible STT endpoint |
GITHUB_TOKEN | GitHub token for Skills Hub (higher API rate limits, skill publish) |
HONCHO_API_KEY | Cross-session user modeling (honcho.dev) |
HONCHO_BASE_URL | Base URL for self-hosted Honcho instances (default: Honcho cloud). No API key required for local instances |
HINDSIGHT_API_KEY | Hindsight API key for graph-aware persistent memory (hindsight.vectorize.io) |
HINDSIGHT_API_URL | Base URL for the Hindsight API (default: https://api.hindsight.vectorize.io) |
HINDSIGHT_TIMEOUT | Timeout in seconds for Hindsight memory-provider API calls (default: 60). Bump this if your Hindsight instance is slow to respond during /sync or on_session_switch and you're seeing timeouts in errors.log. |
MEM0_API_KEY | Mem0 Platform API key for semantic persistent memory (app.mem0.ai) |
MEM0_MODE | Mem0 backend mode: platform (default) or oss — see Memory Providers |
MEM0_HOST | Base URL of a self-hosted Mem0 server (switches the plugin off the Platform API) |
MEM0_USER_ID | Override the user id Mem0 memories are stored under |
MEM0_AGENT_ID | Override the agent id Mem0 memories are tagged with |
RETAINDB_API_KEY | RetainDB API key for persistent memory (retaindb.com) |
RETAINDB_BASE_URL | Base URL for self-hosted RetainDB instances (default: https://api.retaindb.com) |
OPENVIKING_API_KEY | OpenViking API key (leave blank for local dev mode) |
OPENVIKING_ENDPOINT | OpenViking server URL (default: http://127.0.0.1:1933) |
BRV_API_KEY | ByteRover API key (optional, for cloud sync — local-first by default) (app.byterover.dev) |
SUPERMEMORY_API_KEY | Semantic long-term memory with profile recall and session ingest (supermemory.ai) |
DAYTONA_API_KEY | Daytona cloud sandboxes (daytona.io) |
VERCEL_TOKEN | Vercel Sandbox access token (vercel.com) |
VERCEL_PROJECT_ID | Vercel project ID (required with VERCEL_TOKEN) |
VERCEL_TEAM_ID | Vercel team ID (required with VERCEL_TOKEN) |
VERCEL_OIDC_TOKEN | Vercel short-lived OIDC token (development-only alternative) |
Skill API Keys
Secrets consumed by specific bundled skills. Each is only needed if you use the corresponding skill.
| Variable | Used by skill | Description |
|---|---|---|
NOTION_API_KEY | notion | Notion integration token. |
AIRTABLE_API_KEY | airtable | Airtable personal access token. |
TENOR_API_KEY | gif-search | Tenor API key for GIF search. |
TWILIO_ACCOUNT_SID | telephony | Twilio Account SID. |
TWILIO_AUTH_TOKEN | telephony | Twilio Auth Token. |
TWILIO_PHONE_NUMBER | telephony | Twilio phone number in E.164 format. |
Langfuse Observability
Environment variables for the bundled observability/langfuse plugin. Set these in ~/.minerva/.env. The plugin must also be enabled (minerva plugins enable observability/langfuse, or check the box in minerva plugins) before any of these take effect.
| Variable | Description |
|---|---|
MINERVA_LANGFUSE_PUBLIC_KEY | Langfuse project public key (pk-lf-...). Required. |
MINERVA_LANGFUSE_SECRET_KEY | Langfuse project secret key (sk-lf-...). Required. |
MINERVA_LANGFUSE_BASE_URL | Langfuse server URL (default: https://cloud.langfuse.com). Set for self-hosted. |
MINERVA_LANGFUSE_ENV | Environment tag on traces (production, staging, …) |
MINERVA_LANGFUSE_RELEASE | Release/version tag on traces |
MINERVA_LANGFUSE_SAMPLE_RATE | SDK sampling rate 0.0–1.0 (default: 1.0) |
MINERVA_LANGFUSE_MAX_CHARS | Per-field truncation for serialized payloads (default: 12000) |
MINERVA_LANGFUSE_DEBUG | true enables verbose plugin logging to agent.log |
LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY / LANGFUSE_BASE_URL | Standard Langfuse SDK names. Accepted as fallbacks when the MINERVA_LANGFUSE_* equivalents are unset. |
Terminal Backend
| Variable | Description |
|---|---|
TERMINAL_ENV | Backend: local, docker, ssh, singularity, modal, daytona, vercel_sandbox |
MINERVA_DOCKER_BINARY | Override the container binary Minerva shells out to (e.g. podman, /usr/local/bin/docker). When unset, Minerva auto-discovers docker or podman on PATH. Needed when both are installed and you want the non-default, or when the binary lives outside PATH. |
TERMINAL_DOCKER_IMAGE | Docker image (default: nikolaik/python-nodejs:python3.11-nodejs20) |
TERMINAL_DOCKER_FORWARD_ENV | JSON array of env var names to explicitly forward into Docker terminal sessions. Note: skill-declared required_environment_variables are forwarded automatically — you only need this for vars not declared by any skill. |
TERMINAL_DOCKER_VOLUMES | Additional Docker volume mounts (comma-separated host:container pairs) |
TERMINAL_DOCKER_ENV | JSON object of extra env vars to set inside Docker terminal sessions (e.g. {"FOO":"bar"}) |
TERMINAL_DOCKER_EXTRA_ARGS | JSON array of extra docker run arguments (e.g. ["--memory","4g"]) |
TERMINAL_DOCKER_MOUNT_CWD_TO_WORKSPACE | Advanced opt-in: mount the launch cwd into Docker /workspace (true/false, default: false) |
TERMINAL_SINGULARITY_IMAGE | Singularity image or .sif path |
TERMINAL_MODAL_IMAGE | Modal container image |
TERMINAL_DAYTONA_IMAGE | Daytona sandbox image |
TERMINAL_VERCEL_RUNTIME | Vercel Sandbox runtime (node24, node22, python3.13) |
TERMINAL_TIMEOUT | Command timeout in seconds |
TERMINAL_LIFETIME_SECONDS | Max lifetime for terminal sessions in seconds |
TERMINAL_CWD | Deprecated direct override for gateway/cron terminal sessions. Prefer terminal.cwd in config.yaml; CLI still uses the launch directory. |
SUDO_PASSWORD | Enable sudo without interactive prompt |
For cloud sandbox backends, persistence is filesystem-oriented. TERMINAL_LIFETIME_SECONDS controls when Minerva cleans up an idle terminal session, and later resumes may recreate the sandbox rather than keep the same live processes running.
SSH Backend
| Variable | Description |
|---|---|
TERMINAL_SSH_HOST | Remote server hostname |
TERMINAL_SSH_USER | SSH username |
TERMINAL_SSH_PORT | SSH port (default: 22) |
TERMINAL_SSH_KEY | Path to private key |
TERMINAL_SSH_PERSISTENT | Override persistent shell for SSH (default: follows TERMINAL_PERSISTENT_SHELL) |
Container Resources (Docker, Singularity, Modal, Daytona)
| Variable | Description |
|---|---|
TERMINAL_CONTAINER_CPU | CPU cores (default: 1) |
TERMINAL_CONTAINER_MEMORY | Memory in MB (default: 5120) |
TERMINAL_CONTAINER_DISK | Disk in MB (default: 51200) |
TERMINAL_CONTAINER_PERSISTENT | Persist container filesystem across sessions (default: true) |
TERMINAL_SANDBOX_DIR | Host directory for workspaces and overlays (default: ~/.minerva/sandboxes/) |
Persistent Shell
| Variable | Description |
|---|---|
TERMINAL_PERSISTENT_SHELL | Enable persistent shell for non-local backends (default: true). Also settable via terminal.persistent_shell in config.yaml |
TERMINAL_LOCAL_PERSISTENT | Enable persistent shell for local backend (default: false) |
TERMINAL_SSH_PERSISTENT | Override persistent shell for SSH backend (default: follows TERMINAL_PERSISTENT_SHELL) |
Egress proxy (sandbox-injected)
These env vars are NOT set on the host — they're injected into Docker sandboxes by the Egress proxy integration when proxy.enabled: true. Docker is the only wired backend in this release.
| Variable | Description |
|---|---|
MINERVA_EGRESS_PROXY | Set to 1 inside a sandbox when the egress proxy is active. Agent code can check this to know it's running behind a TLS-intercepting proxy. |
Provider env vars (OPENROUTER_API_KEY, OPENAI_API_KEY, …) | Set to opaque proxy tokens, not real upstream secrets, so existing SDKs keep reading the standard env names. iron-proxy swaps those tokens for the real upstream secret at the network boundary. |
MINERVA_PROXY_TOKEN_<ENV_NAME> | Diagnostic alias for each minted provider mapping. E.g. MINERVA_PROXY_TOKEN_OPENROUTER_API_KEY=minerva-proxy-openrouter-…. Same token value as the standard provider env var. |
HTTPS_PROXY / HTTP_PROXY | HTTPS_PROXY points at http://host.docker.internal:<tunnel_port> for CONNECT/MITM. HTTP_PROXY points at <tunnel_port + 1> for plain-HTTP forwarding. |
NO_PROXY | 127.0.0.1,localhost,::1 so loopback dev servers inside the sandbox bypass the proxy. |
REQUESTS_CA_BUNDLE / SSL_CERT_FILE / CURL_CA_BUNDLE / NODE_EXTRA_CA_CERTS | Path to the mounted Minerva egress CA cert inside the sandbox (/etc/ssl/certs/minerva-egress-ca.crt). Lets the language runtimes trust iron-proxy's MITM-minted leaf certs. |
NODE_OPTIONS | Appended with --use-openssl-ca (your existing flags are preserved) so Node.js routes through the OpenSSL store the other CA-bundle vars control. Narrows the Node.js asymmetric CA caveat. |
MINERVA_IRON_PROXY_NONCE | Set on the iron-proxy daemon process itself (NOT inside the sandbox). Used by _pid_alive to confirm a candidate PID still refers to our managed binary across PID recycling. |
These are set automatically by the Docker terminal backend when proxy.enabled: true AND the daemon is running. You don't set them yourself; the relevant operator-facing knobs are in ~/.minerva/config.yaml under the proxy: section — see Egress proxy → Configuration.
Messaging
| Variable | Description |
|---|---|
TELEGRAM_BOT_TOKEN | Telegram bot token (from @BotFather) |
TELEGRAM_ALLOWED_USERS | Comma-separated user IDs allowed to use the bot (applies to DMs, groups, and forums) |
TELEGRAM_ALLOW_ALL_USERS | Allow any Telegram user to trigger the bot (dev only). |
TELEGRAM_GROUP_ALLOWED_USERS | Comma-separated sender user IDs authorized in groups/forums only (does NOT grant DM access). Chat-ID-shaped values (starting with -) are still honored as chat IDs for backward compat with pre-#17686 configs, with a deprecation warning. |
TELEGRAM_GROUP_ALLOWED_CHATS | Comma-separated group/forum chat IDs; any member is authorized |
TELEGRAM_HOME_CHANNEL | Default Telegram chat/channel for cron delivery |
TELEGRAM_HOME_CHANNEL_NAME | Display name for the Telegram home channel |
TELEGRAM_CRON_THREAD_ID | Forum topic ID to receive cron deliveries; overrides TELEGRAM_HOME_CHANNEL_THREAD_ID for cron only. Use in topic mode so replies to cron messages open a new session instead of hitting the system lobby (#24409). |
TELEGRAM_WEBHOOK_URL | Public HTTPS URL for webhook mode (enables webhook instead of polling) |
TELEGRAM_WEBHOOK_PORT | Local listen port for webhook server (default: 8443) |
TELEGRAM_WEBHOOK_SECRET | Secret token Telegram echoes back in each update for verification. Required whenever TELEGRAM_WEBHOOK_URL is set — the gateway refuses to start without it (GHSA-3vpc-7q5r-276h). Generate with openssl rand -hex 32. |
TELEGRAM_REACTIONS | Enable emoji reactions on messages during processing (default: false) |
TELEGRAM_REQUIRE_MENTION | Require an explicit trigger before responding in Telegram groups. Equivalent to telegram.require_mention in config.yaml. |
TELEGRAM_MENTION_PATTERNS | JSON array, newline-separated list, or comma-separated list of regex wake-word patterns accepted when Telegram group mention gating is enabled. Equivalent to telegram.mention_patterns. |
TELEGRAM_EXCLUSIVE_BOT_MENTIONS | When enabled, explicit @...bot mentions in Telegram groups route only to the mentioned bot usernames before reply or wake-word fallbacks run. Default: true. Equivalent to telegram.exclusive_bot_mentions. |
TELEGRAM_REPLY_TO_MODE | Reply-reference behavior: off, first (default), or all. Matches the Discord pattern. |
TELEGRAM_IGNORED_THREADS | Comma-separated Telegram forum topic/thread IDs where the bot never responds |
TELEGRAM_PROXY | Proxy URL for Telegram connections — overrides HTTPS_PROXY. Supports http://, https://, socks5:// |
DISCORD_BOT_TOKEN | Discord bot token |
DISCORD_ALLOWED_USERS | Comma-separated Discord user IDs allowed to use the bot |
DISCORD_ALLOW_ALL_USERS | Allow any Discord user to trigger the bot (dev only). |
DISCORD_ALLOWED_ROLES | Comma-separated Discord role IDs allowed to use the bot (OR with DISCORD_ALLOWED_USERS). Auto-enables the Members intent. Useful when moderation teams churn — role grants propagate automatically. |
DISCORD_ALLOWED_CHANNELS | Comma-separated Discord channel IDs. When set, the bot only responds in these channels (plus DMs if allowed). Overrides config.yaml discord.allowed_channels. |
DISCORD_PROXY | Proxy URL for Discord connections — overrides HTTPS_PROXY. Supports http://, https://, socks5:// |
DISCORD_HOME_CHANNEL | Default Discord channel for cron delivery |
DISCORD_HOME_CHANNEL_NAME | Display name for the Discord home channel |
DISCORD_COMMAND_SYNC_POLICY | Discord slash-command startup sync policy: safe (diff and reconcile), bulk (legacy tree.sync()), or off |
DISCORD_REQUIRE_MENTION | Require an @mention before responding in server channels |
DISCORD_FREE_RESPONSE_CHANNELS | Comma-separated channel IDs where mention is not required |
DISCORD_AUTO_THREAD | Auto-thread long replies when supported |
DISCORD_ALLOW_ANY_ATTACHMENT | Removed; setting it has no effect. Every file type is always accepted and cached; DISCORD_MAX_ATTACHMENT_BYTES is the only inbound limit. |
DISCORD_MAX_ATTACHMENT_BYTES | Maximum bytes per attachment the gateway will cache. Default 33554432 (32 MiB). Set to 0 for no cap (attachments are held in memory while being written). |
DISCORD_REACTIONS | Enable emoji reactions on messages during processing (default: true) |
DISCORD_IGNORED_CHANNELS | Comma-separated channel IDs where the bot never responds |
DISCORD_NO_THREAD_CHANNELS | Comma-separated channel IDs where bot responds without auto-threading |
DISCORD_REPLY_TO_MODE | Reply-reference behavior: off, first (default), or all |
DISCORD_ALLOW_MENTION_EVERYONE | Allow the bot to ping @everyone/@here (default: false). See Mention Control. |
DISCORD_ALLOW_MENTION_ROLES | Allow the bot to ping @role mentions (default: false). |
DISCORD_ALLOW_MENTION_USERS | Allow the bot to ping individual @user mentions (default: true). |
DISCORD_ALLOW_MENTION_REPLIED_USER | Ping the author when replying to their message (default: true). |
SLACK_BOT_TOKEN | Slack bot token (xoxb-...) |
SLACK_APP_TOKEN | Slack app-level token (xapp-..., required for Socket Mode) |
SLACK_ALLOWED_USERS | Comma-separated Slack user IDs |
SLACK_ALLOW_ALL_USERS | Allow any Slack user to trigger the bot (dev only). |
SLACK_ALLOW_BOTS | Accept messages from other Slack bots: none (default), mentions, or all. The bot always ignores its own messages. |
SLACK_THREAD_REQUIRE_MENTION | Require an explicit @mention for Slack thread replies while preserving top-level free-response channels |
SLACK_HOME_CHANNEL | Default Slack channel for cron delivery |
SLACK_HOME_CHANNEL_NAME | Display name for the Slack home channel |
WEBHOOK_ENABLED | Enable the webhook platform adapter (true/false) |
WEBHOOK_PORT | HTTP server port for receiving webhooks (default: 8644) |
WEBHOOK_SECRET | Global HMAC secret for webhook signature validation (used as fallback when routes don't specify their own) |
API_SERVER_ENABLED | Enable the OpenAI-compatible API server (true/false). Runs alongside other platforms. |
API_SERVER_KEY | Bearer token for API server authentication. Required whenever the API server is enabled. |
API_SERVER_CORS_ORIGINS | Comma-separated browser origins allowed to call the API server directly (for example http://localhost:3000,http://127.0.0.1:3000). Default: disabled. |
API_SERVER_PORT | Port for the API server (default: 8642) |
API_SERVER_HOST | Host/bind address for the API server (default: 127.0.0.1). API_SERVER_KEY is still required on loopback; use a narrow API_SERVER_CORS_ORIGINS allowlist for browser access. |
API_SERVER_MODEL_NAME | Model name advertised on /v1/models. Defaults to the profile name (or minerva-agent for the default profile). Useful for multi-user setups where frontends like Open WebUI need distinct model names per connection. |
GATEWAY_PROXY_URL | URL of a remote Minerva API server to forward messages to (proxy mode). When set, the gateway handles platform I/O only — all agent work is delegated to the remote server. Also configurable via gateway.proxy_url in config.yaml. |
GATEWAY_PROXY_KEY | Bearer token for authenticating with the remote API server in proxy mode. Must match API_SERVER_KEY on the remote host. |
MESSAGING_CWD | Deprecated compatibility fallback for gateway working directory. Prefer terminal.cwd in config.yaml. |
GATEWAY_ALLOWED_USERS | Comma-separated user IDs allowed across all platforms |
GATEWAY_ALLOW_ALL_USERS | Allow all users without allowlists (true/false, default: false) |
Minerva Desktop & remote backend
Auth for a minerva serve backend that Minerva Desktop connects to remotely. Per the secrets-only convention, credentials belong in ~/.minerva/.env; the OIDC issuer and client id are better set under dashboard.oauth.self_hosted in config.yaml (env wins when set).
Two sign-in providers ship in the box. For a backend reachable beyond your own machine, the recommended provider is self-hosted OIDC (MINERVA_DASHBOARD_OIDC_*), which authenticates against your own identity provider. The bundled username/password provider (MINERVA_DASHBOARD_BASIC_AUTH_*) is the quickest option for a backend on a trusted LAN or behind a VPN, but is not suitable for direct public-internet exposure. Either way, a non-loopback bind (minerva serve --host 0.0.0.0) engages the auth gate. See Minerva Desktop → Backend authentication providers for the full picture.
| Variable | Description |
|---|---|
MINERVA_DASHBOARD_BASIC_AUTH_USERNAME | Username for the bundled username/password dashboard-auth provider (plugins/dashboard_auth/basic). Activates the provider when set together with a password. Overrides dashboard.basic_auth.username. |
MINERVA_DASHBOARD_BASIC_AUTH_PASSWORD | Plaintext password for the basic provider (hashed in-memory at load). Wins over a config password_hash so you can rotate via env. Overrides dashboard.basic_auth.password. |
MINERVA_DASHBOARD_BASIC_AUTH_PASSWORD_HASH | scrypt password hash for the basic provider (preferred — no plaintext at rest). Compute with python -c "from plugins.dashboard_auth.basic import hash_password; print(hash_password('PW'))". Overrides dashboard.basic_auth.password_hash. |
MINERVA_DASHBOARD_BASIC_AUTH_SECRET | HMAC key (32+ bytes, base64/hex/raw) signing the basic provider's stateless session tokens. Set explicitly so sessions survive restarts / span multiple workers; blank → random per-process (you'll be logged out on every restart). Overrides dashboard.basic_auth.secret. |
MINERVA_DASHBOARD_BASIC_AUTH_TTL_SECONDS | Access-token lifetime for the basic provider (default 12h). Overrides dashboard.basic_auth.session_ttl_seconds. |
MINERVA_DASHBOARD_PUBLIC_URL | Complete public URL the backend is reached at behind a reverse proxy. It controls OAuth callback construction, adds its exact hostname to the HTTP Host/WebSocket Origin guard, and requires the auth gate for non-loopback public hosts even when the backend binds to loopback. Overrides dashboard.public_url. |
MINERVA_DASHBOARD_OIDC_ISSUER | OIDC issuer URL for the bundled self-hosted OIDC provider (plugins/dashboard_auth/self_hosted). Required to activate it. Overrides dashboard.oauth.self_hosted.issuer. |
MINERVA_DASHBOARD_OIDC_CLIENT_ID | Public OIDC client id (authorization-code + PKCE) for the self-hosted OIDC provider. Required to activate it. Overrides dashboard.oauth.self_hosted.client_id. |
MINERVA_DASHBOARD_OIDC_SCOPES | Requested OIDC scopes for the self-hosted OIDC provider (default openid profile email). Overrides dashboard.oauth.self_hosted.scopes. |
MINERVA_DESKTOP_REMOTE_URL | (Desktop side) Base URL of the remote backend, e.g. http://host:9119. When set, overrides the in-app Gateway URL. Requires MINERVA_DESKTOP_REMOTE_TOKEN; with the URL alone the app refuses to connect. |
MINERVA_DESKTOP_REMOTE_TOKEN | (Desktop side) Session token for MINERVA_DESKTOP_REMOTE_URL. Must match the backend's MINERVA_DASHBOARD_SESSION_TOKEN; the app connects with it instead of the sign-in flow. |
MINERVA_DESKTOP_MINERVA | Desktop backend command override. Used by packagers/Nix or troubleshooting to point Electron at a specific minerva executable after backend probing. |
MINERVA_DESKTOP_MINERVA_ROOT | Desktop source-checkout override used by minerva desktop --minerva-root; checked before the packaged first-launch install or an existing minerva on PATH. |
MINERVA_DESKTOP_IGNORE_EXISTING | Set to 1 to make Desktop ignore an existing minerva on PATH during backend resolution. Equivalent to minerva desktop --ignore-existing. |
MINERVA_DESKTOP_CWD | Initial project directory for Desktop chat sessions. Set by minerva desktop --cwd. |
MINERVA_DESKTOP_PYTHON | Absolute path to a Python interpreter for the backend, checked before Electron auto-resolves one for the source checkout. Used by worktree dev helpers (see TUI & Desktop from Worktrees) to reuse a shared venv. |
MINERVA_DESKTOP_DEV_SERVER | Vite dev-server URL the Electron shell loads instead of the packaged bundle (e.g. http://127.0.0.1:5174). Set automatically by npm run dev; only relevant when hacking on the app. |
MINERVA_DESKTOP_CDP_PORT | Overrides the Chrome DevTools Protocol port the renderer exposes on 127.0.0.1 for DOM/CSS inspection tooling (default 9222). Dev-server runs (npm run dev, hgui) open it automatically; a packaged app never does, and no value here changes that. Set to off to disable it on a dev run. Anything that can reach the port can execute code in the renderer. |
Advanced Messaging Tuning
Advanced per-platform knobs for throttling the outbound message batcher. Most users never need to touch these; defaults are set to respect each platform's rate limits without feeling sluggish.
| Variable | Description |
|---|---|
MINERVA_TELEGRAM_TEXT_BATCH_DELAY_SECONDS | Grace window before flushing a queued Telegram text chunk (default: 0.3, clamped to 0.08–2.0). |
MINERVA_TELEGRAM_TEXT_BATCH_SPLIT_DELAY_SECONDS | Delay between split chunks when a single Telegram message exceeds the length limit (default: 1.0, at most 4.0). |
MINERVA_TELEGRAM_MEDIA_BATCH_DELAY_SECONDS | Grace window before flushing queued Telegram media (default: 0.8). |
MINERVA_TELEGRAM_FOLLOWUP_GRACE_SECONDS | Delay before sending a follow-up after the agent finishes, to avoid racing the last stream chunk. |
MINERVA_TELEGRAM_HTTP_CONNECT_TIMEOUT / _READ_TIMEOUT / _WRITE_TIMEOUT / _POOL_TIMEOUT | Override the underlying python-telegram-bot HTTP timeouts (seconds). |
MINERVA_TELEGRAM_INIT_TIMEOUT | Per-attempt cap (seconds) on the Telegram initialize() connect chain during gateway startup, so an unreachable fallback-IP chain can't block startup indefinitely (default: 30). |
MINERVA_TELEGRAM_HTTP_POOL_SIZE | Max concurrent HTTP connections to the Telegram API. |
MINERVA_TELEGRAM_DISABLE_FALLBACK_IPS | Disable the hard-coded Cloudflare fallback IPs used when DNS fails (true/false). |
MINERVA_DISCORD_TEXT_BATCH_DELAY_SECONDS | Grace window before flushing a queued Discord text chunk (default: 0.6). |
MINERVA_DISCORD_TEXT_BATCH_SPLIT_DELAY_SECONDS | Delay between split chunks when a Discord message exceeds the length limit (default: 2.0). |
MINERVA_DISCORD_LIVENESS_INTERVAL_SECONDS | Compatibility/manual override for discord.websocket_liveness_interval_seconds. Interval for sampling the active Discord Gateway WebSocket (default: 15; set to 0 to disable). Prefer the config.yaml key. |
MINERVA_DISCORD_LIVENESS_FAILURE_THRESHOLD | Compatibility/manual override for discord.websocket_liveness_failure_threshold. Consecutive unhealthy WebSocket samples before forcing a reconnect (default: 2). Prefer the config.yaml key. |
MINERVA_VISION_DOWNLOAD_TIMEOUT | Timeout in seconds for downloading an image before handing it to vision models (default: 30). |
MINERVA_VISION_MAX_CONCURRENCY | Max concurrent image encode/resize bursts across the whole process (override for auxiliary.vision.max_concurrency; default: host CPU core count, no ceiling). Bounds only the CPU-bound encode step so a video-frame fan-out can't saturate every core and starve the event loop — the LLM calls stay fully concurrent. Values < 1 are ignored. |
MINERVA_RESTART_DRAIN_TIMEOUT | Gateway: once a stop or restart has started draining, how many seconds in-flight runs get before they are interrupted. Overrides agent.restart_drain_timeout (default: 0 = interrupt at once). How long /restart first waits for turns to finish on their own is agent.restart_after_turn_timeout (default 1800). |
MINERVA_GATEWAY_PLATFORM_CONNECT_TIMEOUT | Per-platform connect timeout during gateway startup and reconnect (seconds; 0/negative waits indefinitely). Applies to the connect attempt and the Discord adapter's ready-wait, so accounts with many slash commands to sync don't get killed mid-startup. Bridged from gateway.platform_connect_timeout in config.yaml (default 30); this env var is the manual override and wins if set explicitly. |
MINERVA_GATEWAY_BUSY_INPUT_MODE | Default gateway busy-input behavior: queue, steer, or interrupt. Can be overridden for the active profile with /busy. |
MINERVA_GATEWAY_BUSY_ACK_ENABLED | Whether the gateway sends an acknowledgment message (⚡/⏳/⏩) when a user sends input while the agent is busy (default: true). Set to false to suppress these messages entirely — the input is still queued/steered/interrupts as normal, only the chat reply is silenced. Bridged from display.busy_ack_enabled in config.yaml. |
MINERVA_GATEWAY_NO_SUPERVISE | Inside the s6-overlay Docker image, opt out of auto-supervision when running minerva gateway run and use pre-s6 foreground semantics (no auto-restart, gateway is the container's main process). Truthy values: 1, true, yes. Equivalent to the --no-supervise CLI flag. No-op outside the s6 image. |
MINERVA_GATEWAY_BOOTSTRAP_STATE | Inside the s6-overlay Docker image, declare the gateway's initial supervised state on a fresh volume. On a blank volume there is no persisted gateway_state.json, so the boot reconciler registers the gateway-default slot but leaves it down (it only auto-starts when the last recorded state was running). Set this to running and the first-boot setup hook seeds gateway_state.json before the reconciler runs, so the gateway comes up on the very first boot. Only the literal value running is honoured. First-boot-only: an existing gateway_state.json is never overwritten, so a deliberately-stopped gateway stays stopped across restarts. No-op outside the s6 image. |
MINERVA_FILE_MUTATION_VERIFIER | Enable the per-turn file-mutation verifier footer (default: true). When enabled, Minerva appends an advisory listing any write_file / patch calls that failed during the turn and were not superseded by a successful write. Set to 0, false, no, or off to suppress. Mirrors display.file_mutation_verifier in config.yaml; the env var wins when set. |
MINERVA_CRON_TIMEOUT | Inactivity timeout for cron job agent runs in seconds (default: 600). The agent can run indefinitely while actively calling tools or receiving stream tokens — this only triggers when idle. Set to 0 for unlimited. |
MINERVA_CRON_SCRIPT_TIMEOUT | Timeout for pre-run scripts attached to cron jobs in seconds (default: 3600). Bounds the script only — skill/agent jobs use the separate MINERVA_CRON_TIMEOUT inactivity budget. Also configurable via cron.script_timeout_seconds in config.yaml. |
MINERVA_CRON_MEDIA_SEND_TIMEOUT | Timeout for each media attachment send during cron delivery via a live gateway adapter, in seconds (default: 300). Raise it if large attachments (long TTS audio, big exports) time out during upload. Also configurable via cron.media_send_timeout_seconds in config.yaml. |
MINERVA_CRON_MAX_PARALLEL | Max cron jobs run in parallel per tick (default: unbounded; 1 restores serial runs). Overrides cron.max_parallel_jobs in config.yaml. |
NeMo Relay
| Variable | Description |
|---|---|
MINERVA_NEMO_RELAY_PLUGINS_TOML | Explicit path to the standard NeMo Relay plugins.toml loaded process-wide by Minerva core. When unset, Minerva does not initialize Relay middleware, dynamic plugins, or exporters. The removed MINERVA_NEMO_RELAY_ATOF_* and MINERVA_NEMO_RELAY_ATIF_* variables are ignored; configure those outputs in the selected file instead. See NeMo Relay observability configuration. |
Agent Behavior
| Variable | Description |
|---|---|
MINERVA_MAX_ITERATIONS | Classic CLI only: tool-calling iteration cap per conversation turn, used when neither --max-turns nor agent.max_turns is set. agent.max_turns is unlimited by default. |
MINERVA_INFERENCE_MODEL | Override model name at process level (takes priority over config.yaml for the session). Also settable via -m/--model flag. |
MINERVA_YOLO_MODE | Set to 1 to bypass dangerous-command approval prompts. Equivalent to --yolo. |
MINERVA_ACCEPT_HOOKS | Auto-approve any unseen shell hooks declared in config.yaml without a TTY prompt. Equivalent to --accept-hooks or hooks_auto_accept: true. |
MINERVA_IGNORE_USER_CONFIG | Skip ~/.minerva/config.yaml and use built-in defaults (credentials in .env still load). Equivalent to --ignore-user-config. |
MINERVA_IGNORE_RULES | Skip auto-injection of AGENTS.md, SOUL.md, .cursorrules, memory, and preloaded skills. Equivalent to --ignore-rules. |
MINERVA_SAFE_MODE | Troubleshooting mode: disable ALL customizations — skips plugin discovery, MCP server loading, and shell-hook registration. Set automatically by --safe-mode (which also sets the two flags above). |
MINERVA_TOOL_PROGRESS | Unsupported since the config-v12 support floor — the variable is ignored. Use display.tool_progress in config.yaml. |
MINERVA_TOOL_PROGRESS_MODE | Deprecated compatibility variable for tool progress mode (still read by the gateway as a fallback). Prefer display.tool_progress in config.yaml. |
MINERVA_HUMAN_DELAY_MODE | Response pacing: off/natural/custom |
MINERVA_HUMAN_DELAY_MIN_MS | Custom delay range minimum (ms) |
MINERVA_HUMAN_DELAY_MAX_MS | Custom delay range maximum (ms) |
MINERVA_QUIET | Suppress non-essential output (true/false) |
CODEX_HOME | When Codex app-server runtime is enabled, override the directory Codex CLI reads its config + auth from (default: ~/.codex). Minerva's migration writes the managed block to <CODEX_HOME>/config.toml. |
MINERVA_KANBAN_TASK | Set by the kanban dispatcher when spawning a worker (task UUID). Workers and the spawned minerva-tools MCP subprocess inherit it so kanban tools gate correctly. Don't set manually. |
MINERVA_ACP_SKIP_CONFIGURED_MCP | Set by an ACP host on the Minerva subprocess it spawns. 1 skips starting the globally configured config.yaml MCP servers before the ACP JSON-RPC loop, for hosts that pass the session's MCP servers through session/new themselves. Servers supplied by the ACP session are still registered; any other value keeps the default. Don't set manually. |
MINERVA_API_TIMEOUT | LLM API call timeout in seconds (default: 1800) |
MINERVA_API_CALL_STALE_TIMEOUT | Non-streaming stale-call timeout in seconds (default: 90). Auto-disabled for local providers when left unset, and may scale upward for very large contexts. Also configurable via providers.<id>.stale_timeout_seconds or providers.<id>.models.<model>.stale_timeout_seconds in config.yaml. |
MINERVA_STREAM_READ_TIMEOUT | Streaming socket read timeout in seconds (default: 120). Auto-increased to MINERVA_API_TIMEOUT for local providers. Increase if local LLMs time out during long code generation. |
MINERVA_STREAM_STALE_TIMEOUT | Stale stream detection timeout in seconds (default: 180). Auto-disabled for local providers. Triggers connection kill if no chunks arrive within this window. |
MINERVA_LOCAL_STREAM_STALE_TIMEOUT | Stale stream ceiling for local providers (Ollama, oMLX, llama-cpp) in seconds (default: 900). When the base stale timeout is at its default and a local endpoint is detected, this finite ceiling replaces the former infinite disable so a wedged local server eventually trips the detector instead of hanging forever. Also configurable via agent.local_stream_stale_timeout in config.yaml. |
MINERVA_STREAM_RETRIES | Number of mid-stream reconnect attempts on transient network errors (default: 2). |
MINERVA_STREAM_STALE_GIVEUP | Cross-turn circuit breaker: after this many consecutive stale kills (streaming or non-streaming) with no completed response, abort each call immediately with an actionable error instead of re-waiting out the stale timeout (default: 5, 0 disables). Resets on any completed response, /model switch, fallback activation, or turn-start primary restore. |
MINERVA_AGENT_TIMEOUT | Gateway inactivity timeout for a running agent in seconds (default: 1800, 30 minutes). Resets on every tool call and streamed token. Set to 0 to disable. |
MINERVA_GATEWAY_MAX_STARTS | Respawn-storm circuit breaker: maximum gateway (re)starts allowed within the window before an exponential backoff is slept to break the storm (default: 5, 0 disables). Also configurable via gateway.respawn_storm.max_starts in config.yaml. |
MINERVA_GATEWAY_START_WINDOW_S | Respawn-storm breaker window in seconds (default: 120). Also configurable via gateway.respawn_storm.window_seconds in config.yaml. |
MINERVA_AGENT_TIMEOUT_WARNING | Gateway: send a warning message after this many seconds of inactivity (default: 75% of MINERVA_AGENT_TIMEOUT). |
MINERVA_AGENT_NOTIFY_INTERVAL | Gateway: interval in seconds between progress notifications on long-running agent turns. |
MINERVA_CHECKPOINT_TIMEOUT | Timeout for filesystem checkpoint creation in seconds (default: 30). |
MINERVA_EXEC_ASK | Enable execution approval prompts in gateway mode (true/false) |
MINERVA_ENABLE_PROJECT_PLUGINS | Enable auto-discovery of repo-local plugins from ./.minerva/plugins/ for both the agent loader and the backend web server (minerva serve). Accepts the standard truthy set: 1 / true / yes / on (case-insensitive). Everything else — including 0, false, no, off, and the empty string — is treated as disabled (default). Note: as of GHSA-5qr3-c538-wm9j (#29156) the backend web server refuses to auto-import a project plugin's Python api file even when this var is enabled — a project plugin's backend routes are only loaded when it is moved under ~/.minerva/plugins/. |
MINERVA_PLUGINS_DEBUG | 1/true to surface verbose plugin-discovery logs on stderr — directories scanned, manifests parsed, skip reasons, and full tracebacks on parse or register() failure. Aimed at plugin authors. |
MINERVA_BACKGROUND_NOTIFICATIONS | Background process notification mode in gateway: concise (default), all, result, error, off |
MINERVA_EPHEMERAL_SYSTEM_PROMPT | Ephemeral system prompt injected at API-call time (never persisted to sessions) |
MINERVA_PREFILL_MESSAGES_FILE | Path to a JSON file of ephemeral prefill messages injected at API-call time. |
MINERVA_ALLOW_PRIVATE_URLS | true/false — allow tools to fetch localhost/private-network URLs. Off by default in gateway mode. |
MINERVA_REDACT_SECRETS | true/false — control secret redaction in tool output, logs, and chat responses (default: true). |
MINERVA_WRITE_SAFE_ROOT | Optional directory prefix that hard-blocks write_file/patch writes outside the listed roots (no approval prompt). Supports multiple directories separated by os.pathsep (: on Unix, ; on Windows). See MINERVA_WRITE_SAFE_ROOT below. |
MINERVA_DISABLE_LAZY_INSTALLS | Internal bridge var set automatically in the official Docker image to prevent runtime dependency installs into the immutable /opt/minerva tree. The user-facing equivalent is security.allow_lazy_installs: false in config.yaml; do not set this in .env. |
MINERVA_DISABLE_FILE_STATE_GUARD | Set to 1 to turn off the "file changed since you read it" guard on patch/write_file. |
MINERVA_BUNDLED_SKILLS | Comma-separated override for the list of bundled skills loaded at startup. |
MINERVA_DEBUG_INTERRUPT | Set to 1 to log detailed interrupt/cancel tracing to agent.log. |
MINERVA_DUMP_REQUESTS | Dump API request payloads to log files (true/false) |
MINERVA_DUMP_REQUEST_STDOUT | Dump API request payloads to stdout instead of log files. |
DELEGATION_MAX_CONCURRENT_CHILDREN | Max parallel subagents per delegate_task batch (default: 10, floor of 1, no ceiling). Also configurable via delegation.max_concurrent_children in config.yaml — the config value takes priority. |
MINERVA_WRITE_SAFE_ROOT
When this variable is set, write_file and patch may only target paths inside the listed directory prefix(es). Any path outside those roots is rejected immediately — the write does not go through the dangerous-command approval system and there is no prompt to override it.
The official Docker image sets MINERVA_WRITE_SAFE_ROOT=/opt/data alongside MINERVA_HOME=/opt/data so the agent cannot escape the mounted data volume.
Do not add this to ~/.minerva/.env unless you intend to sandbox writes. A common mistake is pointing it at a project directory while expecting the agent to edit ~/.minerva/cron/jobs.json, ~/.minerva/skills/, or scripts under a profile — those paths are outside the sandbox and every write_file/patch to them fails with an outside MINERVA_WRITE_SAFE_ROOT error.
To allow both a workspace and Minerva state, list both prefixes (order does not matter):
export MINERVA_WRITE_SAFE_ROOT=/path/to/project:/home/you/.minerva
Unset the variable or remove it from .env to restore normal writes (still subject to the credential-path denylist — see File write safety).
Interface
| Variable | Description |
|---|---|
MINERVA_TUI | Launch the TUI instead of the classic CLI when set to 1. Equivalent to passing --tui. |
MINERVA_TUI_DIR | Path to a prebuilt ui-tui/ directory (must contain dist/entry.js and populated node_modules). Used by distros and Nix to skip the first-launch npm install. |
MINERVA_TUI_RESUME | Resume a specific TUI session by ID on launch. When set, minerva --tui skips forging a fresh session and picks up the named session instead — useful for re-attaching after a disconnect or terminal crash. |
MINERVA_TUI_THEME | Force the TUI color theme: light, dark, or a raw 6-character background hex (e.g. ffffff or 1a1a2e). When unset, Minerva auto-detects using COLORFGBG and terminal background queries; this variable overrides detection on terminals (Ghostty, Warp, iTerm2, etc.) that don't set COLORFGBG. |
MINERVA_INFERENCE_MODEL | Force the model for minerva -z / minerva chat without mutating config.yaml. Pairs with the --provider flag. Useful for scripted callers (sweeper, CI, batch runners) that need to override the default model per run. |
Session Settings
| Variable | Description |
|---|---|
MINERVA_SESSION_ID | Exported automatically into every tool subprocess Minerva spawns (terminal, execute_code, persistent shell, Docker/Singularity backends, delegated subagent runs). Set by the agent to the current session ID; user scripts called from tools can read it to correlate their output, telemetry, or side effects with the originating Minerva session. You should not set this manually — overriding it from a parent shell only takes effect outside an agent run, and is overwritten the moment the agent starts a session. |
AI_AGENT | Set to minerva-agent by the CLI and gateway entry points (only when not already set by an outer harness), and exported into every terminal-tool shell — including remote backends (Docker, SSH, Modal, Daytona, Singularity, Vercel). The emerging cross-agent standard for child-process attribution — generic tooling (e.g. huggingface_hub's agent detection) reads it to know it runs under an AI agent. minerva-agent is a self-chosen id: it is not registered in the public agent-harness registry (huggingface.js agent-harnesses.ts), so registry-based tooling reports it as unknown. Don't set manually. |
MINERVA_AGENT | Set to true by the CLI and gateway entry points and exported into every terminal-tool shell so child processes can detect they run inside Minerva specifically. Don't set manually. |
Context Compression (config.yaml only)
Context compression is configured exclusively through config.yaml — there are no environment variables for it. Threshold settings live in the compression: block, while the summarization model/provider lives under auxiliary.compression:.
compression:
enabled: true
threshold: 0.50
target_ratio: 0.20 # fraction of threshold to preserve as recent tail
protect_last_n: 20 # minimum recent messages to keep uncompressed
Older configs with compression.summary_model, compression.summary_provider, and compression.summary_base_url are automatically migrated to auxiliary.compression.* on first load.
Auxiliary Task Overrides
Auxiliary tasks are configured in config.yaml under auxiliary.<task>.* (provider, model, base_url, api_key); see Configuration. The only environment overrides still read are legacy model overrides; prefer the config.yaml keys:
| Variable | Description |
|---|---|
AUXILIARY_VISION_MODEL | Legacy override for the vision model (vision_analyze, browser_vision). Prefer auxiliary.vision.model. |
AUXILIARY_VIDEO_MODEL | Legacy override for the video-analysis model, used when neither auxiliary.video.model nor auxiliary.vision.model is set. |
There are no AUXILIARY_VISION_PROVIDER, _BASE_URL or _API_KEY environment overrides; set auxiliary.vision.provider, base_url and api_key in config.yaml instead.
AUXILIARY_WEB_EXTRACT_* variables are obsolete: web_extract and browser snapshots no longer use an auxiliary LLM. Long pages and snapshots are truncated deterministically with the full text stored on disk for read_file paging.
For task-specific direct endpoints, Minerva uses the task's configured API key or OPENAI_API_KEY. It does not reuse OPENROUTER_API_KEY for those custom endpoints.
Fallback Providers (config.yaml only)
The primary model fallback chain is configured exclusively through config.yaml — there are no environment variables for it. Add a top-level fallback_providers list with provider and model keys to enable automatic failover when your main model encounters errors. Auxiliary tasks whose provider is auto also consult this chain before Minerva's built-in auxiliary discovery chain.
fallback_providers:
- provider: openrouter
model: anthropic/claude-sonnet-4
The older top-level fallback_model single-provider shape is still read for backward compatibility, but new configuration should use fallback_providers. For task-specific auxiliary policy, use auxiliary.<task>.fallback_chain in config.yaml; there is no environment variable equivalent.
See Fallback Providers for full details.
Provider Routing (config.yaml only)
These go in ~/.minerva/config.yaml under the provider_routing section:
| Key | Description |
|---|---|
sort | Sort providers: "price" (default), "throughput", or "latency" |
only | List of provider slugs to allow (e.g., ["anthropic", "google"]) |
ignore | List of provider slugs to skip |
order | List of provider slugs to try in order |
require_parameters | Only use providers supporting all request params (true/false) |
data_collection | "allow" (default) or "deny" to exclude data-storing providers |
Use minerva config set to set environment variables — it automatically saves them to the right file (.env for secrets, config.yaml for everything else).