Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Settings Schema

This page is a typed, structured listing of every key in the caliban settings file. For a narrative explanation of how scopes interact, how to locate each file, and how to edit settings interactively, see Settings Reference and Settings Layering.

Settings files are TOML by primary convention (settings.toml / settings.local.toml); JSON is accepted on import only. Unknown top-level keys are tolerated for forward-compat.


Model / Agent

KeyTypeDefaultDescription
agentstring—Agent profile name (sub-agent dispatch hint). Reserved — not yet consumed by any dispatch path.
modelstring | { provider, name }—Primary model. Bare string (e.g. "claude-sonnet-4-6") or qualified object { provider = "anthropic", name = "..." }.
fallback_modelstring | { provider, name }—Fallback model when the primary errors. Same shapes as model.
model_overrides{ string → string }{}Per-route model overrides (keys are router route names). Reserved — not yet consumed: the router keys on route purpose, not this map. Router config now flows through the settings [router] section (#540); per-route overrides are folded in by #699.
effort"low" | "medium" | "high" | "max" | "auto"—Default reasoning effort level.

Permissions

Nested under the [permissions] table.

KeyTypeDefaultDescription
permissions.allowstring[][]Patterns that auto-allow (legacy bucket form).
permissions.askstring[][]Patterns that prompt the user (legacy bucket form).
permissions.denystring[][]Patterns that hard-deny (legacy bucket form).
permissions.rulesRuleSpec[][]Ordered v2 rule array. When non-empty, takes precedence over the three buckets above. Source order is preserved (first match wins).
permissions.enforceboolean—When true, refuse --no-permissions / bypass mode at startup.
permissions.default_modestring—Initial permission mode at session start. Values: default, acceptEdits, plan, auto, dontAsk, bypassPermissions.
permissions.audit_logbooleantrueAppend-only permission-decision log toggle.

RuleSpec fields (used in permissions.rules entries):

FieldTypeDescription
patternstringGlob matching Tool or Tool:first-arg-glob (e.g. "Bash:git *").
action"allow" | "ask" | "deny"Decision for matching calls.
commentstring (optional)Human-readable comment shown in /permissions.
reasonstring (optional)Deny reason shown to the operator and logged.
expires_atISO 8601 timestamp (optional)Rule is skipped after this time.
[permissions]
# v2 ordered rules (preferred)
[[permissions.rules]]
pattern = "Bash:git *"
action  = "allow"
comment = "git commands OK"

[[permissions.rules]]
pattern = "Bash:rm *"
action  = "deny"
reason  = "use git revert"

[[permissions.rules]]
pattern = "*"
action  = "ask"

Sandbox

Nested under the [sandbox] table. OS-sandbox posture for Bash commands run under --workspace / --restrict-paths (#406, ADR 0054).

KeyTypeDefaultDescription
sandbox.network"deny" | "allow""deny" (when the fence is active)Network-egress posture for sandboxed commands. "deny" blocks egress (loopback still works) — git fetch, cargo, npm install, gh, curl fail; "allow" restores full egress. Overridden by --sandbox-network on the CLI. This is the first user-reachable sandbox setting.
[sandbox]
network = "allow"   # opt out of the default egress fence for this workspace

Secret-scrubbing is automatic, not a settings key

Under --workspace, sandboxed commands also run with a scrubbed environment — secret-named variables (*KEY*, *SECRET*, *TOKEN*, *PASSWORD*, *CREDENTIAL*, plus OTEL_EXPORTER_OTLP_HEADERS) are dropped from the child's environment (#405). This is on by default and is not (yet) configured through settings.toml.


Hooks

KeyTypeDefaultDescription
hooks{ string → … }{}Raw hook event → handler list map (parsed into caliban_config_types::HooksConfig, re-exported as caliban_agent_core::HooksConfig).
disable_all_hooksbooleanfalseKill-switch: disable every external hook handler.
allow_managed_hooks_onlybooleanfalseWhen true, only managed-scope hooks fire.
allowed_http_hook_urlsstring[][]HTTP-hook URL allowlist (glob patterns).
http_hook_allowed_env_varsstring[][]Environment variable names that HTTP hooks are permitted to read.

MCP Servers

Under [mcp_servers.<name>]. Each entry configures one MCP server.

KeyTypeDefaultDescription
type"stdio" | "http" | "sse""stdio"Transport selector. Also accepted as transport (TOML alias).
commandstring""Executable command (stdio only).
argsstring[][]Argv after the command (stdio only).
env{ string → string }{}Environment variables injected for the server process (stdio only).
cwdstring—Working directory override (stdio only).
urlstring—Absolute http:// or https:// URL (http/sse transports).
headers{ string → string }{}Static request headers (http/sse only).
oauth"off" | "auto" | "manual""off"OAuth mode (http/sse only).
disabledbooleanfalseMark this server disabled without removing the entry.
permissionsobject—Per-server permission scoping (composes with global rules).
[mcp_servers.linear]
command = "npx"
args    = ["-y", "@linear/mcp-server"]

The gonzalo code-graph server is a stdio server consumed the same way — point command at the gonzalo-mcp binary and pass the store root (populated with gonzalo index) via env. Its tools then surface as mcp__gonzalo__{search,node,callers,callees,impact,explore}:

[mcp_servers.gonzalo]
command = "gonzalo-mcp"
[mcp_servers.gonzalo.env]
GONZALO_ROOT = "/path/to/graph-store"

Router

KeyTypeDefaultDescription
routerobject—Model-router config — the same shape as the [router] section of caliban.toml (default_purpose + [[router.route]]), plus optional per-provider [router.provider.X] blocks. Schema owned by caliban-model-router, so the settings layer carries it as an opaque object.

Router config resolves through the settings layer: the router value flows through the normal settings precedence and shows up in caliban config print with its source scope like any other key. The one exception is an explicit --config <PATH> / CALIBAN_ROUTER_CONFIG file, which is the highest-precedence source and overrides the settings [router] section when set. If neither is present, caliban uses the single-provider fallback.

Per-provider overrides (api_key_env / base_url — e.g. for a proxy or a keyless local endpoint) go under [router.provider.X]:

[router]
default_purpose = "main_loop"

[[router.route]]
purpose = "main_loop"
provider = "openai"
model = "local-model"

[router.provider.openai]
base_url = "http://localhost:8080/v1"

Migrating from caliban.toml

The walk-up / home-dir caliban.toml discovery was removed in #699 — a bare repo-root caliban.toml is no longer picked up automatically. Migrate an existing one into the settings layer with caliban config import-router (it moves top-level [provider.X] blocks under [router.provider.X]), or keep pointing at it explicitly with --config.


Memory

Nested under [memory].

KeyTypeDefaultDescription
memory.auto_memory_enabledboolean—Enable / disable auto-memory topic files.
memory.auto_memory_directorystringPlatform defaultDirectory for auto-memory topic files.
memory.cap_tokens_autointeger—Token budget cap for the auto-memory tier.
memory.cap_tokens_claude_mdinteger—Token budget cap for the CLAUDE.md tier.
memory.cap_tokens_combinedinteger—Combined token budget cap across all tiers.

Plugins

KeyTypeDefaultDescription
pluginsobject—Plugin manager knobs (schema owned by caliban-plugins). Reserved — not yet consumed: the plugin manager currently reads its config from the environment (PluginSettings::from_env), not this key.

UI

KeyTypeDefaultDescription
output_stylestring"default"Active output-style name (see Output Styles). Precedence: the CALIBAN_OUTPUT_STYLE env var wins, then this setting, then default (#620).
editor_modestring—Input editing mode: "vim" or "emacs". Reserved — not yet consumed (the vim/emacs editing feature is tracked by #11); setting it has no effect today.
view_modestring—TUI layout mode: "compact" or "expanded". Reserved — not yet consumed; no layout switch exists yet.
statusLine.commandstring—Required when statusLine is set. Shell command whose stdout prefixes the status bar.
statusLine.timeout_msinteger (50–5000)—Maximum ms to wait for the status-line script.
statusLine.paddinginteger (0–8)—Spaces of padding around the custom segment.
tuiobject—TUI knobs. Reserved — not yet consumed (forward-compat placeholder; no sub-key is read today).

statusLine casing

statusLine uses camelCase on disk for Claude Code compatibility. The TOML alias status_line is also accepted.


Auth

KeyTypeDefaultDescription
api_key_helperstring | object | object[]—Provider API-key supplier(s). Bare string = command path; object = { command, provider?, refreshIntervalMs?, slowHelperWarningMs? }; array = per-provider list.

Observability

KeyTypeDefaultDescription
enable_telemetryboolean—OTel / cost emitter toggle.

Context-Window Management

KeyTypeDefaultDescription
auto_compact_thresholdnumber (0–1) or null0.75Pre-turn autocompaction threshold (context utilization fraction). null disables autocompact.
micro_compact_enabledbooleantrueEnable the per-turn microcompact (LLM-free supersession) pass.
compact_strategystring"summarize"Strategy used by /compact and threshold-autocompact: "summarize" (LLM summary of older turns — preserves context, incurs a provider call), "drop-oldest" (LLM-free; drops oldest turns past the recent window), or "noop" (disable).
tool_result_cap_charsinteger (≥ 0)50000Global per-tool-result cap in characters. 0 disables.
min_cache_block_tokensinteger (≥ 0)1024Minimum estimated tokens on the last user message to merit the conversation-level cache marker.

Stream Watchdog

The streaming idle watchdog aborts a run when a response goes silent for too long. It distinguishes two phases: prefill (before the first output token — where a slow local model with a large context may legitimately pause) and mid-content (after the first token, where a long gap signals a genuine stall).

KeyTypeDefaultDescription
stream_idle_timeout_msinteger (≥ 0)90000Silence (ms) tolerated after the first output token before aborting a stalled stream. 0 disables the watchdog entirely.
stream_prefill_timeout_msinteger (≥ 0)300000Silence (ms) tolerated before the first output token (slow local-model prefill). 0 falls back to the idle window. Frontier models prefill in milliseconds and never approach this.

Agent-Loop Policy

The [agent_loop] group gathers agent-loop policy — the turn budget and the spiral-containment guards — under one surface, distinct from the model-inference knobs (effort, thinking) that govern a single call (ADR 0058). Every key is optional and defaults to the value the loop has always used, so an absent group changes nothing.

[agent_loop]
max_turns = 80              # or pass --max-turns (CLI wins)
no_edit_nudge_threshold = 8
KeyTypeDefaultDescription
max_turnsinteger (≥ 0)50Hard cap on agent-loop iterations. The --max-turns CLI flag overrides this (precedence: CLI > settings > default). 0 is a deterministic immediate max-turns stop.
no_edit_nudge_thresholdinteger (≥ 0)10Consecutive zero-edit turns after which the loop injects one neutral "make the edit" nudge (#239). 0 disables the nudge.
empty_turn_nudge_maxinteger (≥ 0)2Maximum consecutive degenerate (output-but-no-work) turns the loop nudges before letting the run end (#249). 0 disables the guard.
max_turn_thinking_charsinteger (≥ 0)262144Per-turn cap on cumulative thinking characters before the run stops with ThinkingBudgetExhausted (#62). 0 disables the guard. A backstop far above any legitimate single-turn reasoning.
time_budget_secsinteger (≥ 0)0Wall-clock time budget for the whole agent loop, in seconds. 0/unset means no deadline (today's behavior). A positive value ends the run with TimeBudgetExceeded once that many seconds elapse — checked at the top of each turn, so the loop stops between turns rather than mid-turn. Headless: subtype=time_budget, exit code 75 (same graceful-bound class as max-turns).
cost_budget_usdnumber (≥ 0)(none)Cost budget for the whole agent loop, in USD. Unset or ≤ 0 means no cost cap. A positive value ends the run with CostBudgetExceeded once the run's accumulated estimated cost (usage × the rate card in caliban-telemetry) reaches it — checked between turns. Works in TUI and headless (unlike the CLI-only --max-budget-usd). Headless: subtype=budget_exceeded, exit code 137. Cost is $0.00 (cap inert) for a model with no rate-card entry.
verification_guidance"off" | "verify-when-cheap" | "full"(from profile)How much the system prompt encourages the model to verify its own work. off injects no guidance. verify-when-cheap encourages a quick reproduction when cheap. full strongly encourages reproduce-then-confirm. caliban never runs tests for the model — this only shapes the prompt. When unset, the effective value comes from the resolved profile (below); when set, it wins over the profile.
profile"cost-optimized" | "quality-first" | "local-guarded"(adaptive)Named policy profile bundling the loop knobs (ADR 0058, B6). When unset, the default is chosen from execution context: a local provider (an OpenAI-compatible endpoint on a loopback/private/LAN host via OPENAI_BASE_URL) → local-guarded; cloud (first-party providers, or OpenAI at its public endpoint) → cost-optimized. Naming a profile overrides the context default.

Profiles. Each profile sets a coherent verification posture (the lever eval sub-project A proved load-bearing, whose sign flips with model strength: +8pt on a strong cloud model, −16pt on a weak local one). Budgets (max_turns / time_budget_secs / cost_budget_usd) stay opt-in — a profile never imposes a surprising hard cap.

Profileverification_guidanceIntent
cost-optimizedoffCloud default: cost-conservative (verification costs ~1.8×, so skip it).
quality-firstfullFor a strong model: correctness over cost.
local-guardedverify-when-cheapLocal default: verify (generation is ~free), paired with the wrong-path/divergence guard once that ships (B4, #664).

Precedence: an explicit knob (e.g. verification_guidance) > the named profile > the context-adaptive default.

max_turns and the three guards were the existing loop knobs; time_budget_secs (B2, #662), cost_budget_usd (B3, #663), verification_guidance (B5, #665), and profile + adaptive defaults (B6, #666) are the additions. The remaining child — the eval-gated wrong-path/divergence guard (B4, #664) — will complete the local-guarded pairing when it lands.


Enterprise (Managed Scope)

KeyTypeDefaultDescription
parent_settings_behavior"block" | "augment""augment"When "block" in the managed scope, the managed layer flips to the top of the merge chain (enterprise lockdown).

Miscellaneous

KeyTypeDefaultDescription
additional_directoriesstring[][]Intended as extra workspace roots for file/shell tools. Reserved — not yet consumed: no tool path is gated on it today (workspace-scoping follow-ups are tracked by #324). Distinct from the env-driven CLAUDE.md search-root plumbing.
claude_md_excludesstring[][]Glob patterns to exclude from CLAUDE.md/AGENTS.md discovery (claudeMdExcludes). Unioned with the CALIBAN_CLAUDE_MD_EXCLUDES env var — both sets apply (#694).
env{ string → string }{}Environment-variable overrides applied to child processes caliban spawns — Bash commands, stdio MCP servers, and command hooks (#694). Precedence: a more-specific per-item env (an MCP server's env, a hook's env) wins over these, which in turn override the inherited process environment.

Environment overrides

A subset of settings can be overridden by CALIBAN_* environment variables that are read into the settings layer. The environment wins over the settings file, and each override is attributed in caliban config print under _env_overrides (a list of { key, env }) so you can see exactly which key an environment variable set — the environment is a real, visible source, not a silent side channel (#538).

VariableSettings keyNotes
CALIBAN_STORAGE_SUBSTRATEstorage.substrateSame vocabulary as the file (fs / remote / git / s3); an invalid value is a hard error naming the variable (#659).
CALIBAN_STORAGE_REMOTE_URLstorage.remote.urlSynthesizes [storage.remote] when absent.
CALIBAN_STORAGE_REMOTE_TOKEN_ENVstorage.remote.token_envThe name of the variable holding the token, never the token itself.

A blank (empty / whitespace-only) value is ignored — the file setting stands.

Note

This is the initial slice of the environment settings layer: today it covers the storage overrides, applied through a single aggregation point (Settings::apply_env_overrides) with an injectable lookup so configurations are testable without mutating process env. Extending the registry to the remaining CALIBAN_* settings-shadowing variables (and adding a CI lint that bans ad-hoc env::var reads for them) is tracked as the #538 follow-up. Bootstrap/runtime variables — the daemon launch contract, path pointers, logging, secrets, and the provider/OTel SDK contracts — are intentionally not part of this layer.