Skip to main content
Author(s): @benbrandt This is a tracking RFD for the collection of RFDs that require breaking changes to the protocol and should make up ACP v2.

Elevator pitch

What are you proposing to change?
With ACP, we aim to move fast while keeping breaking changes to a minimum. However, we’ve gotten to a point where there are enough changes we would like to do that would benefit from some core redesigns that will allow for extending the protocol with new features more easily. We’ve also managed to add new features that have led to learnings that would benefit from consolidation and alignment in other areas of the protocol to smooth things out and make things more consistent.

Status quo

How do things work today and what problems does this cause? Why would we change things?
We have had a fairly successful time adding new features via new capabilities and adding in new features in a non-breaking way. But some of the learnings we have made will require breaking changes, and it feels like there are enough of these built up, or RFDs we are stuck due to required changes that now is a good time to do so.

What we propose to do about it

What are you proposing to improve the situation?

Current Active RFDs

Current RFDs with active maintainer focus that are targeting the v2 release: These RFDs define v2’s breaking changes, and they are the scope of the v2 Preview. Other RFDs, such as Remote Transports, add new transports, methods, or capabilities without changing existing messages, so they don’t block v2. A transport can add its own requirements, such as reconnection, keepalive, or stream resumption, without changing the core protocol. Other RFDs will progress separately and are not dependent on breaking changes (specifically the new prompt lifecycle) and can land in either or both v1 and v2.

v2 Changes

This list tracks every breaking change in v2. Smaller changes without their own RFD are recorded here and in the migration guide.
  • Remove the dedicated session modes API from v2. This includes the modes session response fields, session/set_mode, current_mode_update, and the SessionMode* types.
  • Agents should expose mode-like and model-related state through Session Config Options instead of dedicated mode or model selector APIs.
  • Remove the v1 Client filesystem and terminal execution surface from v2. This includes clientCapabilities.fs, the top-level clientCapabilities.terminal field, fs/* methods, terminal/* methods, and the Client-owned semantics of v1 terminal tool-call content. Terminal authentication remains separate under capabilities.auth.terminal.
  • Add Agent-owned, display-only terminal output. Tool calls reference terminals by terminalId; terminal upserts carry command, absolute cwd, replay snapshots, and exit status; terminal output chunks append independently base64-encoded bytes. The display surface is baseline v2 and does not add Client execution or control methods.
  • Make plan variants the default v2 plan shape by replacing the old plan session update with item-based plan_update.
  • Replace the v1 split between tool_call and tool_call_update with a single tool-call update upsert shape keyed by toolCallId.
  • Add tool-call content chunks so Agents can stream individual ToolCallContent items that append to a tool call.
  • Replace the v1 Diff oldText / newText shape with diff file states: optional Git --patch text (git_patch) plus structured file operations for add, delete, modify, move, copy, and non-text changes.
  • Make permission requests carry a required prompt title and optional extensible subject tagged union. Tool-call permissions use subject.type: "tool_call" with the same ToolCallUpdate payload shape as session updates, command permissions use subject.type: "command" with the command, required absolute working directory, and optional display associations, and subject-less permissions rely on the common prompt fields.
  • Add whole-message updates for user_message, agent_message, and agent_thought alongside streamed chunks. Message updates are upserts keyed by messageId; their content arrays replace current message content, while chunks append to the current content.
  • Apply the top-level _meta of upsert updates as a metadata patch: omission leaves it unchanged, null clears it, and an object patches stored metadata by top-level key, where a key set to null is removed and any other value replaces that key whole.
  • Require message IDs on streamed message chunks.
  • Acknowledge prompt insertion by returning the inserted user message’s messageId from session/prompt, without waiting for foreground work to finish. Live user-message updates use the same ID; retention remains optional. Prompts sent during active work are inserted or held in order, not rejected.
  • Report foreground activity with state_update (running, idle, requires_action), and move the stop reason from the session/prompt response to the idle update.
  • Report failures after prompt insertion by ending foreground work with an idle state_update whose stopReason is error, carrying an optional JSON-RPC error object. A JSON-RPC error on session/prompt always means the message was not inserted.
  • Do not use JSON-RPC 2.0 batches. Each transport message is a single request, notification, or response, and receivers reject an array with -32600, as MCP does since 2025-06-18.
  • Make enums and tagged unions open where a safe fallback exists: _-prefixed values are for extensions, and other unknown values are reserved for future ACP versions.
  • Add the cancelled status for tool calls and plan entries.
  • Add background work: a paused tool call status, opt-in capabilities.cancel on tool calls and terminals with tool_call/cancel and terminal/cancel, and a background list on state snapshots.
  • Allow initial configOptions and availableCommands in session/new and session/resume responses, and add type discriminators to commands (command) and command input (text).
  • Reject initialize with -32022 (Unsupported protocol version) when no supported version is at or below the requested one, with the requested and supported versions in the error data.
  • Require a type discriminator on session/set_config_option values, and rename the config option group field to groupId.
  • Make usage_update.cost a patch field: omitted leaves it unchanged and null clears it.
  • Make mcpServers optional on session setup requests.
  • Clean up capability naming and organization:
    • Use a single capabilities field in both initialize params and results, replacing the v1-style clientCapabilities and agentCapabilities fields.
    • Require implementation metadata in both initialize params and results with a single role-agnostic info field, replacing the v1-style clientInfo and agentInfo fields so agent-to-agent and other symmetric ACP connections do not need role-specific field names.
    • Group authentication methods under auth/*: v2 uses auth/login and auth/logout instead of v1’s top-level authenticate and logout method names. An Agent that returns a non-empty authMethods list advertises the authentication surface and MUST implement both methods; if the field is omitted or empty, Clients MUST NOT call either method. There is no capabilities.auth.logout support marker, and capabilities.auth remains orthogonal for authentication-related extensions. The generated request and response type names follow the grouped method naming as LoginAuthRequest / LoginAuthResponse and LogoutAuthRequest / LogoutAuthResponse.
    • Rename the authentication method descriptor’s id to methodId, make its type discriminator required, and advertise Client support for terminal methods with a capabilities.auth.terminal object marker.
    • Use concise capability group names such as session and auth, replacing names like sessionCapabilities.
    • Make session optional so Agents that only expose non-session method surfaces can omit it.
    • Require the baseline session lifecycle methods when session is present: session/new, session/list, session/resume, session/close, session/prompt, session/cancel, and session/update.
    • Remove session/load from v2. session/resume handles both no-replay resume and full replay by using the optional replayFrom cursor from the Session Resume Replay RFD.
    • Move optional session-scoped capability groups under session, including prompt and mcp as session.prompt and session.mcp.
    • Represent support markers as capability objects instead of booleans. Supplying {} means supported, while omission or null means unsupported. Booleans remain appropriate for actual data or configuration inside an already-advertised capability.
  • Align MCP server transports with the current MCP transport model:
    • Remove the deprecated HTTP+SSE MCP transport from v2.
    • Make stdio an explicit session.mcp.stdio capability so Agents that cannot launch local subprocesses can opt out.
    • Require MCP server configurations to include a type discriminator, including type: "stdio", so unknown future transports can be preserved as extension/future variants.
    • Keep HTTP as the remote MCP server transport capability.
  • Unify ID naming and typing across the v2 schema. Protocol fields should use domain-specific ID names such as messageId, toolCallId, planId, terminalId, configId, and methodId rather than a generic id whenever the field identifies a protocol entity or references another resource.

RFDs to be Written

Changes under consideration that still need to be drafted or moved to draft:
  • MCP: revamp MCP server support, including tool timeouts and more lifecycle methods

Shiny future

How will things play out once this feature exists?
There is a lot of work to do, especially on the SDK side, to support both versions, but it is likely that we should be able to allow Agents specifically to target v2 APIs and gracefully fall back to v1 messages for v1 clients, to avoid huge support issues. However, once all of this work is in place, it should be much easier to make additional breaking changes in the future when necessary, we’ve been kind of letting this build up given the effort required for the entire ecosystem, but the ACP maintainers will be charting a course forward to make this as smooth as possible!

Implementation details and plan

Tell me more about your implementation. What is your detailed implementation plan?

v2 + v1 Schema publishing

I created the initial draft of the v2 schema as a direct duplicate of v1. The side-by-side Rust types still make the schema differences explicit as v2 evolves. The Rust schema does not provide cross-version conversion. Even initialize-request normalization depends on SDK routing policy, while many v2 lifecycle and update semantics require state that a schema-level conversion cannot supply. SDKs supporting both versions should expose explicit versioned implementations or build a purpose-specific adapter at their runtime boundary. Once we have more pieces in place, we can start publishing both schemas to assist SDK developers to start figuring out how to support this. This should be done in an opt-in, off by default, clearly labeled unstable way for SDK consumers. There will likely be bumps as we figure out the necessary plumbing and we shouldn’t be shipping v2 in production without feature flags prior to a more stable release as we align all of the necessary pieces.

SDK Support

With the needed breaking changes, as much as possible I am targeting having a consistent API surface for Agents, since they will want to target v2 APIs but still support v1 clients. Because of how the version negotiation works, if we can achieve the same thing for clients that will be great, but if not, they will at least be provided clear version entry points.

Frequently asked questions

What questions have arisen over the course of authoring this document or during subsequent discussions?

Revision history

  • 2026-10-30: Added the v2 Background Work changes to the change list now that they are in the v2 schema.
  • 2026-10-30: Added the config option type/groupId changes and the usage_update.cost patch semantics to the change list.
  • 2026-10-29: Scoped the v2 Preview to the RFDs with breaking changes. Remote Transports and other additive work no longer block v2, and transport-specific reliability requirements belong to each transport.
  • 2026-10-29: Dropped JSON-RPC batches from v2, following MCP.
  • 2026-10-29: Reconciled the v2 change list with the migration guide, adding open enums, state_update, cancelled statuses, setup-response commands, -32022, optional mcpServers, and the auth method descriptor changes. ID examples now use stable fields only.
  • 2026-10-27: The v2 Background Work RFD now adds a paused tool call status, leaves agent-internal housekeeping out of the background list, and defines how permission requests for background work are identified.
  • 2026-10-26: The v2 Background Work RFD now lists background terminals, adds opt-in terminal/cancel, and defines ordering rules and background subagent listing.
  • 2026-10-21: Added the v2 Background Work RFD for tool calls that outlive foreground work, individual tool-call cancellation, and a background list on state snapshots.
  • 2026-10-13: Added the v2 Metadata Patches RFD so a top-level _meta object on an upsert patches stored metadata by key instead of replacing it.
  • 2026-10-01: Recorded that failures after prompt insertion end foreground work with an error stop reason that carries an optional JSON-RPC error.
  • 2026-10-12: Specified that every git_patch path, including rename and copy headers, is absolute with no a/ or b/ prefix, and otherwise follows Git, including /dev/null and path quoting.
  • 2026-09-30: Removed NES-specific capability and optional-session examples; session remains optional for Agents exposing non-session method surfaces.
  • 2026-07-20: Clarified git_patch and renamed its payload from diff to text.
  • 2026-07-20: Clarified that idle means ready for a new prompt while background updates may continue; steering and queueing remain separate concerns.
  • 2026-07-20: Scoped the v2 authentication surface to Agents that return one or more valid authMethods; those Agents must implement both auth/login and auth/logout, while omission or an empty array means Clients must not call either method.
  • 2026-07-14: Added the v2 Terminal Output RFD for Agent-owned, display-only terminal output.
  • 2026-07-02: Added the v2 Diff File States RFD for renderable git patches, structured file operations, and non-text file changes.
  • 2026-07-02: Moved the v2 RFD collection to Active.
  • 2026-07-02: Added the v2 Permission Requests RFD for required permission titles, optional structured subjects, and tool-call permission subjects.
  • 2026-07-02: Added the v2 Session Resume Replay RFD and recorded that session/resume replaces session/load in v2 by using optional replayFrom cursors.
  • 2026-07-02: Added the v2 Required Session Methods RFD and recorded that session/list, session/resume, and session/close are baseline when session is present.
  • 2026-06-30: Recorded the v2 ID unification principle: prefer domain-specific ID field names.
  • 2026-06-25: Recorded the v2 initialize information cleanup: required role-agnostic info in both params and results, replacing clientInfo and agentInfo.
  • 2026-06-25: Recorded the v2 authentication method cleanup: grouped auth/login and auth/logout method names replace v1’s top-level authenticate and capability-gated logout, with matching generated type names for login and logout auth requests and responses.
  • 2026-06-09: Added tool-call content chunks for streaming individual ToolCallContent items.
  • 2026-06-09: Added the v2 Message Updates and Chunks RFD to define whole-message upserts alongside streamed message chunks.
  • 2026-06-08: Added the v2 Tool Call Updates RFD to make tool_call_update the single upsert-style tool-call session update.
  • 2026-06-05: Recorded the v2 capability cleanup: unified initialize capability fields, optional session support for NES-only agents, session-scoped prompt and mcp capabilities, object-shaped support markers, explicit session.mcp.stdio, removal of deprecated MCP SSE transport, and tagged MCP server transport configs.
  • 2026-06-02: Recorded the v2 decision to follow JSON-RPC 2.0 batch request and notification behavior.
  • 2026-06-02: Recorded the v2 decision to remove Client filesystem and terminal execution capabilities, methods, and Client-owned terminal tool-call content.
  • 2026-06-02: Added the v2 Plan Variants RFD to make item-based plan_update the default v2 plan shape.
  • 2026-06-01: Recorded that model selection should remain represented by session config options instead of a dedicated selector API.
  • 2026-05-28: Recorded the v2 decision to remove session modes in favor of session config options
  • 2026-05-06: Initial draft