ax-openclaw-plugin
v0.1.2
Published
ax companion plugin for binding a local OpenClaw runtime to ax.
Readme
ax OpenClaw Companion Plugin
This is a standalone OpenClaw plugin prototype. It binds a local OpenClaw runtime to ax and keeps an outbound WebSocket connection to the ax backend. ax can then send agent requests to the plugin without exposing the user's local OpenClaw Gateway to the public internet.
Flow
- Start the ax backend HTTP/WebSocket server.
- Install the plugin into OpenClaw.
- Run
openclaw ax bind. - Approve the binding in the ax web app.
- Restart OpenClaw Gateway.
- ax sends
agent.requestframes over the plugin connection. - The plugin dispatches the request through OpenClaw channel APIs.
- The plugin streams tokens/content and reliably sends terminal
done/errorframes back to ax.
Commands
openclaw ax bind --server http://8.153.200.8:8787
openclaw ax status
openclaw ax logoutFor split local development, run the backend on the API/WS port and the web app on a separate port:
PORT=3101 \
PUBLIC_BASE_URL=http://127.0.0.1:3101 \
OPENCLAW_PLUGIN_BIND_BASE_URL=http://127.0.0.1:5175 \
npm run start:backend-http
NEXT_PUBLIC_PIE_API_BASE_URL=http://127.0.0.1:3101 \
NEXT_PUBLIC_PIE_APP_BASE_URL=http://127.0.0.1:5175 \
npm --prefix app run dev
openclaw ax bind --server http://127.0.0.1:3101
openclaw gateway run --force --verboseIn this mode the plugin polls and connects to 3101, while the bind URL opens the UX at
5175/openclaw-plugin/bind?code=....
ax Backend
The ax backend now exposes the plugin endpoints through src/backend/node-http-server.ts.
Run it locally with:
npm run start:backend-httpThe same server process must handle both /v1/openclaw/plugin/connect and consumer chat
routes so that the in-memory WebSocket connection registry is visible when ax routes a
message to the plugin.
Implemented endpoints:
POST /v1/openclaw/plugin/bind/start
GET /v1/openclaw/plugin/bind/poll?bindSessionId=...
GET /v1/openclaw/plugin/connect
GET /v1/consumer/openclaw-plugin/bindings/pending?code=...
POST /v1/consumer/openclaw-plugin/bindings/approve
POST /v1/consumer/openclaw-plugin/bindings/revoke
GET /v1/consumer/openclaw-plugin/status/connect is upgraded to WebSocket. The zero-dependency plugin uses Node's built-in
WebSocket client, so it sends installationId, deviceToken, and pluginVersion as query
parameters. The backend still accepts the older Authorization: Bearer <deviceToken> and
x-ax-installation-id header form for compatibility.
Server To Plugin Messages
{
"type": "agent.request",
"messageId": "srv-msg-1",
"requestId": "chat_123",
"agentId": "agt_ax",
"conversationId": "cnv_123",
"userId": "usr_123",
"input": { "text": "hello" },
"metadata": {},
"history": []
}The plugin also accepts:
agent.cancelpingbinding.revoked
Plugin To Server Messages
plugin.helloplugin.statusagent.startedagent.deltaagent.input_requiredagent.tool.startedagent.tool.completedagent.token(legacy compatibility)agent.contentagent.doneagent.errorpong
agent.done remains the terminal success frame for existing clients. Streaming clients should
prefer agent.delta for assistant text and agent.tool.started / agent.tool.completed for
OpenClaw tool progress.
When OpenClaw emits an approval request, the plugin sends agent.input_required with:
approval.id/approval.slugapproval.runIdapproval.sessionKeyapproval.conversationIdresume.transport: "same-conversation agent.request"resume.protocol: "openclaw.exec.approval.resolve"
The AX UI should show the provided commands. OpenClaw approval replies are slash commands in
the same AX conversation:
/approve [id-or-slug]
/approve session [id-or-slug]
/approve always [id-or-slug]
/deny [id-or-slug]If only one approval is pending in the OpenClaw session, the id/slug may be omitted. The plugin
maps these replies to OpenClaw exec.approval.resolve instead of starting an unrelated run.
Terminal messages are stored under ~/.openclaw/ax-openclaw-plugin and retried after
reconnect.
Build
npm install
npm run typecheck
npm run test -- tests/openclaw-plugin/e2e.test.ts
npm run buildNotes
The plugin package lives as a workspace under packages/openclaw-plugin. The ax backend
integration lives in src/openclaw-plugin and is covered by
tests/openclaw-plugin/e2e.test.ts, which starts a real HTTP server and WebSocket client.
