Control Protocol
Control requests let a host program steer a running Claude Code process.
They travel on the same JSON line channel as the stream messages.
The Agent SDK uses them, for example to change the model or to answer a permission question.
A host sends a line with type set to control_request and request.subtype set to set_model. Claude Code answers with a control_response line.
The protocol is on whenever you start claude -p --input-format stream-json --output-format stream-json. You write requests to stdin and read answers on stdout. You choose which requests to send.
Subtypes
The schema does not mark the direction of each request. Only the Agent SDK pages describe most of them, and no other docs page does, so every row has the status
2.1.311; for the 2.1.311 additions, chunk-7ew55hkc.js:19068 for ui_prompt_paint, chunk-7ew55hkc.js:18942 for the ui_attach list, chunk-7ew55hkc.js:17074 for turn_handoff, chunk-7ew55hkc.js:17966 for oauth_token_refresh, chunk-7ew55hkc.js:17747 for mcpMount, chunk-7ew55hkc.js:13704 for background_color, and chunk-7ew55hkc.js:15654 for the transcript note).
subtype | Status | What It Does |
|---|---|---|
initialize | Undocumented: Only the program shows this item. It can change without notice. | Starts the SDK session with hooks, MCP servers, and agent settings. |
interrupt | Undocumented: Only the program shows this item. It can change without notice. | Stops the turn that runs now. |
can_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for permission to use a tool with the given input. |
set_ | Undocumented: Only the program shows this item. It can change without notice. | Sets the permission mode. |
set_ | Undocumented: Only the program shows this item. It can change without notice. | Sets the model for the next turns. |
set_ | Undocumented: Only the program shows this item. It can change without notice. | No description in the program schema. |
rename_ | Undocumented: Only the program shows this item. It can change without notice. | Sets the title of the session. |
set_ | Undocumented: Only the program shows this item. It can change without notice. | No description in the program schema. |
mcp_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the state of all MCP server connections. Since 2., live sends a success reply only to the clients attached at that moment, when the CLI writes through a cloud session or Remote Control worker. The reply is not stored, and a reply sent while the stream is down is lost. |
file_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for @ file suggestions for a partial path. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the use of the context window by category. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the cost summary that / prints in print mode. |
list_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the models that the worker lets you choose. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the data of /, with plan limits when they are known. Since 2., each entry of session. in the reply also has cache and cache (integers, see Stream JSON Messages). |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the rows of the / screen as text. |
export_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the conversation as the text that / writes. |
list_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the cloud sessions of the signed-in account. The CLI reads them with its own sign-in. Refused in a cloud-hosted session. New in 2.. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the title, branch, and environment kind of one cloud session. Refused in a cloud-hosted session. New in 2.. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for one page of the stored transcript of a cloud session that the account owns. Refused in a cloud-hosted session. New in 2.. Since 2. the schema warns that a page is not always the whole transcript: for a compacted session the service sends the rows its last compaction kept, then the compact_ entry and what followed, so the messages that the compaction summarized can be on no page. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the rows and switches of the / dialog. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the rows of the / menu. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the state of the / dialog. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the browsers that have a connection to Claude in Chrome. |
select_ | Undocumented: Only the program shows this item. It can change without notice. | Switches Claude in Chrome to the browser that you name. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the state of the / dialog. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the version of the binary. |
mcp_ | Undocumented: Only the program shows this item. It can change without notice. | Calls an MCP tool without a model turn. |
rewind_ | Undocumented: Only the program shows this item. It can change without notice. | Undoes the file changes made since a user message. |
cancel_ | Undocumented: Only the program shows this item. It can change without notice. | Removes a waiting async user message from the queue. |
read_ | Undocumented: Only the program shows this item. It can change without notice. | Reads a file of the session, for a remote sidebar viewer. |
list_ | Undocumented: Only the program shows this item. It can change without notice. | No description in the program schema. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the git diff of the workspace. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Reads the current plan of plan mode. |
seed_ | Undocumented: Only the program shows this item. It can change without notice. | Seeds the cache of read files with a path and a time. |
hook_ | Undocumented: Only the program shows this item. It can change without notice. | Delivers a hook callback with its input. |
register_ | Undocumented: Only the program shows this item. It can change without notice. | Registers the hooks of a device with the worker. |
upload_ | Undocumented: Only the program shows this item. It can change without notice. | Sends a hook template before the device hooks register. |
remote_ | Undocumented: Only the program shows this item. It can change without notice. | A cloud client says which tools it serves. |
remote_ | Undocumented: Only the program shows this item. It can change without notice. | Forwards one step of a tool call to the attached machine. |
remote_ | Undocumented: Only the program shows this item. It can change without notice. | Calls a plumbing tool on the attached machine. |
remote_ | Undocumented: Only the program shows this item. It can change without notice. | Checks that an announced machine is still alive. |
remote_ | Undocumented: Only the program shows this item. It can change without notice. | A new worker asks the client to announce its tools again. |
turn_ | Undocumented: Only the program shows this item. It can change without notice. | Hands a turn to a cloud worker. Since 2. it can have requires_ (string): the request_ of a rewind_ request that the client sent first. A worker that reads it appends the turn only if that rewind was its last one, the last user or assistant message is still the one the rewind left at the end, and nothing waits to be appended ahead of the turn. Otherwise it appends nothing and answers an error that starts with invalid_ and then unknown, other, moved_, or lines_. A worker announces that it reads the member with requires_ in turn_. A worker without that key ignores the member, so send it only once every worker that could read it has the key. |
mcp_ | Undocumented: Only the program shows this item. It can change without notice. | Carries one MCP message for an MCP server that the SDK hosts. |
mcp_ | Undocumented: Only the program shows this item. It can change without notice. | Replaces the set of MCP servers that the host manages. |
reload_ | Undocumented: Only the program shows this item. It can change without notice. | Reloads plugins from disk. |
reload_ | Undocumented: Only the program shows this item. It can change without notice. | Reloads skills from disk. |
reload_ | Undocumented: Only the program shows this item. It can change without notice. | Reads the output style folders again. |
register_ | Undocumented: Only the program shows this item. It can change without notice. | Adds a folder as a working folder root, and can reload CLAUDE., skills, and plugins. |
set_ | Undocumented: Only the program shows this item. It can change without notice. | Moves the session to a new working folder, like /. |
claim_ | Undocumented: Only the program shows this item. It can change without notice. | No description in the program schema. |
mcp_ | Undocumented: Only the program shows this item. It can change without notice. | Reconnects an MCP server that failed. |
mcp_ | Undocumented: Only the program shows this item. It can change without notice. | Turns an MCP server on or off. |
mcp_ | Undocumented: Only the program shows this item. It can change without notice. | No description in the program schema. |
set_ | Undocumented: Only the program shows this item. It can change without notice. | Sets or clears the permission mode of one MCP server. |
set_ | Undocumented: Only the program shows this item. It can change without notice. | Tells the session which Claude in Chrome browser to prefer. |
set_ | Undocumented: Only the program shows this item. It can change without notice. | Pauses or resumes prompt suggestions. |
stop_ | Undocumented: Only the program shows this item. It can change without notice. | Stops a running task. |
background_ | Undocumented: Only the program shows this item. It can change without notice. | No description in the program schema. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Reads the last 8 KiB of the output of a background task. |
apply_ | Undocumented: Only the program shows this item. It can change without notice. | Merges settings into the flag settings layer. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Returns the merged settings and the settings of each source. |
update_ | Undocumented: Only the program shows this item. It can change without notice. | Writes settings through the writer of Claude Code. |
get_ | Undocumented: Only the program shows this item. It can change without notice. | Returns the hooks that the read-only / menu shows. |
list_ | Undocumented: Only the program shows this item. It can change without notice. | Returns the permission rules and workspace folders that / lists. Since 2. the source of a rule can be mcp (string). |
elicitation | Undocumented: Only the program shows this item. It can change without notice. | Asks the SDK consumer to handle an MCP elicitation. |
request_ | Undocumented: Only the program shows this item. It can change without notice. | Asks the SDK consumer to show a dialog and return the choice. |
submit_ | Undocumented: Only the program shows this item. It can change without notice. | Sends a / report with the transcript and a cleaned error log. |
remote_ | Undocumented: Only the program shows this item. It can change without notice. | Asks the host for a fresh work secret for Remote Control. |
oauth_ | Undocumented: Only the program shows this item. It can change without notice. | Asks the host for a fresh OAuth token after a 401 error. Since 2. the request can also have kind:, and then the CLI asks for the second token that authorizes the cloud-sessions API. A host that set CLAUDE_ answers it, and the token must belong to the same account and organization as the sign-in token. Without kind, the request is for the claude.ai sign-in token. |
host_ | Undocumented: Only the program shows this item. It can change without notice. | Asks the host for a fresh provider credential after a credential failure. |
message_ | Undocumented: Only the program shows this item. It can change without notice. | Records a thumbs up or down for a message. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | A remote screen joins the session. Since 2. its answers list can name ui_ too, and holds up to 6 names (5 before). |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | A remote screen leaves the session. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | No description in the program schema. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | A press on a button or link that a plugin drew for a remote screen. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the screen modules of a plugin. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | A change in an input that a plugin drew for a remote screen. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | A pick in a select that a plugin drew for a remote screen. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | Asks for the list of open panes. Since 2. each pane in the reply can have background_ (string): what the surface paints under the body of the pane while it is shown. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | The person chose which open pane the screen shows. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | The keyboard moved between the prompt box and a pane. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | The person closed a pane on a remote screen. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | The person scrolled a site that a remote screen draws. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | The keyboard moved in a site that a remote screen draws. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | No description in the program schema. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | A plugin reads the draft and cursor of the prompt box. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | A plugin puts text in the prompt box as a draft. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | New in 2.. Sets one layer of styled runs over the draft in the prompt box and changes nothing else: not the draft, the caret, or its undo history. A change of the draft drops every layer. The request has surface (desktop, mobile, or vscode), client_, layer, text, and decorations. Each decoration has start, end, and the optional color, background, dim, bold, italic, underline, and strikethrough. Without text, the request clears the layer. The reply is {painted:. It goes only to a client whose ui_ named ui_. If there is no answer in 5 seconds, the result is is. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | A plugin or the engine shows a suggestion in the prompt box. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | No description in the program schema. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | An edit in the prompt box of a remote screen. |
ui_ | Undocumented: Only the program shows this item. It can change without notice. | A remote prompt box asks what the plugins add to its autocomplete list. |
success | Undocumented: Only the program shows this item. It can change without notice. | The request was handled. |
error | Undocumented: Only the program shows this item. It can change without notice. | The request failed or was refused. |
Some requests go from Claude Code to the host, such as can_use_tool, elicitation, hook_callback, request_user_dialog, and the token refresh requests.
The host must answer them or the turn waits.
Example
{"type":"control_request","request_id":"req-1","request":{"subtype":"set_model","model":"sonnet"}}
{"type":"control_response","response":{"subtype":"success","request_id":"req-1","response":{"model":"claude-sonnet-5-5"}}}
The set_model request has a model field.
A success reply has subtype: "success" and the request_id.
Since 2.1.307 a set_model success reply also has response.model, the model the session now uses.
An alias comes back as the full model ID.
An error reply has subtype: "error", the request_id, an error text, and sometimes an error_code.
Source: the program (strings of the request and response builders). The fields of the other subtypes are not listed here.
We ran both examples on 2.1.309 with claude -p --input-format stream-json --output-format stream-json --verbose (see Probes). The reply matches.
The request_id is any text you pick, and the reply repeats it.
set_model takes an alias such as sonnet or a full model ID. It replies success even for a name the API does not know, and response.model repeats that name, so the error shows up on the next request.
The Agent SDK's setModel() waits up to 15 seconds for this reply (5 seconds before 2.1.307). Source: the release notes.
A reply can come before the first system init line, because init appears only after the first user message.
{"type":"control_request","request_id":"req-2","request":{"subtype":"get_binary_version"}}
{"type":"control_response","response":{"subtype":"success","request_id":"req-2","response":{"version":"2.1.305","buildTime":"2026-10-20T18:04:27Z"}}}
{"type":"control_request","request_id":"req-3","request":{"subtype":"set_permission_mode","mode":"nonsense"}}
{"type":"control_response","response":{"subtype":"error","request_id":"req-3","error":"Cannot set permission mode: must be one of acceptEdits, auto, bypassPermissions, default, dontAsk, plan","error_code":"invalid_mode"}}
An unknown subtype gives "error":"Unsupported control request subtype: <name>" with no error_code.
How It Works
Each reply is a single control_response that matches the request_id.
A sender can cancel its own request with control_cancel_request.
Long requests send control_request_progress lines first.
Exact Fields
The exact fields: https://clawdipedia.cc/schemas/claude-code-control-protocol.json, made from the program's own validators. It has a Request and a Response definition for each subtype.
It lists every field of this release, so build on the fields it names and look each one up there before you rely on it.
Related Pages
- Headless and Print Mode
- Stream JSON Messages
- MCP Runtime for the MCP requests (
mcp_status,mcp_call,mcp_toggle)