Step 2 of opt-in ACP v2 support (step 1: #1217). Behind `CLAUDE_AGENT_ACP_EXPERIMENTAL_V2=1`, the v2 surface now serves `session/new`, `session/list`, `session/resume` (without replay), `session/close`, `session/delete`, and `session/set_config_option`. ACP v1 is unchanged. `capabilities.session` is still not advertised. Under v2, advertising it commits the agent to the whole baseline, including `session/prompt` and `replayFrom: start` replay, and those come in later steps. Until then these methods are served but not advertised. ## Translation As in step 1, each v2 request becomes the v1 request that `ClaudeAcpAgent` already serves, and each v1 response or update becomes its v2 form (`src/v2/session.ts`, `src/v2/session-update.ts`): - **MCP servers:** v2 requires a `type` on every transport, but the agent recognizes a v1 stdio server by its *missing* `type`. A v2 `type: "stdio"` config passed through as is would be silently skipped, so the tag is dropped. The lists v1 requires (`args`, `env`, `headers`) are defaulted. A transport v1 can't express is rejected with invalid params instead of being left out of the session. - **Config options:** `id` → `configId`, a select group's `group` → `groupId`. A select value in `session/set_config_option` drops its v2 `type: "id"`, and value types v1 can't express are rejected. - **Modes:** responses drop `modes`, and `current_mode_update` is dropped. The agent always lists the mode as the `mode` config option, and every mode change also reaches the client as a `config_option_update` or in the `set_config_option` response. - **Commands:** `available_commands_update` inputs gain `type: "text"`. - **Notices, session info, usage:** passed through unchanged. v2 needs no capability for notices, so a v2 client is reported to the agent as taking them, and advisories arrive as `notice` instead of transcript messages. - **Elicitation:** the same in v1 and v2, so it's forwarded. MCP OAuth at `session/new` works. - Update kinds that aren't translated yet (messages, tool calls, plans, extensions) throw, so a gap shows up as an error, not a missing update. - `replayFrom` is rejected until replayed history can be translated. Also bumps `@agentclientprotocol/sdk`: - to 1.6.1, whose router types `closed` as always present, so `serveAcp` drops its `closed!`; - to 1.7.0, which type-checks the v2 extensible-union values the adapter builds, at any depth ([typescript-sdk#268](https://github.com/agentclientprotocol/typescript-sdk/pull/268)). The v2 translations compile unchanged. The exception is `createElicitation`, which relays the v1 request: v1 types a property schema's tag as any string, and an MCP server's schema passes through unchecked, as on v1. It gets a cast with a comment saying so. ## Testing - `src/tests/acp-v2.test.ts` drives the router with the SDK's v2 client app, which validates every response, session update, and elicitation against the v2 schema. New cases cover session creation with v2 MCP servers, config options, and commands; rejected MCP transports; list/close/resume/delete and rejected `replayFrom`; setting the mode with no `current_mode_update` reaching the client; notice support; MCP OAuth through URL elicitation; and unit tests for grouped options, rejected value types, and untranslated updates. Breaking the stdio or command-input translation makes the tests fail. - Ran the built binary over stdio against a real Claude Code session: v2 `initialize`, `session/new`, `list`, setting the mode, and `close` all passed the v2 client's validation, and the 52 real commands arrived with `type: "text"` inputs. `session/new` took ~0.7 s, the same as over v1. - `npm run build`, `npm run check`, `npm run test:run`.
ACP adapter for the Claude Agent SDK
Use Claude Agent SDK from ACP-compatible clients!
This tool implements an ACP agent by using the official Claude Agent SDK, supporting:
- Context @-mentions
- Images
- Tool calls (with permission requests)
- Compact file changes through the negotiated AIR diff patch extension
- Following
- Edit review
- TODO lists
- Nested subagent transcripts
- Interactive (and background) terminals
- Custom Slash commands
- Client MCP servers
- Session-scoped long-running goals for AIR through the goal extension under
_meta.jetbrains.air.goal - Structured errors, recovery, and warnings through the opt-in session failure extension
- Concrete model and effort defaults through the opt-in recommended config value extension
- Tool permission presentation, editable choices, and durable effects through the permission extension
- One fact per field in every tool call report, as the ACP tool call contract defines
- All AIR extensions, capabilities, and
_metakeys: AIR extensions
Learn more about the Agent Client Protocol.
To try changes that have landed on main but are not released yet, install from the
preview channel — every push to main publishes one. See
docs/RELEASES.md.
npm install @agentclientprotocol/claude-agent-acp@preview
Subagent sessions
Subagents are exposed only after bilateral capability negotiation. Until the released ACP SDKs
preserve the draft clientCapabilities.subagents field, a supporting client may advertise
nativeSubagentSessions in _meta.jetbrains.air.capabilities; the adapter mirrors the capability
in its initialize response. The canonical field remains supported and takes precedence once it is
available. Without either client signal, Agent/Task lifecycle keeps its legacy ordinary ACP
tool-call representation and child interactions stay on the root session. Clients that use the
historical _meta["subagent-transcript"] capability or forwardSubagentText session option retain
the flattened child transcript behavior. See AIR extensions.
Contribution Policy
This project does not require a Contributor License Agreement (CLA). Instead, contributions are accepted under the following terms:
By contributing to this project, you agree that your contributions will be licensed under the Apache License, Version 2.0. You affirm that you have the legal right to submit your work, that you are not including code you do not have rights to, and that you understand contributions are made without requiring a Contributor License Agreement (CLA).