Configuration Reference
Full reference for ~/.fathom/config.toml. All sections are optional — missing fields use defaults. Old configs without newer sections load without errors.
Full Example
# ─────────────────────────────────────────
# LLM Provider
# ─────────────────────────────────────────
[llm]
provider = "deepseek"
base_url = "https://api.deepseek.com"
api_key = "sk-your-key"
model = "deepseek-chat"
fast_model = ""
max_tokens = 8192
temperature = 0.7
# ─────────────────────────────────────────
# Agents
# ─────────────────────────────────────────
[agent]
max_depth = 2
max_agents = 20
max_iterations = 50
timeout_seconds = 600
use_multiprocess = false
stall_warn_seconds = 450
stall_kill_seconds = 1200
session_token_limit = 0
replan_rounds = 1
approval_tools = ["save_contacts", "git_push"]
approval_fallback = "allow"
approval_timeout_seconds = 300
# ─────────────────────────────────────────
# Search
# ─────────────────────────────────────────
[search]
backend = "hybrid"
[search.linkup]
api_key = "..."
[search.exa]
api_key = "..."
[search.tavily]
api_key = "..."
[search.serper]
api_key = "..."
[search.brave]
api_key = "..."
[search.parallel]
api_key = "..."
# ─────────────────────────────────────────
# Context Management
# ─────────────────────────────────────────
[context]
context_window = 128000
context_window_profile = "low"
compact_threshold = 0.50
tool_output_max_bytes = 50000
tool_output_max_lines = 2000
turn_budget_bytes = 200000
# ─────────────────────────────────────────
# Memory
# ─────────────────────────────────────────
[memory]
enabled = true
db_path = ""
embeddings = "auto"
embedding_model = "text-embedding-3-small"
semantic_weight = 0.7
top_k = 5
min_score = 0.25
temporal_decay = 0.01
auto_digest = true
llm_classify = true
rerank = false
gc_ttl_days = 30
gc_compact_above = 200
gc_auto = false
# ─────────────────────────────────────────
# Hooks
# ─────────────────────────────────────────
[[hooks]]
event = "PreToolUse"
command = "/usr/local/bin/my-guard.sh"
tool = "shell"
timeout_ms = 3000
# ─────────────────────────────────────────
# Output
# ─────────────────────────────────────────
[output]
dir = "./research-output"
# ─────────────────────────────────────────
# Export
# ─────────────────────────────────────────
[export]
format = "html"
# ─────────────────────────────────────────
# Notifications
# ─────────────────────────────────────────
[notifications]
webhook_url = ""
email_to = ""
email_from = ""
smtp_host = ""
smtp_port = 587
smtp_username = ""
smtp_password = ""
telegram_bot_token = ""
telegram_chat_id = ""
# ─────────────────────────────────────────
# Contacts
# ─────────────────────────────────────────
[contacts]
db_path = "./contacts.db"
pg_url = ""
# ─────────────────────────────────────────
# CRM Sync
# ─────────────────────────────────────────
[crm]
provider = ""
domain = ""
api_key = ""
# ─────────────────────────────────────────
# MCP Servers
# ─────────────────────────────────────────
[[mcp.servers]]
name = "web-search"
transport = "stdio"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-web-search"]
[[mcp.servers]]
name = "remote-tools"
transport = "http"
url = "https://mcp.example.com"[llm]
LLM provider settings. The api_key field is required for operation.
| Field | Type | Default | Description |
|---|---|---|---|
provider | string | “deepseek” | Provider name |
base_url | string | “https://api.deepseek.com” | API endpoint |
api_key | string | “” | Required for operation |
model | string | “deepseek-chat” | Model identifier |
fast_model | string | “” | Cheap/fast model for entity extraction, memory absorb, reranking. Empty = reuse model |
max_tokens | u32 | 8192 | Max response tokens |
temperature | f32 | 0.7 | Generation temperature |
[agent]
Agent orchestration settings: depth limits, concurrency, and timeouts.
| Field | Type | Default | Description |
|---|---|---|---|
max_depth | u32 | 2 | Max sub-agent nesting depth |
max_agents | u32 | 20 | Max agents per session |
max_iterations | u32 | 50 | Max LLM iterations per agent |
timeout_seconds | u64 | 600 | Session timeout (seconds) |
use_multiprocess | bool | false | Isolate agents in separate processes |
max_concurrent_children | u32 | 4 | Max children of one parent running concurrently |
stall_warn_seconds | u64 | 450 | Seconds of zero progress before stall warning (0 disables) |
stall_kill_seconds | u64 | 1200 | Seconds of zero progress before agent is cancelled (0 disables) |
deny_tools | map | {} | Per-role tool deny lists: {“verifier”: [“shell”, “save_contacts”]} |
role_models | map | {} | Per-role model overrides: {“researcher”: “deepseek-chat”} |
session_token_limit | u64 | 0 | Session-wide token budget; 0 disables. Fan-out stops when reached |
replan_rounds | u32 | 1 | Goal Mode: max gap-filling replan rounds after initial fan-out (0 disables) |
approval_tools | string[] | [“save_contacts”, “git_push”] | Tools requiring operator approval before execution |
approval_fallback | string | “allow” | Verdict when no operator connected: “allow” or “deny” |
approval_timeout_seconds | u64 | 300 | Seconds to wait for operator approval before fallback applies |
[search]
Search backend configuration. Sub-sections [search.*] contain API keys per provider. DuckDuckGo requires no key.
| Field | Type | Default | Description |
|---|---|---|---|
backend | string | “hybrid” | Search backend to use |
Backend Values
| Value | Description |
|---|---|
linkup | Linkup search API |
exa | Exa neural search |
tavily | Tavily search API |
serper | Serper (Google) API |
brave | Brave Search API |
parallel | Parallel.ai search API |
duckduckgo | DuckDuckGo (no key needed) |
hybrid | First configured backend with results (order: linkup → exa → tavily → serper → brave → parallel → duckduckgo) |
smart | All configured backends in parallel, dedup by URL, reciprocal rank fusion ranking |
[context]
Context management and token budget settings.
| Field | Type | Default | Description |
|---|---|---|---|
context_window | u32 | 128000 | Context window size (tokens) |
context_window_profile | string | “low” | Window profile: low (128K) or max (256K). Explicit context_window always wins |
compact_threshold | f32 | 0.50 | Compression trigger (fraction of window) |
tool_output_max_bytes | u32 | 50000 | Tool output limit (bytes) |
tool_output_max_lines | u32 | 2000 | Tool output limit (lines) |
turn_budget_bytes | u32 | 200000 | Aggregate budget per turn (bytes) |
[output]
| Field | Type | Default | Description |
|---|---|---|---|
dir | string | “./research-output” | Output directory for results |
[export]
| Field | Type | Default | Description |
|---|---|---|---|
format | string | “html” | pdf | html | json | docx. Unknown format falls back to HTML. PDF/DOCX require pandoc. |
[notifications]
Notifications are sent only when the corresponding field is non-empty.
| Field | Type | Default | Description |
|---|---|---|---|
webhook_url | string | “” | URL for JSON POST on completion |
email_to | string | “” | Email recipient |
email_from | string | “” | Email sender (default: fathom@localhost) |
smtp_host | string | “” | SMTP server (default: localhost) |
smtp_port | u16 | 587 | SMTP port |
smtp_username | string | “” | SMTP login |
smtp_password | string | “” | SMTP password |
telegram_bot_token | string | “” | Telegram bot token |
telegram_chat_id | string | “” | Telegram chat ID for notifications |
[contacts]
| Field | Type | Default | Description |
|---|---|---|---|
db_path | string | “./contacts.db” | SQLite database path |
pg_url | string | “” | PostgreSQL URL (non-empty → use PG instead of SQLite) |
[crm]
CRM synchronization. Leave provider empty to disable.
| Field | Type | Default | Description |
|---|---|---|---|
provider | string | “” | amocrm | bitrix24 | hubspot | empty |
domain | string | “” | Domain/subdomain (amoCRM, Bitrix24) |
api_key | string | “” | API key/token |
[memory]
Long-term semantic memory settings. The memory subsystem stores facts in SQLite with hybrid vector+BM25 search, entity graph, and automatic housekeeping.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Master switch. When false, no memory DB is opened and memory_* tools are not registered |
db_path | string | “” | Path to memory SQLite file. Empty = ~/.fathom/memory.db |
embeddings | string | “auto” | Embedding backend: auto, openai, or tfidf |
embedding_base_url | string | “” | OpenAI-compatible embeddings endpoint. Empty = reuse llm.base_url |
embedding_api_key | string | “” | API key for embeddings endpoint. Empty = reuse llm.api_key |
embedding_model | string | “text-embedding-3-small” | Embedding model id (OpenAI-compatible backend) |
semantic_weight | f32 | 0.7 | Hybrid search weight: score = w*semantic + (1-w)*bm25 |
top_k | u32 | 5 | Default number of memories returned by search/digest |
min_score | f32 | 0.25 | Minimum hybrid score for a search hit |
temporal_decay | f32 | 0.01 | Linear freshness decay per day (0 disables) |
auto_digest | bool | true | Inject topic digest into system prompt of top-level agents |
llm_classify | bool | true | Use LLM to classify new facts (duplicate/supersede/contradict/related) |
rerank | bool | false | Second-pass LLM reranking of search results (+1 LLM call per search) |
gc_ttl_days | u32 | 30 | GC: archive untouched run-scoped facts older than this |
gc_compact_above | u32 | 200 | GC: compact scope group when it holds more than this many active rows |
gc_confidence_decay_rate | f64 | 0.02 | GC: daily confidence decay rate for inactive memories |
gc_confidence_threshold | f64 | 0.15 | GC: confidence threshold below which a memory is archived |
gc_auto | bool | false | Auto-run GC + distill on a background timer (hourly) |
[[hooks]]
Lifecycle hooks — subprocesses invoked at defined points of the agent loop. JSON on stdin, JSON verdict on stdout. All hooks are best-effort: timeout, spawn failure, or unparsable verdict = allow.
| Field | Type | Default | Description |
|---|---|---|---|
event | string | required | PreToolUse, PostToolUse, or Stop |
command | string | required | Command to run (receives JSON on stdin, answers JSON on stdout) |
args | string[] | [] | Command arguments |
tool | string | “” | Only fire for this tool name (empty = all tools). Applies to Pre/PostToolUse |
timeout_ms | u64 | 5000 | Hook timeout in milliseconds (floor 500ms at runtime) |
Hook Events
| Event | Input (JSON on stdin) | Output (JSON on stdout) |
|---|---|---|
PreToolUse | {“event”:“PreToolUse”,“tool”:“…”,“args”:…} | {“decision”:“allow|deny”,“reason”:“…”} |
PostToolUse | {“event”:“PostToolUse”,“tool”:“…”,“result”:“…”,“success”:bool} | {“append_context”:“…”} |
Stop | {“event”:“Stop”,“final_summary”:“…”} | {“continue”:bool,“reason”:“…”} |
Stop hooks can force continuation up to 3 times (MAX_STOP_CONTINUATIONS). PostToolUse append_context values are concatenated and wrapped in [hook context].
[[mcp.servers]]
Array of MCP (Model Context Protocol) servers for extending tool capabilities.
| Field | Type | Description |
|---|---|---|
name | string | Server name |
transport | string | stdio | http |
command | string? | Command (for stdio transport) |
args | string[] | Arguments (for stdio transport) |
url | string? | URL (for http transport) |
Environment Variables
Environment variables override config-file values where the runtime defines an override. Generic config and state paths use PR_ names such as PR_CONFIG and PR_MEMORY_DB; specialized PARALLEL_* variables remain valid for CDP, vision, directory and Twitter integrations.
Priority Order
- 1Environment variablesHighest priority
PR_CONFIG,PR_MEMORY_DB, and other explicitly supported overrides; specializedPARALLEL_*variables apply only to their integrations - 2Config file
~/.fathom/config.toml - 3DefaultsLowest priority
Built-in default values
| Environment Variable | Config Equivalent | Description |
|---|---|---|
LLM_API_KEY | llm.api_key | LLM API key |
LLM_PROVIDER | llm.provider | LLM provider name |
LLM_MODEL | llm.model | Model identifier |
LLM_BASE_URL | llm.base_url | API endpoint |
SEARCH_BACKEND | search.backend | Search backend |
PARALLEL_VISION_API_BASE | — | Vision model API base URL |
PARALLEL_VISION_API_KEY | — | Vision model API key |
PARALLEL_VISION_MODEL | — | Vision model name |
PARALLEL_CDP_ENDPOINT | — | Chrome DevTools Protocol endpoint for browser tools (default: ws://127.0.0.1:9222) |
PARALLEL_2GIS_API_KEY | — | 2GIS Catalog API key for business directory search |
PARALLEL_GOOGLE_PLACES_API_KEY | — | Google Places API key for business directory search |
PARALLEL_YANDEX_MAPS_API_KEY | — | Yandex Maps Geosearch API key for business directory search |
PARALLEL_TWITTER_BEARER_TOKEN | — | Twitter/X API v2 bearer token for social search |
FATHOM_API_KEYS | — | Comma-separated API keys for HTTP server authentication |
FATHOM_RATE_LIMIT | — | HTTP server rate limit per client (default: 120 requests/minute) |
PR_CONFIG | — | Override config.toml file path |
PR_MEMORY_DB | memory.db_path | Override memory SQLite database path |
PR_OUTPUT_DIR | output.dir | Session output directory (passed to worker processes) |
PR_JOBS_DB | — | Override jobs database path |
PR_JOBS_DIR | — | Override jobs output directory |
FATHOM_CREDENTIAL_KEY | — | 32-byte AES-256-GCM vault key, supplied as 64-character hex or base64 |
FATHOM_COMPUTER_SERVICE_URL | — | Computer relay service URL (default: http://127.0.0.1:8765) |
COMPUTER_TOKEN | — | Authentication token for the computer service or supervisor |
COMPUTER_ALLOW_PRIVATE_HOSTS | — | Development-only override for private/localhost browser targets (default: false) |
Worker control plane
Persistent coworkers, schedules, credentials, notifications, replay and observability are HTTP control-plane capabilities. They are configured through the authenticated /api/v1 routes rather than additional TOML sections. Use the API reference for current routes and request contracts.
Computer use is enabled by the service settings above. The relay supports browser actions, screenshots, accessibility snapshots, confined files and operator control leases; Docker supervisor options are documented in the root docs/COMPUTER-USE.md.
CLI Config Commands
Manage configuration from the command line.
Show Current Config
fathom config showSet a Value
fathom config set llm.api_key "sk-..."Uses dot notation for nested keys: section.field.
Backwards Compatibility
All new sections use #[serde(default)]. Configs from older versions
(with only [llm], [agent], [search]) load correctly —
new fields receive default values automatically.