Sophon

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/openclaw

The CLI:

  1. Connects to OpenClaw on ws://localhost:18789 (override with --openclaw-url).
  2. Asks Sophon Cloud for a 7-letter pairing code via /v1/pairing/start.
  3. Polls until the user types the code into iOS.
  4. 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 → bridgeBridge → SAPiOS sees
agent event, stream:'assistant'POST /v1/bridge/sendMessageDeltamessage_delta SSE
agent event, stream:'lifecycle' endPOST /v1/bridge/sendMessageEndmessage_finalized SSE
agent event, stream:'item', kind=tool/command`POST /v1/bridge/createTaskupdateTask
agent event, stream:'approval', phase=requestedPOST /v1/bridge/requestApprovalapproval_requested SSE
— (server publishes from /v1/me/approvals/:id)server → bridge busapproval_resolved SSE

Reverse direction (user → agent) flows through the bridge bus:

iOS → SAPSAP → bridge (bus)Bridge → OpenClaw
POST /v1/me/sessions/:id/sendsession.messagechat.send RPC
POST /v1/me/approvals/:idapproval.resolvedexec.approval.resolve / plugin.approval.resolve
DELETE /v1/me/sessions/:idsession.cancelledchat.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 decisionServer storesOpenClaw RPC
approveapproveallow-once
approveForSessionapproveallow-once
approve_always (scope=tool)approve_alwaysallow-always
deny, abortdenydeny

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:

FileWhat it does
src/cli.tsArgument parsing, lifecycle
src/pair.tsPairing handshake (/v1/pairing/start + poll)
src/sophon.tsSAP client (WS + REST) with idempotency + backpressure
src/openclaw.tsOpenClaw RPC client and event normaliser
src/bridge.tsThe 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.