openclaw-acp-channel
v0.4.9
Published
OpenClaw channel plugin for ACP (Agent Client Protocol) interface
Readme
OpenClaw ACP Channel Plugin
Channel plugin that exposes OpenClaw agents via the Agent Client Protocol (ACP) standard interface.
Requirements
⚠️ OpenClaw 2026.3.28 or later is required
This plugin uses the dispatchInboundDirectDmWithRuntime API which is only available in OpenClaw 2026.3.28+.
Features
- ACP JSON-RPC over STDIO - Real ACP protocol, not a custom line format
- HTTP webhook dispatch - Bridge forwards prompts into OpenClaw
- Dynamic callback port - Avoids fixed-port collisions across multiple processes
- Session management -
session/new,session/load,session/prompt,session/cancel - Session isolation - Each ACP session maps to a distinct OpenClaw session key
- Tool-call updates - Emits ACP
tool_callandtool_call_update - Session replay - Persisted session history supports
session/load - Security - Bearer token authentication between bridge and plugin
Use Cases
- Skills testing - Test agent behaviors programmatically
- External integrations - Connect any ACP-compatible client
- Mobile/desktop apps - Chat interfaces and agent UIs
- Automation - Script agent interactions
Architecture
ACP Client App
↕ STDIO (ACP protocol)
ACP Bridge Server
↕ HTTP POST (localhost)
OpenClaw Channel Plugin (webhook)
↕
OpenClaw AgentInstallation
Prerequisites
- OpenClaw 2026.3.28 or later (required!)
- Node.js 18+ (for building from source)
Check your OpenClaw version:
openclaw --version
# Should output: OpenClaw 2026.3.28 or higherIf you have an older version, upgrade first:
npm install -g openclaw@latestInstall from Source
# Clone repository
git clone https://github.com/LiboShen/openclaw-acp-channel.git
cd openclaw-acp-channel
# Install dependencies
npm install
# Build
npm run build
# Install plugin
openclaw plugins install .Configuration
Add to your OpenClaw config file (~/.openclaw/openclaw.json or your OPENCLAW_CONFIG_PATH):
{
"plugins": {
"allow": ["acp-channel"],
"entries": {
"acp-channel": {
"enabled": true
}
}
},
"channels": {
"acp-channel": {
"enabled": true,
"allowFrom": ["*"]
}
}
}Configuration Options
- apiToken (optional): Bearer token for bridge ↔ plugin authentication. Not needed for localhost-only usage since the webhook is only accessible on 127.0.0.1.
- bridgeUrl (optional): fallback reply URL. In normal operation the bridge sends a per-request dynamic
bridgeUrl, which overrides this value. - allowFrom (optional): User ID allowlist (default:
["*"]- open to all)
Security Notes
For localhost bridges (default):
- apiToken: Not required — the webhook is bound to loopback (127.0.0.1) so only local processes can reach it
- allowFrom: Use
["*"](open) since only localhost can reach the webhook - Add
apiTokenonly if exposing webhook publicly or needing extra auth layer
Usage
1. Start OpenClaw Gateway
openclaw gatewayThe webhook will be available at: http://localhost:18789/acp-channel/webhook
2. Run the ACP Bridge
node dist/bridge.jsThe bridge speaks ACP JSON-RPC over STDIO.
3. Send ACP JSON-RPC
Example initialize:
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{},"clientInfo":{"name":"client","version":"0.1.0"}}}Example session/new:
{"jsonrpc":"2.0","id":2,"method":"session/new","params":{"cwd":"/tmp","mcpServers":[]}}Example session/prompt:
{"jsonrpc":"2.0","id":3,"method":"session/prompt","params":{"sessionId":"<session-id>","prompt":[{"type":"text","text":"Hello"}]}}The bridge emits session/update notifications and returns a session/prompt result with stopReason.
See src/bridge.ts for the reference implementation and test/acp-jsonrpc-e2e.mjs for a working end-to-end example.
Development
Build
npm install
npm run buildTest
npm test
npm run test:acp
OPENCLAW_WEBHOOK_URL=http://127.0.0.1:18789/acp-channel/webhook npm run test:acp:toolsProject Structure
openclaw-acp-channel/
├── src/
│ ├── index.ts # Plugin entry point
│ ├── channel.ts # Channel implementation
│ ├── bridge.ts # Bridge reference implementation
│ └── types.ts # TypeScript types
├── dist/ # Compiled JavaScript
├── openclaw.plugin.json # Plugin manifest
├── package.json
└── tsconfig.jsonHow It Works
- Client app sends ACP JSON-RPC via STDIO to bridge
- Bridge handles
initialize/session/*methods - Bridge POSTs prompt text to OpenClaw webhook with Bearer token
- Plugin receives message, validates token, dispatches into OpenClaw
- OpenClaw agent processes message and generates response
- Plugin POSTs reply to the bridge callback URL
- Bridge emits ACP
session/updateand resolvessession/prompt
License
MIT
