--- summary: "Multi-agent routing: isolated agents, provider accounts, and bindings" title: Multi-Agent Routing read_when: "You want multiple isolated agents (workspaces + auth) in one gateway process." status: active --- # Multi-Agent Routing Goal: multiple *isolated* agents (separate workspace + `agentDir` + sessions), plus multiple provider accounts (e.g. two WhatsApps) in one running Gateway. Inbound is routed to an agent via bindings. ## What is “one agent”? An **agent** is a fully scoped brain with its own: - **Workspace** (files, AGENTS.md/SOUL.md/USER.md, local notes, persona rules). - **State directory** (`agentDir`) for auth profiles, model registry, and per-agent config. - **Session store** (chat history + routing state) under `~/.clawdbot/agents//sessions`. Skills are per-agent via each workspace’s `skills/` folder, with shared skills available from `~/.clawdbot/skills`. See [Skills: per-agent vs shared](/tools/skills#per-agent-vs-shared-skills). The Gateway can host **one agent** (default) or **many agents** side-by-side. **Workspace note:** each agent’s workspace is the **default cwd**, not a hard sandbox. Relative paths resolve inside the workspace, but absolute paths can reach other host locations unless sandboxing is enabled. See [Sandboxing](/gateway/sandboxing). ## Paths (quick map) - Config: `~/.clawdbot/clawdbot.json` (or `CLAWDBOT_CONFIG_PATH`) - State dir: `~/.clawdbot` (or `CLAWDBOT_STATE_DIR`) - Workspace: `~/clawd` (or `~/clawd-`) - Agent dir: `~/.clawdbot/agents//agent` (or `agents.list[].agentDir`) - Sessions: `~/.clawdbot/agents//sessions` ### Single-agent mode (default) If you do nothing, Clawdbot runs a single agent: - `agentId` defaults to **`main`**. - Sessions are keyed as `agent:main:`. - Workspace defaults to `~/clawd` (or `~/clawd-` when `CLAWDBOT_PROFILE` is set). - State defaults to `~/.clawdbot/agents/main/agent`. ## Agent helper Use the agent wizard to add a new isolated agent: ```bash clawdbot agents add work ``` Then add `bindings` (or let the wizard do it) to route inbound messages. Verify with: ```bash clawdbot agents list --bindings ``` ## Multiple agents = multiple people, multiple personalities With **multiple agents**, each `agentId` becomes a **fully isolated persona**: - **Different phone numbers/accounts** (per provider `accountId`). - **Different personalities** (per-agent workspace files like `AGENTS.md` and `SOUL.md`). - **Separate auth + sessions** (no cross-talk unless explicitly enabled). This lets **multiple people** share one Gateway server while keeping their AI “brains” and data isolated. ## Routing rules (how messages pick an agent) Bindings are **deterministic** and **most-specific wins**: 1. `peer` match (exact DM/group/channel id) 2. `guildId` (Discord) 3. `teamId` (Slack) 4. `accountId` match for a provider 5. provider-level match (`accountId: "*"`) 6. fallback to default agent (`agents.list[].default`, else first list entry, default: `main`) ## Multiple accounts / phone numbers Providers that support **multiple accounts** (e.g. WhatsApp) use `accountId` to identify each login. Each `accountId` can be routed to a different agent, so one server can host multiple phone numbers without mixing sessions. ## Concepts - `agentId`: one “brain” (workspace, per-agent auth, per-agent session store). - `accountId`: one provider account instance (e.g. WhatsApp account `"personal"` vs `"biz"`). - `binding`: routes inbound messages to an `agentId` by `(provider, accountId, peer)` and optionally guild/team ids. - Direct chats collapse to `agent::` (per-agent “main”; `session.mainKey`). ## Example: two WhatsApps → two agents `~/.clawdbot/clawdbot.json` (JSON5): ```js { agents: { list: [ { id: "home", default: true, name: "Home", workspace: "~/clawd-home", agentDir: "~/.clawdbot/agents/home/agent", }, { id: "work", name: "Work", workspace: "~/clawd-work", agentDir: "~/.clawdbot/agents/work/agent", }, ], }, // Deterministic routing: first match wins (most-specific first). bindings: [ { agentId: "home", match: { provider: "whatsapp", accountId: "personal" } }, { agentId: "work", match: { provider: "whatsapp", accountId: "biz" } }, // Optional per-peer override (example: send a specific group to work agent). { agentId: "work", match: { provider: "whatsapp", accountId: "personal", peer: { kind: "group", id: "1203630...@g.us" }, }, }, ], // Off by default: agent-to-agent messaging must be explicitly enabled + allowlisted. tools: { agentToAgent: { enabled: false, allow: ["home", "work"], }, }, whatsapp: { accounts: { personal: { // Optional override. Default: ~/.clawdbot/credentials/whatsapp/personal // authDir: "~/.clawdbot/credentials/whatsapp/personal", }, biz: { // Optional override. Default: ~/.clawdbot/credentials/whatsapp/biz // authDir: "~/.clawdbot/credentials/whatsapp/biz", }, }, }, } ``` ## Per-Agent Sandbox and Tool Configuration Starting with v2026.1.6, each agent can have its own sandbox and tool restrictions: ```js { agents: { list: [ { id: "personal", workspace: "~/clawd-personal", sandbox: { mode: "off", // No sandbox for personal agent }, // No tool restrictions - all tools available }, { id: "family", workspace: "~/clawd-family", sandbox: { mode: "all", // Always sandboxed scope: "agent", // One container per agent docker: { // Optional one-time setup after container creation setupCommand: "apt-get update && apt-get install -y git curl", }, }, tools: { allow: ["read"], // Only read tool deny: ["bash", "write", "edit"], // Deny others }, }, ], }, } ``` **Benefits:** - **Security isolation**: Restrict tools for untrusted agents - **Resource control**: Sandbox specific agents while keeping others on host - **Flexible policies**: Different permissions per agent Note: `tools.elevated` is **global** and sender-based; it is not configurable per agent. If you need per-agent boundaries, use `agents.list[].tools` to deny `bash`. For group targeting, use `agents.list[].groupChat.mentionPatterns` so @mentions map cleanly to the intended agent. See [Multi-Agent Sandbox & Tools](/multi-agent-sandbox-tools) for detailed examples.