acp-cli
Headless CLI client for the Agent Client Protocol (ACP). Talk to coding agents (Claude, Codex, Gemini, etc.) over structured JSON-RPC instead of terminal scraping.
Rust port of ACPX.
Release Highlights (v0.2.2)
- ACP bridge shutdown now always reaps child processes to avoid zombie accumulation.
- Cleanup now also runs on early initialization/session setup failures.
- Bridge cleanup tests expanded with initialization-failure coverage and cross-platform command usage.
Install
Quick Start
# 1. Setup (detect auth, write config)
# 2. Talk to Claude
Usage
# Prompt (persistent session)
# One-shot (no session persistence)
# Read prompt from file
# Pipe from stdin
|
# Different agents
# Named sessions for parallel work
# Output formats
# Timeout
Commands
Flags
| Flag | Default | Description |
|---|---|---|
-s, --session <name> |
Named session | |
--approve-all |
Auto-approve all tool calls | |
--approve-reads |
default | Approve read-only tools, deny writes |
--deny-all |
Deny all tool calls | |
--cwd <dir> |
. |
Working directory |
--format text|json|quiet |
text |
Output format |
--timeout <seconds> |
Max wait time | |
-f, --file <path> |
Read prompt from file (- for stdin) |
|
--no-wait |
Fire-and-forget (queue and return) | |
--agent-override <cmd> |
Raw ACP command override |
Config
Run acp-cli init or create ~/.acp-cli/config.json manually:
Project-level config: .acp-cli.json in git root (same format, overrides global).
Auth Token Resolution
Token for Claude is resolved in order:
ANTHROPIC_AUTH_TOKENenvironment variable~/.acp-cli/config.json→auth_token~/.claude.json→oauthAccount.accessToken- macOS Keychain (
Claude Codeservice)
Note: OAuth tokens (sk-ant-oat01-*) are detected but not injected via env var — the Claude Agent SDK resolves them from Keychain internally using the correct auth flow.
Supported Agents
| Agent | Command | Type |
|---|---|---|
| claude | npx @zed-industries/claude-agent-acp |
npm |
| codex | npx @zed-industries/codex-acp |
npm |
| gemini | gemini --acp |
native |
| copilot | copilot --acp --stdio |
native |
| cursor | cursor-agent acp |
native |
| goose | goose acp |
native |
| kiro | kiro-cli acp |
native |
| pi | npx pi-acp |
npm |
| openclaw | openclaw acp |
native |
| opencode | npx opencode-ai acp |
npm |
| kilocode | npx @kilocode/cli acp |
npm |
| kimi | kimi acp |
native |
| qwen | qwen --acp |
native |
| droid | droid exec --output-format acp |
native |
Unknown agent names are treated as raw commands.
Sessions
Sessions auto-resume by matching (agent, git_root, session_name).
The first acp-cli process for a session becomes the queue owner (holds the agent connection). Subsequent processes connect as queue clients via Unix socket.
Architecture
Main thread (Send) ACP thread (!Send, LocalSet)
├── CLI parsing ├── AcpConnection (spawn_local)
├── Output rendering ├── ClientSideConnection I/O
├── Permission resolution └── BridgedAcpClient callbacks
├── Signal handling
└── Queue IPC server Channel bridge (mpsc + oneshot)
Library Usage
acp-cli can be used as a Rust library:
use AcpBridge;
use PathBuf;
let bridge = start.await?;
let result = bridge.prompt.await?;
bridge.shutdown.await?;
License
MIT