#multi agent team setup

1 messages · Page 1 of 1 (latest)

meager cosmos
#

@golden grotto hello?

golden grottoBOT
#

Yep. First, quick clarification because “3-agent team” can mean two different OpenClaw setups:

  1. One bot you talk to, and it spawns 2 worker sub-agents in the background (recommended for “teamwork” in one chat).
  2. Three fully isolated agents (separate workspaces + auth + memory), usually routed via 3 separate Discord/Telegram bot accounts (recommended for hard isolation / different personas).

Which one do you want?


Fastest path (recommended): 1 chat-bot + sub-agents (a “team” inside one agent)

A) Install + onboard on the VPS

On the VPS:

curl -fsSL https://openclaw.ai/install.sh | bash
#

Hey — I’m here.

To get you set up cleanly, I just need two quick answers:

  1. Do you want one Discord bot that can spawn a “team” via sub-agents (simplest), or 3 separate Discord bots (true isolated agents with separate workspaces/memory)?

  2. On the VPS, paste the output of:

openclaw --version
openclaw status
openclaw models status

Once I have that, I’ll give you the exact next commands for your chosen setup.

#
openclaw onboard --install-daemon

For VPS security, I strongly recommend keeping the Gateway bound to localhost and using SSH tunnel or Tailscale for the dashboard (the wizard/FAQ covers this).

VPS/remote tips (docs):

B) Add your 3 provider auth methods

You can authenticate each provider on the VPS like this:

Codex subscription (ChatGPT/Codex OAuth):

#
openclaw models auth login --provider openai-codex

Claude subscription (setup-token):

  • Generate token on any machine that has Claude Code:
    claude setup-token
    
  • Then on the VPS:
    openclaw models auth paste-token --provider anthropic
    

Docs: https://docs.openclaw.ai/providers/anthropic

MiniMax subscription (Coding Plan OAuth)
Enable the bundled plugin, restart gateway, then login:

#
openclaw plugins enable minimax-portal-auth
openclaw gateway restart
openclaw models auth login --provider minimax-portal --method oauth
# (or --method oauth-cn if you need the CN endpoint)

Docs: https://docs.openclaw.ai/providers/minimax

C) Use sub-agents as your “team”

Once you’ve got multiple providers configured, you can run background workers from the same chat using Sub-agents:

Docs: https://docs.openclaw.ai/tools/subagents

This gives you the “3-agent team” feel without needing 3 Discord bots.


#

Alternative: 3 isolated agents (true multi-agent routing)

If you want hard separation (different workspaces/memory/auth), use multi-agent routing:

Docs: https://docs.openclaw.ai/concepts/multi-agent

Typical pattern on Discord is one Discord bot token per agent (3 bots), then bind each accountId to an agentId.


Two things I need from you to give exact commands

  1. On your VPS, what does this print?
openclaw --version
  1. Are you trying to run this team from Discord only (and you’re OK creating 3 Discord bot accounts), or do you prefer one bot that spawns worker sub-agents behind the scenes?
meager cosmos
#

I'm trying to run it via a telegram group chat - I want 3 isolated agents

#

@golden grotto

golden grottoBOT
#

For a Telegram group chat + 3 isolated agents, the clean way is: 3 separate Telegram bots (3 BotFather tokens) → each bot is a separate accountId → each accountId is bound to a separate agentId (separate workspace + auth + memory).

If you only have one Telegram bot token, you can’t get 3 truly isolated agents in the same group (because there’s only one accountId to route).

Docs (this is the pattern): https://docs.openclaw.ai/concepts/multi-agent

Step-by-step (VPS)

0) Version check (please paste if anything breaks)

openclaw --version

1) Create 3 Telegram bots

In Telegram → @BotFather:

  • /newbot x3 → save 3 tokens + usernames (you’ll @mention them in the group)
#

2) Add 3 isolated agents (3 workspaces)

Pick ids like lead, coder, research:

openclaw agents add lead    --workspace ~/.openclaw/workspace-lead
openclaw agents add coder   --workspace ~/.openclaw/workspace-coder
openclaw agents add research --workspace ~/.openclaw/workspace-research

3) Add 3 Telegram channel accounts (one per bot token)

openclaw channels add --channel telegram --account lead     --token "<BOT_TOKEN_1>"
openclaw channels add --channel telegram --account coder    --token "<BOT_TOKEN_2>"
openclaw channels add --channel telegram --account research --token "<BOT_TOKEN_3>"

(Optional but recommended: disable random DMs to each bot)

#
openclaw config set channels.telegram.accounts.lead.dmPolicy disabled
openclaw config set channels.telegram.accounts.coder.dmPolicy disabled
openclaw config set channels.telegram.accounts.research.dmPolicy disabled

4) Bind each Telegram bot account to an agent

Set bindings via config:

openclaw config set --json bindings '[
  { agentId: "lead",     match: { channel: "telegram", accountId: "lead" } },
  { agentId: "coder",    match: { channel: "telegram", accountId: "coder" } },
  { agentId: "research", match: { channel: "telegram", accountId: "research" } }
]'
meager cosmos
#

one of these (the lead) would also be my main chat agent who I talk to - so only the other two would have to be mention-only

golden grottoBOT
#

Verify:

openclaw agents list --bindings

5) Lock group behavior (mention-only is best for 3 bots)

Start with mention-only for all groups (then tighten to a single group once you know the group id):

openclaw config set --json channels.telegram.groups '{ "*": { "requireMention": true, "groupPolicy": "open" } }'

Telegram note: with default bot privacy mode, bots will typically only see messages that @mention them anyway — which matches what we want. (Docs: https://docs.openclaw.ai/channels/telegram)

6) Restart gateway

#
openclaw gateway restart

7) Add all 3 bots to your Telegram group + test

In the group, try:

  • @YourLeadBot hi
  • @YourCoderBot write a function that…
  • @YourResearchBot summarize…

Once you see it working, you can restrict channels.telegram.groups to only that group id (e.g. -100...) so nobody can add your bots to other groups. Easiest way to get the group id:

openclaw channels logs --channel telegram

and look for chat.id.


#

Next question (so I can tailor the exact config):

Do you already have 3 BotFather tokens ready, or do you currently have only one Telegram bot?

meager cosmos
#

I'm installing Openclaw on my VPS right now. I already have the three bot tokens. can you guide me step by step?

#

@golden grotto

golden grottoBOT
#

I’m here.

For a Telegram group + 3 truly isolated agents (separate workspace/auth/memory) you basically have two choices:

Option A (recommended): 3 Telegram bots (3 BotFather tokens)

That’s the only way to have 3 separate “identities” in the same group (and clean routing).

Do this on the VPS:

  1. Make sure Telegram + MiniMax OAuth plugins are enabled:
openclaw plugins enable telegram
openclaw plugins enable minimax-portal-auth   # only needed if you want MiniMax via subscription OAuth
openclaw gateway restart
  1. Create each agent via the wizard (this is the easiest way because it writes auth into the correct agentDir):
#
openclaw agents add lead
openclaw agents add coder
openclaw agents add research

In each agents add wizard:

  • say YES to “Configure model/auth for this agent now?”
  • then in Channels, pick Telegram and paste that agent’s bot token
  • say YES to “Route selected channels to this agent now? (bindings)”
  1. Add all 3 bots to the Telegram group, and talk to each via @BotUsername …

Option B: 1 Telegram bot, but still 3 isolated backends

Possible, but all replies come from the same bot (no separate identities). Only do this if that’s acceptable.

#

Before we go further: do you already have 3 BotFather bot tokens, or only one right now?

meager cosmos
#

I have three. another problem though, i'm getting this error when hatching the bot in the TUI:

openclaw tui - ws://127.0.0.1:18789 - agent main - session main
connecting | idle
gateway disconnected: pairing required | idle
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gateway connect failed: Error: pairing required
gateway connect failed: Error: pairing required─────────────────────────────────────────────────────────────────────────
gateway connect failed: Error: pairing required
gateway connect failed: Error: pairing required
gateway connect failed: Error: pairing required
gateway connect failed: Error: pairing required

golden grottoBOT
#

That error is Gateway device pairing, not Telegram pairing.

When the TUI connects, it identifies as a new operator device. If the Gateway doesn’t recognize/auto-approve that device, it drops the WS connection with:

pairing required

Fix (run on the VPS where the Gateway is running)

In a second SSH session (or another terminal), run:

openclaw devices list
openclaw devices approve --latest

(or openclaw devices approve <requestId> if you want to pick it manually)

#

Then restart the TUI:

openclaw tui --url ws://127.0.0.1:18789

Docs: https://docs.openclaw.ai/web/control-ui#device-pairing-first-connection and https://docs.openclaw.ai/cli/devices

If devices list shows nothing

Two common causes:

  1. You’re approving against a different gateway than the one your TUI is hitting. Check:
openclaw gateway status
  1. You’re connecting through a proxy/Tailscale Serve/reverse-proxy and the Gateway doesn’t treat it as “local”, so pairing is expected (approving once still fixes it).
#

If you paste openclaw gateway status + openclaw devices list output (redact tokens), I can tell which case you’re in.

meager cosmos
#

marco@mdm-dev-projects-2:~$ openclaw devices list

🦞 OpenClaw 2026.2.19-2 (45d9b20) — Your messages, your servers, your control.


gateway connect failed: Error: pairing required

[openclaw] Failed to start CLI: Error: gateway closed (1008): pairing required
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/marco/.openclaw/openclaw.json
Bind: loopback
at Object.onClose (file:///home/marco/.npm-global/lib/node_modules/openclaw/dist/call-DZzTR0NL.js:438:10)
at WebSocket.<anonymous> (file:///home/marco/.npm-global/lib/node_modules/openclaw/dist/client-DoSZFvf3.js:1538:23)
at WebSocket.emit (node:events:519:28)
at WebSocket.emitClose (/home/marco/.npm-global/lib/node_modules/openclaw/node_modules/ws/lib/websocket.js:273:10)
at Socket.socketOnClose (/home/marco/.npm-global/lib/node_modules/openclaw/node_modules/ws/lib/websocket.js:1346:15)
at Socket.emit (node:events:519:28)
at TCP.<anonymous> (node:net:346:12)
marco@mdm-dev-projects-2:~$ openclaw devices approve --latest

🦞 OpenClaw 2026.2.19-2 (45d9b20) — I'm not magic—I'm just extremely persistent with retries and coping strategies.


gateway connect failed: Error: pairing required

[openclaw] Failed to start CLI: Error: gateway closed (1008): pairing required
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/marco/.openclaw/openclaw.json
Bind: loopback
at Object.onClose (file:///home/marco/.npm-global/lib/node_modules/openclaw/dist/call-DZzTR0NL.js:438:10)
at WebSocket.<anonymous> (file:///home/marco/.npm-global/lib/node_modules/openclaw/dist/client-DoSZFvf3.js:1538:23)
at WebSocket.emit (node:events:519:28)
at WebSocket.emitClose (/home/marco/.npm-global/lib/node_modules/openclaw/node_modules/ws/lib/websocket.js:273:10)
at Socket.socketOnClose (/home/marco/.npm-global/lib/node_modules/openclaw/node_modules/ws/lib/websocket.js:1346:15)
at Socket.emit (node:events:519:28)
at TCP.<anonymous> (node:net:346:12)

I'm connecting to the remote machine via ssh in my Tailnet

golden grottoBOT
#

This is device pairing for the Gateway operator client (TUI/CLI). What’s biting you here is:

  • A non-local connect created a pending device pairing request (silent=false), and
  • after that, even local connects won’t auto-approve, because the gateway keeps reusing the existing pending request.

That’s why even openclaw devices list can’t run — it has to connect as an operator first, and it’s the operator device that’s “not paired”.

Fix (safe + quick): clear the stuck pending device request, then reconnect locally

On the VPS (same machine that runs the gateway):

openclaw gateway stop

ls -la ~/.openclaw/devices
mv ~/.openclaw/devices/pending.json ~/.openclaw/devices/pending.json.bak 2>/dev/null || true
#

openclaw gateway start
openclaw tui --url ws://127.0.0.1:18789

If that works, you should be unblocked immediately.

If it STILL says “pairing required” after that

Then the gateway is not treating your connection as “local” (so it won’t auto-approve). The gateway usually logs why. Please paste the relevant lines from:

openclaw logs --follow

Look for warnings like:

  • “Proxy headers detected from untrusted address…”
#
  • “Loopback connection with non-local Host header…”

Also: are you running the gateway in Docker (or behind a reverse proxy)? That can make the gateway see your client IP as non-loopback, which forces pairing every time.

(Reference: pairing state lives in ~/.openclaw/devices/pending.json + paired.json — docs: https://docs.openclaw.ai/channels/pairing)

meager cosmos
#

marco@mdm-dev-projects-2:~$ openclaw tui --url ws://127.0.0.1:18789

🦞 OpenClaw 2026.2.19-2 (45d9b20) — Shell yeah—I'm here to pinch the toil and leave you the glory.

Error: gateway url override requires explicit credentials
Fix: pass --token or --password when using --url.

golden grottoBOT
#

That one’s simpler: as soon as you pass --url, OpenClaw refuses to “silently” use stored creds. So you must provide --token (or --password) explicitly.

Easiest fix (since you’re SSH’d into the gateway host)

Just don’t override the URL:

openclaw tui

If you do want to keep --url, pass the gateway token

(Do not paste the token into Discord.)

TOKEN=$(openclaw config get gateway.auth.token)
openclaw tui --url ws://127.0.0.1:18789 --token "$TOKEN"
#

If openclaw config get gateway.auth.token errors / is empty, tell me and we’ll generate/set one (but don’t share it in chat).

After you get past this, if you still hit pairing required, we’ll go back to the device-pairing issue (that’s a separate problem).

meager cosmos
#

still says pairing required

golden grottoBOT
#

That means the Gateway still has a stuck pending device-pairing request for your CLI/TUI device (usually created the first time you tried connecting “remotely”). Once that pending request exists with silent=false, local auto-approve won’t kick in until you clear it.

On the VPS (gateway host), run:

openclaw gateway stop

ls -ლა ~/.openclaw/devices
mv ~/.openclaw/devices/pending.json ~/.openclaw/devices/pending.json.bak 2>/dev/null || true

openclaw gateway start
openclaw tui

If it still says pairing required after that, then the gateway is not treating your connection as local (often because it’s behind a proxy/Docker and the gateway sees a non-loopback client IP, or it’s seeing x-forwarded-* headers). In that case, paste the relevant log lines right when you try to connect:

#
openclaw logs --follow

(and tell me: are you running the gateway in Docker, or via Tailscale Serve / any reverse proxy?)

meager cosmos
#

marco@mdm-dev-projects-2:~$ openclaw logs --follow

🦞 OpenClaw 2026.2.19-2 (45d9b20) — Less clicking, more shipping, fewer "where did that file go" moments.

gateway connect failed: Error: pairing required
Gateway not reachable. Is it running and accessible?
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/marco/.openclaw/openclaw.json
Bind: loopback
Hint: run openclaw doctor.

before installing openclaw, I installed tailscale and hardened SSH on the machine. DO I need to allow specific ports ?

#

the web UI works - how???

golden grottoBOT
#

You don’t need to open any special inbound ports for Telegram.

  • Telegram bots use outbound HTTPS (port 443) to api.telegram.org (long polling by default), so as long as your VPS can make outbound 443, Telegram works.
  • Don’t expose the OpenClaw gateway port 18789 to the public internet. Keep bind: loopback and access it via SSH tunnel or Tailscale Serve.

For Tailscale, if you run a firewall (ufw/iptables), the only common thing to allow is:

  • UDP 41641 inbound+outbound for best direct connectivity (Tailscale can still limp via DERP over outbound 443 if needed, but it’s slower).

About the pairing required you’re stuck on

This is not a port/firewall issue — it’s Gateway device pairing. But the key detail is: your Gateway is treating your connection as non-local, so it refuses to auto-approve the operator device and you deadlock.

The most common reason is: you’re not actually hitting the gateway directly on 18789 — you’re hitting some proxy/container path that adds x-forwarded-* headers or changes the source IP, so the gateway won’t consider it “local”.

1) Check what is actually listening on 18789

On the VPS, paste the output of:

#
sudo ss -ltnp | grep ':18789'

If the process is not openclaw (e.g. nginx/caddy/docker-proxy), that explains why “local auto-approve” isn’t happening.

2) If you’re using Docker / reverse proxy, say so

Just answer: “gateway is running in docker” or “I put nginx/caddy in front”.


Quick workaround (usually unblocks immediately)

From your laptop, create an SSH tunnel into the VPS:

ssh -N -L 18789:127.0.0.1:18789 marco@mdm-dev-projects-2
#

Then on your laptop run:

openclaw tui --url ws://127.0.0.1:18789 --token "<gateway-token>"

(Get the token from the VPS with openclaw config get gateway.auth.token — don’t paste it here.)

This tunnel makes the gateway see the connection as truly local, which should trigger the silent auto-approve.


Send me the ss output and whether you’re using Docker/proxy, and I’ll tell you the exact fix (either “connect to the real port” or “set gateway.trustedProxies correctly”).

meager cosmos
#

marco@mdm-dev-projects-2:~$ sudo ss -ltnp | grep ':18789'
LISTEN 0 511 127.0.0.1:18789 0.0.0.0:* users:(("openclaw-gatewa",pid=40655,fd=22))
LISTEN 0 511 [::1]:18789 [::]:* users:(("openclaw-gatewa",pid=40655,fd=23))

golden grottoBOT
#

The web UI can work while the CLI/TUI is blocked because they’re different “devices” to the Gateway.

  • Your browser has its own device identity (stored in that browser profile). It might already be paired, or you might be running the Control UI in “token-only / insecure” mode (which can bypass device identity).
  • Your CLI/TUI is a separate operator device identity — and that one is currently stuck in “pairing required”, so every CLI command that talks to the Gateway (devices, logs, etc.) gets kicked out.

Ports / firewall (Tailscale + Telegram)

No, you don’t need to open random ports for Telegram.

  • Telegram bot: only needs outbound 443 from the VPS.
  • Tailscale: best to allow UDP 41641 (helps direct connections), but it can still work via outbound 443/DERP.
  • You do not need to open Gateway 18789 to the internet. If you’re using Tailscale or SSH, keep it private.

Unblock the CLI/TUI “pairing required” deadlock (most common fix)

On the VPS (gateway host), reset the pending device pairing file, then restart:

#
openclaw gateway stop

ls -la ~/.openclaw/devices
mv ~/.openclaw/devices/pending.json ~/.openclaw/devices/pending.json.bak.$(date +%s) 2>/dev/null || true

openclaw gateway start
openclaw tui

If that was the issue, your next local connect should auto-approve and you’re good.

If it STILL says pairing required after that

Then your “local” connection is not being seen as local by the Gateway (common causes: gateway running in Docker, or a reverse proxy in front).

Please paste the output of these two (safe to share):

#
openclaw gateway status
sudo ss -ltnp | grep ':18789'

That will tell us immediately whether you’re actually hitting the gateway directly, or via a proxy/container (which changes the client IP and forces pairing).

meager cosmos
#

marco@mdm-dev-projects-2:~$ sudo ss -ltnp | grep ':18789'
LISTEN 0 511 127.0.0.1:18789 0.0.0.0:* users:(("openclaw-gatewa",pid=40655,fd=22))
LISTEN 0 511 [::1]:18789 [::]:* users:(("openclaw-gatewa",pid=40655,fd=23))

golden grottoBOT
#

ss shows your Gateway is listening only on loopback and it’s really openclaw-gateway:

127.0.0.1:18789  (openclaw-gatewa pid=40655)

So this is not a firewall/port issue.

Why the web UI works but CLI/TUI doesn’t

The Control UI (browser) is a different “device” than the CLI/TUI. If your browser device already got paired (or you’re accessing it locally/securely), it can connect fine while the CLI device is still “not paired”.

Do you need to allow ports?

For your intended setup (Gateway bound to loopback + access via SSH/Tailscale):

  • Telegram bots: only need outbound TCP 443 (to Telegram API). No inbound ports.
  • Tailscale: ideally allow UDP 41641 (in/out) for best connectivity (optional but recommended).
  • SSH: allow inbound TCP 22 (or whatever port you moved SSH to).
#
  • You do not need to open 18789 publicly (and you shouldn’t).

Fix the “pairing required” deadlock (most likely: stuck pending request)

If you ever tried to connect “remotely” first, the gateway can get a pending device pairing request that keeps getting reused and blocks even local attempts.

Run this on the VPS:

  1. See what the service thinks the config/log paths are:
openclaw gateway status
  1. Stop the gateway service, clear pending device-pairing, start again:
openclaw gateway stop
#
ls -la ~/.openclaw/devices
mv ~/.openclaw/devices/pending.json ~/.openclaw/devices/pending.json.bak.$(date +%s) 2>/dev/null || true

openclaw gateway start
openclaw tui

If it still says pairing required after this, paste the output of openclaw gateway status (it’s safe) and also:

ls -la ~/.openclaw/devices

That’ll tell us whether we’re clearing the right state dir, or if something is recreating the pending request immediately.

#

That ss output is perfect: the Gateway is definitely running locally on 127.0.0.1:18789. So no firewall/ports are involved here.

What’s happening is almost certainly a stuck pending device-pairing request for your CLI/TUI device identity. The browser UI can work because it’s a different device identity (different “device”), so it may already be paired.

Fix: reset the CLI/TUI device identity + clear pending requests (safe, reversible)

Run this on the VPS as marco (not root):

openclaw gateway stop

# back up stuck pending device pairing requests
mv ~/.openclaw/devices/pending.json ~/.openclaw/devices/pending.json.bak.$(date +%s) 2>/dev/null || true

# reset the CLI/TUI device identity (forces a fresh deviceId)
mv ~/.openclaw/identity/device.json ~/.openclaw/identity/device.json.bak.$(date +%s) 2>/dev/null || true
#

openclaw gateway start
openclaw tui

Why this works: the CLI/TUI device id lives in ~/.openclaw/identity/device.json. If it got a non-silent pairing request created earlier, the gateway keeps reusing it. Resetting identity forces a new device id, and because you’re connecting on loopback, the gateway should auto-approve silently.

If it still says pairing required

Don’t use openclaw logs (it needs gateway access). Instead tail the file log directly:

tail -n 200 /tmp/openclaw/openclaw-$(date +%Y-%m-%d).log | grep -Ei "pairing|required|proxy headers|non-local host|loopback"

Paste those lines here.

#

Ports (answering your earlier question)

  • Telegram bot: only needs outbound 443.
  • Tailscale: UDP 41641 helps (recommended), but not required.
  • Keep 18789 closed to the internet (you’re on loopback anyway).

Run the reset steps above and tell me whether openclaw tui connects afterward.