Run the Agent Client Protocol (ACP) bridge that talks to an Apus Gateway.

apus acp speaks ACP over stdio for IDEs and forwards prompts to the Gateway over WebSocket, keeping ACP sessions mapped to Gateway session keys. It is a Gateway-backed ACP bridge, not a full ACP-native editor runtime: it focuses on session routing, prompt delivery, and streaming updates.

If you want an external MCP client to talk directly to Apus channel conversations instead of hosting an ACP harness session, use apus mcp serve instead.

What this is not

apus acp means Apus acts as an ACP server: an IDE or ACP client connects to Apus, and Apus forwards that work into a Gateway session.

This is different from ACP Agents, where Apus runs an external harness such as Codex or Claude Code through acpx.

Quick rule:

Compatibility matrix

ACP area Status Notes
initialize, newSession, prompt, cancel Implemented Core bridge flow over stdio to Gateway chat/send + abort.
listSessions, slash commands Implemented Session list works against Gateway session state with bounded cursor pagination and cwd filtering where Gateway session rows carry workspace metadata; commands are advertised via available_commands_update.
Session lineage metadata Implemented Session listings and session info snapshots include Apus parent and child lineage in _meta so ACP clients can render subagent graphs without private Gateway side channels.
resumeSession, closeSession Implemented Resume rebinds an ACP session to an existing Gateway session without replaying history. Close cancels active bridge work, resolves pending prompts as cancelled, and releases bridge session state.
loadSession Partial Rebinds the ACP session to a Gateway session key and replays ACP event-ledger history for bridge-created sessions. Older/no-ledger sessions fall back to stored user/assistant text.
Prompt content (text, embedded resource, images) Partial Text/resources flatten into chat input; images become Gateway attachments.
Session modes Partial session/set_mode is supported; the bridge exposes Gateway-backed session controls for thought level, tool verbosity, reasoning, usage detail, and elevated actions. Broader ACP-native mode/config surfaces are still out of scope.
Thought streaming Implemented Model thinking content streams as agent_thought_chunk session updates. ACP-native session plans are not emitted.
Session info and usage updates Partial The bridge emits session_info_update and best-effort usage_update notifications from cached Gateway session snapshots. Usage is approximate and only sent when Gateway token totals are marked fresh.
Tool streaming Partial tool_call/tool_call_update events include raw I/O, text content, and best-effort file locations when Gateway tool args/results expose them. Embedded terminals and richer diff-native output are not exposed.
Exec approvals Partial Gateway exec approval prompts during active ACP prompt turns relay to the ACP client with session/request_permission.
Per-session MCP servers (mcpServers) Unsupported Bridge mode rejects per-session MCP server requests. Configure MCP on the Apus Gateway or agent instead.
Client filesystem methods (fs/read_text_file, fs/write_text_file) Unsupported The bridge does not call ACP client filesystem methods.
Client terminal methods (terminal/*) Unsupported The bridge does not create ACP client terminals or stream terminal ids through tool calls.

Known limitations

Usage

apus acp

# Remote Gateway
apus acp --url wss://gateway-host:18789 --token <token>

# Remote Gateway (token from file)
apus acp --url wss://gateway-host:18789 --token-file ~/.apus/gateway.token

# Attach to an existing session key
apus acp --session agent:main:main

# Attach by label (must already exist)
apus acp --session-label "support inbox"

# Reset the session key before the first prompt
apus acp --session agent:main:main --reset-session

ACP client (debug)

Use the built-in ACP client to sanity-check the bridge without an IDE. It spawns the ACP bridge and lets you type prompts interactively.

After a session is established, an unexpected server signal exit makes the client exit with status 1. An explicit exit or quit remains successful when it stops the server by signal. Numeric server exit codes are propagated, including a nonzero code returned during an explicit quit. Closing interactive input, including Ctrl-D at an empty prompt, uses the same client-owned shutdown path; it does not wait for an in-flight response to finish.

apus acp client

# Point the spawned bridge at a remote Gateway
apus acp client --server-args --url wss://gateway-host:18789 --token-file ~/.apus/gateway.token

# Override the server command (default: apus)
apus acp client --server "node" --server-args apus.mjs acp --url ws://127.0.0.1:19001

Permission model (client debug mode):

Protocol smoke testing

For protocol-level debugging, start a Gateway with isolated state and drive apus acp over stdio with an ACP JSON-RPC client. Cover initialize, session/new, session/list with an absolute cwd, session/resume, session/close, duplicate close, and missing resume.

The proof should include the advertised lifecycle capabilities, a Gateway-backed session row, update notifications, and the Gateway sessions.list log:

{
  "initialize": {
    "protocolVersion": 1,
    "agentCapabilities": {
      "sessionCapabilities": {
        "list": {},
        "resume": {},
        "close": {}
      }
    }
  },
  "listSessions": {
    "sessions": [
      {
        "sessionId": "agent:main:acp-smoke",
        "cwd": "/path/to/workspace",
        "_meta": {
          "sessionKey": "agent:main:acp-smoke",
          "kind": "direct"
        }
      }
    ],
    "nextCursor": null
  },
  "notifications": ["session_info_update", "available_commands_update", "usage_update"],
  "gatewayLogTail": ["[gateway] ready", "[ws] ⇄ res ✓ sessions.list 305ms"]
}

Avoid using apus gateway call sessions.list as the only ACP proof. That CLI path may request a fresh-token operator scope upgrade; ACP bridge correctness is proven by ACP stdio frames plus the Gateway sessions.list log.

How to use this

Use ACP when an IDE (or other client) speaks Agent Client Protocol and you want it to drive an Apus Gateway session.

  1. Ensure the Gateway is running (local or remote).
  2. Configure the Gateway target (config or flags).
  3. Point your IDE to run apus acp over stdio.

Example config (persisted):

apus config set gateway.remote.url wss://gateway-host:18789
apus config set gateway.remote.token <token>

Example direct run (no config write):

apus acp --url wss://gateway-host:18789 --token <token>
# preferred for local process safety
apus acp --url wss://gateway-host:18789 --token-file ~/.apus/gateway.token

Selecting agents

ACP does not pick agents directly. It routes by the Gateway session key. Use agent-scoped session keys to target a specific agent:

apus acp --session agent:main:main
apus acp --session agent:design:main
apus acp --session agent:qa:bug-123

Each ACP session maps to a single Gateway session key. One agent can have many sessions; ACP defaults to an isolated acp-bridge:<uuid> session unless you override the key or label.

Per-session mcpServers are not supported in bridge mode. If an ACP client sends them during newSession or loadSession, the bridge returns a clear error instead of silently ignoring them.

If you want ACPX-backed sessions to see Apus plugin tools or selected built-in tools such as cron, enable the gateway-side ACPX MCP bridges instead of trying to pass per-session mcpServers. See ACP Agents and Apus tools MCP bridge.

Use from acpx (Codex, Claude, other ACP clients)

If you want a coding agent such as Codex or Claude Code to talk to your Apus bot over ACP, use acpx with its built-in apus target.

acpx here is the separate acpx CLI from npm, installed on the machine that runs the coding agent. It is not the same thing as the @openclaw/acpx Apus plugin described in ACP Agents, which embeds the ACP runtime in the Gateway and installs no acpx binary.

Typical flow:

  1. Install the acpx CLI on the coding agent's machine and run the Gateway, making sure the ACP bridge can reach it.
  2. Point acpx apus at apus acp.
  3. Target the Apus session key you want the coding agent to use.

Examples:

# One-shot request into your default Apus ACP session
acpx apus exec "Summarize the active Apus session state."

# Persistent named session for follow-up turns
acpx apus sessions ensure --name codex-bridge
acpx apus -s codex-bridge --cwd /path/to/repo \
  "Ask my Apus work agent for recent context relevant to this repo."

If you want acpx apus to target a specific Gateway and session key every time, override the apus agent command in ~/.acpx/config.json:

{
  "agents": {
    "apus": {
      "command": "env APUS_HIDE_BANNER=1 APUS_SUPPRESS_NOTES=1 apus acp --url ws://127.0.0.1:18789 --token-file ~/.apus/gateway.token --session agent:main:main"
    }
  }
}

For a repo-local Apus checkout, use the direct CLI entrypoint instead of the dev runner so the ACP stream stays clean:

env APUS_HIDE_BANNER=1 APUS_SUPPRESS_NOTES=1 node apus.mjs acp ...

This is the easiest way to let Codex, Claude Code, or another ACP-aware client pull contextual information from an Apus agent without scraping a terminal.

Zed editor setup

Add a custom ACP agent in ~/.config/zed/settings.json (or use Zed's Settings UI):

{
  "agent_servers": {
    "Apus ACP": {
      "type": "custom",
      "command": "apus",
      "args": ["acp"],
      "env": {}
    }
  }
}

To target a specific Gateway or agent:

{
  "agent_servers": {
    "Apus ACP": {
      "type": "custom",
      "command": "apus",
      "args": [
        "acp",
        "--url",
        "wss://gateway-host:18789",
        "--token",
        "<token>",
        "--session",
        "agent:design:main"
      ],
      "env": {}
    }
  }
}

In Zed, open the Agent panel and select "Apus ACP" to start a thread.

Session mapping

By default, ACP bridge sessions get an isolated Gateway session key with an acp-bridge: prefix. These normal-model bridge sessions are synthetic and disposable: they are subject to stale-entry pruning and are not treated as protected human conversation surfaces. To reuse a known session, pass a session key or label:

If your ACP client supports metadata, you can override per session:

{
  "_meta": {
    "sessionKey": "agent:main:main",
    "sessionLabel": "support inbox",
    "resetSession": true
  }
}

Learn more about session keys at /concepts/session.

Options

Security note:

acp client options

Related