LibreFang reads its configuration from a single TOML file:
~/.librefang/config.toml
On Windows, ~ resolves to C:\Users\<username>. If the home directory cannot be determined, the system temp directory is used as a fallback.
Key behaviors:
Every struct in the configuration uses #[serde(default)], which means all fields are optional. Omitted fields receive their documented default values.
Channel sections ([channels.telegram], [channels.discord], etc.) are Option<T> -- when absent, the channel adapter is disabled. Including the section header (even empty) enables the adapter with defaults.
Secrets are never stored in config.toml directly. Instead, fields like api_key_env and bot_token_env hold the name of an environment variable that contains the actual secret. This prevents accidental exposure in version control.
Sensitive fields (api_key, shared_secret) are automatically redacted in debug output and logs.
LibreFang supports splitting configuration across multiple files using the include field. This enables modular configs (e.g., separate files for channels, MCP servers, or environment-specific overrides).
Paths are relative to the directory containing the root config file.
Absolute paths are rejected with an error at startup.
.. path traversal components are rejected for security.
Maximum include nesting depth: 10 levels.
Include files are deep-merged before the root config. Root config values always override values from included files.
Include files can themselves contain include arrays (subject to the depth limit).
This mechanism is useful for keeping secrets in a separate file with stricter filesystem permissions, or for sharing a base config across multiple environments.
The simplest working configuration only needs an LLM provider API key set as an environment variable. With no config file at all, LibreFang boots with Anthropic as the default provider:
# ~/.librefang/config.toml# Minimal: just override the model if you want something other than defaults.# Set ANTHROPIC_API_KEY in your environment.[default_model]provider = "anthropic"model = "claude-sonnet-4-20250514"api_key_env = "ANTHROPIC_API_KEY"
Or to use a local Ollama instance with no API key:
These fields sit at the root of config.toml (not inside any [section]).
Field
Type
Default
Description
home_dir
path
~/.librefang
LibreFang home directory. Stores config, agents, skills.
data_dir
path
~/.librefang/data
Directory for SQLite databases and persistent data.
log_level
string
"info"
Log verbosity. One of: trace, debug, info, warn, error.
api_listen
string
"127.0.0.1:4545"
Bind address for the HTTP/WebSocket/SSE API server. Alias: listen_addr.
network_enabled
bool
false
Enable the OFP peer-to-peer network layer.
api_key
string
"" (empty)
API authentication key. When set, all endpoints except /api/health require Authorization: Bearer <key>. Empty means unauthenticated (local development only).
cors_origin
list of strings
[]
CORS allowed origins added to the allow list (in addition to localhost). E.g., ["https://dash.example.com"].
mode
string
"default"
Kernel operating mode. See below.
language
string
"en"
Language/locale code for CLI output and system messages.
usage_footer
string
"full"
Controls usage info appended to responses. See below.
prompt_caching
bool
true
Enable LLM provider prompt caching. Adds cache hints to system prompts (Anthropic: cache_control, OpenAI: automatic prefix caching).
stable_prefix_mode
bool
false
When enabled, avoids volatile system-prompt additions (recalled memory, canonical context) that change every turn, improving provider-side prompt cache hit rates.
max_cron_jobs
usize
500
Global maximum number of cron jobs across all agents.
workspaces_dir
path or null
null
Root directory for agent workspaces. Defaults to ~/.librefang/workspaces. Contains agent working directories and the hands/ subdirectory for user custom hands.
Provider base URL overrides. Maps provider ID to custom base URL (e.g., ollama = "http://192.168.1.100:11434/v1"). Useful for self-hosted or proxied endpoints.
provider_api_keys
map of string→string
{}
Provider API key env var overrides. Maps provider ID to the name of an environment variable holding the key (e.g., nvidia = "NVIDIA_API_KEY"). When not set for a provider, the convention {PROVIDER_UPPER}_API_KEY is used.
provider_regions
map of string→string
{}
Provider region selection. Maps provider ID to a region name defined in the provider's registry TOML (e.g., qwen = "intl"). Overrides the provider's base URL and optionally its API key env var. Applied before provider_urls (lower priority).
tool_timeout_secs
u64
300
Global timeout in seconds for all tool executions. Can be overridden per-tool via [tool_timeouts] section.
tool_timeouts
map of string→u64
{}
Per-tool timeout overrides. Keys are exact tool names or glob patterns. See [tool_timeouts] section for details.
mode values:
Value
Behavior
stable
Conservative: no auto-updates, pinned models, frozen skill registry. Uses FallbackDriver.
default
Balanced: standard operation.
dev
Developer: experimental features enabled.
usage_footer values:
Value
Behavior
off
No usage information shown.
tokens
Show token counts only.
cost
Show estimated cost only.
full
Show both token counts and estimated cost (default).
[default_model]
Configures the primary LLM provider used when agents do not specify their own model.
Explicit path to the SQLite database file. When null, defaults to {data_dir}/librefang.db.
embedding_model
string
"all-MiniLM-L6-v2"
Model name used for generating vector embeddings for semantic memory search.
embedding_provider
string or null
null
Embedding provider (e.g., "openai", "ollama"). Auto-detected if null.
embedding_api_key_env
string or null
null
Environment variable name holding the API key for the embedding provider.
consolidation_threshold
u64
10000
Number of stored memories before automatic consolidation is triggered to merge and prune old entries.
consolidation_interval_hours
u64
24
How often memory consolidation runs (hours). 0 = disabled.
decay_rate
f32
0.1
Memory confidence decay rate. 0.0 = no decay (memories never fade), 1.0 = aggressive decay. Values between 0.0 and 1.0.
[auto_dream]
Background memory consolidation ("dreams") — asks opt-in agents to reflect on and consolidate their own memory via a 4-phase prompt (Orient / Gather / Consolidate / Prune). Dreams trigger event-driven the moment an agent finishes a turn; a sparse backstop scheduler (default 1 day) catches opted-in agents that never turn. Disabled by default; individual agents still opt in via auto_dream_enabled = true on their manifest.
Master toggle. When false, no dream fires regardless of per-agent opt-in.
min_hours
f64
24.0
Minimum hours since that agent's last consolidation before the next one fires.
min_sessions
u32
5
Minimum sessions touched since that agent's last consolidation before the next one fires. Set to 0 to disable the session-count gate.
check_interval_secs
u64
86400
Backstop scheduler cadence, in seconds. Primary trigger is the AgentLoopEnd hook; this only controls the fallback for agents that never turn.
timeout_secs
u64
600
Timeout for a single dream invocation in seconds.
lock_dir
string
""
Optional override for the lock directory. Empty = <data_dir>/auto_dream/. Per-agent locks are stored as <dir>/<agent_id>.lock.
A dream fires for an agent when all gates hold: enabled = true, the agent's manifest has auto_dream_enabled = true, min_hours have elapsed since its last dream, min_sessions have been touched since then, and the per-agent lock can be acquired.
Per-agent opt-in can be toggled at runtime via PUT /api/auto-dream/agents/{id}/enabled (body {"enabled": bool}) or via the Settings → Auto-Dream card on the web dashboard — the new state takes effect at the next turn end (event-driven) or the next backstop tick, whichever comes first. See /configuration/core#auto_dream for the full reference including runtime tool restriction, manual controls, and audit events.
[network]
Configures the OFP (LibreFang Protocol) peer-to-peer networking layer. Authentication has two layers: a shared_secret HMAC admission gate plus per-node Ed25519 identity with TOFU pinning (#3873). The Ed25519 keypair and trust pins live in <data_dir>/peer_keypair.json and <data_dir>/trusted_peers.json.
libp2p multiaddresses to listen on. Port 0 means auto-assign.
bootstrap_peers
list of strings
[]
Multiaddresses of bootstrap peers for DHT discovery.
mdns_enabled
bool
true
Enable mDNS for automatic local network peer discovery.
max_peers
u32
50
Maximum number of simultaneously connected peers.
shared_secret
string
"" (empty)
Pre-shared admission secret for OFP HMAC-SHA256. Required when network_enabled = true. Both sides must use the same value. Acts as a coarse "cluster password" gate; per-node identity is provided separately by the Ed25519 keypair persisted in the data dir, so a leaked shared_secret cannot impersonate a previously-pinned peer. Redacted in logs.
[web]
Configures web search and web fetch capabilities used by agent tools.
Maximum characters returned in fetched content. Content exceeding this is truncated.
max_response_bytes
usize
10485760 (10 MB)
Maximum HTTP response body size in bytes.
timeout_secs
u64
30
HTTP request timeout in seconds.
readability
bool
true
Enable HTML-to-Markdown readability extraction. When true, fetched HTML is converted to clean Markdown.
ssrf_allowed_hosts
list of strings
[]
Hosts/CIDRs exempt from SSRF blocking. Supports CIDR notation ("10.0.0.0/8"), glob prefix patterns ("*.internal.example.com"), and literal IPs or hostnames. Cloud metadata ranges (169.254.0.0/16, 100.64.0.0/10) are always blocked regardless of this list.
[media]
Configures media understanding (image description, audio transcription, video description) for messages that include attachments.
Enable automatic link understanding. When true, URLs in messages are fetched and their content is summarized before the agent processes the message.
max_links
usize
3
Maximum number of links to process per message. Additional links are ignored.
max_content_bytes
usize
102400 (100 KB)
Maximum content size to fetch per link in bytes. Content exceeding this is truncated.
timeout_secs
u64
10
Per-link fetch timeout in seconds.
[channels]
All 45 channel adapters are configured under [channels.<name>]. Each channel is Option<T> -- omitting the section disables the adapter entirely. Including the section header (even empty) enables it with default values.
Universal channel fields: Every channel adapter supports the following common fields in addition to its own specific fields:
Field
Type
Default
Description
default_agent
string or null
null
Agent name to route messages to by default.
account_id
string or null
null
Unique identifier for this bot instance. Used for multi-bot routing via [[bindings]] match rules.
[channels.telegram]bot_token_env = "TELEGRAM_BOT_TOKEN"allowed_users = []# default_agent = "assistant"poll_interval_secs = 1# api_url = "https://api.telegram.org" # override for local Bot API server# account_id = "my-telegram-bot"
Field
Type
Default
Description
bot_token_env
string
"TELEGRAM_BOT_TOKEN"
Env var holding the Telegram Bot API token.
allowed_users
list of strings
[]
Telegram user IDs or usernames allowed to interact. Accepts numeric user IDs ("123456789"), usernames ("alice"), or usernames with @ ("@alice"). Case-insensitive. Empty = allow all.
default_agent
string or null
null
Agent name to route messages to.
poll_interval_secs
u64
1
Long-polling interval in seconds.
account_id
string or null
null
Unique bot instance identifier for multi-bot routing.
api_url
string or null
null
Override the Telegram Bot API base URL. Useful for local Bot API server instances. Defaults to https://api.telegram.org.
Env var holding the Azure Bot Framework app password.
security_token_env
string
"TEAMS_SECURITY_TOKEN"
Env var holding the outgoing webhook security token (base64-encoded, copied from the Teams portal). Used for HMAC-SHA256 verification of every inbound Authorization: HMAC <…> header. If unset or non-base64, signature verification is skipped and a warning is logged once at startup — production should always set this.
Env var holding the Viber Bot auth token. Required — also used as the HMAC-SHA256 key to verify every inbound X-Viber-Content-Signature; missing → 400, mismatched → 401.
Env var holding the Facebook App Secret. Used for HMAC-SHA1 verification of every inbound X-Hub-Signature header. If unset, signature verification is skipped and a warning is logged once at startup — production should always set this.
Supports two modes: stream (default, recommended) and webhook (legacy).
# Stream mode (recommended — no public IP needed)[channels.dingtalk]receive_mode = "stream"app_key_env = "DINGTALK_APP_KEY"app_secret_env = "DINGTALK_APP_SECRET"# Webhook mode (legacy)[channels.dingtalk]receive_mode = "webhook"access_token_env = "DINGTALK_ACCESS_TOKEN"secret_env = "DINGTALK_SECRET"webhook_port = 8457
Field
Type
Default
Description
receive_mode
string
"stream"
Connection mode: "stream" or "webhook".
app_key_env
string
"DINGTALK_APP_KEY"
Env var holding the DingTalk App Key (stream mode).
app_secret_env
string
"DINGTALK_APP_SECRET"
Env var holding the DingTalk App Secret (stream mode).
access_token_env
string
"DINGTALK_ACCESS_TOKEN"
Env var holding the DingTalk webhook access token (webhook mode).
secret_env
string
"DINGTALK_SECRET"
Env var holding the DingTalk signing secret (webhook mode). Required — webhook mode rejects requests without a numeric timestamp header (400), with a stale or mismatched signature (401).
webhook_port
u16
8457
Port for the incoming webhook (webhook mode only).
robot_code
string or null
null
Robot code for stream mode replies (defaults to app_key).
Env var holding the HMAC signing secret for verifying incoming webhooks.
listen_port
u16
8460
Port to listen for incoming webhook requests.
callback_url
string or null
null
URL to POST outgoing messages to. SSRF-guarded: the daemon refuses to start the adapter if this resolves to a private, loopback, link-local, multicast, or cloud-metadata range (e.g. 127.0.0.1, 10.0.0.1, 169.254.169.254, [::1], [::ffff:127.0.0.1]). Public hostnames only.
Delivery strategy. "parallel" = send to all agents simultaneously; "sequential" = send one at a time in order.
routes
map of string to list of strings
{}
Maps peer/channel identifiers to lists of agent names that receive the message.
[inbox]
File-based input inbox for async external commands. Drop text files into a watched directory and they are dispatched as messages to agents. Processed files are moved to a processed/ subdirectory to avoid redelivery.
Directory to watch. Defaults to $HOME_DIR/inbox/. Supports ~ expansion.
poll_interval_secs
u64
5
How often (in seconds) to scan the directory for new files. Minimum 1.
default_agent
string or null
null
Agent name to route files to when no agent: directive is found in the file.
File format: Plain text files (.txt, .md, .json, .py, etc.). The first line may contain an agent:<name> directive to target a specific agent; the rest is sent as the message body. Files without the directive use default_agent.
Safety limits: Files larger than 1 MB are skipped. Binary files (non-text extensions) are skipped. Empty files are moved to processed/ without sending.
Usage examples:
Target a specific agent:
cat > ~/.librefang/inbox/task.txt << 'EOF'agent:code-reviewerPlease review this code for security issues:def login(user, password): query = f"SELECT * FROM users WHERE name='{user}' AND pass='{password}'" return db.execute(query)EOF
Send to the default agent:
echo "Summarize today's system logs" > ~/.librefang/inbox/summarize.txt
Agent bindings route specific channel/account/peer combinations to specific agents. More specific bindings (more non-null fields) take priority over less specific ones.
Env var name holding the bearer token (NOT the token itself). Token must be ≥ 32 characters. Required when enabled = true.
max_payload_bytes
usize
65536
Maximum incoming payload size in bytes (64 KB default).
rate_limit_per_minute
u32
30
Maximum webhook requests per minute per source IP.
[proxy]
Configures HTTP proxy for all outbound connections (LLM APIs, web search, MCP servers, etc.). Environment variables HTTP_PROXY, HTTPS_PROXY, and NO_PROXY are also respected as fallbacks.
HTTP proxy URL. Falls back to HTTP_PROXY / http_proxy env var. Credentials in URLs are redacted in logs.
https_proxy
string or null
null
HTTPS proxy URL. Falls back to HTTPS_PROXY / https_proxy env var.
no_proxy
string or null
null
Comma-separated list of hosts/domains that bypass the proxy. Falls back to NO_PROXY / no_proxy env var.
[[sidecar_channels]]
Sidecar channel adapters allow external processes (written in any language) to act as channel adapters. Communication uses newline-delimited JSON over stdin/stdout.
Master switch for the terminal feature. When false, the terminal WebSocket endpoint is disabled entirely.
allow_remote
bool
false
Allows access from remote or proxied connections. When no auth is configured, allow_unauthenticated_remote must also be true or the connection is refused. Default behavior is local-only access without auth.
allow_unauthenticated_remote
bool
false
Hard foot-gun guard. Must be explicitly set to true to expose an unauthenticated shell over the network when allow_remote = true and no auth is configured. Otherwise such connections are refused even if allow_remote = true.
allowed_origins
list of strings
[]
Additional browser Origin values allowed for terminal WebSocket connections beyond localhost. Use this when the dashboard is served from a custom domain. [*] allows any HTTP/HTTPS origin and should only be used intentionally.
require_proxy_headers
bool
false
When true, loopback connections without proxy headers (X-Forwarded-For, X-Real-IP) are rejected. Enable only when running behind a reverse proxy that injects these headers. (Old name: trust_proxy_headers, still accepted as alias.)
tmux_enabled
bool
true
Enable tmux-backed multi-window terminal. Only effective when the tmux binary is available on the system.
max_windows
u32
16
Maximum number of tmux windows that may exist simultaneously. Guards against resource exhaustion.
tmux_binary_path
string or null
null
Explicit path to the tmux binary. If null, resolved via PATH.
Notes:
Missing Origin is allowed for non-browser clients.
allow_remote = true does not disable auth; if API keys or dashboard credentials are configured, remote clients still need valid auth.
Prefer explicit HTTPS origins over "*" for browser access.
The ws_terminal_messages_per_minute rate limit (default: 3600) in the [rate_limit] section controls per-connection WebSocket message throughput for interactive terminal sessions.
[queue]
Configures the agent command queue, including depth limits, TTL, and per-lane concurrency.
Global tool rules applied to all agents (checked after agent rules).
groups
list of ToolGroup
[]
Named tool groups for reuse in rules.
subagent_max_depth
u32
10
Maximum subagent spawning depth.
subagent_max_concurrent
u32
5
Maximum concurrent subagents.
ToolPolicyRule fields:
Field
Type
Description
pattern
string
Glob pattern to match tool names (e.g., "shell_*", "web_*", "mcp_github_*").
effect
string
"allow" or "deny". Deny-wins: if any deny rule matches, the tool is blocked regardless of allow rules.
ToolGroup fields:
Field
Type
Description
name
string
Group name (e.g., "web_tools", "code_tools").
tools
list of strings
Tool name patterns included in this group.
[tool_timeouts]
Configures per-tool execution timeouts. The global default timeout applies to all tools unless overridden by exact name or glob pattern.
# Global default timeout for all tools (seconds)tool_timeout_secs = 300# Per-tool timeout overrides (exact match or glob pattern)[tool_timeouts]agent_send = 600agent_spawn = 600"mcp_browser_*" = 900shell_exec = 300
Field
Type
Default
Description
tool_timeout_secs
u64
300
Global timeout in seconds for all tool executions. Increase for browser automation or long-running builds.
tool_timeouts
map of string→u64
{}
Per-tool timeout overrides. Keys are exact tool names or glob patterns (e.g., "mcp_browser_*"). Exact matches take priority over glob patterns; among globs, the longest matching pattern wins (most specific first). Falls back to tool_timeout_secs when no entry matches.
Master toggle — when false, the entire proactive memory subsystem is disabled.
auto_memorize
bool
true
Automatically extract and store memories after each agent execution.
auto_retrieve
bool
true
Automatically retrieve relevant memories before each agent execution.
max_retrieve
usize
10
Maximum number of memories to retrieve per query.
extraction_threshold
f32
0.7
Confidence threshold for near-duplicate detection (0.0–1.0).
extraction_model
string or null
null
LLM model for extraction. Supports provider/model (e.g. "anthropic/claude-haiku-4"), provider:model, or bare model name (uses default provider). If null, uses rule-based extraction. There is no separate extraction_provider field.
Session memory TTL in hours. Memories older than this are cleaned up before each agent execution.
duplicate_threshold
f32
0.5
Similarity threshold for duplicate detection (0.0–1.0). Uses vector cosine similarity when embeddings are available, otherwise falls back to Jaccard word overlap.
confidence_decay_rate
f64
0.01
Confidence decay rate per day. Follows exponential decay: conf × e^(−rate × days). Default of 0.01 takes ~70 days to halve.
max_memories_per_agent
usize
1000
Maximum memories per agent. When exceeded, oldest/lowest-confidence entries are evicted. 0 = no cap.
[context_engine]
Configures the pluggable context assembly engine that controls how agent memory is recalled and assembled into prompts.
Built-in engine name. Currently only "default" is supported.
plugin
string or null
null
Plugin name. Resolves to ~/.librefang/plugins/<name>/plugin.toml. Takes precedence over manual hooks if set.
hooks.ingest
string or null
null
Script path for the ingest hook (called on new user message).
hooks.after_turn
string or null
null
Script path for the after_turn hook (called after each completed turn).
hooks.runtime
string or null
"python"
Which launcher runs the hook scripts. Supported: python, native (exec a pre-compiled binary), v, node, deno, go, ruby, bash, bun, php, lua. Unknown values fall back to python with a warning.
plugin_registries
list of objects
Official registry
Plugin registries (GitHub owner/repo) to browse for installable plugins.
Hooks speak a language-agnostic JSON-over-stdin/stdout protocol — pick the runtime that matches your script:
# Go plugin[context_engine.hooks]ingest = "~/.librefang/plugins/my-go-recall/hooks/ingest.go"runtime = "go"# V plugin compiled to a native binary[context_engine.hooks]ingest = "~/.librefang/plugins/fast-recall/hooks/ingest"runtime = "native"
Checking runtime availability
Call GET /api/plugins/doctor to probe every runtime on the host and see which ones are missing — the response includes each runtime's detected version and an install hint. It also cross-references installed plugins and flags any whose declared runtime is not usable on this host.
Runtimes in the official Docker image
The official image (node:lts-bookworm-slim base) ships with python, node, bash, native ready to go. Other runtimes are not bundled to keep the image small — if you need them, extend the image with one of these snippets:
If a plugin's declared runtime is not on PATH, the hook returns a LauncherNotFound error with the install hint — existing plugins keep running, only the misconfigured one is affected.
[audit]
Configures audit log retention.
[audit]retention_days = 90
Field
Type
Default
Description
retention_days
u32
90
Number of days to retain audit log entries. 0 = unlimited retention.
[health_check]
Configures periodic health checks for LLM providers.
[health_check]health_check_interval_secs = 60
Field
Type
Default
Description
health_check_interval_secs
u64
60
Interval in seconds between provider health checks.
[plugins]
Configures additional plugin registries to search for installable context engine plugins.
Additional GitHub owner/repo plugin registries. Merged with context_engine.plugin_registries.
[prompt_intelligence]
Configures prompt versioning and A/B experiment support. When enabled, LibreFang automatically tracks prompt version history and supports running A/B experiments to compare prompt variants. See the Prompt Intelligence guide for full documentation.
Complete table of all environment variables referenced by the configuration. None of these are read by the config file itself -- they are read at runtime by the kernel and channel adapters.
LLM Provider Keys
Variable
Used By
Description
ANTHROPIC_API_KEY
[default_model]
Anthropic API key (Claude models).
GEMINI_API_KEY
Gemini driver
Google Gemini API key. Alias: GOOGLE_API_KEY.
OPENAI_API_KEY
OpenAI-compat driver
OpenAI API key.
GROQ_API_KEY
Groq provider
Groq API key (fast Llama inference).
DEEPSEEK_API_KEY
DeepSeek provider
DeepSeek API key.
PERPLEXITY_API_KEY
Perplexity provider / web search
Perplexity API key.
OPENROUTER_API_KEY
OpenRouter provider
OpenRouter API key.
TOGETHER_API_KEY
Together AI provider
Together AI API key.
MISTRAL_API_KEY
Mistral provider
Mistral AI API key.
FIREWORKS_API_KEY
Fireworks provider
Fireworks AI API key.
COHERE_API_KEY
Cohere provider
Cohere API key.
AI21_API_KEY
AI21 provider
AI21 Labs API key.
CEREBRAS_API_KEY
Cerebras provider
Cerebras API key.
SAMBANOVA_API_KEY
SambaNova provider
SambaNova API key.
HUGGINGFACE_API_KEY
Hugging Face provider
Hugging Face Inference API key.
XAI_API_KEY
xAI provider
xAI (Grok) API key.
REPLICATE_API_KEY
Replicate provider
Replicate API key.
Web Search Keys
Variable
Used By
Description
BRAVE_API_KEY
[web.brave]
Brave Search API key.
JINA_API_KEY
[web.jina]
Jina AI Search API key.
TAVILY_API_KEY
[web.tavily]
Tavily Search API key.
PERPLEXITY_API_KEY
[web.perplexity]
Perplexity Search API key (shared with LLM provider).
KernelConfig::validate() runs at boot time and returns a list of warnings (non-fatal). The kernel still starts, but logs each warning.
What is validated
For every enabled channel (i.e., its config section is present in the TOML), the validator checks that the corresponding environment variable(s) are set and non-empty:
Channel
Env vars checked
Telegram
bot_token_env
Discord
bot_token_env
Slack
app_token_env, bot_token_env (both checked)
WhatsApp
access_token_env
Matrix
access_token_env
Email
password_env
Teams
app_password_env
Mattermost
token_env
Zulip
api_key_env
Twitch
oauth_token_env
Rocket.Chat
token_env
Google Chat
service_account_env
XMPP
password_env
LINE
access_token_env
Viber
auth_token_env
Messenger
page_token_env
Reddit
client_secret_env
Mastodon
access_token_env
Bluesky
app_password_env
Feishu
app_secret_env
Revolt
bot_token_env
Nextcloud
token_env
Guilded
bot_token_env
Keybase
paperkey_env
Threema
secret_env
Nostr
private_key_env
Webex
bot_token_env
Pumble
bot_token_env
Flock
bot_token_env
Twist
token_env
Mumble
password_env
DingTalk
app_key_env (stream) or access_token_env (webhook)
Discourse
api_key_env
Gitter
token_env
ntfy
token_env (only if token_env is non-empty; public topics are OK without auth)
Gotify
app_token_env
Webhook
secret_env
LinkedIn
access_token_env
For web search providers, the validator checks:
Provider
Env var checked
brave
web.brave.api_key_env
jina
web.jina.api_key_env
tavily
web.tavily.api_key_env
perplexity
web.perplexity.api_key_env
duckduckgo
(no check -- no API key needed)
auto
(no check -- cascading fallback handles missing keys)
What is NOT validated
The api_key_env in [default_model] is not checked by validate(). Missing LLM keys cause errors at runtime when the driver is first used.
The shared_secret in [network] is not validated against network_enabled. If networking is enabled with an empty secret, authentication will fail at connection time.
MCP server configurations are not validated at config load time. Connection errors surface during the background MCP connect phase.
Agent manifests have their own separate validation.