Gateway architecture
Last updated: 2026-01-05Overview
- A single long‑lived Gateway owns all messaging surfaces (WhatsApp via Baileys, Telegram via grammY, Slack, Discord, Signal, iMessage, WebChat).
- All clients (macOS app, CLI, web UI, automations) connect to the Gateway over
one transport: WebSocket on the configured bind host (default
127.0.0.1:18789). - One Gateway per host; it is the only place that opens a WhatsApp session.
- A bridge (default
18790) is used for nodes (macOS/iOS/Android). - A canvas host (default
18793) serves agent‑editable HTML and A2UI.
Components and flows
Gateway (daemon)
- Maintains provider connections.
- Exposes a typed WS API (requests, responses, server‑push events).
- Validates inbound frames against JSON Schema.
- Emits events like
agent,chat,presence,health,heartbeat,cron.
Clients (mac app / CLI / web admin)
- One WS connection per client.
- Send requests (
health,status,send,agent,system-presence). - Subscribe to events (
tick,agent,presence,shutdown).
Nodes (macOS / iOS / Android)
- Connect to the bridge (TCP JSONL) rather than the WS server.
- Pair with the Gateway to receive a token.
- Expose commands like
canvas.*,camera.*,screen.record,location.get.
WebChat
- Static UI that uses the Gateway WS API for chat history and sends.
- In remote setups, connects through the same SSH/Tailscale tunnel as other clients.
Connection lifecycle (single client)
Wire protocol (summary)
- Transport: WebSocket, text frames with JSON payloads.
- First frame must be
connect. - After handshake:
- Requests:
{type:"req", id, method, params}→{type:"res", id, ok, payload|error} - Events:
{type:"event", event, payload, seq?, stateVersion?}
- Requests:
- If
CLAWDBOT_GATEWAY_TOKEN(or--token) is set,connect.params.auth.tokenmust match or the socket closes. - Idempotency keys are required for side‑effecting methods (
send,agent) to safely retry; the server keeps a short‑lived dedupe cache.
Protocol typing and codegen
- TypeBox schemas define the protocol.
- JSON Schema is generated from those schemas.
- Swift models are generated from the JSON Schema.
Remote access
- Preferred: Tailscale or VPN.
- Alternative: SSH tunnel
- The same handshake + auth token apply over the tunnel.
Operations snapshot
- Start:
clawdbot gateway(foreground, logs to stdout). - Health:
healthover WS (also included inhello-ok). - Supervision: launchd/systemd for auto‑restart.
Invariants
- Exactly one Gateway controls a single Baileys session per host.
- Handshake is mandatory; any non‑JSON or non‑connect first frame is a hard close.
- Events are not replayed; clients must refresh on gaps.