Skip to main content
anyagent ships a catalog of known agents. Each entry says how to find the CLI, how to launch it in protocol mode, and the quirks verified against a real install. Guessed flags never ship.

Catalog

Native wires are driven directly by an adapter written for that agent. ACP agents share one adapter that speaks the Agent Client Protocol.

Capability matrix

What each adapter reports after open. Read it from session.info().details.capabilities at runtime; never hardcode this table.
  • handshake: the ACP initialize response says whether the agent takes images, loads sessions, and accepts steering. Cursor, for example, reports images and resume; Antigravity’s server reports no steer.
  • on first sight: ACP has no handshake flag for these. The capability is added, with a SessionUpdated, the first time the agent sends one.
Every gate holds the same way: an unsupported call fails typed with UnsupportedFeature instead of misbehaving. TurnEnded.usage (the turn’s token counts) is not a capability: claude, codex, opencode, pi, and antigravity over agy fill it; ACP agents leave it None. A compaction turn carries the summary’s tokens on opencode and none on pi, which reports no model call for it.

Config options by agent

On claude, codex, and opencode each model choice also carries that model’s own effort and fast in options (opencode: effort only). Other agents leave it empty.

Answers by agent

What Answer::Deny { message } and Answer::Cancel send. Where the wire takes no message, the message is dropped.

Per-agent notes

The fullest native adapter. fast appears when the selected model reports supportsFastMode; switching it resumes the process under the hood with the same Session handle and conversation. Rollback can restore files. A tool a permissions.deny rule or the CLI’s own mode refuses ends Denied; a hook’s refusal still shows as Failed (the CLI sends no denial frame for it). Client MCP servers ride the mcp_set_servers control request after initialize, so their header and env values never appear in argv. A server that fails to connect, or a CLI that refuses the request, is a Warning diagnostic. While a declared server is still connecting (up to 30 s for an unreachable one) the CLI holds later input, so the first turn and the answers to cancel, configure and usage requests wait for it. A running Bash reports ToolProgress only when the CLI runs with CLAUDE_CODE_CONTAINER_ID or CLAUDE_CODE_REMOTE set (2.1.283); a subagent’s Bash sent none when probed. An output schema rides --json-schema; the CLI’s StructuredOutput call arrives as a text message of its own holding the JSON, after any text the model wrote first.
Opts into the app-server’s experimental API. Approval policy and sandbox switch live. mode: plan is codex’s plan collaboration mode and keeps the last approval policy; to leave it, select an approval policy and prompt again. Images ride as localImage items. Client MCP servers ride as launch overrides (stdio and HTTP; no SSE). Header and env values ride env vars the overrides name, never argv. codex forwards stdio MCP env by name, so a declared name is also set on codex itself; PATH, or a name codex’s environment already has with another value, is refused. Two server names that differ only by case or -/_ are refused too: they would share env vars. rollback maps to thread/revert; files are never restored. Questions are translated defensively but the capability stays off until observed live. MCP progress maps to ToolProgress, but 0.154.0 did not forward a stdio server’s progress when probed. probe opens no thread: it reads config/read and skills/list, so the user’s MCP servers and hooks never start. It may miss skills codex loads about 0.5 s after it starts (0.154.0: marketplace plugins; forceReload does not wait for them). An output schema rides every turn/start as outputSchema; the model API takes only strict schemas (every object additionalProperties: false) and fails the turn otherwise. A subagent’s child thread nests under the subAgentActivity item or the spawnAgent call that names it (0.154.0 sends either); the spawn call also names the child’s model.
anyagent starts opencode serve on a private localhost port per session, gated by a per-session secret, and drives its HTTP + SSE wire. Task-tool child sessions nest as subagents; the task names the child’s role (subagent_type) and model. No steer (mid-turn prompts queue) and no plan quota. Pass a model as configure("model", "provider/id"); opencode’s free opencode/… models need no key. Client MCP servers (stdio, HTTP, SSE) are added with POST /mcp at open. opencode keeps them per server process, and each session has its own, so they last for that session. A server opencode cannot connect fails open with InvalidConfiguration. To drive it over ACP instead: AgentInstallation::acp("opencode", path, ["acp"]).
Provider-key based: log in with /login <provider> inside the CLI, or set the provider’s API-key variable. generate launches with --no-tools --no-session, so it is text-only and nothing is saved.
Discovery picks the richer wire that is installed:
The headless agy wire cannot prompt: in Ask and AcceptEdits mode every permission-gated tool is denied by the agent itself (the tool shows as failed), AutoApprove launches with --dangerously-skip-permissions, questions are skipped with a diagnostic, and a mid-turn prompt queues. Cancel kills the process and resumes the conversation in a fresh one, about two seconds.The ACP server is Google’s own (antigravity-acp in the ACP registry, a 314 MB download). It reuses the agy login: anyagent calls its authenticate once per open (about 2 s, no browser), or set auth.type in ~/.gemini/antigravity-acp/settings.json to skip that. When only agy is found, the installation carries upgrade: Some(MissingAgent) with the download hint:
Force the headless CLI with ANYAGENT_ANTIGRAVITY_BIN=~/.local/bin/agy. Google’s terms restrict third-party tools driving a personal Antigravity login; the ACP server is the sanctioned path. Surface that choice to users.
Runs over cursor-agent acp. Permission requests gate shell commands outside its allowlist; file edits never ask, so sandbox accordingly. Before the handshake anyagent runs cursor-agent about for the version and account and fails typed with cursor-agent login when logged out. A model switch adopts that model’s own options (effort, fast, thinking, context). Cursor’s extension requests are answered: ask_question becomes a Question, update_todos drives the plan, task (a subagent run) is surfaced as a header only. Cursor reports no context usage, so each turn ends with an estimate (4 chars ≈ 1 token) labelled anyagent/estimated in extensions.
Its credential lives in a sqlite row that exists logged out too, so discovery reports Unknown and probe answers for real. effort is exposed as a live option even though ACP advertises none: the adapter reads the level from kiro’s metadata and switches it by running /effort <level> as a hidden prompt between turns.
Only its file tools ask permission. Its terminal tool runs without asking, so a denied write does not stop it from writing via shell. Hermes never sends tool status updates. No effort option.
Plain ACP. Grok exposes effort from the model’s reasoningEfforts; qwen exposes none. Both log in through their own TUI.
Compaction is native-adapter only. ACP has no compaction in schema 1.7, so ACP agents refuse with UnsupportedFeature.

Any other ACP agent

No catalog entry needed. Build the installation yourself:
Events, requests, and capabilities are identical downstream. What you lose is the catalog’s verified quirks: launch flags, login commands, auth error hints.

Pointing at a specific binary

Every catalog entry reads ANYAGENT_<AGENT>_BIN first:
Or skip discovery with AgentInstallation::at(id, executable).

Windows

Every catalog agent ships for Windows and every installer below puts its directory on PATH, so discovery finds them without extra configuration. npm installs are .cmd shims; discovery skips the bare bash shim next to them. Cursor’s Windows installer is irm 'https://cursor.com/install?win32=true' | iex.

Several logins of the same agent

anyagent sets the agent’s own config-home variable (CLAUDE_CONFIG_DIR, CODEX_HOME, …) for that process. An agent with no such variable fails with InvalidConfiguration; an isolation request is never silently dropped.

Launch options

env reaches every agent process, side processes included, after config_home’s variable: on the same name, yours wins.