You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
OpenFang reads its configuration from a single TOML file:
~/.openfang/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.
Minimal Configuration
The simplest working configuration only needs an LLM provider API key set as an environment variable. With no config file at all, OpenFang boots with Anthropic as the default provider:
# ~/.openfang/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
~/.openfang
OpenFang home directory. Stores config, agents, skills.
data_dir
path
~/.openfang/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:50051"
Bind address for the HTTP/WebSocket/SSE API server.
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).
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.
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.
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 secret for OFP HMAC-SHA256 mutual authentication. Required when network_enabled = true. Both sides must use the same secret. 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.
[channels]
All 40 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.
Every channel config includes a default_agent field (optional agent name to route messages to) and an overrides sub-table (see Channel Overrides).
Maps channel platform names to platform-specific user IDs, binding this user identity across channels.
api_key_hash
string or null
null
SHA256 hash of the user's personal API key for authenticated API access.
Role hierarchy (highest to lowest privilege):
Role
Description
owner
Full administrative access. Can manage all agents, users, and configuration.
admin
Can manage agents and most settings. Cannot modify owner accounts.
user
Can interact with agents. Limited management capabilities.
viewer
Read-only access. Can view agent responses but cannot send messages.
Channel Overrides
Every channel adapter supports an [channels.<name>.overrides] sub-table that customizes agent behavior per-channel.
[channels.telegram.overrides]
model = "claude-haiku-4-5-20251001"system_prompt = "You are a concise Telegram assistant."dm_policy = "respond"group_policy = "mention_only"rate_limit_per_user = 10threading = trueoutput_format = "telegram_html"usage_footer = "tokens"
Field
Type
Default
Description
model
string or null
null
Model override for this channel. Uses the agent's default model when null.
system_prompt
string or null
null
System prompt override for this channel.
dm_policy
string
"respond"
How the bot handles direct messages. See below.
group_policy
string
"mention_only"
How the bot handles group messages. See below.
rate_limit_per_user
u32
0
Maximum messages per user per minute. 0 = unlimited.
threading
bool
false
Enable thread replies (where supported by the platform).
output_format
string or null
null
Override output formatting. See below.
usage_footer
string or null
null
Override usage footer mode for this channel. Values: off, tokens, cost, full.
dm_policy values:
Value
Description
respond
Respond to all direct messages (default).
allowed_only
Only respond to DMs from users in the allowed list.
ignore
Ignore all direct messages.
group_policy values:
Value
Description
all
Respond to all messages in group chats.
mention_only
Only respond when the bot is @mentioned (default).
commands_only
Only respond to slash commands.
ignore
Ignore all group messages.
output_format values:
Value
Description
markdown
Standard Markdown (default).
telegram_html
Telegram HTML subset (<b>, <i>, <code>, etc.).
slack_mrkdwn
Slack mrkdwn format (*bold*, _italic_, `code`).
plain_text
No formatting markup.
Environment Variables
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.
TAVILY_API_KEY
[web.tavily]
Tavily Search API key.
PERPLEXITY_API_KEY
[web.perplexity]
Perplexity Search API key (shared with LLM provider).
Channel Tokens
Variable
Channel
Description
TELEGRAM_BOT_TOKEN
Telegram
Bot API token from @BotFather.
DISCORD_BOT_TOKEN
Discord
Discord bot token.
SLACK_APP_TOKEN
Slack
Slack app-level token (xapp-) for Socket Mode.
SLACK_BOT_TOKEN
Slack
Slack bot token (xoxb-) for REST API.
WHATSAPP_ACCESS_TOKEN
WhatsApp
WhatsApp Cloud API access token.
WHATSAPP_VERIFY_TOKEN
WhatsApp
Webhook verification token.
MATRIX_ACCESS_TOKEN
Matrix
Matrix homeserver access token.
EMAIL_PASSWORD
Email
Email account password or app password.
TEAMS_APP_PASSWORD
Teams
Azure Bot Framework app password.
MATTERMOST_TOKEN
Mattermost
Mattermost bot token.
TWITCH_OAUTH_TOKEN
Twitch
Twitch OAuth token.
ROCKETCHAT_TOKEN
Rocket.Chat
Rocket.Chat auth token.
ZULIP_API_KEY
Zulip
Zulip bot API key.
XMPP_PASSWORD
XMPP
XMPP account password.
GOOGLE_CHAT_SERVICE_ACCOUNT
Google Chat
Service account JSON key.
LINE_CHANNEL_SECRET
LINE
LINE channel secret.
LINE_CHANNEL_ACCESS_TOKEN
LINE
LINE channel access token.
VIBER_AUTH_TOKEN
Viber
Viber Bot auth token.
MESSENGER_PAGE_TOKEN
Messenger
Facebook page access token.
MESSENGER_VERIFY_TOKEN
Messenger
Webhook verification token.
REDDIT_CLIENT_SECRET
Reddit
Reddit app client secret.
REDDIT_PASSWORD
Reddit
Reddit bot account password.
MASTODON_ACCESS_TOKEN
Mastodon
Mastodon access token.
BLUESKY_APP_PASSWORD
Bluesky
Bluesky app password.
FEISHU_APP_SECRET
Feishu
Feishu/Lark app secret.
REVOLT_BOT_TOKEN
Revolt
Revolt bot token.
NEXTCLOUD_TOKEN
Nextcloud
Nextcloud Talk auth token.
GUILDED_BOT_TOKEN
Guilded
Guilded bot token.
KEYBASE_PAPERKEY
Keybase
Keybase paper key.
THREEMA_SECRET
Threema
Threema Gateway API secret.
NOSTR_PRIVATE_KEY
Nostr
Nostr private key (nsec or hex).
WEBEX_BOT_TOKEN
Webex
Webex bot token.
PUMBLE_BOT_TOKEN
Pumble
Pumble bot token.
FLOCK_BOT_TOKEN
Flock
Flock bot token.
TWIST_TOKEN
Twist
Twist API token.
MUMBLE_PASSWORD
Mumble
Mumble server password.
DINGTALK_ACCESS_TOKEN
DingTalk
DingTalk webhook access token.
DINGTALK_SECRET
DingTalk
DingTalk signing secret.
DISCOURSE_API_KEY
Discourse
Discourse API key.
GITTER_TOKEN
Gitter
Gitter auth token.
NTFY_TOKEN
ntfy
ntfy auth token (optional for public topics).
GOTIFY_APP_TOKEN
Gotify
Gotify app token (sending).
GOTIFY_CLIENT_TOKEN
Gotify
Gotify client token (receiving).
WEBHOOK_SECRET
Webhook
HMAC signing secret for webhook verification.
LINKEDIN_ACCESS_TOKEN
LinkedIn
LinkedIn OAuth2 access token.
Validation
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
access_token_env
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
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.
Related Configuration
Some subsystems have their own configuration that is not part of config.toml but is worth noting:
Session Compaction (runtime)
Configured internally via CompactionConfig (not currently exposed in config.toml):
Field
Default
Description
threshold
80
Compact when session message count exceeds this.
keep_recent
20
Number of recent messages preserved verbatim after compaction.
max_summary_tokens
1024
Maximum tokens for the LLM summary of compacted messages.
WASM Sandbox (runtime)
Configured internally via SandboxConfig (not currently exposed in config.toml):
Field
Default
Description
fuel_limit
1000000
Maximum CPU instruction budget. 0 = unlimited.
max_memory_bytes
16777216 (16 MB)
Maximum WASM linear memory.
timeout_secs
null (30s fallback)
Wall-clock timeout for epoch-based interruption.
Model Routing (per-agent manifest)
Configured in agent manifests via ModelRoutingConfig:
Field
Default
Description
simple_model
"claude-haiku-4-5-20251001"
Model for simple queries.
medium_model
"claude-sonnet-4-20250514"
Model for medium-complexity queries.
complex_model
"claude-sonnet-4-20250514"
Model for complex queries.
simple_threshold
100
Token count below which a query is classified as simple.
complex_threshold
500
Token count above which a query is classified as complex.
Autonomous Guardrails (per-agent manifest)
Configured in agent manifests via AutonomousConfig:
Field
Default
Description
quiet_hours
null
Cron expression for quiet hours (agent pauses during this window).
max_iterations
50
Maximum tool-use iterations per invocation.
max_restarts
10
Maximum automatic restarts before permanent stop.
heartbeat_interval_secs
30
Seconds between heartbeat health checks.
heartbeat_channel
null
Channel to send heartbeat status to (e.g., "telegram").