Documentation Index
Fetch the complete documentation index at: https://agentclientprotocol.com/llms.txt Use this file to discover all available pages before exploring further.
Tool Calls
How Agents report tool call execution
Tool calls represent actions that language models request Agents to perform during a session. When an LLM determines it needs to interact with external systems—like reading files, running code, or fetching data—it generates tool calls that the Agent executes on its behalf.
Agents report tool calls through session/update notifications, allowing Clients to display real-time progress and results to users.
Tool call updates may arrive while the Agent reports idle. They do not change the state.
While Agents handle the actual execution, they may use Client-mediated interactions like permission requests to provide a richer, more integrated experience.
Reporting
When the language model requests a tool invocation, the Agent SHOULD report it to the Client with a tool_call_update:
{
"jsonrpc": "2.0",
"method": "session/update",
"params": {
"sessionId": "sess_abc123def456",
"update": {
"sessionUpdate": "tool_call_update",
"toolCallId": "call_001",
"title": "Reading configuration file",
"kind": "read",
"status": "pending"
}
}
}Tool kinds help Clients choose appropriate icons and optimize how they display tool execution progress.
Custom or future tool kinds can be used when Clients can fall back to generic tool display behavior. Custom tool kinds MUST begin with _. Unknown non-underscore tool kinds are reserved for future ACP variants.
The tool_call_update notification is an upsert keyed by toolCallId. For
existing tool calls, fields other than _meta leave the previous value
unchanged when omitted, explicitly clear or unset the value when null, and
replace the previous value when concrete values are sent. For a new
toolCallId, omitted fields use Client defaults. content and locations are
replaced as whole arrays; send [] or null to clear them. For _meta, omit
the field to leave it unchanged or set it to null to clear it. Use
tool_call_content_chunk when a tool produces content incrementally and the
Client should append each item instead of replacing the whole content
collection. Display-only terminal bytes use terminal_output_chunk instead.
Updating
As tools execute, Agents send updates to report progress and results.
{
"jsonrpc": "2.0",
"method": "session/update",
"params": {
"sessionId": "sess_abc123def456",
"update": {
"sessionUpdate": "tool_call_update",
"toolCallId": "call_001",
"status": "in_progress",
"content": [
{
"type": "content",
"content": {
"type": "text",
"text": "Found 3 configuration files..."
}
}
]
}
}
}
All fields except toolCallId are optional in updates. Only the fields being changed need to be included.
Streaming Content
As tools execute, Agents MAY stream individual content items with
tool_call_content_chunk:
{
"jsonrpc": "2.0",
"method": "session/update",
"params": {
"sessionId": "sess_abc123def456",
"update": {
"sessionUpdate": "tool_call_content_chunk",
"toolCallId": "call_001",
"content": {
"type": "content",
"content": {
"type": "text",
"text": "Found 3 configuration files..."
}
}
}
}
}Clients apply tool_call_update and tool_call_content_chunk notifications in
the order they are received for each toolCallId. A
tool_call_content_chunk appends its content item to the current tool-call
content. A later tool_call_update with content replaces all content
currently stored for that tool call, including content accumulated from earlier
chunks. Later chunks append to that replacement content. A tool_call_update
with content: [] or content: null clears the tool-call content. A
tool_call_content_chunk’s _meta, when present, is chunk-scoped.
Requesting Permission
The Agent MAY request permission from the user before proceeding with an operation, such as executing a tool call, by calling the session/request_permission method:
{
"jsonrpc": "2.0",
"id": 5,
"method": "session/request_permission",
"params": {
"sessionId": "sess_abc123def456",
"title": "Approve file edit?",
"description": "Allow the agent to edit src/main.rs?",
"subject": {
"type": "tool_call",
"toolCall": {
"toolCallId": "call_001"
}
},
"options": [
{
"optionId": "allow-once",
"name": "Allow once",
"kind": "allow_once"
},
{
"optionId": "reject-once",
"name": "Reject",
"kind": "reject_once"
}
]
}
}For a proposed command, the subject can describe the command directly:
{
"title": "Run the test suite?",
"subject": {
"type": "command",
"command": "cargo test",
"cwd": "/home/user/project",
"toolCallId": "call_001",
"terminalId": "term_001"
},
"options": [
{
"optionId": "allow-once",
"name": "Allow once",
"kind": "allow_once"
}
]
}
For type: "command", command and cwd are required, and cwd MUST be
an absolute path. toolCallId, terminalId, and _meta are optional and
nullable; omission and null are equivalent and mean the value was not
provided. The IDs only associate the permission with displayed state and may be
unavailable before execution starts. Selecting an allow option authorizes the
Agent to execute the command; it does not ask the Client to execute anything.
The Client responds with the user’s decision:
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"outcome": {
"outcome": "selected",
"optionId": "allow-once"
}
}
}
Clients MAY automatically allow or reject permission requests according to the user settings.
If the current active work gets cancelled, the Client MUST respond with the "cancelled" outcome:
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"outcome": {
"outcome": "cancelled"
}
}
}Permission Options
Each permission option provided to the Client contains:
allow_once- Allow this operation only this timeallow_always- Allow this operation and remember the choicereject_once- Reject this operation only this timereject_always- Reject this operation and remember the choice
Custom or future permission option kinds can be used as UI hints. Custom kinds MUST begin with _. Unknown non-underscore kinds are reserved for future ACP variants. Clients that do not understand a kind should preserve the value and use a generic permission option treatment.
Status
Tool calls progress through different statuses during their lifecycle:
Custom or future status values can be used when Clients can display a generic progress state. Custom status values MUST begin with _; unknown non-underscore statuses are reserved for future ACP variants.
Content
Tool calls can produce different types of content:
Tool call content type values can also be custom or future variants. Implementations should preserve unknown content payloads when storing, replaying, proxying, or forwarding tool calls, and otherwise render a generic content item or ignore the item if no safe display is available.
Regular Content
Standard content blocks like text, images, or resources:
{
"type": "content",
"content": {
"type": "text",
"text": "Analysis complete. Found 3 issues."
}
}Display-only Terminals
A terminal content item references an Agent-owned terminal by ID:
{
"type": "terminal",
"terminalId": "term_001"
}
The item is only a display anchor. terminalId is required. Optional nullable
_meta is scoped to this content item; omission and null both mean that no
item metadata was provided. terminalId is unique within the session, remains
stable for the terminal’s lifetime, and MUST NOT be reused for a different
terminal. It is independent of toolCallId, even when an Agent uses the same
string for both. The reference and the terminal’s session updates may arrive in
either order, so Clients retain state for a first-seen terminalId.
Agents create and update stored terminal state with terminal_update:
{
"sessionUpdate": "terminal_update",
"terminalId": "term_001",
"command": "cargo test",
"cwd": "/home/user/project",
"output": {
"data": "cnVubmluZyB0ZXN0cw0K"
},
"exitStatus": {
"exitCode": 0,
"signal": null
}
}
terminal_update is an upsert keyed by required terminalId. Other fields are
patches: omission leaves the previous value unchanged, null clears it, and a
concrete value replaces it. On a first-seen ID, omitted fields start unknown or
empty.
commanddescribes the command being run. Agents SHOULD provide it on the first update when applicable.cwdis the command’s working directory and MUST be absolute when supplied.outputis an authoritative replacement snapshot. Its requireddatais RFC 4648 base64-encoded bytes with JSON SchemacontentEncoding: "base64". A concrete snapshot is the complete byte sequence the Agent wants the Client to retain for the terminal at that point. It replaces all previously stored bytes; Clients MUST NOT merge or splice bytes from the previous snapshot into it. Optional nullableoutput._metais scoped to that snapshot; omission andnullboth mean no snapshot metadata was provided.- A concrete
exitStatusmarks the terminal as exited. Its optional nullableexitCodeandsignalreport known exit information. Its optional nullable_metais scoped to that exit information. For all three fields, omission andnullboth mean the value was not provided. Conventional POSIX signal names includeSIGTERM,SIGKILL, andSIGINT; other platforms may use platform-specific names. Terminal exit and tool call status are independent. - The top-level
_metais terminal-scoped and follows the same patch semantics.
For example, a process terminated by a POSIX termination signal can report
"exitStatus": { "signal": "SIGTERM" }.
For live output, Agents send terminal_output_chunk:
{
"sessionUpdate": "terminal_output_chunk",
"terminalId": "term_001",
"data": "cGFzc2VkDQo="
}
terminalId and data are required. Each data value is an independently RFC
4648 base64-encoded byte chunk with JSON Schema contentEncoding: "base64". Clients
decode each chunk separately and append the decoded bytes in received order for
that terminalId; they MUST NOT concatenate encoded strings before
decoding. Chunk boundaries may split UTF-8 code points or terminal escape
sequences, so decoders retain parser state across chunks. Optional nullable
_meta is chunk-scoped; omission and null both mean no chunk metadata was
provided.
Diffs
File modifications shown as diffs. A diff always includes structured file changes and can optionally include renderable patch text.
changes is authoritative for affected absolute paths and operations. patch,
when present, provides renderable text for some or all of those changes and MUST
be consistent with changes. Agents SHOULD provide patch whenever feasible.
Clients MUST handle diffs where patch is omitted or null.
{
"type": "diff",
"changes": [
{
"operation": "modify",
"path": "/home/user/project/src/config.json",
"fileType": "text",
"mimeType": "application/json"
}
],
"patch": {
"format": "git_patch",
"text": "diff --git /home/user/project/src/config.json /home/user/project/src/config.json\n--- /home/user/project/src/config.json\n+++ /home/user/project/src/config.json\n@@ -1,3 +1,3 @@\n {\n- \"debug\": false\n+ \"debug\": true\n }\n"
}
}Omit patch when there is no useful text patch, such as a same-path binary
update or symlink target change:
{
"type": "diff",
"changes": [
{
"operation": "modify",
"path": "/home/user/project/assets/logo.png",
"fileType": "binary",
"mimeType": "image/png"
}
]
}Following the Agent
Tool calls can report file locations they’re working with, enabling Clients to implement “follow-along” features that track which files the Agent is accessing or modifying in real-time.
{
"path": "/home/user/project/src/main.py",
"line": 42
}Last updated Oct 08, 2026