Skip to content

ACP Configuration

The [acp] section controls how Crucible hosts external agents over the Agent Client Protocol — which agent it reaches for by default, how it discovers them, and what each named profile is allowed to do.

Add it to ~/.config/crucible/config.toml (or whatever -C / $CRUCIBLE_CONFIG points at). Every field has a default, so [acp] is optional.

[acp]

FieldTypeDefaultDescription
default_agentstring(unset)Profile to use when --acp is omitted. Unset means auto-discover the first available agent.
streaming_timeout_minutesinteger15Time allowed for one complete response
[acp]
default_agent = "claude"
streaming_timeout_minutes = 15

Earlier versions also parsed enable_discovery, session_timeout_minutes, max_message_size_mb and lazy_agent_selection. No code read them, so they are removed. A config file that still contains them loads without an error; the values are ignored.

streaming_timeout_minutes defaults to 15 rather than something tighter because reasoning models routinely go quiet for minutes at a time mid-turn.

[acp.agents.<name>] — agent profiles

A profile either extends a built-in (opencode, claude, gemini, codex, cursor) or defines its own command. The profile name is what you pass to cru chat -a <name>.

FieldTypeDefaultDescription
extendsstring(unset)Built-in profile to inherit command and args from
commandstring(from extends)Executable to spawn
argsarray of string(from extends)Arguments passed to the command
envtable{}Environment variables for the agent process
descriptionstring(unset)Human-readable label
delegationtable(unset)See the delegation sub-table below
permissionstable(unset)Per-agent override of the global [permissions]

A profile with neither command nor a resolvable extends is rejected at spawn time — Crucible has nothing to run.

# Point Claude Code at a local proxy
[acp.agents.claude-proxy]
extends = "claude"
description = "Claude Code through a local gateway"
env = { ANTHROPIC_BASE_URL = "http://localhost:4000" }
# A completely custom agent binary
[acp.agents.my-agent]
command = "/usr/local/bin/my-agent"
args = ["--mode", "acp"]
env = { MY_AGENT_ENDPOINT = "http://localhost:8080" }

env values are passed to the agent process verbatim. Keep secrets out of this table — the agent inherits Crucible’s environment, so exporting the variable in your shell is both simpler and safer.

[acp.agents.<name>.delegation]

Controls whether this agent may hand work to another agent via the delegate_session tool. Absent means no delegation configuration, which leaves the tool unadvertised.

FieldTypeDefaultDescription
enabledboolfalseWhether this agent may delegate at all
max_depthinteger1Deepest delegation chain permitted. 0 disables delegation; 1 allows delegation but no nesting; 2 lets a delegated child delegate once more
allowed_targetsarray of string(unset — any target)Restrict which agents may be delegated to
result_max_bytesinteger51200Truncation limit for a delegated result
max_concurrent_delegationsinteger3Concurrent children one session may spawn
timeout_secsinteger300Seconds a delegated child may run before cancellation, blocking or background
[acp.agents.orchestrator]
extends = "claude"
[acp.agents.orchestrator.delegation]
enabled = true
max_depth = 2
allowed_targets = ["researcher", "reviewer"]
result_max_bytes = 102400
max_concurrent_delegations = 5
timeout_secs = 600

Depth is derived from the child session’s parent chain at every level, so a chain cannot be extended by handing off through an intermediary.

[acp.agents.<name>.permissions]

Same shape as the global [permissions] section. When set, it replaces the global config for sessions using this profile — use it to give different agents different trust levels.

FieldTypeDefaultDescription
defaultstring"ask"Decision when no rule matches: allow, deny, or ask
allowarray of string[]Patterns that auto-approve
denyarray of string[]Patterns that refuse
askarray of string[]Patterns that always prompt
[acp.agents.claude.permissions]
default = "ask"
deny = ["bash:rm *", "write_file:*"]
[acp.agents.opencode.permissions]
default = "allow"
deny = ["bash:rm -rf *"]

See permissions for pattern syntax and Permission Precedence for which layer wins when they disagree.

Full example

[acp]
default_agent = "claude-proxy"
streaming_timeout_minutes = 30
[acp.agents.claude-proxy]
extends = "claude"
description = "Claude Code through a local gateway"
env = { ANTHROPIC_BASE_URL = "http://localhost:4000" }
[acp.agents.claude-proxy.delegation]
enabled = true
max_depth = 1
[acp.agents.claude-proxy.permissions]
default = "ask"
deny = ["bash:rm *"]

See Also