Skip to main content

Configuration

All configuration is via microclaw.config.yaml.

For anti-drift defaults, use Generated Config Defaults and Generated Provider Matrix, produced from code by scripts/generate_docs_artifacts.mjs.

Required

KeyDescription
api_keyLLM API key (ollama can be empty; openai-codex supports OAuth or api_key)

At runtime, at least one channel must be enabled:

  • Telegram (legacy: telegram_bot_token; recommended: channels.telegram.accounts.<id>.bot_token)
  • Discord (legacy: discord_bot_token; recommended: channels.discord.accounts.<id>.bot_token)
  • Slack (legacy: channels.slack.bot_token + channels.slack.app_token; recommended: per-account tokens under channels.slack.accounts.<id>)
  • Feishu/Lark (legacy: channels.feishu.app_id + channels.feishu.app_secret; recommended: per-account credentials under channels.feishu.accounts.<id>)
  • IRC (channels.irc.server + channels.irc.nick + channels.irc.channels)
  • Web UI (web_enabled: true)

Optional

KeyDefaultDescription
telegram_bot_token""Telegram bot token from @BotFather (required only if Telegram is enabled)
channels.telegram.default_accountunsetDefault Telegram account ID in multi-account mode. If unset, uses default when present, otherwise first account key (sorted)
channels.telegram.accounts.<id>.bot_tokenunsetTelegram bot token for a specific account (recommended multi-account mode)
channels.telegram.accounts.<id>.bot_usernameunsetTelegram username for a specific account (without @)
channels.telegram.accounts.<id>.modelunsetOptional per-bot model override for this Telegram account
channels.telegram.accounts.<id>.soul_pathunsetOptional per-bot SOUL file path for this Telegram account
channels.telegram.accounts.<id>.allowed_groups[]Optional Telegram group allowlist scoped to that account
channels.telegram.allowed_user_ids[]Optional Telegram private-chat sender allowlist at channel scope
channels.telegram.accounts.<id>.allowed_user_ids[]Optional Telegram private-chat sender allowlist scoped to that account (merged with channel scope)
channels.discord.default_accountunsetDefault Discord account ID in multi-account mode. If unset, uses default when present, otherwise first account key (sorted)
channels.discord.accounts.<id>.bot_tokenunsetDiscord bot token for a specific account
channels.discord.accounts.<id>.allowed_channels[]Optional Discord channel allowlist scoped to that account
channels.discord.accounts.<id>.no_mentionfalseIf true, that Discord account replies in guild channels without mention
channels.discord.accounts.<id>.modelunsetOptional per-bot model override for this Discord account
channels.discord.accounts.<id>.soul_pathunsetOptional per-bot SOUL file path for this Discord account
allow_group_slash_without_mentionfalseIf true, group/server/channel slash commands can run without @mention (default remains mention-gated in groups/channels)
channels.slack.default_accountunsetDefault Slack account ID in multi-account mode
channels.slack.accounts.<id>.bot_tokenunsetSlack bot token for a specific account
channels.slack.accounts.<id>.app_tokenunsetSlack app token (Socket Mode) for a specific account
channels.slack.accounts.<id>.allowed_channels[]Optional Slack channel allowlist scoped to that account
channels.slack.accounts.<id>.modelunsetOptional per-bot model override for this Slack account
channels.slack.accounts.<id>.soul_pathunsetOptional per-bot SOUL file path for this Slack account
channels.feishu.default_accountunsetDefault Feishu/Lark account ID in multi-account mode
channels.feishu.accounts.<id>.app_idunsetFeishu/Lark app ID for a specific account
channels.feishu.accounts.<id>.app_secretunsetFeishu/Lark app secret for a specific account
channels.feishu.accounts.<id>.domainfeishuDomain for that account (feishu, lark, or custom URL)
channels.feishu.accounts.<id>.allowed_chats[]Optional Feishu chat allowlist scoped to that account
channels.feishu.accounts.<id>.modelunsetOptional per-bot model override for this Feishu/Lark account
channels.feishu.accounts.<id>.soul_pathunsetOptional per-bot SOUL file path for this Feishu/Lark account
channels.feishu.accounts.<id>.topic_modefalseOptional per-bot threaded reply mode; only supported for account domain feishu or lark
bot_username""Global default bot username (used by all channels unless overridden)
discord_bot_tokenunsetDiscord bot token (required only if Discord is enabled)
web_enabledtrueEnable local Web UI channel
llm_provideranthropicProvider preset ID (or custom ID). anthropic uses native Anthropic API, others use OpenAI-compatible API
modelprovider-specificModel name
llm_base_urlprovider preset defaultOptional custom base URL
openai_compat_body_overrides{}Global request-body overrides for OpenAI-compatible providers (openai, openrouter, deepseek, ollama, etc.)
openai_compat_body_overrides_by_provider{}Provider-specific OpenAI-compatible request-body overrides (keyed by provider name, case-insensitive)
openai_compat_body_overrides_by_model{}Model-specific OpenAI-compatible request-body overrides (keyed by exact model name)
data_dir~/.microclawData root (runtime data in data_dir/runtime, skills in data_dir/skills)
working_dir~/.microclaw/working_dirDefault working directory for bash/read_file/write_file/edit_file/glob/grep; relative paths resolve from here
working_dir_isolationchatWorking directory isolation mode for bash/read_file/write_file/edit_file/glob/grep: shared uses working_dir/shared, chat isolates each chat under working_dir/chat/<channel>/<chat_id>
high_risk_tool_user_confirmation_requiredtrueRequire explicit user confirmation before high-risk tool execution (for example bash)
sandbox.modeoffBash execution mode: off runs on host; all routes bash tool calls to Docker containers
sandbox.backendautoSandbox backend (auto/docker)
sandbox.imageubuntu:25.10Base image used for sandbox containers
sandbox.container_prefixmicroclaw-sandboxPrefix for sandbox container names
sandbox.security_profilehardenedSandbox privilege profile: hardened (--cap-drop ALL --security-opt no-new-privileges), standard (Docker default caps), privileged (--privileged)
sandbox.cap_add[]Optional extra Linux capabilities added with --cap-add (applies to hardened and standard)
sandbox.no_networktrueIf true, sandbox containers run with --network=none
sandbox.require_runtimefalseIf true and Docker is unavailable while sandbox.mode=all, command fails fast instead of host fallback
sandbox.mount_allowlist_pathunsetOptional external mount allowlist file (one allowed root path per line)
max_tokens8192Max tokens per LLM response
max_tool_iterations100Max tool-use loop iterations per message
max_document_size_mb100Maximum allowed inbound Telegram document size (files above limit are rejected with a hint message)
max_history_messages50Number of recent messages sent as context
control_chat_ids[]Chat IDs allowed to perform cross-chat tool actions
plugins.enabledfalseEnable plugin manifest loading and plugin command/tool/context runtime
plugins.dir<data_dir>/pluginsOptional plugin manifest directory override
max_session_messages40Message threshold that triggers context compaction
compact_keep_recent20Number of recent messages kept verbatim during compaction
reflector_enabledtrueEnable the background memory reflector (see Memory System)
reflector_interval_mins15How often the reflector runs (minutes)
memory_token_budget1500Estimated token budget for injecting structured memories into prompt context
embedding_providerunsetRuntime embedding provider (openai or ollama) for semantic memory; leave unset to disable
embedding_api_keyunsetAPI key for embedding provider (if required)
embedding_base_urlunsetOptional custom embedding API base URL
embedding_modelprovider defaultEmbedding model name
embedding_dimprovider defaultEmbedding vector dimension used by sqlite-vec index
channels.<name>.soul_pathunsetOptional channel-level SOUL file path fallback
soul_pathunsetPath to a SOUL.md file that defines bot personality, voice, and values. If unset, checks data_dir/SOUL.md then ./SOUL.md

Path compatibility:

  • If users already configured data_dir / skills_dir / working_dir, those values keep working unchanged.
  • If not configured, defaults are data_dir=~/.microclaw, skills_dir=<data_dir>/skills, working_dir=~/.microclaw/working_dir.

OpenAI-compatible body overrides

Use these keys when a provider/model needs extra OpenAI-compatible request body parameters.

Merge order (later wins):

  1. openai_compat_body_overrides (global)
  2. openai_compat_body_overrides_by_provider[llm_provider]
  3. openai_compat_body_overrides_by_model[model]

Set a value to null to remove that key from the outgoing JSON body.

llm_provider: "deepseek"
model: "deepseek-chat"

openai_compat_body_overrides:
temperature: 0.2
max_tokens: 4096

openai_compat_body_overrides_by_provider:
deepseek:
top_p: null
reasoning_effort: "high"

openai_compat_body_overrides_by_model:
deepseek-chat:
temperature: 0.0

Behavior details:

  • provider keys are normalized to lowercase during config load
  • model keys are trim-normalized and matched by exact model string
  • runtime-controlled fields such as stream mode and tool payload can still be set by MicroClaw depending on request path

With per-bot model overrides

When channels.<name>.accounts.<id>.model is set, MicroClaw uses that bot/account model for requests on that channel account. openai_compat_body_overrides_by_model then matches against that effective model.

llm_provider: "openrouter"
model: "openai/gpt-4o-mini" # global default fallback

channels:
telegram:
default_account: "main"
accounts:
main:
enabled: true
bot_token: "xxx"
model: "openai/gpt-4o-mini"
ops:
enabled: true
bot_token: "yyy"
model: "deepseek/deepseek-chat"

openai_compat_body_overrides:
temperature: 0.2

openai_compat_body_overrides_by_model:
"openai/gpt-4o-mini":
temperature: 0.0
"deepseek/deepseek-chat":
top_p: null
reasoning_effort: "high"

Notes:

  • llm_provider is still global today.
  • If two bots share the same model string, they share the same by_model override block.

Docker sandbox

To run bash tool calls in containers, set:

sandbox:
mode: "all"
backend: "auto"
security_profile: "hardened" # hardened|standard|privileged
# cap_add: ["SETUID", "SETGID", "CHOWN"]
image: "ubuntu:25.10"
container_prefix: "microclaw-sandbox"
no_network: true
require_runtime: false

Behavior:

  • sandbox.mode: "off" (default): host execution.
  • sandbox.security_profile defaults to hardened:
    • hardened: --cap-drop ALL --security-opt no-new-privileges (most restrictive)
    • standard: Docker default capabilities (useful when sandbox commands need apt/chown/su)
    • privileged: full container privilege (--privileged), debugging only
  • sandbox.cap_add appends --cap-add entries for hardened and standard.
  • sandbox.mode: "all" + Docker unavailable:
    • require_runtime: false: fallback to host with warning.
    • require_runtime: true: fail fast.

Quick opt-in:

microclaw setup --enable-sandbox
microclaw doctor sandbox

Optional hardening files:

  • mount allowlist: ~/.microclaw/sandbox-mount-allowlist.txt
  • file path allowlist: ~/.microclaw/sandbox-path-allowlist.txt

Each file supports one absolute path per line (# comments allowed).

Channel-specific required fields

channels.<name>.bot_username is optional for all channels.
If set, it overrides global bot_username for that channel.

  • Telegram enabled:
    • Legacy single-account: telegram_bot_token + username (bot_username or channels.telegram.bot_username)
    • Multi-account: at least one enabled channels.telegram.accounts.<id>.bot_token
  • Discord enabled:
    • Legacy single-account: discord_bot_token
    • Multi-account: at least one enabled channels.discord.accounts.<id>.bot_token
  • Slack enabled:
    • Legacy single-account: channels.slack.bot_token and channels.slack.app_token
    • Multi-account: at least one enabled account with both channels.slack.accounts.<id>.bot_token and channels.slack.accounts.<id>.app_token
  • Feishu/Lark enabled:
    • Legacy single-account: channels.feishu.app_id and channels.feishu.app_secret
    • Multi-account: at least one enabled account with channels.feishu.accounts.<id>.app_id and channels.feishu.accounts.<id>.app_secret
  • IRC enabled: channels.irc.server, channels.irc.nick, and channels.irc.channels are required. Optional: port, password, mention_required, tls, tls_server_name, tls_danger_accept_invalid_certs.
  • Web-only mode is valid: keep web_enabled: true (default) and leave other channel tokens empty.

IRC channel keys

KeyDefaultDescription
channels.irc.serverunsetIRC server host or IP
channels.irc.port"6667"IRC port
channels.irc.nickunsetIRC bot nick
channels.irc.usernameunsetIRC username (defaults to nick when empty)
channels.irc.real_name"MicroClaw"IRC real name sent in USER command
channels.irc.channelsunsetComma-separated channel list (for example #general,#ops)
channels.irc.passwordunsetOptional IRC server password
channels.irc.modelunsetOptional model override for IRC bot
channels.irc.mention_required"true"Whether channel messages require mention to trigger reply
channels.irc.tls"false"Enable IRC TLS connection
channels.irc.tls_server_nameunsetOptional TLS SNI/server name override
channels.irc.tls_danger_accept_invalid_certs"false"Accept invalid TLS certs (testing only)

Supported llm_provider values

openai, openai-codex, openrouter, anthropic, ollama, google, alibaba, deepseek, moonshot, mistral, azure, bedrock, zhipu, minimax, cohere, tencent, xai, huggingface, together, custom.

ollama is supported as a local OpenAI-compatible provider. Recommended defaults:

  • llm_base_url: http://127.0.0.1:11434/v1
  • api_key: optional
  • model: one of your local pulled models (for example llama3.2)

openai-codex supports two auth modes:

  • run codex login before microclaw start
  • OAuth token source: ~/.codex/auth.json (or $CODEX_HOME/auth.json)
  • or configure api_key for your OpenAI-compatible proxy endpoint

Multi-chat permissions

control_chat_ids defines which chats can perform cross-chat tool actions.

  • non-control chats: only their own chat_id
  • control chats: can operate across chats
  • global memory writes require control-chat privileges

See Multi-Chat Permissions for setup and verification steps.

Semantic memory switches (two-layer)

Semantic memory is intentionally guarded by two independent switches:

  1. Compile-time switch (default off): build with --features sqlite-vec
  2. Runtime switch (default off): set embedding_provider in config

If either switch is off, MicroClaw degrades gracefully to keyword retrieval + Jaccard dedup.

Build examples

Default safe build (no sqlite-vec):

cargo build --release

Enable sqlite-vec explicitly:

cargo build --release --features sqlite-vec

Runtime example

memory_token_budget: 1500

# optional semantic memory runtime config (requires --features sqlite-vec build)
embedding_provider: "openai" # openai | ollama
embedding_api_key: "sk-..."
# embedding_base_url: "http://127.0.0.1:11434/v1"
embedding_model: "text-embedding-3-small"
# embedding_dim: 1536

Setup Wizard

Run the recommended interactive Q&A flow:

microclaw setup

Features:

  • interactive terminal UI
  • provider/model list pickers (visible choices, not blind cycling)
  • local + online validation
  • safe microclaw.config.yaml write with backup in microclaw.config.backups/ (latest 50 kept)
  • supports multi-account JSON editing (channels.<name>.accounts) for Telegram/Discord/dynamic channels
  • supports per-bot soul_path picker (Telegram + dynamic channels): choose from discovered souls/*.md or manual filename/path input
  • Web Settings panel supports the same per-bot soul_path picker and account editing path

Preset providers:

  • openai
  • openrouter
  • anthropic
  • ollama
  • google
  • alibaba
  • deepseek
  • moonshot
  • mistral
  • azure
  • bedrock
  • zhipu
  • minimax
  • cohere
  • tencent
  • xai
  • huggingface
  • together
  • custom

Logging

Enable debug logging with:

RUST_LOG=debug microclaw start

Limit to MicroClaw logs:

RUST_LOG=microclaw=debug microclaw start