Skip to main content

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

Undocumented: Only the program shows this item. It can change without notice.
. Source: the program (the bundled schema of 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).

subtypeStatusWhat 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_use_tool
Undocumented: Only the program shows this item. It can change without notice.
Asks for permission to use a tool with the given input.
set_permission_mode
Undocumented: Only the program shows this item. It can change without notice.
Sets the permission mode.
set_model
Undocumented: Only the program shows this item. It can change without notice.
Sets the model for the next turns.
set_max_thinking_tokens
Undocumented: Only the program shows this item. It can change without notice.
No description in the program schema.
rename_session
Undocumented: Only the program shows this item. It can change without notice.
Sets the title of the session.
set_color
Undocumented: Only the program shows this item. It can change without notice.
No description in the program schema.
mcp_status
Undocumented: Only the program shows this item. It can change without notice.
Asks for the state of all MCP server connections. Since 2.1.309, liveReply: true 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_suggestions
Undocumented: Only the program shows this item. It can change without notice.
Asks for @ file suggestions for a partial path.
get_context_usage
Undocumented: Only the program shows this item. It can change without notice.
Asks for the use of the context window by category.
get_session_cost
Undocumented: Only the program shows this item. It can change without notice.
Asks for the cost summary that /usage prints in print mode.
list_models
Undocumented: Only the program shows this item. It can change without notice.
Asks for the models that the worker lets you choose.
get_usage
Undocumented: Only the program shows this item. It can change without notice.
Asks for the data of /usage, with plan limits when they are known. Since 2.1.311, each entry of session.model_usage in the reply also has cacheCreationEphemeral5mInputTokens and cacheCreationEphemeral1hInputTokens (integers, see Stream JSON Messages).
get_status
Undocumented: Only the program shows this item. It can change without notice.
Asks for the rows of the /status screen as text.
export_conversation
Undocumented: Only the program shows this item. It can change without notice.
Asks for the conversation as the text that /export writes.
list_cloud_sessions
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.1.307.
get_cloud_session
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.1.307.
get_cloud_session_transcript
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.1.307. Since 2.1.311 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_boundary entry and what followed, so the messages that the compaction summarized can be on no page.
get_memory_dialog
Undocumented: Only the program shows this item. It can change without notice.
Asks for the rows and switches of the /memory dialog.
get_skills_dialog
Undocumented: Only the program shows this item. It can change without notice.
Asks for the rows of the /skills menu.
get_chrome_dialog
Undocumented: Only the program shows this item. It can change without notice.
Asks for the state of the /chrome dialog.
get_chrome_browsers
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_chrome_browser
Undocumented: Only the program shows this item. It can change without notice.
Switches Claude in Chrome to the browser that you name.
get_sandbox_dialog
Undocumented: Only the program shows this item. It can change without notice.
Asks for the state of the /sandbox dialog.
get_binary_version
Undocumented: Only the program shows this item. It can change without notice.
Asks for the version of the binary.
mcp_call
Undocumented: Only the program shows this item. It can change without notice.
Calls an MCP tool without a model turn.
rewind_files
Undocumented: Only the program shows this item. It can change without notice.
Undoes the file changes made since a user message.
cancel_async_message
Undocumented: Only the program shows this item. It can change without notice.
Removes a waiting async user message from the queue.
read_file
Undocumented: Only the program shows this item. It can change without notice.
Reads a file of the session, for a remote sidebar viewer.
list_directory
Undocumented: Only the program shows this item. It can change without notice.
No description in the program schema.
get_workspace_diff
Undocumented: Only the program shows this item. It can change without notice.
Asks for the git diff of the workspace.
get_plan
Undocumented: Only the program shows this item. It can change without notice.
Reads the current plan of plan mode.
seed_read_state
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_callback
Undocumented: Only the program shows this item. It can change without notice.
Delivers a hook callback with its input.
register_device_hooks
Undocumented: Only the program shows this item. It can change without notice.
Registers the hooks of a device with the worker.
upload_device_hook_template
Undocumented: Only the program shows this item. It can change without notice.
Sends a hook template before the device hooks register.
remote_tools_announce
Undocumented: Only the program shows this item. It can change without notice.
A cloud client says which tools it serves.
remote_tool_call
Undocumented: Only the program shows this item. It can change without notice.
Forwards one step of a tool call to the attached machine.
remote_plumbing_call
Undocumented: Only the program shows this item. It can change without notice.
Calls a plumbing tool on the attached machine.
remote_tools_probe
Undocumented: Only the program shows this item. It can change without notice.
Checks that an announced machine is still alive.
remote_tools_reannounce
Undocumented: Only the program shows this item. It can change without notice.
A new worker asks the client to announce its tools again.
turn_handoff
Undocumented: Only the program shows this item. It can change without notice.
Hands a turn to a cloud worker. Since 2.1.311 it can have requires_rewind_request_id (string): the request_id of a rewind_conversation 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_handoff: required_rewind_ and then unknown, other, moved_on, or lines_waiting. A worker announces that it reads the member with requires_rewind_request_id: true in turn_handoff_available. A worker without that key ignores the member, so send it only once every worker that could read it has the key.
mcp_message
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_set_servers
Undocumented: Only the program shows this item. It can change without notice.
Replaces the set of MCP servers that the host manages.
reload_plugins
Undocumented: Only the program shows this item. It can change without notice.
Reloads plugins from disk.
reload_skills
Undocumented: Only the program shows this item. It can change without notice.
Reloads skills from disk.
reload_output_styles
Undocumented: Only the program shows this item. It can change without notice.
Reads the output style folders again.
register_repo_root
Undocumented: Only the program shows this item. It can change without notice.
Adds a folder as a working folder root, and can reload CLAUDE.md, skills, and plugins.
set_cwd
Undocumented: Only the program shows this item. It can change without notice.
Moves the session to a new working folder, like /cd.
claim_session
Undocumented: Only the program shows this item. It can change without notice.
No description in the program schema.
mcp_reconnect
Undocumented: Only the program shows this item. It can change without notice.
Reconnects an MCP server that failed.
mcp_toggle
Undocumented: Only the program shows this item. It can change without notice.
Turns an MCP server on or off.
mcp_read_resource
Undocumented: Only the program shows this item. It can change without notice.
No description in the program schema.
set_mcp_permission_mode_override
Undocumented: Only the program shows this item. It can change without notice.
Sets or clears the permission mode of one MCP server.
set_chrome_browser_hints
Undocumented: Only the program shows this item. It can change without notice.
Tells the session which Claude in Chrome browser to prefer.
set_prompt_suggestions_paused
Undocumented: Only the program shows this item. It can change without notice.
Pauses or resumes prompt suggestions.
stop_task
Undocumented: Only the program shows this item. It can change without notice.
Stops a running task.
background_tasks
Undocumented: Only the program shows this item. It can change without notice.
No description in the program schema.
get_task_output
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_flag_settings
Undocumented: Only the program shows this item. It can change without notice.
Merges settings into the flag settings layer.
get_settings
Undocumented: Only the program shows this item. It can change without notice.
Returns the merged settings and the settings of each source.
update_settings
Undocumented: Only the program shows this item. It can change without notice.
Writes settings through the writer of Claude Code.
get_hooks_listing
Undocumented: Only the program shows this item. It can change without notice.
Returns the hooks that the read-only /hooks menu shows.
list_permission_rules
Undocumented: Only the program shows this item. It can change without notice.
Returns the permission rules and workspace folders that /permissions lists. Since 2.1.311 the source of a rule can be mcpMount (string).
elicitation
Undocumented: Only the program shows this item. It can change without notice.
Asks the SDK consumer to handle an MCP elicitation.
request_user_dialog
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_feedback
Undocumented: Only the program shows this item. It can change without notice.
Sends a /feedback report with the transcript and a cleaned error log.
remote_control_work_secret
Undocumented: Only the program shows this item. It can change without notice.
Asks the host for a fresh work secret for Remote Control.
oauth_token_refresh
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.1.311 the request can also have kind: "sessions", and then the CLI asks for the second token that authorizes the cloud-sessions API. A host that set CLAUDE_CODE_SDK_HAS_SESSIONS_OAUTH_REFRESH 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_auth_token_refresh
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_rated
Undocumented: Only the program shows this item. It can change without notice.
Records a thumbs up or down for a message.
ui_attach
Undocumented: Only the program shows this item. It can change without notice.
A remote screen joins the session. Since 2.1.311 its answers list can name ui_prompt_paint too, and holds up to 6 names (5 before).
ui_detach
Undocumented: Only the program shows this item. It can change without notice.
A remote screen leaves the session.
ui_render
Undocumented: Only the program shows this item. It can change without notice.
No description in the program schema.
ui_press
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_client_module
Undocumented: Only the program shows this item. It can change without notice.
Asks for the screen modules of a plugin.
ui_input
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_select
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_panes
Undocumented: Only the program shows this item. It can change without notice.
Asks for the list of open panes. Since 2.1.311 each pane in the reply can have background_color (string): what the surface paints under the body of the pane while it is shown.
ui_pane_show
Undocumented: Only the program shows this item. It can change without notice.
The person chose which open pane the screen shows.
ui_pane_focus
Undocumented: Only the program shows this item. It can change without notice.
The keyboard moved between the prompt box and a pane.
ui_close
Undocumented: Only the program shows this item. It can change without notice.
The person closed a pane on a remote screen.
ui_scroll
Undocumented: Only the program shows this item. It can change without notice.
The person scrolled a site that a remote screen draws.
ui_focus
Undocumented: Only the program shows this item. It can change without notice.
The keyboard moved in a site that a remote screen draws.
ui_copy
Undocumented: Only the program shows this item. It can change without notice.
No description in the program schema.
ui_prompt_read
Undocumented: Only the program shows this item. It can change without notice.
A plugin reads the draft and cursor of the prompt box.
ui_prompt_fill
Undocumented: Only the program shows this item. It can change without notice.
A plugin puts text in the prompt box as a draft.
ui_prompt_paint
Undocumented: Only the program shows this item. It can change without notice.
New in 2.1.311. 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_id, layer, text, and decorations. Each decoration has start, end, and the optional color, backgroundColor, dimColor, bold, italic, underline, and strikethrough. Without text, the request clears the layer. The reply is {painted: boolean}. It goes only to a client whose ui_attach named ui_prompt_paint. If there is no answer in 5 seconds, the result is isPainted: false.
ui_prompt_suggest
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_read_selection
Undocumented: Only the program shows this item. It can change without notice.
No description in the program schema.
ui_prompt_edit
Undocumented: Only the program shows this item. It can change without notice.
An edit in the prompt box of a remote screen.
ui_prompt_autocomplete
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​

Change the model, then read the reply
{"type":"control_request","request_id":"req-1","request":{"subtype":"set_model","model":"sonnet"}}
Reply from Claude Code
{"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.

Ask for the version
{"type":"control_request","request_id":"req-2","request":{"subtype":"get_binary_version"}}
Reply
{"type":"control_response","response":{"subtype":"success","request_id":"req-2","response":{"version":"2.1.305","buildTime":"2026-10-20T18:04:27Z"}}}
A request that fails
{"type":"control_request","request_id":"req-3","request":{"subtype":"set_permission_mode","mode":"nonsense"}}
Error reply
{"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.