OpenClaw bridge
@sophonai/openclaw is the canonical Sophon connector. It wraps
a local OpenClaw gateway as a paired Sophon installation. Once
paired, you chat with your OpenClaw from the iPhone exactly as if
it were a native Sophon agent — same rendering, same streaming,
same tool-call cards, same HITL approvals.
If you're here because you want a Claude-Code-shaped agent on your phone with five minutes of setup, this is the page.
What is OpenClaw?
OpenClaw is the open-source, self-hosted gateway that powers
Claude Code-style local agents. It exposes a JSON-RPC WebSocket
on localhost:18789 with a chat surface, tool execution, and
human-in-the-loop approvals. The Sophon bridge is a thin
translator between OpenClaw's wire format and SAP — nothing
more.
Install and pair
npx @sophonai/openclawThe CLI:
- Connects to OpenClaw on
ws://localhost:18789(override with--openclaw-url). - Asks Sophon Cloud for a 7-letter pairing code via
/v1/pairing/start. - Polls until the user types the code into iOS.
- On success, holds two long-lived connections — one to the
gateway and one to
wss://api.sophon.at/v1/bridge/ws— and forwards events both directions.
Stop the process at any time; iOS marks the installation as degraded until it comes back. Re-running the CLI with the stashed token reconnects without re-pairing.
What it forwards
The bridge translates OpenClaw events into SAP events one-for-one:
| OpenClaw → bridge | Bridge → SAP | iOS sees |
|---|---|---|
agent event, stream:'assistant' | POST /v1/bridge/sendMessageDelta | message_delta SSE |
agent event, stream:'lifecycle' end | POST /v1/bridge/sendMessageEnd | message_finalized SSE |
agent event, stream:'item', kind=tool/command | `POST /v1/bridge/createTask | updateTask |
agent event, stream:'approval', phase=requested | POST /v1/bridge/requestApproval | approval_requested SSE |
— (server publishes from /v1/me/approvals/:id) | server → bridge bus | approval_resolved SSE |
Reverse direction (user → agent) flows through the bridge bus:
| iOS → SAP | SAP → bridge (bus) | Bridge → OpenClaw |
|---|---|---|
POST /v1/me/sessions/:id/send | session.message | chat.send RPC |
POST /v1/me/approvals/:id | approval.resolved | exec.approval.resolve / plugin.approval.resolve |
DELETE /v1/me/sessions/:id | session.cancelled | chat.abort (in progress) |
Operator scopes
The bridge claims three operator scopes at handshake:
scopes: ['operator.read', 'operator.write', 'operator.approvals']operator.approvals is needed for the *.approval.resolve RPCs.
If you self-host an OpenClaw with a stricter scope policy, add
this to its allowlist.
Tool-frame deduplication
OpenClaw fans some tool lifecycles through two stream:'item'
channels — one with kind:'tool' (provider-level) and one with
kind:'command' (exec wrapper). The bridge dedups by
(runId, toolCallId, phase) so iOS doesn't render "Ran 2
commands" when the agent ran one. The iOS adapter does a
defensive id-check too.
Approval mapping
iOS's rich approval vocabulary collapses onto OpenClaw's three decisions:
| iOS decision | Server stores | OpenClaw RPC |
|---|---|---|
approve | approve | allow-once |
approveForSession | approve | allow-once |
approve_always (scope=tool) | approve_always | allow-always |
deny, abort | deny | deny |
approve_always writes a permanent grant onto
installations.metadata.approval_grants. The next time the agent
asks for the same (action, scope, scope_value) tuple, the
server auto-resolves without bothering you.
Multi-host install
Run @sophonai/openclaw on a second Mac with the same Sophon
account. iOS sees it as a second installation under the same
connector type — distinguish them via the emoji + custom
name swipe-action in Settings.
CLI flags
--openclaw-url <ws-url> (default ws://localhost:18789)
--openclaw-token <token> OpenClaw operator token
--sophon-base <url> (default https://api.sophon.at)
--sophon-token <inst_…:s_…> skip pairing (CI / re-attach)
--host-label <name> visible in Sophon's host list
--verbose
Where to find the code
The OpenClaw bridge lives in this repo at
s-chat-cloud/connectors/openclaw-bridge/.
~600 lines of TypeScript across five files:
| File | What it does |
|---|---|
src/cli.ts | Argument parsing, lifecycle |
src/pair.ts | Pairing handshake (/v1/pairing/start + poll) |
src/sophon.ts | SAP client (WS + REST) with idempotency + backpressure |
src/openclaw.ts | OpenClaw RPC client and event normaliser |
src/bridge.ts | The glue — translate event streams both ways |
If you're writing your own connector, this is the canonical reference implementation. See Write your own connector for the path when your agent doesn't speak OpenClaw.
Troubleshooting
- 401 on
/v1/bridge/ws— your install token was revoked or rotated. Re-pair. exec.approval.resolve INVALID_REQUEST— your gateway version uses a different param name; update OpenClaw to ≥ v3.- Tool cards show twice — older bridge dist; rebuild and restart.
- Pairing code times out — codes expire after 120 s. Restart the CLI to mint a fresh one.