pi-acp-rs
v0.5.2
Published
ACP adapter for the pi coding agent
Readme
pi-acp-rs
Use the pi coding agent from Zed and other Agent Client Protocol (ACP) clients.
pi-acp-rs connects an ACP client to pi over a local process boundary. It starts
pi when a session is opened and forwards prompts, tool activity, session history,
model settings, and usage information. pi still owns the agent loop, providers,
credentials, and tools; pi-acp-rs is the adapter between pi and the client.
Requirements
- Node.js and npm, to install pi
- pi installed and available on your
PATH - Zed or another ACP-compatible client
- Linux (x86-64 or arm64), macOS (Intel or Apple Silicon), or Windows (x86-64)
Install
1. Install pi
npm install --global @earendil-works/pi-coding-agent
pi --version2. Install pi-acp-rs
The easiest option is the npm package, which selects the native binary for the current platform:
npm install --global pi-acp-rs
pi-acp-rs --versionYou can also download the latest standalone release for your platform from GitHub Releases.
| Platform | Release asset |
| --- | --- |
| Linux x86-64 | pi-acp-linux-x64 |
| Linux arm64 | pi-acp-linux-arm64 |
| macOS Intel | pi-acp-macos-x64 |
| macOS Apple Silicon | pi-acp-macos-arm64 |
| Windows x86-64 | pi-acp-windows-x64.exe |
On Linux and macOS, make the downloaded file executable and move it to a
directory on your PATH:
chmod +x pi-acp-<platform>
sudo mv pi-acp-<platform> /usr/local/bin/pi-acp-rs
pi-acp-rs --versionOn Windows, keep the .exe suffix and add the directory containing
pi-acp-windows-x64.exe to PATH. You can also point Zed directly at the full
path to the executable. The release includes CHECKSUMS.txt; verify the
download's SHA-256 checksum when installing from a release.
Configure Zed
Add pi-acp-rs to Zed's settings.json:
{
"agent_servers": {
"pi": {
"command": "pi-acp-rs",
"args": [],
"env": {}
}
}
}Restart or open a new agent thread in Zed. If Zed cannot find a binary installed
on your shell's PATH, use an absolute path instead:
{
"agent_servers": {
"pi": {
"command": "/usr/local/bin/pi-acp-rs",
"args": [],
"env": {}
}
}
}Environment variables in this block are inherited by pi. This is where you can
set pi options such as PI_PROVIDER and PI_MODEL if your pi setup uses them.
Sign in to pi
If pi needs an API key or provider login, run its interactive setup once:
pi-acp-rs --terminal-loginComplete the setup in the terminal, then start a new agent session in Zed. ACP clients that support terminal authentication can also launch this action from their authentication prompt.
Configuration
Most users can keep the defaults. Set these variables in Zed's env block or
in the environment that launches pi-acp-rs:
| Variable | Default | Use |
| --- | --- | --- |
| PI_ACP_PI_COMMAND | pi | Path or command name for pi. On Windows, use the full path to the npm-generated pi.cmd when it is not on PATH. |
| PI_ACP_VERSION_CHECK | false | Set to true to show a startup notice when a newer pi version is available. |
| PI_ACP_ENABLE_EMBEDDED_CONTEXT | false | Set to true for ACP clients that send embedded context. |
| PI_ACP_ENABLE_MCP | false | Set to true to accept and wire non-empty ACP mcpServers through pi-mcp-adapter. |
| PI_ACP_RPC_TIMEOUT_SECS | 30 | Maximum time to wait for an individual pi request. |
| PI_ACP_SETTLE_TIMEOUT_SECS | 600 | Maximum time to wait for pi to finish a turn after accepting a prompt. Set to 0 to disable this fallback. |
| RUST_LOG | warn | Set to pi_acp=debug for diagnostic logs. Logs are written to stderr so ACP stdout remains available for protocol messages. |
MCP support
MCP support is opt-in. pi-acp-rs does not discover Zed's MCP settings and does
not read or write .pi/mcp.json. The supported path is:
Zed -- ACP session/new|load mcpServers --> pi-acp-rs
-- runtime-register --> pi-mcp-adapter inside pi
-- stdio/http/sse --> MCP serversTo enable this path:
Install the adapter as a global pi package in the same environment and pi agent directory used by Zed:
pi install npm:pi-mcp-adapterSet the flag in the Zed
agent_serversentry. Putting it only in a shell that was not used to launch Zed may have no effect:{ "agent_servers": { "pi": { "command": "pi-acp-rs", "args": [], "env": { "PI_ACP_ENABLE_MCP": "true" } } } }Configure servers in Zed's
context_serverssettings. A custom stdio server usessource: "stdio"; an HTTP server usessource: "http":{ "context_servers": { "my-local-server": { "source": "stdio", "command": "/path/to/my-mcp-server", "args": [], "env": {} }, "my-http-server": { "source": "http", "url": "https://example.example/mcp" } } }Create a new ACP session after changing either configuration. The server command, arguments, and environment must be usable by the process that runs pi. MCP registrations are session-scoped and are not persisted to disk.
Remote development
For a remote Zed project, Zed only sends stdio servers that have
"remote": true. This applies to both custom and extension-provided context
servers. Set that flag only when the command is installed and can run in the
remote agent environment:
{
"source": "stdio",
"remote": true,
"command": "/usr/local/bin/my-mcp-server",
"args": []
}If the server must keep running on the local machine while the agent is remote,
use an HTTP endpoint reachable by the remote agent. A local stdio process needs
a Zed-side relay or MCP-over-ACP support; pi-acp-rs cannot recover it from an
empty ACP mcpServers list.
Diagnose an empty server list
Inspect the raw ACP session/new or session/load request:
"mcpServers": []means Zed did not pass any server. ChangingPI_ACP_ENABLE_MCPcannot add one; check Zedcontext_servers, enabled state, project scope, and theremoteflag.- A non-empty list with
MCP wiring is disabledmeansPI_ACP_ENABLE_MCP=truewas not inherited by pi-acp. - A non-empty list with an adapter error means
pi-mcp-adapteris not installed in the pi agent directory used by that session.
The default is false deliberately: accepting an ACP MCP menu can start
external commands and connect to network services. Explicit opt-in preserves
existing pi behavior and keeps the advertised ACP capabilities honest when the
optional adapter is unavailable.
Troubleshooting
pi-acp-rs or pi cannot be found
Check both commands from a terminal:
pi --version
pi-acp-rs --versionIf they work in a terminal but not in Zed, use absolute paths in Zed's
command or set PI_ACP_PI_COMMAND to the full path of pi. On Windows, pi is
usually an npm pi.cmd wrapper rather than a native pi.exe.
Authentication fails
Run pi-acp-rs --terminal-login and complete the provider setup. If you use
environment variables for credentials, make sure they are present in Zed's
env block as well as in your shell.
A session stops unexpectedly
pi-acp-rs reports when its pi child process exits and does not restart it
automatically. Start a new agent session after fixing the underlying pi error.
Set RUST_LOG=pi_acp=debug temporarily if you need more detail.
Build from source
Prebuilt releases are recommended. To build locally, install the Rust toolchain
specified by rust-toolchain.toml, then run:
git clone https://github.com/AndPuQing/pi-acp.git
cd pi-acp
cargo build --releaseThe binary is written to target/release/pi-acp.
ACP protocol v2 (experimental)
ACP protocol v2 is an unstable draft. It is behind the off-by-default
protocol-v2 feature, so a normal build is unaffected in behavior, dependency
set, and ACP semantics:
cargo build --release --features protocol-v2With it enabled, the adapter negotiates the version from the client's
initialize and serves either; each connection gets the version it asked for.
The translation core still speaks v1 only — v1 <-> v2 conversion happens once,
at the connection boundary, using the schema crate's conversion layer.
Two v2-specific behaviors are worth knowing:
- v2 clients receive
message_ids and a complete-message patch. pi's RPC messages carry no id, so the adapter mints one per assistant message (pi-msg-<n>) and tags every chunk with it; v1 clients get the same ids (v1'smessageIdis optional, so this is a strict improvement). Atmessage_enda v2 client additionally gets anagent_messageupdate carrying the authoritative complete content under that same id, which patches what it streamed. - v2 has no session modes.
session/set_modeandcurrent_mode_updatewere removed in favor of config options, so those updates are skipped on the v2 path (the thinking/model selectors still arrive asconfig_option_update). v1 is unchanged.session/resumereplacessession/loadfor v2 clients, and onlyreplayFrom: {"type":"start"}and an omittedreplayFromare supported — an unknown cursor is rejected rather than guessed at.
License
MIT
