Observed since 20 Oct, 18:22 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Thin Python CLI client for the Agent Client Protocol (ACP)
Thin Python CLI client for the Agent Client Protocol (ACP).
Status: alpha (v0.1). No persistent daemon yet, so every call pays a 3-10s cold start while the adapter boots. Fine for scripts and CI, painful for interactive loops. v0.2 will add a daemon. See Known limitations.
acpc is a headless Python CLI for ACP, built on top of the official agent-client-protocol SDK. Output is plain text with no ANSI escapes, so it composes cleanly with pipes, files, and other agents.
pip install acpc
# or
uv tool install acpc
Requires Python 3.12+.
# Send a prompt to Codex
acpc prompt codex "fix the tests"
# Use a model preset
acpc prompt claude "analyze this repo" --model fast
# Pipe a prompt from stdin
echo "explain the architecture" | acpc prompt codex -
# Read prompt from file, write output to file
acpc prompt codex --input-file task.md -o result.md
| Command | Description |
|---|---|
prompt <agent> [text] | Send a prompt to an ACP agent |
run <agent> [text] | Alias for prompt |
models [agent] | Show available models and presets |
agents | List registered agents and install status |
sessions <agent> | List agent sessions (via ACP) |
install <agent> | Run the agent's install command |
stop <agent> | Stop running sessions for an agent |
stop -s <id> | Stop a specific session by ID |
status | Show all running sessions |
generate-completion | Generate or install shell completions |
All options for the prompt command:
| Flag | Description | ACP mapping |
|---|---|---|
--last | Resume the last session | session/load |
-s, --session ID | Resume session by ID | session/load |
--model MODEL | Model ID or preset (fast/standard/max) | session/set_model |
--mode MODE | Set mode for the session | session/set_mode |
--permissions LEVEL | Permission policy (see below) | request_permission |
--cwd DIR | Working directory for the agent | session/new (cwd) |
--json | NDJSON output (ACP events) | local |
--quiet | Final text only (no streaming) | local |
-o, --output FILE | Write output to file | local |
--input-file FILE | Read prompt from file | local |
--timeout SECS | Timeout in seconds | local |
--dry-run | Resolve config and exit without running | local |
Instead of memorizing vendor-specific model IDs, use one of three tier names:
acpc prompt claude --model fast # cheapest, fastest
acpc prompt claude --model standard # default
acpc prompt codex --model max # most capable
Run acpc models to see what each preset resolves to for a given agent.
Presets live in ~/.agents/config.toml. If the file doesn't exist, built-in defaults are used:
[models.claude]
fast = "haiku"
standard = "sonnet"
max = "opus"
[models.codex]
fast = "..."
standard = "..."
max = "..."
Use --dry-run to verify what model will be used without running:
acpc prompt codex --model standard "task" --dry-run
acpc models # show presets and available models for all agents
acpc models claude # show for a specific agent
Available models are cached from ACP responses (TTL 7 days).
Each acpc prompt call refreshes the cache as a side effect, so it stays fresh without an extra round-trip.
If the cache is stale, acpc models <agent> fetches live from the adapter.
The --permissions flag controls how acpc responds to ACP permission requests.
Tool calls are classified by their kind field into three categories.
| Level | read-like | edit/execute | delete/move |
|---|---|---|---|
all | allow | allow | allow |
write | allow | allow | deny |
read | allow | deny | deny |
none | deny | deny | deny |
prompt | allow | ask user | ask user |
Read-like tool kinds: read, search, think, fetch, switch_mode, other.
Default: prompt when stdin is a TTY, read when piped (non-TTY).
In non-interactive contexts, denied operations cause exit code 3.
stdout carries agent output only. stderr carries [acpc]-prefixed diagnostics.
text (default): Agent text streams to stdout as it arrives.
Tool calls appear on stderr as [acpc] tool: edit:src/main.py.
acpc prompt codex "fix the bug" > fix.md
json: Every ACP session_update event passes through as NDJSON.
The stream is wrapped by session_started, session_ended, and session_error meta-events.
acpc prompt codex "fix the bug" --json | jq 'select(.sessionUpdate == "agent_message_chunk")'
quiet: Collects all text, emits only the final result when the session ends.
The -o flag writes to a file (not written on crash).
acpc prompt codex "summarize" --quiet -o summary.md
Every completed session saves its ID per agent. Use --last to resume:
acpc prompt codex "remember: the password is hunter2"
acpc prompt codex --last "what was the password?"
Resume a specific session by ID:
acpc prompt codex -s 019cf2ca-b50f-7a13-ad67-14fe4db0e0ac "follow up"
Session IDs and resume commands appear on stderr:
[acpc] session: 019cf2ca-b50f-7a13-ad67-14fe4db0e0ac
[acpc] resume: acpc prompt codex -s 019cf2ca-b50f-7a13-ad67-14fe4db0e0ac "follow up"
Last-session tracking is scoped per PPID to avoid race conditions in concurrent use.
Agents are defined in TOML files. Three agents ship built-in (codex, claude, gemini).
Run acpc agents to see the current list and install status.
identity = "my-agent"
name = "My Agent"
author = "Me"
run_command = "my-agent-acp"
install_command = "npm install -g my-agent-acp"
Place .toml files in the platform config directory to add or override agents:
~/.config/acpc/agents/~/Library/Application Support/acpc/agents/%APPDATA%\acpc\agents\User overrides take priority over built-in agents with the same identity.
acpc install codex # runs the install_command from the TOML file
acpc agents # shows install status for all agents
Running sessions are tracked in the platform state directory (~/.local/state/acpc/ on Linux).
Each entry stores PID, agent identity, working directory, and start time.
acpc status # list running sessions
acpc stop codex # stop all sessions for codex
acpc stop -s 019cf2ca-b50f-7a13-ad67 # stop a specific session
Signal handling: Ctrl+C sends session/cancel via ACP, waits 2s for the agent to exit cleanly, then sends SIGKILL to the entire process group.
Child processes are spawned in their own process group to prevent orphans.
| Code | Meaning |
|---|---|
| 0 | Success (end_turn) |
| 1 | Agent error (max_tokens, max_turn_requests, ACP error) |
| 2 | Usage error (unknown agent, missing prompt) |
| 3 | Permission denied (non-interactive) |
| 124 | Timeout (--timeout exceeded) |
| 130 | SIGINT (Ctrl+C) |
| 141 | SIGPIPE |
| 143 | SIGTERM |
TOML agent files define run_command and install_command, which acpc executes as shell commands.
This is the same trust level as shell aliases or PATH entries.
Only place TOML files you trust in the config directory.
The spawned adapter process inherits your full environment (env vars, PATH, credentials).
Environment filtering (--env) is planned for v0.2.
As a workaround, use env -i to strip the environment:
env -i HOME="$HOME" PATH="$PATH" acpc prompt codex "task"
In non-TTY environments (CI, scripts, pipes), permissions default to read.
Use --permissions all to allow writes, or --permissions none for dry runs.
# CI: run agent, capture JSON output, check exit code
acpc prompt codex "run the test suite and fix failures" \
--permissions all \
--json \
--timeout 300 \
> agent-output.ndjson
if [ $? -eq 0 ]; then
echo "Agent completed successfully"
elif [ $? -eq 124 ]; then
echo "Agent timed out"
else
echo "Agent failed with exit code $?"
fi
# Parse agent text from NDJSON
acpc prompt codex "summarize changes" --json \
| jq -r 'select(.sessionUpdate == "agent_message_chunk") | .content.text' \
| tr -d '\n'
v0.1 covers the basics. A few rough edges to be aware of:
acpc prompt spawns a fresh adapter process. No persistent daemon yet, so interactive multi-turn loops feel slow. Scripts and CI are fine. The daemon lands in v0.2.taskkill instead of killpg).--last is not orchestration-safe. Last-session tracking is scoped per parent PID. That works for a human in a terminal, but breaks when one orchestrator agent spawns several acpc calls. For programmatic use, grab the session ID from stderr and pass it back with -s SESSION_ID. acpc warns when --last is used.GEMINI_API_KEY in env. OAuth reuse in ACP subprocess mode is broken upstream (gemini-cli #7549, #12042). API key is the only reliable auth path right now.--env flag is planned for v0.2.MIT
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.0 | 20 Apr 2026 | 3 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 18:22 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:67f3efe547b86cb6fd549ae8e525d899b61969c5062a196d3e01a7e6516c0c6e