The SDK bundles a native Claude Code binary for your platform as an optional dependency such as @anthropic-ai/claude-agent-sdk-darwin-arm64. Most installs need no separate Claude Code install. The SDK version tracks the bundled Claude Code version. SDK v0.3.191 bundles Claude Code v2.1.191, so a feature on this page that requires a Claude Code version needs the SDK release with the same patch number or later. If your package manager skips optional dependencies, the SDK throws Native CLI binary for <platform>-<arch> not found; set pathToClaudeCodeExecutable to a separately installed claude binary instead.If your package manager doesn’t apply npm’s libc field, as Yarn 1.x doesn’t, you get both the glibc and musl platform packages on Linux, roughly doubling the install size. On Agent SDK v0.2.141 or later, the SDK still launches the correct variant. To reclaim the space in a container image, delete the platform package that doesn’t match the libc where your app runs; for a glibc runtime on x64, that’s rm -rf node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl. On a development machine the deletion is temporary, since Yarn reinstalls the package on the next dependency change.
When you compile your application into a single-file executable with bun build --compile, the SDK cannot resolve the bundled CLI binary at runtime. require.resolve does not work inside the compiled executable’s $bunfs virtual filesystem, so the SDK throws Native CLI binary for <platform>-<arch> not found.To work around this, embed the platform binary as a file asset, extract it to a real path at startup with extractFromBunfs(), and pass that path to pathToClaudeCodeExecutable.The extractFromBunfs() helper requires @anthropic-ai/claude-agent-sdk v0.3.144 or later. The example below builds for macOS on Apple Silicon:
import binPath from "@anthropic-ai/claude-agent-sdk-darwin-arm64/claude" with { type: "file" };import { extractFromBunfs } from "@anthropic-ai/claude-agent-sdk/extract";import { query } from "@anthropic-ai/claude-agent-sdk";const cliPath = extractFromBunfs(binPath);for await (const message of query({ prompt: "Hello", options: { pathToClaudeCodeExecutable: cliPath },})) { console.log(message);}
extractFromBunfs() copies the embedded binary out of the compiled executable’s virtual filesystem to a per-user temp directory and returns the real path. Outside a compiled executable it returns the input path unchanged, so the same code runs in development without modification.Each compiled executable embeds a single platform’s binary. Match the platform package in the import to your --target:
To cross-compile, install the non-matching platform package, for example npm install @anthropic-ai/claude-agent-sdk-linux-x64 --force.
On Windows, the binary subpath is claude.exe, for example @anthropic-ai/claude-agent-sdk-win32-x64/claude.exe.
Import the /core entry when you bundle the Agent SDK
If your application bundles the Agent SDK together with its own dependencies, import from @anthropic-ai/claude-agent-sdk/core instead of the package root. The /core entry requires TypeScript Agent SDK v0.3.282 or later, and its types require TypeScript 5.0 or later.The /core entry exports the same query(), startup(), tool(), createSdkMcpServer(), and resolveSettings() as the root entry, along with the functions that rename, tag, and delete sessions, AbortError, the runtime constants, and every type. It adds no names of its own. To keep the code your application loads small, /core leaves out some root exports, including prewarm(), the InMemorySessionStore class, and the helpers that list, read, fork, import, and summarize sessions. If you need one of them, use the root entry instead.The root entry inlines its own copies of zod and @modelcontextprotocol/sdk. The /core entry imports them from your node_modules at the ranges the Agent SDK’s peerDependencies declare, so a bundle that already includes them doesn’t carry a second copy. Import from either the root or /core in a given process, not both: they are separate bundles, and loading both gives you two copies of the Agent SDK’s classes and state.
Pre-warms the CLI subprocess by spawning it and completing the initialize handshake before a prompt is available. The returned WarmQuery handle accepts a prompt later and writes it to an already-ready process, so the first query() call resolves without paying subprocess spawn and initialization cost inline. If you don’t know the session’s working directory yet, use prewarm() instead.
function startup(params?: { options?: Options; initializeTimeoutMs?: number;}): Promise<WarmQuery>;
Optional configuration object. Same as the options parameter to query()
initializeTimeoutMs
number
Maximum time in milliseconds to wait for subprocess initialization. Defaults to 60000. If initialization does not complete in time, the promise rejects with a timeout error
Returns a Promise<WarmQuery> that resolves once the subprocess has spawned and completed its initialize handshake.Of the hook_progress messages a SessionStart or Setup hook emits before the handshake completes, you get only the newest, which carries all of the hook’s output so far. startup() holds that message, the hook’s hook_started message, and anything else the subprocess emits before the handshake completes. The held messages reach you once you call .query() on the WarmQuery and iterate the result.
Call startup() early, for example on application boot, then call .query() on the returned handle once a prompt is ready. This moves subprocess spawn and initialization out of the critical path.
import { startup } from "@anthropic-ai/claude-agent-sdk";// Pay startup cost upfrontconst warm = await startup({ options: { maxTurns: 3 } });// Later, when a prompt is ready, this is immediatefor await (const message of warm.query("What files are here?")) { console.log(message);}
Alpha. Starts a Claude Code process as a spare before you know which session it will serve, so you can bind it to a session later with claim(). Use it in an application that boots before the user picks a folder. Requires TypeScript Agent SDK v0.3.282 or later.prewarm() completes the same initialize handshake as startup(), with the process waiting in options.cwd when you set it and otherwise in a private temporary directory under your Claude Code config directory. The session’s working directory, its SessionStart hooks, its stdio MCP servers, and its CLAUDE.md and git context wait for the claim. A spare holds roughly 230 to 260 MB of memory while it waits. If your spawnClaudeCodeProcess runs Claude Code on another machine or in a container, set options.cwd to a directory that exists there for the spare to wait in.
function prewarm(params?: { options?: Options; initializeTimeoutMs?: number;}): Promise<SpareProcess>;
options and initializeTimeoutMs mean the same as for startup(), except that options.cwd sets only the directory the spare waits in. The promise resolves with a SpareProcess once the process has completed its initialize handshake. prewarm() throws if options sets resume, continue, or forkSession, because a spare has no session yet. Everything a claim can’t set, such as mcpServers, hooks, canUseTool, settingSources, systemPrompt, and plugins, is fixed for the life of the spare, so keep one spare per distinct set of those options and prewarm again when they change.
Prewarm on application boot, then claim the spare when the user starts a session:
import { prewarm } from "@anthropic-ai/claude-agent-sdk";// On application boot, before the session's folder is knownconst spare = await prewarm({ options: { maxTurns: 3 } });// Later, when the user starts a session in a folderconst claimedQuery = spare.claim({ prompt: "What files are here?", options: { cwd: "/path/to/project" },});spare.claimed.catch((error: Error) => { // Unless the message starts with "option_not_applied", the prompt didn't run: // start this session with query() instead console.error("Claim failed:", error.message);});try { for await (const message of claimedQuery) { console.log(message); }} catch (error) { // After a refused claim, the claimed query throws once it has yielded the error result console.error(`Session ended with an error: ${error}`);}
Optional extras. annotations provides MCP behavioral hints to clients. searchHint is a one-line capability phrase shown in the deferred-tool list when tool search is active. alwaysLoad: true keeps this tool’s full schema in the initial prompt instead of deferring it
Defined in @modelcontextprotocol/sdk/types.js. All fields are optional hints; clients should not rely on them for security decisions.
Field
Type
Default
Description
title
string
undefined
Human-readable title for the tool
readOnlyHint
boolean
false
If true, the tool does not modify its environment
destructiveHint
boolean
true
If true, the tool may perform destructive updates. Set destructiveHint: true explicitly on any tool you mark always_ask, or the auto mode classifier can approve that tool’s calls in place of your canUseTool callback. Leaving destructiveHint unset isn’t enough, because Claude Code treats an unset destructiveHint as false when it handles always_ask calls, although the MCP specification’s default is true
idempotentHint
boolean
false
If true, repeated calls with the same arguments have no additional effect (only meaningful when readOnlyHint is false)
openWorldHint
boolean
true
If true, the tool interacts with external entities (for example, web search). If false, the tool’s domain is closed (for example, a memory tool)
When true, this server’s tools stay in the initial prompt instead of being deferred behind tool search. Combines with per-tool alwaysLoad in tool()
options.timeout
number
Timeout in milliseconds for this server’s tool calls. Claude Code applies it to this server in place of MCP_TOOL_TIMEOUT. Pass a whole number of at least 1000. Claude Code ignores other values. Requires TypeScript Agent SDK v0.3.248 or later
Display title: custom title, most recent prompt, auto-generated summary, or first prompt
lastModified
number
Last modified time in milliseconds since epoch
fileSize
number | undefined
Session file size in bytes. Only populated for local JSONL storage
customTitle
string | undefined
The session’s custom title when one is set, for example with --name, /rename, a hook’s sessionTitle output, or renameSession(). Otherwise the AI-generated session title, if the session has one
Print the 10 most recent sessions for a project. Results are sorted by lastModified descending, so the first item is the newest. Omit dir to search across all projects.
Message role. "system" appears only when options.includeSystemMessages is true
uuid
string
Unique message identifier
session_id
string
Session this message belongs to
message
unknown
Raw message payload from the transcript
parent_tool_use_id
string | null
For subagent messages, the tool_use_id of the Agent or Skill tool call that started the subagent. null for main-session messages and older sessions
parent_agent_id
string | null
For messages from a nested subagent, the agentId of the subagent that spawned it. null for main-session messages, messages from top-level subagents, and older sessions. Requires Claude Code v2.1.202 or later
Copies a session’s transcript into a new session so you can take the conversation in another direction while the original stays unchanged. To branch from an earlier point in the conversation, pass upToMessageId.
function forkSession( sessionId: string, options?: ForkSessionOptions): Promise<ForkSessionResult>;
Project directory path. When omitted, searches all project directories
options.upToMessageId
string
undefined
Copy the transcript up to and including the message with this uuid: a value from getSessionMessages(), or a uuid you set on a streamed SDKUserMessage. When omitted, copies the whole transcript
options.title
string
undefined
Title for the fork. When omitted, the SDK derives one from the original session, followed by (fork)
Returns { sessionId }, the new session’s UUID. Pass it as resume to continue the fork. The fork doesn’t include the original session’s file checkpoints, so you can’t rewind it to a checkpoint captured before the fork.forkSession() throws when:
sessionId is not a UUID
the session cannot be found, or has no messages
upToMessageId matches no message in the transcript
Resolves the effective Claude Code settings for a given directory using the same merge engine as the CLI, without spawning the Claude CLI. Use it to inspect what configuration a query() call would see before invoking one.
This function is alpha and its API may change before stabilization.
The snapshot differs from what a live query() session applies:
policyHelper: resolveSettings() reads MDM sources, including macOS plist and Windows HKLM/HKCU, but doesn’t execute the admin-configured policyHelper subprocess.
Server-managed settings: resolveSettings() doesn’t fetch server-managed settings. Pass them as options.serverManagedSettings to include them.
defaultMode: the snapshot returns permissions.defaultMode as-is from every tier, so it can include the 'auto' and 'bypassPermissions' values from project and local settings, which a live session ignores.
function resolveSettings( options?: ResolveSettingsOptions): Promise<ResolvedSettings>;
Which filesystem sources to load. Pass [] to skip user, project, and local settings. Endpoint-managed policy loads in all cases. resolveSettings() includes server-managed settings only when you pass options.serverManagedSettings
options.managedSettings
Settings
undefined
Policy-tier settings supplied by the embedding host. Follows the same rules as managedSettings in Options, except that resolveSettings() doesn’t execute a configured policyHelper, so the snapshot can include settings that a live session drops
options.serverManagedSettings
Settings
undefined
Server-managed settings payload from /api/claude_code/settings. Non-restrictive keys pass through unfiltered
The example below resolves settings for a project directory and prints the source that controls the cleanup period. On a machine where no settings file sets cleanupPeriodDays, both printed lines show undefined for the value, which is the expected output rather than an error.
When true, generate one-line progress summaries for subagents and forward them on task_progress events via the summary field. Applies to foreground and background subagents
allowDangerouslySkipPermissions
boolean
false
Enable bypassing permissions. Required when using permissionMode: 'bypassPermissions', at startup or later through setPermissionMode(). See plan mode for how it interacts with permissionMode: 'plan'
allowedTools
string[]
[]
Tools to auto-approve without prompting, apart from reads from network paths. This does not restrict Claude to only these tools. If you name one of the task-tracking tools here, Claude Code also opts the session in. Other unlisted tools fall through to permissionMode and canUseTool. Use disallowedTools to block tools. See Permissions
Custom permission function, invoked only when the permission flow falls through to a prompt. Not invoked for calls auto-approved by allowedTools, allow rules, or permissionMode. An allow rule doesn’t pre-approve the actions no mode auto-approves. See CanUseTool for details
continue
boolean
false
Continue the most recent conversation
cwd
string
process.cwd()
Current working directory
debug
boolean
false
Enable debug mode for the Claude Code process
debugFile
string
undefined
Write debug logs to a specific file path. Implicitly enables debug mode
disallowedTools
string[]
[]
Tools to deny. A bare name such as "Bash" removes the tool from Claude’s context. A scoped rule such as "Bash(rm *)" leaves the tool available and denies matching calls in every permission mode, including bypassPermissions, for the command as written. See Permissions
effort
'low' | 'medium' | 'high' | 'xhigh' | 'max'
undefined
Controls how much effort Claude puts into its response. Works with adaptive thinking to guide thinking depth. See adjust the effort level
Environment variables. When set, this replaces the subprocess environment instead of merging with process.env, so pass { ...process.env, YOUR_VAR: 'value' } to keep inherited variables like PATH. See Handle slow or stalled API responses for an example of this pattern, and Environment variables for variables the underlying CLI reads. Set CLAUDE_AGENT_SDK_CLIENT_APP to identify your app in the User-Agent header
executable
'bun' | 'deno' | 'node'
Auto-detected
JavaScript runtime to use
executableArgs
string[]
[]
Arguments to pass to the executable
extraArgs
Record<string, string | null>
{}
Additional arguments
fallbackModel
string
undefined
Model to use if the primary model fails. Accepts a comma-separated list. For the order and the cap, see Fallback model chains. For guidance, see Choose a model
forkSession
boolean
false
When resuming with resume, fork to a new session ID instead of continuing the original session
forwardSubagentText
boolean
false
Forward subagent text and thinking blocks as assistant and user messages with parent_tool_use_id set, so consumers can render a nested transcript. Without this option, Claude Code omits the text and thinking blocks of a subagent that runs in the foreground. For nested subagents, skills with context: fork, and the Claude Code version each needs, see Follow subagent messages
Include hook lifecycle events in the message stream as SDKHookStartedMessage, SDKHookProgressMessage, and SDKHookResponseMessage. Lifecycle events for SessionStart and Setup hooks are always included and don’t need this option. Some hook events, such as Notification, SessionEnd, PreCompact, and PostCompact, never produce an SDKHookStartedMessage, even with this option. For those events, Claude Code still emits an SDKHookProgressMessage while a command hook that runs for more than a second produces output, and emits an SDKHookResponseMessage only when a hook that runs in the background finishes
includePartialMessages
boolean
false
Include partial message events
loadTimeoutMs
number
60000
Alpha. Timeout in milliseconds for each sessionStore.load() and sessionStore.listSubkeys() call during resume materialization. If the adapter doesn’t settle within this window, the query fails instead of hanging. Ignored when sessionStore is not set
managedSettings
Settings
undefined
Policy-tier settings your host process supplies to the spawned session. On machines with admin-deployed managed settings, Claude Code ignores these unless the admin’s highest-priority managed source sets parentSettingsBehavior: 'merge', and never merges them while a policyHelper supplies managed settings. Merged values pass through a restrictive-only filter; Restrict parent settings covers what the filter admits and the allowManaged*Only locks. A host that sets CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST has three keys read straight from this payload instead: its model configuration on Claude Code v2.1.222 or later, modelPricing when no managed source sets it on v2.1.246 or later, and its ENABLE_TOOL_SEARCH env entry on v2.1.247 or later
maxBudgetUsd
number
undefined
Stop the query when the client-side cost estimate reaches this USD value. The estimate can pass this value, so leave headroom. Counts only the call’s own spend; totals restored from a resumed session don’t count. For accuracy caveats and reset behavior, see Track cost and usage
maxThinkingTokens
number
undefined
Deprecated: Use thinking instead. Maximum tokens for thinking process
Callback for handling MCP elicitation requests. Called when an MCP server requests user input and no hook handles it first. When not provided, unhandled elicitation requests are declined automatically
outputFormat
{ type: 'json_schema', schema: JSONSchema }
undefined
Define output format for agent results. See Structured outputs for details
Permission mode for the session. If you omit it and nothing else sets a permission mode, such as a permissions.defaultMode setting, the session starts in default. See Permission modes
permissionPromptToolName
string
undefined
MCP tool name for permission prompts
permissionPrompts
'host' | 'none'
'host'
Who answers permission prompts: 'host' routes them to your canUseTool callback or the permissionPromptToolName tool, and 'none'denies the calls that would have prompted. Requires Claude Code v2.1.259 or later
persistSession
boolean
true
When false, disables session persistence to disk. Sessions cannot be resumed later
planModeInstructions
string
undefined
Custom workflow instructions for plan mode. When permissionMode is 'plan', this string replaces the default plan-mode workflow body. The CLI still wraps it with the read-only enforcement preamble and the ExitPlanMode protocol footer
Load custom plugins from local paths. See Plugins for details
projectConfigRoot
string
undefined
Absolute path of the trusted checkout that cwd is a worktree of. Claude Code reads project settings, .mcp.json, and the project’s .claude/ commands, agents, skills, workflows, routines, and output styles from this directory instead of cwd, and sets CLAUDE_PROJECT_DIR to it. Hooks, helper scripts such as apiKeyHelper, and stdio MCP servers start with this directory as their working directory. CLAUDE.md files and .claude/rules/ still load from cwd. Requires Claude Code v2.1.275 or later
promptSuggestions
boolean
false
Enable prompt suggestions. After a turn, Claude Code emits a prompt_suggestion message carrying a predicted next user prompt. Claude Code generates no suggestion for some turns, such as while your account is close to or at its usage limit. See When Claude Code skips suggestions
resume
string
undefined
Session ID to resume
resumeDropsTurn
string
undefined
With resumeSessionAt: the prompt UUID of the turn the truncating resume intends to discard. Claude Code refuses the resume when the discarded range contains anything not attributable to that turn, such as absorbed queued messages or task notifications, and names the --resume-drops-turn flag in the rejection message. Only the Agent SDK and print-mode resumes read the pair. Requires Claude Code v2.1.223 or later
Alpha. Flush mode for sessionStore. Ignored when sessionStore is not set
settings
string | Settings
undefined
Inline settings object, a settings file path, or an inline JSON string. Populates the flag-settings layer in the precedence order. Change at runtime with applyFlagSettings()
Control which filesystem settings to load. Pass [] to disable user, project, and local settings. Endpoint-managed policy loads regardless; server-managed settings are fetched when the session authenticates with an organization credential on an eligible configuration. See Use Claude Code features
skills
string[] | 'all'
undefined
Skills available to the session. Pass 'all' to enable every discovered skill, or a list of skill names. Pass exact names only. On Agent SDK v0.3.221 or later, the SDK rejects malformed and wildcard-form names with an error before starting the Claude Code process. When set, the SDK adds the Skill tool to allowedTools automatically. If you also pass tools, include 'Skill' in that list. See Skills
spawnClaudeCodeProcess
(options: SpawnOptions) => SpawnedProcess
undefined
Custom function to spawn the Claude Code process. Use to run Claude Code in VMs, containers, or remote environments
stderr
(data: string) => void
undefined
Callback for stderr output
strictMcpConfig
boolean
false
Use only the servers passed in mcpServers and ignore project .mcp.json, user settings, plugin-provided MCP servers, and claude.ai connectors
System prompt configuration. Pass a string for a custom prompt, or { type: 'preset', preset: 'claude_code' } to use Claude Code’s system prompt. Pass an array of strings with the exported SYSTEM_PROMPT_DYNAMIC_BOUNDARY constant between the static and per-request parts to cache the static part of a custom prompt. When using the preset object form, add append to extend it with additional instructions, and set excludeDynamicSections: true to move per-session context into the first user message for better prompt-cache reuse across machines. Set snapshot: false to rebuild the prompt on every request instead of reusing the prompt the session recorded on its first request. To set snapshot on a custom prompt, pass the { type: 'custom', prompt } form. The { type: 'custom' } form and the snapshot field require TypeScript Agent SDK v0.3.257 or later
taskBudget
{ total: number }
undefined
Alpha. API-side task budget in tokens. When set, the model is told its remaining token budget so it can pace tool use and wrap up before the limit
Controls Claude’s thinking/reasoning behavior. See ThinkingConfig for options
title
string
undefined
Display title for the session. When resuming via resume or continue, the resumed session’s persisted title takes precedence; use renameSession() to retitle an existing session
toolAliases
Record<string, string>
undefined
Map built-in tool names to MCP tool names so Claude calls your MCP implementation in place of the built-in. For example, { Bash: 'mcp__workspace__bash' }
Tool configuration. Pass an array of tool names or use the preset to get Claude Code’s default tools
verbatimPrompts
boolean
false
Deliver every prompt as written. The SDK sends each user message with client_composed: true. See client_composed for what Claude Code skips on those messages. Use this option when your prompt text includes content the end user didn’t type. For per-turn control, leave it off and set client_composed on individual streamed messages instead. Requires TypeScript Agent SDK v0.3.280 or later and Claude Code v2.1.248 or later; the Claude Code version bundled with those SDK versions satisfies the Claude Code requirement
The CLI subprocess reads several environment variables that control API timeouts and stall detection. Pass them through the env option:
import { query } from "@anthropic-ai/claude-agent-sdk";const result = query({ prompt: "Analyze this code", options: { env: { ...process.env, API_TIMEOUT_MS: "120000", CLAUDE_CODE_MAX_RETRIES: "2", CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS: "120000", }, },});
API_TIMEOUT_MS: how long each request attempt can wait for response headers, in milliseconds. It doesn’t limit how long a streaming response runs after the headers arrive. Default 600000. Applies to the main loop and all subagents.
CLAUDE_CODE_MAX_RETRIES: maximum API retries. Default 10, capped at 15. Each retry gets its own API_TIMEOUT_MS window.For unattended runs that need to wait through longer outages, set CLAUDE_CODE_RETRY_WATCHDOG=1: it retries transient capacity errors indefinitely and, on Claude Code v2.1.199 or later, raises the default for other transient errors to 300 and removes the cap on this variable.
CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS: stall watchdog for subagents. While the stream watchdog is on, the default is CLAUDE_STREAM_IDLE_TIMEOUT_MS plus 5 minutes, which comes to 600000 unless you raise that variable. With the stream watchdog off, the default is 600000. Before v2.1.257, the default was always 600000.The timer resets on each stream event. On a stall, Claude Code aborts the subagent and reports the stall to the parent. For a background subagent, it also marks the task failed and attaches any partial result.
CLAUDE_ENABLE_STREAM_WATCHDOG with CLAUDE_STREAM_IDLE_TIMEOUT_MS: stream watchdog that aborts the request when headers have arrived but the response body stops streaming. The watchdog is on by default for all providers; set CLAUDE_ENABLE_STREAM_WATCHDOG=0 to disable it. CLAUDE_STREAM_IDLE_TIMEOUT_MS defaults to 300000 and is clamped to that minimum. After the abort, Automatic retries covers what Claude Code does, based on how far the response had progressed.While the watchdog waits out a response that a gateway behind ANTHROPIC_BASE_URL holds open with keep-alive pings, a host that sets includePartialMessages keeps receiving pingstream events, so read those frames as liveness rather than timing the session out on silence. Before v2.1.257, the frames stopped 5 minutes after the last real stream event.
Interrupts the query. Only available in streaming input mode. When the CLI advertises the interrupt_receipt_v1 capability in SDKSystemMessage.capabilities, resolves with an SDKControlInterruptResponse listing the messages that were pending when the interrupt arrived. Resolves undefined on CLIs before v2.1.205
rewindFiles(userMessageId, options?)
Restores files to their state at the specified user message. Pass { dryRun: true } to preview changes. Requires enableFileCheckpointing: true. See File checkpointing
setPermissionMode()
Changes the permission mode (only available in streaming input mode)
setModel()
Changes the model (only available in streaming input mode). Passing undefined or the string "default" resets to Claude Code’s default model. A session in auto mode changes to default mode if the new model doesn’t support auto mode
setMaxThinkingTokens()
Deprecated: Use the thinking option instead. Changes the maximum thinking tokens. Passing null resets thinking to the session default: a mid-session override is cleared, and thinking stays off for sessions that have it disabled
applyFlagSettings(settings)
Merges settings into the session’s flag settings layer at runtime (only available in streaming input mode). See applyFlagSettings()
updateSettings(source, settings)
Writes one allowlisted key to the project’s local settings file or your user settings file, so the value persists for later sessions. See updateSettings(). Requires TypeScript SDK v0.3.257 or later, which bundles Claude Code v2.1.257
initializationResult()
Returns the full initialization result including supported commands, models, account info, and output style configuration
reinitialize()
Re-sends the initialize control request to the running CLI and returns a fresh result instead of the cached first-connect result. Use it after a transport gap, such as reattaching to a session after a disconnect, so pending permission requests reach your canUseTool callback again. Make the callback idempotent per request ID, because a request whose response was lost is dispatched again. Requires Claude Code v2.1.195 or later
supportedCommands()
Returns available commands. From Agent SDK v0.3.216 the list reflects mid-session command changes; see SDKCommandsChangedMessage
Returns the status of connected MCP servers as McpServerStatus[]
getContextUsage(opts?)
Returns an SDKControlGetContextUsageResponse breaking down the session’s context window usage by category, skill, and tool. With the default detail, it includes the data /context shows in an interactive session, computed with token-counting API requests that don’t appear in the message stream; see how these requests are handled. The detail option requires Agent SDK v0.3.257 or later
readFile(path, options?)
Reads a file from the session’s filesystem. Claude Code resolves the path against cwd; What readFile() can read lists the files it serves. Pass { maxBytes } to change the read cap (default 1 MB, ceiling 10 MB) and { encoding: 'base64' } for binary files such as images. Resolves with an SDKControlReadFileResponse, or null on permission denial, a missing file, or a transport error. Requires TypeScript SDK v0.2.121 or later
reloadPlugins(options?)
Reloads plugins from disk, so plugins you install or edit mid-session reach the running session. Resolves with an SDKControlReloadPluginsResponse listing the session’s commands, subagents, plugins, and MCP server status. Requires Agent SDK v0.2.85 or later. The holdOnCacheImpact option requires Agent SDK v0.3.268 or later. The addPlugins option requires Agent SDK v0.3.301 or later
reloadSkills()
Reloads skills from disk, so skills you add or edit mid-session become available to the running session. Resolves with an SDKControlReloadSkillsResponse listing the skills available after the reload. Requires Agent SDK v0.3.163 or later
reloadOutputStyles()
Re-reads output styles from disk, so a style file you add or edit mid-session becomes available to the running session. Resolves with an SDKControlReloadOutputStylesResponse listing the style names available after the reload. Requires Agent SDK v0.3.261 or later
seedReadState(path, mtime)
Marks a file as already read so a later Edit doesn’t fail with File has not been read yet. See seedReadState(). Requires TypeScript SDK v0.2.83 or later
accountInfo()
Returns account information
reconnectMcpServer(serverName)
Reconnect an MCP server by name. If the name also matches an entry in a settings file such as .mcp.json or ~/.claude.json, Claude Code reconnects the server you configured through mcpServers or setMcpServers(), not the settings-file entry. That resolution order requires Claude Code v2.1.257 or later
toggleMcpServer(serverName, enabled)
Enable or disable an MCP server by name, with the same name resolution as reconnectMcpServer(). Disabling a server disconnects it and removes its tools. See toggleMcpServer() for the Claude Code version this needs for each kind of server
setMcpServers(servers)
Replace the MCP servers this method manages: servers added through it and in-process SDK servers. Resolves with an McpSetServersResult naming which servers were added and removed, and any errors; that section says which other servers stay connected
setMcpPermissionModeOverride(serverName, mode)
Overrides the permission mode for one MCP server’s tools with a stricter mode than the session’s, or clears the override with null. Only available in streaming input mode. See setMcpPermissionModeOverride(). Requires TypeScript SDK v0.3.187 or later
readMcpResource(serverName, uri)
Alpha. Reads one MCP Apps ui:// resource from a connected MCP server so your application can render a tool’s widget. Resolves with an SDKControlMcpReadResourceResponse. Requires TypeScript Agent SDK v0.3.280 or later
streamInput(stream)
Stream input messages to the query for multi-turn conversations
stopTask(taskId)
Stop a running background task by ID
backgroundTasks(toolUseId?)
Moves the running Bash commands and subagents that the turn is waiting on to the background, the same as pressing Ctrl+B in the interactive terminal. See backgroundTasks(). Requires TypeScript SDK v0.2.139 or later
close()
Close the query and terminate the underlying process. Forcefully ends the query and cleans up all resources
Overrides the permission mode for one MCP server’s tools with a stricter mode than the session’s, or clears the override with null. Use it when a session runs in a mode that skips per-action prompts but one server’s tools should still be reviewed. Requires TypeScript SDK v0.3.187 or later.Pass one of three values as mode:
'default': Claude Code evaluates that server’s tool calls as Manual mode does.
'auto': Claude Code routes that server’s tool calls through the auto mode classifier. Claude Code rejects this value when the classifier isn’t available to the session.
null: clears the override.
The override only takes effect while the session is in a mode that skips per-action prompts: bypassPermissions or auto. In any other session mode Claude Code ignores the override, so it can never widen what the session allows.The promise resolves with { warning } when no server by that name is known yet. Claude Code stores the override anyway and applies it once a server with that exact name connects, so the warning is a typo check, not a failure.Only available in streaming input mode, the same constraint as setModel() and setPermissionMode().
Marks a file as already read so a later Edit doesn’t fail with File has not been read yet. Use it when your application has dropped an earlier Read result from the conversation context and Claude will edit that file next. Requires TypeScript SDK v0.2.83 or later.Pass mtime as the file’s modification time at the moment of that earlier read, in whole milliseconds since the epoch, for example Math.floor(stat.mtimeMs). If the file on disk changed after that time, Claude Code skips the mark.The promise resolves whether or not the file was marked, so a resolved promise doesn’t tell you which happened.
Moves the running Bash commands and subagents that the turn is waiting on to the background, the same as pressing Ctrl+B in the interactive terminal. Pass the toolUseId of a tool call to background only the Bash command or subagent that call started, or omit it to background every foreground task. Requires TypeScript SDK v0.2.139 or later.Each backgrounded tool call returns to Claude immediately with a running-in-the-background result, the turn continues, and Claude Code emits an SDKTaskNotificationMessage when the task finishes.In a session where background tasks are enabled, the promise resolves to a boolean:
true: a task was backgrounded, or you omitted toolUseId.
false: the toolUseId you passed matched no foreground task.
If background tasks are disabled for the session, such as with CLAUDE_CODE_DISABLE_BACKGROUND_TASKS, the promise rejects instead and nothing is backgrounded.
Changes settings on a running session without restarting the query. Use it when a setting that has no dedicated setter needs to change mid-session, such as tightening permissions after the agent reads untrusted input. setModel() and setPermissionMode() are dedicated setters for those two keys; applyFlagSettings() is the general form that accepts any subset of the settings keys, and passing model here behaves the same as setModel().Only some keys take effect mid-session:
Applied on the next turn: effortLevel, ultracode, permissions, hooks, skillOverrides, fastMode, agent. Switching agent also applies that agent’s model override and hooks on the next turn. Its system prompt applies on the next turn, or, in a session that reuses a recorded system prompt, once the session is compacted.
Applied during the current turn: model. If you switch model while Claude is working on a turn, the response Claude is already generating finishes on the old model, and the rest of the turn, starting with the next call Claude Code makes to the model, uses the new one. Subagents keep their own model. Before v2.1.212, a mid-turn switch waited for the next turn.
No effect mid-session: the system prompt options. These are resolved once at startup, so the running session keeps the original value even though the call succeeds. To change them, start a new session.
effortLevel accepts an effort level name. It also accepts "ultracode", which requests xhigh effort with ultracode on. applyFlagSettings() declares effortLevel without that value, so in TypeScript pass { ultracode: true, effortLevel: "xhigh" } for the same result, or the ultracode key alone to turn ultracode on at the session’s current effort level. The ultracode value requires Claude Code v2.1.203 or later and is accepted only by applyFlagSettings(), not by the effortLevel key in a settings file. Before v2.1.284, the ultracode key alone also set the level to xhigh.The values are written to the flag-settings layer, merged over what the inline settings option of query() set at startup. This is the same tier the on-page precedence section calls programmatic options.Successive calls shallow-merge top-level keys. A second call with { permissions: {...} } replaces the entire permissions object from the prior call rather than deep-merging into it.To clear a key you set with applyFlagSettings(), pass null for that key. Most keys then fall back first to a value that the settings option of query() set at startup, then to lower-precedence sources. A cleared model resets to Claude Code’s default model, even when a settings file sets model. Passing undefined has no effect because JSON serialization drops it.Three keys besides model reset session state instead of falling back:
effortLevel: null returns the session to the model’s default effort level, not to the effort option of query() or an effortLevel from a settings file.
agent: null runs the main thread with no agent, starting with the next turn, rather than restoring the agent option of query() or an agent from a settings file. If the cleared agent had applied its own model, the session returns to the model it resolved at startup.
ultracode: null turns ultracode off, as false does, rather than restoring an ultracode value from a settings file. The session keeps its current effort level, so pass effortLevel in the same call to change it.
Only available in streaming input mode, the same constraint as setModel() and setPermissionMode().The example below switches the active model mid-session, then clears the override so the model resets to Claude Code’s default model.
import { query } from "@anthropic-ai/claude-agent-sdk";const q = query({ prompt: messageStream });// Override the model for the rest of the sessionawait q.applyFlagSettings({ model: "claude-opus-4-6" });// Later: clear the override; the model resets to Claude Code's defaultawait q.applyFlagSettings({ model: null });
applyFlagSettings() is TypeScript-only. The Python SDK does not expose an equivalent method.
Writes one allowlisted key to a settings file on disk, so the value persists for later sessions that load that source. Each source accepts one key, with a string value:
"localSettings": accepts outputStyle and merges it into the project’s local settings file, .claude/settings.local.json. The new style takes effect on the session’s next request.
"userSettings": accepts effortLevel and saves it as the default effort level for the session’s current model, under modelSettings in your user settings file. Passing max writes nothing, because max is session-only. The running session keeps its current effort level either way, so call applyFlagSettings() when you also want to change that. This source requires TypeScript SDK v0.3.277 or later, which bundles Claude Code v2.1.277.
The call rejects when the request carries any other key, when the session runs over a remote transport, and when the session’s settingSources exclude the source you name. Deleting a key isn’t supported.
Disabling a server disconnects it and removes its tools from the session. For servers you added mid-session and for in-process servers, this depends on your Claude Code version:
A stdio, SSE, or HTTP server you added mid-session with setMcpServers(): removing its tools requires Claude Code v2.1.285 or later.
An in-process server you created with createSdkMcpServer(), whether you passed it in mcpServers or with setMcpServers(): disconnecting it and removing its tools requires Claude Code v2.1.286 or later. Disabling one also fails its tool calls that are still running, so Claude receives an error result for each of them immediately, without waiting for your handler to return.
Handle returned by startup(). The subprocess is already spawned and initialized, so calling query() on this handle writes the prompt directly to a ready process with no startup latency.
Alpha. Handle returned by prewarm(): a started Claude Code process that isn’t bound to a session yet and can be claimed once. Requires TypeScript Agent SDK v0.3.282 or later.
Bind the spare to a session in options.cwd and send its first message. Returns a Query synchronously, as query() does. Can only be called once
claimed
Resolves with the session’s working directory and ID once Claude Code accepts the claim. Rejects when Claude Code refuses the claim, when the process exited or was closed first, and, with a message that starts with option_not_applied, when the session is running without the model or maxThinkingTokens you asked for
exited
Settles when the process exits, claimed or not. Replace a spare that exits before you claim it
close()
Terminate the process. Before a claim this discards the spare and rejects claimed
options.cwd is required. A claim can also set additionalDirectories, model, permissionMode, maxThinkingTokens, a flag-settings overlay in settings, appendSystemPrompt, title, agents, and per-session tokens in env.Claude Code can refuse a claim, for example for a folder that doesn’t exist or one whose project settings set env, agent, or model. After a refusal, a prompt that claim() already sent gets an error result whose text starts with not_claimed, and the returned query then throws. Wrap the query’s loop in a try block to continue past the throw. When claimed rejects with a message that starts with option_not_applied, the session is running without the model or maxThinkingTokens you asked for. After any other rejection your prompt hasn’t run, so start the session with query() instead.
hooks_applied reports whether Claude Code registered the hooks that the initialize request carried. The SDK sends that request once when the session starts and again on each reinitialize() call. The field requires Agent SDK v0.3.238 or later.Claude Code omits the field when the request carried no hooks. When the request carried hooks, the value depends on whether the request is the session’s first initialize and, for a repeated one, on how it reached the session:
true: Claude Code registered the hooks. A session’s first initialize returns this value. A repeated initialize sent over the CLI’s stdin also returns true. In that case the hooks in the new request replace the hooks registered earlier.
false: Claude Code ignored the hooks. A repeated initialize sent to a remote session returns this value, so a second client that joins a session can’t replace the hooks the first client registered.
Before Agent SDK v0.3.238, the response never carried the field, and Claude Code ignored hooks on every repeated initialize.The request’s sdkMcpServerManifests field and the response’s sdk_mcp_manifests_parked field are for the in-process SDK MCP servers you created with createSdkMcpServer(). Your application doesn’t set or read either field.claude_code_version is the Claude Code version of the process that runs the session’s turns. It is the same value the SDKSystemMessage init message carries, so you can read the CLI version before the first turn.
The field requires Agent SDK v0.3.296 or later, which bundles Claude Code v2.1.296.
If the field is undefined and you set pathToClaudeCodeExecutable, point it at Claude Code v2.1.296 or later.
The response always reports fast_mode_state, and when something blocks fast mode, fast_mode_disabled_reason carries the reason code alongside it, so you can explain the blocked state instead of re-deriving availability. Both behaviors require Claude Code v2.1.219 or later. Before v2.1.219, the response omitted fast_mode_state when fast mode wasn’t available and never carried a reason. For the reason codes and their meanings, see fast_mode_disabled_reason on the result message.The control-response wrapper for a successful initialize also carries a pending_permission_requests array. The field is on the response wrapper itself, not in the SDKControlInitializeResponse payload above. Each entry is a complete control_request message with the same { type: "control_request", request_id, request } shape the session streams for permission requests while running.The array lists the permission requests that this Claude Code process has issued and not yet resolved. The SDK reads the array for you and dispatches each entry to your canUseTool callback, the same redelivery that reinitialize() triggers after a transport gap. Handle repeated request IDs idempotently, because an entry can repeat a request the callback already received before the connection dropped.The array is always present on a successful initialize response and is empty when this process has no unresolved permission request. Requires Claude Code v2.1.268 or later. Earlier versions could omit the field, so if you parse the wire protocol yourself, treat a missing field as an older CLI rather than as proof that nothing is pending.
The interrupt receipt: the value interrupt() resolves with on a CLI that advertises the interrupt_receipt_v1 capability in SDKSystemMessage.capabilities. Requires Claude Code v2.1.205 or later. Earlier CLIs answer the interrupt with an empty success payload, so interrupt() resolves to undefined.
type SDKControlInterruptResponse = { still_queued: string[]; cancelled?: string[];};
still_queued lists the UUIDs of the user messages that were pending when the interrupt arrived: messages still in the queue, plus any messages Claude Code had already taken off the queue for the next turn. Once the session’s first turn has started, Claude Code processes the listed messages after the interrupt unless you cancel them first, and can merge several into one turn. If you interrupt before the first turn starts, Claude Code aborts that turn as soon as it starts, and the listed messages in that turn get no response.Use the receipt to decide whether to resend anything. A listed message that you don’t cancel enters the conversation whether or not it gets a response, so resending it delivers it to Claude twice.Interpret the list with these caveats:
Only messages that were enqueued with a UUID appear. An empty array doesn’t mean nothing else will run.
Only main-thread messages are listed. Messages addressed to a subagent are out of scope.
The list can include UUIDs your client never sent, such as session-scoped scheduled task triggers. Ignore UUIDs you don’t recognize instead of treating them as an error.
A client that drives the CLI’s control protocol directly, rather than through interrupt(), can set cancel_queued: true on the interrupt control request. Claude Code v2.1.219 and later advertises support with the interrupt_cancel_queued_v1 capability in SDKSystemMessage.capabilities; older CLIs ignore the field and leave queued messages to run as usual. Such an interrupt also cancels every message that would otherwise be listed under still_queued: the receipt lists them under cancelled instead, still_queued is empty, and none of them run.The cancelled list carries the same caveats as still_queued. The interrupt() method never sends cancel_queued, so receipts it resolves with don’t carry cancelled.The receipt is a snapshot taken at the moment the interrupt is processed, and on a clean interrupt it arrives before the interrupted turn’s SDKResultMessage. Read the receipt rather than inspecting the queue after that result: the loop starts the next queued turn immediately, so the queue you inspect after the result has already changed.
Return type of getContextUsage(). With the default detail, the response includes the payload Claude Code renders for the /context command in an interactive session. Alongside the token counts, that payload carries display fields such as color and gridRows that Claude Code uses to draw the /context usage grid.The method’s optional detail argument chooses how Claude Code counts each category. The detail argument requires Agent SDK v0.3.257 or later.
'full': the default. Claude Code counts each category with token-counting API requests. These requests don’t appear in the message stream, so cost tracking that reads the stream won’t see them. On the Anthropic API, token counting isn’t billed.
'summary': pass { detail: 'summary' } to get an answer from the last response’s usage and local estimates instead. No token-count requests go out, and the per-category numbers are approximate.
When you send /context as a prompt instead of calling the method, Claude Code attaches an SDKContextUsage payload to the context_usage field of the assistant message that delivers the result. That field requires Agent SDK v0.3.232 or later.In SDKControlGetContextUsageResponse, categories[].id, mcpInstructions, and the pluginId and path fields of agents and skills.skillFrontmatter entries require Agent SDK v0.3.304 or later.
Read token attribution from the collection fields:
categories holds the per-category totals. Each entry’s kind classifies the row with the same values as SDKContextUsageCategory. Classify rows on it rather than on the display name. The field requires Agent SDK v0.3.268 or later.
mcpTools and agents attribute tokens to individual MCP tools and subagents.
memoryFiles lists each loaded memory file with its cost.
skills.skillFrontmatter attributes the skill listing’s tokens to each included skill. The per-skill counts measure each skill’s listing entry as Claude Code actually sends it, which can be shorter than the skill’s full frontmatter. Compare skills.totalSkills with skills.includedSkills to see whether every discovered skill made it into the listing.
totalTokens is the session’s current context usage, and maxTokens is the window that usage is measured against. That window is the model’s context window, or the lower auto-compaction window when one applies. rawMaxTokens carries the same value as maxTokens, and percentage is totalTokens as a rounded percentage of that window. apiUsage holds the usage from the latest API response, not a running total for the session.Claude Code leaves the optional deferredBuiltinTools, systemTools, and systemPromptSections diagnostics unset, so expect them to be absent even though the type declares them.
Find a row by ID, a server’s instruction tokens, or an entry’s plugin and file
MCP server instructions are the usage notes that connected servers supply and Claude Code adds to context, and the mcp_instructions row of categories counts their tokens. Use these getContextUsage() fields to pick out one categories row by id, split the mcp_instructions tokens by server, or find the plugin and file behind an agent or skill entry:
Field
Found on
What it holds
id
Each categories row
The row’s identifier, one of the values the response type lists, such as mcp_instructions. Match on id to pick out one row, or on kind to group rows. A later Claude Code version can send a value your installed types don’t list, so treat an id you don’t recognize as absent
mcpInstructions
The response
One { serverName, tokens } entry per connected MCP server that supplies instructions, or an empty array when none does. The tokens values are estimates that add up to the mcp_instructions row’s tokens. serverName is the name that mcpServerStatus() reports for that server
pluginId
agents and skills.skillFrontmatter entries
Names the plugin the entry comes from, as an ID in the form name@marketplace, and is absent for an entry that doesn’t come from a plugin. When the plugin didn’t come from a marketplace, the part after @ names its origin instead, such as inline for one you loaded through the plugins option
path
agents and skills.skillFrontmatter entries
Absolute path of the file that defines the agent or skill, on the machine where Claude Code runs. The field is absent when no file defines the entry, for example an agent from the agents option or a skill built into Claude Code
As an example of matching on id, this sample finds the mcp_instructions row:
// q is the Query object that query() returnedconst usage = await q.getContextUsage();// undefined if no connected server supplies instructionsconst row = usage.categories.find((c) => c.id === "mcp_instructions");
contents holds the file text, or base64 data when you requested encoding: 'base64'; the response’s encoding field is set to 'base64' in that case. absPath is the resolved absolute path. truncated is set when the file was longer than the maxBytes cap and the contents were cut at that limit.
readFile() serves a narrower set of files than the Read tool:
A regular file inside one of the session’s working directories, such as cwd and additionalDirectories
A few of Claude Code’s own files for the session, such as tool results
Read deny and ask rules still block a matching path, and a broad Read allow rule doesn’t open the rest of the filesystem to readFile(). For anything else the call resolves with null.
The collection fields describe the session after the call:
commands, agents, and mcpServers: the session’s commands, subagents, and MCP server status, in the same shapes that supportedCommands(), supportedAgents(), and mcpServerStatus() return. supportedAgents() keeps returning the list captured at initialization, so read agents here for the set after a reload
plugins: each loaded plugin with its name and install path. version repeats what the plugin’s manifest declares and is plugin-author-controlled, so validate it before trusting it. It’s omitted when the manifest declares none
error_count: the number of errors from loading plugins
Pass { holdOnCacheImpact: true } to reloadPlugins() to hold a reload that would invalidate the conversation’s prompt cache instead of applying it. Claude Code runs the check that the interactive /reload-plugins command makes before it warns about the cache cost. The option requires Agent SDK v0.3.268 or later. A Claude Code executable older than v2.1.268, such as one you point pathToClaudeCodeExecutable at, ignores the option and applies the reload.When you pass the option, read held to learn what happened:
true: the reload wasn’t applied, and the collection fields describe the session as it still is. cache_impact says what applying would change. To apply anyway, call reloadPlugins() again without the option.
false: the check found no cache impact, and the reload was applied.
Absent: you didn’t pass the option, or the Claude Code executable is older than v2.1.268 and applied the reload.
cache_impact is present only alongside held: true. mcp_servers_added and mcp_servers_removed name the plugin MCP servers the reload would register or drop, as scoped plugin:<plugin>:<server> names. The names are plugin-authored, so validate them before showing them. lsp_tool_change says whether applying would add or remove the LSP tool, or null when it would do neither. The may- forms mean the check couldn’t fully see the pending plugin set.
To load plugin folders that weren’t in the plugins option at startup, pass them to reloadPlugins() as addPlugins, a list of SdkPluginConfig entries whose path is absolute. Claude Code loads the new folders and reloads the session’s existing plugins in one pass. Each added plugin’s MCP servers connect too, unless you set skipMcpDiscovery on that folder’s entry. Requires Agent SDK v0.3.301 or later and Claude Code v2.1.301 or later.This example adds one folder to a running query q and prints the install path of every plugin the session has loaded when the call returns:
If the folder loaded, the printed list includes /opt/my-app/plugins/reports, and the plugin’s commands and subagents appear in result.commands and result.agents.An added folder stays part of the session. When you call reloadPlugins() again, Claude Code reloads it with the other plugins, and you don’t pass it in addPlugins again.If reloadPlugins() rejects, none of the addPlugins folders are added, so pass them in addPlugins again when you retry. When the rejection has one of the following causes, the session keeps the plugins it already had:
A relative path or a malformed entry: the error message says add_plugins must be a list of { type: "local", path } entries with absolute paths. Claude Code refuses the whole list over one bad entry, so pass every entry as { type: "local", path } with an absolute path
An administrator has turned on disableSideloadFlags in your managed settings: the message says reload_plugins add_plugins is disabled by managed settings (disableSideloadFlags). To load the folder, ask that administrator to remove the setting
The sandbox couldn’t be rebuilt: with sandboxing on, Claude Code rebuilds the sandbox configuration so that sandboxed shell commands can’t write to the folders you add. The message says the sandbox could not be rebuilt to keep shell commands out of this folder. Check that your sandbox settings still form a valid configuration
If you pass holdOnCacheImpact and the call resolves with held: true, the addPlugins folders aren’t added. To add them anyway, call reloadPlugins() again with the same addPlugins list and without holdOnCacheImpact.When the call resolves without held: true and a folder is still missing from result.plugins, start by checking for these causes:
The folder doesn’t exist or its plugin failed to load: result.error_count is 1 or higher. The folder stays part of the session even so. After you fix the folder, call reloadPlugins() again to load it, this time without listing it in addPlugins
The Claude Code executable is older than v2.1.301: an executable older than v2.1.301 ignores addPlugins and reloads only the plugins the session already had. Check claude_code_version on the init message, and run an executable at v2.1.301 or later
Pass readMcpResource() the server name as mcpServerStatus() reports it and a ui:// URI, such as the ui.resourceUri a tool declares in its _meta. The call rejects for any other URI scheme, for an SDK MCP server your application hosts itself, and for a server that isn’t connected. It’s available when the init message’s capabilities include mcp_read_resource_v1.Each contents entry is one content item as the server sent it, minus any _meta key under the com.anthropic/ prefix, which is reserved for Claude Code. blob holds base64 data for a binary item, and _meta is the item’s own _meta, where an MCP Apps server puts the resource’s ui.csp and ui.permissions.The contents are untrusted third-party HTML, so render them in a sandbox.
Natural language description of when to use this agent
tools
No
Array of allowed tool names. If omitted, inherits every tool available to subagents. To preload Skills into the agent’s context, use the skills field rather than listing 'Skill' here
disallowedTools
No
Array of tool names to explicitly disallow for this agent. MCP server-level patterns are also accepted: mcp__server or mcp__server__* removes every tool from that server, and mcp__* removes every MCP tool from any server
prompt
Yes
The agent’s system prompt
model
No
Model override for this agent. Accepts an alias such as 'fable', 'opus', 'sonnet', 'haiku', 'inherit', or a full model ID. 'inherit' uses the main model. When you omit it, Claude Code picks the model in the subagent model order
mcpServers
No
MCP server specifications for this agent
skills
No
Array of skill names to preload into the agent context
initialPrompt
No
Auto-submitted as the first user turn when this agent runs as the main thread agent
maxTurns
No
Maximum number of agentic turns (API round-trips) before stopping
autoCompactWindow
No
Lower the auto-compact window for this agent when it runs as a subagent, to a token count from 100000 to 1000000. Requires TypeScript Agent SDK v0.3.296 or later
background
No
Run this agent as a non-blocking background task when invoked
omitClaudeMd
No
Leave the user, project, and local CLAUDE.md files out of this agent’s initial context; managed policy files still load. Use it for agents that take everything they need from the Agent tool prompt. Ignored when this agent runs as the main thread agent. Requires TypeScript Agent SDK v0.3.271 or later
memory
No
Memory source for this agent: 'user', 'project', or 'local'
effort
No
Reasoning effort level for this agent. Accepts a named level or an integer
Specifies MCP servers available to a subagent. Can be a server name (string referencing a server from the parent’s mcpServers config) or an inline server configuration record mapping server names to configs.
type AgentMcpServerSpec = string | Record<string, McpServerConfigForProcessTransport>;
Where McpServerConfigForProcessTransport is McpStdioServerConfig | McpSSEServerConfig | McpHttpServerConfig | McpSdkServerConfig.
When settingSources is omitted or undefined, query() loads the same filesystem settings as the Claude Code CLI: user, project, and local. See What settingSources does not control for inputs that are read regardless of this option, and how to disable them.
import { query } from "@anthropic-ai/claude-agent-sdk";// Do not load user, project, or local settings from diskconst result = query({ prompt: "Analyze this code", options: { settingSources: [] }});
Load only specific setting sources:
import { query } from "@anthropic-ai/claude-agent-sdk";// Load only project settings, ignore user and localconst result = query({ prompt: "Run CI checks", options: { settingSources: ["project"] // Only .claude/settings.json }});
To load CLAUDE.md project instructions, include "project" in settingSources. See Modify system prompts for how CLAUDE.md loading interacts with the system prompt options.
When multiple sources are loaded, settings are merged with this precedence (highest to lowest):
Local settings (.claude/settings.local.json)
Project settings (.claude/settings.json)
User settings (~/.claude/settings.json)
Programmatic options such as agents, allowedTools, and settings override user, project, and local filesystem settings. Managed policy settings take precedence over programmatic options.
Custom permission function type for controlling tool usage.The function is the SDK replacement for the interactive permission prompt: it’s invoked only when the permission evaluation flow resolves to a prompt. Tool calls already approved by an allowedTools entry, a settings allow rule, or the permission mode, such as acceptEdits or bypassPermissions, never invoke it. To gate every tool call, use a PreToolUse hook instead.An allow rule doesn’t pre-approve the actions no mode auto-approves; see How permissions are evaluated for which of them reach the callback and what happens in dontAsk and auto mode.
Suggested permission updates so the user is not prompted again for this tool. Bash prompts include a suggestion with the localSettingsdestination, so returning it in updatedPermissions writes the rule to .claude/settings.local.json and persists across sessions.
blockedPath
string
The file path that triggered the permission request, if applicable
mcpServer
{ name: string; source: string }
For an mcp__* tool, the MCP server that serves it and where that server’s definition came from, with the fields of McpServerProvenance. Absent for other tools. Requires Agent SDK v0.3.274 or later
decisionReason
string
Explains why this permission request was triggered
defaultToNo
boolean
When true, a single stray keystroke must not approve this request: open your prompt on its decline option, don’t pre-select approve, and offer no one-key approve shortcut. Requires Agent SDK v0.3.268 or later
suppressAlwaysAllowRule
boolean
When true, don’t offer a persistent always-allow choice for this request. Requires Agent SDK v0.3.268 or later
toolUseID
string
Unique identifier for this specific tool call within the assistant message
agentID
string
If running within a sub-agent, the sub-agent’s ID
requestId
string
The control_request envelope’s request_id. A control_response your application sends outside the SDK, such as a signed HTTP POST, must echo this value so the Claude Code process can match the reply to the request
The callback normally resolves the request by returning a PermissionResult, which the SDK writes back over its transport as the control_response. Return null only when your application has already sent the control_response for this request over its own channel, echoing requestId; the SDK then skips writing the response to its transport. Returning null in any other case leaves the tool call blocked indefinitely, because no control_response is ever sent and permission prompts don’t time out.The requestId option and the null return value require Claude Code v2.1.199 or later.
If you return allow with more than 4,096 items in updatedPermissions, Claude Code treats the result as invalid and denies the tool call. Each update counts as one item, and so does each entry in its rules or directories list. The denial message ends with updatedPermissions may hold at most 4096 updates, rules and directories in all. To have the call allowed, return 4,096 items or fewer.
Configuration for an in-process MCP server. It is what createSdkMcpServer() returns, plus an optional tools list of McpServerToolPolicy entries that you add.
To require approval for calls to one of the server’s tools, or deny them, add a policy entry naming the tool. Spread what createSdkMcpServer() returns into an object under mcpServers and put the entry in a tools list on that object, because the function’s tools option accepts tool definitions and not policy entries. The policy list requires Agent SDK v0.3.301 or later, and McpServerToolPolicy describes what each permission_policy value does.In this script, an allowedTools wildcard pre-approves every tool on the records server, but delete_record is marked always_ask, so calls to it go to canUseTool anyway. With the destructiveHint: true annotation, the call still reaches the callback if the session runs in auto mode, where the auto mode classifier could otherwise approve it.
import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";import { z } from "zod";const deleteRecord = tool( "delete_record", "Delete a customer record by ID", { id: z.string() }, async ({ id }) => ({ content: [{ type: "text", text: `Deleted record ${id}` }] }), { annotations: { destructiveHint: true } });const records = createSdkMcpServer({ name: "records", tools: [deleteRecord] });for await (const message of query({ prompt: "Delete customer record 42", options: { mcpServers: { // Spread the returned config and add the policy list beside it records: { ...records, tools: [{ name: "delete_record", permission_policy: "always_ask" as const }] } }, allowedTools: ["mcp__records__*"], canUseTool: async (toolName, input) => { console.log(`Approval requested for ${toolName}`); return { behavior: "allow", updatedInput: input }; } }})) { if (message.type === "result" && message.subtype === "success") { console.log(message.result); }}
When Claude calls delete_record, the script prints Approval requested for mcp__records__delete_record.To change or lift a tool’s policy while the session runs, pass the server’s config with a new tools value to setMcpServers(). The tools value you pass takes effect from Claude’s next call to that server’s tools:
A list with entries: the entries replace the current policies
An empty list: every policy on the server is cleared
No tools key: the current policies stay
Include in that call your other in-process servers and any server an earlier setMcpServers() call added, or the call disconnects them.
One entry in an McpSdkServerConfigWithInstance’s tools list, naming one of the server’s tools and setting the permission policy for calls to that tool. The list requires Agent SDK v0.3.301 or later and Claude Code v2.1.301 or later. An older Claude Code executable, such as an executable you point pathToClaudeCodeExecutable at, ignores the list. Then always_ask and always_deny aren’t enforced, and each call goes through the permission flow.
The tool’s bare name as passed to tool(), without the mcp__<server>__ prefix
permission_policy
'always_allow' | 'always_ask' | 'always_deny'
The approval policy for the tool’s calls, always_ask or always_deny. always_allow is ignored on an in-process server: to pre-approve a tool, list it in allowedTools instead
org_max_permission
'allow' | 'ask' | 'blocked'
A per-tool ceiling that an organization admin sets. Ignored on an in-process server, so leave it unset
Choose always_ask to approve each call yourself, or always_deny to block the tool outright:
always_deny: a call to the tool is denied in every permission mode, including bypassPermissions, but a mod in a plugin you load can still approve it
If you pass neither canUseTool nor permissionPromptToolName, or set permissionPrompts to 'none', an always_ask call that isn’t settled first is denied unless a PermissionRequest hook allows it.In auto, plan, and bypassPermissions mode, a call to a tool marked always_ask can be approved before it reaches your canUseTool callback.
auto: the auto mode classifier reviews the call and can allow it. To make every call reach your callback in auto mode, set destructiveHint: true in the tool’s annotations
plan: while auto mode is available to the session, calls to an always_ask tool annotated readOnlyHint: true go to the auto mode classifier, which can allow them. Calls to other always_ask tools reach your callback. To make a read-only tool’s calls reach your callback too, add destructiveHint: true to that tool’s annotations alongside readOnlyHint: true. Alternatively, set useAutoModeDuringPlan to false, which turns the classifier off during planning
bypassPermissions: when the CLAUDE_CODE_REMOTE environment variable is true, as it is in a cloud session, the call is approved without your callback, whatever the tool’s annotations. Anywhere else the call reaches your callback. To make it reach your callback in a cloud session too, run the session in default or acceptEdits mode instead
Set destructiveHint to true explicitly in auto and plan mode. For always_ask calls, Claude Code reads an unset destructiveHint as false, although the default listed under ToolAnnotations is true.
type SdkPluginConfig = { type: "local"; path: string; skipMcpDiscovery?: boolean;};
Field
Type
Description
type
'local'
Must be 'local' (only local plugins currently supported)
path
string
Path to the plugin directory. A relative path resolves against the cwd option when the session starts. The path must be absolute when you load the plugin mid-session with addPlugins
skipMcpDiscovery
boolean
When true, the SDK loads skills, hooks, agents, and commands from this plugin but does not read its .mcp.json or manifest mcpServers. Set this when your application owns the plugin’s MCP connections.
Three messages in this union report control-request progress and model refusals. Each has type: "system", so tell them apart by the subtype listed with each one:
SDKControlRequestProgressMessage, subtype: "control_request_progress": reports progress on a long-running control request that your client sent. request_id matches the message to that request, and status is "started" or "api_retry". Requires Agent SDK v0.3.203 or later.
SDKModelRefusalFallbackMessage, subtype: "model_refusal_fallback": emitted when the model ends the stream with a refusal and the turn is retried on a fallback model. Carries original_model and fallback_model. Requires Agent SDK v0.3.170 or later.
SDKModelRefusalNoFallbackMessage, subtype: "model_refusal_no_fallback": emitted when the model ends the stream with a refusal and no retry runs, for example because no fallback model is configured. Carries original_model. Requires Agent SDK v0.3.193 or later.
The message field is a BetaMessage from the Anthropic SDK. It includes fields like id, content, model, stop_reason, and usage.SDKAssistantMessageError is one of: 'authentication_failed', 'oauth_org_not_allowed', 'account_on_hold', 'billing_error', 'rate_limit', 'overloaded', 'invalid_request', 'model_not_found', 'server_error', 'max_output_tokens', 'cloud_credential_error', or 'unknown'. Four of these values mean more than their names say:
'model_not_found': the selected model doesn’t exist or isn’t available to your account or deployment
'overloaded': the API returned a 529 because the server is at capacity, as opposed to 'rate_limit', which is a 429 against your quota
'cloud_credential_error': Claude Code couldn’t obtain usable AWS or Google Cloud credentials on the machine it runs on, so no request reached the cloud provider. The usual cause is a cloud sign-in that expired or was never completed on that machine, though a briefly unreachable credential service reports the same value. See Could not load AWS or Google Cloud credentials. Requires TypeScript Agent SDK v0.3.267 or later, which bundles Claude Code v2.1.267
aborted is true when an interrupt or abort truncated the assistant message before the stream completed: the message has no stop_reason and the content may end mid-word. The field is absent on normally completed messages. It requires Agent SDK v0.3.214 or later.agent_id identifies the subagent that produced the message and is absent on main-thread messages. The value equals the task_id on that subagent’s task_started and other task events, and is unchanged when the subagent is resumed. On messages from a nested subagent, it names the nested subagent, not the subagent that spawned it. The field requires Agent SDK v0.3.292 or later.Match a subagent’s messages to its task events on agent_id rather than pairing a message’s parent_tool_use_id with a task event’s tool_use_id. When a tool call resumes the subagent, the task events carry that call’s tool_use_id, while the messages keep the parent_tool_use_id of the tool call that first started the subagent, so the two no longer match.Claude Code sets user_message_uuid and user_message_uuids on the turn’s first assistant message, under the conditions in user_message_uuid. When the turn continues one that a restart interrupted, the assistant messages that carry those fields also carry resume_reason.timestamp is the ISO 8601 time when the message’s content finished generating on the process that produced it. The value comes from that machine’s clock, so use it for display only and don’t order messages by it. One API turn can produce several assistant messages that share a message.id, each with its own timestamp. When the field is absent, fall back to the time you received the message.context_usage is a structured copy of the /context report, typed as SDKContextUsage, and requires Agent SDK v0.3.232 or later. When you send /context as a prompt, Claude Code delivers the report as an assistant message whose message.content holds the markdown table, and attaches context_usage to that same message. Claude Code doesn’t set the field on any other assistant message, and earlier versions deliver the /context table without it, so read the breakdown from the field when it’s present and fall back to the markdown text when it isn’t.usage_report is a structured copy of the /usage report, typed as SDKUsageReport, and requires Agent SDK v0.3.273 or later. When you send /usage as a prompt, Claude Code delivers the report as an assistant message whose message.content holds the text. It attaches usage_report to that same message only when the session meets all of these conditions:
The session authenticates with a claude.ai credential
The credential shows a known plan type or carries the user:profile scope
The account isn’t on usage-based billing
A claude setup-token token passed as CLAUDE_CODE_OAUTH_TOKEN doesn’t qualify by default, because it carries only the user:inference scope. Other sessions, such as API-key sessions, deliver the text without the field, and so do earlier versions. Read the report from the field when it’s present and fall back to the text when it isn’t.
Set pasted_content to send content the user pasted into your prompt UI rather than typed, one entry per paste, each a string or an array of content blocks. Claude Code appends each entry’s text after the typed text, in order, and may wrap each paste in <pasted_content> tags. Blocks other than text are ignored, so send images and documents in message.content. Requires Agent SDK v0.3.277 or later.Set inline_pastes to tell Claude Code which parts of message.content the user pasted rather than typed, one string per paste. The prompt text stays where the user put it. Claude Code may wrap each listed paste in <pasted_content> tags where it stands, so Claude can tell pasted material from the user’s own words. Only pastes in the prompt’s last text block are wrapped. Requires TypeScript Agent SDK v0.3.280 or later.Each paste field has a size limit:
pasted_content: if the entries plus the content blocks inside them number more than 1,000, Claude Code ignores the whole field.
inline_pastes: Claude Code uses the first 100 entries that aren’t blank and ignores the rest.
Set shouldQuery, client_composed, or priority to change how Claude Code handles a message you send:
shouldQuery: set it to false to append the message to the transcript without triggering an assistant turn. The message is held and merged into the next user message that does trigger a turn. Use this to inject context, such as the output of a command you ran out of band, without spending a model call on it.
client_composed: set it to true to have Claude Code deliver the message text as written. Claude Code then doesn’t expand @path or @server:resource mentions, and doesn’t run text that starts with / as a command. While the verbatimPrompts option is on, the SDK sets the field on every message. Requires TypeScript Agent SDK v0.3.280 or later and Claude Code v2.1.248 or later.
priority: controls when a message you send during a running turn reaches Claude:
'next', or no priority field: Claude reads the message in the same turn, as soon as the tool calls it is running finish. If the turn ends first, the message starts the next turn.
'later': Claude Code holds the message until the turn ends and sends it as a new turn.
'now' with origin: { kind: "human" }: on Claude Code v2.1.286 or later, work that can continue in the background moves there, and Claude reads the message in the same turn. Work that can move includes shell commands, subagents, and MCP tool calls. On v2.1.287 or later it also includes WebFetch and WebSearch calls. When Claude is only writing a response, or the work it is running can’t move, Claude Code interrupts the turn instead and Claude reads the message next.
'now' without that origin: Claude Code interrupts the turn and Claude reads the message next.
This message, sent while a turn is running, asks Claude to change course without losing a shell command that is still running:
const message: SDKUserMessage = { type: "user", message: { role: "user", content: "Skip the integration tests and summarize what you have so far" }, parent_tool_use_id: null, priority: "now", origin: { kind: "human" },};
A user message that a subagent produces, such as the tool_result for one of its own tool calls, carries agent_id. See SDKAssistantMessage, which defines the field and its version requirement.On a message that carries a tool_result block, tool_use_result is the tool’s structured output object rather than the text sent to the model. Its shape depends on the tool named by the matching tool_use block, so the field is typed unknown; the built-in shapes are listed under Tool Output Types. These results need handling beyond their listed shape:
The Agent tool: tool_use_result is AgentOutput. Render from it rather than parsing the tool_result text. A completed result’s content holds the subagent’s report, or, for a subagent whose report goes through a SubagentHandback tool call, a short note about that hand-back in place of the report. In auto mode on Claude Code v2.1.271 or later, every subagent that produces a completed result reports that way unless it is a fork, and Claude receives the report as a separate message from the subagent.
A WebFetch or WebSearch call that Claude Code moved to the background to deliver a 'now' message: the user message carrying that call’s tool_result has tool_use_result set to { detachedToolCall: true }. The call is still running, and Claude receives its result once it finishes. No second tool_result for that tool_use_id follows, so if your application draws a row for each tool call, mark this row as moved to the background when this message arrives. Requires Claude Code v2.1.287 or later.
An MCP tool whose result contains resource_link blocks: tool_use_result is an object with a resourceLinks array of SDKMcpResourceLink entries. Claude receives each link as a line of text in the tool_result block, so read resourceLinks to render the files the server returned instead of parsing that text. Claude Code omits resourceLinks when the result has no links and on results from subagents, keeps at most 50 links per result, and stops adding links once the array reaches 64 KiB of serialized JSON. resourceLinks requires Agent SDK v0.3.257 or later.
An MCP tool that returns structuredContent: tool_use_result is an object whose structuredContent member holds what the server sent and whose content member holds the McpOutput value. Results from subagents don’t carry structuredContent.
An MCP tool whose structuredContent serializes to more than 1,048,576 characters of JSON: Claude Code leaves structuredContent off tool_use_result and sets structuredContentOmitted: true in its place, so your application can tell a dropped object from a tool that sent none. The other members, such as content and resourceLinks, stay, and what Claude receives doesn’t change. Claude Code v2.1.287 or later applies this cap. Two kinds of tool differ:
A tool whose tools/list entry declares an MCP Apps ui:// resource has a limit of 8,388,608 characters on Claude Code v2.1.295 or later, and versions before v2.1.295 exempt it.
A user turn injected from outside the session, one whose origin kind is peer or channel, reaches the stream as a replay whether it was delivered during an active turn or started a new turn while the session was idle. Before v2.1.207, an injected turn delivered while the session was idle produced no message on the stream and only appeared when you re-read the transcript.
Several fields on the result carry diagnostic detail beyond subtype:
api_error_status: the HTTP status code of the API error that terminated the conversation. Absent or null when the turn ended without an API error.
ttft_ms: time to first token in milliseconds, measured when the first complete assistant message arrives. Present on the success arm only.
ttft_stream_ms: time in milliseconds until the first message_start stream event, when the response stream opens. Lower than ttft_ms; the gap between the two is time spent streaming the first message. Present on the success arm only.
time_to_request_ms: time in milliseconds from the start of the turn until Claude Code sends the API request. Present on the success arm only. Requires Claude Code v2.1.162 or later.
user_message_uuid: the uuid of the message you sent that this turn answered. See user_message_uuid for which results carry it.
user_message_uuids: the uuids of every message you sent that Claude Code answered in this turn. See user_message_uuids.
resume_reason: why this turn continues one that a restart interrupted. Present on both arms. See resume_reason.
local_command: the name of the command the turn dispatched, on the success result of a turn that a command completed without entering the agent loop, such as /compact. The name is folded to lowercase letters and underscores, so /reload-plugins reports reload_plugins. A command that an MCP server provides, and the built-in /mcp, report mcp. A command you defined yourself reports custom. The arguments are never included. Absent on every turn that entered the agent loop and on sends that ran no command. Requires Agent SDK v0.3.268 or later.
request_sent_wall_ms: epoch milliseconds at which Claude Code dispatched the API request, for joins against server-side timestamps. Present only together with user_message_uuid, on a success result with is_error false whose turn sent an API request.
first_content_frame_ms: time in milliseconds until the first content_block_start or content_block_delta stream event, counting thinking blocks as content. Present on the success arm only, when is_error is false. Requires Agent SDK v0.3.260 or later.
first_stream_post_ms, first_stream_post_ack_ms, first_stream_post_wall_ms: timings for uploading the turn’s first stream event. Claude Code records them only in sessions it streams to claude.ai, such as cloud sessions, and the results query() yields don’t carry them. Requires Agent SDK v0.3.260 or later.
usage: main agent loop only. Excludes subagent and auxiliary model calls, and is per-turn in streaming-input sessions. Prefer modelUsage for token/cost accounting.
modelUsage: per-model totals for every model call made through the query pipeline during this query() call, including the main loop, subagents, and internal calls such as compaction and Workflow agents. Helper calls outside that pipeline, such as the permission classifier and token-counting requests, are excluded. A call that resumes a session also counts the per-model totals restored from the session’s earlier calls. In streaming-input sessions the totals are cumulative across turns, so read the latest result rather than summing across results. See Track costs in streaming input mode for resets and Recover totals after a session crash for zeroed results.
total_cost_usd: cumulative estimated cost in USD, covering the same calls as modelUsage and reset at the same points. A call that resumes a session also counts the totals restored from the session’s earlier calls. It is an estimate, not a billing statement. See Track cost and usage for accuracy caveats.
queued_turn_count: the number of messages you sent with origin: { kind: "human" } that are still waiting when Claude Code produced the result. See queued_turn_count for what 0 and an absent field tell you.
result_index: where this result falls in the run’s delivery order, counting from 0 across every result the process writes. Present on both arms. A result whose write fails still consumes its number, so a gap in the sequence means a result was lost. Requires Agent SDK v0.3.268 or later.
startup_failure_reason: why Claude Code refused to start, on the error_during_execution result it writes before exiting on a known startup failure. See startup_failure_reason for the values and which failures carry it. Requires Agent SDK v0.3.274 or later.
terminal_reason: why the loop ended. One of "completed", "max_turns", "tool_deferred", "aborted_streaming", "aborted_tools", "hook_stopped", "stop_hook_prevented", "background_requested", "blocking_limit", "rapid_refill_breaker", "prompt_too_long", "image_error", "model_error", "api_error", "malformed_tool_use_exhausted", "budget_exhausted", "structured_output_retry_exhausted", "tool_deferred_unavailable", or "turn_setup_failed".
fast_mode_state: one of "on", "off", or "cooldown".
fast_mode_disabled_reason: why fast mode isn’t available right now. Absent when nothing blocks fast mode, though a request may still run at standard speed. During the cooldown after a fast mode rate limit, Claude Code reports fast_mode_state: "cooldown" with no reason code and re-enables fast mode when the cooldown expires. Requires Claude Code v2.1.219 or later.
Use the reason code to explain why fast mode is off in your own UI instead of re-deriving availability. Each code names the check that blocked fast mode:
Reason code
Meaning
free
The account doesn’t have the paid subscription or usage credits fast mode requires
The fast mode Opus model isn’t in the organization’s availableModels allowlist
sdk_opt_in_required
The session hasn’t opted in to fast mode: pass fastMode: true in the settings option or through applyFlagSettings()
pending
The availability check hasn’t completed yet
The same pair of fields appears on SDKSystemMessage and on the SDKControlInitializeResponse, so you can read the fast mode state before the first turn.The origin field forwards the SDKMessageOrigin of the user message that triggered this result. Results that carry origin: { kind: "task-notification" } include:
Synthetic follow-up turns: when the SDK injects a synthetic follow-up turn, such as for a finished background task, the resulting SDKResultMessage carries this kind
Fired scheduled tasks and messages from other sessions: cloud scheduled tasks whose trigger fired and server-verified messages from your other sessions arrive with this kind too, each with the subkind described in Task-notification subkinds
Check kind to distinguish results that answer your prompt from injected follow-ups before routing or suppressing them. If your application declares scheduled runs, their results carry kind: "task-notification" too, so don’t suppress on kind alone.When several background-task completions are queued together, Claude Code can answer them in one turn rather than one turn each. Each completion still produces its own result with this origin. All but the last of the completions Claude Code answers together produce empty results with num_turns: 0, in order, and the last one’s result carries the turn that answers them all.The field is absent for results emitted before any user turn, such as startup errors.When a PreToolUse hook returns permissionDecision: "defer", the result has stop_reason: "tool_deferred" and deferred_tool_use carries the pending tool’s id, name, and input. Read this field to surface the request in your own UI, then resume with the same session_id to continue. See Defer a tool call for later for the full round trip.
The uuid of the SDKUserMessage the turn is answering, echoed so you can match Claude Code’s reply to the message you sent. Claude Code echoes a uuid only if you set one on the message. The field is optional on SDKUserMessage, and a string prompt passed to query() carries none.Which of your messages a turn answers depends on how the turn started:
A regular message you sent, meaning one without isSynthetic: true: the turn answers that message for its whole run. When you send several messages close together, Claude Code can merge them into one turn, and the field then carries only the last message’s uuid. To match the reply to any of the merged messages, use user_message_uuids.
A message you sent with isSynthetic: true: the turn answers that message at first. If Claude Code picks up a regular message of yours between tool calls, the turn answers the picked-up message from then on. Echoing a synthetic message’s uuid requires Agent SDK v0.3.265 or later; earlier versions echo nothing on synthetic turns.
The prompt Claude Code generates to continue an interrupted turn under CLAUDE_CODE_RESUME_INTERRUPTED_TURN: when the interrupted turn’s last prompt is a regular message you sent, whether it opened the turn or Claude Code picked it up during the turn, the continued turn answers that message at first. resume_reason tells the continued turn’s frames from the interrupted attempt’s. When the last prompt isn’t a regular message of yours, the continued turn answers no message of yours at first. If Claude Code picks up a regular message of yours between tool calls, the turn answers the picked-up message from then on. Echoing the interrupted turn’s prompt requires Agent SDK v0.3.268 or later.
Any other prompt Claude Code generated itself: the turn answers no message of yours at first and its frames carry no echo. If Claude Code picks up a regular message of yours between tool calls, the turn answers that message from then on. The pickup echo requires Agent SDK v0.3.265 or later; earlier versions echo nothing on these turns.
Claude Code echoes the answered message’s uuid on three kinds of frame:
The result: every result of a turn that answered a message you sent. Every such result carries it on Agent SDK v0.3.265 or later. Before v0.3.265, the success result of a turn that a regular message started lacked it when the turn sent no API request or ended with a deferred tool call. Before v0.3.246, error results lacked it too, and before v0.3.216 every result did.
The turn’s first reply: the first assistant message, and with includePartialMessages also the first stream event whose event.type isn’t ping, so you can bind the reply before the result arrives. The first-reply echo requires Agent SDK v0.3.246 or later. Before v0.3.269, with includePartialMessages, Claude Code set it on that first stream event only, or on the first assistant message when the turn streamed nothing. When the message the turn is answering changes mid-turn, the first reply after the change carries the field too, on Agent SDK v0.3.265 or later; earlier versions set it on one reply frame per turn.
Every thinking_tokens frame of the turn: so you can attribute thinking progress to the message you sent without waiting for the turn’s first reply. Requires Agent SDK v0.3.260 or later.
Claude Code omits the field in these cases:
Reply frames other than those first replies
Subagent frames
Turns that answer no message of yours, or answer a message you sent without a uuid
Results that answer no message you sent, such as the zeroed result after a crashed worker process
When a UserPromptSubmit hook blocks a message that starts its own turn, or stops it with continue: false, you still get a result for that message. It’s a success result with is_error: false and num_turns: 0, its result is the block message or stop message, and it echoes the message’s uuid under the same rules as any other result. The result has no terminal_reason, and nothing on it besides the result text says a hook ended the turn. A message that a hook blocks while another turn is running may get no result: see user_message_uuids.
The uuids of every message you sent that Claude Code answered in this turn. When you send several messages close together, Claude Code can merge them into one turn, and user_message_uuid then names only the last of them. To match the reply to any of the merged messages, look for that message’s uuid anywhere in this list. Requires Agent SDK v0.3.259 or later.Claude Code sets the list together with user_message_uuid on each reply frame that carries that field and on the result. For the full set of turn frames that echo the answered message’s uuid, and the version each requires, see user_message_uuid. The list always contains user_message_uuid and holds at most 64 entries.When Claude Code picks up a regular message you sent while a turn was running, it adds that message’s uuid to the result’s list. When a UserPromptSubmit hook blocks the message at pickup, Claude Code drops it instead: the message never reaches Claude and isn’t kept for a later turn. You get no result for it, and its uuid appears in no result’s list. If a hook can block messages, set a timeout on waiting for a result that lists a message you sent while a turn was running.That holds when the hook’s output is a block alone. If the output sets continue: false, even beside decision: "block", or the hook is a prompt hook that answers ok: false without continueOnBlock: true, Claude Code stops the message instead of dropping it. The message waits for its own turn, you get a result for it, and its text stays in the conversation, so Claude sees it on the next turn.When a first reply or result carries user_message_uuid without the list, it came from an earlier Claude Code version, so fall back to the single field.
Why this turn continues one that a restart interrupted. Claude Code sets this field on a turn that continues an interrupted one under CLAUDE_CODE_RESUME_INTERRUPTED_TURN, so you can tell the continued turn’s reply and result from the interrupted attempt’s. Requires Agent SDK v0.3.268 or later.Claude Code sets the field on two kinds of frame:
The continued turn’s result: on the success and error arms alike, whether or not the result carries user_message_uuid.
The continued turn’s reply frames: those that carry user_message_uuid.
The value is a short lowercase token, such as interrupted_turn.
The number of messages you sent with origin: { kind: "human" } that are still waiting in the command queue when Claude Code produced the result. Requires Agent SDK v0.3.242 or later.What 0 and an absent field tell you:
0: Claude Code doesn’t count messages you sent without that origin, and doesn’t count task notifications, so a turn can still follow.
Absent: the final result that Claude Code emits after a crash or fatal startup error omits the field, and may carry zeroed totals.
Why Claude Code refused to start, so your application can offer the fix instead of a retry. Claude Code sets it on the error_during_execution result it writes before exiting on a known startup failure. That result carries zeroed totals, and its errors array carries the same text as stderr. The field is absent on every other result. Requires Agent SDK v0.3.274 or later.Set CLAUDE_CODE_STARTUP_FAILURE_RESULTS to 1 in env to receive this result for every SDKStartupFailureReason value. Without that variable, Claude Code writes the result only for these failures, and the rest end with stderr output, a non-zero exit, and no result message:
A resume that Claude Code stops because it can’t return the session to its worktree, with worktree_unverified or worktree_resume_refused. That section says which error carries which value.
A refused continue of a conversation that a background session holds, with session_held_by_background. For a refused resume of such a conversation, Claude Code writes the result only when the variable is set.
Managed settings list the API providers this machine may use, and the session is set up for a provider that isn’t listed, or for an endpoint the settings don’t pin. Requires Claude Code v2.1.285 or later
org_verify_failed
The sign-in’s organization couldn’t be verified against the pin, for example because of a network failure or a revoked token
org_pin_mismatch
The sign-in belongs to an organization the pin doesn’t allow
managed_settings_invalid
Managed policy settings couldn’t be read, the pin names no organization, or managed model restrictions leave no permitted model for the Default option
remote_settings_required_unavailable
Managed settings that the organization requires couldn’t be loaded
The managed settings request to the Cloud gateway came back with a 403, which the gateway’s troubleshooting table covers
proxy_invalid
A proxy setting isn’t a complete URL
temp_dir_unusable
The per-user temporary directory is unsafe or couldn’t be created
cwd_unavailable
The working directory was deleted, moved, or can’t be read
shell_tool_missing
On Windows, no shell tool is available: Git Bash is missing, and PowerShell is missing or turned off with CLAUDE_CODE_USE_POWERSHELL_TOOL
session_held_by_background
The conversation to resume or continue is running as a background session
worktree_resume_refused
The session’s worktree failed its safety checks, or the resume was launched from inside it. errors says whether running the same resume again continues without the worktree
worktree_unverified
The session’s worktree couldn’t be verified right now, and retrying may succeed
cli_version_too_old
This Claude Code version is below the minimum Anthropic requires
bypass_root
Bypass permissions mode was requested while running as root
org_config_required_unavailable
The session needs the organization’s policies and managed settings before it can start, and they couldn’t be loaded, for example because of a network failure or an Anthropic server error. Requires Agent SDK v0.3.293 or later
org_config_refused
Anthropic refused to provide the organization’s policies and managed settings for this sign-in, for example because the sign-in expired or was revoked, or the organization doesn’t allow Claude Code for this account. Requires Agent SDK v0.3.293 or later
fast_mode_state reports the session’s fast mode state. When something blocks fast mode, fast_mode_disabled_reason names the check that blocked it; the field requires Claude Code v2.1.219 or later. For the reason codes and their meanings, see fast_mode_disabled_reason on the result message.terminal_slash_commands names the entries in slash_commands whose interface is bound to the local terminal, such as exit. You can send them like any other entry in slash_commands; the field exists so a remote or mobile client can hide them from its command menus. The field is present only when non-empty, and requires Agent SDK v0.3.229 or later.
source on each mcp_servers entry: where the server’s definition came from, with the same values as McpServerStatus’s source. Requires Agent SDK v0.3.274 or later.
effort: the effort level Claude Code sends on the session’s next request, or null when it sends none. Claude Code sets the field only on the init message it sends to Remote Control clients, and omits it from the init message your application reads. Requires Agent SDK v0.3.234 or later.
The capabilities array names the protocol behaviors this CLI implements, so you can feature-detect instead of comparing claude_code_version strings. It is an open set: ignore values you don’t recognize, and check for the specific capability whose behavior you rely on. The field requires Claude Code v2.1.205 or later and is absent on earlier CLIs.
The interrupt control request honors cancel_queued: true, cancelling the messages the receipt would otherwise list under still_queued and listing them under cancelled instead. See SDKControlInterruptResponse. Requires Claude Code v2.1.219 or later
sdk_mcp_manifests
The initialize control request accepts sdkMcpServerManifests, MCP handshake results captured from your in-process SDK MCP servers. Claude Code advertises this capability in v2.1.286 or later
sdk_mcp_tools_list_changed
A tools/list_changed notification from an SDK MCP server makes Claude Code list that server’s tools again, so a tool the server adds mid-session reaches Claude. Claude Code advertises this capability in v2.1.286 or later
The plugin_errors array lists plugin load failures. An entry describes either a plugin that didn’t load and is absent from plugins, or a plugin that loaded without one of its parts, such as its hooks file. The key is omitted when nothing failed. SDKSystemMessage declares plugin_errors in Agent SDK v0.3.283 or later.When a directory or archive from your plugins option itself fails to load, the entry’s plugin field holds a positional tag such as inline[0] instead of a plugin name. This happens, for example, when the path doesn’t exist or the manifest is invalid. Match such an entry to your option by its path field.The table below lists the fields of each plugin_errors entry.
Field
Type
Description
plugin
string
The failing plugin’s ID, or a positional tag such as inline[0] when the plugin directory or archive itself failed to load
type
string
Error category from an open set, such as path-not-found or manifest-validation-error. Treat a value you don’t recognize as a generic failure
message
string
Display text describing the failure
path
string
Present only when the plugin directory or archive itself failed to load. Its absolute path, with a relative path from your plugins option resolved against the cwd option
Streaming partial message (only when includePartialMessages is true).The parent_tool_use_id field is always null: stream events are emitted for the main session only. For subagent attribution, use complete messages, which carry agent_id and parent_tool_use_id, or enable forwardSubagentText to receive subagent text and thinking as complete messages.
type SDKPartialAssistantMessage = { type: "stream_event"; event: BetaRawMessageStreamEvent; // From Anthropic SDK parent_tool_use_id: string | null; uuid: UUID; session_id: string; ttft_ms?: number; // Time to first token in ms, present only on message_start events user_message_uuid?: string; user_message_uuids?: string[]; resume_reason?: string;};
Claude Code sets user_message_uuid and user_message_uuids on the turn’s first non-ping stream event, and again when the message that the turn is answering changes, under the conditions in user_message_uuid. When the turn continues one that a restart interrupted, the stream events that carry those fields also carry resume_reason.
Generic text banner emitted by the loop. Carries warnings, notices, and other non-error status lines Claude Code raises, and hook feedback such as a UserPromptSubmit hook’s block reason.On Claude Code v2.1.227 or later, a hook’s systemMessage can arrive as this message, with each line prefixed by the hook’s name, such as PostToolUse:Bash says:. Each event’s section on the hooks page says how output surfaces.Render content as plaintext at the given level.
Emitted on graceful worker teardown so remote clients can show why the worker exited instead of waiting for heartbeat timeout. The reason is a short snake_case string set by the host CLI, such as "host_exit" or "remote_control_disabled". Act on this only when streaming live. A resumed session replays past instances of this message, so ignore them in that case.
Plugin installation progress event. Emitted when CLAUDE_CODE_SYNC_PLUGIN_INSTALL is set, so your Agent SDK application can track marketplace plugin installation before the first turn. The started and completed statuses bracket the overall install. The installed and failed statuses report individual marketplaces and include name.
Stream event emitted when the permission system denies a tool call without an interactive prompt. Use it to render the denial in your UI as it happens, rather than only observing the is_error tool result that follows. Which denials it reports depends on how the run handles permission prompts:
With a canUseTool callback and the default permissionPrompts: 'host': permission prompts go to your callback, and this event reports the denials Claude Code decides on its own without calling it.
With neither: a bare -p run, or query() that sets neither canUseTool nor permissionPromptToolName, denies any tool call that would have prompted unless a PermissionRequest hook allows it, and this event reports those denials as well as the ones Claude Code decides on its own. Before v2.1.223, Claude Code didn’t emit this event in runs without a callback.
With an MCP prompt tool, set with permissionPromptToolName or the --permission-prompt-tool flag, and the default permissionPrompts: 'host': Claude Code doesn’t emit this event at all, not even for the rule denials it decides on its own.
With permissionPrompts: 'none': Claude Code denies the calls that would have prompted, even when canUseTool or an MCP prompt tool is also set, and this event reports those denials as well as the ones Claude Code decides on its own. Requires Claude Code v2.1.259 or later.
In every configuration, this event skips any denial decided on the PreToolUse hook path, whether the hook denied the call itself or a deny rule overrode the hook’s allow or ask decision. The event is also best-effort: occasionally Claude Code records a denial without emitting this event, so permission_denials on the result message is the authoritative record.
Structured form of the /context report, carried as context_usage on the SDKAssistantMessage that delivers a /context result. Agent SDK v0.3.232 and later export the type. Unlike SDKControlGetContextUsageResponse, it carries only the data needed to render the usage breakdown, without display fields such as color and gridRows. Claude Code computes the report with token-counting API requests that don’t appear in the message stream; see how these requests are handled.
The table lists what Claude Code puts in each field. The fields from model through over_limit describe the session as a whole, and the collection fields attribute tokens to individual items.
Field
Type
Description
model
string
The main loop’s model Claude Code computed the usage for, not a subagent’s
total_tokens
number
Claude Code’s estimate of the tokens in use. Not clamped to the window, so it can exceed raw_max_tokens when the session is over the limit
raw_max_tokens
number
The model’s context window, or the lower auto-compact window when one applies, such as one you set or the 200K boundary Claude Code applies to some models with a 1M-token window. Claude Code measures total_tokens against this window
percentage
number
total_tokens as a rounded percentage of raw_max_tokens, so it can exceed 100 when the session is over the limit
over_limit
object
Present only when total_tokens exceeds raw_max_tokens. tokens_over is the amount over, and kind says how Claude Code resolved the window
One entry per row of the usage-by-category breakdown
mcp_tools
object[]
Tokens attributed to each MCP tool, with its wire name, such as mcp__linear__create_issue, and its server_name
memory_files
object[]
Tokens attributed to each loaded memory file, with its path and a source label such as Project or User in type
agents
object[]
Tokens attributed to each custom subagent definition, with a source identifier such as projectSettings, userSettings, or plugin. Built-in subagents aren’t listed
skills
object[]
Tokens attributed to each skill in the skill listing, with a source identifier and, for plugin skills, the plugin’s name in plugin_name. Absent when no skills contribute tokens
over_limit.kind records how Claude Code resolved the window, not whether the API accepts the next request:
hard_limit: the window is what Claude Code believes to be the model’s own limit, past which the API refuses requests
compaction_window: the window is a compaction-policy window, which may or may not coincide with the model’s limit
Claude Code evolves the type additively, adding new data as optional fields rather than reshaping existing ones. Read the fields you know and ignore any you don’t recognize.
Structured form of the /usage report, carried as usage_report on the SDKAssistantMessage that delivers a /usage result. Agent SDK v0.3.273 and later export the type. The type is experimental: its shape may change.
session: Claude Code’s running cost and usage totals, read from the same ledger as total_cost_usd and modelUsage on SDKResultMessage. Each model_usage entry is a ModelUsage.
rate_limits: the plan’s usage rows in limits and usage-credits spend in extra_usage. It is null when Claude Code couldn’t get the plan’s usage, for example when the session’s OAuth token lacks the user:profile scope.
Claude Code computes session.total_cost_usd locally from token counts, so it is an estimate and not what your plan bills. The usage-credits spend the server reports is the separate extra_usage block. See Track cost and usage for the accuracy caveats.limits holds the server’s usage rows as the server sent them: which meters apply, their scope, labels, severity, and order are the server’s, so render the rows verbatim.
An empty array means the server reported no meters.
null means Claude Code has no rows to report.
Each row of limits describes one usage meter:
Field
Type
Description
kind
string
The server’s meter kind, such as session, weekly_all, or weekly_scoped. Classify a row on this, never on a label
group
string
The server’s row group, such as session or weekly. Rows render grouped under it, in the server’s order
percent
number
Share of the window used, 0-100
resets_at
string | null
ISO 8601 timestamp when the window resets
scope
object | null
Optional. What a scoped row is for, a model or a surface, with the server’s display label
severity
string
The server’s reading of the row for a meter’s color, such as normal, warning, or critical
is_active
boolean
true on the row the server picks for a single-value indicator to show
Before Agent SDK v0.3.277, the type declared severity and is_active as optional and nullable, and a row could arrive without them.extra_usage is the usage credits spend and cap for the billing period as the server reports them, present when the plan has usage credits. Amounts are in minor units of currency, cents for USD.
monthly_limit is null when this account has no spending cap of its own. On Team and Enterprise plans, don’t render null as unlimited.
is_enabled is false while usage credits can’t pay for requests.
Provenance of a user-role message. This appears as origin on SDKUserMessage and is forwarded onto the corresponding SDKResultMessage so you can tell what triggered a given turn.
Direct input from the end user. If your application forwards what the user typed as a user message, set its origin to { kind: "human" } explicitly: Claude Code treats a user message with no origin as unattributed, and checks that require a human-typed prompt, such as the ultracode workflow keyword, don’t accept it. Before v2.1.210, Claude Code treated an absent origin on a user message as human input.
channel
Message arriving on a channel. server is the source MCP server name.
peer
Message from another agent: an in-process teammate or a cross-session peer, another of your Claude Code sessions. See Peer origin fields for the per-field semantics and the trust model.
task-notification
Synthetic turn injected for a delivery that arrives without a fresh user prompt, such as a finished background task; see SDKTaskNotificationMessage for that arm. A prompt your application declares as a scheduled run carries this kind too. The optional subkind marks what raised the notification. See Task-notification subkinds.
Synthetic turn injected when the session continues without fresh user input, such as a command result that triggers a follow-up prompt.
unclassified
Injected turn whose origin couldn’t be determined. Requires Claude Code v2.1.223 or later. When Claude Code receives an SDKUserMessage with isSynthetic: true and can’t classify it as any other kind, it sets this kind as the message arrives and frames the turn to the model as a non-user source rather than treating it as human input. Your application shouldn’t set this value.
When Claude Code delivers a task notification into a session, it sets subkind on the notification’s origin if Anthropic servers verified where that notification came from. It also sets subkind when your application declares the message as a scheduled run itself, which requires TypeScript Agent SDK v0.3.280 or later. subkind requires Claude Code v2.1.213 or later, and it takes one of two values:
peer-send-message: the notification is a message that another of your sessions sent with the server-side send_message tool that cloud sessions use to message each other, not the cross-session SendMessage tool, and Anthropic servers verified that both sessions belong to the same private group of sessions. Requires Claude Code v2.1.224 or later. A send_message delivery the servers didn’t verify that way gets no subkind.
Every other task notification has no subkind. That includes PR activity delivered into a session and background events such as a finished task. Messages from the cross-session SendMessage tool aren’t task notifications at all: whether they come from a session on the same machine or through Anthropic servers from another machine, Claude Code gives them kind: "peer" and the peer origin fields.fireReason says why a scheduled-trigger notification fired, as a short lowercase token such as scheduled, manual, retry, catch_up, or api. Anthropic servers set it on a cloud scheduled task’s deliveries, and your application sets it when it declares a scheduled run. It’s absent when neither sent one. Requires TypeScript Agent SDK v0.3.280 or later.A background task can run more than once under the same task_id, such as when Claude resumes a subagent. Each run has its own run_id. When a run’s notification reaches your session as a user message, runId on that message’s task-notification origin holds the same value. A notification can arrive after the task’s next run has started, and it still carries the earlier run’s ID. To tell which run a turn belongs to, compare runId, not task_id. Requires TypeScript Agent SDK v0.3.292 or later.
If your application runs prompts on its own schedule, declare each run so Claude Code frames the turn to the model as a scheduled task rather than as live input from the user. Start the session with CLAUDE_CODE_HOST_SCHEDULED_RUN set to 1 in env, then send the run’s SDKUserMessage with origin: { kind: "task-notification", subkind: "scheduled-trigger", fireReason: "scheduled" } and without isSynthetic. Claude Code ignores the declaration in a process started without that variable. It also ignores it in a process whose environment carries CLAUDECODE or CLAUDE_CODE_CHILD_SESSION. Claude Code keeps fireReason only when the value is 1 to 32 lowercase letters or underscores. Requires TypeScript Agent SDK v0.3.280 or later.
A peer origin identifies which agent sent the message: an in-process teammate sending to main with SendMessage, or a cross-session peer, another of your Claude Code sessions. Cross-session peers require Claude Code v2.1.224 or later on macOS and Linux; see cross-session messaging availability for the native Windows requirement. A cross-session peer can run on the same machine, or on another of your machines when its message arrives through Remote Control.
from: the teammate’s name, or the sender address for a cross-session peer. For a one-way cross-machine message, the sender has no reply address and from is "unknown". The value is sender-authored; verifiedPeerPid is the verified identity.
fromMode: the sending session’s permission class, bypass or prompting, declared by a host that relays a peer message between your sessions, such as the desktop app. Claude Code reads it in the receiving session when it applies the inbound controls. Requires Agent SDK v0.3.234 or later.
senderTaskId: the teammate’s task ID. Absent for a cross-session peer.
name: the sender’s display name, normalized by Claude Code: it strips Unicode control, format, surrogate, and line or paragraph separator code points, then trims the result and caps it at 64 code points with an ellipsis. Requires Claude Code v2.1.205 or later.
body: the decoded message body with the peer envelope stripped, byte-exact with what the model sees. Present for a single teammate message, absent when several are merged; for a cross-session peer, present only when the turn is exactly one peer envelope formed by Claude Code. Render name and body instead of re-parsing the message text. Before v2.1.299, merged messages kept the first message’s body. Requires Claude Code v2.1.205 or later.
fromSession: the sender’s host-openable session ID, set by the sender’s host so your UI can link back to the sending session. Like from, it is sender-asserted: use it as a navigation target only, and don’t treat it as proof of the sender’s identity. Requires Claude Code v2.1.216 or later.
verifiedPeerPid: the process ID of the process that connected to this session’s cross-session messaging socket, verified by the kernel and read from the connection itself, never from the payload. Use it, not from, to identify the sender: from is forgeable by any same-user process. The field is absent when Claude Code can’t verify it, such as on Windows or non-socket ingress, so an absent value means the sender is unverified. For relayed traffic it identifies the relay rather than the message’s author, and process IDs are recyclable, so treat it as provenance rather than an authentication token. Requires Claude Code v2.1.216 or later.
The prompt_id field is a UUID identifying the user prompt currently being processed. It matches the prompt.id attribute on OpenTelemetry events and is absent until the first user input. Requires Claude Code v2.1.196 or later.
mcp_server is present when the tool comes from an MCP server; see McpServerProvenance. The PostToolUse, PostToolUseFailure, PermissionRequest, and PermissionDenied inputs carry the same field. The field requires Agent SDK v0.3.274 or later.
Fires once after every tool call in a batch has resolved, before the next model request. tool_response carries the serialized tool_result content the model sees; the shape differs from PostToolUseHookInput’s structured Output object.
Fires before a requested model switch takes effect. context_tokens and the fields after it estimate what re-sending the conversation to the new model costs. For the full field descriptions and blocking semantics, see PreModelSwitch.
type TeammateIdleHookInput = BaseHookInput & { hook_event_name: "TeammateIdle"; teammate_name: string; /** @deprecated since v2.1.178. Carries the session-derived team name; will be removed. */ team_name: string;};
directory is the absolute path of the directory that was added. source is "slash_command" when /add-dir added it and "register_repo_root" when the SDK control request did.
Documentation of input schemas for built-in Claude Code tools. These types are exported from @anthropic-ai/claude-agent-sdk/sdk-tools and can be used for type-safe tool interactions.The StructuredOutput tool has no type here: Claude Code builds its input schema from the schema you pass to outputFormat, so there is nothing fixed to export. See Recognize the StructuredOutput tool call for what that call looks like in your message stream.
Tool name:Agent. The previous name Task is still accepted as an alias when this tool is available to the session.The tools array in the SDKSystemMessage init message lists this tool as Task for backward compatibility.
The mode field is deprecated and ignored on Claude Code v2.1.212 or later. A subagent runs in either the parent session’s permission mode or its definition’s permissionMode, and the subagent inheritance rules decide which.
type BashInput = { command: string; timeout?: number; // milliseconds. Foreground: capped at 600000 by default, higher values are clamped. With run_in_background (Claude Code v2.1.285 or later): the background time limit, 1800000 when omitted, capped at 7200000 unless raised description?: string; run_in_background?: boolean; dangerouslyDisableSandbox?: boolean;};
Executes Bash commands with optional timeout and background execution. The working directory persists between commands, including commands run in later turns of a multi-turn session; shell state such as exported environment variables doesn’t. For the limits on which directory changes carry over, see What persists between commands. For what sets the foreground ceiling, see Timeout and output limits. For the background time limit, see Time limit for background commands.
Runs a background source and delivers each event to Claude so it can react without polling: command runs a script and emits one event per stdout line, and ws opens a WebSocket and emits one event per text frame. Provide exactly one of command or ws. The ws source requires Claude Code v2.1.195 or later.timeout_ms is the watch’s deadline in milliseconds. It defaults to 300000 and accepts values up to 3600000. The effective deadline is at most 1800000, which is 30 minutes, so a larger accepted value is shortened to that. At the deadline the watch ends and Claude receives one notice so it can start a new watch if it still needs one.The exported type marks timeout_ms as required because the schema fills in the default; a call that omits it validates.When Monitor runs a command, it follows the same permission rules as Bash; a WebSocket watch prompts for approval separately. See the Monitor tool reference for behavior and provider availability.
Removed in Claude Code v2.1.277, together with its TaskOutputInput type. Previously retrieved output from a running or completed background task; Claude reads a background task’s output file with Read instead.A disallowedTools entry or a deny rule that still names TaskOutput is ignored without a warning.
Reads files from the local filesystem, including text, images, PDFs, and Jupyter notebooks.
Use pages for PDF page ranges (for example, "1-5").
allow_large lets Claude read a text file past the usual size limits when the session’s context window has room. It requires Agent SDK v0.3.296 or later, which bundles Claude Code v2.1.296.
For a PDF, Claude receives the file’s contents inside the Read call’s tool_result content. A read that returns the pdfoutput carries a summary text block followed by a document block. One that returns the parts output carries the summary text block followed by one block per extracted page: an image block, or a text block naming the page when Claude Code couldn’t render it as an image. Before Agent SDK v0.3.242, Claude Code delivered the file’s contents as a separate user message after the tool result.
type TaskStopInput = { task_id?: string; shell_id?: string; // Deprecated: use task_id};
Stops a running background task or shell by ID. As of v2.1.198, task_id also accepts an agent-team teammate or a named background agent by agent ID or name.
type WebFetchInput = { url: string; prompt: string; offset?: number;};
Fetches content from a URL and processes it with an AI model.offset is the number of characters to skip from the start of the page. Claude sets it to keep reading a long page. The field requires Agent SDK v0.3.290 or later.
type WorkflowInput = { script?: string; name?: string; scriptPath?: string; args?: unknown; // any JSON value; the published typings render this as an object map resumeFromRunId?: string; title?: string; // ignored; the script's meta block sets the title description?: string; // ignored; the script's meta block sets the description};
Runs a dynamic workflow: a script that orchestrates many subagents in the background and returns one consolidated result. The Workflow tool is available in Agent SDK v0.3.149 and later. At least one of script, name, or scriptPath is required.
Field
Type
Description
script
string
Inline workflow script. Must begin with export const meta = { name, description } as a literal, followed by the script body using agent(), parallel(), pipeline(), and phase(). An optional phases array in meta groups agents under named stages in the progress view
name
string
Name of a built-in workflow or one saved in .claude/workflows/. Resolved to a script
scriptPath
string
Path to a workflow script file on disk, such as the scriptPath a previous run returned. Takes precedence over script and name. Claude Code rejects scriptPath with an error when the session’s tools don’t include Read
args
unknown
Input value exposed to the script as the global args, for parameterized named workflows such as a research question or a list of file paths. Pass arrays and objects as actual JSON values, not as a JSON-encoded string
resumeFromRunId
string
Run ID of a prior Workflow invocation to resume. Completed agent() calls with unchanged inputs usually return cached results; the rest run live. Resume after a pause covers which completed calls re-run. Same session only
title
string
Ignored; the script’s meta block sets the title
description
string
Ignored; the script’s meta block sets the description
Creates and manages a structured task list for tracking progress.
The following tools are available by default only on Claude Opus 4.7, Claude Sonnet 4.6, Claude Haiku 4.5, and earlier models. On every other model, including model IDs Claude Code doesn’t recognize, they aren’t available unless you opt in:
TodoWrite
TaskCreate
TaskGet
TaskUpdate
TaskList
Wherever the tools are available, Claude Code provides the four Task tools, or TodoWrite instead when you set CLAUDE_CODE_ENABLE_TASKS=0.This default set applies in Claude Code v2.1.268 and later, which the TypeScript Agent SDK bundles from v0.3.268.See Model availability to opt in.
type ExitPlanModeInput = { /** Deprecated: no longer used. */ allowedPrompts?: Array<{ tool: "Bash"; prompt: string; }>; [k: string]: unknown;};
Exits plan mode. The allowedPrompts field is deprecated and ignored; Claude Code still accepts it so existing callers and transcripts validate. Before v2.1.205, it requested prompt-based Bash permissions for implementing the plan.
type EnterWorktreeInput = { name?: string; path?: string;};
Creates and enters a temporary git worktree for isolated work. Pass path to switch into an existing worktree instead of creating a new one. On first entry the target must be a registered worktree of the current repository or, in a multi-repo workspace, of a repository nested inside it; from within a worktree session it must be under .claude/worktrees/ of the session’s repository. name and path are mutually exclusive.
type ExitWorktreeInput = { action: "keep" | "remove"; discard_changes?: boolean;};
Exits the current git worktree and returns to the original working directory. The keep action leaves the worktree and branch on disk, while remove deletes both. discard_changes must be true when removing a worktree that has uncommitted files or unmerged commits.
Schedules a prompt to run on a 5-field cron schedule in local time. Set recurring to false to fire once at the next match. Jobs are session-scoped by default, and resuming with --resume or --continue restores jobs that haven’t expired. See Session-scoped scheduled tasks.Setting durable to true requests persistence to .claude/scheduled_tasks.json so the job survives restarts. Durable scheduling isn’t available in every session: when it isn’t, Claude Code accepts durable: true but creates the job session-only. Read the output’s durable field to see whether the job persisted.
Schedules a one-shot wake-up that fires the given prompt after a delay. This tool backs the self-paced /loop command. The runtime clamps delaySeconds to between 60 and 3600 seconds. The delaySeconds, reason, prompt, and noop fields are required unless stop is true. noop: true reports a wake-up where nothing changed. Setting stop: true cancels the pending wakeup and ends the self-paced /loop. The stop field requires Claude Code v2.1.202 or later. See the ScheduleWakeup row in the tools reference.
Manages cloud scheduled tasks, formerly routines: the scheduled and triggered Claude Code runs hosted in the cloud. This tool backs the /schedule command. trigger_id is required for the get, update, run, and list_runs actions. body is required for create, update, and create_webhook_trigger, and optional for run.create_webhook_trigger, list_runs, and get_run_log each require a minimum Claude Code version:
create_webhook_trigger: attaches an event source to an existing scheduled task, such as a GitHub event that fires it. The body names the source, the events, and the task to fire. Requires Claude Code v2.1.225 or later.
list_runs and get_run_log: list_runs lists a scheduled task’s recent runs, and get_run_log reads one run’s log. session_id names the run to read, from a list_runs result, and cursor pages through either action’s results. Both actions require Claude Code v2.1.227 or later.
This tool is available only when the session is authenticated with a claude.ai account on a plan with cloud scheduled tasks enabled. It is absent when your organization’s policy disables cloud sessions. On Claude Code v2.1.227 or later, the tool is also absent when an Owner has turned off scheduled tasks for the organization.
type PushNotificationInput = { message: string; status: "proactive";};
Sends a proactive push notification to the user. Keep message under 200 characters because mobile operating systems truncate longer text. See the PushNotification row in the tools reference for provider availability; push delivery runs through Anthropic-hosted infrastructure that isn’t accessible from Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, or Microsoft Foundry.
Reports code-review findings as a structured list so Claude Code can render them instead of printing them as text. Findings are ordered most-severe first, with at most 32 per call, and the array is empty when none survived. Requires Claude Code v2.1.196 or later.level is optional and holds the effort level Claude reports for the review. Claude Code doesn’t compare it with the level the review ran at, so the two can differ.Each finding carries these fields:
file: repo-relative path the finding is in. The optional line is the 1-indexed line it anchors to.
summary: one-sentence statement of the defect. failure_scenario describes the concrete inputs and state that lead to the wrong output or crash.
short_summary: optional compressed label of at most 60 characters for compact display. Requires Claude Code v2.1.212 or later.
category: optional short kebab-case slug of the finding type, such as correctness or test-coverage. Requires Claude Code v2.1.199 or later.
verdict: set when a verify pass ran; absent on inline-only reviews.
outcome: set only when re-reporting after applying fixes.
Publishes a local .html or .md file as a hosted artifact page, or lists the user’s published artifacts. Omit action or pass "publish" to publish file_path, which is required for the publish action. Each field below applies to a publish:
icon: one short generic word for the artifact’s browser-tab icon, such as chart or map. Claude includes it on a first publish and omits it on an update, which keeps the artifact’s stored icon.
favicon: deprecated, and Claude omits it.
title: names the published page in the browser tab and gallery when the HTML file has no <title> tag.
url: targets an existing artifact to update in place instead of creating a new one.
force is a last-resort overwrite that discards a newer version another session published. On a conflict, the failed publish returns the newer content; Claude merges its changes onto that content, or re-reads the artifact, and publishes again. Pass force only when the user explicitly asks to discard that version.Pass "list" to enumerate the user’s published artifacts; only limit and scope may accompany it. scope defaults to "mine", which lists artifacts the user owns; "shared" lists artifacts other people shared with the user, and "all" lists both.limit sets the most artifacts a listing returns, from 1 to 200. A limit above 50 requires Agent SDK v0.3.292 or later. Without limit, a listing returns up to 25.
capabilities: the runtime capabilities the published page uses, keyed by capability name, such as the connectors the page may call. The artifact service validates the declaration and rejects a publish that names a capability the account can’t use or gives one an invalid config. Pass {} to clear a stored declaration, and omit the field on a redeploy to keep it. Requires Agent SDK v0.3.235 or later.
contract: the runtime version the published page runs against. Omit it to keep the artifact’s current version, pass "latest" to upgrade, or pass a specific version to pin or roll back. Requires Agent SDK v0.3.235 or later.
The types are exported, but the tool is off by default in Agent SDK sessions. Publishing also requires every condition in the artifacts availability table, which sessions authenticated with an API key don’t meet.
Reads and writes the claude.ai Project attached to the session. Dispatches on method:
project_info: returns project metadata and the doc list.
project_read: reads one doc by path.
project_search: queries the project’s knowledge base with query. n caps the hits and defaults to 5.
project_write: creates or replaces a doc at path from exactly one of content, which carries inline text, or local_path, which names a file inside the working directory. present_to_user: true marks the written doc as the deliverable the user needs to see.
type ReadMcpResourceDirInput = { server: string; uri: string;};
Lists the direct children of a directory resource on an MCP server. Only usable against a server that has declared support for directory listing; the listing isn’t recursive. Directory listing isn’t enabled in every session: when it’s off, the call returns an empty resources list and the error field reports that directory listing isn’t enabled.
type RefreshMcpToolsInput = { server?: string; // refresh only this server; omit to refresh all connected servers};
Re-queries the tool list of connected MCP servers and applies any changes. The types are exported, but Claude Code registers the tool only when you set CLAUDE_CODE_ENABLE_REFRESH_MCP_TOOLS=1 in the env option, and only in sessions with at least one MCP server. Requires Claude Code v2.1.211 or later.
Renders a clickable role-picker chip row during Cowork onboarding so the user can pick their role and get a matching plugin installed. Takes no arguments; the role list is defined by the client. The call blocks until the user responds.
Tool name: dynamic MCP tool names of the form mcp__<server>__<tool>
type McpInput = { [k: string]: unknown;};
MCP tool arguments are an open object: each server defines its own parameters, so the type places no constraints on field names or values. Consult the server’s own tool schema for the fields a specific tool accepts.
Documentation of output schemas for built-in Claude Code tools. These types are exported from @anthropic-ai/claude-agent-sdk/sdk-tools and represent the actual response data returned by each tool.
Returns the result from the subagent. Discriminated on the status field: "completed" for finished tasks, "async_launched" for background tasks, and "remote_launched" for tasks Claude Code dispatched to a cloud session, where sessionUrl links to that session and taskId identifies it.On the completed variant, resolvedModel names the model the subagent started on, which can differ from the requested model input when availableModels or another override applies. This field requires Claude Code v2.1.174 or later. On async_launched, it names the model in use when the task moved to the background.modelsUsed lists the models the subagent used, in order. The field is present only when a mid-run swap happened, and a model appears again when the run swapped back to it. On async_launched, the list covers the models used before backgrounding. Both modelsUsed and the backgrounding behavior of resolvedModel require Claude Code v2.1.212 or later.If Claude Code kept the subagent’s isolated worktree, worktreePath on the completed result is where to find it. worktreeBranch is its branch, present when Claude Code created the worktree with git.Claude Code fills usage and totalTokens from the subagent’s final API request, not from the whole run, so usage.service_tier is the service tier string the API reported on that request. When present, usage.output_tokens_details.thinking_tokens is the number of that request’s output tokens that were thinking tokens. The output_tokens_details field requires TypeScript SDK v0.3.228 or later, which bundles Claude Code v2.1.228. The fallback_credit field requires TypeScript SDK v0.3.285 or later, which bundles Claude Code v2.1.285.usage.output_tokens_details matches Usage.output_tokens_details in meaning, scoped to that final request, but every level of it is optional here. Guard both the object and the field, for example usage.output_tokens_details?.thinking_tokens ?? 0, rather than reading it directly.Before v2.1.207, the published type was narrower. It omitted worktreePath, worktreeBranch, citations, toolStats.frameCount, and the inference_geo, speed, and iterations usage fields, and it typed service_tier as "standard" | "priority" | "batch". Fields the type marks optional can be absent on results recorded by earlier versions.
Returns the questions asked and the user’s answers. response is set when the user typed a freeform reply instead of answering the structured questions; when present, Claude receives “The user responded: …” instead of the per-question answer list.
The stdout, stderr, and backgroundTaskId fields carry:
Field
What it carries
stdout
The command’s stdout and stderr, merged into one interleaved stream
stderr
Notices the tool itself adds, such as a shell working-directory reset, not the command’s stderr
backgroundTaskId
Present for background commands
timedOutAfterMs is the timeout in milliseconds, set when the command reached its timeout and moved to the background rather than starting there explicitly. backgroundCwdHint is set when the backgrounded command contained a directory-change builtin such as cd, pushd, popd, or chdir, and notes that the session working directory didn’t change. Both fields require Claude Code v2.1.210 or later.When a subagent running in the foreground owns a backgrounded command, the command ends when that subagent’s run ends. Claude Code sets backgroundEndsWithFinalResponse to true on such commands, and omits the field when the command survives the turn, as commands started by the main conversation or by background subagents do. The field requires Claude Code v2.1.227 or later.Claude Code sets gitOperation.commit.branch to the branch named in git’s commit summary line, and omits it for a commit made on a detached HEAD. The field requires Agent SDK v0.3.227 or later. Claude Code reports a gh pr reopen command as the reopened PR action, which requires Agent SDK v0.3.234 or later.
Returns the write result with structured diff information. What originalFile and structuredPatch hold depends on the write:
For a newly created file, originalFile is null and structuredPatch is empty
On an overwrite, originalFile carries the previous content, except when that content is larger than about 10 MB: Claude Code then skips the diff and returns originalFile null and structuredPatch empty
structuredPatch is also empty when the write changed nothing or the diff timed out
Returns file paths matching the glob pattern, sorted by modification time.totalMatches and countIsComplete require Claude Code v2.1.191 or later. totalMatches reports the number of matching files before truncation. When countIsComplete is false, totalMatches is a lower bound because the underlying search truncated its own output.
Returns search results. The shape varies by mode: file list, content with matches, or match counts. In count mode, numFiles and numMatches are totals over the full result set, not the paginated slice. Before v2.1.208, a head_limit or offset that truncated the listed entries also truncated those totals.totalFiles requires Claude Code v2.1.208 or later and reports the total number of results before head_limit and offset pagination in files_with_matches mode. totalLines requires Claude Code v2.1.210 or later and reports the total number of lines before pagination in content mode.
Returns the fetched content with HTTP status and metadata.artifactRead is Claude Code’s own record of an artifact read, present only when Claude fetched an artifact the session can publish to. Claude Code reads it back when a session resumes so a later publish builds on the right version; your code doesn’t need to act on it. slug names the artifact, ver is the version the read put on record and is absent when it recorded none, and seeded: false marks a read whose full source didn’t reach Claude. The seeded field requires Agent SDK v0.3.239 or later.
type WorkflowOutput = { status: "async_launched" | "remote_launched"; taskId: string; taskType?: "local_workflow" | "remote_agent"; workflowName?: string; runId?: string; summary?: string; transcriptDir?: string; scriptPath?: string; sessionUrl?: string; // set when the workflow launched as a cloud session warning?: string; error?: string;};
Returns immediately after the tool accepts the invocation. The final result arrives later as a task completion. Check error before treating the run as started: a script that fails its syntax check returns status: "async_launched" with error set, and never runs.
Field
Type
Description
status
"async_launched" | "remote_launched"
The tool accepted the invocation. "async_launched" for in-process runs, "remote_launched" for runs dispatched to a cloud session instead of running in-process
taskId
string
Background task identifier for the run
taskType
"local_workflow" | "remote_agent"
Task type of the registered background task, matching the status arm
workflowName
string
The meta.name from the workflow script
runId
string
Workflow run identifier to pass as resumeFromRunId on a later invocation. Absent for remote_launched runs, where the cloud session URL is the resume handle
summary
string
One-line description of what the workflow does
transcriptDir
string
Directory where subagent transcripts are written during execution
scriptPath
string
Path to the persisted workflow script for this run. Edit it and pass back as scriptPath to rerun without resending the script
sessionUrl
string
Cloud session URL, set when status is "remote_launched"
warning
string
Non-blocking heads-up, such as local git state diverging from the pushed branch a cloud session will clone
error
string
Set when the script fails its syntax check. When present, the run did not start despite the launched status
The following tools are available by default only on Claude Opus 4.7, Claude Sonnet 4.6, Claude Haiku 4.5, and earlier models. On every other model, including model IDs Claude Code doesn’t recognize, they aren’t available unless you opt in:
TodoWrite
TaskCreate
TaskGet
TaskUpdate
TaskList
Wherever the tools are available, Claude Code provides the four Task tools, or TodoWrite instead when you set CLAUDE_CODE_ENABLE_TASKS=0.This default set applies in Claude Code v2.1.268 and later, which the TypeScript Agent SDK bundles from v0.3.268.See Model availability to opt in.
Returns the scheduled cron jobs: durable jobs from .claude/scheduled_tasks.json and session-only jobs from the current session. A session-only job carries durable: false; jobs read from disk omit the field.
Returns when the wake-up will fire as an epoch millisecond timestamp, the delay actually used, and whether the requested delay was clamped. The stopped field is true when the call ended the loop with stop: true. It requires Claude Code v2.1.202 or later. The cancelledWakeups field counts how many pending wakeups a stop: true call cancelled. A value of 0 means nothing was pending, and a recurring /loop cron isn’t cancelled by stop: true. It requires Claude Code v2.1.206 or later.
Returns the number of findings reported, the level value Claude passed, and the findings echoed back for the result body. Requires Claude Code v2.1.196 or later. The echoed short_summary field requires Claude Code v2.1.212 or later.
Returns the published page’s url and the local path that was published for the publish action, with updated set to true when the publish redeployed an existing artifact, and warnings carrying any publish-time advisories. The list action returns the artifacts rows instead, with truncated set when more artifacts exist than the requested limit. On listings whose scope isn’t "mine", each row carries rel marking whether the user owns the artifact or it was shared with them, and the output’s scope records which non-default scope produced the listing; both are absent on default listings.A list result also reports total, the number of artifacts that match the listed scope, including ones beyond limit. When total_at_least is set, that number is a lower bound and more artifacts may exist. Both fields require Agent SDK v0.3.292 or later.
Discriminated on the method field, mirroring the input. project_read returns small text docs inline in content and writes larger docs to a local_file path instead; project_search returns RAG hits with rag: true when the project’s index is available and falls back to a docs path list otherwise.
Returns the direct children of the directory resource. Subdirectories appear with mimeType "inode/directory"; error carries a human-readable message when the server couldn’t list the directory.
type RefreshMcpToolsOutput = Array<{ server: string; status: "refreshed" | "error" | "not_connected"; toolCount?: number; // tools now available from this server added?: string[]; // tool names this refresh added removed?: string[]; // tool names this refresh removed error?: string; // why the refresh failed or the server was unavailable}>;
Returns one entry per server: refreshed means the re-queried tool list was applied, error means the re-query failed and the previous tool set was kept, and not_connected means the server has no live connection to query.
type ShowOnboardingRolePickerOutput = { role?: string; dismissed?: boolean;};
Returns the user’s selection: role when they picked a role chip or typed one, and dismissed: true when they closed the picker. An empty object means the user approved the call without picking a role.
MCP tool results are returned as a string or an array of content blocks, depending on the server. The trailing plain-object branch in the exported type is a schema-generation artifact. For a result that also carries structuredContent or resource links, see tool_use_result, which holds this value in its content member. At runtime the value may also be undefined, although the exported type doesn’t model this.
No API key. The session authenticates another way, such as a claude.ai login, a bearer token, or a cloud provider
Agent SDK v0.3.234 and later list these four values in the type. The type also keeps user, project, org, temporary, and oauth so older code still compiles, and Claude Code doesn’t report them.
Available beta features that can be enabled via the betas option. See Beta headers for more information.
type SdkBeta = "context-1m-2025-08-07";
On the Claude API, the context-1m-2025-08-07 beta is retired for Claude Sonnet 4.5 and Claude Sonnet 4. If you still pass it with either model, requests that exceed the standard 200K-token context window return an error, so remove it from betas. To run a session with a 1M-token context window, set model to a model that runs with the 1M window by default, such as claude-sonnet-5-5 or claude-opus-5-5. For a model that reaches 1M only through its [1m] variant, append the suffix to the model ID, as in claude-opus-4-6[1m].
builtin is true on a row when the command is Claude Code’s own and typing /name runs it. It’s absent for a command defined by a user, project, plugin, or MCP server, and for a bundled command that one of those replaces by name. Requires Agent SDK v0.3.277 or later.
Information about an available subagent that can be invoked via the Agent tool.
type AgentInfo = { name: string; description: string; model?: string;};
Field
Type
Description
name
string
Agent type identifier (for example, "Explore", "general-purpose")
description
string
Description of when to use this agent
model
string | undefined
Model this agent uses: an alias or model ID, or 'inherit' for the parent’s model. When it’s undefined, Claude Code picks the model in the subagent model order
The MCP server that serves an mcp__* tool, and where that server’s definition came from. The PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, and PermissionDenied hook inputs carry it as mcp_server, and the CanUseTool options carry it as mcpServer. Both omit it for tools that don’t come from an MCP server.
type McpServerProvenance = { name: string; source: string;};
Field
Type
Description
name
string
The name the server is registered under, the same value mcpServerStatus() reports for it
source
string
Where the server’s definition came from: sdk, plugin, or a configuration scope
source takes one of the following values. The set is open, so treat a value you don’t recognize as a configured source, never as sdk:
sdk: an in-process server your application registered. Only the SDK host application can register one, so a configured server never reports sdk, whatever its name.
plugin: a server a plugin provides. Its name is the scoped plugin:<plugin-name>:<server-name> form described under plugin-provided MCP servers.
A configuration scope: user, project, local, dynamic, managed, enterprise, claudeai, or agent. A .mcp.json server reports project, and MCP installation scopes defines local, project, and user. Servers your application passes in the mcpServers option, other than in-process SDK servers, report dynamic.
Base trust decisions on source, not on name or the mcp__<server>__ tool-name prefix. For any source other than sdk, name is untrusted text: escape it before display.McpServerProvenance and the fields that carry it require Agent SDK v0.3.274 or later.
Use source to decide how far to trust a server, and the _meta on each tools entry to find a UI resource the server attached to that tool:
source: where the server’s definition came from, with the same values as source on McpServerProvenance. Base trust decisions on source rather than on name, because only your own in-process server reports sdk, whatever name any other server is registered under. If you don’t recognize a source value, treat that server as you treat any server whose source isn’t sdk. Requires Agent SDK v0.3.274 or later
_meta: the ui object and the ui/resourceUri string from the _meta the server declared for the tool. Claude Code withholds every other _meta key. ui/resourceUri is an older top-level spelling of ui.resourceUri. When the server attaches an MCP Apps UI resource to the tool, ui.resourceUri or ui/resourceUri holds the resource’s ui:// URI. Fetch that URI with readMcpResource() and render the resource in your application. Requires Agent SDK v0.3.280 or later
Claude Code sends _meta only when the capabilities array of the system message with subtype init lists mcp_tool_ui_meta_v1. You don’t turn mcp_tool_ui_meta_v1 on yourself.
If your server declares ui.resourceUri for a tool but the _meta.ui your application receives holds only visibility, the ui object the server sent failed one of Claude Code’s checks. Compare the _meta in your server’s tools/list response against the checks for each key:
ui: reaches your application unchanged, including any members other than resourceUri and visibility, if all three checks pass:
resourceUri is absent, or is a string that starts with ui://
visibility is absent, or lists only "model" and "app"
The whole object is at most 4,096 characters when serialized as JSON
If any of the checks fails, your application receives at most a ui whose only member is a visibility array with the "model" and "app" entries the server listed.
ui/resourceUri: reaches your application if it is a string that starts with ui:// and is at most 4,096 characters. Otherwise Claude Code drops it
When Claude Code is left with no ui member and no ui/resourceUri string to send, the tools entry has no _meta at all.
thinkingTokens counts the thinking tokens this model generated. outputTokens already includes them, so don’t add the two together. The field is absent until a turn runs on a Claude Code version that records it, so a resumed session that began on an earlier version reports a partial count. thinkingTokens requires Agent SDK v0.3.257 or later.The canonicalModel and provider fields require Claude Code v2.1.218 or later. canonicalModel is the canonical model ID that the pricing lookup uses; it can differ from the raw model string that keys the entry, for example when that string is a provider-specific ID or an alias.provider names the API backend that served the model, such as firstParty, bedrock, vertex, foundry, anthropicAws, mantle, or gateway.costBasis names the price table that priced the model’s latest request: list for list price, managed for a modelPricing table, or unknown when neither matched the model ID. The field requires Claude Code v2.1.246 or later.
BetaServerToolUsage, BetaIterationsUsage, BetaOutputTokensDetails, and BetaFallbackCreditUsage are defined in @anthropic-ai/sdk.output_tokens_details breaks the billed output down by category. It currently carries one field, thinking_tokens: number, counting the output tokens the model generated as internal reasoning, including the thinking-block delimiters. The output_tokens_details field requires TypeScript SDK v0.3.228 or later, which bundles Claude Code v2.1.228.
Billing: read the breakdown for observability, not for billing. output_tokens stays the authoritative total, and output_tokens - thinking_tokens approximates the non-reasoning output.
What the count covers: the raw reasoning the model produced, which can be longer than the thinking text returned in the response body. The API computes it by re-tokenizing that raw text, so it can differ from the model’s exact generation count by a few tokens.
Streaming: on streamed assistant messages this breakdown, like output_tokens, is a message_start placeholder and carries no real count, so read it from the result message’s usage as Read output tokens from the result message describes. On the result message, thinking_tokens reads 0 when the model or provider reports no breakdown.
null cases: output_tokens_details itself is null on assistant messages Claude Code synthesizes, such as API-error messages.
Whether Usage carries fallback_credit depends on your installed @anthropic-ai/sdk, which added it in 0.115.0.
MCP tool result type (from @modelcontextprotocol/sdk/types.js). structuredContent is a JSON object that can be returned alongside content, including image blocks. See Return structured data.
type CallToolResult = { content: Array<{ type: "text" | "image" | "audio" | "resource" | "resource_link"; // Additional fields vary by type }>; structuredContent?: Record<string, unknown>; isError?: boolean;};
One file an MCP tool returned by reference. Claude Code builds each entry from a resource_link block in the tool’s result and delivers the list as resourceLinks on SDKUserMessage.tool_use_result, or as resource_links on SDKTaskNotificationMessage when the call finished in the background. Requires Agent SDK v0.3.257 or later.
Controls Claude’s thinking/reasoning behavior. Takes precedence over the deprecated maxThinkingTokens.
type ThinkingDisplay = "summarized" | "omitted";type ThinkingConfig = | { type: "adaptive"; display?: ThinkingDisplay } // The model determines when and how much to reason (Opus 4.6+) | { type: "enabled"; budgetTokens?: number; display?: ThinkingDisplay } // Fixed thinking token budget | { type: "disabled" }; // No extended thinking
The optional display field controls whether thinking text is returned "summarized" or "omitted". On Claude Opus 4.7 and later, the API default is "omitted", so set "summarized" to receive thinking content in thinking blocks. Claude Code doesn’t pass your display value to some providers, such as Amazon Bedrock and Google Cloud’s Agent Platform. On those providers, Opus 4.7 and later return empty thinking blocks even when you set display to "summarized".
The signal field tells your spawn function when to tear down the process. Pass it as the signal option to Node’s spawn(), or pass it to your VM or container teardown handler.This signal does not fire the instant Options.abortController aborts. The SDK first closes the process’s stdin and waits about two seconds so the CLI can shut down cleanly, then aborts this signal. To react the moment the caller aborts instead, listen on your own Options.abortController.signal, which your spawn function can reference from its enclosing scope.
When you call setMcpServers(), Claude Code applies these rules:
Servers the call doesn’t name: outside a cloud session, Claude Code disconnects the servers an earlier setMcpServers() call added and the in-process SDK servers, and lists them in removed. Other servers keep running and aren’t listed in removed, among them the stdio, HTTP, and SSE servers from the mcpServers option, servers from settings files, and plugin-provided servers.
Stdio, HTTP, and SSE servers that an earlier setMcpServers() call added: outside a cloud session, a server you name again with an identical config keeps its connection and tools. It appears in neither added nor removed. If you pass a changed config, Claude Code reconnects the server using that config and lists it in added, not in removed.
Stdio, HTTP, and SSE servers the call names that no earlier call added: outside a cloud session, Claude Code adds the server and lists it in added, or in errors if it refuses the server.
In-process SDK servers the call names: a server already registered through mcpServers or an earlier call keeps its running instance and timeout. If you pass a tools policy list for it, even an empty one, you replace its policies; otherwise they stay. To run a new instance outside a cloud session, omit the server from one call and name it in the next.
Built-in servers the CLI started at startup: if the call names one, Claude Code drops that entry and reports it in errors.
Stdio, HTTP, or SSE servers that share a name with one from an MCP installation scope such as .mcp.json: under that name the session uses your server’s tools rather than the installation-scope server’s. Before Claude Code v2.1.305, Claude Code could disconnect your server and connect the installation-scope server when your app reloaded plugins.
The promise resolves after newly added stdio, HTTP, and SSE servers connect or fail, so tools from servers that connected are available on the next turn.added lists the servers Claude Code added or replaced, whether or not they connected. A server that failed to connect appears in both added and errors, with the failure text under errors and a failed row in mcpServerStatus(). Before Claude Code v2.1.257, a server whose connection attempt threw was reported only under errors.
skippedLinks counts the tracked paths the rewind refused to restore or delete for link safety: a symlink, hard link, or other non-regular file at the tracked path, a parent directory that no longer resolves to where it pointed when the checkpoint was taken, or a backup that couldn’t be read safely. The field requires Claude Code v2.1.216 or later. A preview call with rewindFiles(userMessageId, { dryRun: true }) never sets it.
Notification when a background task completes, fails, or is stopped. Background tasks include run_in_background Bash commands, Monitor watches, and background subagents. For the run_id and ambient fields, see SDKTaskStartedMessage, which defines them and their version requirements.
reason is set when a task ends for a cause other than its own completion, failure, or stop, and requires Agent SDK v0.3.273 or later. Claude Code sets it only in sessions that connect through claude.ai: cloud sessions, including those on self-hosted runners, and Remote Control sessions. A local query() call never sets it. Its one value, worker_restart, means the Claude Code process that was running the task restarted. The notification carries status "stopped", so treat the task as neither completed nor failed.When Claude Code moves a long MCP tool call to the background, the tool_result block for that call holds only a placeholder and the call’s real result arrives in this notification. Match the notification to the call with tool_use_id. On a completed notification, resource_links lists the files the tool returned by reference as SDKMcpResourceLink entries, with the same 50-link and 64 KiB limits as tool_use_result.resourceLinks. Claude Code omits resource_links when the result had no links and on notifications for tasks that aren’t MCP tool calls. resource_links requires Agent SDK v0.3.257 or later.Claude Code prepends a notice to every task notification it sends to the model, except deliveries stamped with the scheduled-trigger subkind, which carry an assigned-task framing instead. The notice states that no human input has occurred, so the model doesn’t treat the notification as a user instruction or approval.To detect a task-notification turn, check origin.kind === "task-notification" on the SDKUserMessage or SDKResultMessage rather than matching on the notice text. Read subkind from the same field if you need to know what raised it. Before v2.1.205, Claude Code left the notice off notifications that arrived while the session was idle.
Emitted when a hook begins executing.Claude Code delivers this message, SDKHookProgressMessage, and SDKHookResponseMessage to the message stream immediately, including while a SessionStart or Setup hook is still running during session startup. Claude Code v2.1.169 through v2.1.203 delivered these messages in one batch after a SessionStart or Setup hook completed; v2.1.204 restored live delivery.If you start the session with startup(), these messages reach you once you call .query() and iterate the result.
While a tool call runs in the main conversation, Claude Code emits a tool_progress message every 30 seconds with heartbeat: true. Each heartbeat carries the tool name and elapsed seconds, so you can distinguish a long-running call from a stalled session. Claude Code doesn’t emit heartbeats for tool calls inside a subagent. The heartbeat field requires Agent SDK v0.3.214 or later. Before v2.1.257, Claude Code didn’t emit heartbeats for a foreground Agent tool call either.On tool_progress messages for the Agent tool other than heartbeats, subagent_type names the running subagent type, such as general-purpose. subagent_retry is present while that subagent waits out an API error backoff, such as a rate limit or overload, with one message per retry attempt. Both fields require Agent SDK v0.3.214 or later.To render a retry indicator from subagent_retry:
Track the indicator by parent_tool_use_id, which is unique per subagent. tool_use_id is shared by parallel subagents from one assistant turn, so tracking by it would let one subagent’s update clear another’s indicator.
Clear the indicator when a later tool_progress for the same parent_tool_use_id arrives with neither subagent_retry nor heartbeat: true, or when the tool’s result message arrives. Frames with heartbeat: true report liveness only, so keep the indicator when one arrives. attempt can exceed max_retries under persistent retry, so don’t derive clearing from the counters.
Treat error_category as a token for choosing your own message text, not as display text. The values are rate_limit, overloaded, authentication_failed, server_error, cloud_credential_error, and unknown. Handle a value you don’t recognize the way you handle unknown, because later releases can add values.
run_id identifies one run of the task. When a task runs again under the same task_id, such as a subagent that Claude resumes, the new run gets a new run_id. The field requires Agent SDK v0.3.292 or later. Use it to keep the runs of one task apart:
Detect a late message: compared as plain strings, the run IDs of one task sort in the order the runs started, so a message whose run_id sorts before the run you’re showing comes from an earlier run. Treat the value as opaque apart from that comparison.
Fall back to task_id: when a message carries no run_id, such as the task_notification that a resumed session emits to close a task the earlier process started, attribute it by task_id.
For example, these three messages, trimmed to their identifying fields, come from a background subagent that Claude resumed once. The two task_started messages share a task_id, and the notification that ended the first run carries the first run’s ID:
ambient is true for tasks that aren’t part of the session’s work, such as tasks Claude Code runs for its own operation. Live-update watchers are also ambient, including watchers the user asked for. Exclude ambient tasks from activity indicators. The field requires Agent SDK v0.3.247 or later.ambient also appears on SDKTaskNotificationMessage and on SDKBackgroundTasksChangedMessage entries.is_backgrounded and spawn_depth describe how Claude Code started the task. Both fields require Agent SDK v0.3.238 or later.
is_backgrounded: Claude Code sets it on "local_agent" and "local_bash" tasks. true means the task runs in the background. false means the task runs in the foreground, and the tool call that started it stays blocked until the task finishes or moves to the background.
spawn_depth: Claude Code sets it on "local_agent" tasks only. A subagent that the main thread spawned has depth 1. A subagent that a depth 1 subagent spawned has depth 2, and so on.
A resumed subagent always reports is_backgrounded: true, because Claude Code runs every resumed subagent in the background. When a foreground task moves to the background later, Claude Code reports the new is_backgrounded value in a task_updated message rather than sending a second task_started.parent_task_id holds the task_id of the subagent that launched this task. Use it to group each task under the subagent that started it. Claude Code sets it on subagent, Bash, and Monitor tasks. The field requires Agent SDK v0.3.292 or later. It is absent when:
The main thread launched the task
Claude Code no longer tracks the parent task
A teammate or an agent inside a workflow launched the task
The parent can be a foreground task or one that already ended, so treat an ID you don’t recognize as no parent.
Emitted periodically while a subagent or background task is running. For the run_id field, see SDKTaskStartedMessage, which defines it and its version requirement.For a subagent task, the summary field carries a model-generated progress summary and is populated only when agentProgressSummaries is enabled. For a backgrounded MCP tool call, summary carries the MCP server’s latest reported progress and doesn’t depend on that option.
Emitted when a background task’s state changes, such as when it transitions from running to completed. Merge patch into your local task map keyed by task_id. The end_time field is a Unix epoch timestamp in milliseconds, comparable with Date.now(). For the run_id field, see SDKTaskStartedMessage, which defines it and its version requirement.
Emitted whenever the set of live background tasks changes: a task starts, completes, or is killed; a foreground agent is backgrounded; or a task’s description, ambient, or parent_task_id field changes. For the run_id and parent_task_id fields on each entry, see SDKTaskStartedMessage, which defines them and their version requirements.The tasks array is the full live set. Replace any cached set with each payload instead of pairing task_started and task_notification events, so the next membership change corrects any event you missed.When a task ends, its task_updated and task_notification arrive before the background_tasks_changed that drops it from the list. Ordering relative to the per-task events is otherwise unspecified.Nothing is emitted at startup. Reset to an empty set whenever the session’s CLI process starts or restarts and let the next membership change repopulate it.When you send a repeated initialize control request to a running session, such as with reinitialize() after a transport gap, Claude Code follows the response with a snapshot of the current live set, even when it is empty. A reconnecting host therefore learns what is running without waiting for the next membership change. Before Agent SDK v0.3.239, Claude Code sent no snapshot after a repeated initialize.Requires Claude Code v2.1.203 or later.
subagent_type names the subagent type on entries whose task_type is "local_agent", such as general-purpose or a custom subagent’s name. The field requires Agent SDK v0.3.293 or later.
Emitted while Claude is producing a thinking block, including a redacted one. estimated_tokens is a running estimate of the thinking tokens generated so far in the current block, and estimated_tokens_delta is the increment carried by this frame. Use these estimates for progress display.When the model or provider reports a breakdown, the final count for the top-level agent loop is the result message’s usage.output_tokens_details.thinking_tokens, which doesn’t include subagent tokens.Requires Claude Code v2.1.153 or later.
Emitted when Claude Code reports the session’s state. To receive these messages, set CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS=1. Claude Code can report the same state more than once, so read a message as the session’s current state rather than as a transition.The state field carries one of these values:
running: the session is working.
idle: Claude Code is waiting for your next prompt.
requires_action: the session is blocked on an answer to a request it sent your host, such as a permission prompt.
A turn’s idle message and its result message can arrive in either order. To change whether idle waits for background work such as a background subagent or a workflow run, see CLAUDE_CODE_BG_TASKS_REPORT_RUNNING.
When errorCode is "credits_required", the rejection is from a claude.ai subscription whose included usage is exhausted, and the session cannot continue until the user buys usage credits. canUserPurchaseCredits indicates whether the authenticated user can buy credits for the account, and hasChargeableSavedPaymentMethod indicates whether a saved payment method is on file. All three fields are absent on rate-limit events that are not credits-required rejections. Requires Claude Code v2.1.181 or later.
Claude Code doesn’t emit this message type. When you send a command such as /context or /usage as a prompt, its output arrives as an SDKAssistantMessage.
Emitted when the set of available commands changes mid-session, such as when Claude Code discovers skills as the agent enters a subdirectory. The commands array is the full updated list, so replace any cached command list with this payload. Calling supportedCommands() after this message returns the same updated list, because the method tracks the latest push; this requires Agent SDK v0.3.216 or later. In earlier SDK versions, supportedCommands() returns the snapshot captured at initialization and never reflects mid-session changes.Claude Code also emits this message when an MCP server’s prompts join or leave the list, for example when a server finishes connecting after the session starts. This requires Claude Code v2.1.281 or later.
Emitted after a turn when promptSuggestions is enabled and Claude Code generated a suggestion for that turn. Contains the predicted next user prompt. For the turns that get none, see When Claude Code skips suggestions.
Emitted when the session’s conversation is replaced without ending the session. In a query() call, only /clear and its aliases produce this message. Mount an empty transcript under new_conversation_id and discard any cached session title.
trigger: what discarded the conversation. Reset your transcript on every conversation_reset message, including one where this field is absent or carries a value you don’t recognize.
user_message_uuid: the uuid of the user message that carried the /clear. Use it to match the reset to that message.
timestamp: when the reset happened, as an ISO 8601 string in UTC. Use it for display, not for ordering messages.
The trigger, user_message_uuid, and timestamp fields require Claude Code v2.1.281 or later.The SDK’s published typings declare SDKConversationResetMessage in Claude Code v2.1.203 and later. Before v2.1.203, SDKMessage referenced the type without declaring it, so narrowing on type === "conversation_reset" failed to typecheck when skipLibCheck was disabled.
Use these two constants to check tool names that your application’s users enter. Both spell each name the way you write it in permission rules, hook matchers, and the tools and disallowedTools options. Import them from @anthropic-ai/claude-agent-sdk or from @anthropic-ai/claude-agent-sdk/core. They require Agent SDK v0.3.301 or later and are alpha.The SDK’s type declarations give BUILTIN_TOOL_NAMES a readonly tuple type and LEGACY_TOOL_NAME_ALIASES a string-to-string record type:
BUILTIN_TOOL_NAMES: names of Claude Code’s built-in tools in alphabetical order, such as Agent, Bash, and Read. MCP tool names aren’t included. Because the type is a tuple of string literals, (typeof BUILTIN_TOOL_NAMES)[number] gives you a union type of the names
LEGACY_TOOL_NAME_ALIASES: earlier tool names that permission rules, hook matchers, and the tools and disallowedTools options still accept. Each key is an earlier name and its value is the current one: for example, Task maps to Agent, and KillShell and KillBash map to TaskStop
You can confirm a name with either of two tests: BUILTIN_TOOL_NAMES includes it, or Object.hasOwn(LEGACY_TOOL_NAME_ALIASES, name) returns true. A name that fails both can still be valid, because BUILTIN_TOOL_NAMES leaves out MCP tools and some built-in tools. If you build a deny list from BUILTIN_TOOL_NAMES, Claude can still use the tools the constant leaves out. To deny every tool, set disallowedTools: ["*"] instead.Finding a name in BUILTIN_TOOL_NAMES doesn’t tell you the session has that tool: TodoWrite is listed even though it’s disabled by default. To see which tools a session has, read the tools array of its SDKSystemMessage. That array includes MCP tools and lists the Agent tool as Task, so map each name through LEGACY_TOOL_NAME_ALIASES before comparing it with BUILTIN_TOOL_NAMES.
AbortError is the only error class in the SDK’s typed API. Other failures, such as the Claude Code process exiting or failing to launch, reject the message iteration with errors that carry no SDK class to match on. Troubleshooting keys those errors by message, with the cause and fix for each.
Stop at startup if enabled is true but the sandbox can’t start. Set false to fall back to unsandboxed execution with a warning on stderr
autoAllowBashIfSandboxed
boolean
true
Auto-approve Bash commands when sandbox is enabled
excludedCommands
string[]
[]
Commands that bypass sandbox restrictions, such as ['docker *']. These run unsandboxed automatically without model involvement; sandbox.excludedCommands covers when an entry applies
allowUnsandboxedCommands
boolean
true
Allow the model to request running commands outside the sandbox. When true, the model can set dangerouslyDisableSandbox in tool input, which falls back to the permissions system
Filesystem-specific sandbox configuration for read/write restrictions
ignoreViolations
Record<string, string[]>
undefined
Map of command substrings, or * for every command, to substrings of the violation text to ignore, such as { "*": ['/etc/hosts'] }; see sandbox.ignoreViolations
enableWeakerNestedSandbox
boolean
false
Enable a weaker nested sandbox for compatibility
allowNestedUserNamespaces
boolean
false
Let sandboxed commands on Linux and WSL2 create user namespaces. Before you set it to true, read sandbox.allowNestedUserNamespaces, which covers the tools that need it and the security boundary you turn off. Requires Claude Code v2.1.305 or later
ripgrep
{ command: string; args?: string[] }
undefined
Custom ripgrep binary configuration for sandbox environments
The sandbox depends on platform support and, on Linux, tools like bubblewrap and socat. When enabled is true and the sandbox can’t start, query() reports a result message with subtype: "error_during_execution" and the reason in errors. For a single message query() call, the SDK throws after yielding that error result, so wrap the loop in a try block to continue past it. See Handle the result for the error contract.To run unsandboxed instead, set failIfUnavailable: false.
import { query } from "@anthropic-ai/claude-agent-sdk";try { for await (const message of query({ prompt: "Build and test my project", options: { sandbox: { enabled: true, autoAllowBashIfSandboxed: true, network: { allowLocalBinding: true } } } })) { if ("result" in message) console.log(message.result); }} catch (error) { // A single-shot query() throws after yielding an error result, // such as when the sandbox can't start (failIfUnavailable defaults to true). console.log(`Session ended with an error: ${error}`);}
Unix socket security: The allowUnixSockets option can grant access to system services that reach outside the sandbox. For example, allowing /var/run/docker.sock effectively grants full host system access through the Docker API, bypassing sandbox isolation. Only allow Unix sockets that are strictly necessary and understand the security implications of each.
Network-specific configuration for sandbox mode. These settings apply to sandboxed Bash commands when enabled is true in the parent SandboxSettings. They do not restrict the WebFetch tool, which uses permission rules instead.
Domain names that sandboxed processes cannot access. Takes precedence over allowedDomains
strictAllowlist
boolean
false
Deny sandboxed commands access to hosts outside the network allowlist instead of prompting. Enforced for sandboxed commands only; in-process tools such as WebFetch aren’t gated by it. Only honored from user, managed, or CLI --settings settings; project settings are ignored. Requires Claude Code v2.1.219 or later
allowManagedDomainsOnly
boolean
false
Managed-settings only. When set in managed settings, only allowedDomains entries and WebFetch(domain:...) allow rules from managed settings are honored, and allow entries from user, project, or local settings are ignored. From the SDK, pass it through the managedSettings option
allowLocalBinding
boolean
false
Allow processes to bind to local ports (for example, for dev servers)
allowUnixSockets
string[]
[]
Unix socket paths that processes can access (for example, Docker socket)
allowAllUnixSockets
boolean
false
Allow access to all Unix sockets, and on Linux to VM sockets (AF_VSOCK)
httpProxyPort
number
undefined
HTTP proxy port for network requests
socksProxyPort
number
undefined
SOCKS proxy port for network requests
The built-in sandbox proxy enforces allowedDomains based on the requested hostname and does not terminate or inspect TLS traffic, so techniques such as domain fronting can potentially bypass it. See Sandboxing security limitations for details and Secure deployment for configuring a TLS-terminating proxy.
When allowUnsandboxedCommands is enabled, the model can request to run commands outside the sandbox by setting dangerouslyDisableSandbox: true in the tool input. These requests fall back to the existing permissions system, meaning your canUseTool handler is invoked, allowing you to implement custom authorization logic.Your excludedCommands entries instead take a call out of the sandbox with no model involvement; sandbox.excludedCommands covers when an entry applies.In the example below, isCommandAuthorized stands in for an authorization check you define.
import { query } from "@anthropic-ai/claude-agent-sdk";for await (const message of query({ prompt: "Deploy my application", options: { sandbox: { enabled: true, allowUnsandboxedCommands: true // Model can request unsandboxed execution }, permissionMode: "default", canUseTool: async (tool, input) => { // Check if the model is requesting to bypass the sandbox if (tool === "Bash" && input.dangerouslyDisableSandbox) { // The model is requesting to run this command outside the sandbox console.log(`Unsandboxed command requested: ${input.command}`); if (isCommandAuthorized(input.command)) { return { behavior: "allow" as const, updatedInput: input }; } return { behavior: "deny" as const, message: "Command not authorized for unsandboxed execution" }; } return { behavior: "allow" as const, updatedInput: input }; } }})) { if ("result" in message) console.log(message.result);}
Commands running with dangerouslyDisableSandbox: true have full system access. Ensure your canUseTool handler validates these requests carefully.If permissionMode is set to bypassPermissions and allowUnsandboxedCommands is enabled, the model can autonomously execute commands outside the sandbox without approval prompts, apart from the actions no mode auto-approves. This combination effectively allows the model to escape sandbox isolation silently.