
Here’s the bottom line up front. Running several agents on different models at once from a single OpenClaw gateway is not a few config lines and done. We covered this across two separate posts, and re-reading both for this consolidation, we found a lot of overlap — and information that flatly disagreed, like the gateway port number. This piece merges the two, fixes what was wrong, and checks whether the “next goal” we set five months ago actually happened.
🔍 Overview — Why Run Multiple Agents at All
If you want to use AI like a personal assistant, you need a system that runs around the clock and replies the moment you message it. Not one agent — several, each on a different model, working independently in its own channel. This piece documents the process of running Siwol (Gemini-based) and Red (Grok-based) simultaneously through a single OpenClaw gateway: the config struggles, the routing principles, and the duplicate-response troubleshooting, all of it.
🏗️ Architecture — One Gateway, Two Brains

The core principle is simple. Siwol runs Gemini only, Red runs Grok only. Fallbacks are restricted to the same provider so the models never mix. Each agent uses a separate Discord bot account, with channel access physically separated.
19876. Re-verifying for this consolidation, we found nothing to support that number, and it doesn’t match the current official docs (docs.openclaw.ai/cli/gateway). The actual default port is 18789, corrected in the diagram above.⚙️ Dissecting the openclaw.json Core Config
The core of OpenClaw multi-agent configuration lives in three sections of ~/.openclaw/openclaw.json.
1. agents — Agent Definitions
Declares each agent’s ID, name, model, and workspace.
"agents": {
"list": [
{
"id": "main",
"name": "Siwol",
"workspace": "~/.openclaw/workspace",
"model": {
"primary": "vertex-ai/gemini-3-flash-preview",
"fallbacks": ["vertex-ai/gemini-3-pro-preview"]
}
},
{
"id": "red",
"name": "Red",
"workspace": "~/.openclaw/workspace-red",
"model": {
"primary": "xai/grok-4-1-fast-reasoning",
"fallbacks": ["xai/grok-4-0709"]
}
}
]
}
2. bindings — Routing Rules
Determines which agent responds when a given Discord bot account receives a message. This is the core mechanism of multi-agent routing.
"bindings": [
{ "agentId": "main", "match": { "channel": "discord", "accountId": "siwol" } },
{ "agentId": "red", "match": { "channel": "discord", "accountId": "red" } }
]
bindings must sit at the JSON top level. Put it inside agents and you get an Unrecognized key: bindings error.3. channels.discord — Channel Access Isolation
Physically separates which channels each bot account can access. The key is placing guilds inside each account, not as shared config.
"accounts": {
"siwol": {
"guilds": { "serverID": { "channels": { "siwolChannelID": { "allow": true } } } }
},
"red": {
"guilds": { "serverID": { "channels": { "redChannelID": { "allow": true } } } }
}
}
With this in place, the routing flow looks like this.
Discord message received
↓
Which bot account received it?
├── siwol bot → bindings match accountId="siwol"
│ → agentId="main" (Siwol, Gemini)
└── red bot → bindings match accountId="red"
→ agentId="red" (Red, Grok)
Matching by accountId keeps things cleanly separated. DMs are also automatically split by bot account — message Siwol and Siwol answers, message Red and Red answers.
🧠 Workspace — The Agent’s Soul
Each agent’s personality, memory, and behavioral rules are defined by its workspace files. OpenClaw reads these at the start of every session to build the agent’s context.
~/.openclaw/workspace/ (Siwol)
├── SOUL.md ← innocent, warm personality, polite speech
├── IDENTITY.md ← name, emoji (🌸)
├── USER.md ← owner info
└── AGENTS.md ← behavioral rules
~/.openclaw/workspace-red/ (Red)
├── SOUL.md ← bold, spicy personality, casual speech
├── IDENTITY.md ← name, emoji (🔥)
├── USER.md ← owner info + boundary settings
├── AGENTS.md ← behavioral rules
└── memory/ ← dated memory records
SOUL.md is what fundamentally decides the agent’s personality. It’s why the same prompt gets completely different tones back. Separating workspaces this way also means what you tell Siwol never leaks over to Red.
🔧 Troubleshooting — What Actually Broke
1. Duplicate responses. Right after setup, Siwol started sending the same reply 3-4 times in a row. Two causes.
Cause A — no debounce configured. OpenClaw has a debounce feature that bundles consecutive incoming messages, but the default config doesn’t set it.
"messages": {
"inbound": {
"debounceMs": 2000
}
}
Cause B — no queue.mode configured. Set queue mode to collect so consecutive messages are gathered and processed together.
"queue": {
"mode": "collect"
}
2. Four config errors. Beyond the duplicate-response issue above, here’s what we actually hit, by the literal error message.
| Error | Cause | Fix |
|---|---|---|
Unrecognized key: bindings | bindings placed inside agents | Move to the JSON top level |
expected record, received array | accounts written as an array ([]) | Change to an object ({}) |
| Siwol answering in Red’s channel | guilds placed in shared config | Move guilds inside each account |
| Siwol answering in Red’s channel pretending to be Red | Incomplete channel separation, workspace bleed | accountId-based routing + fully isolated per-account guilds |
guilds shared, and the bots end up answering in each other’s channels like ghosts.3. Gateway port conflict & infinite restart. systemd auto-starts the OpenClaw service on WSL boot, and if the port was already occupied, it fell into an infinite restart loop. Fixed with a service dependency setting plus a port-availability check.
4. Port forwarding (NAT mode). WSL2 runs in NAT mode, so there’s no direct external access. A PowerShell script set up automatic forwarding from the Windows host to the WSL port.
🔌 MCP Tool Integration — Giving the AI Hands and Feet
For an agent to be genuinely useful, it needs to use tools, not just talk. Connecting MCP servers through OpenClaw’s mcporter lets Siwol and Red interact directly with external services.
🟢 Knowledge RAG MCP — vector search across all of Confluence+Jira (LanceDB-based)
🔴 Google Calendar, WordPress — check schedules, post to the blog
Knowledge RAG in particular chunks, embeds, and indexes all of Confluence and Jira into a vector DB, so a natural-language question like “how did we fix that port conflict again?” surfaces past records instantly.
📊 Operations — Two Weeks In (as of February 2026)
| Item | Siwol (Gemini) | Red (Grok) |
|---|---|---|
| Model | gemini-3-flash-preview | grok-4-1-fast-reasoning |
| Response speed | Fast (Flash trait) | Moderate (reasoning) |
| Personality | Innocent and warm | Bold and spicy |
| Main use | Daily chat, briefings | Code, search, assistance |
Resource overhead on WSL was near zero. API-based, so the two agents combined used 100-200MB RAM, with CPU essentially at 0% while idle.
🔄 So Where Does This Stand Now?
Everything above is a February 2026 record. Five and a half months later, we checked it against actual GitHub and the official docs, one item at a time.

The next goal — what actually happened. The original post set automatic agent-to-agent handoff as its next goal: Siwol deciding a task needs code execution and automatically passing it to Red. Checking this, that vision did not ship as envisioned. Per the official docs (docs.openclaw.ai/concepts/delegate-architecture), delegation is still based on pre-defined static bindings, not a dynamic judgment call based on task content. Direct agent-to-agent messaging does exist (docs.openclaw.ai/concepts/multi-agent), but it’s off by default and requires explicit activation plus an allowlist entry. Tools like sessions_spawn/sessions_send, which let a higher-level agent programmatically delegate to another agent, do exist — but these too require an operator to design the setup manually. Bottom line: the automatic-classification-and-delegation vision itself hasn’t shipped as a turnkey feature, but adjacent tools that need manual configuration now exist.
Where does Red stand now? This isn’t something GitHub can answer — it’s a question about our own team’s internal record. Re-verifying this piece, we needed to confirm whether Red is part of the current team lineup, and our own memory lookup didn’t resolve it, so we’ve put the question to Terry separately. This piece treats the Siwol/Red setup as an early-2026 experiment record and makes no claim about Red’s current status either way. We’ll update this section once we know.
Item by item, here’s where the config stands.
- bindings at the top level — still exactly right. The schema itself is stable.
- debounceMs / queue.mode — still valid config keys.
debounceMsnow ships with a 2000ms default, andqueue.modehas grown from the singlecollectoption to four:steer/followup/collect/interrupt. With a default now in place, the “you must set this manually” urgency the original post emphasized may not be as pressing today. - Workspace file structure — SOUL.md/IDENTITY.md/USER.md/AGENTS.md are still core. Current official docs also list a broader bootstrap file set that includes TOOLS.md, MEMORY.md, and HEARTBEAT.md — none of which appeared in the original posts.
- mcporter — unchanged, still the standard MCP integration tool.
🧭 Wrapping Up
Three things matter most from this consolidation. First, we corrected where the two original posts disagreed, like the gateway port number (19876 → 18789). Second, the automatic agent-to-agent handoff set as a next goal didn’t ship as envisioned, but manually-configurable adjacent capabilities now exist. Third, the config surface itself has grown wider — the workspace bootstrap file set alone went from 4 files to at least 7. If you’re setting up multi-agent OpenClaw today, read the “Dissecting the openclaw.json Core Config” section above together with “So Where Does This Stand Now?”