acpx
Your agents love acpx! 🤖❤️ They hate having to scrape characters from a PTY session 😤
acpx is a headless CLI client for the Agent Client Protocol (ACP), so AI agents and orchestrators can talk to coding agents over a structured protocol instead of PTY scraping.
One command surface for Codex, Claude, Gemini, OpenCode, Pi, or custom ACP servers. Built for agent-to-agent communication over the command line.
- Persistent sessions: multi-turn conversations that survive across invocations, scoped per repo
- Named sessions: run parallel workstreams in the same repo (
-s backend,-s frontend) - Prompt queueing: submit prompts while one is already running, they execute in order
- Cooperative cancel command:
cancelsends ACPsession/cancelvia queue IPC without tearing down session state - Soft-close lifecycle: close sessions without deleting history from disk
- Queue owner TTL: keep queue owners alive briefly for follow-up prompts (
--ttl) - Fire-and-forget:
--no-waitqueues a prompt and returns immediately - Graceful cancel:
Ctrl+Csends ACPsession/cancelbefore force-kill fallback - Session controls:
set-modeandset <key> <value>forsession/set_modeandsession/set_config_option - Crash reconnect: dead agent processes are detected and sessions are reloaded automatically
- Prompt from file/stdin:
--file <path>or piped stdin for prompt content - Config files: global + project JSON config with
acpx config show|init - Session inspect/history:
sessions showandsessions history --limit <n> - Local status checks:
statusreports running/dead/no-session, pid, uptime, last prompt - Client methods: stable
fs/*andterminal/*handlers with permission controls and cwd sandboxing - Auth handshake: stable
authenticatesupport via env/config credentials - Structured output: typed ACP messages (thinking, tool calls, diffs) instead of ANSI scraping
- Any ACP agent: built-in registry +
--agentescape hatch for custom servers - One-shot mode:
execfor stateless fire-and-forget tasks
$ acpx codex sessions new $ acpx codex "find the flaky test and fix it" [thinking] Investigating test suite for flaky failures [tool] Run npm test -- --reporter=verbose (running) [tool] Run npm test -- --reporter=verbose (completed) output: ✓ auth.login (0.8s) ✗ checkout.submit (timed out after 5000ms) ✓ cart.add (0.3s) [thinking] Found it — checkout.submit has a race condition in the async setup [tool] Edit src/checkout.test.ts (completed) output: Success. Updated 1 file. [tool] Run npm test -- checkout.submit (completed) output: ✓ checkout.submit (0.4s) Fixed: added `await` to the setup hook in checkout.submit. The test was reading stale state from the previous run. [done] end_turn
Quick setup — tell your agent about acpx
Copy the block below and paste it into your OpenClaw, Pi, Claude Code, or similar agent harness. It will install acpx, read the skill reference, and know how to use ACP for all future coding agent tasks.
I want you to use acpx to run coding agents over the Agent Client Protocol
(ACP) instead of scraping PTY sessions. Please do the following:
1. Install acpx globally (recommended) or use npx:
npm install -g acpx@latest
Or without installing:
npx acpx@latest
2. Install the acpx skill so you have the full reference available:
npx acpx@latest --skill install acpx
3. Read the acpx skill reference so you know every command, flag, and
workflow pattern:
https://raw.githubusercontent.com/janitrai/acpx/main/skills/acpx/SKILL.md
4. If you need the full CLI reference with all options and examples:
https://raw.githubusercontent.com/janitrai/acpx/main/docs/CLI.md
From now on, when you need to delegate work to a coding agent, use acpx
instead of spawning raw terminal sessions. For example:
npx acpx@latest codex "fix the failing tests"
npx acpx@latest claude "refactor the auth module"
npx acpx@latest codex exec "one-shot: summarize this repo"
Install
npm install -g acpx@latest
Or run without installing:
npx acpx@latest codex "fix the tests"Session state lives in ~/.acpx/ either way. Global install is a little faster, but npx acpx@latest works fine.
Agent prerequisites
acpx auto-downloads ACP adapters with npx on first use. You do not need to install adapter packages manually.
The only prerequisite is the underlying coding agent you want to use:
acpx codex-> Codex CLI: https://codex.openai.comacpx claude-> Claude Code: https://claude.ai/codeacpx gemini-> Gemini CLI: https://github.com/google/gemini-cliacpx opencode-> OpenCode: https://opencode.aiacpx pi-> Pi Coding Agent: https://github.com/mariozechner/pi
Usage examples
acpx codex sessions new # create a session (explicit) for this project dir acpx codex 'fix the tests' # implicit prompt (routes via directory-walk) acpx codex prompt 'fix the tests' # explicit prompt subcommand echo 'fix flaky tests' | acpx codex # prompt from stdin acpx codex --file prompt.md # prompt from file acpx codex --file - "extra context" # explicit stdin + appended args acpx codex --no-wait 'draft test migration plan' # enqueue without waiting if session is busy acpx codex cancel # cooperative cancel of in-flight prompt acpx codex set-mode plan # session/set_mode acpx codex set approval_policy conservative # session/set_config_option acpx exec 'summarize this repo' # default agent shortcut (codex) acpx codex exec 'what does this repo do?' # one-shot, no saved session acpx codex sessions new --name api # create named session acpx codex -s api 'implement cursor pagination' # prompt in named session acpx codex sessions new --name docs # create another named session acpx codex -s docs 'rewrite API docs' # parallel work in another named session acpx codex sessions # list sessions for codex command acpx codex sessions list # explicit list acpx codex sessions show # inspect cwd session metadata acpx codex sessions history # show recent turn history acpx codex sessions new # create fresh cwd-scoped default session acpx codex sessions new --name api # create fresh named session acpx codex sessions close # close cwd-scoped default session acpx codex sessions close api # close cwd-scoped named session acpx codex status # local process status for current session acpx config show # show resolved config (global + project) acpx config init # create ~/.acpx/config.json template acpx claude 'refactor auth middleware' # built-in claude agent acpx gemini 'add startup logging' # built-in gemini agent acpx my-agent 'review this patch' # unknown name -> raw command acpx --agent './bin/dev-acp --profile ci' 'run checks' # --agent escape hatch
Practical scenarios
# Review a PR in a dedicated session and auto-approve permissions acpx --cwd ~/repos/shop --approve-all codex -s pr-842 \ 'Review PR #842 for regressions and propose a minimal fix' # Keep parallel streams for the same repo acpx codex -s bugfix 'isolate flaky checkout test' acpx codex -s release 'draft release notes from recent commits'
Global options in practice
acpx --approve-all codex 'apply the patch and run tests' acpx --approve-reads codex 'inspect repo structure and suggest plan' # default mode acpx --deny-all codex 'explain what you can do without tool access' acpx --cwd ~/repos/backend codex 'review recent auth changes' acpx --format text codex 'summarize your findings' acpx --format json codex exec 'review changed files' acpx --format quiet codex 'final recommendation only' acpx --timeout 90 codex 'investigate intermittent test timeout' acpx --ttl 30 codex 'keep queue owner alive for quick follow-ups' acpx --verbose codex 'debug why adapter startup is failing'
Configuration files
acpx reads config in this order (later wins):
- global:
~/.acpx/config.json - project:
<cwd>/.acpxrc.json
CLI flags always win over config values.
Supported keys:
{
"defaultAgent": "codex",
"defaultPermissions": "approve-all",
"ttl": 300,
"timeout": null,
"format": "text",
"agents": {
"my-custom": { "command": "./bin/my-acp-server" }
},
"auth": {
"my_auth_method_id": "credential-value"
}
}Use acpx config show to inspect the resolved result and acpx config init to create the global template.
Output formats
# text (default): human-readable stream with tool updates acpx codex 'review this PR' # json: NDJSON events, useful for automation acpx --format json codex exec 'review this PR' \ | jq -r 'select(.type=="tool_call") | [.status, .title] | @tsv' # quiet: final assistant text only acpx --format quiet codex 'give me a 3-line summary'
Built-in agents and custom servers
Built-ins:
| Agent | Adapter | Wraps |
|---|---|---|
codex |
codex-acp | Codex CLI |
claude |
claude-agent-acp | Claude Code |
gemini |
native | Gemini CLI |
opencode |
native | OpenCode |
pi |
pi-acp | Pi Coding Agent |
Use --agent as an escape hatch for custom ACP servers:
acpx --agent ./my-custom-acp-server 'do something'Session behavior
- Prompt commands require an existing saved session record (created via
sessions new). - Prompts route by walking up from
cwd(or--cwd) to the nearest git root (inclusive) and selecting the nearest active session matching(agent command, dir, optional name). - If no git root is found, prompts only match an exact
cwdsession (no parent-directory walk). -s <name>selects a parallel named session during that directory walk.sessions new [--name <name>]creates a fresh session for that scope and soft-closes the prior one.sessions close [name]soft-closes the session: queue owner/processes are terminated, record is kept withclosed: true.- Auto-resume for cwd scope skips sessions marked closed.
- Prompt submissions are queue-aware per session. If a prompt is already running, new prompts are queued and drained by the running
acpxprocess. - Queue owners use an idle TTL (default 300s).
--ttl <seconds>overrides it;--ttl 0keeps owners alive indefinitely. --no-waitsubmits to that queue and returns immediately.cancelsends cooperativesession/cancelto the running queue owner process and returns success when no prompt is running (nothing to cancel).set-modeandsetroute through queue-owner IPC when active, otherwise they reconnect directly to applysession/set_modeandsession/set_config_option.execis always one-shot and does not reuse saved sessions.- Session metadata is stored under
~/.acpx/sessions/. - Each successful prompt appends lightweight turn history previews (
role,timestamp,textPreview) to session metadata. Ctrl+Cduring a running turn sends ACPsession/canceland waits briefly forstopReason=cancelledbefore force-killing if needed.- If a saved session pid is dead on the next prompt,
acpxrespawns the agent, attemptssession/load, and transparently falls back tosession/newif loading fails.
Full CLI reference
See docs/CLI.md.
License
MIT