{"id":51710033,"url":"https://github.com/cameronapak/zo-openclaw-gateway","last_synced_at":"2026-07-16T19:33:54.267Z","repository":{"id":371274086,"uuid":"1239212249","full_name":"cameronapak/zo-openclaw-gateway","owner":"cameronapak","description":"OpenClaw-compatible WebSocket gateway that bridges Rabbit r1 (and other OpenClaw clients) to the Zo Computer API.","archived":false,"fork":false,"pushed_at":"2026-06-15T13:47:29.000Z","size":28,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-14T09:39:33.498Z","etag":null,"topics":["ai-gateway","openclaw","rabbit-r1","voice-assistant","websocket","zo-computer"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cameronapak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-14T21:51:04.000Z","updated_at":"2026-06-15T13:47:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cameronapak/zo-openclaw-gateway","commit_stats":null,"previous_names":["cameronapak/zo-openclaw-gateway"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/cameronapak/zo-openclaw-gateway","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameronapak%2Fzo-openclaw-gateway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameronapak%2Fzo-openclaw-gateway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameronapak%2Fzo-openclaw-gateway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameronapak%2Fzo-openclaw-gateway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cameronapak","download_url":"https://codeload.github.com/cameronapak/zo-openclaw-gateway/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameronapak%2Fzo-openclaw-gateway/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35557060,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-16T02:00:06.687Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-gateway","openclaw","rabbit-r1","voice-assistant","websocket","zo-computer"],"created_at":"2026-07-16T19:33:52.860Z","updated_at":"2026-07-16T19:33:54.260Z","avatar_url":"https://github.com/cameronapak.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# zo-openclaw-gateway\n\nAn OpenClaw-compatible WebSocket gateway that bridges **Rabbit r1** (and other OpenClaw clients) to the [Zo Computer](https://zo.computer) API.\n\nTalk to your Zo from a Rabbit r1. The gateway speaks the OpenClaw operator protocol over WebSocket, so the r1 thinks it's talking to a real OpenClaw gateway, while every `chat.send` is transparently routed to Zo's `/zo/ask` endpoint.\n\n\u003e Built and tested against a real Rabbit r1. Originally a personal project, now open-sourced so anyone can run their own.\n\n---\n\n## How it works\n\n```\nRabbit r1  ──WebSocket──▶  zo-openclaw-gateway  ──HTTP──▶  Zo API (/zo/ask)\n (OpenClaw protocol)        (this repo)                     (your Zo Computer)\n```\n\nThe gateway is an **adapter**, not a full OpenClaw clone. It implements just enough of the OpenClaw operator protocol to satisfy the r1's connect, session, and chat flow, then maps each request to the equivalent Zo API call.\n\n### What it implements\n\n| OpenClaw surface | What happens |\n|---|---|\n| `connect` (challenge + auth) | Bootstrap-token / device-token auth, issues reusable device tokens |\n| `chat.send` (and aliases) | Routes to Zo `/zo/ask`, streams the response back as OpenClaw `chat`/`agent` events |\n| `sessions.list` / `chat.history` | Backed by a local JSON state file |\n| `models.list` / `agents.list` | Pulled live from Zo (`/models/available`, `/personas/available`) |\n| `talk.config` / `talk.speak` / `tts.*` | Returns a `talk_unconfigured` fallback so the r1 uses its **local** TTS instead of server-side |\n| `health`, `ping`, `heartbeat` | Standard keep-alive |\n| QR setup (`/qr`, `/setup-code`) | Generates a scannable setup code for the r1's pairing flow |\n\nEach OpenClaw session maps to its own Zo `conversation_id`, so conversation continuity is preserved across reconnects.\n\n### Voice / TTS\n\nServer-side TTS is intentionally **disabled**. The gateway returns a `talk_unconfigured` fallback signal, which tells the r1 to synthesize speech locally. This keeps your provider keys off the gateway and avoids latency. If you want server-side TTS later, the `talk.speak` and `tts.convert` handlers are the extension points.\n\n---\n\n## Quick start\n\n### Prerequisites\n\n- [Bun](https://bun.sh) runtime (v1.3+)\n- A [Zo Computer](https://zo.computer) account\n- A Rabbit r1 (or any OpenClaw-compatible client)\n\n### 1. Get your Zo API key\n\nIn Zo Computer, go to **Settings → Advanced → Access Tokens** and create a token.\n\n### 2. Configure environment\n\n```bash\ncp .env.example .env\n```\n\nFill in:\n\n```bash\nZO_API_KEY=your-zo-access-token\nOPENCLAW_ADMIN_TOKEN=choose-a-long-random-secret\nGATEWAY_PUBLIC_URL=wss://your-gateway.example.com   # see deployment below\n```\n\n### 3. Install \u0026 run\n\n```bash\nbun install\nbun start\n```\n\nThe gateway listens on `:8787` by default.\n\n### 4. Generate a setup code for your r1\n\n```bash\ncurl -H \"Authorization: Bearer $OPENCLAW_ADMIN_TOKEN\" \\\n  https://your-gateway.example.com/setup-qr\n```\n\nThis returns JSON with a `qrDataUrl`. For an HTML page you can scan directly:\n\n```bash\ncurl -H \"Authorization: Bearer $OPENCLAW_ADMIN_TOKEN\" \\\n  https://your-gateway.example.com/qr\n```\n\nScan the QR with the Rabbit r1's OpenClaw setup flow. The r1 connects, authenticates via the bootstrap token, receives a reusable device token, and you're talking to Zo.\n\n---\n\n## Deployment\n\nThe gateway is a standard Bun HTTP/WebSocket server — deploy it anywhere that exposes a public `wss://` endpoint.\n\n### Option A: Zo Computer User Service\n\nIf you have a Zo Computer, run it as a managed HTTP service (this is how the author runs it):\n\n1. Push this repo into your Zo workspace.\n2. Register an HTTP user service with entrypoint `bun run src/server.ts`.\n3. Set `ZO_API_KEY`, `OPENCLAW_ADMIN_TOKEN`, and `GATEWAY_PUBLIC_URL` as service env vars (the public `wss://\u003cservice\u003e.zocomputer.io` URL).\n4. The service auto-starts and restarts on crash.\n\n### Option B: Any Node/Bun host\n\nFly.io, Railway, Render, a VPS — anything with a public address works. Make sure `GATEWAY_PUBLIC_URL` points at the deployed `wss://` address and `PORT` is set to whatever the platform assigns.\n\n---\n\n## Configuration\n\nAll config is via environment variables:\n\n| Variable | Required | Default | Description |\n|---|---|---|---|\n| `ZO_API_KEY` | yes | — | Zo access token |\n| `OPENCLAW_ADMIN_TOKEN` | yes | — | Protects `/qr`, `/setup-code`, `/setup-qr` |\n| `GATEWAY_PUBLIC_URL` | no | `ws://localhost:8787` | Public `wss://` URL for setup codes |\n| `STATE_FILE` | no | `./data/state.json` | Where device tokens + session history are persisted |\n| `PORT` | no | `8787` | Listen port |\n\n---\n\n## Development\n\n```bash\nbun install\nbun test        # run the test suite\nbun run typecheck\nbun run observe # tail structured gateway logs\n```\n\nTests use an in-memory `FakeZoClient`, so no real Zo key is needed to run them.\n\n### Project structure\n\n```\nsrc/\n├── server.ts            # entrypoint — reads env, boots Bun.serve\n├── openclaw-gateway.ts  # core: WS handler, protocol, auth, chat routing\n├── zo-client.ts         # HTTP client for Zo API (ask + stream + models + personas)\n├── setup-code.ts        # QR/setup-code encoding (clawdbot-gateway format)\n├── state.ts             # JSON-file-backed state store (sessions, tokens)\n└── types.ts             # shared types\ntests/\n├── gateway.test.ts      # connect, chat, sessions, tool labels, TTS fallback\n└── setup-code.test.ts   # setup-code encode/decode round-trip\nscripts/\n└── observe.ts           # structured-log tailer for debugging\n```\n\n---\n\n## Protocol reference\n\nSee [`docs/protocol.md`](docs/protocol.md) for a summary of the OpenClaw operator protocol methods this gateway implements, and [`docs/architecture.md`](docs/architecture.md) for the request/response flow diagrams.\n\nOfficial OpenClaw docs: \u003chttps://docs.openclaw.ai/gateway/protocol\u003e\n\n---\n\n## Security notes\n\n- `OPENCLAW_ADMIN_TOKEN` gates all setup-code generation. Keep it secret.\n- Device tokens (`oc_dev_*`) are persisted in `STATE_FILE`. Anyone with one can connect and chat with your Zo. Treat the state file as a credential.\n- The gateway redacts token/secret/password fields from structured logs, but **never log the raw state file or env in production**.\n- After pairing, consider rotating your `OPENCLAW_ADMIN_TOKEN` if it was exposed during setup.\n\n---\n\n## License\n\n[MIT](LICENSE) — Cam Pak\n\n---\n\nBuilt on [Zo Computer](https://zo.computer). Not affiliated with Rabbit Inc. or OpenClaw.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcameronapak%2Fzo-openclaw-gateway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcameronapak%2Fzo-openclaw-gateway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcameronapak%2Fzo-openclaw-gateway/lists"}