Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Finding an agent to drive

The protocol publishes a catalog of ACP agents pinned to exact versions. cacp-agents reads it and installs from it, so an agent’s build never changes underfoot the way npx <pkg>@latest does, and no package manager sits in the chat path.

let catalog = registry::catalog(&cache_dir).expect("a catalog");
let agent = catalog.agents.iter().find(|a| a.id == "claude-acp").unwrap();

let installed = match Installed::find(&data_dir, &agent.id) {
    Some(installed) => installed,
    None => agent.install(&data_dir, |line| println!("{line}"))?,
};

let mut command = Command::new(&installed.command);
command.args(&installed.args).current_dir(&cwd);
let (conn, _child) = cacp::spawn(&mut command, client)?;

It carries no runtime and does not depend on cacp. The working directory, the environment and stderr are yours to set, and cacp::spawn takes it from there.

registry::catalog serves a cache under a day old as-is, tries the network otherwise, and falls back to a stale cache when that fails — so a catalog opened offline is out of date rather than empty.

Everything here blocks: it reaches the network and runs npm. Call it off a worker rather than inside a turn.

MCP servers

The same module shape covers the MCP registry, for handing an agent servers it can reach: mcp::search queries it live, and Server::install places an npm package or hands back None for a remote server that needs no install.

Remote servers only work against an agent that advertises mcp_capabilities.http. Check before offering one, rather than sending an entry it will fail to dial.