1B(a): document claude_cli.door — subscription agent acts through the §15 door
ci / gates (push) Has been cancelled
ci / rust (push) Has been cancelled
ci / sandbox-k8s (push) Has been cancelled
ci / frontend (push) Has been cancelled
ci / e2e (push) Has been cancelled

Adds the claude_cli.door provider pattern (mcp_config + allowed/disallowed
tools) so a subscription claude_cli agent reaches the Clawmates door via Claude
Code's own MCP client, with native tools locked out (door = only actuator).

Validated live on gw-04: subdoor agent (claude_cli, subscription) → door →
outbox + agent|door.executed audit, cost 0.0; shell command denied.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-16 19:24:24 -07:00
co-authored by Claude Opus 4.8
parent ec5d3b3149
commit ea5687565a
@@ -19,6 +19,29 @@ quickstart_completed = true
[providers.models.claude_cli.default] [providers.models.claude_cli.default]
model = "haiku" model = "haiku"
# claude_cli ACTING through the §15 door (subscription agent that ACTS, not just
# reasons). claude -p has no tool API ZeroClaw can drive, so instead we let
# Claude Code's OWN MCP client reach the door: `--mcp-config` points at a JSON
# file describing the door as an http MCP server; `tools` (--allowedTools)
# auto-approves the door tool; `disallowed_tools` (--disallowedTools) locks out
# claude's native tools so the gated door is the ONLY actuator.
# Create /zeroclaw-data/clawmates-mcp.json (NOT committed; token injected):
# { "mcpServers": { "clawmates": { "type": "http",
# "url": "http://clawmates_server_1:8080/mcp",
# "headers": { "Authorization": "Bearer <per-workspace door token>" } } } }
# NOTE: model MUST be set via env (ZEROCLAW_providers__models__claude_cli__door__model)
# — the TOML sub-table parses empty (resolve_default_model gotcha).
[providers.models.claude_cli.door]
tools = ["mcp__clawmates__email_send"]
disallowed_tools = ["Bash", "BashOutput", "KillShell", "Write", "Edit", "NotebookEdit", "Read", "Glob", "Grep", "WebFetch", "WebSearch", "Task"]
mcp_config = "/zeroclaw-data/clawmates-mcp.json"
# An agent that ACTS through the door (uncomment; it needs NO ZeroClaw
# mcp_bundles — the door comes via claude's own MCP client):
# [agents.subdoor]
# model_provider = "claude_cli.door"
# risk_profile = "toolfree"
# Tool-free profile — agents can only reason + call the MCP door (tools inject # Tool-free profile — agents can only reason + call the MCP door (tools inject
# AFTER this allowlist filter). `level = "full"` removes ZeroClaw's OWN approval # AFTER this allowlist filter). `level = "full"` removes ZeroClaw's OWN approval
# prompts so the agent is autonomous; governance happens at the Clawmates door # prompts so the agent is autonomous; governance happens at the Clawmates door