claude-code, codex, hermes, and clawboo-native; those are CLIs Clawboo installs and runs per task (see Connecting runtimes). OpenClaw has its own state directory, its own scheduler, and its own external messaging channels; Clawboo coordinates with it, it does not run it.
Prerequisites
OpenClaw is a separate project. Clawboo connects to an OpenClaw Gateway you run locally; it does not bundle OpenClaw. The onboarding wizard’s OpenClaw path can install, configure, and start one for you, or you can point Clawboo at a Gateway you already run.
- An OpenClaw Gateway, reachable over WebSocket (default
ws://localhost:18789). The Clawboo server connects to the URL stored in settings (gatewayUrl). - The Gateway’s auth token. Clawboo’s onboarding writes one into OpenClaw’s
~/.openclaw/.envasGATEWAY_AUTH_TOKENand mirrors it into Clawboo’ssettings.json(gatewayToken). - Node.js (Clawboo’s prerequisite). The install step runs
npm install -g openclaw@^2026.5, sonpmmust be onPATH. - For OpenClaw 2026.5.x and later: a one-time device pairing approval, see Device pairing.
How OpenClaw connects
There are two connections to the Gateway, and they exist for different reasons.The browser connection (same-origin proxy)
The browser never talks to the Gateway directly. The SPA opens a WebSocket to the Clawboo server’s own/api/gateway/ws endpoint, and the server proxies it upstream to the Gateway. The proxy is what injects the auth token and signs the Ed25519 device-auth connect frame server-side, so the browser never sees the credential. WS upgrades to any path other than /api/gateway/ws are dropped (socket.destroy()).
This is the runtime/execution path: the chat stream (chat.send, chat.abort), session control (sessions.abort, sessions.patch), and live config patches ride this browser→proxy→Gateway connection.
The server connection (OpenClawAgentSource)
The Clawboo server opens its own Gateway connection, theOpenClawAgentSource. This is the registry of record leg: it calls agents.list() and mirrors the result into SQLite so the fleet list, agent files, and team membership survive the Gateway being down. Reads (listAgents, getAgent, listTeams) come from SQLite and work offline; writes, file I/O, and live sessions delegate to the Gateway and require a live connection.
A headless Node connection can’t use the browser’s crypto.subtle device-auth path, so the server reuses the already-paired proxy device identity (~/.clawboo/proxy-device-identity.json) to sign its connect frame via the gateway-client signConnect hook. Two details are load-bearing here, both confirmed against OpenClaw 2026.5.x:
- The server connects with
client.id=cli(the Gateway validatesclient.idagainst a fixed allowlist; a custom id likeclawboo-serveris rejected and the socket closes with code1008). - The server presents an
Originof the gateway host (http(s)://<gateway-host>). A headless Node WebSocket sends noOriginby default, which the Gateway rejects withCONTROL_UI_ORIGIN_NOT_ALLOWED; Clawboo injects thewspackage’s WebSocket (which honours a customorigin) to satisfy the check.
If the server connection is down, reads still serve SQLite (the agent list renders, flagged
stale: true), but writes 503. GET /api/agents returns { defaultId, mainKey, agents, stale, lastSyncedAt }; agent-file GET/PUT and session reads return 503 { "error": "gateway_disconnected" }. See Agents API.Channels
OpenClaw can connect to external messaging channels (WhatsApp, Telegram, and the like) and runs its own cron/heartbeat scheduler. These are the runtime’s private plane; Clawboo never serves a channel and never co-runs the Gateway’s scheduler. The OpenClaw adapter declares this in its capabilities:nativeChannels: 'gateway', nativeScheduler: true, nativeSkills: 'preserve', nativeMemory: 'preserve'. Clawboo’s Routines schedule team-task work, a different domain from OpenClaw’s own-life cron, so the two never conflate.
Steps
The OpenClaw onboarding path runs these from the wizard, but each maps to a/api/system/* route you can also drive directly. See the System API for full shapes.
1. Detect
GET /api/system/status reports whether OpenClaw is installed, the Gateway is running, and Node is sufficient:
gateway.running is true when a managed PID is alive or the port probes reachable. When the Gateway is running and ~/.openclaw/.env exists, the handler syncs the .env token into Clawboo’s settings as a side effect.
2. Install (optional)
POST /api/system/install-openclaw is a Server-Sent Events stream that runs npm install -g openclaw@^2026.5. The version is pinned to the ^2026.5 range deliberately: the gateway-client advertises connect protocol minProtocol: 3, maxProtocol: 4, and pinning the install keeps a fresh user on a protocol-compatible OpenClaw until that range is widened.
3. Configure
POST /api/system/configure-openclaw with body { provider, apiKey?, model?, gatewayPort? } writes OpenClaw’s openclaw.json and .env, generates a Gateway token, and saves Clawboo’s settings. provider is required; apiKey is required for every provider except the keyless ones — ollama (local) and openai-codex (the ChatGPT subscription; see below). The handler writes a local-mode Gateway config (gateway.mode: 'local', token auth via ${GATEWAY_AUTH_TOKEN}), enables agent-to-agent tooling (tools.agentToAgent.enabled: true, tools.sessions.visibility: 'all'), and resolves a default model from the provider.
Or: use your ChatGPT subscription
OpenClaw has a built-inopenai-codex provider that runs on a ChatGPT subscription (the same backend the Codex runtime uses) — no API key anywhere. Its credential is OpenClaw’s OWN OAuth profile, created by running OpenClaw’s login in your terminal (Clawboo never automates the exchange):
codex login (your browser opens, you approve, no code to type, and no dependence on the ChatGPT device-authorization setting). Detection is a presence-only scan of the auth-profile files (an oauth-type openai-codex profile; token values are never read into responses or logs). Once the profile exists, the configure path is fully keyless: the default model is set to openai-codex/gpt-5.5 and no key line touches .env. A codex-CLI login alone is NOT enough — OpenClaw needs its own sign-in (distinct OAuth grants; this also keeps refresh-token lineages separate).
Model refs:
openai-codex/<model> is the minimal activation on the current OpenClaw generation (2026.5.x); newer OpenClaw’s doctor --fix rewrites these refs to the canonical openai/* form. Also note the subscription quota is shared — OpenClaw agents, Codex-runtime agents, Hermes subscription runs, and your own codex usage all draw from the same ChatGPT plan allowance, and these turns report no USD cost to Clawboo’s budgets.4. Start the Gateway
POST /api/system/gateway with body { action } controls the Gateway process. action: "status" and action: "stop" return JSON; action: "start" and action: "restart" are SSE streams that spawn the Gateway detached, poll until the port is reachable (up to 60s), sync the token, and reconnect the server-side OpenClawAgentSource. An unknown action returns 400.
5. Connect (and pair the device)
Once the Gateway is reachable, the SPA connects through/api/gateway/ws. On a fresh OpenClaw 2026.5.x install the first connect fails with NOT_PAIRED; proceed to the next section.
Device pairing (NOT_PAIRED)
OpenClaw 2026.5.x and later dropped auto-pair-on-first-connect. A new device lands in OpenClaw’s pending list, and every connect attempt rejects with a structured error until a human approves it:err.code === 'NOT_PAIRED' in three places: the connect screen, the onboarding StartGatewayStep, and the bootstrap auto-reconnect, and swaps in a DevicePairingApproval card. The card’s “Approve this device” button hits POST /api/system/approve-device, which performs a two-step shell-out against the OpenClaw CLI:
openclaw devices approve --latestruns in preview mode: it printsApprove this exact request with: openclaw devices approve <UUID>and exits non-zero. Clawboo regex-extracts the UUID from the captured stdout/stderr.openclaw devices approve <UUID>performs the actual approval.
Why OpenClaw can’t be run by the per-task executor
The other four runtimes execute a board task by spawning a one-shot process: claim the task, provision a worktree, run the CLI/SDK, report up. OpenClaw is a connected substrate; its runs ride the live Gateway session over the server’s long-lived connection, so the one-shot executor runner refuses it by construction, before any board mutation:- The OpenClaw adapter’s
capabilities()declareruntimeClass: 'connected-substrate'(andworktrees: false). resolveRuntimeIntegration(caps)maps that class tohome.kind === 'connected'.- The executor runner checks this before the atomic claim and returns
{ ok: false, reason: 'connected_substrate' }, which the REST layer maps to422. The refusal landing pre-claim is the point: a misrouted run never touches the board.
/api/runtimes/:id/run only accepts the four non-OpenClaw runtime ids (isRuntimeId excludes openclaw), so calling it with openclaw returns 404 { "error": "unknown runtime 'openclaw'" }. OpenClaw’s team work flows through its live session and the board orchestration over the Gateway connection, not through the per-task runner.
Global memory scope
When the server-side connection comes up,OpenClawAgentSource registers Clawboo’s shared Memory and Tasks MCP servers into the Gateway’s top-level mcp.servers config (each as { url, transport: 'streamable-http' }), so OpenClaw agents can read and write the one shared team memory. This is idempotent; it reads the current config, skips the patch when both servers are already registered with the right URLs (so the per-reconnect re-apply can’t burn the Gateway’s 3-writes-per-60s control-plane budget), and a stale config is re-merged on reconnect.
Two scoping facts follow from the Gateway config being process-wide:
- Memory is registered at GLOBAL scope for OpenClaw. The other four runtimes get a per-run team scope baked into their attach URL; a single static Gateway-config URL can’t carry a per-run team binding, so an OpenClaw agent’s memory facts are team-unscoped. This is an organizational boundary for the local-first single-user model, not a security one.
- TeamChat is deliberately NOT registered for OpenClaw. A process-wide static URL can’t carry a per-run author binding, and registering the
team_chattool unbound would let an OpenClaw agent post as any author (identity from tool args), breaking the anti-spoof property that the peer-chat room depends on. Instead, an OpenClaw agent’s room participation is fully server-mediated through the team exchange, which posts the agent’s drained turn under the authoritative bound identity.
Verify it worked
GET /api/agents/registry/health(always200) reports the sourceconnection; it should readconnectedwith a recentlastSyncedAt.GET /api/agentsshould return your OpenClaw agents withstale: false.GET /api/system/statusshould showgateway.running: true.- Send a message in group chat; the send is an HTTP
POST /api/teams/:id/chatand the reply streams back over SSE (/api/teams/:id/chat/stream), because team orchestration runs server-side. The same-origin WS proxy carries the 1:1 chat and exec approvals, not the team run.
Troubleshooting
A down Gateway doesn’t block you if you have other agents. When the browser can’t reach the Gateway on load, a pure-OpenClaw user gets the connect / offline screen. But if you also have Native, Codex, Claude Code, or Hermes agents, Clawboo loads your dashboard anyway and floats a reconnect banner at the top instead of blocking, so you keep working with those agents. The banner’s Reconnect starts the Gateway if needed and brings your OpenClaw agents back online.
POST /api/runtimes/openclaw/... returns 404. OpenClaw is not a /api/runtimes runtime; only claude-code, codex, hermes, and clawboo-native are. Drive OpenClaw through /api/system/* and /api/gateway/ws, not the runtime install/connect/run routes.Related
- Connecting runtimes, the CLI runtimes (different connection model)
- Runtimes overview, the capability matrix
- Gateway and events, the Gateway flow and the Bridge→Policy→Handler pipeline
- AgentSource, the registry-of-record sync internals
- Memory, the shared Memory-MCP tier
- Peer chat, why TeamChat is server-mediated for OpenClaw
- System API · Agents API, full request/response shapes
- Glossary, canonical term definitions