Skip to content

Reference configs

View Markdown~15,477 tokens

caudra config example FILE prints the reference of a TOML config file: every key the file accepts, with its description, type, and default, all commented out. This page shows the reference of each file. Config files explains what each file is for.

caudra.toml holds settings, and in the global file the [experimental] switches. Download this reference as caudra.example.toml.

# Every caudra.toml setting. Each one is commented out, so this file changes
# nothing until you edit it. `caudra config example caudra` prints it.
#
# To change a setting, copy its line into your caudra.toml under the same
# [table] header, remove the "#", and set your value. A value in angle
# brackets, such as <string>, marks a setting that has no default. The global
# file is ~/.config/caudra/caudra.toml, or %APPDATA%\caudra\caudra.toml on
# Windows. A project .caudra/caudra.toml takes the same settings, except
# [experimental], [automations], and the ones marked global-only.
#
# caudra.toml holds the settings only you write. Other files hold what Caudra
# writes itself, or what needs rules of its own: permissions.toml (permission
# rules for tools and MCP servers), mcp.toml (MCP servers), providers.toml
# (model providers and their models), workcell.toml (profiles for direct remote
# Workcell connections), sandboxes.toml (managed sandbox providers, networks,
# transfers, and profiles), init.lua (Lua code that sets up plugins), .env
# (environment variables, such as API keys, for any the environment does not
# set), commands/ (custom slash commands, one Markdown file each).
# `caudra config files` shows where each one lives, and
# `caudra config example FILE` prints the reference of a TOML file.
#
# Full reference: https://caudra.ai/docs/configuration/
version = 1
# Start every session with YOLO mode (skip permission prompts, deny rules still
# apply); global config only.
# Type: bool.
# always_yolo = false
# Start every session with Auto permission mode (preserve required prompts and
# screen unmatched calls); global config only. Needs
# `experimental.decision_engine`, otherwise sessions start in Ask.
# Type: bool.
# always_auto = false
# Start every session with fast mode, on the models that sell a fast tier
# (ignored otherwise).
# Type: bool.
# always_fast = false
# Start every session with extended thinking (true/"adaptive", "off", an effort
# level ("minimal" to "max"), or a token budget).
# Type: bool | string. Default: unset.
# always_thinking = <bool | string>
[experimental]
# Experimental features stay off until you turn them on, and each switch is
# independent. Only the global caudra.toml may hold this table. Caudra reads it
# once at startup, so a change needs a restart.
# Turn on workflows.
# Type: bool.
# workflows = false
# Turn on managed sandboxes.
# Type: bool.
# sandboxes = false
# Turn on direct remote Workcell connections.
# Type: bool.
# remote_workcell = false
# Turn on Lua plugins and init.lua.
# Type: bool.
# lua_plugins = false
# Turn on the decision engine and Auto mode.
# Type: bool.
# decision_engine = false
# Turn on cross-session messages.
# Type: bool.
# cross_session_messaging = false
# Turn on automations.
# Type: bool.
# automations = false
[ui]
# Show splash animation on startup.
# Type: bool.
# splash_animation = true
# Show vertical scrollbar in scrollable areas.
# Type: bool.
# scrollbar = true
# Touch-friendly pointer handling: auto, on, or off. Widens the scrollbar's hit
# zone so a finger can tap it, scrolls one line per wheel event instead of
# mouse_scroll_lines, and leaves text selection to the terminal. Auto detects
# Termux around Caudra itself, which SSH does not carry, so set this to on when
# reaching Caudra from a phone over SSH.
# Type: string.
# touch = "auto"
# Terminal notification method: auto, osc9, bell, or off. Auto is off in a
# Herdr pane, where Herdr shows its own notification when Caudra is blocked or
# finished.
# Type: string.
# notifications = "auto"
# How LaTeX maths renders: unicode (approximate with Unicode) or raw (show the
# LaTeX source).
# Type: string.
# math = "unicode"
# How mermaid flowcharts render: unicode (draw them with box-drawing
# characters) or off (leave the fence as code).
# Type: string.
# mermaid = "unicode"
# Duration of ordinary status-bar messages (ms). Confirmation prompts use a
# fixed 3-second window.
# Type: u64.
# flash_duration_ms = 10000
# How long Ctrl+X waits before listing the chords it can still reach (ms). 0
# shows the list at once.
# Type: u64.
# which_key_delay_ms = 250
# Typewriter effect speed (ms/char).
# Type: u64.
# typewriter_ms_per_char = 4
# Lines per mouse wheel scroll.
# Type: u32, at least 1.
# mouse_scroll_lines = 3
# Rows of body a shell, python_execution or task card draws. The window follows
# new output while it sits at the bottom and pauses when scrolled up. Click
# inside a window to give it the wheel, which passes back to the transcript at
# either edge, and drag the bar in its last column to move it directly. `0`
# turns scrolling off, restoring the `ui.tool_output_lines` budget for those
# tools. A write is never windowed: it is drawn whole at any setting, as the
# file it created or as the diff of what it replaced.
# Type: u32.
# scroll_card_lines = 10
# Tools whose card never opens on its own: the call stays a single row in every
# view mode until you click it. A server-qualified name still matches, so
# `file_read` also covers `mcp_File_read`. Set to `[]` to opt out.
# Type: string[].
# always_collapsed = ["file_read", "file_glob", "file_grep", "file_index", "webfetch"]
# Maximum visible input lines.
# Type: u32, at least 1.
# max_input_lines = 20
# Show full model reasoning live and persisted. Turn this off to start every
# reasoning block collapsed behind a Thinking or Thought header that can be
# clicked to expand.
# Type: bool.
# show_thinking = true
# Rows of body an open reasoning block draws. The window follows the reasoning
# while it streams and pauses when scrolled up, and a footer reports how much
# sits above and below. Click inside a window to give it the wheel, which
# passes back to the transcript at either edge, and drag the bar in its last
# column to move it directly. Click the footer to follow again. A finished
# block rests on its last rows until you move it. `0` draws every block whole.
# Type: u32.
# thinking_lines = 10
# Show the messages Caudra writes into the conversation on your behalf:
# standing reminders, goal check-ins, nudges, and continuations. Each is one
# dim row that expands on click to the exact text the model was sent. Turn this
# off to keep the transcript to the conversation alone.
# Type: bool.
# show_reminders = true
# Clock format for timestamps: "12h", "24h", or "system" (follow the OS
# preference, 24h when unknown).
# Type: String.
# clock_format = "system"
# Ask GitHub for the latest release on startup and show it in the splash. Off
# by default, so Caudra makes no such request unless you turn this on.
# Type: bool. Env: CAUDRA_ENABLE_UPDATE_CHECK.
# update_check = false
# Name of the color theme to load at startup, overriding the theme you last
# picked with `/theme`. Unset keeps your last pick.
# Type: string. Default: unset.
# theme = <string>
# Light theme to pair with `theme`, in place of the one from the pairing table
# or for a theme that has no pair. `theme` becomes the dark half.
# Type: string. Default: unset.
# theme_light = <string>
[ui.tool_output_lines]
# Rows of output an open tool card shows before it holds the rest back. `other`
# covers every tool that no other key names.
# Rows for `shell`.
# Type: usize, at least 1.
# bash = 5
# Rows for `python_execution`.
# Type: usize, at least 1.
# python_execution = 5
# Rows for `task`, `task_control`.
# Type: usize, at least 1.
# task = 12
# Rows for `file_index`, `code_map`, `code_context`, `code_refs`,
# `code_impact`, `code_expand`.
# Type: usize, at least 1.
# index = 3
# Rows for `file_grep`, `file_glob`.
# Type: usize, at least 1.
# grep = 3
# Rows for `file_read`.
# Type: usize, at least 1.
# read = 3
# Rows for `file_write`, `file_edit`, `file_apply_patch`, `image_generate`,
# `memory`, `plan`.
# Type: usize, at least 1.
# write = 7
# Rows for `webfetch`, `websearch`.
# Type: usize, at least 1.
# web = 3
# Rows for `automation`, `batch`, `execution_environment`, `list_sessions`,
# `publish_message`, `question`, `read_topic`, `send_message`, `skill`,
# `todo_write`, `tool_output`, `view_image`, `work_assignment`, `workflow`.
# Type: usize, at least 1.
# other = 3
[agent]
# Default user system prompt profile from the system-prompts config directory.
# Type: String.
# system_prompt_profile = "builtin"
# Host-enforced default max tool-result size (bytes).
# Type: usize, at least 1024.
# max_output_bytes = 51200
# Host-enforced default max tool-result lines.
# Type: usize, at least 10.
# max_output_lines = 2000
# Context reserved for compaction: token count or percent of the context window
# (e.g. "20%").
# Type: u32 | string. Default: 20%, or 10% when the model's window excludes
# output.
# compaction_buffer = <u32 | string>
# Extra instructions appended to the compaction summary prompt.
# Type: String. Default: unset.
# compaction_instructions = <String>
# Extra instructions the agent receives after any compaction (e.g. re-read
# plan.md).
# Type: String. Default: unset.
# post_compaction_instructions = <String>
# Append a `# User requirements` section to every compaction summary: what the
# user asked for, constrained, and decided, read from their own messages and
# answered questions across every earlier compaction, and extracted by the
# Extract model so the conversation model never sees the request.
# Type: bool.
# compaction_requirements = true
# Committed main-agent response groups between unchanged active background-work
# reminders; 0 disables periodic refresh only, not state-change or
# post-compaction reminders.
# Type: u32.
# background_reminder_turns = 0
# Before the main agent hands control back with pending or in-progress todos
# and no background work running, remind it once per run, repeating the full
# todo list, to verify the work and update the list.
# Type: bool.
# todo_reminder = true
# Task delivery: sync waits for the completed result, auto lets the model
# choose, async returns an admission receipt.
# Type: string.
# task_execution = "auto"
# Shell delivery: sync waits for termination, auto routes by requested timeout,
# async returns an admission receipt.
# Type: string.
# shell_execution = "auto"
# Requested shell timeout above which auto delivery returns an admission
# receipt; independent of the enforced execution deadline.
# Type: u64, at least 1.
# shell_async_threshold_secs = 120
# Name a new session by summarizing its first prompt with the Title model.
# Type: bool.
# generate_titles = true
# Block a write to a file that changed on disk since it was read, and point a
# failed edit or patch at the change.
# Type: bool.
# stale_read_check = true
# Repair malformed tool JSON syntax locally, with one bounded isolated model
# fallback; independent of eager dispatch.
# Type: bool.
# tool_json_repair = true
# Start tools and batch children as soon as their complete arguments arrive,
# instead of waiting for the whole message.
# Type: bool.
# eager_tool_dispatch = true
# Filter completed model-facing shell output with built-in rules.
# Type: bool.
# shell_output_filter = true
# Refuse shell commands with a leading literal `cd ... &&` in favor of the
# shell `workdir` parameter. Set to `false` to disable this nudge independently
# of `shell_native_redirect`.
# Type: bool.
# shell_workdir_redirect = true
# What happens when a shell command only re-implements a native tool, such as
# bare `rg` or `cat`: `enforce` refuses it and names the tool to call instead,
# `annotate` only logs the finding, `off` disables the check. A command using
# any flag the native tool cannot express is never affected.
# Type: string.
# shell_native_redirect = "enforce"
# When the on-demand built-in tools start outside the request array: `auto`
# defers them for a small model or one with no supply metadata and declares
# them upfront for a known non-small model, `always` defers for every model,
# `never` declares them upfront.
# Type: string.
# defer_builtin_tools = "auto"
# GPT Image 2.5 model behind `image_generate`: `sunburst` is the most capable
# and the better editor, `flare` is faster at the same price.
# Type: string.
# image_model = "sunburst"
# Tools to withhold from the model: built-in names, `server.tool`, or
# `server.*` for a whole MCP server. A project list extends the global one.
# Type: string[].
# disabled_tools = []
[agent.messaging]
# Inbound cross-session messages: `auto` accepts only compatible trusted peers,
# `accept` allows wider delivery, `hold` requires approval, `refuse` rejects
# messages. Project settings may only tighten policy: accept < auto < hold <
# refuse. Needs `experimental.cross_session_messaging`; accepting messages can
# start billable turns.
# Type: string.
# inbound = "auto"
# Most peer messages a session admits per minute from all senders together.
# Project settings may only lower it.
# Type: usize, at least 1.
# inbound_per_minute = 64
# Most peer messages a session admits per minute from one sending session.
# Project settings may only lower it.
# Type: usize, at least 1.
# sender_per_minute = 16
# Most topic and broadcast publications a session sends per minute. Project
# settings may only lower it.
# Type: usize, at least 1.
# publish_per_minute = 16
# Most live sessions one topic or broadcast publication reaches. Extra
# recipients are skipped and counted. Project settings may only lower it.
# Type: usize, at least 1.
# max_fanout = 32
# Days the shared message history keeps a message. The newest message on each
# topic outlives this until `history_max_messages` evicts it. Global config
# only.
# Type: u64, at least 1.
# history_days = 30
# Most messages the shared message history keeps; the oldest go first. Global
# config only.
# Type: u64, at least 1.
# history_max_messages = 50000
[agent.steering]
# Automatic steering repairs unusable model output and can add bounded guidance
# about repeated behavior. Each rule has its own table below.
# Master switch for automatic steering, including truncation recovery and
# repeat-policy blocking.
# Type: boolean.
# enabled = true
# Corrective continuations per externally initiated invocation. Zero prevents
# optional recovery continuations.
# Type: integer, 0 to 1024.
# max_recoveries = 32
# Advisory injections per invocation. Zero suppresses advisories.
# Type: integer, 0 to 1024.
# max_advisories = 4
# Consecutive turns carrying neither a tool call nor visible text before the
# run ends, whichever rule intervened. Zero disables the backstop.
# Type: integer, 0 to 1024.
# max_stalled_turns = 5
# Up to 256 exact `provider/model-id` keys, each with its own overrides.
# Type: table.
# models = {}
[agent.steering.rules.truncation]
# Continue output cut off by the response token limit, up to 3 corrective
# requests per externally initiated invocation.
# Explicit `false` disables this rule.
# Type: boolean.
# enabled = true
# Use built-in guidance when omitted. Custom text must be nonblank and at most
# 16,384 UTF-8 bytes.
# Type: string. Default: unset.
# prompt = <string>
# Actual truncation-correction requests per externally initiated invocation,
# shared across truncation episodes.
# Type: integer, 1 to 1024.
# max_attempts = 3
[agent.steering.rules.empty_response]
# Continue after empty output, with separate per-episode limits after recent
# tools and while idle.
# Explicit `false` disables this rule.
# Type: boolean.
# enabled = true
# Use built-in guidance when omitted. Custom text must be nonblank and at most
# 16,384 UTF-8 bytes.
# Type: string. Default: unset.
# prompt = <string>
# Empty-output continuations per episode after recent tool results.
# Type: integer, 1 to 1024.
# max_after_tools = 3
# Empty-output continuations per episode without recent tool results.
# Type: integer, 1 to 1024.
# max_idle = 2
# Continuations per episode after a response that carried no content at all.
# Clamped by the limit above; repeating an unchanged request is not a retry.
# Type: integer, 1 to 1024.
# max_barren = 1
# Non-padding history messages inspected for recent tool results.
# Type: integer, 1 to 4096.
# recent_tool_window = 5
[agent.steering.rules.repeated_tool_call]
# Refuse the third consecutive identical top-level tool name/input before
# execution. Native batch children do not acquire this hard blocker.
# Explicit `false` disables this rule.
# Type: boolean.
# enabled = true
# Use built-in guidance when omitted. Custom text must be nonblank and at most
# 16,384 UTF-8 bytes.
# Type: string. Default: unset.
# prompt = <string>
# Consecutive identical top-level calls. Refuse the call reaching this
# threshold.
# Type: integer, 2 to 1024.
# threshold = 3
[agent.steering.rules.protocol_mismatch]
# Correct an explicit provider tool-use indication with no actual tool calls,
# up to 2 continuations per episode.
# Explicit `false` disables this rule.
# Type: boolean.
# enabled = true
# Use built-in guidance when omitted. Custom text must be nonblank and at most
# 16,384 UTF-8 bytes.
# Type: string. Default: unset.
# prompt = <string>
# Protocol corrective continuations per episode.
# Type: integer, 1 to 1024.
# max_attempts = 2
[agent.steering.rules.missing_task_report]
# Request a missing task summary or required structured report, up to 2
# corrections.
# Explicit `false` disables this rule.
# Type: boolean.
# enabled = true
# Use built-in guidance when omitted. Custom text must be nonblank and at most
# 16,384 UTF-8 bytes.
# Type: string. Default: unset.
# prompt = <string>
# Additional report-correction prompts per task invocation.
# Type: integer, 1 to 1024.
# max_attempts = 2
[agent.steering.rules.abandoned_turn]
# Continue a turn that ended by announcing work the response never performed,
# up to 2 continuations per episode. Spending the allowance accepts the text
# rather than failing the turn.
# Explicit `false` disables this rule.
# Type: boolean.
# enabled = true
# Use built-in guidance when omitted. Custom text must be nonblank and at most
# 16,384 UTF-8 bytes.
# Type: string. Default: unset.
# prompt = <string>
# Continuations per episode after a turn that announced work instead of doing
# it.
# Type: integer, 1 to 1024.
# max_attempts = 2
[agent.steering.rules.repetition]
# Advise on short exact tool cycles, including normalized native batch leaf
# calls, or repeated normalized assistant text.
# Explicit `false` disables this rule.
# Type: boolean.
# enabled = true
# Use built-in guidance when omitted. Custom text must be nonblank and at most
# 16,384 UTF-8 bytes.
# Type: string. Default: unset.
# prompt = <string>
# Recent normalized leaf tool calls retained for cycle detection.
# Type: integer, 1 to 4096.
# window = 24
# Exact repetitions of a tool cycle needed for an advisory.
# Type: integer, 2 to 1024.
# cycle_repeats = 3
# Maximum cycle length in leaf calls. Candidate cycle lengths start at 2.
# Type: integer, 2 to 1024.
# max_cycle = 4
# Recent completed assistant responses retained for text repetition.
# Type: integer, 1 to 4096.
# text_window = 8
# Matching nontrivial normalized assistant responses needed for an advisory.
# Type: integer, 2 to 1024.
# text_repeats = 3
# Completed model responses between this rule's advisories.
# Type: integer, 1 to 1024.
# cooldown = 3
[agent.steering.rules.tool_planning]
# Advise after consecutive failed tool attempts across responses, including
# attempts with different tools or inputs. Any successful tool result ends the
# failure episode. Repeating a successful call is insufficient.
# Explicit `false` disables this rule.
# Type: boolean.
# enabled = true
# Use built-in guidance when omitted. Custom text must be nonblank and at most
# 16,384 UTF-8 bytes.
# Type: string. Default: unset.
# prompt = <string>
# Number of most recent leaf tool calls that must all have failed since the
# last response containing a successful result.
# Type: integer, 1 to 1024.
# after_calls = 6
# Distinct completed model responses represented by those failed calls.
# Type: integer, 1 to 1024.
# after_responses = 3
# Completed model responses between this rule's advisories.
# Type: integer, 1 to 1024.
# cooldown = 3
[agent.steering.rules.relative_paths]
# Suggest up to two shorter relative forms when file, patch, code-graph, or
# shell `workdir` paths spell out the working directory or its parent. The hint
# appears once per context.
# Explicit `false` disables this rule.
# Type: boolean.
# enabled = true
# Use built-in guidance when omitted. Custom text must be nonblank and at most
# 16,384 UTF-8 bytes.
# Type: string. Default: unset.
# prompt = <string>
# Characters a relative form must save over its absolute path before the path
# is suggested.
# Type: integer, 1 to 1024.
# min_saved_chars = 12
[provider]
# Default model identifier (e.g. `anthropic/claude-sonnet-4-6`).
# Type: String. Default: unset.
# default_model = <String>
# Glob patterns for permitted qualified model specs; empty permits all models.
# Type: string[].
# allowed_models = []
# Glob patterns for excluded qualified model specs; exclusions take precedence.
# Type: string[].
# excluded_models = []
# HTTP connect timeout (seconds).
# Type: u64, at least 1.
# connect_timeout_secs = 10
# Longest the server may send nothing before the request is abandoned
# (seconds).
# Type: u64, at least 10.
# stream_timeout_secs = 300
[storage]
# Max total log size (MB).
# Type: u64, at least 1.
# max_log_bytes_mb = 200
# Max number of log files to keep.
# Type: u32, at least 1.
# max_log_files = 10
# Largest session Caudra will hydrate when opening one (MB), counted in
# uncompressed payload bytes rather than disk or memory. A session past this
# refuses to load; trim it or raise this.
# Type: u64, at least 64. Env: CAUDRA_MAX_EAGER_LOAD_MB.
# max_eager_load_mb = 1024
# Minimum severity written to the log file: trace, debug, info, warn, or error.
# RUST_LOG overrides it.
# Type: string.
# log_level = "info"
# Number of input history entries to retain.
# Type: usize, at least 10.
# input_history_size = 100
# Store session data in a temporary directory removed when Caudra exits.
# Type: bool.
# ephemeral = false
[storage.retention]
# `trim` and `forget` take keep policies in `restic forget` terms, such as
# `{ keep_last = 50, keep_within = "90d" }`. A session is kept when any rule
# matches.
# Evaluate policies per working directory (`directory`) or across every session
# (`none`).
# Type: string.
# group_by = "directory"
# Hours between background sweeps. A sweep reclaims freed space, and applies
# `trim` and `forget` when they are set. `0` disables the sweep;
# `caudra storage` commands still work.
# Type: u64.
# sweep_interval_hours = 24
# Sessions outside this policy lose file revert, tool output files, archives,
# and large rich outputs but stay resumable. Empty means never trim
# automatically.
# Type: table.
# trim = {}
# Sessions outside this policy are deleted. Empty means never delete
# automatically.
# Type: table.
# forget = {}
[storage.snapshots]
# Each tool call that changes files leaves a change record, which file revert
# undoes. A record over a limit is refused and its call runs unrecorded.
# Record each tool call's file changes so file revert can undo them, locally
# and remotely. `false` turns recording and file revert off and keeps records
# already made. `--no-snapshots` overrides this for one run.
# Type: bool.
# enabled = true
# Most file data one change record may cover, and the size each workspace's
# change store is trimmed to. A record over it is refused and its call runs
# unrecorded. Values above the store's limit are lowered to it, and locally
# that limit is the default.
# Type: u64, at least 1.
# max_bytes_mb = 512
# Most files one change record may cover, counted after ignore rules. A record
# over it is refused and its call runs unrecorded. Values above the store's
# limit are lowered to it, and locally that limit is the default.
# Type: u64, at least 1.
# max_files = 50000
# Largest file a change record stores. A larger file is left unrecorded, and a
# file revert across a call that changed it stops with a conflict. Values above
# the store's limit are lowered to it, and locally that limit is the default.
# Type: u64, at least 1.
# max_file_bytes_mb = 100
[telemetry]
# Each setting that names an environment variable gives way to it.
# Master switch.
# Type: bool. Env: CAUDRA_ENABLE_TELEMETRY.
# enabled = false
# Where metrics go: `otlp`, `console`, `none`, or a comma-separated mix.
# Type: string. Env: OTEL_METRICS_EXPORTER.
# metrics_exporter = "none"
# Where events go: `otlp`, `console`, `none`, or a comma-separated mix.
# Type: string. Env: OTEL_LOGS_EXPORTER.
# logs_exporter = "none"
# OTLP protocol: `grpc`, `http/protobuf`, or `http/json`. Required when an
# exporter is `otlp`.
# Type: string. Default: unset. Env: OTEL_EXPORTER_OTLP_PROTOCOL.
# protocol = <string>
# Collector endpoint. HTTP appends `/v1/metrics` and `/v1/logs`.
# Type: string. Default: unset. Env: OTEL_EXPORTER_OTLP_ENDPOINT.
# endpoint = <string>
# Extra headers sent with every export.
# Type: table. Env: OTEL_EXPORTER_OTLP_HEADERS.
# headers = {}
# Per-export request timeout (ms).
# Type: integer. Env: OTEL_EXPORTER_OTLP_TIMEOUT.
# timeout_ms = 10000
# Payload compression: `gzip` or `none`.
# Type: string. Env: OTEL_EXPORTER_OTLP_COMPRESSION.
# compression = "none"
# Metrics-only protocol override.
# Type: string. Default: unset. Env: OTEL_EXPORTER_OTLP_METRICS_PROTOCOL.
# metrics_protocol = <string>
# Metrics-only endpoint, used verbatim with no path appended.
# Type: string. Default: unset. Env: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT.
# metrics_endpoint = <string>
# Metrics-only headers, merged over `headers`.
# Type: table. Env: OTEL_EXPORTER_OTLP_METRICS_HEADERS.
# metrics_headers = {}
# Metrics-only request timeout (ms).
# Type: integer. Default: unset. Env: OTEL_EXPORTER_OTLP_METRICS_TIMEOUT.
# metrics_timeout_ms = <integer>
# Logs-only protocol override.
# Type: string. Default: unset. Env: OTEL_EXPORTER_OTLP_LOGS_PROTOCOL.
# logs_protocol = <string>
# Logs-only endpoint, used verbatim with no path appended.
# Type: string. Default: unset. Env: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT.
# logs_endpoint = <string>
# Logs-only headers, merged over `headers`.
# Type: table. Env: OTEL_EXPORTER_OTLP_LOGS_HEADERS.
# logs_headers = {}
# Logs-only request timeout (ms).
# Type: integer. Default: unset. Env: OTEL_EXPORTER_OTLP_LOGS_TIMEOUT.
# logs_timeout_ms = <integer>
# How often metrics are exported (ms).
# Type: integer. Env: OTEL_METRIC_EXPORT_INTERVAL.
# metrics_interval_ms = 60000
# Deadline for one metrics export, retries included (ms).
# Type: integer. Env: OTEL_METRIC_EXPORT_TIMEOUT.
# metrics_export_timeout_ms = 30000
# How often queued events are flushed (ms).
# Type: integer. Env: OTEL_LOGS_EXPORT_INTERVAL, OTEL_BLRP_SCHEDULE_DELAY.
# logs_interval_ms = 5000
# Event queue capacity. Events are dropped and counted when it is full.
# Type: integer. Env: OTEL_BLRP_MAX_QUEUE_SIZE.
# logs_max_queue_size = 2048
# Maximum events per export request.
# Type: integer. Env: OTEL_BLRP_MAX_EXPORT_BATCH_SIZE.
# logs_max_export_batch_size = 512
# Deadline for one events export, retries included (ms).
# Type: integer. Env: OTEL_BLRP_EXPORT_TIMEOUT.
# logs_export_timeout_ms = 30000
# Metric temporality: `delta` or `cumulative`.
# Type: string. Env: OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE.
# metrics_temporality = "delta"
# `service.name` on the exported resource.
# Type: string. Env: OTEL_SERVICE_NAME.
# service_name = "caudra"
# Extra resource attributes, your place for team or environment labels.
# Type: table. Env: OTEL_RESOURCE_ATTRIBUTES.
# resource_attributes = {}
# Attach `session.id` to metrics. Turn off to keep metric cardinality low.
# Type: bool. Env: OTEL_METRICS_INCLUDE_SESSION_ID.
# metrics_include_session_id = true
# Attach `app.version` to metrics.
# Type: bool. Env: OTEL_METRICS_INCLUDE_VERSION.
# metrics_include_version = false
# Include prompt text in `caudra.user_prompt` events. Off by default.
# Type: bool. Env: OTEL_LOG_USER_PROMPTS.
# log_user_prompts = false
# Include tool input in `caudra.tool_result` events. Off by default.
# Type: bool. Env: OTEL_LOG_TOOL_DETAILS.
# log_tool_details = false
# Character cap on any logged prompt or tool input.
# Type: integer. Env: CAUDRA_OTEL_CONTENT_MAX_LENGTH.
# content_max_length = 10240
[worktrees]
# What creates and removes worktrees for `/worktree`: `auto` uses Herdr inside
# a Herdr pane and git elsewhere, `git` always runs git.
# Type: string.
# backend = "auto"
# Where git-created worktrees go, as `<directory>/<repository>/<branch>`. A
# leading `~/` is your home directory.
# Type: string. Default: `<data dir>/worktrees`.
# directory = <string>
[decisions]
# The typed decision engine. It needs `decision_engine = true` under
# [experimental]. Connection settings and thresholds are global-only.
# Decision API base URL, such as `https://api.typesafe.ai`. Caudra appends
# `/v1/systemone` and keeps any path prefix. `TYPESAFE_BASE_URL` replaces a
# configured value. HTTPS required except for numeric loopback HTTP or explicit
# `allow_http` consent. No credentials, query, fragment, whitespace, or control
# characters.
# Type: string. Default: unset.
# base_url = <string>
# Decision model identifier, nonblank and without control characters.
# Type: string.
# model = "jev-latest"
# Environment variable containing the optional credential, never the credential
# itself. Project environment values are excluded.
# Type: string.
# api_key_env = "TYPESAFE_API_KEY"
# Explicit global consent to send decision context to a non-loopback endpoint.
# Type: boolean.
# allow_remote = false
# Global-only opt-in for non-loopback HTTP. Also requires
# `allow_remote = true`. Use only with transport protection you control, such
# as a trusted encrypted tunnel.
# Type: boolean.
# allow_http = false
# Positive decision-request deadline in milliseconds, separate from shell
# execution timeouts.
# Type: integer.
# timeout_ms = 800
# Retain bounded decision records in the local `caudra.db`.
# Type: boolean.
# log = false
# Positive retention period for decision records.
# Type: integer.
# log_retention_days = 90
[decisions.features]
# `off` turns a feature off, `shadow` collects predictions without applying
# them, `advise` adds caution or suggestions, and `enforce` applies the
# feature's own behavior. Each feature lists the modes it takes.
# Add warnings to an existing permission prompt without delaying the answer.
# Modes: off, shadow, advise.
# Type: string.
# permission_advice = "off"
# Escalate an eligible Auto call to a prompt on a flag or engine failure. Only
# `enforce` lets Auto run scripts and other lines that cannot be checked
# command by command. No answer channel means denial. Modes: off, shadow,
# enforce.
# Type: string.
# auto_screening = "off"
# Warn about possible project writes during Plan review only when
# `shell_writes` is configured. Never establish read-only authority. Modes:
# off, shadow, advise.
# Type: string.
# shell_effect = "off"
# Add caution to flagged web/MCP output and tighten upload/credential Auto
# screening for the session. Content remains available. Modes: off, shadow,
# advise.
# Type: string.
# content_screening = "off"
# Advise with local shell estimates. Enforce may fill an omitted timeout and
# select delivery at admission. Explicit timeouts stay unchanged. Modes: off,
# shadow, advise, enforce.
# Type: string.
# shell_duration = "off"
# Rerank the existing lexical tool shortlist. This neither loads arbitrary
# names nor grants execution permission. Modes: off, shadow, enforce.
# Type: string.
# tool_search = "off"
# Suggest a shortlisted skill. The agent still chooses whether to load it.
# Modes: off, shadow, advise.
# Type: string.
# skill_suggestions = "off"
# Skip an unlikely-to-pass goal evaluation within the continuation budget and
# continue work. Only the normal evaluator can certify completion. Modes: off,
# shadow, enforce.
# Type: string.
# goal_prescreen = "off"
# Choose a model job for a new unpinned subagent from its task label, mode,
# profile, and a redacted prompt excerpt. Explicit jobs, profile pins, and
# continuations keep their routing. Modes: off, shadow, enforce.
# Type: string.
# subagent_routing = "off"
[decisions.thresholds]
# Probabilities between 0 and 1. Flags trigger at or above their threshold, and
# goal prescreening skips at or below its own.
# Probability for a permission warning.
# Type: float.
# permission_flag = 0.85
# Probability for escalating an eligible Auto call.
# Type: float.
# auto_flag = 0.85
# Probability that sampled content attempts instruction injection.
# Type: float.
# content_injection = 0.9
# Probability that sampled content addresses the agent.
# Type: float.
# content_addressed_to_agent = 0.9
# Probability that a shell command runs until stopped.
# Type: float.
# shell_endless = 0.9
# Probability mass a duration bound needs before an engine estimate is used.
# Type: float.
# shell_duration = 0.9
# Confidence required for tool search and skill suggestions. Tool-search choice
# probability must also meet it. Subagent routing picks the Fast model when
# this much difficulty probability is at or below routine work, and the Best
# model when this much is on open-ended work.
# Type: float.
# routing_confidence = 0.9
# Skip an evaluator at or below this completion probability, within the
# continuation budget.
# Type: float.
# goal_skip_below = 0.05
# Optional project-write warning threshold. Omission leaves the warning
# disabled. No built-in enforcement threshold.
# Type: float. Default: unset.
# shell_writes = <float>
[automations]
# Limits for automations, which need `automations = true` under [experimental].
# Only the global caudra.toml may hold this table.
# Most turns automations may start in one session per rolling hour, shared by
# all of its automations.
# Type: u32, 1 to 600.
# turns_per_hour = 20
# Stop automation-started turns after this many since the last human input.
# Human input resets the count, and unset means no cap.
# Type: u32, 1 to 10000. Default: unset.
# max_unattended_turns = <u32>
# Let `http()` in automations reach loopback and private network hosts. Without
# it, automations reach public hosts only.
# Type: bool.
# allow_private_network = false
[plugins]
# Bundled tools are on by default. Turn one off with `enabled = false` in its
# own table, such as [plugins.websearch]. Names: bash, batch, edit, glob, grep,
# index, list, memory, question, read, sessions, skill, task, todo_write,
# tool_output, view_image, webfetch, websearch, write.
[plugins.index]
# Refuse to index files larger than this many MiB.
# Type: integer, 1 to 16.
# max_file_size_mb = 2
[plugins.skill]
# Offer the builtin caudra-plugin-dev skill for writing caudra plugins. Needs
# `experimental.lua_plugins`.
# Type: boolean.
# plugin_dev = false
# Offer the builtin caudra-workflow-dev skill for writing and running
# workflows. Needs `experimental.workflows`.
# Type: boolean.
# workflow_dev = true
# Offer the builtin caudra-automation-dev skill for writing automations. Needs
# `experimental.automations`.
# Type: boolean.
# automation_dev = true
# Offer the builtin caudra-docs skill: this build's user documentation, loaded
# one page or section at a time.
# Type: boolean.
# docs = true
[plugins.task]
# Max concurrently running subagents.
# Type: integer, at least 1.
# max_concurrent = 8

permissions.toml holds permission rules for tools and MCP servers. Download this reference as permissions.example.toml.

# Every permissions.toml setting. Each one is commented out, so this file
# changes nothing until you edit it. `caudra config example permissions` prints
# it.
#
# Each commented table header starts an example. To use one, copy the header
# and the lines you need, remove the "#", and put your own names and values in
# place of the examples. Leave the lines without a "#" as they are. A required
# key shows a sample value, and any other key shows its default. A value in
# angle brackets, such as <string>, marks a key with no default to show.
#
# The global file is ~/.config/caudra/permissions.toml, or
# %APPDATA%\caudra\permissions.toml on Windows. A project
# .caudra/permissions.toml adds rules of its own. Deny and ask rules from both
# files apply, and a project shell allow waits until you trust the project
# policy in /permissions.
#
# A file that is unreadable, malformed, or newer than this build fails closed:
# Caudra denies tool calls until you fix it.
#
# Full reference: https://caudra.ai/docs/permissions/#toml-policy
version = 1
# What a call that no rule matches does: `allow`, `deny`, or `prompt`. `allow`
# acts as `prompt` and waits in /permissions for review, and a project cannot
# weaken a global `deny`.
# Type: string.
# default = "prompt"
# [shell]
# Each [TOOL] table holds the rules of one tool, such as [shell] here, and
# ["*"] holds rules for every tool. A shell allow or ask pattern is literal
# words with an optional final ` *`, such as `git status *`, in at most 8 words
# and 256 bytes. One invalid pattern makes the whole file fail closed.
# Scopes the tool may use without asking, such as `["git status *"]`, or `true`
# for every call. Only shell allows grant access, and a project shell allow
# waits until you trust the project policy. Other allows wait in /permissions
# for review.
# Type: bool | string[]. Default: unset.
# allow = <bool | string[]>
# Scopes that always ask, such as `["git push *"]`, or `true` for every call.
# Type: bool | string[]. Default: unset.
# ask = <bool | string[]>
# Scopes the tool may never use, such as `["rm -rf *"]`, or `true` for every
# call. A deny in either file blocks the whole call.
# Type: bool | string[]. Default: unset.
# deny = <bool | string[]>
# What a call of this tool that no rule matches does: `allow`, `deny`, or
# `prompt`. Unset follows the top-level `default`.
# Type: string. Default: unset.
# default = <string>
# [mcp.github]
# Each [mcp.SERVER] table holds the rules for the tools of one MCP server, such
# as [mcp.github] here. Name each tool as the server does, without the
# `github__` prefix.
# Tools to allow without asking: a list of names, one name, `"*"` for every
# tool, or `true` for every tool. MCP allows wait in /permissions for review.
# Type: bool | string | string[]. Default: unset.
# allow = <bool | string | string[]>
# Tools that always ask, in the same forms as `allow`.
# Type: bool | string | string[]. Default: unset.
# ask = <bool | string | string[]>
# Tools the model may never call, in the same forms as `allow`. `false` in any
# of the three adds nothing.
# Type: bool | string | string[]. Default: unset.
# deny = <bool | string | string[]>
# What a call to a tool of this server that no rule matches does: `allow`,
# `deny`, or `prompt`. Unset follows the top-level `default`.
# Type: string. Default: unset.
# default = <string>

mcp.toml holds MCP servers. Download this reference as mcp.example.toml.

# Every mcp.toml setting. Each one is commented out, so this file changes
# nothing until you edit it. `caudra config example mcp` prints it.
#
# Each commented table header starts an example. To use one, copy the header
# and the lines you need, remove the "#", and put your own names and values in
# place of the examples. Leave the lines without a "#" as they are. A required
# key shows a sample value, and any other key shows its default. A value in
# angle brackets, such as <string>, marks a key with no default to show.
#
# The global file is ~/.config/caudra/mcp.toml, or %APPDATA%\caudra\mcp.toml on
# Windows. A project .caudra/mcp.toml adds servers, and a project server
# replaces a global server with the same name. A project server that runs a
# command, or that reaches a private address, waits until you review it in
# /mcp.
#
# When /mcp turns a server on or off, Caudra sets `enabled` in the file that
# defines the server and keeps your comments.
#
# Full reference: https://caudra.ai/docs/mcp/
version = 1
# Defer MCP tools behind `tool_search` only when the servers offer more than
# this many. `0` always defers. A project value replaces the global one.
# Type: integer.
# defer_tools = 10
# [mcp.filesystem]
# Each [mcp.NAME] table is one server, and a stdio server like this one runs
# `command`. NAME is 1 to 64 ASCII letters, digits, and hyphens, and cannot be
# the name of a built-in tool. The tools of the server are named NAME__TOOL.
# Start the server. `/mcp` sets this key when it turns a server on or off.
# Type: bool.
# enabled = true
# Milliseconds to wait for each response from the server.
# Type: integer, 1 to 300000.
# timeout = 30000
# Load every tool of the server up front instead of through `tool_search`.
# Type: bool.
# always_load = false
# Stdio servers: the program and its arguments. It must not be empty. When
# `url` is also set, `command` wins.
# Type: string[]. Required.
# command = ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
# Stdio servers: environment variables for the server process, such as
# `{ GITHUB_TOKEN = "..." }`. Values are stored as plain text.
# Type: table.
# environment = {}
# [mcp.analytics]
# An HTTP server connects to `url` instead of running a command. `enabled`,
# `timeout`, and `always_load` work here too.
# HTTP servers: the server URL. It must start with `http://` or `https://`.
# Type: string. Required.
# url = "https://mcp.example.com/mcp"
# HTTP servers: headers sent with every request, such as
# `{ Authorization = "Bearer ..." }`. Values are stored as plain text.
# Type: table.
# headers = {}
# [mcp.analytics.oauth]
# The static OAuth client of [mcp.analytics], for a server that has no dynamic
# client registration. Without it, Caudra registers a client when the server
# asks for a login.
# The client ID of the app you registered with the server.
# Type: string. Required.
# client_id = "analytics-client"
# The client secret, for a confidential client. It is stored as plain text.
# Type: string. Default: unset.
# client_secret = <string>
# Pin the loopback port of the redirect URI, so you can register the URI in
# advance. Unset tries the default port, then any free port, so the URI can
# change between runs.
# Type: integer, at most 65535. Default: unset.
# callback_port = <integer>
# The path of the redirect URI. It must start with `/`.
# Type: string.
# callback_path = "/mcp/oauth/callback"
# The host name of the redirect URI, such as `localhost` when the server
# registered that form. The listener still binds to 127.0.0.1.
# Type: string.
# callback_hostname = "127.0.0.1"

providers.toml holds model providers and their models. Download this reference as providers.example.toml.

# Every providers.toml setting. Each one is commented out, so this file changes
# nothing until you edit it. `caudra config example providers` prints it.
#
# Each commented table header starts an example. To use one, copy the header
# and the lines you need, remove the "#", and put your own names and values in
# place of the examples. Leave the lines without a "#" as they are. A required
# key shows a sample value, and any other key shows its default. A value in
# angle brackets, such as <string>, marks a key with no default to show.
#
# The global file is ~/.config/caudra/providers.toml, or
# %APPDATA%\caudra\providers.toml on Windows. There is no project file.
#
# `caudra auth login` and `caudra auth logout` rewrite this file and drop its
# comments, so keep a copy of the ones you want.
#
# Full reference: https://caudra.ai/docs/providers/#providers-toml
version = 1
# [my-provider]
# Each top-level table is one provider, named by its slug. A new slug, such as
# my-provider here, adds a custom provider whose models are
# `my-provider/MODEL`. A built-in slug, such as [anthropic], changes that
# provider and ignores `protocol`, `api_key_env`, `discover_models`, `models`,
# `enable_free_models`, except that opencode reads `enable_free_models`. In an
# environment variable name, `<SLUG>` is the slug in capitals with `_` for `-`.
# The name pickers and auth status show.
# Type: string. Default: the built-in name, or the slug.
# display_name = <string>
# The wire format: `openai`, `openai-responses`, `anthropic`, or `google`.
# Type: string. Required.
# protocol = "openai"
# The API origin. Caudra appends the protocol paths.
# Type: string. Default: the plan URL, or the built-in URL. Env:
# <SLUG>_BASE_URL.
# base_url = <string>
# A built-in plan key, which sets the base URL and the default model.
# Type: string. Default: unset.
# plan = <string>
# The environment variable that holds the API key.
# Type: string. Default: `<SLUG>_API_KEY`.
# api_key_env = <string>
# An API key, stored as plain text. Caudra tries the environment variable and
# saved credentials first.
# Type: string. Default: unset.
# api_key = <string>
# The model to use after login when none is saved yet, such as
# `my-provider/my-model`.
# Type: string. Default: unset.
# default_model = <string>
# Also list the models the provider's model endpoint reports.
# Type: bool.
# discover_models = false
# Opencode only. Show the free models of its catalog. Unset counts as `false`.
# Type: bool. Default: unset.
# enable_free_models = <bool>
# Aperture only. Overrides for the upstream providers it routes, keyed by
# upstream id.
# Type: table. Default: unset.
# overrides = <table>
# [my-provider.purposes]
# Which models of my-provider are small and which are flagships. Each key takes
# one prefix or a list.
# Model id prefixes for small, fast models, best first. A prefix covers every
# id that starts with it, and the first one also names the model that fills the
# slot, so it has to be a real id.
# Type: string | string[]. Default: unset.
# fast = <string | string[]>
# Model id prefixes for flagship models, best first. A prefix cannot also be in
# `fast`. A model a job is bound to in the picker wins over both lists.
# Type: string | string[]. Default: unset.
# best = <string | string[]>
# [my-provider.model_defaults]
# Model keys for every model of my-provider, including the ones only discovery
# finds. A [[my-provider.models]] entry wins key by key.
# Tokens of context.
# Type: integer. Default: discovered, or the protocol default.
# context_window = <integer>
# The most tokens one response may hold.
# Type: integer. Default: discovered, or the protocol default.
# max_output_tokens = <integer>
# Send tool examples as a structured field. It is off unless declared, because
# the protocol says nothing about the model behind it.
# Type: bool. Default: false.
# supports_tool_examples = <bool>
# The model accepts extended thinking.
# Type: bool. Default: discovered, or the protocol default.
# supports_thinking = <bool>
# For an API that rejects requests with thinking off. It implies
# `supports_thinking` and raises thinking to minimal effort when it is off,
# compaction included.
# Type: bool. Default: false.
# requires_thinking = <bool>
# The model accepts images. When false, image input and `view_image` are off.
# Type: bool. Default: false.
# supports_vision = <bool>
# `anthropic` and `openai-responses` only. The model reads a PDF that
# `webfetch` attaches inside its tool result. When it is off, `webfetch`
# returns the text of the PDF instead.
# Type: bool. Default: false.
# supports_pdf = <bool>
# `openai-responses` only. The endpoint honours an explicit
# `prompt_cache_breakpoint`, so the system prompt closes with one.
# Type: bool. Default: false.
# supports_cache_breakpoints = <bool>
# The reasoning controls the model takes, such as
# `[{ type = "effort", values = ["low", "high"] }]`. A `type` is `toggle`,
# `effort` with `values`, or `budget_tokens` with an optional `min` and `max`.
# `[]` declares that it takes none, so Caudra sends no reasoning level.
# Type: table[]. Default: unset.
# reasoning_options = <table[]>
# USD per million input tokens.
# Type: float. Default: 0.
# pricing_input = <float>
# USD per million output tokens.
# Type: float. Default: 0.
# pricing_output = <float>
# USD per million tokens written to the prompt cache.
# Type: float. Default: 0.
# pricing_cache_write = <float>
# USD per million tokens read from the prompt cache.
# Type: float. Default: 0.
# pricing_cache_read = <float>
# USD per million input tokens in fast mode.
# Type: float. Default: unset.
# pricing_fast_input = <float>
# USD per million output tokens in fast mode.
# Type: float. Default: unset.
# pricing_fast_output = <float>
# [[my-provider.models]]
# One model my-provider serves, so repeat the table for each model. A key it
# leaves out comes from [my-provider.model_defaults], then from discovery, and
# then from the default shown.
# The model id, which makes the spec `SLUG/ID`.
# Type: string. Required.
# id = "my-model"
# Tokens of context.
# Type: integer. Default: discovered, or the protocol default.
# context_window = <integer>
# The most tokens one response may hold.
# Type: integer. Default: discovered, or the protocol default.
# max_output_tokens = <integer>
# Send tool examples as a structured field. It is off unless declared, because
# the protocol says nothing about the model behind it.
# Type: bool. Default: false.
# supports_tool_examples = <bool>
# The model accepts extended thinking.
# Type: bool. Default: discovered, or the protocol default.
# supports_thinking = <bool>
# For an API that rejects requests with thinking off. It implies
# `supports_thinking` and raises thinking to minimal effort when it is off,
# compaction included.
# Type: bool. Default: false.
# requires_thinking = <bool>
# The model accepts images. When false, image input and `view_image` are off.
# Type: bool. Default: false.
# supports_vision = <bool>
# `anthropic` and `openai-responses` only. The model reads a PDF that
# `webfetch` attaches inside its tool result. When it is off, `webfetch`
# returns the text of the PDF instead.
# Type: bool. Default: false.
# supports_pdf = <bool>
# `openai-responses` only. The endpoint honours an explicit
# `prompt_cache_breakpoint`, so the system prompt closes with one.
# Type: bool. Default: false.
# supports_cache_breakpoints = <bool>
# The reasoning controls the model takes, such as
# `[{ type = "effort", values = ["low", "high"] }]`. A `type` is `toggle`,
# `effort` with `values`, or `budget_tokens` with an optional `min` and `max`.
# `[]` declares that it takes none, so Caudra sends no reasoning level.
# Type: table[]. Default: unset.
# reasoning_options = <table[]>
# USD per million input tokens.
# Type: float. Default: 0.
# pricing_input = <float>
# USD per million output tokens.
# Type: float. Default: 0.
# pricing_output = <float>
# USD per million tokens written to the prompt cache.
# Type: float. Default: 0.
# pricing_cache_write = <float>
# USD per million tokens read from the prompt cache.
# Type: float. Default: 0.
# pricing_cache_read = <float>
# USD per million input tokens in fast mode.
# Type: float. Default: unset.
# pricing_fast_input = <float>
# USD per million output tokens in fast mode.
# Type: float. Default: unset.
# pricing_fast_output = <float>
# [aperture.overrides.llmserver]
# Aperture routes the models of upstream providers as
# `aperture/UPSTREAM/MODEL`. Each [aperture.overrides.UPSTREAM] table overrides
# the models of one upstream, such as llmserver here.
# Tokens of context.
# Type: integer. Default: unset.
# context_window = <integer>
# The most tokens one response may hold.
# Type: integer. Default: unset.
# max_output_tokens = <integer>
# The models accept extended thinking.
# Type: bool. Default: unset.
# supports_thinking = <bool>
# The models accept images.
# Type: bool. Default: unset.
# supports_vision = <bool>
# The native provider an opaque upstream works like, such as `llama-cpp`,
# `google`, or `anthropic`. Caudra warns about a value it does not know and
# ignores it.
# Type: string. Default: unset.
# base = <string>
# The path Caudra sends ahead of each request, which Aperture appends to the
# upstream base URL. Set it to `""` when that URL already has its own path.
# Type: string. Default: `/v1`, `/v1beta` for Gemini routes, none for Anthropic
# and Z.AI.
# path_prefix = <string>
# Overrides for single models, keyed by model id, which win key by key. Quote
# an id that holds a dot, such as `models."qwen-3.6"`.
# Type: table.
# models = {}

workcell.toml holds profiles for direct remote Workcell connections. Caudra reads it only when experimental.remote_workcell is on. Download this reference as workcell.example.toml.

# Every workcell.toml setting. Each one is commented out, so this file changes
# nothing until you edit it. `caudra config example workcell` prints it.
#
# Each commented table header starts an example. To use one, copy the header
# and the lines you need, remove the "#", and put your own names and values in
# place of the examples. Leave the lines without a "#" as they are. A required
# key shows a sample value, and any other key shows its default. A value in
# angle brackets, such as <string>, marks a key with no default to show.
#
# The global file is ~/.config/caudra/workcell.toml, or
# %APPDATA%\caudra\workcell.toml on Windows. There is no project file. It has
# to be a regular file, not a symlink, that you own and that group and others
# cannot write, so `chmod 600` suits it. It holds at most 256 KiB.
#
# Caudra reads this file only while `remote_workcell` is true under
# [experimental] in the global caudra.toml.
#
# Full reference: https://caudra.ai/docs/remote-workspaces/#configure-a-profile
version = 1
[workcell.profiles]
# Keep this header, because the file needs it even without profiles.
# [workcell.profiles.dev]
# Each [workcell.profiles.NAME] table is one profile, which
# `caudra --workcell-profile NAME` connects to. NAME is 1 to 64 ASCII letters,
# digits, ".", "-", and "_", and starts with a letter or digit. `endpoint` is
# at most 2048 bytes, and each expected ID at most 512.
# The Workcell endpoint: HTTPS with any host, or HTTP on a numeric loopback
# address such as `127.0.0.1`. Caudra refuses `localhost`, user information, a
# query, and a fragment.
# Type: string. Required.
# endpoint = "https://workcell.example/mcp"
# The working directory, relative to the Workcell root, where `.` is the root
# itself. It cannot start with `/` or hold `..`.
# Type: string. Required.
# cwd = "projects/app"
# The saved bearer credential, as `credential:NAME`, which
# `caudra auth workcell set NAME` creates. A loopback profile needs one too.
# Type: string. Required.
# credential_ref = "credential:dev"
# An identity check: the connection fails unless the server reports this ID.
# Type: string. Default: unset.
# expected_server_id = <string>
# An identity check: the connection fails unless the workspace reports this ID.
# Type: string. Default: unset.
# expected_workspace_id = <string>

sandboxes.toml holds managed sandbox providers, networks, transfers, and profiles. Caudra reads it only when experimental.sandboxes is on. Download this reference as sandboxes.example.toml.

# Every sandboxes.toml setting. Each one is commented out, so this file changes
# nothing until you edit it. `caudra config example sandboxes` prints it.
#
# Each commented table header starts an example. To use one, copy the header
# and the lines you need, remove the "#", and put your own names and values in
# place of the examples. Leave the lines without a "#" as they are. A required
# key shows a sample value, and any other key shows its default. A value in
# angle brackets, such as <string>, marks a key with no default to show.
#
# The global file is ~/.config/caudra/sandboxes.toml, or
# %APPDATA%\caudra\sandboxes.toml on Windows. There is no project file. It has
# to be a regular file with one link, owned by you, that group and others have
# no access to, so `chmod 600` suits it. The directory that holds it has to be
# yours, and each directory above that has to be yours or root's. None of them
# may let group or others write, except a sticky directory that root owns, such
# as /tmp. No part of the path may be a symlink.
#
# The file holds at most 256 records and 1024 KiB, and one record at most 64
# KiB. A network lists at most 256 domains and CIDRs together, and a transfer
# at most 128 globs.
#
# `/sandbox` saves this file and keeps your comments. Saving creates no VM.
#
# Caudra reads this file only while `sandboxes` is true under [experimental] in
# the global caudra.toml.
#
# Full reference: https://caudra.ai/docs/sandboxes/#configuration-schema
version = 1
[sandbox]
# Keep this header, because the file needs it even without records.
# [sandbox.providers.local]
# Each [sandbox.providers.NAME] table is one sandbox provider. Every kind of
# record has names of its own: 1 to 64 ASCII letters, digits, ".", "-", and
# "_", starting with a letter or digit.
# The provider type. `e2b-libvirt` is the only one.
# Type: string. Required.
# kind = "e2b-libvirt"
# The origin of the lifecycle API: HTTPS, or HTTP on a numeric loopback
# address, with no path, credentials, query, or fragment. Caudra refuses
# `http://localhost`.
# Type: string. Required.
# api_endpoint = "http://127.0.0.1:3000"
# The origin of the sandbox proxy, with the same rules as `api_endpoint`.
# Type: string. Required.
# proxy_endpoint = "http://127.0.0.1:49983"
# The lifecycle API key, as `sandbox-api:NAME`, not a Workcell
# `credential:NAME`. `caudra auth sandbox generate NAME` or
# `caudra auth sandbox set NAME` saves it.
# Type: string. Required.
# credential_ref = "sandbox-api:local"
# [sandbox.networks.default]
# Each [sandbox.networks.NAME] table is one network policy, which profiles can
# share.
# `required` enforces the lists below, so empty lists deny all traffic. `off`
# enforces nothing, and then both lists must be empty and `tls_mode` must stay
# `sni-only`.
# Type: string. Required.
# enforcement = "required"
# `sni-only` or `mitm`.
# Type: string.
# tls_mode = "sni-only"
# Domains the sandbox may reach, such as `github.com` or
# `*.githubusercontent.com`.
# Type: string[].
# domains = []
# Address ranges the sandbox may reach, such as `10.0.0.0/8`.
# Type: string[].
# cidrs = []
# [sandbox.transfers.default]
# Each [sandbox.transfers.NAME] table is one file transfer policy, which
# profiles can share. Protected paths stay protected even with `exclude = []`.
# Leave out the files that `.gitignore` ignores.
# Type: bool.
# respect_gitignore = true
# `ask` offers to copy the project into a new sandbox, and `none` skips the
# offer. Later transfers work either way.
# Type: string.
# initial_seed = "ask"
# Only `false` works, because Caudra never deletes files on its own.
# Type: bool.
# delete_extraneous = false
# Relative globs of paths never to copy. A list you set replaces the one shown.
# A glob cannot start with `/` or `!`, or hold `.`, `..`, `\`, or `:`.
# Type: string[].
# exclude = ["**/.git/**", "**/.env*", "**/target/**", "**/node_modules/**", "**/.venv/**", "**/.ssh/**", "**/.aws/**", "**/.caudra/**", "**/*.pem", "**/*.key"]
# [sandbox.profiles.dev]
# Each [sandbox.profiles.NAME] table is one launch profile, which
# `caudra --sandbox NAME` starts. The file is refused while a record the
# profile names is missing. The provider checks the template, the resources,
# and the lease only at launch.
# The name of a [sandbox.providers.NAME] record.
# Type: string. Required.
# provider = "local"
# A template ID from the provider catalog. Each launch uses the revision the
# catalog lists at that time.
# Type: string. Required.
# template = "caudra-rust"
# Virtual CPUs.
# Type: integer, at least 1. Required.
# cpus = 4
# Memory in MiB.
# Type: integer, at least 1. Required.
# memory_mib = 4096
# Virtual disk size in GiB. It reserves no host space.
# Type: integer, at least 1. Required.
# disk_gib = 20
# The working directory, relative to the Workcell root, where `.` is the root
# itself.
# Type: string. Required.
# cwd = "."
# The name of a [sandbox.networks.NAME] record.
# Type: string. Required.
# network = "default"
# The name of a [sandbox.transfers.NAME] record.
# Type: string. Required.
# transfer = "default"
# Keep the disk when the sandbox pauses or its lease ends. Only a persistent
# sandbox can pause.
# Type: bool.
# persistent = true
# Seconds the sandbox may run before its lease ends. `0` never ends, which
# needs a provider without a lease cap.
# Type: integer. Required.
# running_ttl_seconds = 3600
# What happens to the sandbox when Caudra exits. `detach` is the only value.
# Type: string.
# on_exit = "detach"

Website privacy and analytics