Agent coordination
Multi-agent sandbox and tools
Each agent in a multi-agent setup can override the global sandbox and tool policy. This page covers per-agent configuration, precedence rules, and examples.
Backends and modes — full sandbox reference.
Debug "why is this blocked?"
Elevated exec for trusted senders.
Configuration examples
Example 1: Personal + restricted family agent
{ "agents": { "entries": { "main": { "default": true, "name": "Personal Assistant", "workspace": "~/.openclaw/workspace", "sandbox": { "mode": "off" } }, "family": { "name": "Family Bot", "workspace": "~/.openclaw/workspace-family", "sandbox": { "mode": "all", "scope": "agent" }, "tools": { "allow": ["read", "message"], "deny": ["exec", "write", "edit", "apply_patch", "process", "browser"], "message": { "crossContext": { "allowWithinProvider": false, "allowAcrossProviders": false } } } } } }, "bindings": [ { "agentId": "family", "match": { "channel": "whatsapp", "accountId": "*", "peer": { "kind": "group", "id": "[email protected]" } } } ]}Result:
mainagent: runs on host, full tool access.familyagent: runs in the configured container sandbox backend (one container per agent), onlyreadand current-conversation message sends.
Example 2b: Global coding profile + messaging-only agent
{ "tools": { "profile": "coding" }, "agents": { "entries": { "main": { "default": true }, "support": { "tools": { "profile": "messaging", "allow": ["slack"] } } } }}Result:
- default agents get coding tools.
supportagent is messaging-only (+ Slack tool).
Example 3: Different sandbox modes per agent
{ "agents": { "defaults": { "sandbox": { "mode": "non-main", "scope": "session" } }, "entries": { "main": { "default": true, "workspace": "~/.openclaw/workspace", "sandbox": { "mode": "off" } }, "public": { "workspace": "~/.openclaw/workspace-public", "sandbox": { "mode": "all", "scope": "agent" }, "tools": { "allow": ["read"], "deny": ["exec", "write", "edit", "apply_patch"] } } } }}Configuration precedence
When both global (agents.defaults.*) and agent-specific (agents.entries.*.*) configs exist:
Sandbox config
Agent-specific settings override global:
agents.entries.*.sandbox.mode > agents.defaults.sandbox.modeagents.entries.*.sandbox.scope > agents.defaults.sandbox.scopeagents.entries.*.sandbox.workspaceRoot > agents.defaults.sandbox.workspaceRootagents.entries.*.sandbox.workspaceAccess > agents.defaults.sandbox.workspaceAccessagents.entries.*.sandbox.docker.* > agents.defaults.sandbox.docker.*agents.entries.*.sandbox.browser.* > agents.defaults.sandbox.browser.*agents.entries.*.sandbox.prune.* > agents.defaults.sandbox.prune.*Tool restrictions
The filtering order is:
Tool profile
tools.profile or agents.entries.*.tools.profile.
Provider tool profile
tools.byProvider[provider].profile or agents.entries.*.tools.byProvider[provider].profile.
Global tool policy
tools.allow / tools.deny.
Provider tool policy
tools.byProvider[provider].allow/deny.
Agent-specific tool policy
agents.entries.*.tools.allow/deny.
Agent provider policy
agents.entries.*.tools.byProvider[provider].allow/deny.
Sandbox tool policy
tools.sandbox.tools or agents.entries.*.tools.sandbox.tools.
Subagent tool policy
tools.subagents.tools, if applicable.
Precedence rules
- Each level can further restrict tools, but cannot grant back denied tools from earlier levels.
- If
agents.entries.*.tools.sandbox.toolsis set, it replacestools.sandbox.toolsfor that agent. - If
agents.entries.*.tools.profileis set, it overridestools.profilefor that agent. - Provider tool keys accept either
provider(e.g.anthropic) orprovider/model(e.g.openai/gpt-5.4).
Empty allowlist behavior
If any explicit allowlist in that chain leaves the run with no callable tools, OpenClaw stops before submitting the prompt to the model. This is intentional: an agent configured with a missing tool such as agents.entries.*.tools.allow: ["query_db"] should fail loudly until the plugin that registers query_db is enabled, not continue as a text-only agent.
Tool policies support group:* shorthands that expand to multiple tools. See Tool groups for the full list.
Configured MCP tools use the same policy surface. Their canonical names are
<safe-server>__<safe-tool>; globs can target a server namespace. For example:
{ agents: { entries: { research: { tools: { allow: ["docs__read_docs"], deny: ["docs__delete_*"], }, }, }, },}Every restrictive layer intersects with the earlier layers, and deny always wins. OpenClaw projects the resulting raw tool set into native Claude, Codex, and Gemini MCP filters before their first model turn. Backend-native names and settings are implementation details, not a second operator policy surface. An MCP server with no allowed tool is omitted. A restrictive catalog failure also omits that server and records a diagnostic instead of failing open.
Per-agent elevated overrides (agents.entries.*.tools.elevated) can further restrict elevated exec for specific agents. See Elevated mode for details.
Migration from single agent
Before (single agent)
{ "agents": { "defaults": { "workspace": "~/.openclaw/workspace", "sandbox": { "mode": "non-main" } } }, "tools": { "sandbox": { "tools": { "allow": ["read", "write", "apply_patch", "exec"], "deny": [] } } }}After (multi-agent)
{ "agents": { "entries": { "main": { "default": true, "workspace": "~/.openclaw/workspace", "sandbox": { "mode": "off" } } } }}Tool restriction examples
Read-only agent
{ "tools": { "allow": ["read"], "deny": ["exec", "write", "edit", "apply_patch", "process"] }}Shell execution with filesystem tools disabled
{ "tools": { "allow": ["read", "exec", "process"], "deny": ["write", "edit", "apply_patch", "browser", "gateway"] }}Communication-only
This complete configuration applies the tool allow/deny policy to the communication agent and sets session visibility for every agent on the Gateway:
{ "tools": { "sessions": { "visibility": "tree" } }, "agents": { "entries": { "communication": { "tools": { "allow": ["sessions_list", "sessions_send", "sessions_history", "session_status"], "deny": ["exec", "write", "edit", "apply_patch", "read", "browser"] } } } }}tools.sessions.visibility is Gateway-wide and cannot be set per agent. Session tools default to all with agent-to-agent messaging on. With tree, callers can access their current session and sessions they spawn; the canonical main session can still access every session belonging to its agent. Incognito restrictions and the sandbox spawned-session clamp still apply. See tools.sessions and tools.agentToAgent.
sessions_history in this profile still returns a bounded, sanitized recall view rather than a raw transcript dump. Assistant recall strips thinking tags, <relevant-memories> scaffolding, plain-text tool-call XML payloads (including <tool_call>...</tool_call>, <function_call>...</function_call>, <tool_calls>...</tool_calls>, <function_calls>...</function_calls>, and truncated tool-call blocks), downgraded tool-call scaffolding, leaked ASCII/full-width model control tokens, and malformed MiniMax tool-call XML before redaction/truncation.
Common pitfall: "non-main"
Testing
After configuring multi-agent sandbox and tools:
Check agent resolution
openclaw agents list --bindingsVerify sandbox containers
docker ps --filter "name=openclaw-sbx-"Test tool restrictions
- Send a message requiring restricted tools.
- Verify the agent cannot use denied tools.
Monitor logs
openclaw logs --follow | grep -E "routing|sandbox|tools"Troubleshooting
Agent not sandboxed despite `mode: 'all'`
- Check if there's a global
agents.defaults.sandbox.modethat overrides it. - Agent-specific config takes precedence, so set
agents.entries.*.sandbox.mode: "all".
Tools still available despite deny list
- Check the full filtering order: profile → provider profile → global policy → provider policy → agent policy → agent provider policy → sandbox → subagent.
- Each level can only further restrict, not grant back.
- See Sandbox vs tool policy vs elevated for step-by-step debugging.
- For MCP tools, use the provider-safe name shown by OpenClaw, such as
docs__read_docsordocs__*; do not use a backend's raw config field name.
Container not isolated per agent
- Default
scopeis"agent"(one container per agent id). - Set
scope: "session"for one container per session, orscope: "shared"to reuse one container across agents.
Related
- Elevated mode
- Multi-agent routing
- Sandbox configuration
- Sandbox vs tool policy vs elevated — debugging "why is this blocked?"
- Sandboxing — full sandbox reference (modes, scopes, backends, images)
- Session management
- OpenShell — a managed sandbox backend a per-agent sandbox can delegate to
- ACP agents — a separate boundary: OpenClaw sandbox policy does not wrap ACP harness execution
- Sub-agents — the spawned sessions these limits clamp