Elevator pitch
What are you proposing to change?ACP v2 should use a single
sessionUpdate: "tool_call_update" notification for both creating and updating tool calls. The payload is an upsert keyed by toolCallId: if the Client has not seen the ID before, it creates a new displayed tool call; otherwise, it patches the existing tool call.
ACP v2 should also add sessionUpdate: "tool_call_content_chunk" for streaming discrete tool-call content items. Chunks are keyed by toolCallId and append one ToolCallContent item to the current content for that tool call. The separate Terminal Output RFD defines byte chunks for a referenced terminal.
Status quo
How do things work today and what problems does this cause? Why would we change things?ACP v1 has two related tool-call session updates:
tool_call_update notifications if that is all they receive. There also wasn’t a way to handle unsetting values, which we established with session_info_update.
What we propose to do about it
What are you proposing to improve the situation?ACP v2 should remove
sessionUpdate: "tool_call" and make sessionUpdate: "tool_call_update" the only tool-call session update.
The v2 ToolCallUpdate payload has the following semantics:
toolCallIdis required.title,kind,status,content,locations,rawInput, andrawOutputare patch fields.- An omitted patch field leaves the previous value unchanged.
nullexplicitly clears or unsets the field.- Any concrete value replaces the previous value.
contentandlocationsare replaced as whole arrays, not appended.[]andnullboth clear a collection field._metapreserves omitted,null, and object values as distinct update signals.- For a new
toolCallId, omitted fields use Client defaults. - Agents SHOULD include
titlethe first time they report atoolCallId.
session/request_permission method should also carry this same ToolCallUpdate shape for tool-call permissions. In v2, permission requests use an optional subject tagged union; tool-call permissions set subject.type: "tool_call" and carry the update in the subject’s toolCall field, so the permission UI receives the same patch/upsert payload shape as session updates while leaving room for future permission subjects.
Permission-specific prompt text should be carried by the request’s common required title and optional description fields instead of ToolCallUpdate.title or ToolCallUpdate.content. That keeps a permission prompt from accidentally replacing displayed tool-call state.
ACP v2 should define a matching streaming update:
tool_call_content_chunk
toolCallIdis required.contentis required and contains oneToolCallContentitem.- Clients append the chunk’s
contentitem to the current content for thattoolCallId. - Clients apply
tool_call_updateandtool_call_content_chunknotifications in the order they are received for eachtoolCallId. - If a
tool_call_updateincludescontent, that array replaces all content currently stored for the tool call, including content accumulated from earlier chunks. - Later
tool_call_content_chunknotifications append to the replacement content. content: []orcontent: nullontool_call_updateclears tool-call content.
Shiny future
How will things play out once this feature exists?There is a single way to update a tool call, removing lots of confusion from how v1 operated. Agents can stream discrete content items without repeatedly resending the whole content array, while still retaining a replacement update for replay, correction, and redaction. Terminal byte streams use their terminal-specific snapshot and chunk updates.
Implementation details and plan
Tell me more about your implementation. What is your detailed implementation plan?
- Remove the v2
sessionUpdate: "tool_call"variant from the schema. - Represent patch fields with a three-state type so implementations can distinguish omitted,
null, and concrete values. - Add the v2
sessionUpdate: "tool_call_content_chunk"variant with requiredtoolCallIdand required singlecontentitem. - Document ordering between full replacement content on
tool_call_updateand appended content chunks.
Compatibility
When converting v1 to v2, both v1tool_call and v1 tool_call_update should map to v2 tool_call_update.
When converting v2 back to v1, adapters can represent compatible v2 updates as a v1 ToolCallUpdate. Conversion is also lossy for some explicit clear operations because v1 update fields cannot represent every distinction between omitted and null. Collection clears can be represented as empty arrays, but scalar/raw-field clears may have to be omitted when targeting v1. This will be a best-effort conversion.
tool_call_content_chunk cannot be represented by the stateless v2-to-v1 conversion helper because v1 tool-call content updates replace the whole content array rather than appending one item. A stateful bridge can choose to accumulate chunks and emit replacement arrays to v1 clients.
Frequently asked questions
What questions have arisen over the course of authoring this document or during subsequent discussions?
Why keep the tool_call_update name instead of tool_call?
Most of the other notification names end in “update”, and this was by far the most used, so it should help with the migration hopefully.
Why make null different from omission?
Tool-call updates need both operations. Omission means “I am not changing this field”; null means “clear the value.” Without the distinction, Agents cannot unset a previously supplied field without resending a full replacement object.
Why add chunks instead of making tool_call_update.content append?
tool_call_update.content needs replacement semantics for replay, correction, and redaction. A separate chunk variant gives streaming a distinct append operation without making replacement updates ambiguous.
tool_call_content_chunk appends a complete ToolCallContent item. It is not the byte-streaming operation for terminal output; terminals use terminal_output_chunk so arbitrary byte boundaries do not create many content items.
Revision history
- 2026-07-14: Distinguished tool-call content item chunks from terminal byte-stream chunks.
- 2026-07-02: Updated permission requests to carry tool-call updates through an optional
subjecttagged union and to use separatetitleanddescriptionfields for permission-specific prompt text. - 2026-06-09: Added
tool_call_content_chunkfor streaming tool-call content. - 2026-06-08: Initial draft