Skip to content

Configuration Reference

This page is the reference for config.yaml, organized under the Three Enriches — settings (simple), configurations (power user), and options (developer). For the conceptual overview, see The Three Enriches.

The source of truth is internal/config/config.go. If anything on this page contradicts the Go types in that file, trust the Go types.

AI Butler looks for config in a platform-specific location — typically ~/.config/aibutler/config.yaml on Linux/macOS. You can override this with AIBUTLER_CONFIG or a --config flag. If no config file exists, sensible defaults are used and AI Butler starts in single-user local mode.

settings: # tier 1 — simple, for everyone
configurations: # tier 2 — power-user structure
options: # tier 3 — developer tunables

settings:
language: en # UI language (ISO 639-1)
timezone: Europe/Madrid # IANA timezone
notifications: true
morning_briefing: "07:00" # time of day, or empty to disable
active_channels: # channels to activate at startup
- webchat
- telegram
model: claude # top-level model provider alias
persona_name: "Butler"
skills: [] # skill IDs to load
agents_enabled: true # enable specialist agents
agent_mode: swarm # single | multi | swarm | custom | auto
cost:
strategy: balanced # frugal | balanced | quality
monthly_budget: 25 # USD
offline_mode: false
telemetry_enabled: false

configurations:
models:
primary: claude-sonnet-4-6
fallback: claude-haiku-4-5

Per-channel toggles. The channel is activated only if it appears in settings.active_channels AND the required credentials are in the vault.

configurations:
channels:
telegram:
enabled: true
typing_indicators: true
voice_response: auto # text | voice | auto | both
slack:
enabled: true
typing_indicators: true
voice_response: text
configurations:
agents:
max_concurrent: 5
max_depth: 4
default_subagent_model: claude-haiku-4-5
routing: classify # classify | explicit | round-robin
custom_roles:
- name: reviewer
description: "Code review specialist"
model: claude-opus-4-6
tools: [file.read, file.search, git.diff, git.log]
system_prompt: "You are a careful code reviewer..."
configurations:
security:
shell:
mode: allowlist # allowlist | denylist
allowed:
- ls
- cat
- grep
- go
- git
configurations:
cost:
alerts: [50, 80, 100] # % of budget
alert_channel: telegram
on_budget_reached: warn # warn | pause
configurations:
web:
port: 3377
bind_address: 0.0.0.0
max_upload_size_mb: 25
configurations:
mcp:
servers:
- name: filesystem
command: ["mcp-server-filesystem", "/home/me"]
- name: github
command: ["mcp-server-github"]
configurations:
schedule:
enabled: true
configurations:
iot:
adapter: stub # "stub" (default) — or "homeassistant" when wired
configurations:
voice:
stt_provider: whisper # "whisper" | "stub"
tts_provider: stub # "stub" | "piper"
configurations:
embedding:
provider: "" # "" (auto) | openai | ollama | openai_compat
model: text-embedding-3-small
base_url: "" # only for ollama / openai_compat
configurations:
plugins:
auto_enable: true
plugin_dir: "" # defaults to <data_dir>/plugins
configurations:
a2a:
enabled: false
port: 8081
bind_address: 127.0.0.1
token_hashes: # SHA-256 hex hashes of allowed bearer tokens
- "a1b2c3d4..."
configurations:
mcp_server:
allowed_capabilities: # which capabilities are exposed to MCP clients
- memory.read
- data.read
configurations:
oauth:
redirect_uri: https://aibutler.example.com/oauth/callback
gmail:
client_id: ""
client_secret: ""
google_calendar:
client_id: ""
client_secret: ""
github:
client_id: ""
client_secret: ""
configurations:
swarm:
enabled: true
max_depth: 4
budget_usd: 5.0
workspace_ttl_hours: 24
configurations:
registry:
health_ttl_minutes: 5
self_register: false
configurations:
hooks:
pre_tool_use:
- command: "echo blocked >&2 && exit 2"
tools: ["shell.exec"]
post_tool_use:
- command: "gofumpt -w ."
tools: ["file.edit", "file.write"]

See Hooks for the full reference.

Role-based permission rules are expressed per-rule. See internal/config/config.go for the PermissionRuleConfig type.

configurations:
bridges:
bridges: # yes, nested — the outer key is reserved
ffmpeg-convert:
command: "ffmpeg"
args: ["-i", "{{input}}", "{{output}}", "-y"]
timeout: 60s
capabilities: [shell.execute]

See Subprocess Bridges for details.

configurations:
sandbox:
mode: workspace-only # off | workspace-only | allow-list
allow_paths:
- /home/me/projects
- /tmp
configurations:
backup:
remote:
provider: s3 # s3 | http
endpoint: s3.amazonaws.com
bucket: my-aibutler-backups
region: us-east-1
access_key: "" # prefer vault over inline
secret_key: ""
encrypt_key: "" # optional age encryption key

Developer-tier tunables. Defaults are generally fine — only override when you know what you’re doing.

options:
models:
temperature: 0.7
max_tokens: 4096
request_timeout: 120s
retry_count: 3
options:
database:
busy_timeout: 5000
options:
agents:
max_tool_calls: 50
subagent_timeout: 5m
background_timeout: 30m
background_max: 3
per_subagent_budget: 0 # 0 = unlimited
autonomy_level: l1 # l1 | l2 | l3
parallel_tool_limit: 5
per_user_agent_limit: 3
l3_time_bound: 30m
options:
prompts:
max_tier1_tokens: 500
max_skills_per_turn: 3
skill_trigger_threshold: 0.4
truncation_strategy: balanced # balanced | essential_only
max_instruction_tokens: 200
options:
cost:
cache_ttl: 5m
expensive_threshold: 10000
options:
typing:
interval_ms: 3000
timeout_ms: 120000
options:
media:
max_upload_size_mb: 20
max_text_lines: 500
options:
sessions:
cleanup_interval: 1h
max_age: 168h # 7 days
options:
schedule:
tick_interval: 60s
max_concurrent: 3
options:
voice:
max_audio_size_mb: 25
stt_timeout: 30s
options:
plugins:
max_plugins: 20
exec_timeout: 30s
max_memory_mb: 64
options:
transaction:
per_transaction_limit: 0 # max USD per transaction (0 = blocked)
daily_limit: 0 # max USD daily total (0 = blocked)

Terminal window
aibutler config show

Prints the current effective configuration, grouped by tier. Use this to verify overrides from env vars and command-line flags landed correctly.