17 KiB
API Interface Reference
This document organizes the current API surface of xworkmate-bridge based on the actual code paths in this repository.
It focuses on:
- the ACP Bridge exposed by
xworkmate-go-core serve - the Gemini ACP adapter exposed by
xworkmate-go-core gemini-acp-adapter - auxiliary HTTP handlers that exist in code but are not currently mounted by
main.go
1. Runtime Entry Points
The binary currently exposes these runtime modes:
./build/bin/xworkmate-go-core serve
./build/bin/xworkmate-go-core acp-stdio
./build/bin/xworkmate-go-core gemini-acp-adapter
Relevant source:
2. ACP Bridge HTTP / WebSocket API
Canonical APP-facing public origin:
https://xworkmate-bridge.svc.plus
Canonical APP-facing ACP paths:
POST /acp/rpcGET /acpfor WebSocket ACP
Independent upstream ACP and gateway services may exist behind the bridge, but they are not the primary APP contract.
2.1 Default listen address
serve mode reads:
ACP_LISTEN_ADDR, default127.0.0.1:8787
2.2 Exposed routes
When running xworkmate-go-core serve, only these two routes are mounted:
| Path | Protocol | Purpose |
|---|---|---|
/acp/rpc |
HTTP POST | JSON-RPC entrypoint |
/acp |
WebSocket | ACP over WebSocket |
Any other path returns 404.
2.3 Auth and CORS
Bridge auth is bearer-token based:
- Environment variable:
ACP_AUTH_TOKEN - Required header:
Authorization: Bearer <token>
Origin allowlist comes from:
ACP_ALLOWED_ORIGINS- default:
https://xworkmate.svc.plus,http://localhost:*,http://127.0.0.1:*
Behavior summary:
- missing or invalid bearer token: HTTP
401, JSON-RPC error code-32001 - disallowed origin: HTTP
403, JSON-RPC error code-32003 OPTIONS /acp/rpcis supported for CORS preflight
Relevant source:
2.4 Content negotiation
For POST /acp/rpc:
- normal JSON-RPC response:
Content-Type: application/json - if
Acceptcontainstext/event-stream, the server streams notifications as SSE and sends the final JSON-RPC result through SSE as well
2.5 JSON-RPC methods exposed by the bridge
The bridge currently handles these methods:
| Method | Description |
|---|---|
acp.capabilities |
Return current bridge capability summary |
session.start |
Start a task session |
session.message |
Continue an existing session |
session.cancel |
Cancel an active session |
session.close |
Close session state |
xworkmate.dispatch.resolve |
Resolve provider choice from candidate providers and requirements |
xworkmate.routing.resolve |
Resolve execution target / provider / skills from routing metadata |
xworkmate.mounts.reconcile |
Reconcile managed MCP configuration and mount-related settings |
xworkmate.gateway.connect |
Connect bridge runtime to gateway |
xworkmate.gateway.request |
Send a request to the connected gateway runtime |
xworkmate.gateway.disconnect |
Disconnect gateway runtime |
Unknown methods return JSON-RPC error code -32601.
3. Bridge Method Details
3.1 acp.capabilities
Request:
{
"jsonrpc": "2.0",
"id": "cap-1",
"method": "acp.capabilities"
}
Response shape:
{
"jsonrpc": "2.0",
"id": "cap-1",
"result": {
"singleAgent": true,
"multiAgent": true,
"providerCatalog": [
{ "providerId": "codex", "label": "Codex" },
{ "providerId": "opencode", "label": "OpenCode" },
{ "providerId": "gemini", "label": "Gemini" }
],
"gatewayProviders": [
{ "providerId": "local", "label": "Local" },
{ "providerId": "openclaw", "label": "OpenClaw" }
],
"capabilities": {
"single_agent": true,
"multi_agent": true,
"providerCatalog": [
{ "providerId": "codex", "label": "Codex" },
{ "providerId": "opencode", "label": "OpenCode" },
{ "providerId": "gemini", "label": "Gemini" }
],
"gatewayProviders": [
{ "providerId": "local", "label": "Local" },
{ "providerId": "openclaw", "label": "OpenClaw" }
]
}
}
}
Notes:
providerCatalogis bridge-owned and built in at startupgatewayProvidersis the APP-facing gateway provider catalog- production upstream routing map is fixed to:
codex->https://acp-server.svc.plus/codex/acp/rpcopencode->https://acp-server.svc.plus/opencode/acp/rpcgemini->https://acp-server.svc.plus/gemini/acp/rpc
- APP traffic reaches those upstreams through the bridge's canonical public ACP path, not by depending on upstream URLs directly
- upstream ACP auth uses
Authorization: Bearer $INTERNAL_SERVICE_TOKEN multiAgentis controlled byACP_MULTI_AGENT_ENABLED, defaulttrue
3.2 session.start
Starts a session and resets any existing state with the same sessionId.
Minimum required params:
{
"sessionId": "session-1"
}
Typical request:
{
"jsonrpc": "2.0",
"id": "task-1",
"method": "session.start",
"params": {
"sessionId": "session-1",
"threadId": "thread-1",
"taskPrompt": "Reply with exactly pong",
"workingDirectory": "/tmp/demo",
"routing": {
"routingMode": "explicit",
"explicitExecutionTarget": "singleAgent",
"explicitProviderId": "opencode"
}
}
}
Rules:
sessionIdis required, otherwise-32602threadIddefaults tosessionId- work is queued per
threadId - for public single-agent multi-turn usage,
routingshould be resent on later turns
3.3 session.message
Continues an existing session.
Minimum required params:
{
"sessionId": "session-1"
}
Typical request:
{
"jsonrpc": "2.0",
"id": "task-2",
"method": "session.message",
"params": {
"sessionId": "session-1",
"threadId": "thread-1",
"taskPrompt": "Continue the previous task",
"workingDirectory": "/tmp/demo",
"routing": {
"routingMode": "explicit",
"explicitExecutionTarget": "singleAgent",
"explicitProviderId": "opencode"
}
}
}
3.4 session.cancel
Request:
{
"jsonrpc": "2.0",
"id": "cancel-1",
"method": "session.cancel",
"params": {
"sessionId": "session-1"
}
}
Response:
{
"accepted": true,
"cancelled": true
}
Notes:
acceptedindicates the request envelope was acceptedcancelledistrueonly when an active session was actually cancelled- if the session does not exist or is already finished,
cancelledmay befalse
3.5 session.close
Request:
{
"jsonrpc": "2.0",
"id": "close-1",
"method": "session.close",
"params": {
"sessionId": "session-1"
}
}
Response:
{
"accepted": true,
"closed": true
}
Notes:
acceptedindicates the request envelope was acceptedclosedistrueonly when an existing session state was actually closed- if the session does not exist or is already gone,
closedmay befalse
3.6 xworkmate.dispatch.resolve
Purpose:
- choose a provider from a list of candidates
- apply preferred provider and capability constraints
- optionally consider node state and node info
Key params:
providers: array of provider definitionspreferredProviderIdrequiredCapabilitiesnodeStatenodeInfo
Provider item shape:
{
"id": "codex",
"name": "Codex",
"defaultArgs": ["app-server"],
"capabilities": ["singleAgent", "tools"]
}
3.7 xworkmate.routing.resolve
Purpose:
- resolve routing metadata into:
- execution target
- provider
- gateway provider
- model
- selected skills
- install suggestion / unavailable state
Canonical use:
- apps should use this method as the single preflight source for:
- effective execution target
- effective provider selection
- unavailable code / message
- apps should not re-derive provider availability or
autoresolution fromacp.capabilities
Key input fields:
taskPromptworkingDirectoryrouting.routingModerouting.preferredGatewayProviderIdrouting.explicitExecutionTargetrouting.explicitProviderIdrouting.explicitModelrouting.explicitSkillsrouting.allowSkillInstallrouting.installApprovalrouting.availableSkillsaiGatewayBaseUrlaiGatewayApiKey
Representative response fields:
resolvedExecutionTargetresolvedProviderIdresolvedGatewayProviderIdresolvedModelresolvedSkillsskillResolutionSourceneedsSkillInstallunavailableunavailableCodeunavailableMessageskillInstallRequestIdskillCandidatesmemorySources
APP-facing interpretation:
- if
resolvedExecutionTarget = single-agent, useresolvedProviderId - if
resolvedExecutionTarget = gateway, useresolvedGatewayProviderId
3.7.1 UI / APP consumption model
Recommended APP-side flow:
- Call
acp.capabilitiesat startup or refresh time. - Read:
providerCatalogassingleAgentProvidersgatewayProvidersasgatewayProviders
- Before execution, call
xworkmate.routing.resolve. - Use the resolved fields, not local heuristics, to decide which UI state and execution branch to use.
- Send
session.startorsession.messagethrough the bridge canonical path.
Suggested APP-side view model:
{
"executionTargets": ["single-agent", "multi-agent", "gateway"],
"singleAgentProviders": ["codex", "opencode", "gemini"],
"gatewayProviders": ["local", "openclaw"]
}
Recommended interpretation rules:
- if
resolvedExecutionTarget = single-agent- read
resolvedProviderId - ignore
resolvedGatewayProviderId
- read
- if
resolvedExecutionTarget = multi-agent- treat the run as bridge-orchestrated multi-agent execution
- do not force a single provider picker as the primary routing control
- if
resolvedExecutionTarget = gateway- read
resolvedGatewayProviderId - ignore
resolvedProviderId
- read
UI binding guidance:
- provider picker for single-agent mode should be populated from
providerCatalog - gateway picker should be populated from
gatewayProviders - gateway UI should display
localandopenclawas selectable providers - disabled or unavailable states should come from
xworkmate.routing.resolveresponse fields such as:unavailableunavailableCodeunavailableMessage
Do not:
- infer provider availability from hardcoded lists
- treat
openclawas a single-agent provider - re-derive auto-routing from prompt text on the APP side
- use upstream URLs as the APP-facing contract
3.8 xworkmate.mounts.reconcile
Purpose:
- reconcile managed MCP server config for supported local tools and homes
Key params:
config.autoSyncconfig.usesArisconfig.managedMcpServersaiGatewayUrlconfiguredCodexCliPathcodexHomeopencodeHomeopenclawHomearis
Managed MCP server item shape:
{
"id": "xworkmate_server",
"command": "xworkmate-mcp",
"args": ["--port", "7777"],
"enabled": true
}
3.9 Gateway runtime methods
xworkmate.gateway.connect
Purpose:
- connect a bridge runtime session to the bridge-owned production gateway route
- from the APP perspective this still enters through the canonical bridge ACP
path and bridge JSON-RPC methods, not a direct
openclawURL contract
Key params:
runtimeIdgatewayProviderIdclientIdlocaleuserAgentconnectAuthModeconnectAuthFieldsconnectAuthSourceshasSharedAuthhasDeviceTokenendpoint.hostendpoint.portendpoint.tlspackageInfodeviceInfoidentityauth
Response fields:
oksnapshotauthreturnedDeviceTokenerror
Notes:
- for
gatewayProviderId=openclaw, the bridge overrides runtime endpoint selection towss://openclaw.svc.plus - for
gatewayProviderId=local, the bridge keeps the caller-provided local gateway endpoint configuration - upstream gateway auth uses
Authorization: Bearer $INTERNAL_SERVICE_TOKEN - the app does not provide production openclaw endpoint truth
xworkmate.gateway.request
Purpose:
- send a gateway runtime RPC-like request through an existing runtime connection
Params:
runtimeIdmethodparamstimeoutMs
Response fields:
okpayloaderror
xworkmate.gateway.disconnect
Params:
runtimeId
Response:
{
"accepted": true
}
4. WebSocket Contract
/acp accepts the same JSON-RPC method set as /acp/rpc.
Differences from HTTP:
- each inbound message is a JSON-RPC request frame
- notifications are written back as WebSocket JSON messages
- result envelopes and error envelopes are also written as WebSocket JSON messages
Observed bridge behavior on the public deployment:
- authenticated plain
GET /acpwithout WebSocket upgrade headers returns HTTP400 Bad Request - authenticated
GET /acpwith valid WebSocket upgrade headers returns HTTP101 Switching Protocols
5. Gemini ACP Adapter API
5.1 Default listen address
gemini-acp-adapter reads:
GEMINI_ADAPTER_LISTEN_ADDR, default127.0.0.1:8791
5.2 Exposed routes
When running xworkmate-go-core gemini-acp-adapter, only these routes are mounted:
| Path | Protocol | Purpose |
|---|---|---|
/acp/rpc |
HTTP POST | Adapter JSON-RPC entrypoint |
/acp |
WebSocket | Adapter WebSocket JSON-RPC entrypoint |
5.3 Auth and CORS
Adapter auth is separate from bridge auth:
- Environment variable:
GEMINI_ADAPTER_AUTH_TOKEN - Required header:
Authorization: Bearer <token>
Allowed origins come from:
GEMINI_ADAPTER_ALLOWED_ORIGINS- default:
https://xworkmate.svc.plus,http://localhost:*,http://127.0.0.1:*
5.4 Adapter JSON-RPC methods
| Method | Description |
|---|---|
acp.capabilities |
Synthesized Gemini single-agent capability response |
session.start |
Start adapter-local Gemini session |
session.message |
Continue adapter-local Gemini session |
session.cancel |
Accept cancel request, currently returns cancelled: false |
session.close |
Close adapter-local session |
gemini.initialize |
Return upstream initialize result |
gemini.raw |
Forward raw Gemini-facing payload handling |
Unsupported methods return:
{
"success": false,
"error": "unsupported method: <method>"
}
5.5 Core adapter env vars
GEMINI_ADAPTER_LISTEN_ADDRGEMINI_ADAPTER_BINGEMINI_ADAPTER_ARGSGEMINI_ADAPTER_PROTOCOL_VERSIONGEMINI_ADAPTER_AUTH_TOKENGEMINI_ADAPTER_PROVIDER_IDGEMINI_ADAPTER_PROVIDER_LABELGEMINI_ADAPTER_ALLOWED_ORIGINSGEMINI_ADAPTER_UPSTREAM_METHODACP_GEMINI_BIN
6. Auxiliary HTTP Handlers Present in Code
The repository also contains two plain HTTP handlers:
These handlers are currently not mounted by main.go, so they are not part of the live binary HTTP routing surface unless another embedding program wires them in.
6.1 Username/password auth handler
Request body:
{
"username": "demo",
"password": "secret"
}
Behavior:
- invalid JSON ->
400 invalid json - auth failure ->
401 <error message> - success ->
200 {"status":"ok"}
6.2 Bearer token auth handler
Behavior:
- no service ->
503 service unavailable - invalid bearer token ->
401 unauthorized - success ->
200 {"ok":true}
7. Public Deployment Notes
Existing project docs already record the current public ingress convention:
- Bridge-facing public ACP HTTP JSON-RPC path:
.../acp/rpc - WebSocket ACP path:
.../acp
Reference docs:
- docs/acp-public-validation-2026-04-09.md
- docs/gemini-acp-adapter.md
- docs/architecture/acp-forwarding-topology.md
8. Suggested Maintenance Rule
If a new externally callable method is added to:
then this document should be updated in the same change.