OpenFang Configuration Reference

Complete reference for config.toml, covering every configurable field in the OpenFang Agent OS.


Overview

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:

[default_model]
provider = "ollama"
model = "llama3.2:latest"
base_url = "http://localhost:11434"
api_key_env = ""

Full Example

# ============================================================
# OpenFang Agent OS -- Complete Configuration Reference
# ============================================================

# --- Top-level fields ---
home_dir = "~/.openfang"             # OpenFang home directory
data_dir = "~/.openfang/data"        # SQLite databases and data files
log_level = "info"                   # trace | debug | info | warn | error
api_listen = "127.0.0.1:50051"      # HTTP/WS API bind address
network_enabled = false              # Enable OFP peer-to-peer network
api_key = ""                         # API Bearer token (empty = unauthenticated)
mode = "default"                     # stable | default | dev
language = "en"                      # Locale for CLI/messages
usage_footer = "full"                # off | tokens | cost | full

# --- Default LLM Provider ---
[default_model]
provider = "anthropic"
model = "claude-sonnet-4-20250514"
api_key_env = "ANTHROPIC_API_KEY"

# --- Fallback Providers ---
[[fallback_providers]]
provider = "ollama"
model = "llama3.2:latest"
api_key_env = ""

[[fallback_providers]]
provider = "groq"
model = "llama-3.3-70b-versatile"
api_key_env = "GROQ_API_KEY"

# --- Memory ---
[memory]
embedding_model = "all-MiniLM-L6-v2"
consolidation_threshold = 10000
decay_rate = 0.1

# --- Network (OFP Wire Protocol) ---
[network]
listen_addresses = ["/ip4/0.0.0.0/tcp/0"]
bootstrap_peers = []
mdns_enabled = true
max_peers = 50
shared_secret = ""                   # Required when network_enabled = true

# --- Web Tools ---
[web]
search_provider = "auto"             # auto | brave | tavily | perplexity | duckduckgo
cache_ttl_minutes = 15

[web.brave]
api_key_env = "BRAVE_API_KEY"
max_results = 5

[web.tavily]
api_key_env = "TAVILY_API_KEY"
search_depth = "basic"               # basic | advanced
max_results = 5
include_answer = true

[web.perplexity]
api_key_env = "PERPLEXITY_API_KEY"
model = "sonar"

[web.fetch]
max_chars = 50000
max_response_bytes = 10485760        # 10 MB
timeout_secs = 30
readability = true

# --- MCP Servers ---
[[mcp_servers]]
name = "filesystem"
timeout_secs = 30
env = []
[mcp_servers.transport]
type = "stdio"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/docs"]

[[mcp_servers]]
name = "remote-api"
timeout_secs = 60
env = ["GITHUB_PERSONAL_ACCESS_TOKEN"]
[mcp_servers.transport]
type = "sse"
url = "https://mcp.example.com/sse"

# --- A2A Protocol ---
[a2a]
enabled = false
listen_path = "/a2a"

[[a2a.external_agents]]
name = "research-agent"
url = "https://agent.example.com/.well-known/agent.json"

[[a2a.external_agents]]
name = "code-reviewer"
url = "https://reviewer.example.com/.well-known/agent.json"

# --- RBAC Users ---
[[users]]
name = "Alice"
role = "owner"                       # owner | admin | user | viewer
api_key_hash = ""
[users.channel_bindings]
telegram = "123456"
discord = "987654321"

[[users]]
name = "Bob"
role = "user"
[users.channel_bindings]
slack = "U0123ABCDEF"

# --- Channel Adapters ---
[channels.telegram]
bot_token_env = "TELEGRAM_BOT_TOKEN"
allowed_users = []
poll_interval_secs = 1

[channels.discord]
bot_token_env = "DISCORD_BOT_TOKEN"
allowed_guilds = []
intents = 33280

[channels.slack]
app_token_env = "SLACK_APP_TOKEN"
bot_token_env = "SLACK_BOT_TOKEN"
allowed_channels = []

Section Reference

Top-Level Fields

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.
language string "en" Language/locale code for CLI output and system messages.
usage_footer string "full" Controls usage info appended to responses.

[default_model]

Configures the primary LLM provider used when agents do not specify their own model.

[default_model]
provider = "anthropic"
model = "claude-sonnet-4-20250514"
api_key_env = "ANTHROPIC_API_KEY"
Field Type Default Description
provider string "anthropic" Provider name.
model string "claude-sonnet-4-20250514" Model identifier.
api_key_env string "ANTHROPIC_API_KEY" Name of the environment variable holding the API key.
base_url string or null null Override the API base URL.

[memory]

Configures the SQLite-backed memory substrate, including vector embeddings and memory decay.

[memory]
embedding_model = "all-MiniLM-L6-v2"
consolidation_threshold = 10000
decay_rate = 0.1
Field Type Default Description
sqlite_path path or null null Explicit path to the SQLite database file.
embedding_model string "all-MiniLM-L6-v2" Model name used for generating vector embeddings for semantic memory search.
consolidation_threshold u64 10000 Number of stored memories before automatic consolidation is triggered.
decay_rate f32 0.1 Memory confidence decay rate.

[network]

Configures the OFP (OpenFang Protocol) peer-to-peer networking layer with HMAC-SHA256 mutual authentication.

[network]
listen_addresses = ["/ip4/0.0.0.0/tcp/0"]
max_peers = 50
shared_secret = ""
Field Type Default Description
listen_addresses list of strings ["/ip4/0.0.0.0/tcp/0"] libp2p multiaddresses to listen on.
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.

[web]

Configures web search and web fetch capabilities used by agent tools.

[web]
search_provider = "auto"
cache_ttl_minutes = 15
Field Type Default Description
search_provider string "auto" Which search engine to use.
cache_ttl_minutes u64 15 Cache duration for search/fetch results in minutes.

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"
dm_policy = "respond"
group_policy = "mention_only"
rate_limit_per_user = 10
Field Type Default Description
model string or null null Model override for this channel.
system_prompt string or null null System prompt override for this channel.
dm_policy string "respond" How the bot handles direct messages.
group_policy string "mention_only" How the bot handles group messages.
rate_limit_per_user u32 0 Maximum messages per user per minute.
threading bool false Enable thread replies (where supported by the platform).

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.