Follow Discord
Sweep 23 Oct 2026 · 21:48Z Build v2.1.310 529 read Stable v2.1.308 Latest v2.1.309 Next v2.1.310 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One capture · claude-code

One read of Claude Code CLIclaude-code-20261023T190701Z

220 pages moved out of 228 read.

Pages moved 220 significant first
Pages read 228 in this capture
Captured 19:07 UTC
Corpus hash 7e3663570d29 corpus-hash

What this read moved

26-50 of 220, page 2 of 9

This capture is too large to show at once. Changes 26-50 of 220 are below, significant first; the rest are on the following screens.

agent-sdk/structured-outputs Changed · +5 / -5 lines

from line 50
5050 
5151To use structured outputs, define a [JSON Schema](https://json-schema.org/understanding-json-schema/about) describing the shape of data you want, then pass it to `query()` via the `outputFormat` option (TypeScript) or `output_format` option (Python). When the agent finishes, the result message includes a `structured_output` field with validated data matching your schema.
5252 
53Before running the examples on this page, install the Claude Agent SDK by following the [quickstart](/docs/en/agent-sdk/quickstart.md#setup). The example below asks the agent to research Anthropic and return the company name, year founded, and headquarters as structured output.
53Before running the examples on this page, install the Claude Agent SDK by following the [quickstart](https://code.claude.com/docs/en/agent-sdk/quickstart.md#setup). The example below asks the agent to research Anthropic and return the company name, year founded, and headquarters as structured output.
5454 
5555```typescript TypeScript theme={null}
5656import { query } from "@anthropic-ai/claude-agent-sdk";
from line 366
366366 
367367## Recognize the StructuredOutput tool call
368368 
369When you set `outputFormat` in TypeScript or `output_format` in Python, your message stream carries a tool call named `StructuredOutput` that you never defined. Claude Code adds this tool to the session, and the agent calls it to return its answer. The [system init message](/docs/en/agent-sdk/typescript.md#sdksystemmessage) lists it in the `tools` array, and each call arrives as two blocks:
369When you set `outputFormat` in TypeScript or `output_format` in Python, your message stream carries a tool call named `StructuredOutput` that you never defined. Claude Code adds this tool to the session, and the agent calls it to return its answer. The [system init message](https://code.claude.com/docs/en/agent-sdk/typescript.md#sdksystemmessage) lists it in the `tools` array, and each call arrives as two blocks:
370370 
371371* A `tool_use` block named `StructuredOutput`, whose input is the object the agent produced for your schema
372372* A `tool_result` block reading `Structured output provided successfully`
from line 377
377377 
378378## Error handling
379379 
380Structured output generation can fail when the agent cannot produce valid JSON matching your schema. This typically happens when the schema is too complex for the task, the task itself is ambiguous, or the agent hits its retry limit trying to fix validation errors. It can also happen without any validation failure: a [model fallback](/docs/en/model-config.md#automatic-model-fallback) can retract an already-completed output mid-stream, and if no retry replaces it the run ends with the same error. Check the `errors` list on the error result message to tell the two causes apart before debugging your schema.
380Structured output generation can fail when the agent cannot produce valid JSON matching your schema. This typically happens when the schema is too complex for the task, the task itself is ambiguous, or the agent hits its retry limit trying to fix validation errors. It can also happen without any validation failure: a [model fallback](https://code.claude.com/docs/en/model-config.md#automatic-model-fallback) can retract an already-completed output mid-stream, and if no retry replaces it the run ends with the same error. Check the `errors` list on the error result message to tell the two causes apart before debugging your schema.
381381 
382382When an error occurs, the result message has a `subtype` indicating what went wrong:
383383 
from line 386
386386| `success` | Output was generated and validated successfully |
387387| `error_max_structured_output_retries` | No valid output remained after multiple attempts (validation failures, or a model-fallback retraction with no successful retry) |
388388 
389A result can also end with subtype `success` but no `structured_output` value, for example when the run completes without the agent producing a structured output. Treat that case as a failure as well. The troubleshooting entry [structured\_output is None but the result says success](/docs/en/agent-sdk/troubleshooting.md#structured_output-is-none-but-the-result-says-success) covers this case. The example below treats a result as successful only when the `subtype` is `success` and `structured_output` is present, and handles every other result as a failure:
389A result can also end with subtype `success` but no `structured_output` value, for example when the run completes without the agent producing a structured output. Treat that case as a failure as well. The troubleshooting entry [structured\_output is None but the result says success](https://code.claude.com/docs/en/agent-sdk/troubleshooting.md#structured_output-is-none-but-the-result-says-success) covers this case. The example below treats a result as successful only when the `subtype` is `success` and `structured_output` is present, and handles every other result as a failure:
390390 
391391```typescript TypeScript theme={null}
392392import { query } from "@anthropic-ai/claude-agent-sdk";
from line 479
479479 
480480* [JSON Schema documentation](https://json-schema.org/): learn JSON Schema syntax for defining complex schemas with nested objects, arrays, enums, and validation constraints
481481* [API Structured Outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs): use structured outputs with the Claude API directly for single-turn requests without tool use
482* [Custom tools](/docs/en/agent-sdk/custom-tools.md): give your agent custom tools to call during execution before returning structured output
482* [Custom tools](https://code.claude.com/docs/en/agent-sdk/custom-tools.md): give your agent custom tools to call during execution before returning structured output
483483 

agent-sdk/subagents Changed · +41 / -41 lines

from line 9
99 
1010You can create subagents in three ways:
1111 
12* **Programmatically**: use the `agents` parameter in your `query()` options. See the [TypeScript](/docs/en/agent-sdk/typescript.md#agentdefinition) and [Python](/docs/en/agent-sdk/python.md#agentdefinition) references
13* **Filesystem-based**: define agents as markdown files in `.claude/agents/` directories. See [defining subagents as files](/docs/en/sub-agents.md)
12* **Programmatically**: use the `agents` parameter in your `query()` options. See the [TypeScript](https://code.claude.com/docs/en/agent-sdk/typescript.md#agentdefinition) and [Python](https://code.claude.com/docs/en/agent-sdk/python.md#agentdefinition) references
13* **Filesystem-based**: define agents as markdown files in `.claude/agents/` directories. See [defining subagents as files](https://code.claude.com/docs/en/sub-agents.md)
1414* **Built-in general-purpose**: Claude can invoke the built-in `general-purpose` subagent at any time via the Agent tool without you defining anything
1515 
1616This guide focuses on the programmatic approach, which is recommended for SDK applications.
from line 19
1919 
2020Because subagents are separate agent instances, delegating work to them gives you four benefits:
2121 
22* **Context isolation**: each subagent runs in its own conversation, which starts fresh unless the subagent is a [fork](/docs/en/sub-agents.md#fork-the-current-conversation). Either way, intermediate tool calls and results stay inside the subagent; only its final message returns to the parent. A `research-assistant` subagent can explore dozens of files without any of that content accumulating in the main conversation. The parent receives a concise summary, not every file the subagent read. See [What subagents inherit](#what-subagents-inherit) for exactly what's in the subagent's context.
22* **Context isolation**: each subagent runs in its own conversation, which starts fresh unless the subagent is a [fork](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation). Either way, intermediate tool calls and results stay inside the subagent; only its final message returns to the parent. A `research-assistant` subagent can explore dozens of files without any of that content accumulating in the main conversation. The parent receives a concise summary, not every file the subagent read. See [What subagents inherit](#what-subagents-inherit) for exactly what's in the subagent's context.
2323* **Parallelization**: multiple subagents can run concurrently, so independent subtasks finish in the time of the slowest one rather than the sum of all of them. During a code review, you can run `style-checker`, `security-scanner`, and `test-coverage` subagents simultaneously instead of sequentially.
2424* **Specialized instructions and knowledge**: each subagent can have a tailored system prompt with specific expertise, best practices, and constraints. A `database-migration` subagent can have detailed knowledge about SQL best practices, rollback strategies, and data integrity checks that would be unnecessary noise in the main agent's instructions.
2525* **Tool restrictions**: subagents can be limited to specific tools, reducing the risk of unintended actions. A `doc-reviewer` subagent might only have access to Read and Grep tools, ensuring it can analyze but never accidentally modify your documentation files.
from line 140
140140| :- | :- | :- | :- |
141141| `description` | `string` | Yes | Natural language description of when to use this agent |
142142| `prompt` | `string` | Yes | The agent's system prompt defining its role and behavior |
143| `tools` | `string[]` | No | Array of allowed tool names. If omitted, inherits every [tool available to subagents](/docs/en/sub-agents.md#available-tools) |
143| `tools` | `string[]` | No | Array of allowed tool names. If omitted, inherits every [tool available to subagents](https://code.claude.com/docs/en/sub-agents.md#available-tools) |
144144| `disallowedTools` | `string[]` | No | Array of tool names to remove from the agent's tool set. 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 |
145| `model` | `string` | 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](/docs/en/sub-agents.md#choose-a-model) |
146| `skills` | `string[]` | No | List of skill names to preload into the agent's context at startup. At most the [first 32 distinct names](/docs/en/sub-agents.md#preload-skills-into-subagents) in the list are preloaded. Unlisted skills remain invocable through the Skill tool |
145| `model` | `string` | 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](https://code.claude.com/docs/en/sub-agents.md#choose-a-model) |
146| `skills` | `string[]` | No | List of skill names to preload into the agent's context at startup. At most the [first 32 distinct names](https://code.claude.com/docs/en/sub-agents.md#preload-skills-into-subagents) in the list are preloaded. Unlisted skills remain invocable through the Skill tool |
147147| `memory` | `'user' \| 'project' \| 'local'` | No | Memory source for this agent |
148148| `mcpServers` | `(string \| object)[]` | No | MCP servers available to this agent, by name or inline config |
149149| `initialPrompt` | `string` | No | Auto-submitted as the first user turn when this agent runs as the main thread agent. Ignored when the agent is invoked as a subagent |
150150| `maxTurns` | `number` | No | Maximum number of agentic turns before the agent stops. When the agent reaches the limit, Claude Code returns its output marked as partial, and you can [resume the agent](#resume-subagents) to continue. The partial marking requires Claude Code v2.1.246 or later |
151| `autoCompactWindow` | `number` | No | Lower the [auto-compact window](/docs/en/sub-agents.md#subagent-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. The Python SDK's [`AgentDefinition`](/docs/en/agent-sdk/python#agentdefinition) doesn't have this field |
151| `autoCompactWindow` | `number` | No | Lower the [auto-compact window](https://code.claude.com/docs/en/sub-agents.md#subagent-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. The Python SDK's [`AgentDefinition`](https://code.claude.com/docs/en/agent-sdk/python#agentdefinition) doesn't have this field |
152152| `background` | `boolean` | No | Run this agent as a non-blocking background task when invoked |
153| `omitClaudeMd` | `boolean` | No | Leave the user, project, and local CLAUDE.md files out of this agent's initial context; managed policy files still load. Ignored when the agent runs as the main thread agent. Requires TypeScript Agent SDK v0.3.271 or later. The Python SDK's [`AgentDefinition`](/docs/en/agent-sdk/python#agentdefinition) doesn't have this field |
153| `omitClaudeMd` | `boolean` | No | Leave the user, project, and local CLAUDE.md files out of this agent's initial context; managed policy files still load. Ignored when the agent runs as the main thread agent. Requires TypeScript Agent SDK v0.3.271 or later. The Python SDK's [`AgentDefinition`](https://code.claude.com/docs/en/agent-sdk/python#agentdefinition) doesn't have this field |
154154| `effort` | `'low' \| 'medium' \| 'high' \| 'xhigh' \| 'max' \| number` | No | Reasoning effort level for this agent |
155| `permissionMode` | `PermissionMode` | No | Permission mode for tool execution within this agent. The [subagent inheritance rules](/docs/en/agent-sdk/permissions.md#available-modes) decide when it applies |
155| `permissionMode` | `PermissionMode` | No | Permission mode for tool execution within this agent. The [subagent inheritance rules](https://code.claude.com/docs/en/agent-sdk/permissions.md#available-modes) decide when it applies |
156156 
157In the Python SDK, multi-word field names such as `disallowedTools` and `mcpServers` keep their camelCase spelling to match the wire format rather than following Python's snake\_case convention. See the [`AgentDefinition` reference](/docs/en/agent-sdk/python#agentdefinition) for details.
157In the Python SDK, multi-word field names such as `disallowedTools` and `mcpServers` keep their camelCase spelling to match the wire format rather than following Python's snake\_case convention. See the [`AgentDefinition` reference](https://code.claude.com/docs/en/agent-sdk/python#agentdefinition) for details.
158158 
159159#### Choose whether Claude waits for subagents
160160 
161By default, a subagent your main agent spawns [runs in the background](/docs/en/sub-agents.md#run-subagents-in-foreground-or-background). The Agent tool result has `status: "async_launched"`, and the report arrives in a later turn.
161By default, a subagent your main agent spawns [runs in the background](https://code.claude.com/docs/en/sub-agents.md#run-subagents-in-foreground-or-background). The Agent tool result has `status: "async_launched"`, and the report arrives in a later turn.
162162 
163163Claude waits when its next action needs the report: the call blocks and returns `status: "completed"`. To make that choice yourself:
164164 
from line 167
167167 
168168### Filesystem-based definition (alternative)
169169 
170You can also define subagents as markdown files in `.claude/agents/` directories. See the [Claude Code subagents documentation](/docs/en/sub-agents.md) for details on this approach. Programmatically defined agents take precedence over filesystem-based agents with the same name.
170You can also define subagents as markdown files in `.claude/agents/` directories. See the [Claude Code subagents documentation](https://code.claude.com/docs/en/sub-agents.md) for details on this approach. Programmatically defined agents take precedence over filesystem-based agents with the same name.
171171 
172172> [!NOTE]
173173>
174> When Claude calls the Agent tool without a `subagent_type`, it gets the built-in `general-purpose` subagent, which Claude can spawn even when you define no agents of your own. Setting [`CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS=1`](/docs/en/env-vars) removes that default, and such a call fails with [`subagent_type is required`](/docs/en/errors#subagent-type-is-required).
174> When Claude calls the Agent tool without a `subagent_type`, it gets the built-in `general-purpose` subagent, which Claude can spawn even when you define no agents of your own. Setting [`CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS=1`](https://code.claude.com/docs/en/env-vars) removes that default, and such a call fails with [`subagent_type is required`](https://code.claude.com/docs/en/errors#subagent-type-is-required).
175175 
176176## What subagents inherit
177177 
178Unless the subagent is a [fork](/docs/en/sub-agents.md#fork-the-current-conversation), its context window starts fresh, with no parent conversation, but isn't empty. The only content you pass from parent to subagent is the Agent tool's prompt string, so include any file paths, error messages, or decisions the subagent needs directly in that prompt.
178Unless the subagent is a [fork](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation), its context window starts fresh, with no parent conversation, but isn't empty. The only content you pass from parent to subagent is the Agent tool's prompt string, so include any file paths, error messages, or decisions the subagent needs directly in that prompt.
179179 
180A subagent that has the [`SendMessage`](/docs/en/tools-reference) tool starts with a list of the other named agents running in the session, so it knows which names it can send messages to. Claude Code adds the list to the subagent's first turn automatically. A [fork](/docs/en/sub-agents.md#fork-the-current-conversation) doesn't get the list because it inherits the parent conversation instead.
180A subagent that has the [`SendMessage`](https://code.claude.com/docs/en/tools-reference) tool starts with a list of the other named agents running in the session, so it knows which names it can send messages to. Claude Code adds the list to the subagent's first turn automatically. A [fork](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation) doesn't get the list because it inherits the parent conversation instead.
181181 
182182A subagent also inherits the main session's extended thinking configuration.
183183 
from line 186
186186| The subagent receives | The subagent doesn't receive |
187187| :- | :- |
188188| Its own system prompt (`AgentDefinition.prompt`) and the Agent tool's prompt | The parent's conversation history or tool results |
189| Project CLAUDE.md (loaded via [`settingSources`](/docs/en/agent-sdk/claude-code-features#control-filesystem-settings-with-settingsources)). An agent that sets [`omitClaudeMd`](#agentdefinition-configuration) starts without it | Preloaded skill content, unless listed in `AgentDefinition.skills` |
190| Tool definitions (inherited from parent or the subset in `tools`, [filtered for background runs](/docs/en/sub-agents.md#available-tools)) | The parent's system prompt |
189| Project CLAUDE.md (loaded via [`settingSources`](https://code.claude.com/docs/en/agent-sdk/claude-code-features#control-filesystem-settings-with-settingsources)). An agent that sets [`omitClaudeMd`](#agentdefinition-configuration) starts without it | Preloaded skill content, unless listed in `AgentDefinition.skills` |
190| Tool definitions (inherited from parent or the subset in `tools`, [filtered for background runs](https://code.claude.com/docs/en/sub-agents.md#available-tools)) | The parent's system prompt |
191191 
192192> [!NOTE]
193193>
194194> The parent receives the subagent's final report, but may summarize it in its own response. To preserve subagent output verbatim in the user-facing response, include an instruction to do so in the prompt or `systemPrompt` option you pass to the main `query()` call.
195195>
196> In v2.1.210 and later, Claude Code [scans the final message for instruction-shaped patterns](/docs/en/sub-agents.md#subagent-output-scanning) before the parent reads it. The scan treats three kinds of pattern differently:
196> In v2.1.210 and later, Claude Code [scans the final message for instruction-shaped patterns](https://code.claude.com/docs/en/sub-agents.md#subagent-output-scanning) before the parent reads it. The scan treats three kinds of pattern differently:
197197>
198198> * **Control-tag imitation**: Claude Code neutralizes a tag that only the harness emits, such as a `<system-reminder>` block, in place. It inserts a backslash after the opening angle bracket and deletes nothing.
199199> * **Permission-configuration mentions**: Claude Code keeps references to the permission configuration, such as `.claude/settings.json`, `bypassPermissions`, or `--dangerously-skip-permissions`, as written.
from line 201
201201>
202202> For a control-tag or permission-configuration match, Claude Code prepends a `[harness: ...]` marker line naming the matched patterns; a turn-marker match doesn't add the marker line. Those are the only modifications the scan makes: it never removes or rewords the subagent's text.
203203 
204An API error that ends the subagent early, such as a rate limit, is never delivered as its result. See [API errors in subagents](/docs/en/sub-agents.md#api-errors-in-subagents) for the foreground and background behavior.
204An API error that ends the subagent early, such as a rate limit, is never delivered as its result. See [API errors in subagents](https://code.claude.com/docs/en/sub-agents.md#api-errors-in-subagents) for the foreground and background behavior.
205205 
206206## Invoke subagents
207207 
from line 223
223223 
224224### Forked subagents
225225 
226A [fork](/docs/en/sub-agents.md#fork-the-current-conversation) is a subagent that copies the conversation so far instead of starting fresh. From Claude Code v2.1.302, Claude can start forks in your application with nothing configured, by calling the Agent tool with `subagent_type: "fork"`.
226A [fork](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation) is a subagent that copies the conversation so far instead of starting fresh. From Claude Code v2.1.302, Claude can start forks in your application with nothing configured, by calling the Agent tool with `subagent_type: "fork"`.
227227 
228To stop Claude from starting forks, add an [`Agent(fork)` deny rule](/docs/en/agent-sdk/permissions#allow-and-deny-rules):
228To stop Claude from starting forks, add an [`Agent(fork)` deny rule](https://code.claude.com/docs/en/agent-sdk/permissions#allow-and-deny-rules):
229229 
230230```python Python theme={null}
231231options = ClaudeAgentOptions(
from line 319
319319 
320320Claude invokes subagents through the Agent tool. To detect when a subagent is invoked, check for `tool_use` blocks where `name` is `"Agent"`.
321321 
322Messages from within a subagent's context include a `parent_tool_use_id` field. In TypeScript, each assistant and user message a subagent produces also carries [`agent_id`](/docs/en/agent-sdk/typescript#sdkassistantmessage): the `task_id` of that subagent's [task events](/docs/en/agent-sdk/typescript.md#sdktaskstartedmessage). `agent_id` stays the same when you [resume the subagent](#resume-subagents). `agent_id` requires TypeScript Agent SDK v0.3.292 or later.
322Messages from within a subagent's context include a `parent_tool_use_id` field. In TypeScript, each assistant and user message a subagent produces also carries [`agent_id`](https://code.claude.com/docs/en/agent-sdk/typescript#sdkassistantmessage): the `task_id` of that subagent's [task events](https://code.claude.com/docs/en/agent-sdk/typescript.md#sdktaskstartedmessage). `agent_id` stays the same when you [resume the subagent](#resume-subagents). `agent_id` requires TypeScript Agent SDK v0.3.292 or later.
323323 
324324> [!NOTE]
325325>
from line 417
417417 
418418When a subagent stops at its [`maxTurns`](#agentdefinition-configuration) limit, Claude Code marks the output in the Agent tool result as partial, so Claude knows the run is unfinished.
419419 
420When a subagent completes, the Agent tool result includes a text block containing `agentId: <id>`. The built-in [`Explore` and `Plan` agents](/docs/en/sub-agents#built-in-subagents) are one-shot and don't return an `agentId`, so use a custom agent or `general-purpose` when you need to resume. To resume a subagent programmatically:
420When a subagent completes, the Agent tool result includes a text block containing `agentId: <id>`. The built-in [`Explore` and `Plan` agents](https://code.claude.com/docs/en/sub-agents#built-in-subagents) are one-shot and don't return an `agentId`, so use a custom agent or `general-purpose` when you need to resume. To resume a subagent programmatically:
421421 
4224221. **Capture the session ID**: extract `session_id` from messages during the first query
4234232. **Extract the agent ID**: parse `agentId` from the Agent tool result text
from line 549
549549}
550550```
551551 
552Subagent transcripts are stored in separate files and persist independently of the main conversation. See [resume subagents in Claude Code](/docs/en/sub-agents.md#resume-subagents) for compaction behavior and the `cleanupPeriodDays` cleanup period.
552Subagent transcripts are stored in separate files and persist independently of the main conversation. See [resume subagents in Claude Code](https://code.claude.com/docs/en/sub-agents.md#resume-subagents) for compaction behavior and the `cleanupPeriodDays` cleanup period.
553553 
554554## Tool restrictions
555555 
556556Use the `tools` field to limit what a subagent can do:
557557 
558* **Omit `tools`**: the subagent gets every [tool available to subagents](/docs/en/sub-agents.md#available-tools)
558* **Omit `tools`**: the subagent gets every [tool available to subagents](https://code.claude.com/docs/en/sub-agents.md#available-tools)
559559* **List tools**: the subagent gets only those. A code reviewer that should never edit files, for example, gets `["Read", "Grep", "Glob"]`
560560 
561561A tool you leave out isn't in the subagent's session at all: Claude works without it, with no permission prompt or error.
from line 625
625625 
626626> [!NOTE]
627627>
628> This section describes TypeScript SDK v0.3.219 and Python SDK v0.2.127 and later, the releases that bundle Claude Code v2.1.219 or later. On earlier releases, some of these limits are missing or default differently, so upgrade before you rely on them to bound a run. The [environment variable reference](/docs/en/env-vars.md) and [turns and budget](/docs/en/agent-sdk/agent-loop.md#turns-and-budget) record the Claude Code version that added each variable and the spend cap's subagent enforcement.
628> This section describes TypeScript SDK v0.3.219 and Python SDK v0.2.127 and later, the releases that bundle Claude Code v2.1.219 or later. On earlier releases, some of these limits are missing or default differently, so upgrade before you rely on them to bound a run. The [environment variable reference](https://code.claude.com/docs/en/env-vars.md) and [turns and budget](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#turns-and-budget) record the Claude Code version that added each variable and the spend cap's subagent enforcement.
629629 
630630Claude decides on its own when to spawn a subagent and how many to spawn. Each subagent makes its own API requests, which count toward the query's `total_cost_usd`, and a subagent can spawn subagents of its own, so one prompt can grow into a tree of agents.
631631 
632You can cap that growth in three ways: how deeply subagents nest, how many run at once, and how much the whole query spends. Set the depth and concurrency limits as environment variables through the [`env`](/docs/en/agent-sdk/typescript#options) option, and the spend limit as a query option:
632You can cap that growth in three ways: how deeply subagents nest, how many run at once, and how much the whole query spends. Set the depth and concurrency limits as environment variables through the [`env`](https://code.claude.com/docs/en/agent-sdk/typescript#options) option, and the spend limit as a query option:
633633 
634634| Limit | Set it with | Default | What Claude Code does at the limit |
635635| :- | :- | :- | :- |
636| Depth | [`CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH`](/docs/en/env-vars) | `3` layers of subagents below your main agent. `1` stops your subagents from spawning any of their own | Leaves a subagent at the bottom layer unable to spawn, so it does its delegated work itself. See [nested subagents](/docs/en/sub-agents.md#let-subagents-spawn-their-own-subagents) |
637| Concurrency | [`CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS`](/docs/en/env-vars) | `20` subagents running at once, counting every subagent Claude spawns with the Agent tool | Refuses to spawn another subagent, returning `Concurrent subagent limit reached`, until the running count drops below the limit. Sessions with [ultracode](/docs/en/model-config.md#adjust-effort-level) active are never refused. See the [concurrent subagent limit](/docs/en/sub-agents.md#concurrent-subagent-limit) |
638| Spend | `maxBudgetUsd` in TypeScript, `max_budget_usd` in Python | No limit. Counts the call's own spend, subagent requests included | Enforces the cap in three ways: refuses to spawn more subagents, returning `Budget limit reached`, stops background subagents that are still running, and ends the query with the `error_max_budget_usd` result subtype. For how the caps behave across a session, see [turns and budget](/docs/en/agent-sdk/agent-loop.md#turns-and-budget) |
636| Depth | [`CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH`](https://code.claude.com/docs/en/env-vars) | `3` layers of subagents below your main agent. `1` stops your subagents from spawning any of their own | Leaves a subagent at the bottom layer unable to spawn, so it does its delegated work itself. See [nested subagents](https://code.claude.com/docs/en/sub-agents.md#let-subagents-spawn-their-own-subagents) |
637| Concurrency | [`CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS`](https://code.claude.com/docs/en/env-vars) | `20` subagents running at once, counting every subagent Claude spawns with the Agent tool | Refuses to spawn another subagent, returning `Concurrent subagent limit reached`, until the running count drops below the limit. Sessions with [ultracode](https://code.claude.com/docs/en/model-config.md#adjust-effort-level) active are never refused. See the [concurrent subagent limit](https://code.claude.com/docs/en/sub-agents.md#concurrent-subagent-limit) |
638| Spend | `maxBudgetUsd` in TypeScript, `max_budget_usd` in Python | No limit. Counts the call's own spend, subagent requests included | Enforces the cap in three ways: refuses to spawn more subagents, returning `Budget limit reached`, stops background subagents that are still running, and ends the query with the `error_max_budget_usd` result subtype. For how the caps behave across a session, see [turns and budget](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#turns-and-budget) |
639639 
640640The two SDKs treat the `env` option differently: the TypeScript SDK replaces the subprocess environment with it, so spread `process.env` into it to keep variables like `PATH`, while the Python SDK merges it into the inherited environment. This example turns nesting off, allows at most five subagents at a time, and stops the query once the estimated spend reaches \$5:
641641 
from line 705
705705 
706706### Run Opus 5 with subagents
707707 
708Claude Opus 5 delegates to subagents more readily than earlier models, so the [depth, concurrency, and spend limits](#cap-subagent-depth-concurrency-and-spend) matter most on queries that run Opus 5. The [Opus 5 prompting guide](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-opus-5#controlling-subagent-spawning) has a delegation instruction you can add to any prompt. Whether Claude Code adds an instruction of its own depends on which [system prompt](/docs/en/agent-sdk/modifying-system-prompts.md#how-system-prompts-work) you use:
708Claude Opus 5 delegates to subagents more readily than earlier models, so the [depth, concurrency, and spend limits](#cap-subagent-depth-concurrency-and-spend) matter most on queries that run Opus 5. The [Opus 5 prompting guide](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-opus-5#controlling-subagent-spawning) has a delegation instruction you can add to any prompt. Whether Claude Code adds an instruction of its own depends on which [system prompt](https://code.claude.com/docs/en/agent-sdk/modifying-system-prompts.md#how-system-prompts-work) you use:
709709 
710710* **`claude_code` preset**: when the model is Opus 5, Claude Code adds a line to its system prompt telling Claude not to call the Agent tool unless it's asked to. The Agent tool stays available.
711711* **A custom prompt, or no `systemPrompt`**: Claude Code doesn't build its system prompt, so that line is absent. Add the prompting guide's delegation instruction to your own prompt.
from line 714
714714 
715715## Scale up with dynamic workflows
716716 
717Subagents work well for a few delegated tasks per turn. For runs that coordinate dozens to hundreds of agents, use the `Workflow` tool, which moves the orchestration into a script the runtime executes outside the conversation context. See [dynamic workflows](/docs/en/workflows.md) for how workflows differ from turn-by-turn subagent delegation.
717Subagents work well for a few delegated tasks per turn. For runs that coordinate dozens to hundreds of agents, use the `Workflow` tool, which moves the orchestration into a script the runtime executes outside the conversation context. See [dynamic workflows](https://code.claude.com/docs/en/workflows.md) for how workflows differ from turn-by-turn subagent delegation.
718718 
719The `Workflow` tool is available in the TypeScript Agent SDK v0.3.149 and later. Include `Workflow` in `allowedTools` to auto-approve workflow runs. The tool input and output schemas are listed in the [TypeScript reference](/docs/en/agent-sdk/typescript.md#workflow).
719The `Workflow` tool is available in the TypeScript Agent SDK v0.3.149 and later. Include `Workflow` in `allowedTools` to auto-approve workflow runs. The tool input and output schemas are listed in the [TypeScript reference](https://code.claude.com/docs/en/agent-sdk/typescript.md#workflow).
720720 
721721## Troubleshooting
722722 
from line 737
737737* **A file under an added directory**: Claude Code loads `.claude/agents/` from directories added with the `add_dirs` (Python) or `additionalDirectories` (TypeScript) option, or the CLI's `--add-dir` or `/add-dir`, but doesn't watch them, so a new or edited file there needs a session restart.
738738* **A programmatic agent with the same name**: `agents` passed to `query()` override a filesystem agent with the same name.
739739 
740For the file format, see [how to write subagent files](/docs/en/sub-agents.md#write-subagent-files).
740For the file format, see [how to write subagent files](https://code.claude.com/docs/en/sub-agents.md#write-subagent-files).
741741 
742742## Related documentation
743743 
744* [Claude Code subagents](/docs/en/sub-agents.md): subagent documentation including filesystem-based definitions
745* [Dynamic workflows](/docs/en/workflows.md): orchestrate many subagents from a script for jobs too large for one conversation
746* [SDK overview](/docs/en/agent-sdk/overview.md): getting started with the Claude Agent SDK
744* [Claude Code subagents](https://code.claude.com/docs/en/sub-agents.md): subagent documentation including filesystem-based definitions
745* [Dynamic workflows](https://code.claude.com/docs/en/workflows.md): orchestrate many subagents from a script for jobs too large for one conversation
746* [SDK overview](https://code.claude.com/docs/en/agent-sdk/overview.md): getting started with the Claude Agent SDK
747747 

agent-sdk/todo-tracking Changed · +14 / -14 lines

from line 2
22 
33> Track todos in Agent SDK sessions and render Claude's progress in your application from structured tool calls
44 
5Claude Code provides the [task-tracking tools](/docs/en/tools-reference.md#task-tool-availability) by default only on the models listed under [Model availability](#model-availability). Newer models track multi-step work without a written todo list, so on those you don't need anything on this page for Claude to work through multi-step tasks.
5Claude Code provides the [task-tracking tools](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability) by default only on the models listed under [Model availability](#model-availability). Newer models track multi-step work without a written todo list, so on those you don't need anything on this page for Claude to work through multi-step tasks.
66 
77In a session that has the task-tracking tools, Claude keeps a written todo list, updating each item's status as it works. You see each change in the message stream as a structured tool call. Opt a session in only when your application reads those tool calls, whether to log task activity or to render its own progress display.
88 
from line 22
2222>
2323> This default set applies in Claude Code v2.1.268 and later, which the TypeScript Agent SDK bundles from v0.3.268.
2424 
25On a model that doesn't have the tools by default, unless you opt a session in, you see no `tool_use` blocks for them in the message stream. The Agent SDK applies these defaults through the Claude Code binary that it bundles. If you point `pathToClaudeCodeExecutable` (TypeScript) or `cli_path` (Python) at your own Claude Code install, you get whichever tools that install provides, under its own defaults. To see the exact set in a running session, [check which tools are available](/docs/en/tools-reference.md#check-which-tools-are-available). To opt a session in, do one of the following:
25On a model that doesn't have the tools by default, unless you opt a session in, you see no `tool_use` blocks for them in the message stream. The Agent SDK applies these defaults through the Claude Code binary that it bundles. If you point `pathToClaudeCodeExecutable` (TypeScript) or `cli_path` (Python) at your own Claude Code install, you get whichever tools that install provides, under its own defaults. To see the exact set in a running session, [check which tools are available](https://code.claude.com/docs/en/tools-reference.md#check-which-tools-are-available). To opt a session in, do one of the following:
2626 
27* Name one of the tools in the [`allowedTools`](/docs/en/agent-sdk/permissions#allow-and-deny-rules) (TypeScript) or `allowed_tools` (Python) option
27* Name one of the tools in the [`allowedTools`](https://code.claude.com/docs/en/agent-sdk/permissions#allow-and-deny-rules) (TypeScript) or `allowed_tools` (Python) option
2828* List the tools in the `tools` option, which restricts the session's built-in tools to the ones it names. Include the tools you want alongside the other built-in tools you use
2929* Set `CLAUDE_CODE_ENABLE_TODO_TOOLS=1` in the `env` option, as the examples on this page do. In TypeScript, `env` replaces the subprocess environment, so spread `...process.env` to keep inherited variables. In Python, `env` is merged on top of the inherited environment
3030 
from line 50
5050 
5151## Examples
5252 
53Before running these examples, install the Claude Agent SDK by following the [quickstart](/docs/en/agent-sdk/quickstart.md). Every example on this page shares the same permission setup and exit behavior:
53Before running these examples, install the Claude Agent SDK by following the [quickstart](https://code.claude.com/docs/en/agent-sdk/quickstart.md). Every example on this page shares the same permission setup and exit behavior:
5454 
55* **Permission mode**: the example prompts ask Claude to do real work on a project, so each example sets `permissionMode: "acceptEdits"` (TypeScript) or `permission_mode="acceptEdits"` (Python) to auto-approve the file edits that work produces. See [Permission modes](/docs/en/agent-sdk/permissions.md#permission-modes) for the alternatives.
55* **Permission mode**: the example prompts ask Claude to do real work on a project, so each example sets `permissionMode: "acceptEdits"` (TypeScript) or `permission_mode="acceptEdits"` (Python) to auto-approve the file edits that work produces. See [Permission modes](https://code.claude.com/docs/en/agent-sdk/permissions.md#permission-modes) for the alternatives.
5656* **Turn limit**: each example runs until the agent finishes and yields its final result message. If a session reaches its turn limit first, that result message has the `error_max_turns` subtype. Check `subtype` to detect that ending.
57* **Error handling**: these examples use single-shot `query()` calls. After yielding an `error_max_turns` result, `query()` raises an error that includes `Reached maximum number of turns`. Each example wraps its loop in a try block to exit cleanly when that happens. See [Handle the result](/docs/en/agent-sdk/agent-loop.md#handle-the-result) for the result subtypes.
57* **Error handling**: these examples use single-shot `query()` calls. After yielding an `error_max_turns` result, `query()` raises an error that includes `Reached maximum number of turns`. Each example wraps its loop in a try block to exit cleanly when that happens. See [Handle the result](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#handle-the-result) for the result subtypes.
5858 
5959> [!NOTE]
6060>
61> The task system messages, [`SDKTaskNotificationMessage`](/docs/en/agent-sdk/typescript#sdktasknotificationmessage) (TypeScript) or [`TaskNotificationMessage`](/docs/en/agent-sdk/python#tasknotificationmessage) (Python) among them, report background tasks such as backgrounded commands and subagents. In the message stream, you see todo activity as `tool_use` blocks in the assistant messages.
61> The task system messages, [`SDKTaskNotificationMessage`](https://code.claude.com/docs/en/agent-sdk/typescript#sdktasknotificationmessage) (TypeScript) or [`TaskNotificationMessage`](https://code.claude.com/docs/en/agent-sdk/python#tasknotificationmessage) (Python) among them, report background tasks such as backgrounded commands and subagents. In the message stream, you see todo activity as `tool_use` blocks in the assistant messages.
6262 
6363### Monitor todo changes
6464 
from line 138
138138 
139139The following example watches the assistant stream for `TaskCreate` and `TaskUpdate` `tool_use` blocks and keeps a map of tasks keyed by task ID in a `TaskTracker` class, rerendering a progress summary on every change. The summary counts completed and in-progress tasks and shows each active item's `activeForm` label in place of its `subject`. Use this shape when your application maintains a progress display instead of logging each event.
140140 
141The assigned task ID isn't in the `TaskCreate` input. Claude Code delivers each tool's structured output on the user message that carries its `tool_result` block, in the `tool_use_result` field. For `TaskCreate`, that object is documented for TypeScript as `TaskCreateOutput` under [Tool Output Types](/docs/en/agent-sdk/typescript.md#tool-output-types), and in Python the field is a plain dict of the same shape. The tracker pairs each `tool_result` block with its `tool_use` call by `tool_use_id` and reads `task.id` from the paired message's `tool_use_result`. Claude can read the list back with `TaskList` and one task's full details with `TaskGet`.
141The assigned task ID isn't in the `TaskCreate` input. Claude Code delivers each tool's structured output on the user message that carries its `tool_result` block, in the `tool_use_result` field. For `TaskCreate`, that object is documented for TypeScript as `TaskCreateOutput` under [Tool Output Types](https://code.claude.com/docs/en/agent-sdk/typescript.md#tool-output-types), and in Python the field is a plain dict of the same shape. The tracker pairs each `tool_result` block with its `tool_use` call by `tool_use_id` and reads `task.id` from the paired message's `tool_use_result`. Claude can read the list back with `TaskList` and one task's full details with `TaskGet`.
142142 
143143```typescript TypeScript theme={null}
144144import { query } from "@anthropic-ai/claude-agent-sdk";
from line 365
365365 
366366## Related documentation
367367 
368* [Agent SDK reference - TypeScript](/docs/en/agent-sdk/typescript.md): the options, types, and tool schemas for the TypeScript SDK, including the Task tool input and output types
369* [Agent SDK reference - Python](/docs/en/agent-sdk/python.md): the options, types, and tool documentation for the Python SDK
370* [Streaming Input](/docs/en/agent-sdk/streaming-vs-single-mode.md): the two input modes, and when to use streaming input instead of the single-shot calls these examples use
371* [Give Claude custom tools](/docs/en/agent-sdk/custom-tools.md): define your own tools with the SDK's in-process MCP server
368* [Agent SDK reference - TypeScript](https://code.claude.com/docs/en/agent-sdk/typescript.md): the options, types, and tool schemas for the TypeScript SDK, including the Task tool input and output types
369* [Agent SDK reference - Python](https://code.claude.com/docs/en/agent-sdk/python.md): the options, types, and tool documentation for the Python SDK
370* [Streaming Input](https://code.claude.com/docs/en/agent-sdk/streaming-vs-single-mode.md): the two input modes, and when to use streaming input instead of the single-shot calls these examples use
371* [Give Claude custom tools](https://code.claude.com/docs/en/agent-sdk/custom-tools.md): define your own tools with the SDK's in-process MCP server
372372 

agent-sdk/tool-search Changed · +10 / -10 lines

from line 34
3434 
3535> [!NOTE]
3636>
37> Tool search is on by default behind an `ANTHROPIC_BASE_URL` gateway, with nothing to set. If the gateway rejects it, see [Tool search through an LLM gateway](/docs/en/mcp.md#tool-search-through-a-gateway). Before Claude Code v2.1.304, the SDK disabled tool search behind such a gateway unless `ENABLE_TOOL_SEARCH` was `true`, `auto`, or `auto:N`.
37> Tool search is on by default behind an `ANTHROPIC_BASE_URL` gateway, with nothing to set. If the gateway rejects it, see [Tool search through an LLM gateway](https://code.claude.com/docs/en/mcp.md#tool-search-through-a-gateway). Before Claude Code v2.1.304, the SDK disabled tool search behind such a gateway unless `ENABLE_TOOL_SEARCH` was `true`, `auto`, or `auto:N`.
3838 
3939You control whether and when tool definitions are deferred with the `ENABLE_TOOL_SEARCH` environment variable, which takes these values:
4040 
from line 42
4242| :- | :- |
4343| (unset) | Tool search is on, with tool definitions deferred and discovered on demand. Falls back to loading upfront on models earlier than Opus 4 and Sonnet 4, on the [earlier Agent Platform models](#configure-tool-search), and on Microsoft Foundry deployments hosted on Azure. |
4444| `true` | Tool search is on, with the same fallbacks as (unset). |
45| `auto` | Tool search is off, and tool definitions load upfront, until the definitions it can defer reach 10% of the model's context window. Tool search then activates, and can [stay on in the same conversation](/docs/en/mcp.md#tools-that-stay-deferred-below-the-threshold) even if those definitions later drop below 10%. |
45| `auto` | Tool search is off, and tool definitions load upfront, until the definitions it can defer reach 10% of the model's context window. Tool search then activates, and can [stay on in the same conversation](https://code.claude.com/docs/en/mcp.md#tools-that-stay-deferred-below-the-threshold) even if those definitions later drop below 10%. |
4646| `auto:N` | Same as `auto` with a custom percentage. `auto:5` activates when those definitions reach 5% of the context window. Lower values activate sooner. |
4747| `false` | Tool search is off. All tool definitions are loaded into context on every turn. |
4848 
49Setting [`CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS`](/docs/en/env-vars) keeps tool search off. You can't override it by setting `ENABLE_TOOL_SEARCH` yourself. On Claude Code v2.1.227 or later, your organization can keep tool search on under this variable through [managed settings](/docs/en/managed-settings.md). In a session that [gets the HIPAA configuration](/docs/en/hipaa-setup.md#check-how-developers-sign-in-and-connect), tool search is off, and neither `ENABLE_TOOL_SEARCH` nor managed settings turns it back on. [Disable pre-release capabilities](/docs/en/llm-gateway-protocol.md#disable-pre-release-capabilities) covers where the override applies and what the variable strips.
49Setting [`CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS`](https://code.claude.com/docs/en/env-vars) keeps tool search off. You can't override it by setting `ENABLE_TOOL_SEARCH` yourself. On Claude Code v2.1.227 or later, your organization can keep tool search on under this variable through [managed settings](https://code.claude.com/docs/en/managed-settings.md). In a session that [gets the HIPAA configuration](https://code.claude.com/docs/en/hipaa-setup.md#check-how-developers-sign-in-and-connect), tool search is off, and neither `ENABLE_TOOL_SEARCH` nor managed settings turns it back on. [Disable pre-release capabilities](https://code.claude.com/docs/en/llm-gateway-protocol.md#disable-pre-release-capabilities) covers where the override applies and what the variable strips.
5050 
51Tool search applies to all registered tools, whether they come from remote MCP servers or [custom SDK MCP servers](/docs/en/agent-sdk/custom-tools.md). When you use `auto`, the SDK counts every definition that tool search can defer toward one combined threshold: each MCP tool that isn't marked [`alwaysLoad`](/docs/en/mcp#exempt-a-server-from-deferral), from any server, plus the built-in tools that load on demand. The SDK loads core built-in tools such as Bash, Read, and Edit upfront and doesn't count them toward the threshold. A [mod](/docs/en/plugins/mods/reference.md#tools) in one of your plugins can also defer a tool or load it upfront, which changes that count.
51Tool search applies to all registered tools, whether they come from remote MCP servers or [custom SDK MCP servers](https://code.claude.com/docs/en/agent-sdk/custom-tools.md). When you use `auto`, the SDK counts every definition that tool search can defer toward one combined threshold: each MCP tool that isn't marked [`alwaysLoad`](https://code.claude.com/docs/en/mcp#exempt-a-server-from-deferral), from any server, plus the built-in tools that load on demand. The SDK loads core built-in tools such as Bash, Read, and Edit upfront and doesn't count them toward the threshold. A [mod](https://code.claude.com/docs/en/plugins/mods/reference.md#tools) in one of your plugins can also defer a tool or load it upfront, which changes that count.
5252 
5353Set the value in the `env` option on `query()`. In TypeScript, `env` replaces the subprocess environment, so spread `...process.env` to keep inherited variables. In Python, `env` is merged on top of the inherited environment. This example connects to a remote MCP server that exposes many tools, pre-approves all of them with a wildcard, and uses `auto:5` so tool search activates when the definitions it can defer reach 5% of the context window:
5454 
from line 121
121121 
122122To run this example, replace `https://tools.example.com/mcp` with the URL of your own MCP server. On success the result text prints to the console.
123123 
124Because this is a single-shot `query()` call, the SDK raises after yielding an error result, so the example wraps the loop in a try block. To see why a run failed, check the result message's `subtype`, such as `error_during_execution`, inside the loop. For more on result messages, see [Handle the result](/docs/en/agent-sdk/agent-loop.md#handle-the-result).
124Because this is a single-shot `query()` call, the SDK raises after yielding an error result, so the example wraps the loop in a try block. To see why a run failed, check the result message's `subtype`, such as `error_during_execution`, inside the loop. For more on result messages, see [Handle the result](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#handle-the-result).
125125 
126126## Optimize tool discovery
127127 
from line 149
149149)
150150```
151151 
152For the full set of system prompt options, see [Modifying system prompts](/docs/en/agent-sdk/modifying-system-prompts.md).
152For the full set of system prompt options, see [Modifying system prompts](https://code.claude.com/docs/en/agent-sdk/modifying-system-prompts.md).
153153 
154154## Limits
155155 
from line 160
160160## Related documentation
161161 
162162* [Tool search in the API](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool): Full API documentation for tool search, including custom implementations
163* [Connect MCP servers](/docs/en/agent-sdk/mcp.md): Connect to external tools via MCP servers
164* [Custom tools](/docs/en/agent-sdk/custom-tools.md): Build your own tools with SDK MCP servers
165* [TypeScript SDK reference](/docs/en/agent-sdk/typescript.md): Full API reference
166* [Python SDK reference](/docs/en/agent-sdk/python.md): Full API reference
163* [Connect MCP servers](https://code.claude.com/docs/en/agent-sdk/mcp.md): Connect to external tools via MCP servers
164* [Custom tools](https://code.claude.com/docs/en/agent-sdk/custom-tools.md): Build your own tools with SDK MCP servers
165* [TypeScript SDK reference](https://code.claude.com/docs/en/agent-sdk/typescript.md): Full API reference
166* [Python SDK reference](https://code.claude.com/docs/en/agent-sdk/python.md): Full API reference
167167 

agent-sdk/troubleshooting Changed · +15 / -15 lines

from line 8
88 
99| Symptom | Go to |
1010| :- | :- |
11| Skills not found, a skill not being used, `Invalid skill name` error | [Skills troubleshooting](/docs/en/agent-sdk/skills.md#troubleshooting) |
12| MCP server shows `failed` status, tools not being called, a tool missing from an SDK MCP server, connection timeouts, tool output that exceeds the maximum allowed tokens | [MCP troubleshooting](/docs/en/agent-sdk/mcp.md#troubleshooting) |
13| Plugin not loading, plugin skills not appearing | [Plugins troubleshooting](/docs/en/agent-sdk/plugins.md#troubleshooting) |
14| Claude not delegating to subagents, filesystem-based agents not loading | [Subagents troubleshooting](/docs/en/agent-sdk/subagents.md#troubleshooting) |
15| Checkpointing options not recognized, user messages without UUIDs, `No file checkpoint found`, `File rewinding is not enabled`, `ProcessTransport is not ready for writing` | [File checkpointing troubleshooting](/docs/en/agent-sdk/file-checkpointing.md#troubleshooting) |
16| Hook not firing, matcher not filtering as expected, hook timeout, tool blocked unexpectedly, modified input not applied, session hooks not available in Python, subagent permission prompts multiplying, recursive hook loops with subagents, `systemMessage` not appearing in output | [Fix common issues](/docs/en/agent-sdk/hooks.md#fix-common-issues) on the hooks page |
17| An agent that works on your machine fails in a deployed service or container | [Troubleshoot deployment failures](/docs/en/agent-sdk/hosting.md#troubleshoot-deployment-failures) |
18| `Not logged in`, `Invalid API key`, `API Error`, `429`, `There's an issue with the selected model` | [Error reference](/docs/en/errors.md#find-your-error) |
11| Skills not found, a skill not being used, `Invalid skill name` error | [Skills troubleshooting](https://code.claude.com/docs/en/agent-sdk/skills.md#troubleshooting) |
12| MCP server shows `failed` status, tools not being called, a tool missing from an SDK MCP server, connection timeouts, tool output that exceeds the maximum allowed tokens | [MCP troubleshooting](https://code.claude.com/docs/en/agent-sdk/mcp.md#troubleshooting) |
13| Plugin not loading, plugin skills not appearing | [Plugins troubleshooting](https://code.claude.com/docs/en/agent-sdk/plugins.md#troubleshooting) |
14| Claude not delegating to subagents, filesystem-based agents not loading | [Subagents troubleshooting](https://code.claude.com/docs/en/agent-sdk/subagents.md#troubleshooting) |
15| Checkpointing options not recognized, user messages without UUIDs, `No file checkpoint found`, `File rewinding is not enabled`, `ProcessTransport is not ready for writing` | [File checkpointing troubleshooting](https://code.claude.com/docs/en/agent-sdk/file-checkpointing.md#troubleshooting) |
16| Hook not firing, matcher not filtering as expected, hook timeout, tool blocked unexpectedly, modified input not applied, session hooks not available in Python, subagent permission prompts multiplying, recursive hook loops with subagents, `systemMessage` not appearing in output | [Fix common issues](https://code.claude.com/docs/en/agent-sdk/hooks.md#fix-common-issues) on the hooks page |
17| An agent that works on your machine fails in a deployed service or container | [Troubleshoot deployment failures](https://code.claude.com/docs/en/agent-sdk/hosting.md#troubleshoot-deployment-failures) |
18| `Not logged in`, `Invalid API key`, `API Error`, `429`, `There's an issue with the selected model` | [Error reference](https://code.claude.com/docs/en/errors.md#find-your-error) |
1919| `CLINotFoundError`, `CLIConnectionError`, `ProcessError`, `Claude Code process exited with code N`, `Claude Code returned an error result`, `structured_output` is `None` | [CLI startup](#cli-startup), [CLI process exit](#cli-process-exit), and [Structured outputs](#structured-outputs) on this page |
2020 
2121## CLI startup
from line 32
3232 
3333To fix it:
3434 
35* Install Claude Code if it isn't installed. See [Install Claude Code](/docs/en/setup.md#install-claude-code) for the command on your platform.
35* Install Claude Code if it isn't installed. See [Install Claude Code](https://code.claude.com/docs/en/setup.md#install-claude-code) for the command on your platform.
3636* If you set `cli_path`, confirm the file exists and is the `claude` executable.
3737* If you rely on `PATH` resolution, confirm `claude --version` works in the same environment your application runs in. Processes you launch outside your shell, such as from an IDE or a service manager, often run with a different `PATH`.
3838 
3939The TypeScript SDK looks for the CLI in its bundled platform package and the path you set in `pathToClaudeCodeExecutable`. Match the message you see:
4040 
41* `Native CLI binary for <platform>-<arch> not found`: the bundled platform package is missing, most often because the install skipped optional dependencies. Reinstall `@anthropic-ai/claude-agent-sdk` without skipping optional dependencies, or point `pathToClaudeCodeExecutable` at a [native install](/docs/en/setup.md#install-claude-code). In a single-file executable built with `bun build --compile`, the same message has a different cause and fix. See [Compile to a single executable](/docs/en/agent-sdk/typescript.md#compile-to-a-single-executable).
41* `Native CLI binary for <platform>-<arch> not found`: the bundled platform package is missing, most often because the install skipped optional dependencies. Reinstall `@anthropic-ai/claude-agent-sdk` without skipping optional dependencies, or point `pathToClaudeCodeExecutable` at a [native install](https://code.claude.com/docs/en/setup.md#install-claude-code). In a single-file executable built with `bun build --compile`, the same message has a different cause and fix. See [Compile to a single executable](https://code.claude.com/docs/en/agent-sdk/typescript.md#compile-to-a-single-executable).
4242* `Claude Code native binary not found at <path>` or `Claude Code executable not found at <path>. Is options.pathToClaudeCodeExecutable set?`: the file at the resolved path is missing, or the process can't access it. Confirm the file exists at that path and that the process can access it.
4343 
4444### CLIConnectionError: Refusing to execute batch script
from line 108
108108 
109109The message states the exit code twice, and the `Error output` line is fixed text rather than your process's error output. The same fixed text fills the exception's `stderr` attribute. The exception's `exit_code` attribute carries the code. To capture what the CLI actually wrote to stderr, pass a `stderr` callback in `ClaudeAgentOptions` and log what it receives.
110110 
111A bare `ProcessError` means the CLI exited without reporting an error result. When the CLI did report one, the SDK raises [`ResultError`](/docs/en/agent-sdk/python#resulterror) instead, covered in [Claude Code returned an error result](#claude-code-returned-an-error-result). `ResultError` subclasses `ProcessError`, so `except ProcessError` catches both. To handle them differently, put the `except ResultError` clause first.
111A bare `ProcessError` means the CLI exited without reporting an error result. When the CLI did report one, the SDK raises [`ResultError`](https://code.claude.com/docs/en/agent-sdk/python#resulterror) instead, covered in [Claude Code returned an error result](#claude-code-returned-an-error-result). `ResultError` subclasses `ProcessError`, so `except ProcessError` catches both. To handle them differently, put the `except ResultError` clause first.
112112 
113113Before `claude-agent-sdk` 0.2.140, the Python SDK raised error-result exits as a plain `Exception` rather than a `ResultError`.
114114 
115115### Claude Code process exited with code N
116116 
117IDE wrappers print this message too, and the [error reference](/docs/en/errors.md#claude-code-process-exited-with-code-n) covers it for VS Code and other launchers. This entry covers what your TypeScript SDK code receives. The SDK surfaces a nonzero CLI exit as a plain `Error` that rejects the `for await` loop over `query()`'s messages. There's no SDK error class to catch, so wrap the loop in `try`/`catch` and match on the message:
117IDE wrappers print this message too, and the [error reference](https://code.claude.com/docs/en/errors.md#claude-code-process-exited-with-code-n) covers it for VS Code and other launchers. This entry covers what your TypeScript SDK code receives. The SDK surfaces a nonzero CLI exit as a plain `Error` that rejects the `for await` loop over `query()`'s messages. There's no SDK error class to catch, so wrap the loop in `try`/`catch` and match on the message:
118118 
119119```
120120Claude Code process exited with code 1. stderr: <tail of the CLI's stderr>
from line 130
130130Claude Code returned an error result: <the CLI's own error report>
131131```
132132 
133The text after the colon is the CLI's report of what went wrong, so start there rather than with the exit itself. Python raises this as a [`ResultError`](/docs/en/agent-sdk/python#resulterror), whose `data` attribute carries the full error result. TypeScript rejects the message loop with a plain `Error` carrying the same message shape.
133The text after the colon is the CLI's report of what went wrong, so start there rather than with the exit itself. Python raises this as a [`ResultError`](https://code.claude.com/docs/en/agent-sdk/python#resulterror), whose `data` attribute carries the full error result. TypeScript rejects the message loop with a plain `Error` carrying the same message shape.
134134 
135135## Structured outputs
136136 
from line 138
138138 
139139A result message can end with `subtype: "success"` while `structured_output` is `None` in Python or `undefined` in TypeScript. The run completes, but no validated output exists.
140140 
141Treat this result as a failure in application code. Check both that `subtype` is `success` and that `structured_output` is present before using it. The [Error handling](/docs/en/agent-sdk/structured-outputs.md#error-handling) section shows this pattern for both SDKs. Then check for these causes:
141Treat this result as a failure in application code. Check both that `subtype` is `success` and that `structured_output` is present before using it. The [Error handling](https://code.claude.com/docs/en/agent-sdk/structured-outputs.md#error-handling) section shows this pattern for both SDKs. Then check for these causes:
142142 
143* **A request that Claude declined**: to detect this case in your code, check the result message's `stop_reason` for `"refusal"`. For what to try next, see [Usage Policy refusal](/docs/en/errors.md#usage-policy-refusal).
143* **A request that Claude declined**: to detect this case in your code, check the result message's `stop_reason` for `"refusal"`. For what to try next, see [Usage Policy refusal](https://code.claude.com/docs/en/errors.md#usage-policy-refusal).
144144* **A schema no output can satisfy**: for example, a string whose `minLength` is greater than its `maxLength`. If `structured_output` is missing repeatedly with a schema you believe is correct, look for constraints that contradict each other. If you find none, simplify the schema until outputs validate, then reintroduce your constraints one at a time.
145145 
146146## Report a new issue

agent-sdk/typescript Changed · +177 / -177 lines

This page is larger than the 256 KiB this site keeps, so one side of the diff below stops where the stored text does.

from line 186
186186| `description` | `string` | A description of what the tool does |
187187| `inputSchema` | `Schema extends AnyZodRawShape` | Zod schema defining the tool's input parameters (supports both Zod 3 and Zod 4) |
188188| `handler` | `(args, extra) => Promise<`[`CallToolResult`](#calltoolresult)`>` | Async function that executes the tool logic |
189| `extras` | `{ annotations?: `[`ToolAnnotations`](#toolannotations)`; searchHint?: string; alwaysLoad?: boolean }` | 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](/docs/en/agent-sdk/tool-search.md) is active. `alwaysLoad: true` keeps this tool's full schema in the initial prompt instead of deferring it |
189| `extras` | `{ annotations?: `[`ToolAnnotations`](#toolannotations)`; searchHint?: string; alwaysLoad?: boolean }` | 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](https://code.claude.com/docs/en/agent-sdk/tool-search.md) is active. `alwaysLoad: true` keeps this tool's full schema in the initial prompt instead of deferring it |
190190 
191191#### `ToolAnnotations`
192192 
from line 238
238238| `options.version` | `string` | Optional version string |
239239| `options.instructions` | `string` | Optional server instructions, returned from `initialize` and surfaced to the model as an MCP instructions block |
240240| `options.tools` | `Array<SdkMcpToolDefinition>` | Array of tool definitions created with [`tool()`](#tool) |
241| `options.alwaysLoad` | `boolean` | When `true`, this server's tools stay in the initial prompt instead of being deferred behind [tool search](/docs/en/agent-sdk/tool-search.md). Combines with per-tool `alwaysLoad` in [`tool()`](#tool) |
242| `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`](/docs/en/env-vars). Pass a whole number of at least 1000. Claude Code ignores other values. Requires TypeScript Agent SDK v0.3.248 or later |
241| `options.alwaysLoad` | `boolean` | When `true`, this server's tools stay in the initial prompt instead of being deferred behind [tool search](https://code.claude.com/docs/en/agent-sdk/tool-search.md). Combines with per-tool `alwaysLoad` in [`tool()`](#tool) |
242| `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`](https://code.claude.com/docs/en/env-vars). Pass a whole number of at least 1000. Claude Code ignores other values. Requires TypeScript Agent SDK v0.3.248 or later |
243243 
244244### `listSessions()`
245245 
from line 315
315315| `session_id` | `string` | Session this message belongs to |
316316| `message` | `unknown` | Raw message payload from the transcript |
317317| `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 |
318| `parent_agent_id` | `string \| null` | For messages from a [nested subagent](/docs/en/sub-agents.md#let-subagents-spawn-their-own-subagents), 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 |
318| `parent_agent_id` | `string \| null` | For messages from a [nested subagent](https://code.claude.com/docs/en/sub-agents.md#let-subagents-spawn-their-own-subagents), 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 |
319319 
320320#### Example
321321 
from line 416
416416| `options.upToMessageId` | `string` | `undefined` | Copy the transcript up to and including the message with this `uuid`: a value from [`getSessionMessages()`](#getsessionmessages), or a `uuid` you set on a streamed [`SDKUserMessage`](#sdkusermessage). When omitted, copies the whole transcript |
417417| `options.title` | `string` | `undefined` | Title for the fork. When omitted, the SDK derives one from the original session, followed by `(fork)` |
418418 
419Returns `{ sessionId }`, the new session's UUID. Pass it as [`resume`](#options) to continue the fork. The fork doesn't include the original session's [file checkpoints](/docs/en/agent-sdk/file-checkpointing.md), so you can't rewind it to a checkpoint captured before the fork.
419Returns `{ sessionId }`, the new session's UUID. Pass it as [`resume`](#options) to continue the fork. The fork doesn't include the original session's [file checkpoints](https://code.claude.com/docs/en/agent-sdk/file-checkpointing.md), so you can't rewind it to a checkpoint captured before the fork.
420420 
421421`forkSession()` throws when:
422422 
from line 435
435435The snapshot differs from what a live `query()` session applies:
436436 
437437* **`policyHelper`**: `resolveSettings()` reads MDM sources, including macOS plist and Windows HKLM/HKCU, but doesn't execute the admin-configured `policyHelper` subprocess.
438* **Server-managed settings**: `resolveSettings()` doesn't fetch [server-managed settings](/docs/en/server-managed-settings.md#fetch-and-caching-behavior). Pass them as `options.serverManagedSettings` to include them.
439* **`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](/docs/en/permission-modes.md#which-mode-a-session-starts-in).
438* **Server-managed settings**: `resolveSettings()` doesn't fetch [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md#fetch-and-caching-behavior). Pass them as `options.serverManagedSettings` to include them.
439* **`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](https://code.claude.com/docs/en/permission-modes.md#which-mode-a-session-starts-in).
440440 
441441```typescript theme={null}
442442function resolveSettings(
from line 451
451451| Parameter | Type | Default | Description |
452452| :- | :- | :- | :- |
453453| `options.cwd` | `string` | `process.cwd()` | Directory to resolve project and local settings relative to |
454| `options.settingSources` | [`SettingSource`](#settingsource)`[]` | All sources | Which filesystem sources to load. Pass `[]` to skip user, project, and local settings. [Endpoint-managed policy](/docs/en/managed-settings.md#delivery-mechanisms) loads in all cases. `resolveSettings()` includes server-managed settings only when you pass `options.serverManagedSettings` |
455| `options.managedSettings` | `Settings` | `undefined` | Policy-tier settings supplied by the embedding host. Follows the same rules as [`managedSettings` in `Options`](#options), except that `resolveSettings()` doesn't execute a configured [`policyHelper`](/docs/en/settings-reference#policyhelper), so the snapshot can include settings that a live session drops |
454| `options.settingSources` | [`SettingSource`](#settingsource)`[]` | All sources | Which filesystem sources to load. Pass `[]` to skip user, project, and local settings. [Endpoint-managed policy](https://code.claude.com/docs/en/managed-settings.md#delivery-mechanisms) loads in all cases. `resolveSettings()` includes server-managed settings only when you pass `options.serverManagedSettings` |
455| `options.managedSettings` | `Settings` | `undefined` | Policy-tier settings supplied by the embedding host. Follows the same rules as [`managedSettings` in `Options`](#options), except that `resolveSettings()` doesn't execute a configured [`policyHelper`](https://code.claude.com/docs/en/settings-reference#policyhelper), so the snapshot can include settings that a live session drops |
456456| `options.serverManagedSettings` | `Settings` | `undefined` | Server-managed settings payload from `/api/claude_code/settings`. Non-restrictive keys pass through unfiltered |
457457 
458458#### Return type: `ResolvedSettings`
from line 490
490490| Property | Type | Default | Description |
491491| :- | :- | :- | :- |
492492| `abortController` | `AbortController` | `new AbortController()` | Controller for cancelling operations |
493| `additionalDirectories` | `string[]` | `[]` | Additional directories Claude can access. The SDK passes each entry to Claude Code as `--add-dir`, so with the `project` setting source Claude Code also [loads the directory's skills, commands, and subagents](/docs/en/permissions.md#additional-directories-grant-file-access-not-configuration) |
493| `additionalDirectories` | `string[]` | `[]` | Additional directories Claude can access. The SDK passes each entry to Claude Code as `--add-dir`, so with the `project` setting source Claude Code also [loads the directory's skills, commands, and subagents](https://code.claude.com/docs/en/permissions.md#additional-directories-grant-file-access-not-configuration) |
494494| `agent` | `string` | `undefined` | Agent name for the main thread. The agent must be defined in the `agents` option or in settings |
495495| `agents` | `Record<string, [`AgentDefinition`](#agentdefinition)>` | `undefined` | Programmatically define subagents |
496496| `agentProgressSummaries` | `boolean` | `false` | When `true`, generate one-line progress summaries for subagents and forward them on [`task_progress`](#sdktaskprogressmessage) events via the `summary` field. Applies to foreground and background subagents |
497| `allowDangerouslySkipPermissions` | `boolean` | `false` | Enable bypassing permissions. Required when using `permissionMode: 'bypassPermissions'`, at startup or later through `setPermissionMode()`. See [plan mode](/docs/en/agent-sdk/permissions.md#plan-mode-plan) for how it interacts with `permissionMode: 'plan'` |
498| `allowedTools` | `string[]` | `[]` | Tools to auto-approve without prompting, apart from reads from [network paths](/docs/en/permissions.md#network-paths). This does not restrict Claude to only these tools. If you name one of the [task-tracking tools](/docs/en/agent-sdk/todo-tracking.md#model-availability) here, Claude Code also opts the session in. Other unlisted tools fall through to `permissionMode` and `canUseTool`. Use `disallowedTools` to block tools. See [Permissions](/docs/en/agent-sdk/permissions.md#allow-and-deny-rules) |
497| `allowDangerouslySkipPermissions` | `boolean` | `false` | Enable bypassing permissions. Required when using `permissionMode: 'bypassPermissions'`, at startup or later through `setPermissionMode()`. See [plan mode](https://code.claude.com/docs/en/agent-sdk/permissions.md#plan-mode-plan) for how it interacts with `permissionMode: 'plan'` |
498| `allowedTools` | `string[]` | `[]` | Tools to auto-approve without prompting, apart from reads from [network paths](https://code.claude.com/docs/en/permissions.md#network-paths). This does not restrict Claude to only these tools. If you name one of the [task-tracking tools](https://code.claude.com/docs/en/agent-sdk/todo-tracking.md#model-availability) here, Claude Code also opts the session in. Other unlisted tools fall through to `permissionMode` and `canUseTool`. Use `disallowedTools` to block tools. See [Permissions](https://code.claude.com/docs/en/agent-sdk/permissions.md#allow-and-deny-rules) |
499499| `betas` | [`SdkBeta`](#sdkbeta)`[]` | `[]` | Enable beta features |
500| `canUseTool` | [`CanUseTool`](#canusetool) | `undefined` | Custom permission function, invoked only when the [permission flow](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) 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](/docs/en/permission-modes.md#actions-no-mode-auto-approves). See [`CanUseTool`](#canusetool) for details |
500| `canUseTool` | [`CanUseTool`](#canusetool) | `undefined` | Custom permission function, invoked only when the [permission flow](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) 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](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves). See [`CanUseTool`](#canusetool) for details |
501501| `continue` | `boolean` | `false` | Continue the most recent conversation |
502502| `cwd` | `string` | `process.cwd()` | Current working directory |
503503| `debug` | `boolean` | `false` | Enable debug mode for the Claude Code process |
504504| `debugFile` | `string` | `undefined` | Write debug logs to a specific file path. Implicitly enables debug mode |
505| `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](/docs/en/permissions.md#bash-rule-limits). See [Permissions](/docs/en/agent-sdk/permissions.md#allow-and-deny-rules) |
506| `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](/docs/en/model-config.md#adjust-effort-level) |
507| `enableFileCheckpointing` | `boolean` | `false` | Enable file change tracking for rewinding. See [File checkpointing](/docs/en/agent-sdk/file-checkpointing.md) |
508| `env` | `Record<string, string \| undefined>` | `process.env` | 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](#handle-slow-or-stalled-api-responses) for an example of this pattern, and [Environment variables](/docs/en/env-vars.md) for variables the underlying CLI reads. Set `CLAUDE_AGENT_SDK_CLIENT_APP` to identify your app in the User-Agent header |
505| `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](https://code.claude.com/docs/en/permissions.md#bash-rule-limits). See [Permissions](https://code.claude.com/docs/en/agent-sdk/permissions.md#allow-and-deny-rules) |
506| `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](https://code.claude.com/docs/en/model-config.md#adjust-effort-level) |
507| `enableFileCheckpointing` | `boolean` | `false` | Enable file change tracking for rewinding. See [File checkpointing](https://code.claude.com/docs/en/agent-sdk/file-checkpointing.md) |
508| `env` | `Record<string, string \| undefined>` | `process.env` | 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](#handle-slow-or-stalled-api-responses) for an example of this pattern, and [Environment variables](https://code.claude.com/docs/en/env-vars.md) for variables the underlying CLI reads. Set `CLAUDE_AGENT_SDK_CLIENT_APP` to identify your app in the User-Agent header |
509509| `executable` | `'bun' \| 'deno' \| 'node'` | Auto-detected | JavaScript runtime to use |
510510| `executableArgs` | `string[]` | `[]` | Arguments to pass to the executable |
511511| `extraArgs` | `Record<string, string \| null>` | `{}` | Additional arguments |
512| `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](/docs/en/model-config.md#fallback-model-chains). For guidance, see [Choose a model](/docs/en/agent-sdk/configuration.md#choose-a-model) |
512| `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](https://code.claude.com/docs/en/model-config.md#fallback-model-chains). For guidance, see [Choose a model](https://code.claude.com/docs/en/agent-sdk/configuration.md#choose-a-model) |
513513| `forkSession` | `boolean` | `false` | When resuming with `resume`, fork to a new session ID instead of continuing the original session |
514| `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](/docs/en/sub-agents.md#run-subagents-in-foreground-or-background). For nested subagents, skills with `context: fork`, and the Claude Code version each needs, see [Follow subagent messages](/docs/en/headless.md#follow-subagent-messages) |
514| `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](https://code.claude.com/docs/en/sub-agents.md#run-subagents-in-foreground-or-background). For nested subagents, skills with `context: fork`, and the Claude Code version each needs, see [Follow subagent messages](https://code.claude.com/docs/en/headless.md#follow-subagent-messages) |
515515| `hooks` | `Partial<Record<`[`HookEvent`](#hookevent)`, `[`HookCallbackMatcher`](#hookcallbackmatcher)`[]>>` | `{}` | Hook callbacks for events |
516| `includeHookEvents` | `boolean` | `false` | Include hook lifecycle events in the message stream as [`SDKHookStartedMessage`](#sdkhookstartedmessage), [`SDKHookProgressMessage`](#sdkhookprogressmessage), and [`SDKHookResponseMessage`](#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](/docs/en/hooks.md#run-hooks-in-the-background) finishes |
516| `includeHookEvents` | `boolean` | `false` | Include hook lifecycle events in the message stream as [`SDKHookStartedMessage`](#sdkhookstartedmessage), [`SDKHookProgressMessage`](#sdkhookprogressmessage), and [`SDKHookResponseMessage`](#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](https://code.claude.com/docs/en/hooks.md#run-hooks-in-the-background) finishes |
517517| `includePartialMessages` | `boolean` | `false` | Include partial message events |
518518| `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 |
519| `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`](/docs/en/settings-reference#policyhelper) supplies managed settings. Merged values pass through a restrictive-only filter; [Restrict parent settings](/docs/en/claude-apps-gateway#restrict-parent-settings) covers what the filter admits and the `allowManaged*Only` locks. A host that sets [`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`](/docs/en/env-vars) has three keys read straight from this payload instead: its [model configuration](/docs/en/model-config.md#restrict-model-selection) on Claude Code v2.1.222 or later, [`modelPricing`](/docs/en/settings-reference#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 |
520| `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](/docs/en/agent-sdk/agent-loop.md#budget-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](/docs/en/agent-sdk/cost-tracking.md) |
519| `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`](https://code.claude.com/docs/en/settings-reference#policyhelper) supplies managed settings. Merged values pass through a restrictive-only filter; [Restrict parent settings](https://code.claude.com/docs/en/claude-apps-gateway#restrict-parent-settings) covers what the filter admits and the `allowManaged*Only` locks. A host that sets [`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`](https://code.claude.com/docs/en/env-vars) has three keys read straight from this payload instead: its [model configuration](https://code.claude.com/docs/en/model-config.md#restrict-model-selection) on Claude Code v2.1.222 or later, [`modelPricing`](https://code.claude.com/docs/en/settings-reference#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 |
520| `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](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#budget-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](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md) |
521521| `maxThinkingTokens` | `number` | `undefined` | *Deprecated:* Use `thinking` instead. Maximum tokens for thinking process |
522522| `maxTurns` | `number` | `undefined` | Maximum agentic turns (tool-use round trips) |
523523| `mcpServers` | `Record<string, [`McpServerConfig`](#mcpserverconfig)>` | `{}` | MCP server configurations |
524| `model` | `string` | Default from CLI | Claude model alias or full model name. See [accepted values and provider-specific IDs](/docs/en/model-config.md#available-models) |
524| `model` | `string` | Default from CLI | Claude model alias or full model name. See [accepted values and provider-specific IDs](https://code.claude.com/docs/en/model-config.md#available-models) |
525525| `onElicitation` | `(request: ElicitationRequest, options: { signal: AbortSignal }) => Promise<ElicitationResult>` | `undefined` | 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 |
526| `outputFormat` | `{ type: 'json_schema', schema: JSONSchema }` | `undefined` | Define output format for agent results. See [Structured outputs](/docs/en/agent-sdk/structured-outputs.md) for details |
527| `outputStyle` | `string` | `undefined` | Not an `Options` field. Set `outputStyle` in the inline [`settings`](/docs/en/settings) object or a settings file instead. See [Activate an output style](/docs/en/agent-sdk/modifying-system-prompts.md#activate-an-output-style) |
526| `outputFormat` | `{ type: 'json_schema', schema: JSONSchema }` | `undefined` | Define output format for agent results. See [Structured outputs](https://code.claude.com/docs/en/agent-sdk/structured-outputs.md) for details |
527| `outputStyle` | `string` | `undefined` | Not an `Options` field. Set `outputStyle` in the inline [`settings`](https://code.claude.com/docs/en/settings) object or a settings file instead. See [Activate an output style](https://code.claude.com/docs/en/agent-sdk/modifying-system-prompts.md#activate-an-output-style) |
528528| `pathToClaudeCodeExecutable` | `string` | Auto-resolved from bundled native binary | Path to Claude Code executable. Only needed if optional dependencies were skipped during install or your platform isn't in the supported set |
529| `permissionMode` | [`PermissionMode`](#permissionmode) | `undefined` | Permission mode for the session. If you omit it and nothing else sets a permission mode, such as a [`permissions.defaultMode`](/docs/en/settings-reference#permissions-defaultmode) setting, the session starts in `default`. See [Permission modes](/docs/en/agent-sdk/permissions.md#permission-modes) |
529| `permissionMode` | [`PermissionMode`](#permissionmode) | `undefined` | Permission mode for the session. If you omit it and nothing else sets a permission mode, such as a [`permissions.defaultMode`](https://code.claude.com/docs/en/settings-reference#permissions-defaultmode) setting, the session starts in `default`. See [Permission modes](https://code.claude.com/docs/en/agent-sdk/permissions.md#permission-modes) |
530530| `permissionPromptToolName` | `string` | `undefined` | MCP tool name for permission prompts |
531| `permissionPrompts` | `'host' \| 'none'` | `'host'` | Who answers permission prompts: `'host'` routes them to your [`canUseTool`](#canusetool) callback or the `permissionPromptToolName` tool, and `'none'` [denies the calls that would have prompted](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated). Requires Claude Code v2.1.259 or later |
531| `permissionPrompts` | `'host' \| 'none'` | `'host'` | Who answers permission prompts: `'host'` routes them to your [`canUseTool`](#canusetool) callback or the `permissionPromptToolName` tool, and `'none'` [denies the calls that would have prompted](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated). Requires Claude Code v2.1.259 or later |
532532| `persistSession` | `boolean` | `true` | When `false`, disables session persistence to disk. Sessions cannot be resumed later |
533533| `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 |
534| `plugins` | [`SdkPluginConfig`](#sdkpluginconfig)`[]` | `[]` | Load custom plugins from local paths. See [Plugins](/docs/en/agent-sdk/plugins.md) for details |
534| `plugins` | [`SdkPluginConfig`](#sdkpluginconfig)`[]` | `[]` | Load custom plugins from local paths. See [Plugins](https://code.claude.com/docs/en/agent-sdk/plugins.md) for details |
535535| `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 |
536| `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](/docs/en/interactive-mode.md#when-claude-code-skips-suggestions) |
536| `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](https://code.claude.com/docs/en/interactive-mode.md#when-claude-code-skips-suggestions) |
537537| `resume` | `string` | `undefined` | Session ID to resume |
538538| `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 |
539539| `resumeSessionAt` | `string` | `undefined` | Resume session at a specific message UUID |
540540| `sandbox` | [`SandboxSettings`](#sandboxsettings) | `undefined` | Configure sandbox behavior programmatically. See [Sandbox settings](#sandboxsettings) for details |
541541| `sessionId` | `string` | Auto-generated | Use a specific UUID for the session instead of auto-generating one |
542| `sessionStore` | [`SessionStore`](/docs/en/agent-sdk/session-storage#the-sessionstore-interface) | `undefined` | Mirror session transcripts to an external backend so another host can resume them. See [Persist sessions to external storage](/docs/en/agent-sdk/session-storage.md) |
542| `sessionStore` | [`SessionStore`](https://code.claude.com/docs/en/agent-sdk/session-storage#the-sessionstore-interface) | `undefined` | Mirror session transcripts to an external backend so another host can resume them. See [Persist sessions to external storage](https://code.claude.com/docs/en/agent-sdk/session-storage.md) |
543543| `sessionStoreFlush` | `'batched' \| 'eager'` | `'batched'` | *Alpha.* Flush mode for `sessionStore`. Ignored when `sessionStore` is not set |
544| `settings` | `string \| Settings` | `undefined` | Inline [settings](/docs/en/settings.md) object, a settings file path, or an inline JSON string. Populates the flag-settings layer in the [precedence order](/docs/en/settings.md#settings-precedence). Change at runtime with [`applyFlagSettings()`](#applyflagsettings) |
545| `settingSources` | [`SettingSource`](#settingsource)`[]` | CLI defaults (all sources) | Control which filesystem settings to load. Pass `[]` to disable user, project, and local settings. [Endpoint-managed policy](/docs/en/managed-settings.md#delivery-mechanisms) loads regardless; server-managed settings are fetched when the session authenticates with an organization credential on an [eligible configuration](/docs/en/server-managed-settings.md#platform-availability). See [Use Claude Code features](/docs/en/agent-sdk/claude-code-features.md#what-settingsources-does-not-control) |
546| `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](/docs/en/agent-sdk/skills.md) |
544| `settings` | `string \| Settings` | `undefined` | Inline [settings](https://code.claude.com/docs/en/settings.md) object, a settings file path, or an inline JSON string. Populates the flag-settings layer in the [precedence order](https://code.claude.com/docs/en/settings.md#settings-precedence). Change at runtime with [`applyFlagSettings()`](#applyflagsettings) |
545| `settingSources` | [`SettingSource`](#settingsource)`[]` | CLI defaults (all sources) | Control which filesystem settings to load. Pass `[]` to disable user, project, and local settings. [Endpoint-managed policy](https://code.claude.com/docs/en/managed-settings.md#delivery-mechanisms) loads regardless; server-managed settings are fetched when the session authenticates with an organization credential on an [eligible configuration](https://code.claude.com/docs/en/server-managed-settings.md#platform-availability). See [Use Claude Code features](https://code.claude.com/docs/en/agent-sdk/claude-code-features.md#what-settingsources-does-not-control) |
546| `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](https://code.claude.com/docs/en/agent-sdk/skills.md) |
547547| `spawnClaudeCodeProcess` | `(options: SpawnOptions) => SpawnedProcess` | `undefined` | Custom function to spawn the Claude Code process. Use to run Claude Code in VMs, containers, or remote environments |
548548| `stderr` | `(data: string) => void` | `undefined` | Callback for stderr output |
549| `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](/docs/en/mcp.md#use-mcp-servers-from-claude-ai) |
550| `systemPrompt` | `string \| string[] \| { type: 'custom'; prompt: string \| string[]; snapshot?: boolean } \| { type: 'preset'; preset: 'claude_code'; append?: string; excludeDynamicSections?: boolean; snapshot?: boolean }` | `undefined` (minimal prompt) | 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](/docs/en/agent-sdk/modifying-system-prompts.md#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](/docs/en/agent-sdk/modifying-system-prompts.md#improve-prompt-caching-across-users-and-machines). Set `snapshot: false` to rebuild the prompt on every request instead of [reusing the prompt the session recorded on its first request](/docs/en/agent-sdk/modifying-system-prompts.md#change-the-prompt-of-an-existing-session). 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 |
549| `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](https://code.claude.com/docs/en/mcp.md#use-mcp-servers-from-claude-ai) |
550| `systemPrompt` | `string \| string[] \| { type: 'custom'; prompt: string \| string[]; snapshot?: boolean } \| { type: 'preset'; preset: 'claude_code'; append?: string; excludeDynamicSections?: boolean; snapshot?: boolean }` | `undefined` (minimal prompt) | 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](https://code.claude.com/docs/en/agent-sdk/modifying-system-prompts.md#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](https://code.claude.com/docs/en/agent-sdk/modifying-system-prompts.md#improve-prompt-caching-across-users-and-machines). Set `snapshot: false` to rebuild the prompt on every request instead of [reusing the prompt the session recorded on its first request](https://code.claude.com/docs/en/agent-sdk/modifying-system-prompts.md#change-the-prompt-of-an-existing-session). 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 |
551551| `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 |
552552| `thinking` | [`ThinkingConfig`](#thinkingconfig) | `{ type: 'adaptive' }` for supported models | Controls Claude's thinking/reasoning behavior. See [`ThinkingConfig`](#thinkingconfig) for options |
553553| `title` | `string` | `undefined` | Display title for the session. When resuming via `resume` or `continue`, the resumed session's persisted title takes precedence; use [`renameSession()`](#renamesession) to retitle an existing session |
from line 576
576576});
577577```
578578 
579* [`API_TIMEOUT_MS`](/docs/en/env-vars): 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.
579* [`API_TIMEOUT_MS`](https://code.claude.com/docs/en/env-vars): 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.
580580* `CLAUDE_CODE_MAX_RETRIES`: maximum API retries. Default `10`, capped at `15`. Each retry gets its own `API_TIMEOUT_MS` window.
581581 
582 For unattended runs that need to wait through longer outages, set [`CLAUDE_CODE_RETRY_WATCHDOG=1`](/docs/en/errors#tune-retry-behavior): 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.
582 For unattended runs that need to wait through longer outages, set [`CLAUDE_CODE_RETRY_WATCHDOG=1`](https://code.claude.com/docs/en/errors#tune-retry-behavior): 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.
583583* `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`.
584584 
585585 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.
586* `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](/docs/en/errors.md#automatic-retries) covers what Claude Code does, based on how far the response had progressed.
586* `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](https://code.claude.com/docs/en/errors.md#automatic-retries) covers what Claude Code does, based on how far the response had progressed.
587587 
588588 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 `ping` [stream events](#sdkpartialassistantmessage), 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.
589589 
from line 644
644644| Method | Description |
645645| :- | :- |
646646| `interrupt()` | Interrupts the query. Only available in streaming input mode. When the CLI advertises the `interrupt_receipt_v1` capability in [`SDKSystemMessage.capabilities`](#sdksystemmessage), resolves with an [`SDKControlInterruptResponse`](#sdkcontrolinterruptresponse) listing the messages that were pending when the interrupt arrived. Resolves `undefined` on CLIs before v2.1.205 |
647| `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](/docs/en/agent-sdk/file-checkpointing.md) |
647| `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](https://code.claude.com/docs/en/agent-sdk/file-checkpointing.md) |
648648| `setPermissionMode()` | Changes the permission mode (only available in streaming input mode) |
649| `setModel()` | Changes the model (only available in streaming input mode). Passing `undefined` or the string `"default"` resets to [Claude Code's default model](/docs/en/model-config.md). A session in `auto` mode [changes to `default` mode](/docs/en/agent-sdk/permissions#auto-mode-auto) if the new model doesn't support auto mode |
649| `setModel()` | Changes the model (only available in streaming input mode). Passing `undefined` or the string `"default"` resets to [Claude Code's default model](https://code.claude.com/docs/en/model-config.md). A session in `auto` mode [changes to `default` mode](https://code.claude.com/docs/en/agent-sdk/permissions#auto-mode-auto) if the new model doesn't support auto mode |
650650| `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 |
651651| `applyFlagSettings(settings)` | Merges settings into the session's flag settings layer at runtime (only available in streaming input mode). See [`applyFlagSettings()`](#applyflagsettings) |
652652| `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()`](#updatesettings). Requires TypeScript SDK v0.3.257 or later, which bundles Claude Code v2.1.257 |
from line 660
660660| `readFile(path, options?)` | Reads a file from the session's filesystem. Claude Code resolves the path against `cwd`; [What `readFile()` can read](#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`](#sdkcontrolreadfileresponse), or `null` on permission denial, a missing file, or a transport error. Requires TypeScript SDK v0.2.121 or later |
661661| `reloadPlugins(options?)` | Reloads plugins from disk, so plugins you install or edit mid-session reach the running session. Resolves with an [`SDKControlReloadPluginsResponse`](#sdkcontrolreloadpluginsresponse) listing the session's commands, subagents, plugins, and MCP server status. Requires Agent SDK v0.2.85 or later. The [`holdOnCacheImpact` option](#sdkcontrolreloadpluginsresponse) requires Agent SDK v0.3.268 or later |
662662| `reloadSkills()` | Reloads skills from disk, so skills you add or edit mid-session become available to the running session. Resolves with an [`SDKControlReloadSkillsResponse`](#sdkcontrolreloadskillsresponse) listing the skills available after the reload. Requires Agent SDK v0.3.163 or later |
663| `reloadOutputStyles()` | Re-reads [output styles](/docs/en/output-styles.md) from disk, so a style file you add or edit mid-session becomes available to the running session. Resolves with an [`SDKControlReloadOutputStylesResponse`](#sdkcontrolreloadoutputstylesresponse) listing the style names available after the reload. Requires Agent SDK v0.3.261 or later |
663| `reloadOutputStyles()` | Re-reads [output styles](https://code.claude.com/docs/en/output-styles.md) from disk, so a style file you add or edit mid-session becomes available to the running session. Resolves with an [`SDKControlReloadOutputStylesResponse`](#sdkcontrolreloadoutputstylesresponse) listing the style names available after the reload. Requires Agent SDK v0.3.261 or later |
664664| `accountInfo()` | Returns account information |
665665| `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`](#options) or `setMcpServers()`, not the settings-file entry. That resolution order requires Claude Code v2.1.257 or later |
666666| `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()`](#togglemcpserver) for the Claude Code version this needs for each kind of server |
from line 672
672672 
673673#### `applyFlagSettings()`
674674 
675Changes [settings](/docs/en/settings.md) 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()`.
675Changes [settings](https://code.claude.com/docs/en/settings.md) 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()`.
676676 
677677Only some keys take effect mid-session:
678678 
679* **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](/docs/en/agent-sdk/modifying-system-prompts.md#change-the-prompt-of-an-existing-session), once the session is compacted.
679* **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](https://code.claude.com/docs/en/agent-sdk/modifying-system-prompts.md#change-the-prompt-of-an-existing-session), once the session is compacted.
680680* **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.
681681* **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.
682682 
683`effortLevel` accepts an [effort level](/docs/en/model-config.md#adjust-effort-level) name. It also accepts `"ultracode"`, which requests `xhigh` effort with [ultracode](/docs/en/workflows.md#let-claude-decide-with-ultracode) on. `applyFlagSettings()` declares `effortLevel` without that value, so in TypeScript pass `{ ultracode: true, effortLevel: "xhigh" }` for the same result, or the [`ultracode`](/docs/en/settings-reference#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`.
683`effortLevel` accepts an [effort level](https://code.claude.com/docs/en/model-config.md#adjust-effort-level) name. It also accepts `"ultracode"`, which requests `xhigh` effort with [ultracode](https://code.claude.com/docs/en/workflows.md#let-claude-decide-with-ultracode) on. `applyFlagSettings()` declares `effortLevel` without that value, so in TypeScript pass `{ ultracode: true, effortLevel: "xhigh" }` for the same result, or the [`ultracode`](https://code.claude.com/docs/en/settings-reference#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`.
684684 
685685The 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](#settings-precedence) calls programmatic options.
686686 
687687Successive 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.
688688 
689To 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](/docs/en/model-config.md), even when a settings file sets `model`. Passing `undefined` has no effect because JSON serialization drops it.
689To 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](https://code.claude.com/docs/en/model-config.md), even when a settings file sets `model`. Passing `undefined` has no effect because JSON serialization drops it.
690690 
691691Three keys besides `model` reset session state instead of falling back:
692692 
from line 696
696696 
697697Only available in streaming input mode, the same constraint as `setModel()` and `setPermissionMode()`.
698698 
699The example below switches the active model mid-session, then clears the override so the model resets to [Claude Code's default model](/docs/en/model-config.md).
699The example below switches the active model mid-session, then clears the override so the model resets to [Claude Code's default model](https://code.claude.com/docs/en/model-config.md).
700700 
701701```typescript theme={null}
702702import { query } from "@anthropic-ai/claude-agent-sdk";
from line 719
719719Writes 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:
720720 
721721* **`"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.
722* **`"userSettings"`**: accepts `effortLevel` and saves it as the default [effort level](/docs/en/model-config.md#adjust-effort-level) for the session's current model, under [`modelSettings`](/docs/en/settings-reference#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()`](#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.
722* **`"userSettings"`**: accepts `effortLevel` and saves it as the default [effort level](https://code.claude.com/docs/en/model-config.md#adjust-effort-level) for the session's current model, under [`modelSettings`](https://code.claude.com/docs/en/settings-reference#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()`](#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.
723723 
724724The call rejects when the request carries any other key, when the session runs over a remote transport, and when the session's [`settingSources`](#options) exclude the source you name. Deleting a key isn't supported.
725725 
from line 815
815815 
816816Before Agent SDK v0.3.238, the response never carried the field, and Claude Code ignored `hooks` on every repeated initialize.
817817 
818The request's `sdkMcpServerManifests` field and the response's `sdk_mcp_manifests_parked` field are for the in-process [SDK MCP servers](/docs/en/agent-sdk/custom-tools.md) you created with [`createSdkMcpServer()`](#createsdkmcpserver). Your application doesn't set or read either field.
818The request's `sdkMcpServerManifests` field and the response's `sdk_mcp_manifests_parked` field are for the in-process [SDK MCP servers](https://code.claude.com/docs/en/agent-sdk/custom-tools.md) you created with [`createSdkMcpServer()`](#createsdkmcpserver). Your application doesn't set or read either field.
819819 
820820`claude_code_version` is the Claude Code version of the process that runs the session's turns. It is the same value the [`SDKSystemMessage`](#sdksystemmessage) init message carries, so you can read the CLI version before the first turn.
821821 
from line 822
822822* The field requires Agent SDK v0.3.296 or later, which bundles Claude Code v2.1.296.
823823* If the field is `undefined` and you set `pathToClaudeCodeExecutable`, point it at Claude Code v2.1.296 or later.
824824 
825The response always reports `fast_mode_state`, and when something blocks [fast mode](/docs/en/fast-mode.md), `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`](#sdkresultmessage) on the result message.
825The response always reports `fast_mode_state`, and when something blocks [fast mode](https://code.claude.com/docs/en/fast-mode.md), `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`](#sdkresultmessage) on the result message.
826826 
827827The 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.
828828 
from line 849
849849 
850850* Only messages that were enqueued with a UUID appear. An empty array doesn't mean nothing else will run.
851851* Only main-thread messages are listed. Messages addressed to a subagent are out of scope.
852* The list can include UUIDs your client never sent, such as [session-scoped scheduled task](/docs/en/scheduled-tasks.md) triggers. Ignore UUIDs you don't recognize instead of treating them as an error.
852* The list can include UUIDs your client never sent, such as [session-scoped scheduled task](https://code.claude.com/docs/en/scheduled-tasks.md) triggers. Ignore UUIDs you don't recognize instead of treating them as an error.
853853 
854854A 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`](#sdksystemmessage); 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.
855855 
from line 1007
10071007| :- | :- | :- |
10081008| `id` | Each `categories` row | The row's identifier, one of the values the [response type](#sdkcontrolgetcontextusageresponse) 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 |
10091009| `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()`](#query-object) reports for that server |
1010| `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](/docs/en/plugins/loading.md#find-where-a-plugin-came-from) instead, such as `inline` for one you loaded through the [`plugins`](#options) option |
1010| `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](https://code.claude.com/docs/en/plugins/loading.md#find-where-a-plugin-came-from) instead, such as `inline` for one you loaded through the [`plugins`](#options) option |
10111011| `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`](#options) option or a skill built into Claude Code |
10121012 
10131013As an example of matching on `id`, this sample finds the `mcp_instructions` row:
from line 1074
10741074* `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
10751075* `error_count`: the number of errors from loading plugins
10761076 
1077Pass `{ 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](/docs/en/prompt-caching.md#enabling-or-disabling-a-plugin). 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.
1077Pass `{ 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](https://code.claude.com/docs/en/prompt-caching.md#enabling-or-disabling-a-plugin). 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.
10781078 
10791079When you pass the option, read `held` to learn what happened:
10801080 
from line 1158
11581158| Field | Required | Description |
11591159| :- | :- | :- |
11601160| `description` | Yes | Natural language description of when to use this agent |
1161| `tools` | No | Array of allowed tool names. If omitted, inherits every [tool available to subagents](/docs/en/sub-agents.md#available-tools). To preload Skills into the agent's context, use the `skills` field rather than listing `'Skill'` here |
1161| `tools` | No | Array of allowed tool names. If omitted, inherits every [tool available to subagents](https://code.claude.com/docs/en/sub-agents.md#available-tools). To preload Skills into the agent's context, use the `skills` field rather than listing `'Skill'` here |
11621162| `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 |
11631163| `prompt` | Yes | The agent's system prompt |
1164| `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](/docs/en/sub-agents.md#choose-a-model) |
1164| `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](https://code.claude.com/docs/en/sub-agents.md#choose-a-model) |
11651165| `mcpServers` | No | MCP server specifications for this agent |
11661166| `skills` | No | Array of skill names to preload into the agent context |
11671167| `initialPrompt` | No | Auto-submitted as the first user turn when this agent runs as the main thread agent |
11681168| `maxTurns` | No | Maximum number of agentic turns (API round-trips) before stopping |
1169| `autoCompactWindow` | No | Lower the [auto-compact window](/docs/en/sub-agents.md#subagent-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 |
1169| `autoCompactWindow` | No | Lower the [auto-compact window](https://code.claude.com/docs/en/sub-agents.md#subagent-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 |
11701170| `background` | No | Run this agent as a non-blocking background task when invoked |
11711171| `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 |
11721172| `memory` | No | Memory source for this agent: `'user'`, `'project'`, or `'local'` |
11731173| `effort` | No | Reasoning effort level for this agent. Accepts a named level or an integer |
1174| `permissionMode` | No | Permission mode for tool execution within this agent. The [subagent inheritance rules](/docs/en/agent-sdk/permissions.md#available-modes) decide when it applies. See [`PermissionMode`](#permissionmode) |
1174| `permissionMode` | No | Permission mode for tool execution within this agent. The [subagent inheritance rules](https://code.claude.com/docs/en/agent-sdk/permissions.md#available-modes) decide when it applies. See [`PermissionMode`](#permissionmode) |
11751175| `criticalSystemReminder_EXPERIMENTAL` | No | Experimental: Critical reminder added to the system prompt |
11761176 
11771177### `AgentMcpServerSpec`
from line 1200
12001200 
12011201#### Default behavior
12021202 
1203When `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](/docs/en/agent-sdk/claude-code-features.md#what-settingsources-does-not-control) for inputs that are read regardless of this option, and how to disable them.
1203When `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](https://code.claude.com/docs/en/agent-sdk/claude-code-features.md#what-settingsources-does-not-control) for inputs that are read regardless of this option, and how to disable them.
12041204 
12051205#### Why use settingSources
12061206 
from line 1230
12301230});
12311231```
12321232 
1233To load CLAUDE.md project instructions, include `"project"` in `settingSources`. See [Modify system prompts](/docs/en/agent-sdk/modifying-system-prompts.md#claude-md-files-for-project-level-instructions) for how CLAUDE.md loading interacts with the system prompt options.
1233To load CLAUDE.md project instructions, include `"project"` in `settingSources`. See [Modify system prompts](https://code.claude.com/docs/en/agent-sdk/modifying-system-prompts.md#claude-md-files-for-project-level-instructions) for how CLAUDE.md loading interacts with the system prompt options.
12341234 
12351235#### Settings precedence
12361236 
from line 1258
12581258 
12591259Custom permission function type for controlling tool usage.
12601260 
1261The function is the SDK replacement for the interactive permission prompt: it's invoked only when the [permission evaluation flow](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) 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](/docs/en/agent-sdk/hooks) instead.
1261The function is the SDK replacement for the interactive permission prompt: it's invoked only when the [permission evaluation flow](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) 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](https://code.claude.com/docs/en/agent-sdk/hooks) instead.
12621262 
1263An allow rule doesn't pre-approve the [actions no mode auto-approves](/docs/en/permission-modes.md#actions-no-mode-auto-approves); see [How permissions are evaluated](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) for which of them reach the callback and what happens in `dontAsk` and `auto` mode.
1263An allow rule doesn't pre-approve the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves); see [How permissions are evaluated](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) for which of them reach the callback and what happens in `dontAsk` and `auto` mode.
12641264 
12651265```typescript theme={null}
12661266type CanUseTool = (
from line 1332
13321332 
13331333| Field | Type | Description |
13341334| :- | :- | :- |
1335| `askUserQuestion.previewFormat` | `'markdown' \| 'html'` | Opts into the `preview` field on [`AskUserQuestion`](/docs/en/agent-sdk/user-input#question-format) options and sets its content format. When unset, Claude does not emit previews |
1335| `askUserQuestion.previewFormat` | `'markdown' \| 'html'` | Opts into the `preview` field on [`AskUserQuestion`](https://code.claude.com/docs/en/agent-sdk/user-input#question-format) options and sets its content format. When unset, Claude does not emit previews |
13361336 
13371337### `McpServerConfig`
13381338 
from line 1425
14251425];
14261426```
14271427 
1428For complete information on creating and using plugins, see [Plugins](/docs/en/agent-sdk/plugins.md).
1428For complete information on creating and using plugins, see [Plugins](https://code.claude.com/docs/en/agent-sdk/plugins.md).
14291429 
14301430## Message Types
14311431 
from line 1502
15021502 
15031503* `'model_not_found'`: the selected model doesn't exist or isn't available to your account or deployment
15041504* `'overloaded'`: the API returned a 529 because the server is at capacity, as opposed to `'rate_limit'`, which is a 429 against your quota
1505* `'account_on_hold'`: [your account is on hold](/docs/en/errors.md#your-account-is-on-hold)
1506* `'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](/docs/en/errors.md#could-not-load-aws-or-google-cloud-credentials). Requires TypeScript Agent SDK v0.3.267 or later, which bundles Claude Code v2.1.267
1505* `'account_on_hold'`: [your account is on hold](https://code.claude.com/docs/en/errors.md#your-account-is-on-hold)
1506* `'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](https://code.claude.com/docs/en/errors.md#could-not-load-aws-or-google-cloud-credentials). Requires TypeScript Agent SDK v0.3.267 or later, which bundles Claude Code v2.1.267
15071507 
15081508`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.
15091509 
1510`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`](#sdktaskstartedmessage) and other task events, and is unchanged when the subagent is [resumed](/docs/en/agent-sdk/subagents.md#resume-subagents). The field requires Agent SDK v0.3.292 or later.
1510`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`](#sdktaskstartedmessage) and other task events, and is unchanged when the subagent is [resumed](https://code.claude.com/docs/en/agent-sdk/subagents.md#resume-subagents). The field requires Agent SDK v0.3.292 or later.
15111511 
15121512Match 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.
15131513 
from line 1560
15601560Set `shouldQuery`, `client_composed`, or `priority` to change how Claude Code handles a message you send:
15611561 
15621562* `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.
1563* `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`](/docs/en/mcp#use-mcp-resources) mentions, and doesn't run text that starts with `/` as a command. While the [`verbatimPrompts`](#options) 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.
1563* `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`](https://code.claude.com/docs/en/mcp#use-mcp-resources) mentions, and doesn't run text that starts with `/` as a command. While the [`verbatimPrompts`](#options) 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.
15641564* `priority`: controls when a message you send during a running turn reaches Claude:
15651565 * `'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.
15661566 * `'later'`: Claude Code holds the message until the turn ends and sends it as a new turn.
from line 1583
15831583 
15841584On 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](#tool-output-types). These results need handling beyond their listed shape:
15851585 
1586* The `Agent` tool: `tool_use_result` is [`AgentOutput`](#agent-2). 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](/docs/en/permission-modes.md#eliminate-prompts-with-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](/docs/en/sub-agents.md#fork-the-current-conversation), and Claude receives the report as a separate message from the subagent.
1586* The `Agent` tool: `tool_use_result` is [`AgentOutput`](#agent-2). 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](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-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](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation), and Claude receives the report as a separate message from the subagent.
15871587* 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.
15881588* An MCP tool whose result contains `resource_link` blocks: `tool_use_result` is an object with a `resourceLinks` array of [`SDKMcpResourceLink`](#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.
15891589* An MCP tool that returns [`structuredContent`](#calltoolresult): `tool_use_result` is an object whose `structuredContent` member holds what the server sent and whose `content` member holds the [`McpOutput`](#mcpoutput) value. Results from subagents don't carry `structuredContent`.
15901590* 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:
1591 * Tools from [in-process SDK servers](/docs/en/agent-sdk/custom-tools.md) are exempt and deliver the object whole.
1591 * Tools from [in-process SDK servers](https://code.claude.com/docs/en/agent-sdk/custom-tools.md) are exempt and deliver the object whole.
15921592 * A tool whose `tools/list` entry declares an [MCP Apps `ui://` resource](#mcpserverstatus) has a limit of 8,388,608 characters on Claude Code v2.1.295 or later, and versions before v2.1.295 exempt it.
15931593 
15941594### `SDKUserMessageReplay`
from line 1703
17031703* `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.
17041704* `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`](#user_message_uuid), on a success result with `is_error` false whose turn sent an API request.
17051705* `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.
1706* `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](/docs/en/claude-code-on-the-web.md), and the results `query()` yields don't carry them. Requires Agent SDK v0.3.260 or later.
1706* `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](https://code.claude.com/docs/en/claude-code-on-the-web.md), and the results `query()` yields don't carry them. Requires Agent SDK v0.3.260 or later.
17071707* `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.
1708* `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](/docs/en/agent-sdk/cost-tracking.md#accumulate-costs-across-multiple-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](/docs/en/agent-sdk/cost-tracking.md#track-costs-in-streaming-input-mode) for resets and [Recover totals after a session crash](/docs/en/agent-sdk/cost-tracking.md#recover-totals-after-a-session-crash) for zeroed results.
1709* `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](/docs/en/agent-sdk/cost-tracking.md#accumulate-costs-across-multiple-calls). It is an estimate, not a billing statement. See [Track cost and usage](/docs/en/agent-sdk/cost-tracking.md) for accuracy caveats.
1708* `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](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md#accumulate-costs-across-multiple-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](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md#track-costs-in-streaming-input-mode) for resets and [Recover totals after a session crash](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md#recover-totals-after-a-session-crash) for zeroed results.
1709* `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](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md#accumulate-costs-across-multiple-calls). It is an estimate, not a billing statement. See [Track cost and usage](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md) for accuracy caveats.
17101710* `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`](#queued_turn_count) for what `0` and an absent field tell you.
17111711* `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.
17121712* `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`](#startup_failure_reason) for the values and which failures carry it. Requires Agent SDK v0.3.274 or later.
17131713* `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"`.
17141714* `fast_mode_state`: one of `"on"`, `"off"`, or `"cooldown"`.
1715* `fast_mode_disabled_reason`: why [fast mode](/docs/en/fast-mode.md) 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.
1715* `fast_mode_disabled_reason`: why [fast mode](https://code.claude.com/docs/en/fast-mode.md) 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.
17161716 
17171717Use 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:
17181718 
from line 1721
17211721| `free` | The account doesn't have the paid subscription or usage credits fast mode requires |
17221722| `preference` | The organization has disabled fast mode |
17231723| `extra_usage_disabled` | Usage credits are turned off for the account |
1724| `network_error` | The [availability check](/docs/en/fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) couldn't reach `api.anthropic.com` |
1724| `network_error` | The [availability check](https://code.claude.com/docs/en/fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) couldn't reach `api.anthropic.com` |
17251725| `unknown` | Claude Code couldn't determine availability |
17261726| `not_first_party` | The session uses a provider other than the Anthropic API |
1727| `disabled_by_env` | [`CLAUDE_CODE_DISABLE_FAST_MODE`](/docs/en/env-vars) is set |
1728| `model_not_allowed` | The fast mode Opus model isn't in the organization's [`availableModels`](/docs/en/model-config#restrict-model-selection) allowlist |
1727| `disabled_by_env` | [`CLAUDE_CODE_DISABLE_FAST_MODE`](https://code.claude.com/docs/en/env-vars) is set |
1728| `model_not_allowed` | The fast mode Opus model isn't in the organization's [`availableModels`](https://code.claude.com/docs/en/model-config#restrict-model-selection) allowlist |
17291729| `sdk_opt_in_required` | The session hasn't opted in to fast mode: pass `fastMode: true` in the [`settings`](#options) option or through [`applyFlagSettings()`](#applyflagsettings) |
17301730| `pending` | The availability check hasn't completed yet |
17311731 
from line 1742
17421742 
17431743The field is absent for results emitted before any user turn, such as startup errors.
17441744 
1745When 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](/docs/en/hooks.md#defer-a-tool-call-for-later) for the full round trip.
1745When 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](https://code.claude.com/docs/en/hooks.md#defer-a-tool-call-for-later) for the full round trip.
17461746 
17471747#### `user_message_uuid`
17481748 
from line 1752
17521752 
17531753* **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`](#user_message_uuids).
17541754* **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.
1755* **The prompt Claude Code generates to continue an interrupted turn under [`CLAUDE_CODE_RESUME_INTERRUPTED_TURN`](/docs/en/env-vars)**: 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`](#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.
1755* **The prompt Claude Code generates to continue an interrupted turn under [`CLAUDE_CODE_RESUME_INTERRUPTED_TURN`](https://code.claude.com/docs/en/env-vars)**: 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`](#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.
17561756* **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.
17571757 
17581758Claude Code echoes the answered message's `uuid` on three kinds of frame:
from line 1780
17801780 
17811781#### `resume_reason`
17821782 
1783Why 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`](/docs/en/env-vars), so you can tell the continued turn's reply and result from the interrupted attempt's. Requires Agent SDK v0.3.268 or later.
1783Why 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`](https://code.claude.com/docs/en/env-vars), so you can tell the continued turn's reply and result from the interrupted attempt's. Requires Agent SDK v0.3.268 or later.
17841784 
17851785Claude Code sets the field on two kinds of frame:
17861786 
from line 1796
17961796What `0` and an absent field tell you:
17971797 
17981798* **`0`**: Claude Code doesn't count messages you sent without that `origin`, and doesn't count task notifications, so a turn can still follow.
1799* **Absent**: the final result that Claude Code emits after a crash or fatal startup error omits the field, and [may carry zeroed totals](/docs/en/agent-sdk/cost-tracking.md#recover-totals-after-a-session-crash).
1799* **Absent**: the final result that Claude Code emits after a crash or fatal startup error omits the field, and [may carry zeroed totals](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md#recover-totals-after-a-session-crash).
18001800 
18011801#### `startup_failure_reason`
18021802 
from line 1804
18041804 
18051805Set `CLAUDE_CODE_STARTUP_FAILURE_RESULTS` to `1` in [`env`](#options) 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:
18061806 
1807* A resume that Claude Code stops because it [can't return the session to its worktree](/docs/en/worktrees.md#the-session-resumes-outside-its-worktree), with `worktree_unverified` or `worktree_resume_refused`. That section says which error carries which value.
1807* A resume that Claude Code stops because it [can't return the session to its worktree](https://code.claude.com/docs/en/worktrees.md#the-session-resumes-outside-its-worktree), with `worktree_unverified` or `worktree_resume_refused`. That section says which error carries which value.
18081808* A refused [`continue`](#options) of a conversation that a background session holds, with `session_held_by_background`. For a refused [`resume`](#options) of such a conversation, Claude Code writes the result only when the variable is set.
18091809 
18101810```typescript theme={null}
from line 1834
18341834 
18351835| Value | What stopped the session |
18361836| :- | :- |
1837| `org_pin_api_key_conflict` | Managed settings [require a first-party or Cloud gateway sign-in](/docs/en/authentication.md#restrict-login-to-your-organization), and an Anthropic API key, auth token, or `apiKeyHelper` is configured instead |
1838| `provider_not_allowed` | Managed settings [list the API providers this machine may use](/docs/en/settings-reference.md#allowedproviders), 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 |
1837| `org_pin_api_key_conflict` | Managed settings [require a first-party or Cloud gateway sign-in](https://code.claude.com/docs/en/authentication.md#restrict-login-to-your-organization), and an Anthropic API key, auth token, or `apiKeyHelper` is configured instead |
1838| `provider_not_allowed` | Managed settings [list the API providers this machine may use](https://code.claude.com/docs/en/settings-reference.md#allowedproviders), 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 |
18391839| `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 |
18401840| `org_pin_mismatch` | The sign-in belongs to an organization the pin doesn't allow |
1841| `managed_settings_invalid` | Managed policy settings couldn't be read, the pin names no organization, or [managed model restrictions](/docs/en/errors.md#managed-settings-block-the-default-model) leave no permitted model for the Default option |
1841| `managed_settings_invalid` | Managed policy settings couldn't be read, the pin names no organization, or [managed model restrictions](https://code.claude.com/docs/en/errors.md#managed-settings-block-the-default-model) leave no permitted model for the Default option |
18421842| `remote_settings_required_unavailable` | Managed settings that the organization requires couldn't be loaded |
1843| `gateway_signin_required` | The [Cloud gateway](/docs/en/claude-apps-gateway) ended this sign-in |
1844| `gateway_access_denied` | The managed settings request to the Cloud gateway came back with a 403, which the gateway's [troubleshooting table](/docs/en/claude-apps-gateway-deploy.md#troubleshooting) covers |
1843| `gateway_signin_required` | The [Cloud gateway](https://code.claude.com/docs/en/claude-apps-gateway) ended this sign-in |
1844| `gateway_access_denied` | The managed settings request to the Cloud gateway came back with a 403, which the gateway's [troubleshooting table](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#troubleshooting) covers |
18451845| `proxy_invalid` | A proxy setting isn't a complete URL |
18461846| `temp_dir_unusable` | The per-user temporary directory is unsafe or couldn't be created |
18471847| `cwd_unavailable` | The working directory was deleted, moved, or can't be read |
18481848| `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` |
1849| `session_held_by_background` | The conversation to resume or continue is running as a [background session](/docs/en/agent-view.md) |
1849| `session_held_by_background` | The conversation to resume or continue is running as a [background session](https://code.claude.com/docs/en/agent-view.md) |
18501850| `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 |
18511851| `worktree_unverified` | The session's worktree couldn't be verified right now, and retrying may succeed |
18521852| `cli_version_too_old` | This Claude Code version is below the minimum Anthropic requires |
from line 1895
18951895};
18961896```
18971897 
1898`fast_mode_state` reports the session's [fast mode](/docs/en/fast-mode.md) 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`](#sdkresultmessage) on the result message.
1898`fast_mode_state` reports the session's [fast mode](https://code.claude.com/docs/en/fast-mode.md) 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`](#sdkresultmessage) on the result message.
18991899 
19001900`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.
19011901 
19021902* `source` on each `mcp_servers` entry: where the server's definition came from, with the same values as [`McpServerStatus`](#mcpserverstatus)'s `source`. Requires Agent SDK v0.3.274 or later.
1903* `effort`: the [effort level](/docs/en/model-config.md#adjust-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](/docs/en/remote-control.md) clients, and omits it from the init message your application reads. Requires Agent SDK v0.3.234 or later.
1903* `effort`: the [effort level](https://code.claude.com/docs/en/model-config.md#adjust-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](https://code.claude.com/docs/en/remote-control.md) clients, and omits it from the init message your application reads. Requires Agent SDK v0.3.234 or later.
19041904 
19051905The `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.
19061906 
from line 1908
19081908| - | - |
19091909| `interrupt_receipt_v1` | [`interrupt()`](#query-object) resolves with an [`SDKControlInterruptResponse`](#sdkcontrolinterruptresponse) receipt listing the messages that were pending when the interrupt arrived |
19101910| `interrupt_cancel_queued_v1` | 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`](#sdkcontrolinterruptresponse). Requires Claude Code v2.1.219 or later |
1911| `sdk_mcp_manifests` | The `initialize` control request accepts `sdkMcpServerManifests`, MCP handshake results captured from your in-process [SDK MCP servers](/docs/en/agent-sdk/custom-tools.md). Claude Code advertises this capability in v2.1.286 or later |
1912| `sdk_mcp_tools_list_changed` | A `tools/list_changed` notification from an [SDK MCP server](/docs/en/agent-sdk/custom-tools.md) 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 |
1911| `sdk_mcp_manifests` | The `initialize` control request accepts `sdkMcpServerManifests`, MCP handshake results captured from your in-process [SDK MCP servers](https://code.claude.com/docs/en/agent-sdk/custom-tools.md). Claude Code advertises this capability in v2.1.286 or later |
1912| `sdk_mcp_tools_list_changed` | A `tools/list_changed` notification from an [SDK MCP server](https://code.claude.com/docs/en/agent-sdk/custom-tools.md) 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 |
19131913 
19141914The `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.
19151915 
from line 1967
19671967 
19681968Generic 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.
19691969 
1970On Claude Code v2.1.227 or later, a hook's [`systemMessage`](/docs/en/hooks#json-output) can arrive as this message, with each line prefixed by the hook's name, such as `PostToolUse:Bash says:`. Each [event's section](/docs/en/hooks.md#hook-events) on the hooks page says how output surfaces.
1970On Claude Code v2.1.227 or later, a hook's [`systemMessage`](https://code.claude.com/docs/en/hooks#json-output) can arrive as this message, with each line prefixed by the hook's name, such as `PostToolUse:Bash says:`. Each [event's section](https://code.claude.com/docs/en/hooks.md#hook-events) on the hooks page says how output surfaces.
19711971 
19721972Render `content` as plaintext at the given `level`.
19731973 
from line 2000
20002000 
20012001### `SDKPluginInstallMessage`
20022002 
2003Plugin installation progress event. Emitted when [`CLAUDE_CODE_SYNC_PLUGIN_INSTALL`](/docs/en/env-vars) 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`.
2003Plugin installation progress event. Emitted when [`CLAUDE_CODE_SYNC_PLUGIN_INSTALL`](https://code.claude.com/docs/en/env-vars) 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`.
20042004 
20052005```typescript theme={null}
20062006type SDKPluginInstallMessage = {
from line 2019
20192019Stream 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:
20202020 
20212021* **With a [`canUseTool`](#canusetool) callback** and the default [`permissionPrompts: 'host'`](#options): permission prompts go to your callback, and this event reports the denials Claude Code decides on its own without calling it.
2022* **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](/docs/en/hooks-guide#limitations) 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.
2023* **With an MCP prompt tool**, set with `permissionPromptToolName` or the [`--permission-prompt-tool`](/docs/en/cli-reference#cli-flags) 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.
2022* **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](https://code.claude.com/docs/en/hooks-guide#limitations) 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.
2023* **With an MCP prompt tool**, set with `permissionPromptToolName` or the [`--permission-prompt-tool`](https://code.claude.com/docs/en/cli-reference#cli-flags) 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.
20242024* **With [`permissionPrompts: 'none'`](#options)**: 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.
20252025 
20262026In 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](#sdkresultmessage) is the authoritative record.
from line 2106
21062106| - | - | - |
21072107| `model` | `string` | The main loop's model Claude Code computed the usage for, not a subagent's |
21082108| `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 |
2109| `raw_max_tokens` | `number` | The model's context window, or the lower [auto-compact window](/docs/en/model-config.md#context-window-and-auto-compaction) 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 |
2109| `raw_max_tokens` | `number` | The model's context window, or the lower [auto-compact window](https://code.claude.com/docs/en/model-config.md#context-window-and-auto-compaction) 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 |
21102110| `percentage` | `number` | `total_tokens` as a rounded percentage of `raw_max_tokens`, so it can exceed 100 when the session is over the limit |
21112111| `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 |
21122112| `categories` | [`SDKContextUsageCategory`](#sdkcontextusagecategory)`[]` | One entry per row of the usage-by-category breakdown |
from line 2194
21942194* `session`: Claude Code's running cost and usage totals, read from the same ledger as `total_cost_usd` and `modelUsage` on [`SDKResultMessage`](#sdkresultmessage). Each `model_usage` entry is a [`ModelUsage`](#modelusage).
21952195* `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.
21962196 
2197Claude 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](/docs/en/agent-sdk/cost-tracking.md) for the accuracy caveats.
2197Claude 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](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md) for the accuracy caveats.
21982198 
21992199`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.
22002200 
from line 2251
22512251 
22522252| `kind` | Meaning |
22532253| - | - |
2254| `human` | 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](/docs/en/workflows#ask-for-a-workflow-in-your-prompt), don't accept it. Before v2.1.210, Claude Code treated an absent `origin` on a user message as human input. |
2255| `channel` | Message arriving on a [channel](/docs/en/channels.md). `server` is the source MCP server name. |
2256| `peer` | Message from another agent: an in-process [teammate](/docs/en/agent-teams.md) or a [cross-session peer](/docs/en/cross-session-messaging.md), another of your Claude Code sessions. See [Peer origin fields](#peer-origin-fields) for the per-field semantics and the trust model. |
2254| `human` | 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](https://code.claude.com/docs/en/workflows#ask-for-a-workflow-in-your-prompt), don't accept it. Before v2.1.210, Claude Code treated an absent `origin` on a user message as human input. |
2255| `channel` | Message arriving on a [channel](https://code.claude.com/docs/en/channels.md). `server` is the source MCP server name. |
2256| `peer` | Message from another agent: an in-process [teammate](https://code.claude.com/docs/en/agent-teams.md) or a [cross-session peer](https://code.claude.com/docs/en/cross-session-messaging.md), another of your Claude Code sessions. See [Peer origin fields](#peer-origin-fields) for the per-field semantics and the trust model. |
22572257| `task-notification` | Synthetic turn injected for a delivery that arrives without a fresh user prompt, such as a finished background task; see [`SDKTaskNotificationMessage`](#sdktasknotificationmessage) for that arm. A prompt your application [declares as a scheduled run](#declare-a-scheduled-run) carries this kind too. The optional `subkind` marks what raised the notification. See [Task-notification subkinds](#task-notification-subkinds). |
2258| `coordinator` | Message from a team coordinator in an [agent team](/docs/en/agent-teams.md). |
2258| `coordinator` | Message from a team coordinator in an [agent team](https://code.claude.com/docs/en/agent-teams.md). |
22592259| `auto-continuation` | Synthetic turn injected when the session continues without fresh user input, such as a command result that triggers a follow-up prompt. |
22602260| `unclassified` | Injected turn whose origin couldn't be determined. Requires Claude Code v2.1.223 or later. When Claude Code receives an [`SDKUserMessage`](#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. |
22612261 
from line 2263
22632263 
22642264When 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](#declare-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:
22652265 
2266* `scheduled-trigger`: the notification is a [cloud scheduled task](/docs/en/routines.md)'s stored prompt, delivered because one of the task's triggers fired: its schedule, its [API trigger](/docs/en/routines.md#add-an-api-trigger), its [GitHub trigger](/docs/en/routines.md#add-a-github-trigger), or **Run now**. A prompt your application [declares as a scheduled run](#declare-a-scheduled-run) carries this value too. Claude Code frames these to the model as the session's assigned task, with a different notice from the [notice that other task notifications carry](#sdktasknotificationmessage).
2267* `peer-send-message`: the notification is a message that another of your sessions sent with the server-side `send_message` tool that [cloud sessions](/docs/en/claude-code-on-the-web.md) use to message each other, not the [cross-session `SendMessage` tool](/docs/en/cross-session-messaging), 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.
2266* `scheduled-trigger`: the notification is a [cloud scheduled task](https://code.claude.com/docs/en/routines.md)'s stored prompt, delivered because one of the task's triggers fired: its schedule, its [API trigger](https://code.claude.com/docs/en/routines.md#add-an-api-trigger), its [GitHub trigger](https://code.claude.com/docs/en/routines.md#add-a-github-trigger), or **Run now**. A prompt your application [declares as a scheduled run](#declare-a-scheduled-run) carries this value too. Claude Code frames these to the model as the session's assigned task, with a different notice from the [notice that other task notifications carry](#sdktasknotificationmessage).
2267* `peer-send-message`: the notification is a message that another of your sessions sent with the server-side `send_message` tool that [cloud sessions](https://code.claude.com/docs/en/claude-code-on-the-web.md) use to message each other, not the [cross-session `SendMessage` tool](https://code.claude.com/docs/en/cross-session-messaging), 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.
22682268 
2269Every other task notification has no `subkind`. That includes [PR activity](/docs/en/claude-code-on-the-web.md#how-claude-responds-to-pr-activity) delivered into a session and background events such as a finished task. Messages from the [cross-session `SendMessage` tool](/docs/en/cross-session-messaging) 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](#peer-origin-fields).
2269Every other task notification has no `subkind`. That includes [PR activity](https://code.claude.com/docs/en/claude-code-on-the-web.md#how-claude-responds-to-pr-activity) delivered into a session and background events such as a finished task. Messages from the [cross-session `SendMessage` tool](https://code.claude.com/docs/en/cross-session-messaging) 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](#peer-origin-fields).
22702270 
2271`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](/docs/en/routines.md)'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.
2271`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](https://code.claude.com/docs/en/routines.md)'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.
22722272 
2273A background task can run more than once under the same `task_id`, such as when Claude [resumes a subagent](/docs/en/agent-sdk/subagents.md#resume-subagents). Each run has its own [`run_id`](#sdktaskstartedmessage). 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.
2273A background task can run more than once under the same `task_id`, such as when Claude [resumes a subagent](https://code.claude.com/docs/en/agent-sdk/subagents.md#resume-subagents). Each run has its own [`run_id`](#sdktaskstartedmessage). 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.
22742274 
22752275#### Declare a scheduled run
22762276 
2277If 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`](#options), then send the run's [`SDKUserMessage`](#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`](/docs/en/env-vars) 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.
2277If 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`](#options), then send the run's [`SDKUserMessage`](#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`](https://code.claude.com/docs/en/env-vars) 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.
22782278 
22792279### Peer origin fields
22802280 
2281A `peer` origin identifies which agent sent the message: an in-process [teammate](/docs/en/agent-teams.md) sending to `main` with `SendMessage`, or a [cross-session peer](/docs/en/cross-session-messaging.md), 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](/docs/en/cross-session-messaging.md#availability) for the native Windows requirement. A cross-session peer can run on the same machine, or on [another of your machines](/docs/en/cross-session-messaging.md#message-sessions-on-other-machines) when its message arrives through [Remote Control](/docs/en/remote-control.md).
2281A `peer` origin identifies which agent sent the message: an in-process [teammate](https://code.claude.com/docs/en/agent-teams.md) sending to `main` with `SendMessage`, or a [cross-session peer](https://code.claude.com/docs/en/cross-session-messaging.md), 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](https://code.claude.com/docs/en/cross-session-messaging.md#availability) for the native Windows requirement. A cross-session peer can run on the same machine, or on [another of your machines](https://code.claude.com/docs/en/cross-session-messaging.md#message-sessions-on-other-machines) when its message arrives through [Remote Control](https://code.claude.com/docs/en/remote-control.md).
22822282 
2283* `from`: the teammate's name, or the sender address for a cross-session peer. For a [one-way cross-machine message](/docs/en/cross-session-messaging.md#message-sessions-on-other-machines), the sender has no reply address and `from` is `"unknown"`. The value is sender-authored; `verifiedPeerPid` is the verified identity.
2284* `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](/docs/en/desktop.md#work-across-sessions). Claude Code reads it in the receiving session when it applies the [inbound controls](/docs/en/cross-session-messaging.md#control-inbound-messages). Requires Agent SDK v0.3.234 or later.
2283* `from`: the teammate's name, or the sender address for a cross-session peer. For a [one-way cross-machine message](https://code.claude.com/docs/en/cross-session-messaging.md#message-sessions-on-other-machines), the sender has no reply address and `from` is `"unknown"`. The value is sender-authored; `verifiedPeerPid` is the verified identity.
2284* `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](https://code.claude.com/docs/en/desktop.md#work-across-sessions). Claude Code reads it in the receiving session when it applies the [inbound controls](https://code.claude.com/docs/en/cross-session-messaging.md#control-inbound-messages). Requires Agent SDK v0.3.234 or later.
22852285* `senderTaskId`: the teammate's task ID. Absent for a cross-session peer.
22862286* `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.
22872287* `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.
from line 2290
22902290 
22912291## Hook Types
22922292 
2293For a guide on using hooks with examples and common patterns, see the [Hooks guide](/docs/en/agent-sdk/hooks.md).
2293For a guide on using hooks with examples and common patterns, see the [Hooks guide](https://code.claude.com/docs/en/agent-sdk/hooks.md).
22942294 
22952295### `HookEvent`
22962296 
from line 2415
24152415};
24162416```
24172417 
2418The `prompt_id` field is a UUID identifying the user prompt currently being processed. It matches the [`prompt.id` attribute on OpenTelemetry events](/docs/en/monitoring-usage#event-correlation-attributes) and is absent until the first user input. Requires Claude Code v2.1.196 or later.
2418The `prompt_id` field is a UUID identifying the user prompt currently being processed. It matches the [`prompt.id` attribute on OpenTelemetry events](https://code.claude.com/docs/en/monitoring-usage#event-correlation-attributes) and is absent until the first user input. Requires Claude Code v2.1.196 or later.
24192419 
24202420#### `PreToolUseHookInput`
24212421 
from line 2635
26352635 
26362636#### `PreModelSwitchHookInput`
26372637 
2638Fires 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](/docs/en/hooks.md#premodelswitch).
2638Fires 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](https://code.claude.com/docs/en/hooks.md#premodelswitch).
26392639 
26402640```typescript theme={null}
26412641type PreModelSwitchHookInput = BaseHookInput & {
from line 2654
26542654 
26552655#### `PostModelSwitchHookInput`
26562656 
2657Fires after the session's model changes. It carries the same fields as `PreModelSwitchHookInput`, with two more `source` values. See [PostModelSwitch](/docs/en/hooks.md#postmodelswitch).
2657Fires after the session's model changes. It carries the same fields as `PreModelSwitchHookInput`, with two more `source` values. See [PostModelSwitch](https://code.claude.com/docs/en/hooks.md#postmodelswitch).
26582658 
26592659```typescript theme={null}
26602660type PostModelSwitchHookInput = BaseHookInput & {
from line 3032
30323032 
30333033Documentation 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.
30343034 
3035The `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](/docs/en/agent-sdk/structured-outputs.md#recognize-the-structuredoutput-tool-call) for what that call looks like in your message stream.
3035The `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](https://code.claude.com/docs/en/agent-sdk/structured-outputs.md#recognize-the-structuredoutput-tool-call) for what that call looks like in your message stream.
30363036 
30373037### `ToolInputSchemas`
30383038 
from line 3086
30863086 
30873087> [!NOTE]
30883088>
3089> 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`](#agentdefinition), and the [subagent inheritance rules](/docs/en/agent-sdk/permissions.md#available-modes) decide which.
3089> 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`](#agentdefinition), and the [subagent inheritance rules](https://code.claude.com/docs/en/agent-sdk/permissions.md#available-modes) decide which.
30903090 
30913091```typescript theme={null}
30923092type AgentInput = {
from line 3123
31233123};
31243124```
31253125 
3126Asks the user clarifying questions during execution. See [Handle approvals and user input](/docs/en/agent-sdk/user-input.md#handle-clarifying-questions) for usage details.
3126Asks the user clarifying questions during execution. See [Handle approvals and user input](https://code.claude.com/docs/en/agent-sdk/user-input.md#handle-clarifying-questions) for usage details.
31273127 
31283128### Bash
31293129 
from line 3139
31393139};
31403140```
31413141 
3142Executes 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](/docs/en/tools-reference.md#what-persists-between-commands). For what sets the foreground ceiling, see [Timeout and output limits](/docs/en/tools-reference.md#timeout-and-output-limits). For the background time limit, see [Time limit for background commands](/docs/en/tools-reference.md#time-limit-for-background-commands).
3142Executes 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](https://code.claude.com/docs/en/tools-reference.md#what-persists-between-commands). For what sets the foreground ceiling, see [Timeout and output limits](https://code.claude.com/docs/en/tools-reference.md#timeout-and-output-limits). For the background time limit, see [Time limit for background commands](https://code.claude.com/docs/en/tools-reference.md#time-limit-for-background-commands).
31433143 
31443144### Monitor
31453145 
from line 3163
31633163 
31643164The exported type marks `timeout_ms` as required because the schema fills in the default; a call that omits it validates.
31653165 
3166When Monitor runs a command, it follows the same permission rules as Bash; a WebSocket watch prompts for approval separately. See the [Monitor tool reference](/docs/en/tools-reference.md#monitor-tool) for behavior and provider availability.
3166When Monitor runs a command, it follows the same permission rules as Bash; a WebSocket watch prompts for approval separately. See the [Monitor tool reference](https://code.claude.com/docs/en/tools-reference.md#monitor-tool) for behavior and provider availability.
31673167 
31683168### TaskOutput
31693169 
from line 3203
32033203Reads files from the local filesystem, including text, images, PDFs, and Jupyter notebooks.
32043204 
32053205* Use `pages` for PDF page ranges (for example, `"1-5"`).
3206* `allow_large` lets Claude read a text file past the [usual size limits](/docs/en/tools-reference.md#large-files) when the session's context window has room. It requires Agent SDK v0.3.296 or later, which bundles Claude Code v2.1.296.
3206* `allow_large` lets Claude read a text file past the [usual size limits](https://code.claude.com/docs/en/tools-reference.md#large-files) when the session's context window has room. It requires Agent SDK v0.3.296 or later, which bundles Claude Code v2.1.296.
32073207 
32083208For a PDF, Claude receives the file's contents inside the Read call's `tool_result` content. A read that returns the `pdf` [output](#tool-output-types) 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.
32093209 
from line 3334
33343334};
33353335```
33363336 
3337Runs a [dynamic workflow](/docs/en/workflows.md): 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.
3337Runs a [dynamic workflow](https://code.claude.com/docs/en/workflows.md): 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.
33383338 
33393339| Field | Type | Description |
33403340| - | - | - |
from line 3342
33423342| `name` | `string` | Name of a built-in workflow or one saved in `.claude/workflows/`. Resolved to a script |
33433343| `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` |
33443344| `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 |
3345| `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](/docs/en/workflows.md#resume-after-a-pause) covers which completed calls re-run. Same session only |
3345| `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](https://code.claude.com/docs/en/workflows.md#resume-after-a-pause) covers which completed calls re-run. Same session only |
33463346| `title` | `string` | Ignored; the script's `meta` block sets the title |
33473347| `description` | `string` | Ignored; the script's `meta` block sets the description |
33483348 
from line 3376
33763376>
33773377> This default set applies in Claude Code v2.1.268 and later, which the TypeScript Agent SDK bundles from v0.3.268.
33783378>
3379> See [Model availability](/docs/en/agent-sdk/todo-tracking.md#model-availability) to opt in.
3379> See [Model availability](https://code.claude.com/docs/en/agent-sdk/todo-tracking.md#model-availability) to opt in.
33803380 
33813381### TaskCreate
33823382 
from line 3526
35263526};
35273527```
35283528 
3529Schedules 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](/docs/en/scheduled-tasks.md).
3529Schedules 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](https://code.claude.com/docs/en/scheduled-tasks.md).
35303530 
35313531Setting `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.
35323532 
from line 3566
35663566};
35673567```
35683568 
3569Schedules 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](/docs/en/tools-reference.md).
3569Schedules 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](https://code.claude.com/docs/en/tools-reference.md).
35703570 
35713571### RemoteTrigger
35723572 
from line 3592
35923592};
35933593```
35943594 
3595Manages [cloud scheduled tasks](/docs/en/routines.md), 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`.
3595Manages [cloud scheduled tasks](https://code.claude.com/docs/en/routines.md), 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`.
35963596 
35973597`create_webhook_trigger`, `list_runs`, and `get_run_log` each require a minimum Claude Code version:
35983598 
3599* **`create_webhook_trigger`**: attaches an event source to an existing scheduled task, such as a [GitHub event](/docs/en/routines.md#add-a-github-trigger) that fires it. The `body` names the source, the events, and the task to fire. Requires Claude Code v2.1.225 or later.
3599* **`create_webhook_trigger`**: attaches an event source to an existing scheduled task, such as a [GitHub event](https://code.claude.com/docs/en/routines.md#add-a-github-trigger) that fires it. The `body` names the source, the events, and the task to fire. Requires Claude Code v2.1.225 or later.
36003600* **`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.
36013601 
3602This 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](/docs/en/claude-code-on-the-web.md). On Claude Code v2.1.227 or later, the tool is also absent when an Owner has [turned off scheduled tasks for the organization](/docs/en/routines.md#routines-are-disabled-by-your-organizations-policy).
3602This 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](https://code.claude.com/docs/en/claude-code-on-the-web.md). On Claude Code v2.1.227 or later, the tool is also absent when an Owner has [turned off scheduled tasks for the organization](https://code.claude.com/docs/en/routines.md#routines-are-disabled-by-your-organizations-policy).
36033603 
36043604### PushNotification
36053605 
from line 3612
36123612};
36133613```
36143614 
3615Sends 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](/docs/en/tools-reference.md) 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.
3615Sends 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](https://code.claude.com/docs/en/tools-reference.md) 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.
36163616 
36173617### REPL
36183618 
from line 3686
36863686 
36873687`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.
36883688 
3689* `capabilities`: the runtime capabilities the published page uses, keyed by capability name, such as the [connectors the page may call](/docs/en/artifacts.md#pull-live-data-with-mcp-connectors). 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.
3689* `capabilities`: the runtime capabilities the published page uses, keyed by capability name, such as the [connectors the page may call](https://code.claude.com/docs/en/artifacts.md#pull-live-data-with-mcp-connectors). 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.
36903690* `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.
36913691 
3692The types are exported, but the tool is off by default in Agent SDK sessions. Publishing also requires every condition in the [artifacts availability table](/docs/en/artifacts.md#availability), which sessions authenticated with an API key don't meet.
3692The types are exported, but the tool is off by default in Agent SDK sessions. Publishing also requires every condition in the [artifacts availability table](https://code.claude.com/docs/en/artifacts.md#availability), which sessions authenticated with an API key don't meet.
36933693 
36943694### Projects
36953695 
from line 3892
38923892 
38933893Returns 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.
38943894 
3895On the `completed` variant, `resolvedModel` names the model the subagent started on, which can differ from the requested `model` input when [`availableModels`](/docs/en/model-config#restrict-model-selection) 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.
3895On the `completed` variant, `resolvedModel` names the model the subagent started on, which can differ from the requested `model` input when [`availableModels`](https://code.claude.com/docs/en/model-config#restrict-model-selection) 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.
38963896 
38973897`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.
38983898 
3899If Claude Code [kept the subagent's isolated worktree](/docs/en/worktrees.md#isolate-subagents-with-worktrees), `worktreePath` on the `completed` result is where to find it. `worktreeBranch` is its branch, present when Claude Code created the worktree with git.
3899If Claude Code [kept the subagent's isolated worktree](https://code.claude.com/docs/en/worktrees.md#isolate-subagents-with-worktrees), `worktreePath` on the `completed` result is where to find it. `worktreeBranch` is its branch, present when Claude Code created the worktree with git.
39003900 
39013901Claude 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.
39023902 
from line 3972
39723972 
39733973`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.
39743974 
3975When a subagent running in the foreground owns a backgrounded command, the command [ends when that subagent's run ends](/docs/en/tools-reference.md#when-a-background-command-stops). 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.
3975When a subagent running in the foreground owns a backgrounded command, the command [ends when that subagent's run ends](https://code.claude.com/docs/en/tools-reference.md#when-a-background-command-stops). 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.
39763976 
39773977Claude 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.
39783978 
from line 4329
43294329>
43304330> This default set applies in Claude Code v2.1.268 and later, which the TypeScript Agent SDK bundles from v0.3.268.
43314331>
4332> See [Model availability](/docs/en/agent-sdk/todo-tracking.md#model-availability) to opt in.
4332> See [Model availability](https://code.claude.com/docs/en/agent-sdk/todo-tracking.md#model-availability) to opt in.
43334333 
43344334### TaskCreate
43354335 
from line 4873
48734873| Value | Key in use |
48744874| - | - |
48754875| `ANTHROPIC_API_KEY` | The key in the `ANTHROPIC_API_KEY` environment variable |
4876| `apiKeyHelper` | The key returned by your [`apiKeyHelper`](/docs/en/settings-reference#apikeyhelper) command |
4877| `/login managed key` | The key Claude Code stored when you logged in with a [Claude Console account](/docs/en/authentication.md#claude-console-authentication) |
4876| `apiKeyHelper` | The key returned by your [`apiKeyHelper`](https://code.claude.com/docs/en/settings-reference#apikeyhelper) command |
4877| `/login managed key` | The key Claude Code stored when you logged in with a [Claude Console account](https://code.claude.com/docs/en/authentication.md#claude-console-authentication) |
48784878| `none` | No API key. The session authenticates another way, such as a claude.ai login, a bearer token, or a cloud provider |
48794879 
48804880Agent 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.
from line 4889
48894889 
48904890> [!WARNING]
48914891>
4892> 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](/docs/en/model-config.md#extended-context), 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]`.
4892> 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](https://code.claude.com/docs/en/model-config.md#extended-context), 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]`.
48934893 
48944894### `SlashCommand`
48954895 
from line 4905
49054905};
49064906```
49074907 
4908`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](/docs/en/skills.md#resolve-skills-that-share-a-name). Requires Agent SDK v0.3.277 or later.
4908`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](https://code.claude.com/docs/en/skills.md#resolve-skills-that-share-a-name). Requires Agent SDK v0.3.277 or later.
49094909 
49104910### `ModelInfo`
49114911 
from line 4953
49534953| :- | :- | :- |
49544954| `name` | `string` | Agent type identifier (for example, `"Explore"`, `"general-purpose"`) |
49554955| `description` | `string` | Description of when to use this agent |
4956| `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](/docs/en/sub-agents.md#choose-a-model) |
4956| `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](https://code.claude.com/docs/en/sub-agents.md#choose-a-model) |
49574957 
49584958### `McpServerProvenance`
49594959 
from line 4974
49744974`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`:
49754975 
49764976* **`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.
4977* **`plugin`**: a server a [plugin](/docs/en/agent-sdk/plugins.md) provides. Its `name` is the scoped `plugin:<plugin-name>:<server-name>` form described under [plugin-provided MCP servers](/docs/en/mcp.md#plugin-provided-mcp-servers).
4978* **A configuration scope**: `user`, `project`, `local`, `dynamic`, `managed`, `enterprise`, `claudeai`, or `agent`. A `.mcp.json` server reports `project`, and [MCP installation scopes](/docs/en/mcp.md#mcp-installation-scopes) defines `local`, `project`, and `user`. Servers your application passes in the [`mcpServers` option](#options), other than in-process SDK servers, report `dynamic`.
4977* **`plugin`**: a server a [plugin](https://code.claude.com/docs/en/agent-sdk/plugins.md) provides. Its `name` is the scoped `plugin:<plugin-name>:<server-name>` form described under [plugin-provided MCP servers](https://code.claude.com/docs/en/mcp.md#plugin-provided-mcp-servers).
4978* **A configuration scope**: `user`, `project`, `local`, `dynamic`, `managed`, `enterprise`, `claudeai`, or `agent`. A `.mcp.json` server reports `project`, and [MCP installation scopes](https://code.claude.com/docs/en/mcp.md#mcp-installation-scopes) defines `local`, `project`, and `user`. Servers your application passes in the [`mcpServers` option](#options), other than in-process SDK servers, report `dynamic`.
49794979 
49804980Base 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.
49814981 
from line 5045
50455045 
50465046### `ModelUsage`
50475047 
5048Per-model usage statistics returned in result messages. The `costUSD` value is a client-side estimate. See [Track cost and usage](/docs/en/agent-sdk/cost-tracking.md) for billing caveats.
5048Per-model usage statistics returned in result messages. The `costUSD` value is a client-side estimate. See [Track cost and usage](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md) for billing caveats.
50495049 
50505050```typescript theme={null}
50515051type ModelUsage = {
from line 5070
50705070 
50715071`provider` names the API backend that served the model, such as `firstParty`, `bedrock`, `vertex`, `foundry`, `anthropicAws`, `mantle`, or `gateway`.
50725072 
5073`costBasis` names the price table that priced the model's latest request: `list` for list price, `managed` for a [`modelPricing`](/docs/en/settings-reference#modelpricing) table, or `unknown` when neither matched the model ID. The field requires Claude Code v2.1.246 or later.
5073`costBasis` names the price table that priced the model's latest request: `list` for list price, `managed` for a [`modelPricing`](https://code.claude.com/docs/en/settings-reference#modelpricing) table, or `unknown` when neither matched the model ID. The field requires Claude Code v2.1.246 or later.
50745074 
50755075### `ConfigScope`
50765076 
from line 5120
51205120 
51215121* **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.
51225122* **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.
5123* **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](/docs/en/agent-sdk/cost-tracking.md#read-output-tokens-from-the-result-message) describes. On the result message, `thinking_tokens` reads `0` when the model or provider reports no breakdown.
5123* **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](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md#read-output-tokens-from-the-result-message) describes. On the result message, `thinking_tokens` reads `0` when the model or provider reports no breakdown.
51245124* **`null` cases**: `output_tokens_details` itself is `null` on assistant messages Claude Code synthesizes, such as API-error messages.
51255125 
51265126Whether `Usage` carries `fallback_credit` depends on your installed `@anthropic-ai/sdk`, which added it in 0.115.0.
from line 5127
51275127 
51285128### `CallToolResult`
51295129 
5130MCP 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](/docs/en/agent-sdk/custom-tools.md#return-structured-data).
5130MCP 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](https://code.claude.com/docs/en/agent-sdk/custom-tools.md#return-structured-data).
51315131 
51325132```typescript theme={null}
51335133type CallToolResult = {
from line 5156
51565156};
51575157```
51585158 
5159Claude Code drops a block whose `uri` or `name` isn't a string, and leaves out an optional field whose value isn't of the listed type.
5160 
5161| Field | Type | Description |
5162| :- | :- | :- |
5163| `uri` | `string` | URI of the resource, as the server returned it |
5164| `name` | `string` | Name the server gave the resource |
5165| `title` | `string \| undefined` | Display title, when the server set one |
5166| `description` | `string \| undefined` | Description, when the server set one |
5167| `mimeType` | `string \| undefined` | MIME type, when the server set one |
5168| `size` | `number \| undefined` | Size in bytes, when the server set one |
5169| `annotations` | `Record<string, unknown> \| undefined` | The block's MCP annotations object, when the server set one |
5170 
5171### `ThinkingConfig`
5172 
5173Controls Claude's thinking/reasoning behavior. Takes precedence over the deprecated `maxThinkingTokens`.
5174 
5175```typescript theme={null}
5176type ThinkingDisplay = "summarized" | "omitted";
5177 
5178type ThinkingConfig =
5179 | { type: "adaptive"; display?: ThinkingDisplay } // The model determines when and how much to reason (Opus 4.6+)
5180 | { type: "enabled"; budgetTokens?: number; display?: ThinkingDisplay } // Fixed thinking token budget
5181 | { type: "disabled" }; // No extended thinking
5182```
5183 
5184The 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"`.
5185 
5186### `SpawnedProcess`
5187 
5188Interface for custom process spawning (used with `spawnClaudeCodeProcess` option). `ChildProcess` already satisfies this interface.
5189 
5190```typescript theme={null}
5191interface SpawnedProcess {
5192 stdin: Writable;
5193 stdout: Readable;
5194 readonly killed: boolean;
5195 readonly exitCode: number | null;
5196 kill(signal: NodeJS.Signals): boolean;
5197 on(
5198 event: "exit",
5199 listener: (code: number | null, signal: NodeJS.Signals | null) => void
5200 ): void;
5201 on(event: "error", listener: (error: Error) => void): void;
5202 once(
5203 event: "exit",
5204 listener: (code: number | null, signal: NodeJS.Signals | null) => void
5205 ): void;
5206 once(event: "error", listener: (error: Error) => void): void;
5207 off(
5208 event: "exit",
5209 listener: (code: number | null, signal: NodeJS.Signals | null) => void
5210 ): void;
5211 off(event: "error", listener: (error: Error) => void): void;
5212}
5213```
5214 
5215### `SpawnOptions`
5216 
5217Options passed to the custom spawn function.
5218 
5219```typescript theme={null}
5220interface SpawnOptions {
5221 command: string;
5222 args: string[];
5223 cwd?: string;
5224 env: Record<string, string | undefined>;
5225 signal: AbortSignal;
5226}
5227```
5228 
5229> [!NOTE]
5230>
5231> 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.
5232>
5233> This signal does not fire the instant [`Options.abortController`](#options) 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.
5234 
5235### `McpSetServersResult`
5236 
5237Result of a `setMcpServers()` operation.
5238 
5239```typescript theme={null}
5240type McpSetServersResult = {
5241 added: string[];
5242 removed: string[];
5243 errors: Record<string, string>;
5244};
5245```
5246 
5247When you call `setMcpServers()`, Claude Code applies these rules:
5248 
5249* **Servers the call doesn't name**: outside a [cloud session](/docs/en/claude-code-on-the-web.md), 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`](#options) option, servers from settings files, and plugin-provided servers.
5250* **Servers the call names**: Claude Code replaces a stdio, HTTP, or SSE server that an earlier `setMcpServers()` call added only when its config differs from the one you passed. An in-process SDK server already registered under that name stays as it is, so to swap one, leave it o
5159Claude Code drops a block whose `uri` or `name` isn't a s

agent-sdk/typescript-v2-preview Changed · +5 / -5 lines

from line 6
66>
77> The V2 session API is no longer supported. TypeScript Agent SDK 0.3.142 removes `unstable_v2_createSession`, `unstable_v2_resumeSession`, `unstable_v2_prompt`, and the `SDKSession` and `SDKSessionOptions` types.
88>
9> To migrate, use the [`query()` API](/docs/en/agent-sdk/typescript) and the [session options](/docs/en/agent-sdk/sessions.md) it accepts. Pass an `AsyncIterable<SDKUserMessage>` for multi-turn conversations, or `options.resume` to continue a saved session. This page is kept for reference if you maintain code on Agent SDK 0.2.x or earlier.
9> To migrate, use the [`query()` API](https://code.claude.com/docs/en/agent-sdk/typescript) and the [session options](https://code.claude.com/docs/en/agent-sdk/sessions.md) it accepts. Pass an `AsyncIterable<SDKUserMessage>` for multi-turn conversations, or `options.resume` to continue a saved session. This page is kept for reference if you maintain code on Agent SDK 0.2.x or earlier.
1010 
1111V2 was an experimental session API that removed the need for async generators and yield coordination. Instead of managing generator state across turns, each turn was a separate `send()`/`stream()` cycle. The API surface reduced to creating a session, sending a message, and streaming the response:
1212 
from line 24
2424 
2525> [!NOTE]
2626>
27> The SDK bundles a native Claude Code binary for your platform as an optional dependency, so most installs need no separate Claude Code install. See the [quickstart's install note](/docs/en/agent-sdk/quickstart.md) for the installs that need one.
27> The SDK bundles a native Claude Code binary for your platform as an optional dependency, so most installs need no separate Claude Code install. See the [quickstart's install note](https://code.claude.com/docs/en/agent-sdk/quickstart.md) for the installs that need one.
2828 
2929## Quick start
3030 
from line 380
380380 
381381## Feature availability
382382 
383The V2 session API does not support every V1 feature. The following require the [V1 SDK](/docs/en/agent-sdk/typescript.md):
383The V2 session API does not support every V1 feature. The following require the [V1 SDK](https://code.claude.com/docs/en/agent-sdk/typescript.md):
384384 
385385* Session forking (`forkSession` option)
386386* Some advanced streaming input patterns
from line 387
387387 
388388## See also
389389 
390* [TypeScript SDK reference (V1)](/docs/en/agent-sdk/typescript.md) - Full V1 SDK documentation
391* [SDK overview](/docs/en/agent-sdk/overview.md) - General SDK concepts
390* [TypeScript SDK reference (V1)](https://code.claude.com/docs/en/agent-sdk/typescript.md) - Full V1 SDK documentation
391* [SDK overview](https://code.claude.com/docs/en/agent-sdk/overview.md) - General SDK concepts
392392* [V2 examples on GitHub](https://github.com/anthropics/claude-agent-sdk-demos/tree/main/hello-world-v2) - Working code examples
393393 

agent-sdk/user-input Changed · +20 / -20 lines

from line 8
88 
99For clarifying questions, Claude generates the questions and options. Your role is to present them to users and return their selections. You can't add your own questions to this flow; if you need to ask users something yourself, do that separately in your application logic.
1010 
11The callback can stay pending indefinitely. Execution remains paused until your callback returns. If a user might take longer to respond than your process can reasonably stay running, register a [`PreToolUse` hook](/docs/en/agent-sdk/hooks) that returns the [`defer` decision](/docs/en/hooks#defer-a-tool-call-for-later) instead of waiting in the callback, so the process can exit and resume later from the persisted session.
11The callback can stay pending indefinitely. Execution remains paused until your callback returns. If a user might take longer to respond than your process can reasonably stay running, register a [`PreToolUse` hook](https://code.claude.com/docs/en/agent-sdk/hooks) that returns the [`defer` decision](https://code.claude.com/docs/en/hooks#defer-a-tool-call-for-later) instead of waiting in the callback, so the process can exit and resume later from the persisted session.
1212 
1313This guide shows you how to detect each type of request and respond appropriately.
1414 
from line 42
4242 
4343The callback fires in two cases:
4444 
451. **Tool needs approval**: Claude wants to use a tool that isn't auto-approved by a [permission rule](/docs/en/agent-sdk/permissions.md) or permission mode. Check `tool_name` for the tool (e.g., `"Bash"`, `"Write"`).
451. **Tool needs approval**: Claude wants to use a tool that isn't auto-approved by a [permission rule](https://code.claude.com/docs/en/agent-sdk/permissions.md) or permission mode. Check `tool_name` for the tool (e.g., `"Bash"`, `"Write"`).
46462. **Claude asks a question**: Claude calls the `AskUserQuestion` tool. Check if `tool_name == "AskUserQuestion"` to handle it differently. If you specify a `tools` array, include `AskUserQuestion` for this to work. See [Handle clarifying questions](#handle-clarifying-questions) for details.
4747 
4848> [!WARNING]
4949>
50> **The callback never fires for auto-approved tools.** Any approval earlier in the [permission evaluation flow](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated), an allow rule or a mode like `acceptEdits` or `bypassPermissions`, resolves the call before `canUseTool` is consulted. If you list a tool bare in `allowed_tools`, a `canUseTool` check for that tool runs only when the [evaluation flow](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) routes the call back to a prompt, such as an ask rule or `plan` mode. For logic that must apply to every tool call, use a [`PreToolUse` hook](/docs/en/agent-sdk/hooks), which executes before the rest of the flow and can allow, deny, or modify requests.
50> **The callback never fires for auto-approved tools.** Any approval earlier in the [permission evaluation flow](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated), an allow rule or a mode like `acceptEdits` or `bypassPermissions`, resolves the call before `canUseTool` is consulted. If you list a tool bare in `allowed_tools`, a `canUseTool` check for that tool runs only when the [evaluation flow](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) routes the call back to a prompt, such as an ask rule or `plan` mode. For logic that must apply to every tool call, use a [`PreToolUse` hook](https://code.claude.com/docs/en/agent-sdk/hooks), which executes before the rest of the flow and can allow, deny, or modify requests.
5151>
52> An allow rule doesn't pre-approve the [actions no mode auto-approves](/docs/en/permission-modes.md#actions-no-mode-auto-approves); see [How permissions are evaluated](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) for which of them reach the callback and what happens in `dontAsk` and `auto` mode.
52> An allow rule doesn't pre-approve the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves); see [How permissions are evaluated](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) for which of them reach the callback and what happens in `dontAsk` and `auto` mode.
5353 
54You can also use the [`PermissionRequest` hook](/docs/en/agent-sdk/hooks#available-hooks) to send external notifications (Slack, email, push) when Claude is waiting for approval.
54You can also use the [`PermissionRequest` hook](https://code.claude.com/docs/en/agent-sdk/hooks#available-hooks) to send external notifications (Slack, email, push) when Claude is waiting for approval.
5555 
5656## Handle tool approval requests
5757 
58Once you've passed a `canUseTool` callback in your query options, it fires when Claude wants to use a tool that nothing earlier in the permission flow has approved. In some configurations, such as `dontAsk` mode, Claude Code doesn't call it; the last step of [How permissions are evaluated](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) lists them and says what happens to the call instead.
58Once you've passed a `canUseTool` callback in your query options, it fires when Claude wants to use a tool that nothing earlier in the permission flow has approved. In some configurations, such as `dontAsk` mode, Claude Code doesn't call it; the last step of [How permissions are evaluated](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) lists them and says what happens to the call instead.
5959 
6060Your callback receives three arguments:
6161 
from line 63
6363| - | - |
6464| `toolName` | The name of the tool Claude wants to use (for example, `"Bash"`, `"Write"`, `"Edit"`) |
6565| `input` | The parameters Claude is passing to the tool. Contents vary by tool. |
66| `options` (TS) / `context` (Python) | Additional context including optional `suggestions` (proposed `PermissionUpdate` entries to avoid re-prompting) and a cancellation signal. In TypeScript, `signal` is an `AbortSignal`; in Python, the signal field is reserved for future use. See [`ToolPermissionContext`](/docs/en/agent-sdk/python#toolpermissioncontext) for Python. |
66| `options` (TS) / `context` (Python) | Additional context including optional `suggestions` (proposed `PermissionUpdate` entries to avoid re-prompting) and a cancellation signal. In TypeScript, `signal` is an `AbortSignal`; in Python, the signal field is reserved for future use. See [`ToolPermissionContext`](https://code.claude.com/docs/en/agent-sdk/python#toolpermissioncontext) for Python. |
6767 
6868The `input` object contains tool-specific parameters. Common examples:
6969 
from line 74
7474| `Edit` | `file_path`, `old_string`, `new_string` |
7575| `Read` | `file_path`, `offset`, `limit` |
7676 
77See the SDK reference for complete input schemas: [Python](/docs/en/agent-sdk/python.md#tool-input%2Foutput-types) | [TypeScript](/docs/en/agent-sdk/typescript.md#tool-input-types).
77See the SDK reference for complete input schemas: [Python](https://code.claude.com/docs/en/agent-sdk/python.md#tool-input%2Foutput-types) | [TypeScript](https://code.claude.com/docs/en/agent-sdk/typescript.md#tool-input-types).
7878 
7979You can display this information to the user so they can decide whether to allow or reject the action, then return the appropriate response.
8080 
from line 217
217217* **Approve and remember**: echo a suggested permission rule back so matching calls skip the prompt next time
218218* **Reject**: block the tool and tell Claude why
219219* **Suggest alternative**: block but guide Claude toward what the user wants instead
220* **Redirect entirely**: use [streaming input](/docs/en/agent-sdk/streaming-vs-single-mode.md) to send Claude a completely new instruction
220* **Redirect entirely**: use [streaming input](https://code.claude.com/docs/en/agent-sdk/streaming-vs-single-mode.md) to send Claude a completely new instruction
221221 
222222The `ask_user` and `askUser` helpers in the following snippets stand in for your application's own prompt UI.
223223 
from line 279
279279 
280280**Approve and remember**
281281 
282The user approves and doesn't want to be asked again for this kind of call. The third callback argument carries `suggestions`, an array of ready-made [`PermissionUpdate`](/docs/en/agent-sdk/typescript#permissionupdate) entries. Echo one back in `updatedPermissions` to apply it. A suggestion with the `localSettings` destination writes the rule to `.claude/settings.local.json` so future sessions skip the prompt for matching calls.
282The user approves and doesn't want to be asked again for this kind of call. The third callback argument carries `suggestions`, an array of ready-made [`PermissionUpdate`](https://code.claude.com/docs/en/agent-sdk/typescript#permissionupdate) entries. Echo one back in `updatedPermissions` to apply it. A suggestion with the `localSettings` destination writes the rule to `.claude/settings.local.json` so future sessions skip the prompt for matching calls.
283283 
284In TypeScript, skip the always-allow choice for a request whose options carry [`suppressAlwaysAllowRule: true`](/docs/en/agent-sdk/typescript#canusetool). The hint requires Agent SDK v0.3.268 or later, and the Python `context` doesn't carry it.
284In TypeScript, skip the always-allow choice for a request whose options carry [`suppressAlwaysAllowRule: true`](https://code.claude.com/docs/en/agent-sdk/typescript#canusetool). The hint requires Agent SDK v0.3.268 or later, and the Python `context` doesn't carry it.
285285 
286286The Python example requires `claude-agent-sdk` 0.1.80 or later.
287287 
from line 379
379379 
380380**Redirect entirely**
381381 
382For a complete change of direction (not just a nudge), use [streaming input](/docs/en/agent-sdk/streaming-vs-single-mode.md) to send Claude a new instruction directly. This bypasses the current tool request and gives Claude entirely new instructions to follow.
382For a complete change of direction (not just a nudge), use [streaming input](https://code.claude.com/docs/en/agent-sdk/streaming-vs-single-mode.md) to send Claude a new instruction directly. This bypasses the current tool request and gives Claude entirely new instructions to follow.
383383 
384384## Handle clarifying questions
385385 
from line 387
387387 
388388> [!TIP]
389389>
390> Clarifying questions are especially common in [`plan` mode](/docs/en/agent-sdk/permissions#plan-mode-plan), where Claude explores the codebase and asks questions before proposing a plan. This makes plan mode ideal for interactive workflows where you want Claude to gather requirements before making changes.
390> Clarifying questions are especially common in [`plan` mode](https://code.claude.com/docs/en/agent-sdk/permissions#plan-mode-plan), where Claude explores the codebase and asks questions before proposing a plan. This makes plan mode ideal for interactive workflows where you want Claude to gather requirements before making changes.
391391 
392392The following steps show how to handle clarifying questions:
393393 
from line 800
800800 
801801### Streaming input
802802 
803Use [streaming input](/docs/en/agent-sdk/streaming-vs-single-mode.md) when you need to:
803Use [streaming input](https://code.claude.com/docs/en/agent-sdk/streaming-vs-single-mode.md) when you need to:
804804 
805805* **Interrupt the agent mid-task**: send a cancel signal or change direction while Claude is working
806806* **Provide additional context**: add information Claude needs without waiting for it to ask
from line 810
810810 
811811### Custom tools
812812 
813Use [custom tools](/docs/en/agent-sdk/custom-tools.md) when you need to:
813Use [custom tools](https://code.claude.com/docs/en/agent-sdk/custom-tools.md) when you need to:
814814 
815815* **Collect structured input**: build forms, wizards, or multi-step workflows that go beyond `AskUserQuestion`'s multiple-choice format
816816* **Integrate external approval systems**: connect to existing ticketing, workflow, or approval platforms
from line 820
820820 
821821## Related resources
822822 
823* [Configure permissions](/docs/en/agent-sdk/permissions.md): set up permission modes and rules
824* [Control execution with hooks](/docs/en/agent-sdk/hooks.md): run custom code at key points in the agent lifecycle
825* [TypeScript SDK reference](/docs/en/agent-sdk/typescript.md#canusetool): full canUseTool API documentation
823* [Configure permissions](https://code.claude.com/docs/en/agent-sdk/permissions.md): set up permission modes and rules
824* [Control execution with hooks](https://code.claude.com/docs/en/agent-sdk/hooks.md): run custom code at key points in the agent lifecycle
825* [TypeScript SDK reference](https://code.claude.com/docs/en/agent-sdk/typescript.md#canusetool): full canUseTool API documentation
826826 

agent-teams Changed · +63 / -63 lines

from line 4
44 
55> [!WARNING]
66>
7> Agent teams are experimental and disabled by default. Enable them by setting `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` in your [settings.json](/docs/en/settings.md) or environment. Without that variable, no team is set up at session start, no team directories are written, and Claude does not spawn or propose teammates. Agent teams have [known limitations](#limitations) around session resumption, task coordination, and shutdown behavior.
7> Agent teams are experimental and disabled by default. Enable them by setting `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` in your [settings.json](https://code.claude.com/docs/en/settings.md) or environment. Without that variable, no team is set up at session start, no team directories are written, and Claude does not spawn or propose teammates. Agent teams have [known limitations](#limitations) around session resumption, task coordination, and shutdown behavior.
88 
99Agent teams let you coordinate multiple Claude Code instances working together. One session acts as the team lead, coordinating work, assigning tasks, and synthesizing results. Teammates work independently, each in its own context window, and communicate directly with each other. You can also talk to any teammate directly without going through the lead.
1010 
11Before you set up a team, check whether a lighter option does the job. [Subagents](/docs/en/sub-agents.md) work within a single session, and with [cross-session messaging](/docs/en/cross-session-messaging.md) Claude can pass findings between the sessions you run yourself.
11Before you set up a team, check whether a lighter option does the job. [Subagents](https://code.claude.com/docs/en/sub-agents.md) work within a single session, and with [cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md) Claude can pass findings between the sessions you run yourself.
1212 
1313## When to use agent teams
1414 
from line 19
1919* **Debugging with competing hypotheses**: teammates test different theories in parallel and converge on the answer faster
2020* **Cross-layer coordination**: changes that span frontend, backend, and tests, each owned by a different teammate
2121 
22Agent teams add coordination overhead and use significantly more tokens than a single session. They work best when teammates can operate independently. For sequential tasks, same-file edits, or work with many dependencies, a single session or [subagents](/docs/en/sub-agents.md) are more effective.
22Agent teams add coordination overhead and use significantly more tokens than a single session. They work best when teammates can operate independently. For sequential tasks, same-file edits, or work with many dependencies, a single session or [subagents](https://code.claude.com/docs/en/sub-agents.md) are more effective.
2323 
2424### Compare with subagents
2525 
26Both agent teams and [subagents](/docs/en/sub-agents.md) let you parallelize work, but they operate differently. For separate sessions that pass messages to each other without a team, see [cross-session messaging](/docs/en/cross-session-messaging.md).
26Both agent teams and [subagents](https://code.claude.com/docs/en/sub-agents.md) let you parallelize work, but they operate differently. For separate sessions that pass messages to each other without a team, see [cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md).
2727 
2828![Diagram comparing subagent and agent team architectures. Subagents are spawned by the main agent, do work, and report results back. Agent teams coordinate through a shared task list, with teammates communicating directly with each other.](https://mintcdn.com/claude-code/nsvRFSDNfpSU5nT7/images/subagents-vs-agent-teams-light.png?fit=max\&auto=format\&n=nsvRFSDNfpSU5nT7\&q=85\&s=2f8db9b4f3705dd3ab931fbe2d96e42a)
2929 
from line 32
3232| | Subagents | Agent teams |
3333| :- | :- | :- |
3434| **Context** | Own context window; results return to the caller | Own context window; fully independent |
35| **Communication** | Return a result to the caller. Subagents that Claude [named](/docs/en/sub-agents.md#subagent-names) when it spawned them can also [message each other](/docs/en/sub-agents.md#what-loads-at-startup) | Teammates message each other directly |
36| **Coordination** | Main agent manages all work | Self-coordination through messages, plus a shared task list for [agents that have the Task tools](/docs/en/tools-reference.md#task-tool-availability) |
35| **Communication** | Return a result to the caller. Subagents that Claude [named](https://code.claude.com/docs/en/sub-agents.md#subagent-names) when it spawned them can also [message each other](https://code.claude.com/docs/en/sub-agents.md#what-loads-at-startup) | Teammates message each other directly |
36| **Coordination** | Main agent manages all work | Self-coordination through messages, plus a shared task list for [agents that have the Task tools](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability) |
3737| **Best for** | Focused tasks where only the result matters | Complex work requiring discussion and collaboration |
3838| **Token cost** | Lower: results summarized back to main context | Higher: each teammate is a separate Claude instance |
3939 
from line 41
4141 
4242## Enable agent teams
4343 
44Agent teams are disabled by default. Enable them by setting the `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` environment variable to `1`, either in your shell environment or through [settings.json](/docs/en/settings.md):
44Agent teams are disabled by default. Enable them by setting the `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` environment variable to `1`, either in your shell environment or through [settings.json](https://code.claude.com/docs/en/settings.md):
4545 
4646```json settings.json theme={null}
4747{
from line 51
5151}
5252```
5353 
54Enabling agent teams also changes ordinary delegation. Claude may [name a subagent](/docs/en/sub-agents.md#subagent-names) on its own, and while agent teams are enabled, a subagent that Claude names launches as a teammate, so teams can form even when you didn't ask for one. For more, see [How Claude starts agent teams](#how-claude-starts-agent-teams); to turn the behavior off, see [Claude spawns teammates instead of subagents](#claude-spawns-teammates-instead-of-subagents).
54Enabling agent teams also changes ordinary delegation. Claude may [name a subagent](https://code.claude.com/docs/en/sub-agents.md#subagent-names) on its own, and while agent teams are enabled, a subagent that Claude names launches as a teammate, so teams can form even when you didn't ask for one. For more, see [How Claude starts agent teams](#how-claude-starts-agent-teams); to turn the behavior off, see [Claude spawns teammates instead of subagents](#claude-spawns-teammates-instead-of-subagents).
5555 
56Spawning teammates also requires an interactive session. In [non-interactive mode](/docs/en/headless.md) with the `-p` flag, including Agent SDK sessions, Claude doesn't spawn teammates, and a subagent that Claude names runs as an ordinary [subagent](/docs/en/sub-agents.md) even with agent teams enabled.
56Spawning teammates also requires an interactive session. In [non-interactive mode](https://code.claude.com/docs/en/headless.md) with the `-p` flag, including Agent SDK sessions, Claude doesn't spawn teammates, and a subagent that Claude names runs as an ordinary [subagent](https://code.claude.com/docs/en/sub-agents.md) even with agent teams enabled.
5757 
5858## Start your first agent team
5959 
from line 67
6767one on UX, one on technical architecture, one playing devil's advocate.
6868```
6969 
70From there, Claude populates a [shared task list](/docs/en/interactive-mode.md#task-list) in a [session that has the Task tools](/docs/en/tools-reference.md#task-tool-availability), spawns teammates for each perspective, has them explore the problem, and synthesizes findings when finished.
70From there, Claude populates a [shared task list](https://code.claude.com/docs/en/interactive-mode.md#task-list) in a [session that has the Task tools](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability), spawns teammates for each perspective, has them explore the problem, and synthesizes findings when finished.
7171 
72Claude may sometimes use [subagents](/docs/en/sub-agents.md) instead of creating a team. Subagents appear in the same agent panel as teammates, so the panel alone doesn't confirm a team formed. If Claude spawned subagents instead, ask again and explicitly request an agent team.
72Claude may sometimes use [subagents](https://code.claude.com/docs/en/sub-agents.md) instead of creating a team. Subagents appear in the same agent panel as teammates, so the panel alone doesn't confirm a team formed. If Claude spawned subagents instead, ask again and explicitly request an agent team.
7373 
7474The lead's terminal lists teammates in the agent panel below the prompt input. From the panel:
7575 
from line 102
102102 
103103Set `"iterm2"` to use iTerm2 native split panes explicitly. This mode requires the [`it2` CLI](https://github.com/mkusaka/it2) and shows an error with the install command if `it2` is missing. The setup prompt that offers to install `it2` or switch to tmux appears under `"auto"` or `"tmux"` when your terminal is iTerm2 and tmux is available as a fallback.
104104 
105To override the default, set [`teammateMode`](/docs/en/settings-reference#teammatemode) in `~/.claude/settings.json`:
105To override the default, set [`teammateMode`](https://code.claude.com/docs/en/settings-reference#teammatemode) in `~/.claude/settings.json`:
106106 
107107```json theme={null}
108108{
from line 136
136136 
1371371. The model your spawn prompt names for that teammate.
1381382. For a teammate spawned from a [subagent definition](#use-subagent-definitions-for-teammates), the definition's `model`, where `inherit` selects the lead's model.
1393. [`CLAUDE_CODE_SUBAGENT_MODEL`](/docs/en/model-config#environment-variables), when it's set to anything other than `inherit`.
1393. [`CLAUDE_CODE_SUBAGENT_MODEL`](https://code.claude.com/docs/en/model-config#environment-variables), when it's set to anything other than `inherit`.
1401404. The lead's current model.
141141 
142If an installed [mod](/docs/en/plugins/mods/overview.md) sets a model in its [`agent.spawn`](/docs/en/plugins/mods/reference#subagents) hook, Claude Code uses that model in place of the first source.
142If an installed [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) sets a model in its [`agent.spawn`](https://code.claude.com/docs/en/plugins/mods/reference#subagents) hook, Claude Code uses that model in place of the first source.
143143 
144If you set [`CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1`](/docs/en/sub-agents#run-every-subagent-on-one-model), the first two sources don't apply. Claude Code picks every teammate's model from `CLAUDE_CODE_SUBAGENT_MODEL` when it's set to anything other than `inherit`, and from the lead's current model otherwise. Requires Claude Code v2.1.257 or later.
144If you set [`CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1`](https://code.claude.com/docs/en/sub-agents#run-every-subagent-on-one-model), the first two sources don't apply. Claude Code picks every teammate's model from `CLAUDE_CODE_SUBAGENT_MODEL` when it's set to anything other than `inherit`, and from the lead's current model otherwise. Requires Claude Code v2.1.257 or later.
145145 
146146Before v2.1.251, `CLAUDE_CODE_SUBAGENT_MODEL` came first in this order.
147147 
from line 149
149149>
150150> `teammateDefaultModel` was removed in v2.1.234; Claude Code ignores a leftover value. Name the model in your prompt instead.
151151 
152Claude Code checks the model it selects for a teammate against your organization's [`availableModels`](/docs/en/model-config#restrict-model-selection) allowlist. When the allowlist blocks a value, Claude Code substitutes another model:
152Claude Code checks the model it selects for a teammate against your organization's [`availableModels`](https://code.claude.com/docs/en/model-config#restrict-model-selection) allowlist. When the allowlist blocks a value, Claude Code substitutes another model:
153153 
154* **Family alias such as `opus`**: On the Anthropic API and Claude Platform on AWS, Claude Code runs the teammate on the newest version of that family the allowlist permits. On providers with provider-specific model IDs, where the [substitution doesn't operate](/docs/en/model-config.md#restrict-model-selection), a blocked alias falls back like any other blocked value per the next bullet
154* **Family alias such as `opus`**: On the Anthropic API and Claude Platform on AWS, Claude Code runs the teammate on the newest version of that family the allowlist permits. On providers with provider-specific model IDs, where the [substitution doesn't operate](https://code.claude.com/docs/en/model-config.md#restrict-model-selection), a blocked alias falls back like any other blocked value per the next bullet
155155* **Any other blocked value, including a family alias on providers where the substitution doesn't operate, or one whose family has no permitted version**: Claude Code runs the teammate on the lead's model instead. If you set `CLAUDE_CODE_SUBAGENT_MODEL`, Claude Code tries that model first, under these same rules
156156 
157By default, teammates inherit the lead's [effort level](/docs/en/model-config.md#adjust-effort-level). In split-pane mode this applies from v2.1.186; earlier versions did not pass the lead's session effort to split-pane teammates.
157By default, teammates inherit the lead's [effort level](https://code.claude.com/docs/en/model-config.md#adjust-effort-level). In split-pane mode this applies from v2.1.186; earlier versions did not pass the lead's session effort to split-pane teammates.
158158 
159159### Have teammates plan before implementing
160160 
161For complex or risky tasks, you can have teammates plan before implementing. A teammate that Claude spawns while the lead is in [plan mode](/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) works in read-only plan mode until its plan is ready. Switch the lead into plan mode first, then ask for the teammate:
161For complex or risky tasks, you can have teammates plan before implementing. A teammate that Claude spawns while the lead is in [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) works in read-only plan mode until its plan is ready. Switch the lead into plan mode first, then ask for the teammate:
162162 
163163```text wrap theme={null}
164164Spawn an architect teammate to refactor the authentication module.
from line 166
166166 
167167When that teammate finishes planning, it sends a plan approval request to the lead. If you haven't changed that teammate's permission mode since it was spawned, Claude Code approves the plan as soon as the request arrives, without the lead reviewing it. The teammate's edits and commands still go through the permission prompts described in [Permissions](#permissions). Once approved, the teammate exits plan mode and begins implementation.
168168 
169If you put a running in-process teammate in plan mode by pressing [`Shift+Tab`](/docs/en/permission-modes#switch-permission-modes) while viewing its session, the lead reviews that run's plan instead of Claude Code approving it. You aren't asked to approve it; the lead approves it or sends it back for revision.
169If you put a running in-process teammate in plan mode by pressing [`Shift+Tab`](https://code.claude.com/docs/en/permission-modes#switch-permission-modes) while viewing its session, the lead reviews that run's plan instead of Claude Code approving it. You aren't asked to approve it; the lead approves it or sends it back for revision.
170170 
171171### Talk to teammates directly
172172 
from line 175
175175* **In-process mode**: use the up and down arrow keys in the agent panel to select a teammate, then press Enter to view its session and type to send it a message. Press `x` on a selected teammate to stop it. Press Ctrl+T to toggle the task list.
176176* **Split-pane mode**: click into a teammate's pane to interact with their session directly. Each teammate has a full view of their own terminal.
177177 
178While you're viewing an in-process teammate, plain text and [skills](/docs/en/skills.md) go to that teammate, and built-in commands go to the lead's session, with these safeguards:
178While you're viewing an in-process teammate, plain text and [skills](https://code.claude.com/docs/en/skills.md) go to that teammate, and built-in commands go to the lead's session, with these safeguards:
179179 
180180* `/compact`, `/clear`, and `/rewind` act on the lead's conversation, so Claude Code asks you to confirm before running one of them from this view.
181181* `/model` and `/fast` set the lead's model and fast mode, not the teammate's, so they don't run from this view. A notice tells you why.
from line 186
186186 
187187The shared task list coordinates work across the team. The lead creates tasks and teammates work through them. Tasks have three states: pending, in progress, and completed. Tasks can also depend on other tasks: a pending task with unresolved dependencies cannot be claimed until those dependencies are completed.
188188 
189Agents [without the Task tools](/docs/en/tools-reference.md#task-tool-availability) coordinate through messages instead of the shared task list.
189Agents [without the Task tools](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability) coordinate through messages instead of the shared task list.
190190 
191191The lead can assign tasks explicitly, or teammates can self-claim:
192192 
from line 209
209209 
210210### Enforce quality gates with hooks
211211 
212Use [hooks](/docs/en/hooks.md) to enforce rules when teammates finish work or tasks are created or completed:
212Use [hooks](https://code.claude.com/docs/en/hooks.md) to enforce rules when teammates finish work or tasks are created or completed:
213213 
214* [`TeammateIdle`](/docs/en/hooks#teammateidle): runs when a teammate is about to go idle. Exit with code 2 to send feedback and keep the teammate working.
215* [`TaskCreated`](/docs/en/hooks#taskcreated): runs when a task is being created. Exit with code 2 to prevent creation and send feedback.
216* [`TaskCompleted`](/docs/en/hooks#taskcompleted): runs when a task is being marked complete. Exit with code 2 to prevent completion and send feedback.
214* [`TeammateIdle`](https://code.claude.com/docs/en/hooks#teammateidle): runs when a teammate is about to go idle. Exit with code 2 to send feedback and keep the teammate working.
215* [`TaskCreated`](https://code.claude.com/docs/en/hooks#taskcreated): runs when a task is being created. Exit with code 2 to prevent creation and send feedback.
216* [`TaskCompleted`](https://code.claude.com/docs/en/hooks#taskcompleted): runs when a task is being marked complete. Exit with code 2 to prevent completion and send feedback.
217217 
218218## How agent teams work
219219 
from line 221
221221 
222222### How Claude starts agent teams
223223 
224To start a team, ask Claude for teammates. Claude launches a teammate when it calls the [Agent tool](/docs/en/tools-reference.md) with a [`name`](/docs/en/sub-agents#subagent-names) while agent teams are enabled, unless the call is a [fork](/docs/en/sub-agents.md#fork-the-current-conversation) or passes `isolation` on the call itself. Claude Code doesn't ask you to confirm the launch.
224To start a team, ask Claude for teammates. Claude launches a teammate when it calls the [Agent tool](https://code.claude.com/docs/en/tools-reference.md) with a [`name`](https://code.claude.com/docs/en/sub-agents#subagent-names) while agent teams are enabled, unless the call is a [fork](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation) or passes `isolation` on the call itself. Claude Code doesn't ask you to confirm the launch.
225225 
226226Claude also names ordinary subagents on its own so it can message them later. Those calls follow the same rule, so teams can form even when you didn't ask for one. If you want subagents instead, [turn agent teams off](#claude-spawns-teammates-instead-of-subagents).
227227 
from line 238
238238 
239239Each agent's mailbox is a JSON file at `~/.claude/teams/{team-name}/inboxes/{agent-name}.json`. Claude Code validates every entry when it reads a mailbox file. Entries that don't match the message format are reported as errors and removed from the file; the valid messages are still delivered.
240240 
241Claude Code reports a message as sent only when the write to the recipient's mailbox file succeeds, whether the message is plain text or a structured protocol message such as a plan approval or shutdown request. When the write fails, for example because the disk is full or the mailbox directory isn't writable, the sending agent receives an error and nothing is sent. See [Failed to write to a teammate's inbox](/docs/en/errors.md#failed-to-write-to-a-teammate-inbox) for the error messages and recovery steps.
241Claude Code reports a message as sent only when the write to the recipient's mailbox file succeeds, whether the message is plain text or a structured protocol message such as a plan approval or shutdown request. When the write fails, for example because the disk is full or the mailbox directory isn't writable, the sending agent receives an error and nothing is sent. See [Failed to write to a teammate's inbox](https://code.claude.com/docs/en/errors.md#failed-to-write-to-a-teammate-inbox) for the error messages and recovery steps.
242242 
243243Claude Code manages task dependencies automatically: when a teammate completes a task that other tasks depend on, it unblocks the dependent tasks without any action from you.
244244 
from line 245
245245Teams and tasks are stored locally under a session-derived name. The name is `session-` followed by the first eight characters of the session ID:
246246 
247247* **Team config**: `~/.claude/teams/{team-name}/config.json`. Claude Code removes the team config directory when the session ends.
248* **Task list**: `~/.claude/tasks/{team-name}/`. This directory stays on disk after the session ends. To change [how long Claude Code keeps it](/docs/en/claude-directory.md#cleaned-up-automatically), set [`cleanupPeriodDays`](/docs/en/settings-reference#cleanupperioddays).
248* **Task list**: `~/.claude/tasks/{team-name}/`. This directory stays on disk after the session ends. To change [how long Claude Code keeps it](https://code.claude.com/docs/en/claude-directory.md#cleaned-up-automatically), set [`cleanupPeriodDays`](https://code.claude.com/docs/en/settings-reference#cleanupperioddays).
249249 
250250Claude Code generates both of these automatically at session startup and updates them as teammates join, go idle, or leave.
251251 
from line 253
253253 
254254To define reusable teammate roles, use [subagent definitions](#use-subagent-definitions-for-teammates) instead.
255255 
256The team config contains a `members` array with each member's name and agent ID. The lead's entry always carries the agent type `team-lead`. A teammate's entry carries whatever agent type the lead named when spawning it, whether a [built-in type](/docs/en/sub-agents.md#built-in-subagents) or a [subagent definition](#use-subagent-definitions-for-teammates), and omits the field when the lead named none. Teammates can read this file to discover other team members.
256The team config contains a `members` array with each member's name and agent ID. The lead's entry always carries the agent type `team-lead`. A teammate's entry carries whatever agent type the lead named when spawning it, whether a [built-in type](https://code.claude.com/docs/en/sub-agents.md#built-in-subagents) or a [subagent definition](#use-subagent-definitions-for-teammates), and omits the field when the lead named none. Teammates can read this file to discover other team members.
257257 
258258There is no project-level equivalent of the team config. A file like `.claude/teams/teams.json` in your project directory is not recognized as configuration; Claude treats it as an ordinary file.
259259 
260260### Use subagent definitions for teammates
261261 
262When spawning a teammate in either display mode, you can reference a [subagent](/docs/en/sub-agents.md) type from the project, user, managed, or plugin [subagent scope](/docs/en/sub-agents.md#choose-the-subagent-scope). This lets you define a role once, such as a security-reviewer or test-runner, and reuse it both as a delegated subagent and as an agent team teammate.
262When spawning a teammate in either display mode, you can reference a [subagent](https://code.claude.com/docs/en/sub-agents.md) type from the project, user, managed, or plugin [subagent scope](https://code.claude.com/docs/en/sub-agents.md#choose-the-subagent-scope). This lets you define a role once, such as a security-reviewer or test-runner, and reuse it both as a delegated subagent and as an agent team teammate.
263263 
264264To use a subagent definition, name it when you ask Claude to spawn the teammate:
265265 
from line 269
269269 
270270Claude Code reads the subagent definition you named and applies these parts of it to the teammate. Where a part depends on the teammate's [display mode](#choose-a-display-mode), the entry says so:
271271 
272* **`tools`**: Claude Code limits the teammate to the tools in the definition's `tools` list. For an in-process teammate, Claude Code adds `SendMessage` to that list, and in a [session that has the Task tools](/docs/en/tools-reference.md#task-tool-availability) it adds `TaskCreate`, `TaskGet`, `TaskList`, and `TaskUpdate` too.
272* **`tools`**: Claude Code limits the teammate to the tools in the definition's `tools` list. For an in-process teammate, Claude Code adds `SendMessage` to that list, and in a [session that has the Task tools](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability) it adds `TaskCreate`, `TaskGet`, `TaskList`, and `TaskUpdate` too.
273273* **`model`**: Claude Code uses the definition's `model` in either display mode when your spawn prompt doesn't name one. See [how Claude Code picks a teammate's model](#specify-teammates-and-models).
274274* **`disallowedTools`**: for an in-process teammate, Claude Code removes the tools in the definition's `disallowedTools` from the teammate's set. `SendMessage` and the Task tools it adds stay available even when the list names them.
275* **`effort`**: for an in-process teammate, Claude Code applies the definition's [`effort`](/docs/en/sub-agents#supported-frontmatter-fields) under the [frontmatter effort rules](/docs/en/model-config.md#set-the-effort-level).
276* **`autoCompactWindow`**: for an in-process teammate, Claude Code applies the definition's [`autoCompactWindow`](/docs/en/sub-agents#supported-frontmatter-fields) under [that field's rules](/docs/en/sub-agents.md#subagent-auto-compact-window). A split-pane teammate ignores the field. Requires Claude Code v2.1.296 or later.
275* **`effort`**: for an in-process teammate, Claude Code applies the definition's [`effort`](https://code.claude.com/docs/en/sub-agents#supported-frontmatter-fields) under the [frontmatter effort rules](https://code.claude.com/docs/en/model-config.md#set-the-effort-level).
276* **`autoCompactWindow`**: for an in-process teammate, Claude Code applies the definition's [`autoCompactWindow`](https://code.claude.com/docs/en/sub-agents#supported-frontmatter-fields) under [that field's rules](https://code.claude.com/docs/en/sub-agents.md#subagent-auto-compact-window). A split-pane teammate ignores the field. Requires Claude Code v2.1.296 or later.
277277* **Body**: for an in-process teammate, Claude Code appends the definition's body to its default system prompt as additional instructions. For a split-pane teammate, Claude Code uses the body in place of its default system prompt.
278278* **`skills`**: Claude Code doesn't apply the definition's `skills` to a teammate in either display mode. The teammate loads skills from your project and user settings.
279* **`mcpServers`**: for a split-pane teammate, Claude Code applies the definition's `mcpServers` under the [rules for that field](/docs/en/sub-agents.md#scope-mcp-servers-to-a-subagent), which cover a session started with `--agent` as well. An in-process teammate ignores the field and loads MCP servers from your project and user settings.
279* **`mcpServers`**: for a split-pane teammate, Claude Code applies the definition's `mcpServers` under the [rules for that field](https://code.claude.com/docs/en/sub-agents.md#scope-mcp-servers-to-a-subagent), which cover a session started with `--agent` as well. An in-process teammate ignores the field and loads MCP servers from your project and user settings.
280280 
281281When Claude messages an in-process teammate that is no longer running, Claude Code brings it back in the same session, restores any conversation saved for it, and gives it the message as its next prompt. After you resume a session, teammates aren't brought back this way, per [the resume limitation](#limitations).
282282 
283For a teammate it brings back, Claude Code re-applies a definition that came from a project's `.claude/agents/` directory or an `--add-dir` directory only if you've [trusted the folder the agent file is in](/docs/en/permissions.md#what-runs-before-you-trust-a-folder). Trusting a parent folder doesn't count. Until then, the teammate comes back with none of the definition's tools or instructions, keeping only the tools Claude Code adds to every in-process teammate. See [the teammate's agent definition was not restored](/docs/en/errors.md#teammate-agent-definition-not-restored) for the notice text.
283For a teammate it brings back, Claude Code re-applies a definition that came from a project's `.claude/agents/` directory or an `--add-dir` directory only if you've [trusted the folder the agent file is in](https://code.claude.com/docs/en/permissions.md#what-runs-before-you-trust-a-folder). Trusting a parent folder doesn't count. Until then, the teammate comes back with none of the definition's tools or instructions, keeping only the tools Claude Code adds to every in-process teammate. See [the teammate's agent definition was not restored](https://code.claude.com/docs/en/errors.md#teammate-agent-definition-not-restored) for the notice text.
284284 
285285### Permissions
286286 
287Teammates start with the lead's permission mode, except [`dontAsk` mode](/docs/en/permission-modes#allow-only-pre-approved-tools-with-dontask-mode), which they don't inherit. If the lead runs with `--dangerously-skip-permissions`, all teammates do too. After spawning, you can change an individual teammate's permission mode, but you can't set per-teammate permission modes at spawn time.
287Teammates start with the lead's permission mode, except [`dontAsk` mode](https://code.claude.com/docs/en/permission-modes#allow-only-pre-approved-tools-with-dontask-mode), which they don't inherit. If the lead runs with `--dangerously-skip-permissions`, all teammates do too. After spawning, you can change an individual teammate's permission mode, but you can't set per-teammate permission modes at spawn time.
288288 
289An [in-process](#choose-a-display-mode) teammate runs under the lead's live allow and deny rules, so [`--disallowedTools`](/docs/en/cli-reference#cli-flags), `--tools`, and `--allowedTools` all apply to it. For a split-pane teammate, check each flag:
289An [in-process](#choose-a-display-mode) teammate runs under the lead's live allow and deny rules, so [`--disallowedTools`](https://code.claude.com/docs/en/cli-reference#cli-flags), `--tools`, and `--allowedTools` all apply to it. For a split-pane teammate, check each flag:
290290 
291291* **`--disallowedTools` and `--tools`**: the teammate starts with the lead's command-line deny rules and tool list. Requires Claude Code v2.1.309 or later.
292* **`--allowedTools`**: Claude Code doesn't pass this flag to a split-pane teammate, so an action you allowed with it alone isn't pre-approved there. To approve those actions ahead of time, put the rules under `permissions.allow` in [`--settings`](/docs/en/settings#change-a-setting-for-one-session) when you start the lead. For example, run `claude --settings '{"permissions":{"allow":["Bash(npm *)"]}}'` in your shell. The rules apply to the lead and each split-pane teammate for that session.
292* **`--allowedTools`**: Claude Code doesn't pass this flag to a split-pane teammate, so an action you allowed with it alone isn't pre-approved there. To approve those actions ahead of time, put the rules under `permissions.allow` in [`--settings`](https://code.claude.com/docs/en/settings#change-a-setting-for-one-session) when you start the lead. For example, run `claude --settings '{"permissions":{"allow":["Bash(npm *)"]}}'` in your shell. The rules apply to the lead and each split-pane teammate for that session.
293293 
294294Teammate permission prompts appear in the lead session, so approve them there yourself. You don't need to approve [a teammate's plan](#have-teammates-plan-before-implementing).
295295 
296296#### Messages between agents
297297 
298When one agent sends another a message over `SendMessage`, Claude Code tells the receiving agent the message came from another Claude session, not from you. A teammate can't approve a permission prompt or supply consent on your behalf, and a teammate that was denied an action can't relay it to another teammate to bypass the check. The same rules apply to a message that arrives from [one of your other Claude Code sessions](/docs/en/cross-session-messaging.md#how-a-session-treats-an-incoming-message), outside the team entirely.
298When one agent sends another a message over `SendMessage`, Claude Code tells the receiving agent the message came from another Claude session, not from you. A teammate can't approve a permission prompt or supply consent on your behalf, and a teammate that was denied an action can't relay it to another teammate to bypass the check. The same rules apply to a message that arrives from [one of your other Claude Code sessions](https://code.claude.com/docs/en/cross-session-messaging.md#how-a-session-treats-an-incoming-message), outside the team entirely.
299299 
300In [auto mode](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), the classifier applies two checks to messages between agents:
300In [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), the classifier applies two checks to messages between agents:
301301 
302302* It treats an approval claim relayed from another agent as untrusted input rather than confirmation from you.
303303* It reviews each message before Claude Code delivers it, whether a plain message or a structured protocol message such as a shutdown request or plan approval response. A message it blocks never reaches the recipient.
from line 304
304304 
305305### Context and communication
306306 
307Each teammate has its own context window. When spawned, a teammate loads the same project context as a regular session: CLAUDE.md, MCP servers, and skills. If you start the lead with [`--setting-sources`](/docs/en/cli-reference#cli-flags), teammates load from the same restricted list of sources. Before v2.1.281, [split-pane](#choose-a-display-mode) teammates loaded every settings source.
307Each teammate has its own context window. When spawned, a teammate loads the same project context as a regular session: CLAUDE.md, MCP servers, and skills. If you start the lead with [`--setting-sources`](https://code.claude.com/docs/en/cli-reference#cli-flags), teammates load from the same restricted list of sources. Before v2.1.281, [split-pane](#choose-a-display-mode) teammates loaded every settings source.
308308 
309309A teammate also receives the spawn prompt from the lead. The lead's conversation history does not carry over.
310310 
from line 312
312312 
313313* **Automatic message delivery**: when teammates send messages, they're delivered automatically to recipients. The lead doesn't need to poll for updates.
314314* **Idle notifications**: when a teammate finishes and stops, it automatically notifies the lead and includes its final answer in the notification. A teammate whose turn ends on an API error notifies the lead that it failed and includes the error text.
315* **Shared task list**: [agents that have the Task tools](/docs/en/tools-reference.md#task-tool-availability) can see task status and claim available work.
315* **Shared task list**: [agents that have the Task tools](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability) can see task status and claim available work.
316316* **Teammate messaging**: send a message to one specific teammate by name. To reach everyone, send one message per recipient.
317317 
318318The lead assigns every teammate a name when it spawns them, and any teammate can message any other by that name. To get predictable names you can reference in later prompts, tell the lead what to call each teammate in your spawn instruction.
from line 319
319319 
320320### Token usage
321321 
322Agent teams use significantly more tokens than a single session. Each teammate has its own context window, and token usage scales with the number of active teammates. For research, review, and new feature work, the extra tokens are usually worthwhile. For routine tasks, a single session is more cost-effective. See [agent team token costs](/docs/en/costs.md#agent-team-token-costs) for usage guidance.
322Agent teams use significantly more tokens than a single session. Each teammate has its own context window, and token usage scales with the number of active teammates. For research, review, and new feature work, the extra tokens are usually worthwhile. For routine tasks, a single session is more cost-effective. See [agent team token costs](https://code.claude.com/docs/en/costs.md#agent-team-token-costs) for usage guidance.
323323 
324An in-process teammate's requests fall outside the main conversation's [cache TTL bucket](/docs/en/prompt-caching.md#which-ttl-each-request-gets), so its cache holds for five minutes by default, including on a Claude subscription. To keep it for an hour, set [`subagentPromptCacheTtl`](/docs/en/settings-reference#subagentpromptcachettl) to `1h`. The API bills 1-hour cache writes at a higher rate.
324An in-process teammate's requests fall outside the main conversation's [cache TTL bucket](https://code.claude.com/docs/en/prompt-caching.md#which-ttl-each-request-gets), so its cache holds for five minutes by default, including on a Claude subscription. To keep it for an hour, set [`subagentPromptCacheTtl`](https://code.claude.com/docs/en/settings-reference#subagentpromptcachettl) to `1h`. The API bills 1-hour cache writes at a higher rate.
325325 
326326## Use case examples
327327 
from line 373
373373 
374374There's no hard limit on the number of teammates, but practical constraints apply:
375375 
376* **Token costs scale linearly**: each teammate has its own context window and consumes tokens independently. See [agent team token costs](/docs/en/costs.md#agent-team-token-costs) for details.
376* **Token costs scale linearly**: each teammate has its own context window and consumes tokens independently. See [agent team token costs](https://code.claude.com/docs/en/costs.md#agent-team-token-costs) for details.
377377* **Coordination overhead increases**: more teammates means more communication, task coordination, and potential for conflicts
378378* **Diminishing returns**: beyond a certain point, additional teammates don't speed up work proportionally
379379 
from line 444
444444 
445445Setting the variable to `0` in your user `settings.json` overrides a shell export. Other settings sources can still enable agent teams:
446446 
447* **Higher-precedence settings files**: project settings, local settings, and a `--settings` payload apply after user settings, so an `env` entry that sets the variable to `1` in any of them wins. See [Settings precedence](/docs/en/settings.md#settings-precedence).
448* **Managed settings**: [managed settings](/docs/en/server-managed-settings.md) apply after every other source. If your organization enables agent teams there, ask your administrator to change the managed value.
447* **Higher-precedence settings files**: project settings, local settings, and a `--settings` payload apply after user settings, so an `env` entry that sets the variable to `1` in any of them wins. See [Settings precedence](https://code.claude.com/docs/en/settings.md#settings-precedence).
448* **Managed settings**: [managed settings](https://code.claude.com/docs/en/server-managed-settings.md) apply after every other source. If your organization enables agent teams there, ask your administrator to change the managed value.
449449 
450After the change, Claude may still name subagents, and the name keeps working as a [`SendMessage` address](/docs/en/sub-agents#resume-subagents). Claude receives each subagent's result when it completes.
450After the change, Claude may still name subagents, and the name keeps working as a [`SendMessage` address](https://code.claude.com/docs/en/sub-agents#resume-subagents). Claude receives each subagent's result when it completes.
451451 
452452### Too many permission prompts
453453 
454Teammate permission requests bubble up to the lead, which can create friction. Pre-approve common operations in your [permission settings](/docs/en/permissions.md) before spawning teammates to reduce interruptions.
454Teammate permission requests bubble up to the lead, which can create friction. Pre-approve common operations in your [permission settings](https://code.claude.com/docs/en/permissions.md) before spawning teammates to reduce interruptions.
455455 
456456### Agents stopping early
457457 
from line 482
482482* **Shutdown can be slow**: teammates finish their current request or tool call before shutting down, which can take time.
483483* **One team per session**: a session has exactly one team, scoped to that session. You can't create additional named teams or share a team across sessions.
484484* **No nested teams**: teammates cannot spawn their own teammates. Only the lead can manage the team.
485* **No background subagents from in-process teammates**: an in-process teammate's own subagents run in the foreground, because a teammate's background work can't outlive the lead's process. Claude Code returns an error when a teammate spawns a subagent whose definition sets `background: true`. A teammate's `run_in_background: true` request also fails, either with an error or by running silently in the foreground. Subagents launched from the main conversation follow the [background default](/docs/en/sub-agents.md#run-subagents-in-foreground-or-background).
485* **No background subagents from in-process teammates**: an in-process teammate's own subagents run in the foreground, because a teammate's background work can't outlive the lead's process. Claude Code returns an error when a teammate spawns a subagent whose definition sets `background: true`. A teammate's `run_in_background: true` request also fails, either with an error or by running silently in the foreground. Subagents launched from the main conversation follow the [background default](https://code.claude.com/docs/en/sub-agents.md#run-subagents-in-foreground-or-background).
486486* **Lead is fixed**: the main session is the lead for its lifetime. You can't promote a teammate to lead or transfer leadership.
487487* **Permissions set at spawn**: teammates start with the permission mode described under [Permissions](#permissions). You can change an individual teammate's permission mode after spawning, but you can't set per-teammate permission modes at spawn time.
488488* **Split panes require tmux or iTerm2**: the default in-process mode works in any terminal. Split-pane mode isn't supported in VS Code's integrated terminal, Windows Terminal, or Ghostty.
from line 491
491491 
492492Explore related approaches for parallel work and delegation:
493493 
494* **Lightweight delegation**: [subagents](/docs/en/sub-agents.md) spawn helper agents for research or verification within your session, better for tasks that don't need inter-agent coordination
495* **Messaging between your own sessions**: [cross-session messaging](/docs/en/cross-session-messaging.md) lets Claude pass findings between the sessions you run yourself
496* **Manual parallel sessions**: [Git worktrees](/docs/en/worktrees.md) let you run multiple Claude Code sessions yourself without automated team coordination
494* **Lightweight delegation**: [subagents](https://code.claude.com/docs/en/sub-agents.md) spawn helper agents for research or verification within your session, better for tasks that don't need inter-agent coordination
495* **Messaging between your own sessions**: [cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md) lets Claude pass findings between the sessions you run yourself
496* **Manual parallel sessions**: [Git worktrees](https://code.claude.com/docs/en/worktrees.md) let you run multiple Claude Code sessions yourself without automated team coordination
497497 

agent-view Changed · +146 / -146 lines

from line 10
1010 
1111When you want to work more directly in any agent's session, attach to the row to enter the full conversation.
1212 
13To compare agent view with subagents, agent teams, and worktrees, see [Run agents in parallel](/docs/en/agents.md). Agent view runs sessions on your machine and you dispatch each one; to have Claude start and track parallel sessions in the cloud from one conversation instead, see [Projects](/docs/en/claude-projects.md).
13To compare agent view with subagents, agent teams, and worktrees, see [Run agents in parallel](https://code.claude.com/docs/en/agents.md). Agent view runs sessions on your machine and you dispatch each one; to have Claude start and track parallel sessions in the cloud from one conversation instead, see [Projects](https://code.claude.com/docs/en/claude-projects.md).
1414 
1515> [!NOTE]
1616>
from line 28
2828claude agents
2929```
3030 
31If you haven't yet accepted the [workspace trust dialog](/docs/en/permissions.md#project-allow-rules-and-workspace-trust) for the directory, Claude Code shows it before agent view opens, the same dialog `claude` shows. Accept to save trust for the workspace and continue. If you decline, Claude Code exits without opening agent view.
31If you haven't yet accepted the [workspace trust dialog](https://code.claude.com/docs/en/permissions.md#project-allow-rules-and-workspace-trust) for the directory, Claude Code shows it before agent view opens, the same dialog `claude` shows. Accept to save trust for the workspace and continue. If you decline, Claude Code exits without opening agent view.
3232 
3333Agent view opens with an input at the bottom and a table that fills in as sessions start. Press `Esc` to return to your shell; if you opened agent view by backgrounding a session with `←`, `Esc` returns to that conversation instead. Your sessions keep running while you're away and reappear the next time you open agent view.
3434 
from line 60
6060* **Waiting count**: while background sessions wait on your input, the same spot counts them, such as `← 2 agents`, or `← 99+ agents` when more than 99 wait. The count refreshes about every ten seconds while the terminal is focused and immediately when focus returns
6161* **Finished count**: when background sessions finish successfully while none wait on your input, the footer briefly shows how many finished, such as `← 2 done` for two
6262 
63The waiting count briefly changes color when it goes up or down and when a background session finishes successfully. If you turn on [`prefersReducedMotion`](/docs/en/settings-reference#prefersreducedmotion), you see neither the color change nor the `done` count. In [screen reader mode](/docs/en/accessibility.md), the `←` hint and its counts are hidden.
63The waiting count briefly changes color when it goes up or down and when a background session finishes successfully. If you turn on [`prefersReducedMotion`](https://code.claude.com/docs/en/settings-reference#prefersreducedmotion), you see neither the color change nor the `done` count. In [screen reader mode](https://code.claude.com/docs/en/accessibility.md), the `←` hint and its counts are hidden.
6464 
6565### Open agent view by default
6666 
from line 68
6868 
6969**1. Turn on the setting**
7070 
71In a regular `claude` session, run `/config` and turn on **Open agents view by default**. To skip the menu, set the [`defaultToAgentsView`](/docs/en/settings-reference#defaulttoagentsview) key directly:
71In a regular `claude` session, run `/config` and turn on **Open agents view by default**. To skip the menu, set the [`defaultToAgentsView`](https://code.claude.com/docs/en/settings-reference#defaulttoagentsview) key directly:
7272 
7373```text theme={null}
7474/config defaultToAgentsView=true
from line 90
9090 
9191Run `claude agents` to open agent view. It takes over the full terminal and lists every session grouped by state, with pinned sessions and the ones that need you at the top. Each row shows the session's name, current activity, and its age, counted from when the session was created; a finished session's age freezes at how long the run took.
9292 
93The name is tinted with the color set by [`/color`](/docs/en/commands) in that session, including when you [background a session](#from-inside-a-session) with `←` or `/background`.
93The name is tinted with the color set by [`/color`](https://code.claude.com/docs/en/commands) in that session, including when you [background a session](#from-inside-a-session) with `←` or `/background`.
9494 
9595By default the list shows every background session you've started, across all your projects. A session working in one repository and another in a different worktree both appear here, regardless of which directory you opened agent view from. To narrow the list to one project, pass `--cwd`:
9696 
from line 100
100100 
101101This shows only sessions started under that directory. It still lists a session that has [moved into a worktree](#how-file-edits-are-isolated) under `~/projects/my-app/.claude/worktrees/`.
102102 
103Interactive sessions you have open in other terminals don't appear until you [background them](#from-inside-a-session). [Subagents](/docs/en/sub-agents.md) and [teammates](/docs/en/agent-teams.md) a session spawns aren't listed as separate rows.
103Interactive sessions you have open in other terminals don't appear until you [background them](#from-inside-a-session). [Subagents](https://code.claude.com/docs/en/sub-agents.md) and [teammates](https://code.claude.com/docs/en/agent-teams.md) a session spawns aren't listed as separate rows.
104104 
105105```text theme={null}
106106Pinned
from line 129
129129| State | Icon shows as | What it means |
130130| :- | :- | :- |
131131| Working | Animated | Claude is actively running tools or generating a response |
132| Needs input | Yellow | Claude is waiting on something only you can provide: an answer to a question, a permission decision, or another prompt only you can answer, such as a [sandbox](/docs/en/sandboxing.md) prompt to allow a network host or an MCP server's [request for input](/docs/en/mcp.md#respond-to-mcp-elicitation-requests). A command that needs an attached terminal, such as `/install-github-app` or the `/mcp` settings list, [holds an unattended session here too](#attach-to-a-session) |
132| Needs input | Yellow | Claude is waiting on something only you can provide: an answer to a question, a permission decision, or another prompt only you can answer, such as a [sandbox](https://code.claude.com/docs/en/sandboxing.md) prompt to allow a network host or an MCP server's [request for input](https://code.claude.com/docs/en/mcp.md#respond-to-mcp-elicitation-requests). A command that needs an attached terminal, such as `/install-github-app` or the `/mcp` settings list, [holds an unattended session here too](#attach-to-a-session) |
133133| Idle | Dimmed | The session has nothing to do and is ready for your next prompt |
134134| Completed | Green | The task finished successfully |
135135| Failed | Red | The task ended with an error |
from line 141
141141| :- | :- |
142142| `✻` or animated `✽` | The session process is running, or the session needs your input |
143143| `∙` | The process has exited. You can still peek at the row, and when you reply or attach, Claude restarts it from its saved conversation |
144| `✢` | A [`/loop`](/docs/en/scheduled-tasks) session sleeping between iterations. The row shows its run count and a countdown |
144| `✢` | A [`/loop`](https://code.claude.com/docs/en/scheduled-tasks) session sleeping between iterations. The row shows its run count and a countdown |
145145 
146146The `#N` or `!N` label that can appear at the right edge of a row is a link to the session's [pull request or merge request](#pull-request-status), not part of the state icon.
147147 
from line 149
149149 
150150To read session state from a script or another program, use [`claude agents --json`](#read-session-state-from-a-script) rather than the files under `~/.claude/jobs/`.
151151 
152While agent view is open, Claude Code also sends a notification through your configured [terminal notification channel](/docs/en/terminal-config.md#get-a-terminal-bell-or-notification) when a local background session starts needing your input, finishes, or fails. Sessions that run on a schedule, such as [`/loop`](/docs/en/scheduled-tasks) sessions, notify only when they need your input. Notifications use the same [`preferredNotifChannel` setting](/docs/en/settings-reference#preferrednotifchannel) as the rest of Claude Code and fire the [`Notification` hook](/docs/en/hooks#notification) with the `agent_needs_input` or `agent_completed` type.
152While agent view is open, Claude Code also sends a notification through your configured [terminal notification channel](https://code.claude.com/docs/en/terminal-config.md#get-a-terminal-bell-or-notification) when a local background session starts needing your input, finishes, or fails. Sessions that run on a schedule, such as [`/loop`](https://code.claude.com/docs/en/scheduled-tasks) sessions, notify only when they need your input. Notifications use the same [`preferredNotifChannel` setting](https://code.claude.com/docs/en/settings-reference#preferrednotifchannel) as the rest of Claude Code and fire the [`Notification` hook](https://code.claude.com/docs/en/hooks#notification) with the `agent_needs_input` or `agent_completed` type.
153153 
154154Background sessions don't need any terminal open to keep working. A separate [supervisor process](#the-supervisor-process) runs them, so you can close agent view, close your shell, or start a new interactive session and your dispatched work keeps going.
155155 
from line 159
159159 
160160### Row summaries
161161 
162The one-line summary in each row is generated by a [Haiku-class model](/docs/en/model-config.md) so the row can tell you what the session is doing, what it needs, or what it produced without opening the transcript. While a session is actively working, the row text updates at most once every 15 seconds from the session's own recent output without sending a model request, and the model writes a fresh summary when each turn ends.
162The one-line summary in each row is generated by a [Haiku-class model](https://code.claude.com/docs/en/model-config.md) so the row can tell you what the session is doing, what it needs, or what it produced without opening the transcript. While a session is actively working, the row text updates at most once every 15 seconds from the session's own recent output without sending a model request, and the model writes a fresh summary when each turn ends.
163163 
164164A working row shows what the session says it's doing, and a blocked row shows the question it's asking. During a long turn, the model also rewrites the summary every few minutes so a busy row doesn't keep showing an outdated one. The summary text fills the row's remaining width; open the [peek panel](#peek-and-reply) to read a sentence the terminal edge clips.
165165 
166166When the list is [grouped by directory](#organize-the-list), the summary opens with the session's state as a colored word, such as `Needs input · double jump or wall climb?`. In the default state grouping, the group header already names the state, so the row shows only the summary.
167167 
168The end-of-turn summary and each mid-turn rewrite are one short Haiku-class request through your normal provider, billed and handled under the same [data usage terms](/docs/en/data-usage.md) as the session itself. The 15-second updates between model rewrites reuse the session's own output and don't send a request. On a third-party provider or gateway with no Haiku-class model configured, the request uses the session's main model instead; set [`ANTHROPIC_DEFAULT_HAIKU_MODEL`](/docs/en/model-config#environment-variables) to choose one.
168The end-of-turn summary and each mid-turn rewrite are one short Haiku-class request through your normal provider, billed and handled under the same [data usage terms](https://code.claude.com/docs/en/data-usage.md) as the session itself. The 15-second updates between model rewrites reuse the session's own output and don't send a request. On a third-party provider or gateway with no Haiku-class model configured, the request uses the session's main model instead; set [`ANTHROPIC_DEFAULT_HAIKU_MODEL`](https://code.claude.com/docs/en/model-config#environment-variables) to choose one.
169169 
170170### Pull request status
171171 
from line 172
172172When a session [opens a pull request](#how-file-edits-are-isolated), Claude Code adds a label at the right edge of the row, linked to the pull request:
173173 
174174* Claude Code writes the label as `#1234` for a pull request and as `!1234` for a GitLab merge request.
175* Claude Code emits the link even when it can't detect hyperlink support, for example over SSH or tmux. Set [`FORCE_HYPERLINK=0`](/docs/en/env-vars) to render the label as plain text.
175* Claude Code emits the link even when it can't detect hyperlink support, for example over SSH or tmux. Set [`FORCE_HYPERLINK=0`](https://code.claude.com/docs/en/env-vars) to render the label as plain text.
176176* After you send a follow-up to the session, Claude Code keeps the label while the row returns to live progress.
177177 
178178A session that works on an existing pull request is linked to it the same way. Claude Code finds the pull request differently depending on the command Claude runs:
from line 208
208208 
209209Type a reply in the peek panel and press `Enter` to send it to that session. Prefix a reply with `!` to send a Bash command instead. What happens to the reply depends on the session and on what you send:
210210 
211* A session that's working: `/model`, `/effort`, `/rename`, and `/usage` run right away. Other replies join the session's [message queue](/docs/en/interactive-mode.md#queue-messages-while-claude-works) instead of interrupting the response, and take effect [when queued input does](/docs/en/interactive-mode.md#when-claude-code-sends-what-you-queued). Other [commands](/docs/en/commands.md) wait for the turn to end, even ones that run as soon as you type them at a session's own prompt
211* A session that's working: `/model`, `/effort`, `/rename`, and `/usage` run right away. Other replies join the session's [message queue](https://code.claude.com/docs/en/interactive-mode.md#queue-messages-while-claude-works) instead of interrupting the response, and take effect [when queued input does](https://code.claude.com/docs/en/interactive-mode.md#when-claude-code-sends-what-you-queued). Other [commands](https://code.claude.com/docs/en/commands.md) wait for the turn to end, even ones that run as soon as you type them at a session's own prompt
212212* A reply that is exactly `/stop`: stops the session at once instead of being delivered to it, whether the session is working or waiting on you
213213* A [shell job](#run-a-shell-command): the reply, `/stop` included, goes to the command's terminal as typed input
214214 
from line 216
216216 
217217* A question with predefined choices: the panel lists the choices by number. With the reply input empty, press a choice's number to fill it in, then `Enter` to send it, or type your own answer instead
218218* A question without predefined choices: type your answer. When the empty input shows a suggested reply, press `Tab` to fill it in and edit it before sending
219* A permission prompt or another dialog, such as a [sandbox](/docs/en/sandboxing.md) prompt or an MCP server's [request for input](/docs/en/mcp.md#respond-to-mcp-elicitation-requests): replying doesn't answer it. Your message waits in the queue. To answer the dialog, attach with `→`
219* A permission prompt or another dialog, such as a [sandbox](https://code.claude.com/docs/en/sandboxing.md) prompt or an MCP server's [request for input](https://code.claude.com/docs/en/mcp.md#respond-to-mcp-elicitation-requests): replying doesn't answer it. Your message waits in the queue. To answer the dialog, attach with `→`
220220 
221When a [`PermissionRequest`](/docs/en/hooks#permissionrequest) or [`PreToolUse`](/docs/en/hooks#pretooluse) hook returns output Claude Code can't validate for the call the session is asking about, the row shows the hook event and `hook output invalid:` with the validation error before the pending request's text. For a hook that fails another way, the row says the hook failed. The session still waits on the same request.
221When a [`PermissionRequest`](https://code.claude.com/docs/en/hooks#permissionrequest) or [`PreToolUse`](https://code.claude.com/docs/en/hooks#pretooluse) hook returns output Claude Code can't validate for the call the session is asking about, the row shows the hook event and `hook output invalid:` with the validation error before the pending request's text. For a hook that fails another way, the row says the hook failed. The session still waits on the same request.
222222 
223223When a reply can't be delivered, the error message says whether it was saved. A reply prefixed with `!` or `/` is never saved. Claude Code sends a saved reply as the session's next prompt the next time you restart the session; send any other reply again.
224224 
225With [voice dictation](/docs/en/voice-dictation.md) enabled in [hold mode](/docs/en/voice-dictation.md#hold-to-record), hold your push-to-talk key while the reply input is focused to dictate a reply instead of typing it. The same works in the dispatch input at the bottom of agent view.
225With [voice dictation](https://code.claude.com/docs/en/voice-dictation.md) enabled in [hold mode](https://code.claude.com/docs/en/voice-dictation.md#hold-to-record), hold your push-to-talk key while the reply input is focused to dictate a reply instead of typing it. The same works in the dispatch input at the bottom of agent view.
226226 
227227Use `↑` and `↓` to peek at adjacent sessions without closing the panel, or `→` to attach.
228228 
from line 230
230230 
231231Press `Enter` or `→` on a selected row to attach. Agent view is replaced by the full interactive session. When you attach, Claude posts a short recap of what happened while you were away.
232232 
233While attached, the session behaves like any other Claude Code session: [commands](/docs/en/commands.md), keyboard shortcuts, and features all work, with the exceptions below.
233While attached, the session behaves like any other Claude Code session: [commands](https://code.claude.com/docs/en/commands.md), keyboard shortcuts, and features all work, with the exceptions below.
234234 
235While you're attached, `/install-github-app` and the [`/mcp`](/docs/en/mcp) settings list work normally, since a human at the terminal can complete their dialogs. When nobody is attached, these commands can't open their dialogs, so the session appears under `Needs input` in agent view with a row such as `open this session to manage MCP servers`, and the transcript reply says the same. Attach and run the command again to continue; the needs-input row clears when you attach. `/mcp reconnect <server>`, `/mcp enable`, and `/mcp disable` work without attaching either way.
235While you're attached, `/install-github-app` and the [`/mcp`](https://code.claude.com/docs/en/mcp) settings list work normally, since a human at the terminal can complete their dialogs. When nobody is attached, these commands can't open their dialogs, so the session appears under `Needs input` in agent view with a row such as `open this session to manage MCP servers`, and the transcript reply says the same. Attach and run the command again to continue; the needs-input row clears when you attach. `/mcp reconnect <server>`, `/mcp enable`, and `/mcp disable` work without attaching either way.
236236 
237Attached sessions always render in [fullscreen mode](/docs/en/fullscreen.md), regardless of your `tui` setting, because a background session has no terminal scrollback to append to. Scroll with `PgUp`, `PgDn`, or the mouse wheel, and press `Ctrl+O` for transcript mode. Your terminal's native scroll and tmux copy mode show only the current viewport, the same as when you run any fullscreen application.
237Attached sessions always render in [fullscreen mode](https://code.claude.com/docs/en/fullscreen.md), regardless of your `tui` setting, because a background session has no terminal scrollback to append to. Scroll with `PgUp`, `PgDn`, or the mouse wheel, and press `Ctrl+O` for transcript mode. Your terminal's native scroll and tmux copy mode show only the current viewport, the same as when you run any fullscreen application.
238238 
239An attached session doesn't [report its status to your terminal](/docs/en/terminal-config.md#see-session-status-in-your-terminal).
239An attached session doesn't [report its status to your terminal](https://code.claude.com/docs/en/terminal-config.md#see-session-status-in-your-terminal).
240240 
241241Press `←` on an empty prompt, or run `/exit`, to detach and return to agent view, whether you opened the session from agent view or with `claude attach <id>` from your shell.
242242 
243`←` also detaches while the [`/btw` overlay](/docs/en/interactive-mode#side-questions-with-%2Fbtw) is open. Requires Claude Code v2.1.257 or later. A side question that's still answering keeps running while you're away. The next time you attach, the overlay reopens with it, or with its answer.
243`←` also detaches while the [`/btw` overlay](https://code.claude.com/docs/en/interactive-mode#side-questions-with-%2Fbtw) is open. Requires Claude Code v2.1.257 or later. A side question that's still answering keeps running while you're away. The next time you attach, the overlay reopens with it, or with its answer.
244244 
245245On Windows, if you press `←` within about half a second of attaching, Claude Code shows `Ambiguous ←, press again to detach`, because in that window the terminal can redeliver a press from before you attached. Press `←` again to detach.
246246 
from line 248
248248 
249249`Ctrl+C` keeps its standard interrupt behavior while attached: it cancels a running response or `!` shell command rather than detaching. Pressing `Ctrl+C` twice on an empty prompt detaches.
250250 
251Detaching never stops a background session: `←`, `Ctrl+Z`, `/exit`, and double `Ctrl+C` or double `Ctrl+D` all leave it running. If you detach while a `/loop` is waiting for its next iteration, the loop keeps running and that iteration starts on schedule without you. To stop the loop before you detach, see [Stop a loop](/docs/en/scheduled-tasks.md#stop-a-loop). To end a session from inside it, run `/stop`.
251Detaching never stops a background session: `←`, `Ctrl+Z`, `/exit`, and double `Ctrl+C` or double `Ctrl+D` all leave it running. If you detach while a `/loop` is waiting for its next iteration, the loop keeps running and that iteration starts on schedule without you. To stop the loop before you detach, see [Stop a loop](https://code.claude.com/docs/en/scheduled-tasks.md#stop-a-loop). To end a session from inside it, run `/stop`.
252252 
253253#### Switch sessions without leaving the terminal
254254 
from line 264
264264 
265265When Claude Code can't reopen the conversation, it exits and prints a `claude --resume` command that resumes it.
266266 
267[Claude's task list](/docs/en/interactive-mode.md#task-list) moves to the background session with the conversation, so the checklist is intact when you return to that row.
267[Claude's task list](https://code.claude.com/docs/en/interactive-mode.md#task-list) moves to the background session with the conversation, so the checklist is intact when you return to that row.
268268 
269269The row you pressed `←` from also keeps a bold, undimmed name after you move the selection with the arrow keys or the mouse, so you can tell which session you came from.
270270 
from line 272
272272 
273273After about ten seconds, Claude Code backgrounds the session without waiting any longer, except in cases such as these:
274274 
275* **Foreground subagents are still running**: Claude Code keeps waiting so the work of the [foreground subagents](/docs/en/sub-agents.md#run-subagents-in-foreground-or-background) that Claude started carries over, and shows `Still backgrounding after the current tool`. Press `←` again to background without waiting, which restarts those subagents from the beginning.
275* **Foreground subagents are still running**: Claude Code keeps waiting so the work of the [foreground subagents](https://code.claude.com/docs/en/sub-agents.md#run-subagents-in-foreground-or-background) that Claude started carries over, and shows `Still backgrounding after the current tool`. Press `←` again to background without waiting, which restarts those subagents from the beginning.
276276* **A permission prompt or question is waiting for your answer**: while a permission prompt or a question Claude asked waits, Claude Code keeps waiting and shows `Still backgrounding after the current tool — a question is waiting for your answer.` If your answer lets the turn continue, such as **Yes** on a permission prompt, Claude Code backgrounds the session when the current tool finishes.
277277* **You type into the prompt input**: Claude Code cancels the switch, because unsent text stays in your terminal's input box and wouldn't move to the background session. It shows `Backgrounding cancelled — you have unsent text in the input. Send it or clear it, then press ← again.` Claude keeps working in the foreground.
278* **You stop the turn**: Claude Code cancels the switch and shows `Backgrounding cancelled — the turn was stopped.` For example, the turn stops when you [interrupt Claude with `Esc`](/docs/en/interactive-mode#general-controls) or select **No** [without a comment](/docs/en/permissions.md#add-a-comment-when-you-answer-a-permission-prompt) on a permission prompt from the main conversation, or press `Esc` on a question Claude asks there. Press `←` again to background the session.
279* **A queued message can't move**: messages you [queued while Claude was working](/docs/en/interactive-mode.md#queue-messages-while-claude-works) move to the background session with the conversation. When one of them can't, the session stays in the foreground and Claude Code shows a notice such as `Cannot open agents — 1 queued message can't move to the background. Press ← again once Claude has read it.`
278* **You stop the turn**: Claude Code cancels the switch and shows `Backgrounding cancelled — the turn was stopped.` For example, the turn stops when you [interrupt Claude with `Esc`](https://code.claude.com/docs/en/interactive-mode#general-controls) or select **No** [without a comment](https://code.claude.com/docs/en/permissions.md#add-a-comment-when-you-answer-a-permission-prompt) on a permission prompt from the main conversation, or press `Esc` on a question Claude asks there. Press `←` again to background the session.
279* **A queued message can't move**: messages you [queued while Claude was working](https://code.claude.com/docs/en/interactive-mode.md#queue-messages-while-claude-works) move to the background session with the conversation. When one of them can't, the session stays in the foreground and Claude Code shows a notice such as `Cannot open agents — 1 queued message can't move to the background. Press ← again once Claude has read it.`
280280 
281When Claude Code backgrounds the session, either after about ten seconds or after you press `←` again, it stops a shell command that Claude is still running in the foreground. Claude Code doesn't show the `Background this session?` dialog for that command. In the background session, Claude has no record that the command started, so Claude may run the command again. To keep the command running when the session moves, press `Ctrl+B` to [turn it into a background command](/docs/en/interactive-mode.md#background-bash-commands) while Claude Code is still waiting.
281When Claude Code backgrounds the session, either after about ten seconds or after you press `←` again, it stops a shell command that Claude is still running in the foreground. Claude Code doesn't show the `Background this session?` dialog for that command. In the background session, Claude has no record that the command started, so Claude may run the command again. To keep the command running when the session moves, press `Ctrl+B` to [turn it into a background command](https://code.claude.com/docs/en/interactive-mode.md#background-bash-commands) while Claude Code is still waiting.
282282 
283283Pressing `←` creates the session's row even when the conversation has no messages yet, so `→` still returns to it.
284284 
285You can turn this shortcut off for foreground sessions with the [`leftArrowOpensAgents`](/docs/en/settings-reference#leftarrowopensagents) setting in `/config`.
285You can turn this shortcut off for foreground sessions with the [`leftArrowOpensAgents`](https://code.claude.com/docs/en/settings-reference#leftarrowopensagents) setting in `/config`.
286286 
287287##### Prompts sent as the session moves to the background
288288 
from line 289
289289If you enter a prompt or `!` shell command at the moment the session moves to the background, it is stopped or left unsent:
290290 
291291* **Sent as the conversation closes**: the response or command stops when the conversation closes and agent view opens
292* **Still waiting on [hooks](/docs/en/hooks.md) at that moment**: the prompt isn't sent, and nothing on screen says so. This includes a prompt you typed while [`SessionStart` hooks](/docs/en/hooks#sessionstart) were still running
292* **Still waiting on [hooks](https://code.claude.com/docs/en/hooks.md) at that moment**: the prompt isn't sent, and nothing on screen says so. This includes a prompt you typed while [`SessionStart` hooks](https://code.claude.com/docs/en/hooks#sessionstart) were still running
293293 
294In both cases the text you typed is kept in [prompt history](/docs/en/interactive-mode.md#command-history). To send it again, open the backgrounded session and press `↑` at its prompt to bring the text back.
294In both cases the text you typed is kept in [prompt history](https://code.claude.com/docs/en/interactive-mode.md#command-history). To send it again, open the backgrounded session and press `↑` at its prompt to bring the text back.
295295 
296296### Organize the list
297297 
from line 319
319319 
320320* `/resume` names an id or a search term
321321* the view is scoped with `--cwd`
322* the view was started with [`--safe-mode`](/docs/en/cli-reference#cli-flags)
322* the view was started with [`--safe-mode`](https://code.claude.com/docs/en/cli-reference#cli-flags)
323323* the view was opened with a flag such as `--permission-mode` or `--settings`
324324 
325325If you typed anything after `/resume`, retype without it. If you used one of those flags, run `claude agents` in your shell without it, then type `/resume` alone.
from line 352
352352| `Home` / `End` | Jump to the first or last row |
353353| `Enter` | Attach to the selected session, or submit the input's text if it isn't a [filter](#filter-sessions) |
354354| `Space` | Open or close the peek panel for the selected session |
355| `Shift+Enter` | Insert a newline in the dispatch input, [as in the main prompt](/docs/en/terminal-config.md#enter-multiline-prompts) |
355| `Shift+Enter` | Insert a newline in the dispatch input, [as in the main prompt](https://code.claude.com/docs/en/terminal-config.md#enter-multiline-prompts) |
356356| `Ctrl+Enter` | Dispatch and attach immediately, in terminals where the `?` overlay lists `ctrl+enter to start and open` |
357357| `→` | Attach to the selected session |
358358| `Alt+1`..`Alt+9` | Attach to session 1–9 in the focused session's directory |
from line 366
366366| `Ctrl+J` | Insert a newline in the dispatch input |
367367| `Ctrl+X` | Stop the session; press again within two seconds to delete it |
368368| `Shift+↑` / `Shift+↓` | Reorder the selected session |
369| `Esc` | Close the peek panel, clear the input, or exit. When you opened agent view by backgrounding your session with `←`, the final `Esc` returns to that conversation instead of exiting. With [vim editor mode](/docs/en/interactive-mode.md#vim-editor-mode) on, pressing `Esc` in the input switches from INSERT to NORMAL mode and keeps your text, as in the main prompt |
370| `Ctrl+C` | Clear the input; press twice to exit. While text on screen is selected, the press clears the selection instead, copying it first unless [selecting already copied it](/docs/en/settings-reference.md#copyonselect) |
369| `Esc` | Close the peek panel, clear the input, or exit. When you opened agent view by backgrounding your session with `←`, the final `Esc` returns to that conversation instead of exiting. With [vim editor mode](https://code.claude.com/docs/en/interactive-mode.md#vim-editor-mode) on, pressing `Esc` in the input switches from INSERT to NORMAL mode and keeps your text, as in the main prompt |
370| `Ctrl+C` | Clear the input; press twice to exit. While text on screen is selected, the press clears the selection instead, copying it first unless [selecting already copied it](https://code.claude.com/docs/en/settings-reference.md#copyonselect) |
371371| `?` | Show shortcuts |
372372 
373The shortcuts that have an action in the [`Agents` context](/docs/en/keybindings#agents-actions) follow your [`keybindings.json`](/docs/en/keybindings). So does `Ctrl+G`, through the `Chat` context's `chat:externalEditor` binding.
373The shortcuts that have an action in the [`Agents` context](https://code.claude.com/docs/en/keybindings#agents-actions) follow your [`keybindings.json`](https://code.claude.com/docs/en/keybindings). So does `Ctrl+G`, through the `Chat` context's `chat:externalEditor` binding.
374374 
375375## Dispatch new agents
376376 
from line 380
380380 
381381Type a prompt in the input at the bottom of agent view and press `Enter` to start a new background session. The session is named automatically from the prompt; rename it later with `Ctrl+R`.
382382 
383The automatic name is a short label written by a [Haiku-class model](/docs/en/model-config.md). A name the session gets later also appears on its row, including the [generated title](/docs/en/sessions.md#name-your-sessions) the session gets when you [accept a plan](/docs/en/permission-modes.md#review-and-approve-a-plan) in that session.
383The automatic name is a short label written by a [Haiku-class model](https://code.claude.com/docs/en/model-config.md). A name the session gets later also appears on its row, including the [generated title](https://code.claude.com/docs/en/sessions.md#name-your-sessions) the session gets when you [accept a plan](https://code.claude.com/docs/en/permission-modes.md#review-and-approve-a-plan) in that session.
384384 
385385Paste an image into the prompt to include a screenshot or diagram with the task.
386386 
from line 390
390390 
391391| Input | Effect |
392392| :- | :- |
393| `<agent-name> <prompt>` | If the first word matches a custom [subagent](/docs/en/sub-agents.md) name, that subagent runs as the session's main agent with the configuration from its frontmatter |
393| `<agent-name> <prompt>` | If the first word matches a custom [subagent](https://code.claude.com/docs/en/sub-agents.md) name, that subagent runs as the session's main agent with the configuration from its frontmatter |
394394| `@<agent-name>` | Mention a custom subagent anywhere in the prompt to run it as the main agent |
395395| `@<repo>` | Mention a repository to run the session there. See [Dispatch to a specific directory](#dispatch-to-a-specific-directory) for which repositories are listed |
396| `/<command>` | Suggest [skills](/docs/en/skills.md) and [commands](/docs/en/commands.md) to dispatch as the prompt |
396| `/<command>` | Suggest [skills](https://code.claude.com/docs/en/skills.md) and [commands](https://code.claude.com/docs/en/commands.md) to dispatch as the prompt |
397397| `! <command>` | Run a shell command as a background job instead of starting a Claude session. The job appears as a row you can attach to, watch, and detach from |
398398| `#<number>` or a pull or merge request URL | If a session is already working on that pull request or merge request, Claude Code selects its row instead of dispatching a new session |
399399 
from line 407
407407 
408408Skills, your own commands, and prompt-expanding built-ins such as `/init` are sent to a new background session as its first prompt. The hint `isn't available in agent view` means the built-in command you entered didn't run. To run it, [attach to a session](#attach-to-a-session) and enter it there. Everything you typed stays in the input next to the hint so you can edit it.
409409 
410Packaging a recurring task as a [skill](/docs/en/skills.md) lets you start the same workflow from agent view repeatedly without retyping the prompt.
410Packaging a recurring task as a [skill](https://code.claude.com/docs/en/skills.md) lets you start the same workflow from agent view repeatedly without retyping the prompt.
411411 
412412When the same `@name` matches both a subagent and a sibling repository, the subagent takes precedence. The bare first-word match also applies, so a prompt that happens to begin with one of your subagent names dispatches that subagent rather than treating the word as plain text. Use the `@` form when you want to be explicit, or start the prompt with a different word to avoid the match.
413413 
from line 419
419419* Open `claude agents` in a parent directory and mention a child repository with `@<repo>` in the prompt. Typing `@` lists these targets:
420420 
421421 * Git repositories one level below the launch directory
422 * The registered [git worktrees](/docs/en/worktrees.md) of the repository you launched from that live inside its directory tree, such as the ones Claude creates under `.claude/worktrees/`, labeled with their checked-out branch. Worktrees added outside the repository, such as with `git worktree add ../feature`, aren't listed
422 * The registered [git worktrees](https://code.claude.com/docs/en/worktrees.md) of the repository you launched from that live inside its directory tree, such as the ones Claude creates under `.claude/worktrees/`, labeled with their checked-out branch. Worktrees added outside the repository, such as with `git worktree add ../feature`, aren't listed
423423 * Any directory that already has a session in the list
424424 
425425 A directory whose name contains a space isn't listed.
from line 435
435435 
436436Run `/background` or its alias `/bg` to move the current conversation into a background session. Pass a prompt such as `/bg run the test suite and fix any failures` to give one more instruction first. If Claude is responding when you run `/bg`, the response continues in the background session.
437437 
438Exiting a session that still has background work running, such as subagents, background shell commands, workflows, or [monitors](/docs/en/tools-reference.md#monitor-tool), shows a `Background work is running` dialog instead of quitting immediately. Choose `Move to background and exit` to background the session the same way `/background` does and return to your shell. The option isn't shown when agent view is [turned off](#turn-off-agent-view).
438Exiting a session that still has background work running, such as subagents, background shell commands, workflows, or [monitors](https://code.claude.com/docs/en/tools-reference.md#monitor-tool), shows a `Background work is running` dialog instead of quitting immediately. Choose `Move to background and exit` to background the session the same way `/background` does and return to your shell. The option isn't shown when agent view is [turned off](#turn-off-agent-view).
439439 
440440If a background session on the list already has the conversation's name, Claude Code numbers the new row's name, such as `my-session (2)`, and leaves the existing row's name alone. To rename the new row, select it in agent view and press `Ctrl+R`.
441441 
from line 443
443443 
444444Run `/fork` to copy the current conversation into a new background session while the original keeps running. The copy starts with everything in the conversation up to that point; see the bullets below for where the copy runs. It also carries over the model, permission mode, effort level, and any directories or "don't ask again" permission grants you added during the session. The copy appears as its own row in agent view.
445445 
446After the fork, the two conversations are independent: nothing the copy does enters the original conversation on its own, though in sessions where [cross-session messaging](/docs/en/cross-session-messaging.md) is enabled, either session's Claude can explicitly message the other.
446After the fork, the two conversations are independent: nothing the copy does enters the original conversation on its own, though in sessions where [cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md) is enabled, either session's Claude can explicitly message the other.
447447 
448When [agent view is turned off](#turn-off-agent-view), `/fork` starts a [forked subagent](/docs/en/sub-agents.md#fork-the-current-conversation) instead of copying the session.
448When [agent view is turned off](#turn-off-agent-view), `/fork` starts a [forked subagent](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation) instead of copying the session.
449449 
450450Pass a prompt such as `/fork open a draft pull request with the work so far` and the copy starts working on it immediately. Without a prompt the copy waits for its first instruction: select its row in `claude agents` and press `Space` to send one, or run `claude attach <id>`. The selected row shows `space to send it a prompt` while it waits.
451451 
452452The `/fork` confirmation is one line showing the copy's state, such as `session running`, the name of its agent-view row, and its session ID for `claude attach`. Click the name to switch into the copy: this session moves to the background, the same as pressing `←`, and agent view opens the copy's session.
453453 
454Except when the copy [edits in place](#how-file-edits-are-isolated), Claude Code instructs it to create a worktree of its own before making code changes. Outside a git repository, only a copy moved out of a hook-created worktree gets the instruction; with no [`WorktreeCreate` hook](/docs/en/hooks#worktreecreate), the copy edits in place. A copy moved out of your worktree is also told never to edit, run commands in, or enter that worktree, whatever the isolation setting.
454Except when the copy [edits in place](#how-file-edits-are-isolated), Claude Code instructs it to create a worktree of its own before making code changes. Outside a git repository, only a copy moved out of a hook-created worktree gets the instruction; with no [`WorktreeCreate` hook](https://code.claude.com/docs/en/hooks#worktreecreate), the copy edits in place. A copy moved out of your worktree is also told never to edit, run commands in, or enter that worktree, whatever the isolation setting.
455455 
456456Where the copy starts depends on where the current session is running:
457457 
458458* Like any dispatched session, the copy [moves into its own worktree before editing files](#how-file-edits-are-isolated). In that case the confirmation doesn't mention where the copy runs.
459* When your session moved into its linked [worktree](/docs/en/worktrees.md) after it started, the copy starts back where the session was before the move and, unless it [edits in place](#how-file-edits-are-isolated), makes its code changes in a worktree of its own there. When your worktree is checked out on a branch, that instruction also tells a copy whose task builds on your work to base its new branch on yours, since your branch stays checked out in your worktree. The confirmation ends with `runs in the origin tree`.
459* When your session moved into its linked [worktree](https://code.claude.com/docs/en/worktrees.md) after it started, the copy starts back where the session was before the move and, unless it [edits in place](#how-file-edits-are-isolated), makes its code changes in a worktree of its own there. When your worktree is checked out on a branch, that instruction also tells a copy whose task builds on your work to base its new branch on yours, since your branch stays checked out in your worktree. The confirmation ends with `runs in the origin tree`.
460460* When you launched the session inside a linked worktree of a repository that has a main working tree, the copy starts in that main working tree, with the same worktree-of-its-own rule but no branch instruction. The confirmation ends with `runs in the origin tree` here too.
461461* A session launched inside a worktree of a bare-repository layout has no main working tree to return to, so the copy stays where it is, and the confirmation ends with `edits this checkout`. The same note appears when worktree isolation is [turned off](#how-file-edits-are-isolated) in a session that isn't inside a linked worktree, because the copy then edits the files you have open.
462462 
463Sessions started with launch flags the copy wouldn't inherit, such as a replaced system prompt or a `--tools` allowlist, can't be forked; Claude Code says so instead of making a partial copy. A session dispatched from agent view forks normally: the copy is launched with the same [agent definition](/docs/en/sub-agents.md) and appended instructions as the session it came from.
463Sessions started with launch flags the copy wouldn't inherit, such as a replaced system prompt or a `--tools` allowlist, can't be forked; Claude Code says so instead of making a partial copy. A session dispatched from agent view forks normally: the copy is launched with the same [agent definition](https://code.claude.com/docs/en/sub-agents.md) and appended instructions as the session it came from.
464464 
465465#### What carries over when you background
466466 
467Backgrounding starts a fresh process that resumes from the saved conversation, and in-flight background work moves to it. Running background shell commands, backgrounded subagents, dynamic workflows, scheduled tasks you created with [`/loop`](/docs/en/scheduled-tasks), and Claude's [automatic replies to artifact comments](/docs/en/artifacts.md#let-claude-reply-to-comments-on-its-own) all carry over and keep running there. A subagent moves together with everything it started, so it carries over only when all of that work can move too.
467Backgrounding starts a fresh process that resumes from the saved conversation, and in-flight background work moves to it. Running background shell commands, backgrounded subagents, dynamic workflows, scheduled tasks you created with [`/loop`](https://code.claude.com/docs/en/scheduled-tasks), and Claude's [automatic replies to artifact comments](https://code.claude.com/docs/en/artifacts.md#let-claude-reply-to-comments-on-its-own) all carry over and keep running there. A subagent moves together with everything it started, so it carries over only when all of that work can move too.
468468 
469When a [dynamic workflow](/docs/en/workflows.md) still has subagents running, Claude Code asks before backgrounding with the `Background this session?` dialog, which says how many subagents would restart. Choose `Stay` to let them finish first. If you confirm, Claude Code replays the run in the background session: subagents that were still running start over from the beginning, so the tokens they used so far are spent again. See [Resume after a pause](/docs/en/workflows.md#resume-after-a-pause) for which completed subagents return their saved results and which run again.
469When a [dynamic workflow](https://code.claude.com/docs/en/workflows.md) still has subagents running, Claude Code asks before backgrounding with the `Background this session?` dialog, which says how many subagents would restart. Choose `Stay` to let them finish first. If you confirm, Claude Code replays the run in the background session: subagents that were still running start over from the beginning, so the tokens they used so far are spent again. See [Resume after a pause](https://code.claude.com/docs/en/workflows.md#resume-after-a-pause) for which completed subagents return their saved results and which run again.
470470 
471Claude Code stops background work that can't carry over, such as a running [monitor](/docs/en/tools-reference.md#monitor-tool), and stops a backgrounded subagent that owns a monitor along with it. When any such work is running, Claude Code shows the `Background this session?` dialog so you can confirm before it stops the work.
471Claude Code stops background work that can't carry over, such as a running [monitor](https://code.claude.com/docs/en/tools-reference.md#monitor-tool), and stops a backgrounded subagent that owns a monitor along with it. When any such work is running, Claude Code shows the `Background this session?` dialog so you can confirm before it stops the work.
472472 
473473Once in the background, the session can start new subagents, monitors, and background commands, and those keep running across later detach and reattach.
474474 
from line 482
482482* `--fallback-model`
483483* `--allow-dangerously-skip-permissions`
484484 
485Directories you added during the session with [`/add-dir`](/docs/en/permissions#additional-directories-grant-file-access-not-configuration) also carry through. Carrying `--allow-dangerously-skip-permissions` keeps `bypassPermissions` reachable in the backgrounded session, but it doesn't grant anything new: the mode still needs your [acceptance of the bypass disclaimer](/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) on record.
485Directories you added during the session with [`/add-dir`](https://code.claude.com/docs/en/permissions#additional-directories-grant-file-access-not-configuration) also carry through. Carrying `--allow-dangerously-skip-permissions` keeps `bypassPermissions` reachable in the backgrounded session, but it doesn't grant anything new: the mode still needs your [acceptance of the bypass disclaimer](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) on record.
486486 
487487### Dispatch an agent from your shell
488488 
from line 494
494494 
495495The prompt is the positional argument, not a `-p` value. Claude Code rejects `--bg` combined with `-p` or `--print` before any session is created, because `--print` never starts the interactive session that `claude agents` attaches to.
496496 
497If you run `claude --bg` from a terminal in a directory you haven't [trusted](/docs/en/permissions.md#project-allow-rules-and-workspace-trust), the workspace trust dialog appears first and the session starts once you accept. If you decline, Claude Code exits without starting a session. Where no dialog can appear, such as in a script, the command exits with a [`Workspace not trusted`](/docs/en/errors#workspace-not-trusted-when-dispatching-a-background-session) error instead.
497If you run `claude --bg` from a terminal in a directory you haven't [trusted](https://code.claude.com/docs/en/permissions.md#project-allow-rules-and-workspace-trust), the workspace trust dialog appears first and the session starts once you accept. If you decline, Claude Code exits without starting a session. Where no dialog can appear, such as in a script, the command exits with a [`Workspace not trusted`](https://code.claude.com/docs/en/errors#workspace-not-trusted-when-dispatching-a-background-session) error instead.
498498 
499To run a specific [subagent](/docs/en/sub-agents.md) you have defined, such as a `code-reviewer`, as the session's main agent, combine `--bg` with `--agent`:
499To run a specific [subagent](https://code.claude.com/docs/en/sub-agents.md) you have defined, such as a `code-reviewer`, as the session's main agent, combine `--bg` with `--agent`:
500500 
501501```bash theme={null}
502502claude --agent code-reviewer --bg "address review comments on PR 1234"
from line 504
504504 
505505If the name doesn't match any of your subagents, the launch fails: Claude Code prints a `no agent named` warning and still reports the session as backgrounded, but the session exits immediately with an `--agent '<name>' not found` error.
506506 
507When the backgrounded session later resumes or restarts, Claude Code restores the agent and its tool restrictions; for its system prompt, see [System prompt flags in resumed conversations](/docs/en/cli-reference.md#system-prompt-flags-in-resumed-conversations). It searches the session's own directory for the agent first, provided you've [trusted that workspace](/docs/en/permissions.md#project-allow-rules-and-workspace-trust), so a project-scoped agent still loads when the session is resumed from another directory. If the agent no longer exists, the session continues with the default tools and its transcript opens with a [warning naming the agent](/docs/en/errors.md#session-agent-no-longer-available).
507When the backgrounded session later resumes or restarts, Claude Code restores the agent and its tool restrictions; for its system prompt, see [System prompt flags in resumed conversations](https://code.claude.com/docs/en/cli-reference.md#system-prompt-flags-in-resumed-conversations). It searches the session's own directory for the agent first, provided you've [trusted that workspace](https://code.claude.com/docs/en/permissions.md#project-allow-rules-and-workspace-trust), so a project-scoped agent still loads when the session is resumed from another directory. If the agent no longer exists, the session continues with the default tools and its transcript opens with a [warning naming the agent](https://code.claude.com/docs/en/errors.md#session-agent-no-longer-available).
508508 
509509To continue an existing conversation in the background, pass its full session ID with `--resume`:
510510 
from line 542
542542 
543543Claude Code reads a whole argument as the flag only where a flag can stand: before any bare `--` separator and not where another flag expects its value. Put the flag first, as in `claude --bg "<prompt>"`.
544544 
545Where the position is ambiguous, such as after a run of combined short flags, Claude Code starts nothing. It exits with [`Couldn't tell whether --bg is a flag or text here`](/docs/en/errors#couldnt-tell-whether-bg-is-a-flag-or-text) instead.
545Where the position is ambiguous, such as after a run of combined short flags, Claude Code starts nothing. It exits with [`Couldn't tell whether --bg is a flag or text here`](https://code.claude.com/docs/en/errors#couldnt-tell-whether-bg-is-a-flag-or-text) instead.
546546 
547547#### Run a shell command
548548 
from line 560
560560 
561561### How file edits are isolated
562562 
563When you dispatch a background session from agent view or start one with `claude --bg`, the session starts in your working directory. Before editing files, Claude moves the session into an isolated [git worktree](/docs/en/worktrees.md) under `.claude/worktrees/`, so parallel sessions can read the same checkout but each writes to its own. Once the session is in its worktree, Claude Code [enforces worktree isolation](/docs/en/worktrees.md#how-claude-code-enforces-isolation) for the session and for any subagents it spawns.
563When you dispatch a background session from agent view or start one with `claude --bg`, the session starts in your working directory. Before editing files, Claude moves the session into an isolated [git worktree](https://code.claude.com/docs/en/worktrees.md) under `.claude/worktrees/`, so parallel sessions can read the same checkout but each writes to its own. Once the session is in its worktree, Claude Code [enforces worktree isolation](https://code.claude.com/docs/en/worktrees.md#how-claude-code-enforces-isolation) for the session and for any subagents it spawns.
564564 
565565Claude skips the worktree when:
566566 
from line 567
567567* You [moved a session you already had open to the background](#from-inside-a-session) with `←` or `/background`. That session keeps editing files where it was already working
568568* The session is already inside a linked git worktree, whether Claude created it under `.claude/worktrees/` or you created it with `git worktree add` somewhere else
569569* The file that Claude is editing is inside a linked git worktree, such as one that the session or its subagent created with `git worktree add`
570* The working directory isn't a git repository and no [`WorktreeCreate` hook](/docs/en/hooks#worktreecreate) is configured
570* The working directory isn't a git repository and no [`WorktreeCreate` hook](https://code.claude.com/docs/en/hooks#worktreecreate) is configured
571571* The write is outside the working directory
572572 
573To turn off worktree isolation for a repository where git worktrees are impractical, set [`worktree.bgIsolation`](/docs/en/settings-reference#worktree-bgisolation) to `"none"`. Background sessions then edit your working copy directly without moving into a worktree first. Add the setting to the project's `.claude/settings.json`:
573To turn off worktree isolation for a repository where git worktrees are impractical, set [`worktree.bgIsolation`](https://code.claude.com/docs/en/settings-reference#worktree-bgisolation) to `"none"`. Background sessions then edit your working copy directly without moving into a worktree first. Add the setting to the project's `.claude/settings.json`:
574574 
575575```json theme={null}
576576{
from line 580
580580}
581581```
582582 
583Outside a git repository, sessions write to the working directory directly and aren't isolated from each other, so avoid dispatching parallel sessions that edit the same files. If you use a different version control system, configure a [`WorktreeCreate` hook](/docs/en/worktrees#non-git-version-control) and Claude isolates edits the same way it does for git.
583Outside a git repository, sessions write to the working directory directly and aren't isolated from each other, so avoid dispatching parallel sessions that edit the same files. If you use a different version control system, configure a [`WorktreeCreate` hook](https://code.claude.com/docs/en/worktrees#non-git-version-control) and Claude isolates edits the same way it does for git.
584584 
585585When the hook fails in a directory that isn't a git repository, Claude skips isolation for that directory and edits the working directory in place. Inside a git repository, a session that Claude moves into a worktree before editing can't use the `Edit`, `Write`, or `NotebookEdit` tools on the shared checkout until that move happens.
586586 
587587To find a session's worktree path, attach and check its working directory.
588588 
589A [subagent](/docs/en/sub-agents.md) the background session spawns inherits the session's working directory. Once the session is in a worktree, the subagent's file edits land in that worktree rather than in your working copy. To give a subagent its own separate worktree instead, set [`isolation: worktree`](/docs/en/sub-agents#supported-frontmatter-fields) in its frontmatter or pass `isolation: "worktree"` when spawning it.
589A [subagent](https://code.claude.com/docs/en/sub-agents.md) the background session spawns inherits the session's working directory. Once the session is in a worktree, the subagent's file edits land in that worktree rather than in your working copy. To give a subagent its own separate worktree instead, set [`isolation: worktree`](https://code.claude.com/docs/en/sub-agents#supported-frontmatter-fields) in its frontmatter or pass `isolation: "worktree"` when spawning it.
590590 
591591When a background session has made code changes in a worktree Claude entered, Claude Code instructs Claude to preserve the work before finishing, so it survives if you delete the session and its worktree:
592592 
from line 593
593593* **Commit and push**: Claude commits without asking, and pushes the branch when the repository has a remote.
594594* **Draft pull request**: Claude opens one when the task calls for it, and the [`#N` label](#pull-request-status) appears on the row.
595595* **Never**: pushing to `main` or `master`, force-pushing, and merging.
596* **Your git instructions take precedence**: if the task, `CLAUDE.md`, or [memory](/docs/en/memory.md) says you handle committing or pushing yourself, Claude leaves git to you.
596* **Your git instructions take precedence**: if the task, `CLAUDE.md`, or [memory](https://code.claude.com/docs/en/memory.md) says you handle committing or pushing yourself, Claude leaves git to you.
597597 
598598A session editing a checkout it didn't isolate itself still asks before committing or switching branches. This applies when isolation is set to `"none"`, when the worktree move failed, or when the session started inside a worktree that already existed.
599599 
from line 621
621621 
622622 When another finished session's records also name the worktree, it stays when you delete again; push the commits, then delete again.
623623* A worktree git no longer recognizes, for example after `git worktree prune`, doesn't block the delete. Claude Code deletes the session and leaves the directory on disk.
624* When git or your [`WorktreeRemove` hook](/docs/en/hooks#worktreeremove) fails to remove the worktree, Claude Code keeps the worktree and the session, and the message names the cause. For a hook, the message says how it ended, such as `exited 1`, and quotes the start of its stderr. The message also tells you which of these to do next:
624* When git or your [`WorktreeRemove` hook](https://code.claude.com/docs/en/hooks#worktreeremove) fails to remove the worktree, Claude Code keeps the worktree and the session, and the message names the cause. For a hook, the message says how it ended, such as `exited 1`, and quotes the start of its stderr. The message also tells you which of these to do next:
625625 
626626 * Delete the session again to remove the directory anyway, by pressing `Ctrl+X` twice on its row in agent view or running the `claude rm <id> --force-remove-worktree <worktree-id>` command that the `claude rm` refusal printed. The worktree's branch stays in the repository.
627627 
from line 637
637637 
638638A worktree you created yourself and started the session inside is left in place either way.
639639 
640A session whose worktree directory belongs to no git repository, because the repository was deleted or a [`WorktreeCreate` hook](/docs/en/hooks#worktreecreate) created the directory elsewhere, can still be deleted. While files remain in the directory:
640A session whose worktree directory belongs to no git repository, because the repository was deleted or a [`WorktreeCreate` hook](https://code.claude.com/docs/en/hooks#worktreecreate) created the directory elsewhere, can still be deleted. While files remain in the directory:
641641 
642* Agent view asks for the same `Ctrl+X` double-press before discarding them. For a hook-created directory it runs your [`WorktreeRemove` hook](/docs/en/hooks#worktreeremove) instead, and without one it refuses the delete and keeps the session.
642* Agent view asks for the same `Ctrl+X` double-press before discarding them. For a hook-created directory it runs your [`WorktreeRemove` hook](https://code.claude.com/docs/en/hooks#worktreeremove) instead, and without one it refuses the delete and keeps the session.
643643* `claude rm` keeps the session and worktree, and names the reason.
644644 
645645Either path keeps a directory that another finished session's records name.
from line 651
651651Give the value after the command, or type the command alone to choose one from a list:
652652 
653653* **Model**: `/model <name>`, for example `/model opus`
654* **[Effort level](/docs/en/model-config.md#adjust-effort-level)**: `/effort` with `low`, `medium`, `high`, `xhigh`, or `max`, for example `/effort high`. To start sessions in [ultracode](/docs/en/workflows.md#let-claude-decide-with-ultracode), open agent view from your shell with [`claude agents --effort ultracode`](#dispatch-defaults) instead; the dispatch input doesn't accept `/effort ultracode`
655* **Fast mode**: `/fast on` or `/fast off`. The session starts in fast mode only if fast mode is [available to you](/docs/en/fast-mode.md#requirements) and its model supports fast mode. On a model that doesn't, the session starts with fast mode off, so first use `/model` to pick one of the [models that support fast mode](/docs/en/fast-mode.md). The hint under the input, not the header, confirms whether new sessions get fast mode.
654* **[Effort level](https://code.claude.com/docs/en/model-config.md#adjust-effort-level)**: `/effort` with `low`, `medium`, `high`, `xhigh`, or `max`, for example `/effort high`. To start sessions in [ultracode](https://code.claude.com/docs/en/workflows.md#let-claude-decide-with-ultracode), open agent view from your shell with [`claude agents --effort ultracode`](#dispatch-defaults) instead; the dispatch input doesn't accept `/effort ultracode`
655* **Fast mode**: `/fast on` or `/fast off`. The session starts in fast mode only if fast mode is [available to you](https://code.claude.com/docs/en/fast-mode.md#requirements) and its model supports fast mode. On a model that doesn't, the session starts with fast mode off, so first use `/model` to pick one of the [models that support fast mode](https://code.claude.com/docs/en/fast-mode.md). The hint under the input, not the header, confirms whether new sessions get fast mode.
656656 
657657To undo a choice, give `default` as the value, for example `/effort default`.
658658 
from line 669
669669 
670670* From the shell, pass `--model` with `claude --bg`.
671671* Attach to a running session and run `/model` to switch. A pick from the picker, or a typed `/model <name>`, saves as your default for new sessions unless you press `s` in the picker for a session-only switch. A session-only switch persists if the session is respawned.
672* Dispatch a [subagent](/docs/en/sub-agents.md) that sets `model` in its frontmatter, by starting the prompt with its name or mentioning `@name`. While a `/model` choice in the dispatch input applies, the subagent's `model` isn't used, so enter `/model default` there. If you launched with [`claude agents --model`](#dispatch-defaults), the subagent's isn't used either, so run `claude agents` in your shell without `--model`.
672* Dispatch a [subagent](https://code.claude.com/docs/en/sub-agents.md) that sets `model` in its frontmatter, by starting the prompt with its name or mentioning `@name`. While a `/model` choice in the dispatch input applies, the subagent's `model` isn't used, so enter `/model default` there. If you launched with [`claude agents --model`](#dispatch-defaults), the subagent's isn't used either, so run `claude agents` in your shell without `--model`.
673673 
674674### Permission mode, model, and effort
675675 
from line 677
677677 
678678#### Settings and provider
679679 
680A background session reads its [settings](/docs/en/settings.md) from the directory it runs in, the same as if you had started `claude` there with the [configuration flags it carried over](#what-carries-over-when-you-background). This includes [`env` values](/docs/en/settings-reference#env) in project settings, so an `ANTHROPIC_MODEL` or provider variable set there applies to every background session in that directory.
680A background session reads its [settings](https://code.claude.com/docs/en/settings.md) from the directory it runs in, the same as if you had started `claude` there with the [configuration flags it carried over](#what-carries-over-when-you-background). This includes [`env` values](https://code.claude.com/docs/en/settings-reference#env) in project settings, so an `ANTHROPIC_MODEL` or provider variable set there applies to every background session in that directory.
681681 
682A background session also runs with the `PATH` of the shell you dispatched it from, so the commands it runs find the same tools your terminal does. It keeps that shell's cloud provider selection too, such as `CLAUDE_CODE_USE_BEDROCK` or `CLAUDE_CODE_USE_VERTEX`, along with its `ANTHROPIC_DEFAULT_*_MODEL` aliases and any [`CLAUDE_CODE_EXTRA_BODY`](/docs/en/env-vars) override you exported there.
682A background session also runs with the `PATH` of the shell you dispatched it from, so the commands it runs find the same tools your terminal does. It keeps that shell's cloud provider selection too, such as `CLAUDE_CODE_USE_BEDROCK` or `CLAUDE_CODE_USE_VERTEX`, along with its `ANTHROPIC_DEFAULT_*_MODEL` aliases and any [`CLAUDE_CODE_EXTRA_BODY`](https://code.claude.com/docs/en/env-vars) override you exported there.
683683 
684684#### LLM gateway
685685 
686If you route Claude Code through an [LLM gateway](/docs/en/llm-gateway), put the gateway variables in a settings file's `env` block rather than exporting them in your shell, and background sessions read them with the rest of their settings. [Set in a settings file](/docs/en/llm-gateway-connect.md#set-in-a-settings-file) shows the block and which settings file to use for the credential.
686If you route Claude Code through an [LLM gateway](https://code.claude.com/docs/en/llm-gateway), put the gateway variables in a settings file's `env` block rather than exporting them in your shell, and background sessions read them with the rest of their settings. [Set in a settings file](https://code.claude.com/docs/en/llm-gateway-connect.md#set-in-a-settings-file) shows the block and which settings file to use for the credential.
687687 
688688If you export a gateway `ANTHROPIC_BASE_URL` only in your shell instead, it reaches a background session, together with the `ANTHROPIC_CUSTOM_HEADERS` and credential you exported with it, only when the [supervisor](#the-supervisor-process) was itself started from a shell that exported the same gateway, and only in these cases:
689689 
from line 698
698698 
699699#### Permission mode
700700 
701* **Backgrounded with `/bg` or `←`**: Claude Code keeps the [permission mode](/docs/en/permissions.md) the session was in, so one you switched to `acceptEdits` or `auto` stays there after detaching
702* **Dispatched from `claude agents` started in a shell, or with `claude --bg`**: the new session starts the way a new `claude` session in that directory would, unless you dispatched it from an agent view you opened with [dispatch defaults](#dispatch-defaults). [Which permission mode a session starts in](/docs/en/permission-modes.md#which-mode-a-session-starts-in) lists the order
701* **Backgrounded with `/bg` or `←`**: Claude Code keeps the [permission mode](https://code.claude.com/docs/en/permissions.md) the session was in, so one you switched to `acceptEdits` or `auto` stays there after detaching
702* **Dispatched from `claude agents` started in a shell, or with `claude --bg`**: the new session starts the way a new `claude` session in that directory would, unless you dispatched it from an agent view you opened with [dispatch defaults](#dispatch-defaults). [Which permission mode a session starts in](https://code.claude.com/docs/en/permission-modes.md#which-mode-a-session-starts-in) lists the order
703703 
704704For a session you dispatch from an agent view opened with `←`, Claude Code takes the permission mode from the first of these that applies:
705705 
7061. The target directory's [`permissions.defaultMode`](/docs/en/settings-reference#permissions-defaultmode). `auto` and `bypassPermissions` [take effect only from managed settings, a `--settings` file, or `~/.claude/settings.json`](/docs/en/settings-reference#permissions-defaultmode). Claude Code refuses a `defaultMode` from the project's `.claude/settings.json` or `.claude/settings.local.json` that selects a more permissive mode than the session you came from was in.
7061. The target directory's [`permissions.defaultMode`](https://code.claude.com/docs/en/settings-reference#permissions-defaultmode). `auto` and `bypassPermissions` [take effect only from managed settings, a `--settings` file, or `~/.claude/settings.json`](https://code.claude.com/docs/en/settings-reference#permissions-defaultmode). Claude Code refuses a `defaultMode` from the project's `.claude/settings.json` or `.claude/settings.local.json` that selects a more permissive mode than the session you came from was in.
7077072. The permission mode of the session you came from.
708708 
709 If that session was in `bypassPermissions` mode, the new session can start in Manual mode instead, with the notice `Bypass permissions was requested at launch and ignored`. That happens when your acceptance of the bypass disclaimer is only in `.claude/settings.local.json` or a `--settings` file. Continue in Manual mode, or [add that acceptance to `~/.claude/settings.json`](/docs/en/permission-modes#bypass-permissions-ignored-in-a-background-session).
709 If that session was in `bypassPermissions` mode, the new session can start in Manual mode instead, with the notice `Bypass permissions was requested at launch and ignored`. That happens when your acceptance of the bypass disclaimer is only in `.claude/settings.local.json` or a `--settings` file. Continue in Manual mode, or [add that acceptance to `~/.claude/settings.json`](https://code.claude.com/docs/en/permission-modes#bypass-permissions-ignored-in-a-background-session).
710710 
711711When Claude Code refuses a source's mode as too permissive, the next source in the list decides. For example, if you dispatch from a plan-mode session into a directory whose checked-in settings ask for `acceptEdits`, the new session starts in plan mode. If you move that `defaultMode` to `~/.claude/settings.json`, it applies regardless of the permission mode of the session you came from.
712712 
from line 720
720720claude agents --permission-mode plan --model opus --effort high
721721```
722722 
723`--effort` here accepts the same values as the [top-level `--effort` flag](/docs/en/cli-reference#cli-flags), including `ultracode`.
723`--effort` here accepts the same values as the [top-level `--effort` flag](https://code.claude.com/docs/en/cli-reference#cli-flags), including `ultracode`.
724724 
725`--agent` sets the [subagent](/docs/en/sub-agents.md) used when a dispatch prompt doesn't name one, either with `@name` or as the first word. It defaults to the [`agent` setting](/docs/en/settings-reference#agent) if one is set, otherwise the built-in catch-all `claude` agent. Naming a subagent in the dispatch input overrides both.
725`--agent` sets the [subagent](https://code.claude.com/docs/en/sub-agents.md) used when a dispatch prompt doesn't name one, either with `@name` or as the first word. It defaults to the [`agent` setting](https://code.claude.com/docs/en/settings-reference#agent) if one is set, otherwise the built-in catch-all `claude` agent. Naming a subagent in the dispatch input overrides both.
726726 
727`claude agents` also accepts `--dangerously-skip-permissions` as shorthand for `--permission-mode bypassPermissions`, and `--allow-dangerously-skip-permissions` to make `bypassPermissions` available in each dispatched session's `Shift+Tab` cycle without starting in that mode. Both match the [top-level CLI flags](/docs/en/cli-reference.md).
727`claude agents` also accepts `--dangerously-skip-permissions` as shorthand for `--permission-mode bypassPermissions`, and `--allow-dangerously-skip-permissions` to make `bypassPermissions` available in each dispatched session's `Shift+Tab` cycle without starting in that mode. Both match the [top-level CLI flags](https://code.claude.com/docs/en/cli-reference.md).
728728 
729Pass `--restricted` to start every session you dispatch from the view in [restricted mode](/docs/en/cli-reference.md#cli-flags), as if each were launched with the top-level `--restricted` flag. Requires Claude Code v2.1.248 or later.
729Pass `--restricted` to start every session you dispatch from the view in [restricted mode](https://code.claude.com/docs/en/cli-reference.md#cli-flags), as if each were launched with the top-level `--restricted` flag. Requires Claude Code v2.1.248 or later.
730730 
731731The active defaults appear in the footer below the dispatch input.
732732 
733A background session started in `bypassPermissions` mode needs your [acceptance of the bypass disclaimer](/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) on record, since that mode lets a session you aren't watching act without approval. Passing `--dangerously-skip-permissions` or `--permission-mode bypassPermissions` to `claude agents` shows the same disclaimer when you haven't accepted it before, and accepting applies `bypassPermissions` to the sessions you launch from the view. Passing `--allow-dangerously-skip-permissions` shows the same disclaimer too, and accepting makes `bypassPermissions` available in the `Shift+Tab` cycle of those sessions without starting them in it.
733A background session started in `bypassPermissions` mode needs your [acceptance of the bypass disclaimer](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) on record, since that mode lets a session you aren't watching act without approval. Passing `--dangerously-skip-permissions` or `--permission-mode bypassPermissions` to `claude agents` shows the same disclaimer when you haven't accepted it before, and accepting applies `bypassPermissions` to the sessions you launch from the view. Passing `--allow-dangerously-skip-permissions` shows the same disclaimer too, and accepting makes `bypassPermissions` available in the `Shift+Tab` cycle of those sessions without starting them in it.
734734 
735735#### What persists across restarts
736736 
737737The permission mode, model, and effort you chose for a background session, along with the [configuration flags it carries](#what-carries-over-when-you-background), all persist when the supervisor later [stops and restarts](#the-supervisor-process) its process. A model or effort you changed mid-session with `/model` or `/effort` is kept too.
738738 
739If the session took its effort from your settings rather than from `--effort` or `/effort`, Claude Code reads your settings again each time it starts a process for the session. After you edit the saved effort in `settings.json`, the change reaches sessions you background with `←` or `/bg`, and their later restarts. The saved effort is the [`effortLevel`](/docs/en/settings-reference#effortlevel) key or a [`modelSettings`](/docs/en/settings-reference#modelsettings) entry.
739If the session took its effort from your settings rather than from `--effort` or `/effort`, Claude Code reads your settings again each time it starts a process for the session. After you edit the saved effort in `settings.json`, the change reaches sessions you background with `←` or `/bg`, and their later restarts. The saved effort is the [`effortLevel`](https://code.claude.com/docs/en/settings-reference#effortlevel) key or a [`modelSettings`](https://code.claude.com/docs/en/settings-reference#modelsettings) entry.
740740 
741Claude Code also keeps a name you set with [`/rename`](/docs/en/commands) or `Ctrl+R` across that restart, so you can still run [`claude --resume <name>`](/docs/en/sessions#name-your-sessions) to reach the session.
741Claude Code also keeps a name you set with [`/rename`](https://code.claude.com/docs/en/commands) or `Ctrl+R` across that restart, so you can still run [`claude --resume <name>`](https://code.claude.com/docs/en/sessions#name-your-sessions) to reach the session.
742742 
743A prompt you stashed with [`Ctrl+S`](/docs/en/interactive-mode#general-controls) while attached is kept with the session too. Reopen the session after its process was stopped or restarted, and press `Ctrl+S` to restore the stashed text. Pasted content in the stash doesn't survive the restart.
743A prompt you stashed with [`Ctrl+S`](https://code.claude.com/docs/en/interactive-mode#general-controls) while attached is kept with the session too. Reopen the session after its process was stopped or restarted, and press `Ctrl+S` to restore the stashed text. Pasted content in the stash doesn't survive the restart.
744744 
745745### Settings, plugins, and MCP servers
746746 
from line 748
748748 
749749| Flag | Effect |
750750| :- | :- |
751| [`--settings <file-or-json>`](/docs/en/settings) | Override settings for agent view and dispatched sessions |
752| [`--setting-sources <sources>`](/docs/en/cli-reference#cli-flags) | Load only the named settings sources, in agent view and dispatched sessions |
753| [`--add-dir <path>`](/docs/en/permissions#additional-directories-grant-file-access-not-configuration) | Grant file access to an additional directory |
754| [`--plugin-dir <path>`](/docs/en/plugins/create#load-a-directory-or-archive-for-one-session) | Load a plugin from a local directory |
755| [`--mcp-config <file-or-json>`](/docs/en/mcp) | Load MCP servers from a config file or JSON string |
756| `--strict-mcp-config` | Use only the MCP servers from `--mcp-config`, ignoring other MCP configuration. See [Exclusive control with managed-mcp.json](/docs/en/managed-mcp.md#exclusive-control-with-managed-mcp-json) for what the flag does under a managed MCP file |
751| [`--settings <file-or-json>`](https://code.claude.com/docs/en/settings) | Override settings for agent view and dispatched sessions |
752| [`--setting-sources <sources>`](https://code.claude.com/docs/en/cli-reference#cli-flags) | Load only the named settings sources, in agent view and dispatched sessions |
753| [`--add-dir <path>`](https://code.claude.com/docs/en/permissions#additional-directories-grant-file-access-not-configuration) | Grant file access to an additional directory |
754| [`--plugin-dir <path>`](https://code.claude.com/docs/en/plugins/create#load-a-directory-or-archive-for-one-session) | Load a plugin from a local directory |
755| [`--mcp-config <file-or-json>`](https://code.claude.com/docs/en/mcp) | Load MCP servers from a config file or JSON string |
756| `--strict-mcp-config` | Use only the MCP servers from `--mcp-config`, ignoring other MCP configuration. See [Exclusive control with managed-mcp.json](https://code.claude.com/docs/en/managed-mcp.md#exclusive-control-with-managed-mcp-json) for what the flag does under a managed MCP file |
757757 
758758Repeat `--add-dir`, `--plugin-dir`, or `--mcp-config` once per value. `claude agents` doesn't support the space-separated form, such as `--add-dir a b c`.
759759 
from line 803
803803| `state` | Background sessions | One of `working`, `blocked`, `done`, `failed`, or `stopped`. See [Read session state from a script](#read-session-state-from-a-script) for what each value means |
804804| `pid`, `status` | While the process is alive | Process ID and one of `busy`, `waiting`, or `idle` |
805805| `waitingFor` | When `status` is `waiting` | What the session is blocked on: `permission prompt` for an approval, `input needed` for a question from Claude or an MCP server's input request, `sandbox request`, `worker request`, or `dialog open` |
806| `sessionId`, `name` | When set | `sessionId` is the full session UUID, usable with [`claude --resume`](/docs/en/sessions). An interactive session's `name` is its [default display name](/docs/en/sessions.md#name-your-sessions) until you name the session or accept a plan in it |
806| `sessionId`, `name` | When set | `sessionId` is the full session UUID, usable with [`claude --resume`](https://code.claude.com/docs/en/sessions). An interactive session's `name` is its [default display name](https://code.claude.com/docs/en/sessions.md#name-your-sessions) until you name the session or accept a plan in it |
807807 
808808### Read session state from a script
809809 
from line 811
811811 
812812| `state` | What it means |
813813| :- | :- |
814| `working` | A turn is running, or the session is between steps of work it drives on its own, such as a [`/loop`](/docs/en/scheduled-tasks) iteration or a wait on CI. `status` tells you whether its process is `busy` right now |
814| `working` | A turn is running, or the session is between steps of work it drives on its own, such as a [`/loop`](https://code.claude.com/docs/en/scheduled-tasks) iteration or a wait on CI. `status` tells you whether its process is `busy` right now |
815815| `blocked` | The session is waiting on you: a question it asked, a permission or sandbox decision, an error only you can clear such as an expired login, or its first prompt if you started it without one. When the wait is an open prompt in a live process, `waitingFor` names it |
816816| `done` | The last turn finished what you asked for and the session is ready for your next prompt, whether or not its process is still alive |
817817| `failed`, `stopped` | The task ended with an error, or the session was stopped |
from line 826
826826 
827827Claude Code treats every session listed in agent view as a background session, whether or not you're currently attached to it. By contrast, a session started by running `claude` directly is tied to that terminal and ends when it closes, unless you [send it to the background](#from-inside-a-session).
828828 
829To check which kind of session you're in, run [`/status`](/docs/en/commands). The `Session kind` row reads `background job · attached` or `background job · unattended` in a background session, depending on whether a terminal is attached, and `interactive` in any other session.
829To check which kind of session you're in, run [`/status`](https://code.claude.com/docs/en/commands). The `Session kind` row reads `background job · attached` or `background job · unattended` in a background session, depending on whether a terminal is attached, and `interactive` in any other session.
830830 
831831### The supervisor process
832832 
from line 834
834834 
835835Each session is its own Claude Code process under the supervisor, and what happens to that process depends on the session's state:
836836 
837* **Working, paused on a permission prompt or other dialog, or attached**: the process keeps running. A running subagent, workflow, or monitor counts as working, and so does a pending [session-scoped scheduled task](/docs/en/scheduled-tasks.md), such as a `/loop` wakeup.
837* **Working, paused on a permission prompt or other dialog, or attached**: the process keeps running. A running subagent, workflow, or monitor counts as working, and so does a pending [session-scoped scheduled task](https://code.claude.com/docs/en/scheduled-tasks.md), such as a `/loop` wakeup.
838838* **Finished or waiting for your next message, and unattached for about an hour**: the supervisor stops the process to free resources. A session that ended its turn by asking you a question counts as waiting for your next message. The conversation stays on disk, and the next time you attach or reply, the session resumes where it left off. Pin a session with `Ctrl+T` to keep its process running.
839839* **Exited unexpectedly while the supervisor is running**: the supervisor restarts the process. Ending a session you backgrounded yourself with `←` or `/background`, for example with `kill`, marks it stopped instead of restarting it. For sessions that ended with a shutdown, see [Sessions show as failed or stopped after shutdown](#sessions-show-as-failed-after-shutdown).
840840* **After an auto-update**: the supervisor restarts itself onto the new version and moves idle sessions over in the background. Sessions that are working, waiting on you, or attached aren't interrupted.
841841* **The supervisor itself stops**, for example because its process was ended from outside Claude Code: on macOS and Linux, your sessions stop unless a new supervisor connects within about a minute. To start one, run `claude agents` in your shell. After that minute, see [Keep sessions running after the supervisor stops](#keep-sessions-running-after-the-supervisor-stops).
842842 
843When a session's process stops or restarts, the background shell commands, dynamic workflows, and background subagents Claude started in it carry over to its next process; running monitors and shell commands a subagent started stop with the process. Deleting the session stops everything it carried over. To stop all of it with the process instead, set [`CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF`](/docs/en/env-vars#variables) to `1`.
843When a session's process stops or restarts, the background shell commands, dynamic workflows, and background subagents Claude started in it carry over to its next process; running monitors and shell commands a subagent started stop with the process. Deleting the session stops everything it carried over. To stop all of it with the process instead, set [`CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF`](https://code.claude.com/docs/en/env-vars#variables) to `1`.
844844 
845845The supervisor and its sessions authenticate with the same stored credentials as your interactive sessions. For which settings and shell variables reach a session, including `PATH`, see [Settings and provider](#settings-and-provider). For gateway endpoints, see [LLM gateway](#llm-gateway).
846846 
from line 858
858858 
859859### Where state is stored
860860 
861Session state is stored under your Claude Code config directory. If you set [`CLAUDE_CONFIG_DIR`](/docs/en/env-vars), the supervisor uses that directory instead of `~/.claude` and runs as a separate instance with its own sessions.
861Session state is stored under your Claude Code config directory. If you set [`CLAUDE_CONFIG_DIR`](https://code.claude.com/docs/en/env-vars), the supervisor uses that directory instead of `~/.claude` and runs as a separate instance with its own sessions.
862862 
863863| Path | Contents |
864864| :- | :- |
from line 877
877877 
878878### Turn off agent view
879879 
880To turn off background agents and agent view entirely, set the `disableAgentView` [setting](/docs/en/settings.md) to `true` or set the `CLAUDE_CODE_DISABLE_AGENT_VIEW` environment variable. Administrators can enforce this through [managed settings](/docs/en/managed-settings.md).
880To turn off background agents and agent view entirely, set the `disableAgentView` [setting](https://code.claude.com/docs/en/settings.md) to `true` or set the `CLAUDE_CODE_DISABLE_AGENT_VIEW` environment variable. Administrators can enforce this through [managed settings](https://code.claude.com/docs/en/managed-settings.md).
881881 
882882## Troubleshooting
883883 
from line 895
895895 
896896If you press `←` to background the current session and Claude Code shows a `Background this session?` dialog, the session has in-flight background work that backgrounding would stop, restart, or leave running unattended, and Claude Code asks before it does any of those:
897897 
898* **Work that can't move**: the session has work that can't move to the background session, such as a running [monitor](/docs/en/tools-reference.md#monitor-tool). The dialog names the background work Claude Code would stop and, separately, counts the tasks that carry over.
899* **A workflow with running subagents**: a [dynamic workflow](/docs/en/workflows.md) still has subagents running. The workflow itself carries over, but its running subagents restart from the beginning, and the dialog says how many.
900* **Automatic artifact replies**: Claude is [replying to comments on an artifact on its own](/docs/en/artifacts.md#let-claude-reply-to-comments-on-its-own). Those replies continue in the background session, and the dialog says so.
898* **Work that can't move**: the session has work that can't move to the background session, such as a running [monitor](https://code.claude.com/docs/en/tools-reference.md#monitor-tool). The dialog names the background work Claude Code would stop and, separately, counts the tasks that carry over.
899* **A workflow with running subagents**: a [dynamic workflow](https://code.claude.com/docs/en/workflows.md) still has subagents running. The workflow itself carries over, but its running subagents restart from the beginning, and the dialog says how many.
900* **Automatic artifact replies**: Claude is [replying to comments on an artifact on its own](https://code.claude.com/docs/en/artifacts.md#let-claude-reply-to-comments-on-its-own). Those replies continue in the background session, and the dialog says so.
901901 
902902Run `/tasks` to see everything that's running, then confirm to background anyway or choose `Stay` to let the work finish first. See [What carries over when you background](#what-carries-over-when-you-background) for which kinds of work carry over and which Claude Code stops.
903903 
904904### The conversation says a background agent `was carried into this session and not resumed`
905905 
906This notice names a background [subagent](/docs/en/sub-agents.md) that isn't running in this session.
906This notice names a background [subagent](https://code.claude.com/docs/en/sub-agents.md) that isn't running in this session.
907907 
908908Claude sees the notice and replies on its own, so you don't need to prompt it. If you still need that subagent's work after reading Claude's reply, ask Claude for it.
909909 
from line 918
918918* Within 48 hours, the session shows as failed. Attach or reply to it and it restarts from its saved conversation. To pick the interrupted work back up, send it a reply asking it to continue.
919919* Past 48 hours, such as after the machine was off for days, the session shows as stopped with `ended while the background service was off`. Press `Enter` on the row and the footer shows `Press enter again to resume this session (it ended while the background service was off), or ctrl+x to delete it.` Press `Enter` on the same row again to resume its saved conversation. A reply, or `claude attach <id>`, resumes it without that footer prompt.
920920 
921When [transcript cleanup](/docs/en/settings-reference.md#cleanupperioddays) has removed a stopped session's saved conversation, Claude Code refuses to open the row: the message says there is nothing to resume. `claude rm <id>` deletes the row, except in the [kept cases](#what-deleting-a-session-removes) described above, and `claude respawn <id>` runs its original prompt again. See [This session's saved conversation is no longer on disk](/docs/en/errors.md#this-sessions-saved-conversation-is-no-longer-on-disk).
921When [transcript cleanup](https://code.claude.com/docs/en/settings-reference.md#cleanupperioddays) has removed a stopped session's saved conversation, Claude Code refuses to open the row: the message says there is nothing to resume. `claude rm <id>` deletes the row, except in the [kept cases](#what-deleting-a-session-removes) described above, and `claude respawn <id>` runs its original prompt again. See [This session's saved conversation is no longer on disk](https://code.claude.com/docs/en/errors.md#this-sessions-saved-conversation-is-no-longer-on-disk).
922922 
923923Sleep alone doesn't stop sessions. Sessions are preserved across sleep and the supervisor reconnects to them on wake.
924924 
from line 940
940940 
941941Press `Enter` on the same row again to restart the session with an empty conversation, or run `claude respawn <id>` from the shell.
942942 
943See the [error reference](/docs/en/errors.md#this-session-has-no-saved-transcript) for details.
943See the [error reference](https://code.claude.com/docs/en/errors.md#this-session-has-no-saved-transcript) for details.
944944 
945945### The terminal host died or the session stopped responding
946946 
947The [supervisor](#the-supervisor-process) runs each background session's terminal in its own host process. When that process dies or stops responding, Claude Code shows the reason and offers a restart; in both cases the conversation is saved and the restart resumes it. The [error reference](/docs/en/errors.md#terminal-host-process-died) quotes the full messages.
947The [supervisor](#the-supervisor-process) runs each background session's terminal in its own host process. When that process dies or stops responding, Claude Code shows the reason and offers a restart; in both cases the conversation is saved and the restart resumes it. The [error reference](https://code.claude.com/docs/en/errors.md#terminal-host-process-died) quotes the full messages.
948948 
949949Claude Code never restarts a row running a [shell command](#run-a-shell-command), from `Enter` or from `claude attach`, because that would run the command again; the row's message and `claude attach` both say the command isn't run again.
950950 
from line 985
985985 
986986Within [about a minute](#the-supervisor-process), run `claude agents` or `claude --bg` in your shell to start a fresh supervisor that reads your stored credentials. If you authenticate with an environment variable such as `ANTHROPIC_API_KEY` rather than `/login`, run that next command from a shell where the variable is set.
987987 
988See the [error reference](/docs/en/errors.md#could-not-resolve-authentication-method) for the full list of causes and fixes.
988See the [error reference](https://code.claude.com/docs/en/errors.md#could-not-resolve-authentication-method) for the full list of causes and fixes.
989989 
990990### A background session shows `No LLM gateway`
991991 
992If a background session shows [`No LLM gateway`](/docs/en/errors#no-llm-gateway-opened-from-another-folder), it didn't get your gateway `ANTHROPIC_BASE_URL`, so its requests fail. Claude Code withheld it because you dispatched, woke, or restarted the session from a directory other than the folder the message names.
992If a background session shows [`No LLM gateway`](https://code.claude.com/docs/en/errors#no-llm-gateway-opened-from-another-folder), it didn't get your gateway `ANTHROPIC_BASE_URL`, so its requests fail. Claude Code withheld it because you dispatched, woke, or restarted the session from a directory other than the folder the message names.
993993 
994994You see the message, for example, after you dispatch into a repository with [`@<repo>`](#dispatch-to-a-specific-directory) or wake a stopped session by running `claude attach` from another directory. To give the session your gateway, pick the fix that matches where your gateway is set:
995995 
996996* **You exported the gateway in your terminal**: in a terminal where you've exported the gateway variables, `cd` to the folder the message names and run the message's [`claude respawn <id>`](#manage-sessions-from-the-shell) command.
997997 * The gateway reaches the session only when the [supervisor](#the-supervisor-process) was itself started from a shell that exported the same gateway. If the supervisor wasn't, restart it from the terminal where you ran the respawn command, as [Dispatch fails with `Could not resolve authentication method`](#dispatch-fails-with-could-not-resolve-authentication-method) describes, then run that command again.
998* **You used agent view in a project whose settings set the gateway**: put `ANTHROPIC_BASE_URL` and its credential in [a settings file's `env` block](/docs/en/llm-gateway-connect#set-in-a-settings-file). Use `~/.claude/settings.json`, or `.claude/settings.local.json` in the session's own project, both of which a respawned session reads. Then run [`claude respawn <id>`](#manage-sessions-from-the-shell) in your shell from any directory to restart this session on the gateway.
998* **You used agent view in a project whose settings set the gateway**: put `ANTHROPIC_BASE_URL` and its credential in [a settings file's `env` block](https://code.claude.com/docs/en/llm-gateway-connect#set-in-a-settings-file). Use `~/.claude/settings.json`, or `.claude/settings.local.json` in the session's own project, both of which a respawned session reads. Then run [`claude respawn <id>`](#manage-sessions-from-the-shell) in your shell from any directory to restart this session on the gateway.
999999 
10001000### Background sessions can't read Desktop, Documents, or Downloads on macOS
10011001 
from line 1017
10171017 
10181018Deleting a session in agent view removes the worktree Claude created for it, but [some deletes keep the worktree or leave its directory on disk](#what-deleting-a-session-removes), so leftover directories can accumulate. Directories git no longer recognizes don't appear in `git worktree list`, so remove those by hand.
10191019 
1020List leftover entries with `git worktree list` in the project directory and remove each with `git worktree remove <path>`. See [Clean up worktrees](/docs/en/worktrees.md#clean-up-worktrees).
1020List leftover entries with `git worktree list` in the project directory and remove each with `git worktree remove <path>`. See [Clean up worktrees](https://code.claude.com/docs/en/worktrees.md#clean-up-worktrees).
10211021 
10221022## Limitations
10231023 
from line 1031
10311031 
10321032For other ways to run Claude in parallel, and for passing findings between the sessions you run, see:
10331033 
1034* [Run agents in parallel](/docs/en/agents.md): compare agent view with subagents, agent teams, and worktrees
1035* [Cross-session messaging](/docs/en/cross-session-messaging.md): have your sessions pass findings to each other
1036* [Agent teams](/docs/en/agent-teams.md): coordinate multiple sessions that message each other
1037* [Use Claude Code in the cloud](/docs/en/claude-code-on-the-web.md): run sessions in a managed cloud environment instead of locally
1038* [Projects](/docs/en/claude-projects.md): have Claude coordinate parallel cloud sessions from one conversation and tell you which need you
1034* [Run agents in parallel](https://code.claude.com/docs/en/agents.md): compare agent view with subagents, agent teams, and worktrees
1035* [Cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md): have your sessions pass findings to each other
1036* [Agent teams](https://code.claude.com/docs/en/agent-teams.md): coordinate multiple sessions that message each other
1037* [Use Claude Code in the cloud](https://code.claude.com/docs/en/claude-code-on-the-web.md): run sessions in a managed cloud environment instead of locally
1038* [Projects](https://code.claude.com/docs/en/claude-projects.md): have Claude coordinate parallel cloud sessions from one conversation and tell you which need you
10391039 
10401040## Version history
10411041 
from line 1046
10461046| v2.1.299 | [`/effort` and `/fast` in the dispatch input](#set-the-model-effort-and-fast-mode) set the effort level and fast mode for the sessions you dispatch next. `/model`, `/effort`, or `/fast` typed with no value opens a picker. |
10471047| v2.1.299 | Claude Code [reads `--bg` and `--background` as the flag](#from-your-shell) only before any bare `--` separator and outside another flag's value, and refuses an ambiguous position instead of guessing. Before this release, a prompt or reply of `--bg` or `--background` to a background session could be taken for the flag. That could start new background sessions over and over instead of delivering the text. |
10481048| v2.1.296 | A prompt or `!` shell command that you enter [as the session moves to the background](#switch-sessions-without-leaving-the-terminal) is stopped or left unsent, and its text is kept in prompt history. Before this release, the response or command kept running where you could no longer see it, and a prompt sent right after `←` could run a second time unseen. A prompt typed while `SessionStart` hooks were still running was lost: not sent, and not in prompt history. |
1049| v2.1.295 | `Ctrl+C` at the idle prompt of an [attached background session](#attach-to-a-session) leaves the pending wakeup of a [self-paced `/loop`](/docs/en/scheduled-tasks#let-claude-choose-the-interval) alone, so pressing it twice detaches and the loop keeps running. `Esc` at that prompt [stops the self-paced loop](/docs/en/scheduled-tasks.md#stop-a-loop) and shows a `Pending wakeup cancelled` notice. Before this release, the first `Ctrl+C` could end a self-paced loop without saying so, and `Esc` didn't stop one that had moved to the background with the session. |
1049| v2.1.295 | `Ctrl+C` at the idle prompt of an [attached background session](#attach-to-a-session) leaves the pending wakeup of a [self-paced `/loop`](https://code.claude.com/docs/en/scheduled-tasks#let-claude-choose-the-interval) alone, so pressing it twice detaches and the loop keeps running. `Esc` at that prompt [stops the self-paced loop](https://code.claude.com/docs/en/scheduled-tasks.md#stop-a-loop) and shows a `Pending wakeup cancelled` notice. Before this release, the first `Ctrl+C` could end a self-paced loop without saying so, and `Esc` didn't stop one that had moved to the background with the session. |
10501050| v2.1.295 | On macOS and Linux, when `claude agents` exits while no [supervisor](#keep-sessions-running-after-the-supervisor-stops) is running, it doesn't start a new one on its own. Running sessions then stop about a minute later unless you run `claude agents` again, and agent view can print a notice saying so as it exits. Before this release, the exiting `claude agents` started a new supervisor. |
10511051| v2.1.295 | On macOS with the native installer, background sessions that restart together after an update run under the same Claude Code entry that holds the [protected-folder access](#background-sessions-can’t-read-desktop-documents-or-downloads-on-macos) you granted. Before this release, those sessions could run under the binary's own path instead. macOS lists that path as a separate entry, so the folder-access prompts could come back after an update. |
10521052| v2.1.290 | [`claude attach` and `claude logs`](#manage-sessions-from-the-shell) can take part of a session's name in place of the ID. |
10531053| v2.1.290 | `/model`, `/effort`, `/rename`, and `/usage` sent as a [peek reply](#peek-and-reply) to a working session run right away. |
10541054| v2.1.290 | A [peek reply](#peek-and-reply) that can't be delivered is no longer saved for the next restart when it starts with `/`, or when it answers a question with predefined choices while the session's process is running. |
1055| v2.1.288 | `Ctrl+F` finds sessions by name, and `Alt+↑` / `Alt+↓` jump between group headers. Both, and `Ctrl+R`, can be [rebound](/docs/en/keybindings.md#agents-actions). |
1055| v2.1.288 | `Ctrl+F` finds sessions by name, and `Alt+↑` / `Alt+↓` jump between group headers. Both, and `Ctrl+R`, can be [rebound](https://code.claude.com/docs/en/keybindings.md#agents-actions). |
10561056| v2.1.287 | The [`n:<text>` filter](#filter-sessions) finds sessions by name or first prompt. While any filter is active, groups you collapsed expand to show their matches and the first match is selected, so `Enter` opens it. |
10571057| v2.1.287 | A command sent as a [peek reply](#peek-and-reply) runs when the session's current turn ends, including the commands that run as soon as you type them at a session's own prompt. A reply that is exactly `/stop` stops the session at once. |
1058| v2.1.281 | A [`--setting-sources`](/docs/en/cli-reference#cli-flags) restriction [carries over](#what-carries-over-when-you-background) to a session you background with `←` or `/bg` and to the sessions you dispatch from agent view. Before this release, the spawned session loaded every settings source. |
1059| v2.1.281 | `claude --bg`, and the commands that restart a session, check workspace trust for the session's directory first. From a terminal in that directory, [the trust dialog appears](#from-your-shell) if you haven't accepted it; where no dialog can appear, such as in a script, the command exits with a [`Workspace not trusted`](/docs/en/errors#workspace-not-trusted-when-dispatching-a-background-session) error. |
1058| v2.1.281 | A [`--setting-sources`](https://code.claude.com/docs/en/cli-reference#cli-flags) restriction [carries over](#what-carries-over-when-you-background) to a session you background with `←` or `/bg` and to the sessions you dispatch from agent view. Before this release, the spawned session loaded every settings source. |
1059| v2.1.281 | `claude --bg`, and the commands that restart a session, check workspace trust for the session's directory first. From a terminal in that directory, [the trust dialog appears](#from-your-shell) if you haven't accepted it; where no dialog can appear, such as in a script, the command exits with a [`Workspace not trusted`](https://code.claude.com/docs/en/errors#workspace-not-trusted-when-dispatching-a-background-session) error. |
10601060| v2.1.274 | After an auto-update, an agent view you've been away from for about an hour can relaunch itself onto the new build. When it does, it keeps the [dispatch defaults](#dispatch-defaults) you opened it with: `--model`, `--effort`, `--permission-mode`, `--allow-dangerously-skip-permissions`, and `--agent`. Before this release, the relaunched view kept only `--cwd` and configuration flags such as `--settings` and `--mcp-config`, so sessions you dispatched afterward started without those defaults. |
10611061| v2.1.274 | When a [delete is refused](#what-deleting-a-session-removes) because git or your `WorktreeRemove` hook couldn't remove the worktree, a checked-out submodule that Claude Code verifies has no uncommitted changes to tracked files doesn't block the offer to delete again and remove the directory anyway. Uncommitted work inside a checked-out submodule counts as uncommitted changes, and the message names the submodule. Before this release, any submodule checkout in the worktree blocked the offer, with a message saying the worktree contains a nested repository. |
10621062| v2.1.268 | When a [delete is refused](#what-deleting-a-session-removes) because git or your `WorktreeRemove` hook couldn't remove the worktree, the message names the cause, including how a hook ended and the start of its stderr. For a linked worktree under the repository's `.claude/worktrees/` with no uncommitted changes to tracked files, no nested repository inside it, and no other session's record naming it, deleting the session again removes the directory anyway, from agent view or with `claude rm <id> --force-remove-worktree <worktree-id>`. Before this release, the row showed only `worktree could not be removed (WorktreeRemove hook failed)` or git's error, the hook's stderr went only to the debug log, and deleting again was refused the same way. |
10631063| v2.1.268 | After the first `←` shows `Press ← again to open agents`, or `Press ← again to go back to agents` in an attached session, [the first press that comes at least a second later switches](#switch-sessions-without-leaving-the-terminal), even when quicker presses in between were ignored. Before this release, each ignored press restarted the wait, so pressing `←` again at a steady pace didn't switch until you paused for over a second. |
1064| v2.1.260 | When you [background a session](#from-inside-a-session), your other sessions' [agent listing](/docs/en/cross-session-messaging.md#see-which-sessions-claude-can-reach) shows the conversation once, as its background session, and their messages to it no longer reach the terminal you moved it from. Before this release, that terminal could stay listed as a second interactive session under the conversation's name, and a session that had messaged the conversation before the move kept delivering to that terminal. |
1064| v2.1.260 | When you [background a session](#from-inside-a-session), your other sessions' [agent listing](https://code.claude.com/docs/en/cross-session-messaging.md#see-which-sessions-claude-can-reach) shows the conversation once, as its background session, and their messages to it no longer reach the terminal you moved it from. Before this release, that terminal could stay listed as a second interactive session under the conversation's name, and a session that had messaged the conversation before the move kept delivering to that terminal. |
10651065| v2.1.260 | When a [delete is refused over unpushed commits](#what-deleting-a-session-removes), the message names the worktree's branch and how many commits are unpushed, and deleting the session again discards the worktree and its commits. Before this release, the refusal said only `worktree has commits that are not pushed anywhere`, deleting again was refused the same way, and deleting the session required pushing the commits or removing the worktree by hand. |
10661066| v2.1.257 | `←` [detaches from an attached session while the `/btw` overlay is open](#attach-to-a-session), even mid-answer, and the overlay reopens when you next attach. Before this release, `←` didn't detach while the overlay was open. |
10671067| v2.1.257 | When you run [`claude --resume <session-id> --bg`](#from-your-shell), Claude Code continues that session under its own ID, or starts a copy under a new ID and prints a `note:` line explaining why. `--continue`, a bare `--resume`, and `--resume` with a name or path start a copy with the same note. Before this release, `--resume` with `--bg` always started a copy under a new ID and said nothing. |
10681068| v2.1.257 | When you dispatch a session from an agent view you opened with `←`, Claude Code starts it in [the permission mode the target directory configures](#permission-mode) through `permissions.defaultMode`. When the directory doesn't set one, the permission mode of the session you came from applies. Before this release, the dispatched session always started in the permission mode of the session you came from, overriding it. |
10691069| v2.1.257 | `Ctrl+S`, `Ctrl+T`, and `Ctrl+G` in agent view [follow your `keybindings.json`](#keyboard-shortcuts): `Ctrl+S` and `Ctrl+T` through the `Agents` context's `agents:switchView` and `agents:togglePin` actions, and `Ctrl+G` through the `Chat` context's `chat:externalEditor` binding. Before this release, agent view ignored `keybindings.json` and these keys were fixed. |
1070| v2.1.257 | Starting the [background service](#the-supervisor-process) recovers from two failure causes. On a macOS npm installation, a start during a self-update [waits for the install](/docs/en/errors.md#eacces-when-starting-a-background-session) instead of running the placeholder that npm lays down while replacing the binary. On Windows, a stale `daemon.lock` written before the machine last booted, or whose recorded process ID now belongs to a different process, is replaced. Before this release, the macOS start failed with `Error: claude native binary not installed.` during the install window, and the Windows lock made every start fail with [`exited before it became reachable`](/docs/en/errors#background-service-exited-before-it-became-reachable) until you deleted `~/.claude/daemon.lock`. |
1071| v2.1.257 | When you open or dispatch a background session while another Claude Code process is downloading an npm update, Claude Code [keeps waiting up to two minutes](/docs/en/errors.md#eacces-when-starting-a-background-session) while the install runs, then fails saying `Claude Code is being updated by npm on this machine`. Before this release, the wait stopped at ten seconds, so the open failed with `Couldn't start the background service` while the download was still running. |
1072| v2.1.257 | A background session holding a [cross-session message](/docs/en/cross-session-messaging.md#control-inbound-messages) for your approval shows `approve message from` on its `Needs input` row, with the sender's address and the name the sender claims. Before this release, the row moved to `Needs input` but kept its previous text, so nothing in `claude agents` named the waiting message or its sender. |
1070| v2.1.257 | Starting the [background service](#the-supervisor-process) recovers from two failure causes. On a macOS npm installation, a start during a self-update [waits for the install](https://code.claude.com/docs/en/errors.md#eacces-when-starting-a-background-session) instead of running the placeholder that npm lays down while replacing the binary. On Windows, a stale `daemon.lock` written before the machine last booted, or whose recorded process ID now belongs to a different process, is replaced. Before this release, the macOS start failed with `Error: claude native binary not installed.` during the install window, and the Windows lock made every start fail with [`exited before it became reachable`](https://code.claude.com/docs/en/errors#background-service-exited-before-it-became-reachable) until you deleted `~/.claude/daemon.lock`. |
1071| v2.1.257 | When you open or dispatch a background session while another Claude Code process is downloading an npm update, Claude Code [keeps waiting up to two minutes](https://code.claude.com/docs/en/errors.md#eacces-when-starting-a-background-session) while the install runs, then fails saying `Claude Code is being updated by npm on this machine`. Before this release, the wait stopped at ten seconds, so the open failed with `Couldn't start the background service` while the download was still running. |
1072| v2.1.257 | A background session holding a [cross-session message](https://code.claude.com/docs/en/cross-session-messaging.md#control-inbound-messages) for your approval shows `approve message from` on its `Needs input` row, with the sender's address and the name the sender claims. Before this release, the row moved to `Needs input` but kept its previous text, so nothing in `claude agents` named the waiting message or its sender. |
10731073| v2.1.257 | A prompt stashed with `Ctrl+S` inside an opened background session [is kept with the session](#what-persists-across-restarts), so `Ctrl+S` restores it after the session's process is stopped and started again. Before this release, the stash lived only in the running process and was lost when the session went idle long enough for its process to stop, or when it was stopped and then reopened. |
10741074| v2.1.251 | In a background session that hasn't [moved into a worktree](#how-file-edits-are-isolated), Claude and the subagents it spawns can edit files inside a linked git worktree. |
10751075| v2.1.251 | Claude Code forwards a cloud provider gateway exported in the shell you dispatch from, such as `ANTHROPIC_VERTEX_BASE_URL` or `ANTHROPIC_BEDROCK_BASE_URL` with its auth-bypass flag, to [the session's worker](#llm-gateway) under the same conditions as `ANTHROPIC_BASE_URL`. Before this release, if you backgrounded or dispatched from a shell authenticated only through such a gateway, every request the session made failed, because the endpoint and flag were dropped from its environment. |
1076| v2.1.251 | When a background session starts while another Claude Code process is refreshing a [plugin marketplace](/docs/en/plugins/overview.md), such as a sibling session running the [marketplace auto-update](/docs/en/plugins/install.md#keep-plugins-updated), Claude Code keeps that marketplace's plugins available. Before this release, such a session could start without any of that marketplace's skills, agents, hooks, and MCP servers and stay that way for its whole run. |
1076| v2.1.251 | When a background session starts while another Claude Code process is refreshing a [plugin marketplace](https://code.claude.com/docs/en/plugins/overview.md), such as a sibling session running the [marketplace auto-update](https://code.claude.com/docs/en/plugins/install.md#keep-plugins-updated), Claude Code keeps that marketplace's plugins available. Before this release, such a session could start without any of that marketplace's skills, agents, hooks, and MCP servers and stay that way for its whole run. |
10771077| v2.1.248 | `Shift+Enter` in the [dispatch input](#keyboard-shortcuts) inserts a newline, matching the main prompt, and `Ctrl+Enter` dispatches and attaches immediately in terminals where the `?` overlay lists `ctrl+enter to start and open`. Before this release, `Shift+Enter` dispatched and attached. |
10781078| v2.1.248 | [Deleting a session](#what-deleting-a-session-removes) succeeds when the worktree's commits are already on the local copy of your `origin` remote's default branch and your main checkout has that branch checked out; before this release, the delete was refused with `has commits that are not pushed anywhere`. |
1079| v2.1.248 | A session backgrounded with `←` or `/background` holds the [`git worktree lock`](/docs/en/worktrees#clean-up-subagent-and-background-session-worktrees) on its worktree while it runs; before this release, backgrounding released the lock, and cleanup or `git worktree remove` could remove the worktree under the running session. |
1079| v2.1.248 | A session backgrounded with `←` or `/background` holds the [`git worktree lock`](https://code.claude.com/docs/en/worktrees#clean-up-subagent-and-background-session-worktrees) on its worktree while it runs; before this release, backgrounding released the lock, and cleanup or `git worktree remove` could remove the worktree under the running session. |
10801080| v2.1.248 | A background session that wasn't waiting on your input and is found dead more than 48 hours after its last activity, such as after the machine was off for days, [shows as stopped](#sessions-show-as-failed-after-shutdown) with `ended while the background service was off`, and `Enter` on it asks before resuming its saved conversation. Before this release, such a session reappeared as a fresh failure sorted to the top of the list, and a single `Enter` pulled the weeks-old conversation into the foreground. |
10811081| v2.1.248 | Opening a stopped row whose conversation [you resumed in another terminal](#opening-a-session-says-the-conversation-is-already-open) is refused with `Can't open — this session is running in another terminal`, and the row shows `Open in a terminal` instead of showing under `Working`. Before this release, opening the row started a second process writing to the same conversation. |
10821082| v2.1.248 | A background session waiting on a permission decision while a `PermissionRequest` or `PreToolUse` hook printed an invalid answer [names the hook event and the schema error on its row](#peek-and-reply). Before this release, the row showed only the pending request. |
10831083| v2.1.248 | On Windows, `claude agents` responds to the keyboard when launched in a terminal tab that an earlier program left in win32-input-mode. Before this release, Claude Code didn't decode the key records such a tab sends. |
10841084| v2.1.247 | On Linux and WSL, a session [whose terminal host process died](#the-terminal-host-died-or-the-session-stopped-responding) fails within seconds with the reason. An open that produces no output ends after about ten seconds with a restart offer, and `Enter` on the row restarts the session with its conversation; `claude attach <id>` reports the cause and exits. Before this release, opening such a session showed `opening… · esc to cancel` indefinitely and `claude attach <id>` waited without reporting an error. |
1085| v2.1.246 | On an npm installation, when the [background service](#the-supervisor-process) fails to start while `npm install -g @anthropic-ai/claude-code` is replacing the binary, Claude Code waits up to ten seconds for the install to finish and retries before reporting [`EACCES: permission denied`](/docs/en/errors#eacces-when-starting-a-background-session). |
1086| v2.1.246 | When the [background service](#the-supervisor-process) process dies after printing an error, Claude Code reports the failure and [quotes the service's first error line](/docs/en/errors.md#background-service-exited-before-it-became-reachable). |
1085| v2.1.246 | On an npm installation, when the [background service](#the-supervisor-process) fails to start while `npm install -g @anthropic-ai/claude-code` is replacing the binary, Claude Code waits up to ten seconds for the install to finish and retries before reporting [`EACCES: permission denied`](https://code.claude.com/docs/en/errors#eacces-when-starting-a-background-session). |
1086| v2.1.246 | When the [background service](#the-supervisor-process) process dies after printing an error, Claude Code reports the failure and [quotes the service's first error line](https://code.claude.com/docs/en/errors.md#background-service-exited-before-it-became-reachable). |
10871087| v2.1.246 | If your machine sleeps while the [background service](#the-supervisor-process) is starting, Claude Code retries the start once instead of failing. |
10881088| v2.1.246 | Claude Code waits about two minutes instead of 45 seconds for a newly started [background service](#the-supervisor-process) that is alive but slow to accept connections. |
10891089| v2.1.246 | The [background service](#the-supervisor-process) starts from your home directory, so on macOS and Linux a starting directory that was deleted or moved no longer blocks the start. |
10901090| v2.1.246 | `/fork` [copies the full conversation](#copy-the-session-with-%2Ffork) from a session that itself started as a copy and hasn't recorded a new prompt since: a `/fork` copy you attached to, a session reattached after `←` or `/background` moved it to the background, or a session started with `claude --resume <id> --fork-session`. Before this release, if you ran `/fork` in such a session before sending it a new prompt, Claude Code printed the normal confirmation but started the copy with an empty conversation. Moving such a session to the background with `←` or `/background` lost the conversation the same way. |
1091| v2.1.246 | When you open a session you just dispatched while its worker process is still starting, such as by pressing `Enter` on its row, Claude Code waits for the process and then attaches. Before this release, if you pressed `Enter` while the process was still starting, Claude Code could stop the session with [`Session <id> was stopped while the respawn was in flight`](/docs/en/errors#session-was-stopped-while-the-respawn-was-in-flight). |
1091| v2.1.246 | When you open a session you just dispatched while its worker process is still starting, such as by pressing `Enter` on its row, Claude Code waits for the process and then attaches. Before this release, if you pressed `Enter` while the process was still starting, Claude Code could stop the session with [`Session <id> was stopped while the respawn was in flight`](https://code.claude.com/docs/en/errors#session-was-stopped-while-the-respawn-was-in-flight). |
10921092| v2.1.246 | When you [background](#from-inside-a-session) a named session, Claude Code lists it once, and when you background the same conversation again, it numbers the new row's name, such as `my-session (2)`, with the existing row keeping its name. Before this release, the terminal you pressed `←` in could appear in `claude agents --json` as a second session under the same name, and if you backgrounded the same conversation again, Claude Code added another row under the identical name. |
1093| v2.1.239 | With [vim editor mode](/docs/en/interactive-mode.md#vim-editor-mode) on, pressing `Esc` in agent view's input switches from INSERT to NORMAL mode and keeps your text, matching the main prompt; in NORMAL mode with text still in the input, pressing `Esc` clears it, and pressing `Esc` on an empty input exits, as the [`Esc` shortcut](#keyboard-shortcuts) describes. Before this release, `Esc` cleared the input. |
1093| v2.1.239 | With [vim editor mode](https://code.claude.com/docs/en/interactive-mode.md#vim-editor-mode) on, pressing `Esc` in agent view's input switches from INSERT to NORMAL mode and keeps your text, matching the main prompt; in NORMAL mode with text still in the input, pressing `Esc` clears it, and pressing `Esc` on an empty input exits, as the [`Esc` shortcut](#keyboard-shortcuts) describes. Before this release, `Esc` cleared the input. |
10941094| v2.1.233 | For a session linked to a GitLab merge request, Claude Code writes the row's label in GitLab's `!1234` reference syntax. You can also paste the merge request's URL into the [dispatch input](#filter-sessions) to select that session. Before this release, the label rendered as `#1234`, and a pasted merge request URL matched a session only when its first prompt contained the URL. |
10951095| v2.1.227 | [Deleting a session](#what-deleting-a-session-removes) keeps the session and its worktree while another live Claude Code session is running inside that worktree directory. Agent view shows `not deleted` on the row and the reason in the footer, and `claude rm` prints `kept <id>` with the reason, which names the other session's process ID. Before this release, deleting the session removed the worktree while the other session was still working in it. |
1096| v2.1.225 | `claude agents` in a directory you haven't trusted shows the same [workspace trust dialog](/docs/en/permissions.md#project-allow-rules-and-workspace-trust) that `claude` shows on startup, before agent view opens. Accepting saves trust for that workspace; declining exits without opening agent view. Before this release, `claude agents` opened without asking, so sessions you dispatched from it ran in a directory you'd never been asked to trust. With the list grouped by directory, hovering the mouse over a row highlights it without changing the [dispatch target](#dispatch-to-a-specific-directory); selecting a row with the arrow keys or a click still changes the target. Before this release, moving the mouse over a session in another project silently changed the directory the next dispatched session started in. |
1097| v2.1.221 | `/status` shows a `Session kind` row: `background job · attached` or `background job · unattended` in a background session, depending on whether a terminal is attached, and `interactive` in any other session. Before this release, `/status` didn't report the session kind. `/fork`: Claude Code instructs [the copy](#from-inside-a-session) to isolate its work from the original session's: the copy creates a worktree of its own before making code changes, stays out of the original session's worktree, and bases a new branch on the original's branch when its task builds on that work. See the linked section for the exact conditions. Before this release, the copy received no isolation instruction and could end up editing the worktree or checkout the original session was still working in. With [vim editor mode](/docs/en/interactive-mode.md#vim-editor-mode) on, pressing `←` right after undoing the prompt back to empty with `u` asks for the same confirmation as deleting the text or moving through prompt history, and switches only on the second press; before this release the press switched immediately. |
1098| v2.1.219 | With [vim editor mode](/docs/en/interactive-mode.md#vim-editor-mode) on, pressing `←` on an empty prompt opens agent view from NORMAL mode as well as INSERT, and the footer's `←` hint shows in NORMAL mode; before this release the gesture and hint were INSERT-only, and in NORMAL mode `←` on an empty prompt did nothing. Typing into the input while Claude Code waits to background the session cancels the switch with `Backgrounding cancelled — you have unsent text in the input. Send it or clear it, then press ← again.` so a typed draft isn't lost. |
1096| v2.1.225 | `claude agents` in a directory you haven't trusted shows the same [workspace trust dialog](https://code.claude.com/docs/en/permissions.md#project-allow-rules-and-workspace-trust) that `claude` shows on startup, before agent view opens. Accepting saves trust for that workspace; declining exits without opening agent view. Before this release, `claude agents` opened without asking, so sessions you dispatched from it ran in a directory you'd never been asked to trust. With the list grouped by directory, hovering the mouse over a row highlights it without changing the [dispatch target](#dispatch-to-a-specific-directory); selecting a row with the arrow keys or a click still changes the target. Before this release, moving the mouse over a session in another project silently changed the directory the next dispatched session started in. |
1097| v2.1.221 | `/status` shows a `Session kind` row: `background job · attached` or `background job · unattended` in a background session, depending on whether a terminal is attached, and `interactive` in any other session. Before this release, `/status` didn't report the session kind. `/fork`: Claude Code instructs [the copy](#from-inside-a-session) to isolate its work from the original session's: the copy creates a worktree of its own before making code changes, stays out of the original session's worktree, and bases a new branch on the original's branch when its task builds on that work. See the linked section for the exact conditions. Before this release, the copy received no isolation instruction and could end up editing the worktree or checkout the original session was still working in. With [vim editor mode](https://code.claude.com/docs/en/interactive-mode.md#vim-editor-mode) on, pressing `←` right after undoing the prompt back to empty with `u` asks for the same confirmation as deleting the text or moving through prompt history, and switches only on the second press; before this release the press switched immediately. |
1098| v2.1.219 | With [vim editor mode](https://code.claude.com/docs/en/interactive-mode.md#vim-editor-mode) on, pressing `←` on an empty prompt opens agent view from NORMAL mode as well as INSERT, and the footer's `←` hint shows in NORMAL mode; before this release the gesture and hint were INSERT-only, and in NORMAL mode `←` on an empty prompt did nothing. Typing into the input while Claude Code waits to background the session cancels the switch with `Backgrounding cancelled — you have unsent text in the input. Send it or clear it, then press ← again.` so a typed draft isn't lost. |
10991099| v2.1.218 | Pressing `←` within two seconds of a deletion that emptied the prompt, or of moving through prompt history, shows `Press ← again to open agents`, or `Press ← again to go back to agents` in an attached session, and switches only on a second press at least a second later; before this release the press switched immediately. A `←` that arrives inside pasted or scripted input no longer triggers the switch. Backgrounding a foreground session with `←` shows `Your conversation moved to the background` above the list, and `Esc` at the root of agent view returns to that conversation instead of exiting to the shell, with double `Ctrl+C` remaining the exit; if the conversation can't be reopened, Claude Code exits and prints a `claude --resume` command for it. On Windows, a `←` pressed within about half a second of attaching shows `Ambiguous ←, press again to detach` and detaches on the second press. |
1100| v2.1.217 | The pull request badge on a session's row renders as a hyperlink even when Claude Code can't detect terminal hyperlink support, for example over SSH or tmux; set [`FORCE_HYPERLINK=0`](/docs/en/env-vars) to render it as plain text. Before this release, the badge rendered as plain text when support wasn't detected. |
1100| v2.1.217 | The pull request badge on a session's row renders as a hyperlink even when Claude Code can't detect terminal hyperlink support, for example over SSH or tmux; set [`FORCE_HYPERLINK=0`](https://code.claude.com/docs/en/env-vars) to render it as plain text. Before this release, the badge rendered as plain text when support wasn't detected. |
11011101| v2.1.216 | `/fork`: the [confirmation](#from-inside-a-session) is one line, showing the copy's state, the name of its agent-view row, and its session ID for `claude attach`, ending with `runs in the origin tree` or `edits this checkout` only when the copy runs in the main working tree or edits the checkout you have open. Clicking the name backgrounds this session and opens agent view in the copy's session. The confirmation no longer restates the copy's inherited permission mode; earlier versions printed a multi-line confirmation with no clickable name. Needs input: `/install-github-app` and the `/mcp` settings list, run while nobody is attached, show the session under `Needs input` with a row naming the command, and attaching and re-running the command continues; from v2.1.208 through v2.1.215 they were refused outright in that state. `--agent` restore: resuming or restarting a [backgrounded `--agent` session](#from-your-shell) restores the agent's system prompt and tool restrictions, searching the session's own directory for the agent first, when its workspace is trusted; a session whose agent no longer exists continues with the default tools and system prompt and opens with a visible warning, instead of silently reverting to the default agent. `Ctrl+X`: pressing it twice deletes a session even when the stop attempt fails, instead of a failed stop cancelling the pending delete, and a deleted session whose worker process had died no longer reappears on the next refresh. Worktree deletion: a session whose worktree directory belongs to no git repository can be deleted; before this release every attempt to delete such a session was refused. A directory that's already gone clears immediately. The agent view double-press removes a directory that still has files, running your `WorktreeRemove` hook for a hook-created directory, unless another session's records also name it. `claude rm` keeps such a directory whenever files remain. |
11021102| v2.1.214 | A session backgrounded with `←` or `/background` and left idle with nothing running has its process stopped like any other idle session, instead of keeping its process and the background service running indefinitely. A completed session can be removed with `claude rm` or from agent view after the background service has gone idle, and a session that entered a worktree after being dispatched from a directory that isn't a git repository, such as a multi-repo workspace folder, can be deleted from agent view when the worktree itself belongs to a git repository, because the cleanup is resolved from the worktree instead of the directory the session was dispatched from; both removals were refused on every attempt before. Reopening a stopped session restores its saved conversation even when a folder in the transcript store can't be read. |
1103| v2.1.213 | `/install-github-app`, the [`/mcp`](/docs/en/mcp) settings list, and MCP authentication actions work in a background session while a terminal is attached, and are refused only when nobody is attached, with a message telling you to attach and run the command again; from v2.1.208 through v2.1.212 they were refused even with a terminal attached. |
1103| v2.1.213 | `/install-github-app`, the [`/mcp`](https://code.claude.com/docs/en/mcp) settings list, and MCP authentication actions work in a background session while a terminal is attached, and are refused only when nobody is attached, with a message telling you to attach and run the command again; from v2.1.208 through v2.1.212 they were refused even with a terminal attached. |
11041104| v2.1.212 | [`/fork` in an interactive session](#from-inside-a-session) copies the conversation into a new background session while the original keeps running; the earlier forked-subagent behavior of `/fork` moved to `/subtask`. With [agent view turned off](#turn-off-agent-view), `/fork` keeps the forked-subagent behavior. |
11051105| v2.1.212 | [Typing a bare `/resume` in agent view](#bring-back-a-past-session) opens a picker of past sessions of the repository you opened agent view from. |
11061106| v2.1.211 | Waking a stopped session by attaching or replying from the directory it runs in forwards your shell's gateway `ANTHROPIC_BASE_URL` again, under the same conditions as a fresh dispatch, so a session authenticated through a gateway `ANTHROPIC_AUTH_TOKEN` resumes on the gateway instead of reporting `Not logged in`. Attaching to a stopped session that was backgrounded from another conversation before its first response finished is refused with `This session has no saved transcript` instead of silently starting a blank conversation under the same session id; opening the same row from agent view showed the refusal in the footer. Ending the process of a `←` or `/background` session from outside Claude Code marks it stopped instead of the supervisor restarting it, a stop already recorded on disk is honored unless a reply you sent is still waiting to be delivered, a session restarted after a crash is told it was restarted, and a restarted `←` or `/background` session doesn't resume an interrupted response older than about an hour. A session-naming reply that answers or refuses the prompt instead of labeling it, such as for a prompt that's mostly a link, is discarded and the row keeps a name taken from the prompt text. Deleting a session whose worktree git no longer recognizes succeeds, leaving the worktree directory on disk and naming its path, instead of every attempt being refused. A refused delete shows the reason on the session's row, including the underlying git error when the worktree couldn't be removed, instead of the row silently reappearing. |

agents Changed · +28 / -28 lines

from line 2
22 
33> Compare the ways Claude Code can take on multiple tasks at once: subagents, agent view, agent teams, dynamic workflows, and projects.
44 
5Claude Code has five ways to work on several tasks at once: [subagents](/docs/en/sub-agents.md), [agent view](/docs/en/agent-view.md), [agent teams](/docs/en/agent-teams.md), [dynamic workflows](/docs/en/workflows.md), and [projects](/docs/en/claude-projects.md). They differ in how involved you stay, from steering each conversation yourself to letting Claude coordinate a group of workers, and in whether the work runs on your machine or in the cloud.
5Claude Code has five ways to work on several tasks at once: [subagents](https://code.claude.com/docs/en/sub-agents.md), [agent view](https://code.claude.com/docs/en/agent-view.md), [agent teams](https://code.claude.com/docs/en/agent-teams.md), [dynamic workflows](https://code.claude.com/docs/en/workflows.md), and [projects](https://code.claude.com/docs/en/claude-projects.md). They differ in how involved you stay, from steering each conversation yourself to letting Claude coordinate a group of workers, and in whether the work runs on your machine or in the cloud.
66 
77| Approach | What it gives you | Use it when |
88| :- | :- | :- |
9| [Subagents](/docs/en/sub-agents.md) | Delegated workers inside one session that do a side task in their own context and return a summary | A side task would flood your main conversation with search results, logs, or file contents you won't reference again |
10| [Agent view](/docs/en/agent-view.md) | One screen to dispatch and monitor sessions running in the background, opened with `claude agents`. Research preview | You have several independent tasks and want to hand them off, check status at a glance, and step in only when one needs you |
11| [Agent teams](/docs/en/agent-teams.md) | Multiple coordinated sessions with a shared task list and inter-agent messaging, managed by a lead. Experimental and disabled by default | You want Claude to split a project into pieces, assign them, and keep the workers in sync |
12| [Projects](/docs/en/claude-projects.md) | One ongoing conversation at claude.ai/code or in the desktop app. Claude starts parallel sessions called threads, in the cloud or, when you ask, on your computer through Remote Control, gives each one the project's instructions, and shows you which ones need you. Public beta on Pro and Max | The work spans many tasks over days or weeks, should keep running when your machine is off, and you'd rather describe it once than dispatch and track each session |
13| [Dynamic workflows](/docs/en/workflows.md) | A script that runs many subagents and cross-checks their results, for work too big to coordinate one turn at a time or that needs more than a single pass | A job outgrows a handful of subagents, or you want findings verified against each other: a codebase-wide audit, a 500-file migration, cross-checked research, or a plan drafted from several angles |
9| [Subagents](https://code.claude.com/docs/en/sub-agents.md) | Delegated workers inside one session that do a side task in their own context and return a summary | A side task would flood your main conversation with search results, logs, or file contents you won't reference again |
10| [Agent view](https://code.claude.com/docs/en/agent-view.md) | One screen to dispatch and monitor sessions running in the background, opened with `claude agents`. Research preview | You have several independent tasks and want to hand them off, check status at a glance, and step in only when one needs you |
11| [Agent teams](https://code.claude.com/docs/en/agent-teams.md) | Multiple coordinated sessions with a shared task list and inter-agent messaging, managed by a lead. Experimental and disabled by default | You want Claude to split a project into pieces, assign them, and keep the workers in sync |
12| [Projects](https://code.claude.com/docs/en/claude-projects.md) | One ongoing conversation at claude.ai/code or in the desktop app. Claude starts parallel sessions called threads, in the cloud or, when you ask, on your computer through Remote Control, gives each one the project's instructions, and shows you which ones need you. Public beta on Pro and Max | The work spans many tasks over days or weeks, should keep running when your machine is off, and you'd rather describe it once than dispatch and track each session |
13| [Dynamic workflows](https://code.claude.com/docs/en/workflows.md) | A script that runs many subagents and cross-checks their results, for work too big to coordinate one turn at a time or that needs more than a single pass | A job outgrows a handful of subagents, or you want findings verified against each other: a codebase-wide audit, a 500-file migration, cross-checked research, or a plan drafted from several angles |
1414 
15In every approach the workers are Claude sessions. To involve a different tool, expose it to Claude as an [MCP server](/docs/en/mcp.md).
15In every approach the workers are Claude sessions. To involve a different tool, expose it to Claude as an [MCP server](https://code.claude.com/docs/en/mcp.md).
1616 
1717Three more tools support this work without being a way to run agents themselves:
1818 
19* [Worktrees](/docs/en/worktrees.md) give each session a separate git checkout, so parallel sessions each edit their own copy of the files. Use them for sessions you run yourself. A session you dispatch from agent view [moves into a worktree of its own before it edits files](/docs/en/agent-view.md#how-file-edits-are-isolated), and subagents you spawn can each get one too.
20* [Cross-session messaging](/docs/en/cross-session-messaging.md) lets Claude list and message your other Claude Code sessions on this machine, on another machine, or [in the cloud](/docs/en/claude-code-on-the-web.md), so sessions you run yourself can pass findings and status between themselves.
21* [`/batch`](/docs/en/commands) is a [skill](/docs/en/skills.md) that has Claude split one large change into 5 to 30 worktree-isolated subagents. It's a packaged use of subagents and worktrees, not a separate coordination style.
19* [Worktrees](https://code.claude.com/docs/en/worktrees.md) give each session a separate git checkout, so parallel sessions each edit their own copy of the files. Use them for sessions you run yourself. A session you dispatch from agent view [moves into a worktree of its own before it edits files](https://code.claude.com/docs/en/agent-view.md#how-file-edits-are-isolated), and subagents you spawn can each get one too.
20* [Cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md) lets Claude list and message your other Claude Code sessions on this machine, on another machine, or [in the cloud](https://code.claude.com/docs/en/claude-code-on-the-web.md), so sessions you run yourself can pass findings and status between themselves.
21* [`/batch`](https://code.claude.com/docs/en/commands) is a [skill](https://code.claude.com/docs/en/skills.md) that has Claude split one large change into 5 to 30 worktree-isolated subagents. It's a packaged use of subagents and worktrees, not a separate coordination style.
2222 
2323A few other features run Claude without you driving each step, but they solve a different problem than splitting work across agents:
2424 
25* A [background bash command](/docs/en/interactive-mode.md#background-bash-commands) runs one shell command without blocking the conversation. It doesn't spawn an agent.
26* A [forked subagent](/docs/en/sub-agents.md#fork-the-current-conversation) is a subagent that inherits your full conversation context instead of starting fresh. It's a way to spawn a subagent, not a separate surface. Start one with `/subtask`. Claude also spawns one itself where [fork mode](/docs/en/sub-agents.md#turn-fork-mode-on-or-off) is on. To copy the whole session into a new [background session](/docs/en/agent-view.md#from-inside-a-session) that runs alongside it, use `/fork`. With [agent view turned off](/docs/en/agent-view.md#turn-off-agent-view), the forked-subagent command is `/fork` instead and `/subtask` isn't available.
27* A [cloud scheduled task](/docs/en/routines.md) runs a session on a schedule in the cloud, not in parallel on your machine.
25* A [background bash command](https://code.claude.com/docs/en/interactive-mode.md#background-bash-commands) runs one shell command without blocking the conversation. It doesn't spawn an agent.
26* A [forked subagent](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation) is a subagent that inherits your full conversation context instead of starting fresh. It's a way to spawn a subagent, not a separate surface. Start one with `/subtask`. Claude also spawns one itself where [fork mode](https://code.claude.com/docs/en/sub-agents.md#turn-fork-mode-on-or-off) is on. To copy the whole session into a new [background session](https://code.claude.com/docs/en/agent-view.md#from-inside-a-session) that runs alongside it, use `/fork`. With [agent view turned off](https://code.claude.com/docs/en/agent-view.md#turn-off-agent-view), the forked-subagent command is `/fork` instead and `/subtask` isn't available.
27* A [cloud scheduled task](https://code.claude.com/docs/en/routines.md) runs a session on a schedule in the cloud, not in parallel on your machine.
2828 
2929> [!NOTE]
3030>
31> Running several sessions or subagents at once multiplies token usage. See [Costs](/docs/en/costs.md) for usage and rate-limit details.
31> Running several sessions or subagents at once multiplies token usage. See [Costs](https://code.claude.com/docs/en/costs.md) for usage and rate-limit details.
3232 
3333## Choose an approach
3434 
from line 35
3535The right approach depends on who coordinates the work, whether the workers need to communicate, and whether they edit the same files:
3636 
3737* **Who coordinates the work?**
38 * Claude delegates and collects results inside one conversation: [subagents](/docs/en/sub-agents.md)
39 * You hand off independent tasks and check back later: [agent view](/docs/en/agent-view.md)
40 * Claude plans, assigns, and supervises a group of workers: [agent teams](/docs/en/agent-teams.md), experimental and disabled by default
41 * A script holds the plan instead of Claude's turn-by-turn judgment: [dynamic workflows](/docs/en/workflows.md). See [how workflows compare to subagents and skills](/docs/en/workflows.md#when-to-use-a-workflow)
42* **Do the workers need to talk to each other?** Claude can pass findings with [cross-session messaging](/docs/en/cross-session-messaging.md) between sessions you run yourself, including the sessions you dispatch from agent view. Subagents report results back to the conversation that spawned them, and agent view sessions report results only to you. Teammates in an agent team message each other directly and, when they [have the Task tools](/docs/en/tools-reference.md#task-tool-availability), share a task list.
43* **Do the tasks touch the same files?** Isolate the work with [worktrees](/docs/en/worktrees.md). Subagents and sessions you run yourself can each use a separate worktree. Agent teams don't isolate teammates in worktrees, so [partition the work](/docs/en/agent-teams.md#avoid-file-conflicts) so each teammate owns a different set of files.
38 * Claude delegates and collects results inside one conversation: [subagents](https://code.claude.com/docs/en/sub-agents.md)
39 * You hand off independent tasks and check back later: [agent view](https://code.claude.com/docs/en/agent-view.md)
40 * Claude plans, assigns, and supervises a group of workers: [agent teams](https://code.claude.com/docs/en/agent-teams.md), experimental and disabled by default
41 * A script holds the plan instead of Claude's turn-by-turn judgment: [dynamic workflows](https://code.claude.com/docs/en/workflows.md). See [how workflows compare to subagents and skills](https://code.claude.com/docs/en/workflows.md#when-to-use-a-workflow)
42* **Do the workers need to talk to each other?** Claude can pass findings with [cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md) between sessions you run yourself, including the sessions you dispatch from agent view. Subagents report results back to the conversation that spawned them, and agent view sessions report results only to you. Teammates in an agent team message each other directly and, when they [have the Task tools](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability), share a task list.
43* **Do the tasks touch the same files?** Isolate the work with [worktrees](https://code.claude.com/docs/en/worktrees.md). Subagents and sessions you run yourself can each use a separate worktree. Agent teams don't isolate teammates in worktrees, so [partition the work](https://code.claude.com/docs/en/agent-teams.md#avoid-file-conflicts) so each teammate owns a different set of files.
4444 
4545## Check on running work
4646 
4747The command for checking on running work depends on which approach you used:
4848 
49* For background sessions, `claude agents` opens [agent view](/docs/en/agent-view.md): one screen showing every session, its state, and which ones need your input.
50* For subagents in the current session, named background subagents appear in the @-mention typeahead with their status. The `/agents` command prints a notice pointing to the subagent file locations. To [create and edit custom subagents](/docs/en/sub-agents.md#configure-subagents), ask Claude or edit the files directly. Despite the similar name, `/agents` is separate from `claude agents`.
49* For background sessions, `claude agents` opens [agent view](https://code.claude.com/docs/en/agent-view.md): one screen showing every session, its state, and which ones need your input.
50* For subagents in the current session, named background subagents appear in the @-mention typeahead with their status. The `/agents` command prints a notice pointing to the subagent file locations. To [create and edit custom subagents](https://code.claude.com/docs/en/sub-agents.md#configure-subagents), ask Claude or edit the files directly. Despite the similar name, `/agents` is separate from `claude agents`.
5151* For anything running in the background of the current session, `/tasks` lists each item and lets you check on, attach to, or stop it. The list also includes subagents that have finished.
5252* For dynamic workflows, `/workflows` lists running and completed runs, the phase each is in, and how many agents have finished.
5353 
54For a desktop view of all your sessions, see [parallel sessions in the desktop app](/docs/en/desktop.md#work-in-parallel-with-sessions).
54For a desktop view of all your sessions, see [parallel sessions in the desktop app](https://code.claude.com/docs/en/desktop.md#work-in-parallel-with-sessions).
5555 
5656## Learn more
5757 
5858Each guide below covers setup and configuration for one approach:
5959 
60* [Create custom subagents](/docs/en/sub-agents.md): define reusable specialists and control which tools they can use.
61* [Manage agents with agent view](/docs/en/agent-view.md): dispatch sessions, watch their state, and attach when one needs you.
62* [Orchestrate agent teams](/docs/en/agent-teams.md): set up a lead and teammates, assign tasks, and review their work.
63* [Orchestrate dynamic workflows](/docs/en/workflows.md): run a bundled workflow or have Claude write one that runs many subagents and verifies their findings against each other.
64* [Run parallel sessions with worktrees](/docs/en/worktrees.md): start Claude in an isolated checkout, control what gets copied in, and clean up afterward.
60* [Create custom subagents](https://code.claude.com/docs/en/sub-agents.md): define reusable specialists and control which tools they can use.
61* [Manage agents with agent view](https://code.claude.com/docs/en/agent-view.md): dispatch sessions, watch their state, and attach when one needs you.
62* [Orchestrate agent teams](https://code.claude.com/docs/en/agent-teams.md): set up a lead and teammates, assign tasks, and review their work.
63* [Orchestrate dynamic workflows](https://code.claude.com/docs/en/workflows.md): run a bundled workflow or have Claude write one that runs many subagents and verifies their findings against each other.
64* [Run parallel sessions with worktrees](https://code.claude.com/docs/en/worktrees.md): start Claude in an isolated checkout, control what gets copied in, and clean up afterward.
6565 

amazon-bedrock Changed · +41 / -41 lines

from line 28
2828 
2929**2. Start Claude Code and choose Amazon Bedrock**
3030 
31Run `claude`. At the login prompt, select **3rd-party platform**, then **Amazon Bedrock**. If you're already signed in and see the chat prompt instead, run `/setup-bedrock` to open the wizard. Until `CLAUDE_CODE_USE_BEDROCK=1` is set, Claude Code [hides the command from the command menu](/docs/en/commands.md#how-the-command-menu-matches-what-you-type); type it in full.
31Run `claude`. At the login prompt, select **3rd-party platform**, then **Amazon Bedrock**. If you're already signed in and see the chat prompt instead, run `/setup-bedrock` to open the wizard. Until `CLAUDE_CODE_USE_BEDROCK=1` is set, Claude Code [hides the command from the command menu](https://code.claude.com/docs/en/commands.md#how-the-command-menu-matches-what-you-type); type it in full.
3232 
3333**3. Follow the wizard prompts**
3434 
35Choose how you authenticate to AWS: an AWS profile detected from your `~/.aws` directory, an Amazon Bedrock API key, an access key and secret, or credentials already in your environment. The wizard asks for your region, verifies which Claude models your account can invoke, and lets you pin them. It saves the result to the `env` block of your [user settings file](/docs/en/settings.md), so you don't need to export environment variables yourself.
35Choose how you authenticate to AWS: an AWS profile detected from your `~/.aws` directory, an Amazon Bedrock API key, an access key and secret, or credentials already in your environment. The wizard asks for your region, verifies which Claude models your account can invoke, and lets you pin them. It saves the result to the `env` block of your [user settings file](https://code.claude.com/docs/en/settings.md), so you don't need to export environment variables yourself.
3636 
37After you've signed in, run `/setup-bedrock` any time to reopen the wizard and change your credentials, region, or model pins. The model pin step starts from your currently pinned models. The wizard writes to `~/.claude/settings.json`, or to `$CLAUDE_CONFIG_DIR/settings.json` when [`CLAUDE_CONFIG_DIR`](/docs/en/env-vars#variables) is set.
37After you've signed in, run `/setup-bedrock` any time to reopen the wizard and change your credentials, region, or model pins. The model pin step starts from your currently pinned models. The wizard writes to `~/.claude/settings.json`, or to `$CLAUDE_CONFIG_DIR/settings.json` when [`CLAUDE_CONFIG_DIR`](https://code.claude.com/docs/en/env-vars#variables) is set.
3838 
3939## Set up manually
4040 
from line 126
126126 
127127Claude Code resolves the AWS default credential provider chain once and keeps the resolved credentials in memory. It reuses them until five minutes before they expire, or for one hour when they carry no expiration, so an SSO-backed profile requests credentials from IAM Identity Center about once per credential lifetime. A credential error from the API clears the cache, and the retry resolves fresh credentials.
128128 
129The cache covers every credential method listed at the start of this step except an Amazon Bedrock API key, which doesn't use the provider chain. To resolve the chain on every request instead, set [`CLAUDE_CODE_SKIP_AWS_CRED_CACHE=1`](/docs/en/env-vars).
129The cache covers every credential method listed at the start of this step except an Amazon Bedrock API key, which doesn't use the provider chain. To resolve the chain on every request instead, set [`CLAUDE_CODE_SKIP_AWS_CRED_CACHE=1`](https://code.claude.com/docs/en/env-vars).
130130 
131The resolve that fills the cache times out after 60 seconds. If a step in the chain stalls, for example a `credential_process` helper that waits for input it can't receive, the request fails with [`AWS default-chain credential resolve timed out`](/docs/en/errors#aws-default-chain-credential-resolve-timed-out). If your chain runs an interactive sign-in that legitimately needs longer, such as browser-based SSO with MFA through a wrapper like `aws-vault`, raise the limit in milliseconds with [`CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS`](/docs/en/env-vars). With `CLAUDE_CODE_SKIP_AWS_CRED_CACHE=1` set, each API request resolves the chain without this limit.
131The resolve that fills the cache times out after 60 seconds. If a step in the chain stalls, for example a `credential_process` helper that waits for input it can't receive, the request fails with [`AWS default-chain credential resolve timed out`](https://code.claude.com/docs/en/errors#aws-default-chain-credential-resolve-timed-out). If your chain runs an interactive sign-in that legitimately needs longer, such as browser-based SSO with MFA through a wrapper like `aws-vault`, raise the limit in milliseconds with [`CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS`](https://code.claude.com/docs/en/env-vars). With `CLAUDE_CODE_SKIP_AWS_CRED_CACHE=1` set, each API request resolves the chain without this limit.
132132 
133Except when you authenticate with an Amazon Bedrock API key, the [setup wizard](#sign-in-with-bedrock) applies the same limit to each AWS call it makes while verifying your credentials, and to the credential lookup before each model check. During credential verification, a check that exceeds it fails with [`Timed out after 60s waiting for AWS`](/docs/en/errors#bedrock-setup-verification-timed-out-waiting-for-aws).
133Except when you authenticate with an Amazon Bedrock API key, the [setup wizard](#sign-in-with-bedrock) applies the same limit to each AWS call it makes while verifying your credentials, and to the credential lookup before each model check. During credential verification, a check that exceeds it fails with [`Timed out after 60s waiting for AWS`](https://code.claude.com/docs/en/errors#bedrock-setup-verification-timed-out-waiting-for-aws).
134134 
135135#### Advanced credential configuration
136136 
137Claude Code supports automatic credential refresh for AWS SSO and corporate identity providers. Add these settings to your Claude Code settings file (see [Settings](/docs/en/settings.md) for file locations).
137Claude Code supports automatic credential refresh for AWS SSO and corporate identity providers. Add these settings to your Claude Code settings file (see [Settings](https://code.claude.com/docs/en/settings.md) for file locations).
138138 
139139These two settings have different trigger conditions:
140140 
from line 141
141141* **`awsAuthRefresh`**: runs only when Claude Code detects that your AWS credentials are expired, either locally based on their timestamp or when the API returns a credential error, then retries the request with refreshed credentials.
142142* **`awsCredentialExport`**: runs at session start and on each credential reload, even when the credentials in your AWS default credential provider chain are still valid. Use this when your Amazon Bedrock account requires cross-account credentials that differ from the ones the default provider chain would resolve.
143143 
144Before running the `awsAuthRefresh` command, Claude Code makes an STS `GetCallerIdentity` call to confirm that your credentials are actually expired, and skips the command when they still work. Claude Code sends this check through your [proxy configuration](/docs/en/network-config.md#proxy-configuration), honoring `HTTPS_PROXY` and `NO_PROXY`. Before v2.1.239, Claude Code sent this check directly and hung at startup on networks that only allow egress through a proxy.
144Before running the `awsAuthRefresh` command, Claude Code makes an STS `GetCallerIdentity` call to confirm that your credentials are actually expired, and skips the command when they still work. Claude Code sends this check through your [proxy configuration](https://code.claude.com/docs/en/network-config.md#proxy-configuration), honoring `HTTPS_PROXY` and `NO_PROXY`. Before v2.1.239, Claude Code sent this check directly and hung at startup on networks that only allow egress through a proxy.
145145 
146146##### Example configuration
147147 
from line 210
210210 
211211 Run `/status` to see the resolved region. When the region came from your AWS config files or the default fallback, Claude Code also notes the source in the `/status` output.
212212* When using Amazon Bedrock, the `/logout` command is unavailable since authentication is handled through AWS credentials.
213* The WebSearch tool is not available on Amazon Bedrock. See [WebSearch tool behavior](/docs/en/tools-reference.md#websearch-tool-behavior).
214* You can use settings files for environment variables like `AWS_PROFILE` that you don't want to leak to other processes. See [Settings](/docs/en/settings.md) for more information.
213* The WebSearch tool is not available on Amazon Bedrock. See [WebSearch tool behavior](https://code.claude.com/docs/en/tools-reference.md#websearch-tool-behavior).
214* You can use settings files for environment variables like `AWS_PROFILE` that you don't want to leak to other processes. See [Settings](https://code.claude.com/docs/en/settings.md) for more information.
215215 
216216### 4. Pin model versions
217217 
from line 238
238238| `ANTHROPIC_DEFAULT_OPUS_MODEL='us.anthropic.claude-opus-4-8'` | `us.anthropic.claude-opus-4-8`, the exact ID you pinned |
239239| `ANTHROPIC_BEDROCK_REGION_PREFIX=eu` | `eu.anthropic.claude-opus-5-5`, the built-in default with your preferred prefix |
240240 
241For current and legacy model IDs, see [Models overview](https://platform.claude.com/docs/en/about-claude/models/overview). For the full list of pinning environment variables, see [Model configuration](/docs/en/model-config.md#pin-models-for-third-party-deployments).
241For current and legacy model IDs, see [Models overview](https://platform.claude.com/docs/en/about-claude/models/overview). For the full list of pinning environment variables, see [Model configuration](https://code.claude.com/docs/en/model-config.md#pin-models-for-third-party-deployments).
242242 
243243Claude Code uses these default models when no pinning variables are set:
244244 
from line 249
249249 
250250Background tasks such as session title generation use the small/fast model, normally a Haiku-class model. On Amazon Bedrock, Claude Code uses the default Sonnet model for background tasks because Haiku may not be enabled in every account or region. Two selections change which model carries them:
251251 
252* When you select a primary model with `--model`, `ANTHROPIC_MODEL`, or the `model` setting, background tasks use that model. When Claude Code starts the session on the model you set with [`ANTHROPIC_DEFAULT_MODEL`](/docs/en/model-config#set-a-default-model-for-new-sessions), background tasks use that model too. Setting `ANTHROPIC_DEFAULT_OPUS_MODEL` without `ANTHROPIC_DEFAULT_SONNET_MODEL` also counts as a selection, because the built-in Sonnet model may not be enabled in an account that steers its own Opus.
252* When you select a primary model with `--model`, `ANTHROPIC_MODEL`, or the `model` setting, background tasks use that model. When Claude Code starts the session on the model you set with [`ANTHROPIC_DEFAULT_MODEL`](https://code.claude.com/docs/en/model-config#set-a-default-model-for-new-sessions), background tasks use that model too. Setting `ANTHROPIC_DEFAULT_OPUS_MODEL` without `ANTHROPIC_DEFAULT_SONNET_MODEL` also counts as a selection, because the built-in Sonnet model may not be enabled in an account that steers its own Opus.
253253* To use Haiku for background tasks, set `ANTHROPIC_DEFAULT_HAIKU_MODEL` to a model ID that is available in your account.
254254 
255255> [!WARNING]
from line 275
275275# export ENABLE_PROMPT_CACHING_1H=1
276276```
277277 
278The 1-hour cache TTL is billed at a higher rate than the 5-minute default. See [cache lifetime](/docs/en/prompt-caching.md#cache-lifetime). To set different TTLs for your main conversation and for the requests Claude Code makes outside it, [choose the TTL yourself](/docs/en/prompt-caching.md#choose-the-ttl-yourself).
278The 1-hour cache TTL is billed at a higher rate than the 5-minute default. See [cache lifetime](https://code.claude.com/docs/en/prompt-caching.md#cache-lifetime). To set different TTLs for your main conversation and for the requests Claude Code makes outside it, [choose the TTL yourself](https://code.claude.com/docs/en/prompt-caching.md#choose-the-ttl-yourself).
279279 
280280> [!NOTE]
281281>
from line 283
283283 
284284#### Map each model version to an inference profile
285285 
286The `ANTHROPIC_DEFAULT_*_MODEL` environment variables configure one inference profile per model family. If your organization needs to expose several versions of the same family in the `/model` picker, each routed to its own application inference profile ARN, use the `modelOverrides` setting in your [settings file](/docs/en/settings.md#where-settings-live) instead.
286The `ANTHROPIC_DEFAULT_*_MODEL` environment variables configure one inference profile per model family. If your organization needs to expose several versions of the same family in the `/model` picker, each routed to its own application inference profile ARN, use the `modelOverrides` setting in your [settings file](https://code.claude.com/docs/en/settings.md#where-settings-live) instead.
287287 
288288This example maps four Opus versions to distinct ARNs so users can switch between them without bypassing your organization's inference profiles:
289289 
from line 298
298298}
299299```
300300 
301When a user selects one of these versions in `/model`, Claude Code calls Amazon Bedrock with the mapped ARN. The same mapping applies when you pass the Anthropic model ID directly through `--model` or `ANTHROPIC_MODEL`. Versions without an override fall back to the built-in Amazon Bedrock model ID or any matching inference profile discovered at startup. Before v2.1.200, `--model` and `ANTHROPIC_MODEL` values reached Amazon Bedrock as-is without going through the override map. See [Override model IDs per version](/docs/en/model-config.md#override-model-ids-per-version) for details on how overrides interact with `availableModels` and other model settings.
301When a user selects one of these versions in `/model`, Claude Code calls Amazon Bedrock with the mapped ARN. The same mapping applies when you pass the Anthropic model ID directly through `--model` or `ANTHROPIC_MODEL`. Versions without an override fall back to the built-in Amazon Bedrock model ID or any matching inference profile discovered at startup. Before v2.1.200, `--model` and `ANTHROPIC_MODEL` values reached Amazon Bedrock as-is without going through the override map. See [Override model IDs per version](https://code.claude.com/docs/en/model-config.md#override-model-ids-per-version) for details on how overrides interact with `availableModels` and other model settings.
302302 
303303## Startup model checks
304304 
305305When Claude Code starts with Amazon Bedrock configured, it verifies that the models it intends to use are accessible in your account.
306306 
307If you have pinned a model version that is older than the current Claude Code default, and your account can invoke the newer version, Claude Code prompts you to update the pin. Accepting writes the new model ID to your [user settings file](/docs/en/settings.md) and restarts Claude Code. Declining is remembered until the next default version change. Pins that point to an [application inference profile ARN](#map-each-model-version-to-an-inference-profile) are skipped, since those are managed by your administrator.
307If you have pinned a model version that is older than the current Claude Code default, and your account can invoke the newer version, Claude Code prompts you to update the pin. Accepting writes the new model ID to your [user settings file](https://code.claude.com/docs/en/settings.md) and restarts Claude Code. Declining is remembered until the next default version change. Pins that point to an [application inference profile ARN](#map-each-model-version-to-an-inference-profile) are skipped, since those are managed by your administrator.
308308 
309309If you have not pinned a model and the current default is unavailable in your account, Claude Code falls back for the current session and shows a notice. It tries earlier versions of the default model first and, when the default is an Opus model and no Opus version is available, falls back to the default Sonnet model. The fallback is not persisted. Enable the newer model in your Amazon Bedrock account or [pin a version](#4-pin-model-versions) to make the choice permanent.
310310 
311When you start the session on a specific Sonnet or Opus version, for example with `--model`, `ANTHROPIC_MODEL`, or the [`model` setting](/docs/en/settings-reference#model), that version acts as the session's pinned default for the matching `sonnet` or `opus` alias. Claude Code skips the availability check for the built-in default your model replaces and starts on the model you configured, with no fallback notice.
311When you start the session on a specific Sonnet or Opus version, for example with `--model`, `ANTHROPIC_MODEL`, or the [`model` setting](https://code.claude.com/docs/en/settings-reference#model), that version acts as the session's pinned default for the matching `sonnet` or `opus` alias. Claude Code skips the availability check for the built-in default your model replaces and starts on the model you configured, with no fallback notice.
312312 
313313Model aliases such as `opus` don't act as pins, and neither does a model ID Claude Code doesn't recognize, such as an application inference profile ARN.
314314 
315When these checks find a model your account can't invoke, Claude Code remembers the refusal on this machine for up to a day, and launches during that time skip the remembered model without asking Amazon Bedrock again. Claude Code checks a remembered refusal of a current default model again at launch once ten minutes have passed since the last check, so a default your administrator re-enables comes back. To turn the memory off, set [`CLAUDE_CODE_SKIP_MODEL_ACCESS_MEMORY=1`](/docs/en/env-vars).
315When these checks find a model your account can't invoke, Claude Code remembers the refusal on this machine for up to a day, and launches during that time skip the remembered model without asking Amazon Bedrock again. Claude Code checks a remembered refusal of a current default model again at launch once ten minutes have passed since the last check, so a default your administrator re-enables comes back. To turn the memory off, set [`CLAUDE_CODE_SKIP_MODEL_ACCESS_MEMORY=1`](https://code.claude.com/docs/en/env-vars).
316316 
317317### When your organization enforces a model allowlist
318318 
319If you set [`enforceAvailableModels`](/docs/en/model-config#enforce-the-allowlist-for-the-default-model) in managed settings, the startup model checks use only models your `availableModels` list permits. This applies on the Amazon Bedrock Invoke API and requires Claude Code v2.1.287 or later. A list without `enforceAvailableModels` doesn't restrict these checks.
319If you set [`enforceAvailableModels`](https://code.claude.com/docs/en/model-config#enforce-the-allowlist-for-the-default-model) in managed settings, the startup model checks use only models your `availableModels` list permits. This applies on the Amazon Bedrock Invoke API and requires Claude Code v2.1.287 or later. A list without `enforceAvailableModels` doesn't restrict these checks.
320320 
321321The checks compare each entry with the inference profile ID they would send, including its [region prefix](#cross-region-inference-profile-prefixes), so write the list in those IDs. This example permits Opus 4.8 and Sonnet 4.5 for a deployment whose models resolve to `us.` profiles:
322322 
from line 327
327327}
328328```
329329 
330For aliases, version prefixes, and `modelOverrides` entries, see [Pin models for third-party deployments](/docs/en/model-config.md#pin-models-for-third-party-deployments).
330For aliases, version prefixes, and `modelOverrides` entries, see [Pin models for third-party deployments](https://code.claude.com/docs/en/model-config.md#pin-models-for-third-party-deployments).
331331 
332332### When a model is disabled mid-session
333333 
334334If your account loses access to the model your session is running on, for example because an administrator disables it in your Amazon Bedrock account, Claude Code switches the session to another model instead of failing each request, and shows `Switched to <fallback> because <model> is not available`. It tries the same models as the startup fallback: earlier versions of the same tier first and, for an Opus session with no Opus version available, the default Sonnet model.
335335 
336The switch applies only to a tier you haven't pinned, the same condition as the startup fallback. A session on a specific version you picked, or on an [application inference profile ARN](#map-each-model-version-to-an-inference-profile), keeps its model and, without a fallback model chain, the request fails instead. In [auto mode](/docs/en/permission-modes.md#enable-auto-mode-on-bedrock-agent-platform-or-foundry), Claude Code switches only to a model auto mode supports on Amazon Bedrock. If none of those models is available either, the request fails with [AWS authentication failed](/docs/en/errors.md#aws-authentication-failed) and a hint to enable the model.
336The switch applies only to a tier you haven't pinned, the same condition as the startup fallback. A session on a specific version you picked, or on an [application inference profile ARN](#map-each-model-version-to-an-inference-profile), keeps its model and, without a fallback model chain, the request fails instead. In [auto mode](https://code.claude.com/docs/en/permission-modes.md#enable-auto-mode-on-bedrock-agent-platform-or-foundry), Claude Code switches only to a model auto mode supports on Amazon Bedrock. If none of those models is available either, the request fails with [AWS authentication failed](https://code.claude.com/docs/en/errors.md#aws-authentication-failed) and a hint to enable the model.
337337 
338A [fallback model chain](/docs/en/model-config.md#fallback-model-chains) you configure replaces the tier switch: on these refusals Claude Code switches to your configured fallback instead. To have refused requests fail rather than switch, set [`CLAUDE_CODE_DISABLE_MODEL_ACCESS_FALLBACK=1`](/docs/en/env-vars). A fallback chain you configured still switches on these refusals; remove the chain as well if you want every refused request to fail.
338A [fallback model chain](https://code.claude.com/docs/en/model-config.md#fallback-model-chains) you configure replaces the tier switch: on these refusals Claude Code switches to your configured fallback instead. To have refused requests fail rather than switch, set [`CLAUDE_CODE_DISABLE_MODEL_ACCESS_FALLBACK=1`](https://code.claude.com/docs/en/env-vars). A fallback chain you configured still switches on these refusals; remove the chain as well if you want every refused request to fail.
339339 
340340## Cross-region inference profile prefixes
341341 
from line 427
427427 
428428## 1M token context window
429429 
430Fable models, Sonnet 5 and later, and Opus 4.7 and later run with the [1M token context window](https://platform.claude.com/docs/en/build-with-claude/context-windows#context-window-sizes-by-model) by default on Amazon Bedrock, on both the Invoke API and the [Mantle endpoint](#use-the-mantle-endpoint), with no `[1m]` suffix needed. An application inference profile ARN gets the 1M window when a [`modelOverrides`](#map-each-model-version-to-an-inference-profile) entry maps its model to it. To keep a 200K window instead, set [`CLAUDE_CODE_DISABLE_1M_CONTEXT=1`](/docs/en/model-config#turn-off-1m-context).
430Fable models, Sonnet 5 and later, and Opus 4.7 and later run with the [1M token context window](https://platform.claude.com/docs/en/build-with-claude/context-windows#context-window-sizes-by-model) by default on Amazon Bedrock, on both the Invoke API and the [Mantle endpoint](#use-the-mantle-endpoint), with no `[1m]` suffix needed. An application inference profile ARN gets the 1M window when a [`modelOverrides`](#map-each-model-version-to-an-inference-profile) entry maps its model to it. To keep a 200K window instead, set [`CLAUDE_CODE_DISABLE_1M_CONTEXT=1`](https://code.claude.com/docs/en/model-config#turn-off-1m-context).
431431 
432Opus 4.6 and Sonnet 4.6 on the Invoke API reach the 1M window when you select their `[1m]` variant. The [setup wizard](#sign-in-with-bedrock) offers a 1M context option when it pins models. To enable it for a manually pinned model instead, append `[1m]` to the model ID. See [Pin models for third-party deployments](/docs/en/model-config.md#pin-models-for-third-party-deployments) for details, including how to use the 1M window without changing the pin.
432Opus 4.6 and Sonnet 4.6 on the Invoke API reach the 1M window when you select their `[1m]` variant. The [setup wizard](#sign-in-with-bedrock) offers a 1M context option when it pins models. To enable it for a manually pinned model instead, append `[1m]` to the model ID. See [Pin models for third-party deployments](https://code.claude.com/docs/en/model-config.md#pin-models-for-third-party-deployments) for details, including how to use the 1M window without changing the pin.
433433 
434434Before v2.1.287, the Fable models and Opus 4.7 and later ran with a 200K window by default on the Invoke API and reached the 1M window there through a `[1m]` suffix.
435435 
from line 445
445445 
446446## AWS Guardrails
447447 
448[Amazon Bedrock Guardrails](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) let you implement content filtering for Claude Code. Create a Guardrail in the [Amazon Bedrock console](https://console.aws.amazon.com/bedrock/), publish a version, then add the Guardrail headers to your [settings file](/docs/en/settings.md). Enable Cross-Region inference on your Guardrail if you're using cross-region inference profiles.
448[Amazon Bedrock Guardrails](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) let you implement content filtering for Claude Code. Create a Guardrail in the [Amazon Bedrock console](https://console.aws.amazon.com/bedrock/), publish a version, then add the Guardrail headers to your [settings file](https://code.claude.com/docs/en/settings.md). Enable Cross-Region inference on your Guardrail if you're using cross-region inference profiles.
449449 
450450Example configuration:
451451 
from line 457
457457}
458458```
459459 
460If your organization delivers the guardrail headers through a [Claude apps gateway](/docs/en/claude-apps-gateway) policy instead, they count as [settings that need approval](/docs/en/server-managed-settings.md#environment-variables-and-the-approval-dialog).
460If your organization delivers the guardrail headers through a [Claude apps gateway](https://code.claude.com/docs/en/claude-apps-gateway) policy instead, they count as [settings that need approval](https://code.claude.com/docs/en/server-managed-settings.md#environment-variables-and-the-approval-dialog).
461461 
462462When the guardrail blocks a response partway through, the text streamed so far stays and the reply ends with the message configured on the guardrail for blocked responses.
463463 
from line 499
499499export CLAUDE_CODE_USE_MANTLE=1
500500```
501501 
502To surface a Mantle model in the `/model` picker, list its ID in `availableModels` in your [settings file](/docs/en/settings.md). This setting also restricts the picker to the listed entries. Listing `anthropic.claude-haiku-4-5` removes the bare `haiku` alias from the picker, so also list version prefixes or full IDs for the versions you want to keep selectable. The Mantle ID and the `haiku` alias resolve to the same model family, so the merge keeps only the more specific entry. See [Merge behavior](/docs/en/model-config.md#merge-behavior):
502To surface a Mantle model in the `/model` picker, list its ID in `availableModels` in your [settings file](https://code.claude.com/docs/en/settings.md). This setting also restricts the picker to the listed entries. Listing `anthropic.claude-haiku-4-5` removes the bare `haiku` alias from the picker, so also list version prefixes or full IDs for the versions you want to keep selectable. The Mantle ID and the `haiku` alias resolve to the same model family, so the merge keeps only the more specific entry. See [Merge behavior](https://code.claude.com/docs/en/model-config.md#merge-behavior):
503503 
504504```json theme={null}
505505{
from line 507
507507}
508508```
509509 
510Entries with the `anthropic.` prefix are added as custom picker options, and the ones that match the Mantle format are routed to Mantle. Replace `anthropic.claude-haiku-4-5` with the model ID your account has been granted. See [Restrict model selection](/docs/en/model-config.md#restrict-model-selection) for how `availableModels` interacts with other model settings.
510Entries with the `anthropic.` prefix are added as custom picker options, and the ones that match the Mantle format are routed to Mantle. Replace `anthropic.claude-haiku-4-5` with the model ID your account has been granted. See [Restrict model selection](https://code.claude.com/docs/en/model-config.md#restrict-model-selection) for how `availableModels` interacts with other model settings.
511511 
512512When both providers are active, `/status` shows `Amazon Bedrock + Amazon Bedrock (Mantle)`.
513513 
514514### Route Mantle through a gateway
515515 
516If your organization routes model traffic through a centralized [LLM gateway](/docs/en/llm-gateway) that injects AWS credentials server-side, disable client-side authentication so Claude Code sends requests without SigV4 signatures or `x-api-key` headers:
516If your organization routes model traffic through a centralized [LLM gateway](https://code.claude.com/docs/en/llm-gateway) that injects AWS credentials server-side, disable client-side authentication so Claude Code sends requests without SigV4 signatures or `x-api-key` headers:
517517 
518518```bash theme={null}
519519export CLAUDE_CODE_USE_MANTLE=1
from line 523
523523 
524524### Mantle environment variables
525525 
526These variables are specific to the Mantle endpoint. See [Environment variables](/docs/en/env-vars.md) for the full list.
526These variables are specific to the Mantle endpoint. See [Environment variables](https://code.claude.com/docs/en/env-vars.md) for the full list.
527527 
528528| Variable | Purpose |
529529| :- | :- |
from line 536
536536 
537537### Authentication loop with SSO and corporate proxies
538538 
539If browser sign-in tabs keep opening when you use AWS SSO, remove the `awsAuthRefresh` setting from your [settings file](/docs/en/settings.md).
539If browser sign-in tabs keep opening when you use AWS SSO, remove the `awsAuthRefresh` setting from your [settings file](https://code.claude.com/docs/en/settings.md).
540540 
541541The loop can occur when corporate VPNs or TLS inspection proxies interrupt the SSO browser flow. Claude Code treats the interrupted connection as an authentication failure. When a later request finds the credentials still expired, Claude Code re-runs `awsAuthRefresh`, which opens another tab.
542542 
from line 544
544544 
545545### Certificate errors behind a TLS-inspecting proxy
546546 
547Claude Code applies your [CA certificate store](/docs/en/network-config.md#ca-certificate-store) configuration to its requests to AWS, including:
547Claude Code applies your [CA certificate store](https://code.claude.com/docs/en/network-config.md#ca-certificate-store) configuration to its requests to AWS, including:
548548 
549549* Model discovery
550550* Token counting
from line 575
575575 
576576Amazon Bedrock streams `InvokeModelWithResponseStream` responses in a binary event-stream format with the header `Content-Type: application/vnd.amazon.eventstream`. A gateway or proxy between Claude Code and Amazon Bedrock must forward the response body and its headers, including `Content-Type`, as Amazon Bedrock sent them.
577577 
578If the gateway rewrites `Content-Type` to another value, Claude Code rejects the response with an error that begins `Bedrock streaming response has content-type`, naming the value it received. The common rewrite is `text/event-stream`, from an integration that re-emits the stream as server-sent events. For the `CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_GUARD` variable that the error message names, see [Bedrock streaming response has an unexpected content-type](/docs/en/errors.md#bedrock-streaming-response-has-an-unexpected-content-type).
578If the gateway rewrites `Content-Type` to another value, Claude Code rejects the response with an error that begins `Bedrock streaming response has content-type`, naming the value it received. The common rewrite is `text/event-stream`, from an integration that re-emits the stream as server-sent events. For the `CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_GUARD` variable that the error message names, see [Bedrock streaming response has an unexpected content-type](https://code.claude.com/docs/en/errors.md#bedrock-streaming-response-has-an-unexpected-content-type).
579579 
580580If the gateway drops or blanks the header instead, Claude Code assumes the body is Amazon Bedrock's event stream and decodes it, so a body the gateway passed through unmodified keeps streaming.
581581 
582If a gateway that drops the header also re-emits the stream as server-sent events, Claude Code can't decode the body and falls back to a slower non-streaming path on every turn: each response appears only once it is complete instead of streaming in. In that case, set [`CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_DEFAULT=1`](/docs/en/env-vars) so Claude Code reads the body as server-sent events instead.
582If a gateway that drops the header also re-emits the stream as server-sent events, Claude Code can't decode the body and falls back to a slower non-streaming path on every turn: each response appears only once it is complete instead of streaming in. In that case, set [`CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_DEFAULT=1`](https://code.claude.com/docs/en/env-vars) so Claude Code reads the body as server-sent events instead.
583583 
584584To fix the error or the fallback, configure the gateway to forward the `InvokeModelWithResponseStream` response body and its `Content-Type` header unmodified.
585585 
586A gateway that converts the stream to server-sent events is no longer serving the Amazon Bedrock API. If it also accepts Anthropic Messages API requests, connect to it as an [LLM gateway](/docs/en/llm-gateway-connect.md) with `ANTHROPIC_BASE_URL` instead of `CLAUDE_CODE_USE_BEDROCK`.
586A gateway that converts the stream to server-sent events is no longer serving the Amazon Bedrock API. If it also accepts Anthropic Messages API requests, connect to it as an [LLM gateway](https://code.claude.com/docs/en/llm-gateway-connect.md) with `ANTHROPIC_BASE_URL` instead of `CLAUDE_CODE_USE_BEDROCK`.
587587 
588588### Zero token counts in /context
589589 
from line 593
593593 
594594### Mantle endpoint errors
595595 
596If `/status` does not show `Amazon Bedrock (Mantle)` after you set `CLAUDE_CODE_USE_MANTLE`, the variable is not reaching the process. Confirm it is exported in the shell where you launched `claude`, or set it in the `env` block of your [settings file](/docs/en/settings.md).
596If `/status` does not show `Amazon Bedrock (Mantle)` after you set `CLAUDE_CODE_USE_MANTLE`, the variable is not reaching the process. Confirm it is exported in the shell where you launched `claude`, or set it in the `env` block of your [settings file](https://code.claude.com/docs/en/settings.md).
597597 
598598What a `403` from the Mantle endpoint means depends on whether the error names an IAM action:
599599 

analytics Changed · +7 / -7 lines

from line 9
99| Claude for Teams / Enterprise | [claude.ai/analytics/claude-code](https://claude.ai/analytics/claude-code) | Usage metrics, contribution metrics with GitHub integration, leaderboard, data export | [Details](#access-analytics-for-team-and-enterprise) |
1010| API (Claude Console) | [platform.claude.com/claude-code](https://platform.claude.com/claude-code) | Usage metrics, spend tracking, team insights | [Details](#access-analytics-for-api-customers) |
1111 
12Code Review has its own dashboard. For review activity and spend, see [View usage](/docs/en/code-review-costs.md#view-usage).
12Code Review has its own dashboard. For review activity and spend, see [View usage](https://code.claude.com/docs/en/code-review-costs.md#view-usage).
1313 
1414## Access analytics for Team and Enterprise
1515 
from line 22
2222* **Leaderboard**: top contributors ranked by Claude Code usage
2323* **Data export**: download contribution data as CSV for custom reporting
2424 
25For per-user token counts and cost estimates, configure [OpenTelemetry export](/docs/en/monitoring-usage.md), or export the [spend report](https://support.claude.com/en/articles/12883420-view-usage-analytics-for-team-and-enterprise-plans) from your organization's analytics settings, which lists token usage and estimated usage-credit spend per user and per model.
25For per-user token counts and cost estimates, configure [OpenTelemetry export](https://code.claude.com/docs/en/monitoring-usage.md), or export the [spend report](https://support.claude.com/en/articles/12883420-view-usage-analytics-for-team-and-enterprise-plans) from your organization's analytics settings, which lists token usage and estimated usage-credit spend per user and per model.
2626 
2727### Enable contribution metrics
2828 
from line 36
3636 
3737> [!WARNING]
3838>
39> Contribution metrics are not available for organizations with [Zero Data Retention](/docs/en/zero-data-retention.md) enabled. The analytics dashboard will show usage metrics only.
39> Contribution metrics are not available for organizations with [Zero Data Retention](https://code.claude.com/docs/en/zero-data-retention.md) enabled. The analytics dashboard will show usage metrics only.
4040 
4141**1. Install the GitHub app**
4242 
from line 59
5959* **"GitHub app required"**: install the GitHub app to view contribution metrics
6060* **"Data processing in progress"**: check back in a few days and confirm the GitHub app is installed if data doesn't appear
6161 
62Contribution metrics cover repositories hosted on github.com. For repositories on [GitHub Enterprise Server](/docs/en/github-enterprise-server.md), the analytics dashboard shows usage metrics only.
62Contribution metrics cover repositories hosted on github.com. For repositories on [GitHub Enterprise Server](https://code.claude.com/docs/en/github-enterprise-server.md), the analytics dashboard shows usage metrics only.
6363 
6464### Review summary metrics
6565 
from line 215
215215 
216216## Related resources
217217 
218* [Monitoring with OpenTelemetry](/docs/en/monitoring-usage.md): export real-time metrics and events to your observability stack
219* [Manage costs effectively](/docs/en/costs.md): set spend limits and optimize token usage
220* [Permissions](/docs/en/permissions.md): configure roles and permissions
218* [Monitoring with OpenTelemetry](https://code.claude.com/docs/en/monitoring-usage.md): export real-time metrics and events to your observability stack
219* [Manage costs effectively](https://code.claude.com/docs/en/costs.md): set spend limits and optimize token usage
220* [Permissions](https://code.claude.com/docs/en/permissions.md): configure roles and permissions
221221 

artifacts Changed · +44 / -44 lines

from line 4
44 
55> [!NOTE]
66>
7> Artifacts are available on Pro, Max, Team, and Enterprise plans and require a session signed in with [`/login`](/docs/en/setup#authenticate). See [Availability](#availability) for the full set of requirements.
7> Artifacts are available on Pro, Max, Team, and Enterprise plans and require a session signed in with [`/login`](https://code.claude.com/docs/en/setup#authenticate). See [Availability](#availability) for the full set of requirements.
88 
99An [artifact](https://claude.com/features/artifacts) is a live, interactive web page that Claude Code publishes from your session to a private URL on claude.ai. You open it in a browser, and it updates in place as the session continues. Share it from the page header when you want someone else to see it too.
1010 
from line 12
1212 
1313## When to use an artifact
1414 
15Use an artifact when terminal text is the wrong medium for what Claude produced: output that is easier to look at and interact with than to read line by line. Claude builds the page from anything your session can reach, including your codebase and data it pulls through your [connected tools](/docs/en/mcp.md), so the page can show things that would take paragraphs to describe. For example, ask Claude to:
15Use an artifact when terminal text is the wrong medium for what Claude produced: output that is easier to look at and interact with than to read line by line. Claude builds the page from anything your session can reach, including your codebase and data it pulls through your [connected tools](https://code.claude.com/docs/en/mcp.md), so the page can show things that would take paragraphs to describe. For example, ask Claude to:
1616 
1717* Walk a reviewer through a pull request with annotated diffs
1818* Render a dashboard from data the session already pulled
from line 44
4444After the first publish, Claude prints the URL, and your browser opens to the new page.
4545 
4646* **Reopen the page**: press `Ctrl+]` at any time to reopen the session's most recent artifact
47* **See this session's artifacts**: a `⧉` pill below the prompt shows the artifact's name, or a count when the session has several. In [fullscreen rendering](/docs/en/fullscreen.md), click it to open the [`/artifacts`](#find-an-artifact-again) list
47* **See this session's artifacts**: a `⧉` pill below the prompt shows the artifact's name, or a count when the session has several. In [fullscreen rendering](https://code.claude.com/docs/en/fullscreen.md), click it to open the [`/artifacts`](#find-an-artifact-again) list
4848* **Keep the browser from opening**: set `CLAUDE_CODE_ARTIFACT_AUTO_OPEN=0` in your environment
49* **Remote Control**: if you sent the prompt through [Remote Control](/docs/en/remote-control.md) from claude.ai, Claude Desktop, or the Claude mobile app, no tab opens on the machine running the session. The browser opens there the next time Claude publishes the artifact from a prompt you type at the terminal
49* **Remote Control**: if you sent the prompt through [Remote Control](https://code.claude.com/docs/en/remote-control.md) from claude.ai, Claude Desktop, or the Claude mobile app, no tab opens on the machine running the session. The browser opens there the next time Claude publishes the artifact from a prompt you type at the terminal
5050 
5151Claude picks the artifact's title and a browser-tab icon that matches what the page is, such as a chart or a calendar. The title appears in your [gallery of artifacts](#share-an-artifact) on claude.ai and in shared links. Ask Claude for a specific title or tab icon if you want one.
5252 
53If Claude responds that it can't publish, or writes a local HTML file without a link, artifacts aren't enabled for your session. Check the [Availability](#availability) requirements. If the terminal shows `Artifacts need a claude.ai login`, see [that error's entry](/docs/en/errors.md#artifacts-need-a-claude-ai-login) for how to sign in.
53If Claude responds that it can't publish, or writes a local HTML file without a link, artifacts aren't enabled for your session. Check the [Availability](#availability) requirements. If the terminal shows `Artifacts need a claude.ai login`, see [that error's entry](https://code.claude.com/docs/en/errors.md#artifacts-need-a-claude-ai-login) for how to sign in.
5454 
5555### When Claude Code asks before publishing
5656 
57A new artifact that Claude publishes in response to a prompt you type goes through without a permission prompt or classifier review. In these cases Claude Code asks you first, or in [auto mode](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) has the classifier review the publish:
57A new artifact that Claude publishes in response to a prompt you type goes through without a permission prompt or classifier review. In these cases Claude Code asks you first, or in [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) has the classifier review the publish:
5858 
5959| When | What Claude Code does |
6060| :- | :- |
61| The session is in [plan mode](/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) | Asks before the first publish of each artifact |
61| The session is in [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) | Asks before the first publish of each artifact |
6262| The publish declares runtime capabilities for the page, such as [connector calls](#pull-live-data-with-mcp-connectors) or [file downloads](#offer-a-file-download) | Asks before that publish |
6363| You shared the artifact publicly | Asks once per conversation before changing it |
64| Claude publishes in a turn that a [session-scoped scheduled task](/docs/en/scheduled-tasks.md) firing in your session started, rather than a prompt you typed | Asks before the first publish of each artifact |
64| Claude publishes in a turn that a [session-scoped scheduled task](https://code.claude.com/docs/en/scheduled-tasks.md) firing in your session started, rather than a prompt you typed | Asks before the first publish of each artifact |
6565| Claude can't read the file without your approval | Asks before publishing it. An allow rule for the `Artifact` tool doesn't skip this prompt |
66| In [Manual](/docs/en/permission-modes.md) or `acceptEdits` mode, Claude makes a small change to an artifact's file it can't edit without your approval, such as a project file in Manual mode | Asks before publishing the change. You're asked even if an allow rule covers the `Artifact` tool, because the edit to the file needs your approval |
66| In [Manual](https://code.claude.com/docs/en/permission-modes.md) or `acceptEdits` mode, Claude makes a small change to an artifact's file it can't edit without your approval, such as a project file in Manual mode | Asks before publishing the change. You're asked even if an allow rule covers the `Artifact` tool, because the edit to the file needs your approval |
6767 
68To let Claude read a file outside your [working directories](/docs/en/permissions.md#working-directories) without your approval, add its folder as a working directory with [`--add-dir`](/docs/en/cli-reference#cli-flags) at launch or `/add-dir` during the session. Claude already reads files in those directories, and in the temporary directory it writes pages to, without asking.
68To let Claude read a file outside your [working directories](https://code.claude.com/docs/en/permissions.md#working-directories) without your approval, add its folder as a working directory with [`--add-dir`](https://code.claude.com/docs/en/cli-reference#cli-flags) at launch or `/add-dir` during the session. Claude already reads files in those directories, and in the temporary directory it writes pages to, without asking.
6969 
7070If a publish prompt includes a sentence such as `Also makes 1 edit to that file on disk.`, Claude is changing the artifact's file and publishing it in one step. When you approve the prompt, Claude Code publishes the page, then writes the change to your file.
7171 
from line 94
9494* **`Enter`**: opens it in your browser when it's already attached to the current session, and attaches it when it isn't. Before v2.1.216, `Enter` opened it in your browser
9595* **`o`**: opens it in your browser
9696* **`c`**: copies its link
97* **`d`**: outside a [cloud session](/docs/en/claude-code-on-the-web.md), permanently deletes an artifact you own after you confirm. Its link stops working for everyone, including you
97* **`d`**: outside a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), permanently deletes an artifact you own after you confirm. Its link stops working for everyone, including you
9898 
9999Claude Code reads the list from your claude.ai account, so `/artifacts` works in a new session and after `/clear`, when an artifact's link has scrolled out of the terminal.
100100 
from line 131
131131 
132132When someone shares an artifact with you, you can have Claude read it: give Claude its URL, or attach it from [`/artifacts`](#find-an-artifact-again).
133133 
134Claude reads a page someone else wrote the way it reads a web page with [WebFetch](/docs/en/tools-reference.md#webfetch-tool-behavior): it gets a summary of what it asked about rather than the raw page, and the summary reports instructions written into the page instead of relaying them. Claude Code also saves the page's full source to a local file, which Claude can open when it needs the exact content, such as to republish the artifact as an [editor](#let-someone-edit-with-you).
134Claude reads a page someone else wrote the way it reads a web page with [WebFetch](https://code.claude.com/docs/en/tools-reference.md#webfetch-tool-behavior): it gets a summary of what it asked about rather than the raw page, and the summary reports instructions written into the page instead of relaying them. Claude Code also saves the page's full source to a local file, which Claude can open when it needs the exact content, such as to republish the artifact as an [editor](#let-someone-edit-with-you).
135135 
136136Claude Code asks for your approval before Claude reads the artifact in these cases, in addition to any prompt your permission mode or rules call for:
137137 
138* **Cloud session without network access**: for a [cloud environment](/docs/en/cloud-environments.md#access-levels), that's the **None** level. In [auto mode](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), the classifier can approve instead; in a [Cowork](https://claude.com/product/cowork) session, the approval is yours alone.
139* **Another organization's public artifact**: Claude Code asks you first, even in auto mode. Where Claude Code can't ask you, such as in `bypassPermissions` mode, Claude can't read the artifact. Claude can read these artifacts only while [feature-flag fetching](/docs/en/env-vars.md#features-that-need-feature-flag-fetching) is on.
138* **Cloud session without network access**: for a [cloud environment](https://code.claude.com/docs/en/cloud-environments.md#access-levels), that's the **None** level. In [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), the classifier can approve instead; in a [Cowork](https://claude.com/product/cowork) session, the approval is yours alone.
139* **Another organization's public artifact**: Claude Code asks you first, even in auto mode. Where Claude Code can't ask you, such as in `bypassPermissions` mode, Claude can't read the artifact. Claude can read these artifacts only while [feature-flag fetching](https://code.claude.com/docs/en/env-vars.md#features-that-need-feature-flag-fetching) is on.
140140* **Unconfirmed owner or network setting**: when Claude Code can't confirm who made the artifact, or can't confirm a cloud session's network setting, it asks, and your approval covers that one request.
141* **Plan mode**: in [plan mode](/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode), Claude Code asks before the Artifact tool reads an artifact someone else in your organization made.
141* **Plan mode**: in [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode), Claude Code asks before the Artifact tool reads an artifact someone else in your organization made.
142142 
143When Claude reads the artifact with WebFetch, WebFetch's own [prompting rules](/docs/en/tools-reference.md#webfetch-tool-behavior) still apply.
143When Claude reads the artifact with WebFetch, WebFetch's own [prompting rules](https://code.claude.com/docs/en/tools-reference.md#webfetch-tool-behavior) still apply.
144144 
145145## Collect comments on an artifact
146146 
from line 162
162162If Claude tells you it can't read comments, confirm your version, your session, and your feature-flag setting:
163163 
164164* You're running Claude Code v2.1.221 or later.
165* You're not in your first session since you installed Claude Code or upgraded from a version before v2.1.221. In that [first session after an install or upgrade](/docs/en/env-vars.md#first-session-after-an-install-or-upgrade), Claude might not be able to read comments yet; start a new session and ask again.
165* You're not in your first session since you installed Claude Code or upgraded from a version before v2.1.221. In that [first session after an install or upgrade](https://code.claude.com/docs/en/env-vars.md#first-session-after-an-install-or-upgrade), Claude might not be able to read comments yet; start a new session and ask again.
166166* You haven't turned feature-flag fetching off.
167167 
168168### Let Claude reply to comments on its own
from line 169
169169 
170170After your session publishes an artifact, Claude Code watches that artifact for comments. When someone who can edit the artifact sends a comment to Claude, it reaches your session right away, and Claude can read the thread and reply without you asking.
171171 
172You need Claude Code v2.1.228 or later. If you turned [feature-flag fetching](/docs/en/env-vars.md#features-that-need-feature-flag-fetching) off, Claude Code doesn't watch for comments.
172You need Claude Code v2.1.228 or later. If you turned [feature-flag fetching](https://code.claude.com/docs/en/env-vars.md#features-that-need-feature-flag-fetching) off, Claude Code doesn't watch for comments.
173173 
174Your [permission mode](/docs/en/permission-modes.md) decides what Claude does when a sent comment arrives:
174Your [permission mode](https://code.claude.com/docs/en/permission-modes.md) decides what Claude does when a sent comment arrives:
175175 
176176* **Claude replies on its own**: if you're in a permission mode that lets Claude post the reply without asking you, Claude reads the thread and replies. You see `Auto-replied to comment thread on Artifact: <name>`.
177177* **Claude waits for you**: outside plan mode, when posting the reply would need your approval, you see `Comments are waiting on Artifact: <name>`. Claude then asks you for approval to read the thread, and again to post the reply.
from line 185
185185 
186186* **Press Ctrl+C once at an idle prompt**: Claude pauses replying on every artifact your session is watching. Replies start again after you send your next message.
187187* **Stop the task in `/tasks`**: Claude stops replying on that artifact until you ask it to resume replies there. Publishing the artifact again doesn't start replies again, and the stop still applies when you resume the session later.
188* **Press `Ctrl+X Ctrl+K` twice within 3 seconds**: the chord that [stops every running background subagent](/docs/en/interactive-mode.md#general-controls) also stops Claude from replying on every artifact for the rest of the session. Asking Claude to resume replies doesn't undo this stop.
188* **Press `Ctrl+X Ctrl+K` twice within 3 seconds**: the chord that [stops every running background subagent](https://code.claude.com/docs/en/interactive-mode.md#general-controls) also stops Claude from replying on every artifact for the rest of the session. Asking Claude to resume replies doesn't undo this stop.
189189 
190190A watch that Claude Code started on its own can end after the artifact goes several hours without activity. To start the watch again, publish the artifact again or ask Claude to watch it.
191191 
from line 193
193193 
194194## Pull live data with MCP connectors
195195 
196An artifact can call [MCP connectors](/docs/en/mcp.md#use-mcp-servers-from-claude-ai) each time someone views it, so the page shows current data rather than a snapshot from the session that built it. Connector calls from artifacts are available on Pro, Max, Team, and Enterprise plans and require Claude Code v2.1.209 or later. On earlier versions, Claude publishes the page with whatever data the session gathered while building it.
196An artifact can call [MCP connectors](https://code.claude.com/docs/en/mcp.md#use-mcp-servers-from-claude-ai) each time someone views it, so the page shows current data rather than a snapshot from the session that built it. Connector calls from artifacts are available on Pro, Max, Team, and Enterprise plans and require Claude Code v2.1.209 or later. On earlier versions, Claude publishes the page with whatever data the session gathered while building it.
197197 
198198To create a connector-backed page, name the connector and the data you want in your prompt:
199199 
from line 288
288288 
289289## Improve the visual design
290290 
291Claude applies a built-in design skill when it builds an artifact, so pages get a deliberate palette, typography, and layout without extra prompting. That skill also looks for an existing design system in your project before choosing its own. Design tokens are the named color, typography, and spacing values your design system reuses. To keep artifacts consistent with your product's branding, record them where Claude can find them, such as the project's [CLAUDE.md](/docs/en/memory.md) or a theme file in your repository:
291Claude applies a built-in design skill when it builds an artifact, so pages get a deliberate palette, typography, and layout without extra prompting. That skill also looks for an existing design system in your project before choosing its own. Design tokens are the named color, typography, and spacing values your design system reuses. To keep artifacts consistent with your product's branding, record them where Claude can find them, such as the project's [CLAUDE.md](https://code.claude.com/docs/en/memory.md) or a theme file in your repository:
292292 
293293```markdown theme={null}
294294## Design system
from line 334
334334 
335335### Write a document with Claude Docs
336336 
337Claude Docs reaches Claude Code as a claude.ai [connector](/docs/en/mcp.md#use-mcp-servers-from-claude-ai) rather than a command. When it's connected, `/mcp` lists it as `claude.ai Claude Docs`. A request for a document meant for other people then goes to Claude Docs instead of an artifact page: a spec, a proposal, or a write-up of the plan you worked through in the session. Claude gives you the doc's link when it's drafted.
337Claude Docs reaches Claude Code as a claude.ai [connector](https://code.claude.com/docs/en/mcp.md#use-mcp-servers-from-claude-ai) rather than a command. When it's connected, `/mcp` lists it as `claude.ai Claude Docs`. A request for a document meant for other people then goes to Claude Docs instead of an artifact page: a spec, a proposal, or a write-up of the plan you worked through in the session. Claude gives you the doc's link when it's drafted.
338338 
339339A document that belongs in the codebase, such as a README, stays a file. To get a file for something Claude would otherwise put in Claude Docs, name the format, such as `.docx` or a Markdown file in the repository.
340340 
341To turn the connector off, add `claude.ai Claude Docs` to `deniedMcpServers` or use the `/mcp` toggle, both described in [Disable claude.ai connectors](/docs/en/mcp.md#disable-claude-ai-connectors).
341To turn the connector off, add `claude.ai Claude Docs` to `deniedMcpServers` or use the `/mcp` toggle, both described in [Disable claude.ai connectors](https://code.claude.com/docs/en/mcp.md#disable-claude-ai-connectors).
342342 
343343## Page constraints
344344 
from line 350
350350| No backend | An artifact is a static page. It can't authenticate viewers itself. |
351351| Downloads | The page can't start a download itself. To let viewers save a file the page generates, Claude declares the downloads capability. See [Offer a file download](#offer-a-file-download). |
352352| Single page | Relative links do not resolve, because nothing is deployed alongside the page. For multi-section content, Claude uses in-page anchors rather than separate files. |
353| Source file types | The published file must be `.html`, `.htm`, or `.md`, and must decode as UTF-8, or as little-endian UTF-16 by its byte-order mark. Markdown files render as styled document pages with syntax-highlighted code. A file that doesn't decode, or that contains the replacement character `U+FFFD`, is [refused with the line and column to fix](/docs/en/errors.md#the-source-file-is-not-valid-utf-8-text). |
354| Source location | A file at a path that names a network host is refused without being read. See [Not published: that file is on a network share](/docs/en/errors.md#not-published-that-file-is-on-a-network-share) for which paths are refused and the mapped-drive exception on Windows. |
353| Source file types | The published file must be `.html`, `.htm`, or `.md`, and must decode as UTF-8, or as little-endian UTF-16 by its byte-order mark. Markdown files render as styled document pages with syntax-highlighted code. A file that doesn't decode, or that contains the replacement character `U+FFFD`, is [refused with the line and column to fix](https://code.claude.com/docs/en/errors.md#the-source-file-is-not-valid-utf-8-text). |
354| Source location | A file at a path that names a network host is refused without being read. See [Not published: that file is on a network share](https://code.claude.com/docs/en/errors.md#not-published-that-file-is-on-a-network-share) for which paths are refused and the mapped-drive exception on Windows. |
355355| Rendered size | The rendered page must be 16 MiB or smaller. Large embedded images are the usual cause when a publish fails for size. |
356356 
357357Generating an artifact uses output tokens like any other response, and a styled page is more token-intensive than the same content as terminal text. Inline CSS, JavaScript for interactive controls, and especially images embedded as data URIs are the main contributors. To reduce an artifact's token cost:
from line 367
367367| Requirement | Available when |
368368| :- | :- |
369369| Plan | Pro, Max, Team, or Enterprise. On Pro and Max plans, artifacts are private to you until you share them, and no admin management applies. On Team and Enterprise plans, artifacts are on by default, and an Owner can [turn them off for the organization](#manage-artifacts-for-your-organization) in claude.ai admin settings. |
370| Authentication | The session is backed by a claude.ai account: sign in with `/login` in the CLI or desktop app. Claude Tag sessions are signed in through the agent's identity, so no step is needed there. Sessions using an API key, [gateway token](/docs/en/llm-gateway), or cloud-provider credential cannot publish. |
371| Model provider | Anthropic API. Not available on [Amazon Bedrock](/docs/en/amazon-bedrock.md), [Google Cloud's Agent Platform](/docs/en/google-vertex-ai.md), or [Microsoft Foundry](/docs/en/microsoft-foundry.md). |
372| Organization policy | Customer-managed encryption keys (CMEK), HIPAA, and [Zero Data Retention](/docs/en/zero-data-retention.md) are not enabled for the organization. |
373| Surface | Claude Code CLI, or the Claude desktop app version 1.13576.0 or later. [Claude Tag](https://claude.com/docs/claude-tag/overview) sessions can also publish artifacts when both Claude Tag and artifacts are enabled for the organization. Sessions served by [`claude remote-control`](/docs/en/remote-control) can publish artifacts when you started the session yourself. Requires Claude Code v2.1.281 or later. Off by default in the [Agent SDK](/docs/en/agent-sdk/overview.md), the GitHub Action, and MCP-server contexts, when you run Claude Code with [`-p`](/docs/en/headless) from your own terminal or scripts, and when [`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`](/docs/en/env-vars) is set. |
370| Authentication | The session is backed by a claude.ai account: sign in with `/login` in the CLI or desktop app. Claude Tag sessions are signed in through the agent's identity, so no step is needed there. Sessions using an API key, [gateway token](https://code.claude.com/docs/en/llm-gateway), or cloud-provider credential cannot publish. |
371| Model provider | Anthropic API. Not available on [Amazon Bedrock](https://code.claude.com/docs/en/amazon-bedrock.md), [Google Cloud's Agent Platform](https://code.claude.com/docs/en/google-vertex-ai.md), or [Microsoft Foundry](https://code.claude.com/docs/en/microsoft-foundry.md). |
372| Organization policy | Customer-managed encryption keys (CMEK), HIPAA, and [Zero Data Retention](https://code.claude.com/docs/en/zero-data-retention.md) are not enabled for the organization. |
373| Surface | Claude Code CLI, or the Claude desktop app version 1.13576.0 or later. [Claude Tag](https://claude.com/docs/claude-tag/overview) sessions can also publish artifacts when both Claude Tag and artifacts are enabled for the organization. Sessions served by [`claude remote-control`](https://code.claude.com/docs/en/remote-control) can publish artifacts when you started the session yourself. Requires Claude Code v2.1.281 or later. Off by default in the [Agent SDK](https://code.claude.com/docs/en/agent-sdk/overview.md), the GitHub Action, and MCP-server contexts, when you run Claude Code with [`-p`](https://code.claude.com/docs/en/headless) from your own terminal or scripts, and when [`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`](https://code.claude.com/docs/en/env-vars) is set. |
374374 
375375Whether artifacts are allowed for your organization comes from your organization's policy, which Claude Code loads from `api.anthropic.com`. When Claude Code can't load the policy, artifacts are unavailable. When you ask for one, Claude says why.
376376 
from line 382
382382 
383383| Where | What to do |
384384| :- | :- |
385| [`/config`](/docs/en/commands) | Turn the **Artifacts** row off, which writes [`"enableArtifact": false`](/docs/en/settings-reference#enableartifact) to your user settings |
386| [Settings file](/docs/en/settings.md) | Set `"enableArtifact": false`. The deprecated `"disableArtifact": true` also turns artifacts off |
387| [Environment variable](/docs/en/env-vars.md) | Set `CLAUDE_CODE_DISABLE_ARTIFACT=1` |
388| [Permission rule](/docs/en/permissions.md) | Add `Artifact` to `permissions.deny` |
385| [`/config`](https://code.claude.com/docs/en/commands) | Turn the **Artifacts** row off, which writes [`"enableArtifact": false`](https://code.claude.com/docs/en/settings-reference#enableartifact) to your user settings |
386| [Settings file](https://code.claude.com/docs/en/settings.md) | Set `"enableArtifact": false`. The deprecated `"disableArtifact": true` also turns artifacts off |
387| [Environment variable](https://code.claude.com/docs/en/env-vars.md) | Set `CLAUDE_CODE_DISABLE_ARTIFACT=1` |
388| [Permission rule](https://code.claude.com/docs/en/permissions.md) | Add `Artifact` to `permissions.deny` |
389389 
390Once you turn artifacts off in a [`--settings`](/docs/en/cli-reference#cli-flags) file or with `CLAUDE_CODE_DISABLE_ARTIFACT`, or your administrator turns them off in [managed settings](/docs/en/server-managed-settings.md), no settings file turns them back on.
390Once you turn artifacts off in a [`--settings`](https://code.claude.com/docs/en/cli-reference#cli-flags) file or with `CLAUDE_CODE_DISABLE_ARTIFACT`, or your administrator turns them off in [managed settings](https://code.claude.com/docs/en/server-managed-settings.md), no settings file turns them back on.
391391 
392392You can also set `"enableArtifact": false` in a project's `.claude/settings.json` or `.claude/settings.local.json` to turn artifacts off for sessions in that project. An `"enableArtifact": true` in either file doesn't turn them back on. Honoring the key in project and local settings requires Claude Code v2.1.242 or later.
393393 
394If you add a `WebFetch` deny or ask rule with no `domain:` part, it doesn't turn artifacts off or block artifact reads. A [`WebFetch(domain:claude.ai)` rule in `deny` or `ask` does apply to artifact reads](/docs/en/permissions#allow-or-deny-every-fetch).
394If you add a `WebFetch` deny or ask rule with no `domain:` part, it doesn't turn artifacts off or block artifact reads. A [`WebFetch(domain:claude.ai)` rule in `deny` or `ask` does apply to artifact reads](https://code.claude.com/docs/en/permissions#allow-or-deny-every-fetch).
395395 
396396## Manage artifacts for your organization
397397 
from line 419
419419 
420420### Allowlist the viewer domain
421421 
422The viewer on claude.ai loads each artifact from a sandboxed `*.claudeusercontent.com` origin. If your organization restricts outbound network access, add that domain to your allowlist alongside `claude.ai`. See [Network access requirements](/docs/en/network-config.md#network-access-requirements) for the full list.
422The viewer on claude.ai loads each artifact from a sandboxed `*.claudeusercontent.com` origin. If your organization restricts outbound network access, add that domain to your allowlist alongside `claude.ai`. See [Network access requirements](https://code.claude.com/docs/en/network-config.md#network-access-requirements) for the full list.
423423 
424424An artifact that loads a typeface from [Google Fonts](#improve-the-visual-design) also requests `fonts.googleapis.com` and `fonts.gstatic.com`. Both hosts are optional. If you block them, artifacts render in fallback typefaces. Block with a fast rejection rather than a silent drop so the font request fails immediately instead of delaying the page's first render.
425425 
from line 439
439439 
440440## Related resources
441441 
442* Browse [prompting patterns and workflows](/docs/en/prompt-library.md) that pair with artifacts
443* Turn an artifact prompt you reuse into a [skill](/docs/en/skills.md) so you can invoke it as a command
444* [Connect MCP servers](/docs/en/mcp.md) so Claude can pull data into an artifact while it builds the page
442* Browse [prompting patterns and workflows](https://code.claude.com/docs/en/prompt-library.md) that pair with artifacts
443* Turn an artifact prompt you reuse into a [skill](https://code.claude.com/docs/en/skills.md) so you can invoke it as a command
444* [Connect MCP servers](https://code.claude.com/docs/en/mcp.md) so Claude can pull data into an artifact while it builds the page
445445 

authentication Changed · +68 / -68 lines

from line 6
66 
77## Log in to Claude Code
88 
9After [installing Claude Code](/docs/en/setup.md#install-claude-code), run `claude` in your terminal. Claude Code opens a browser window for you to log in on first launch, except in cases such as these, where it can skip the login prompt:
9After [installing Claude Code](https://code.claude.com/docs/en/setup.md#install-claude-code), run `claude` in your terminal. Claude Code opens a browser window for you to log in on first launch, except in cases such as these, where it can skip the login prompt:
1010 
1111* **API key**: you've set the `ANTHROPIC_API_KEY` environment variable and you approve the key when Claude Code asks whether to use it
12* **Earlier sign-in**: you ran [`claude auth login`](/docs/en/cli-reference#cli-commands) in your shell before your first session, or you rebuilt a dev container that keeps your credentials in a [volume](/docs/en/devcontainer.md#persist-authentication-and-settings-across-rebuilds). If you see the login prompt anyway, [check what can cause it](#login-prompt-still-appears-after-an-earlier-sign-in).
12* **Earlier sign-in**: you ran [`claude auth login`](https://code.claude.com/docs/en/cli-reference#cli-commands) in your shell before your first session, or you rebuilt a dev container that keeps your credentials in a [volume](https://code.claude.com/docs/en/devcontainer.md#persist-authentication-and-settings-across-rebuilds). If you see the login prompt anyway, [check what can cause it](#login-prompt-still-appears-after-an-earlier-sign-in).
1313 
1414If the browser doesn't open automatically, press `c` to copy the login URL to your clipboard, then paste it into your browser.
1515 
from line 22
2222* **Claude Pro or Max subscription**: log in with your claude.ai account. Subscribe at [claude.com/pricing](https://claude.com/pricing?utm_source=claude_code\&utm_medium=docs\&utm_content=authentication_pro_max).
2323* **Claude for Teams or Enterprise**: log in with the claude.ai account your team admin invited you to.
2424* **Claude Console**: log in with your Console credentials. Your admin must have [invited you](#claude-console-authentication) first. You can sign in with or without [creating an API key](#sign-in-without-an-api-key).
25* **Cloud providers**: if your organization uses [Amazon Bedrock](/docs/en/amazon-bedrock.md), [Google Cloud's Agent Platform](/docs/en/google-vertex-ai.md), or [Microsoft Foundry](/docs/en/microsoft-foundry.md), set the required environment variables before running `claude`, or select **3rd-party platform** at the login prompt, which launches an interactive setup wizard for Bedrock and Vertex AI. No browser login is needed.
26* **Cloud gateway**: if your organization runs a self-hosted [Claude apps gateway](/docs/en/claude-apps-gateway), sign in with corporate SSO through `/login`. The gateway-issued token is the session's only credential.
25* **Cloud providers**: if your organization uses [Amazon Bedrock](https://code.claude.com/docs/en/amazon-bedrock.md), [Google Cloud's Agent Platform](https://code.claude.com/docs/en/google-vertex-ai.md), or [Microsoft Foundry](https://code.claude.com/docs/en/microsoft-foundry.md), set the required environment variables before running `claude`, or select **3rd-party platform** at the login prompt, which launches an interactive setup wizard for Bedrock and Vertex AI. No browser login is needed.
26* **Cloud gateway**: if your organization runs a self-hosted [Claude apps gateway](https://code.claude.com/docs/en/claude-apps-gateway), sign in with corporate SSO through `/login`. The gateway-issued token is the session's only credential.
2727 
2828Admins can direct which login method developers use and require claude.ai logins to belong to a specific organization; see [Restrict login to your organization](#restrict-login-to-your-organization).
2929 
3030To log out and re-authenticate, type `/logout` at the Claude Code prompt. Logging out also resets your first-launch setup state, so the next time you run `claude` it walks you through login and setup again.
3131 
32If you're having trouble logging in, see [authentication troubleshooting](/docs/en/troubleshoot-install.md#login-and-authentication).
32If you're having trouble logging in, see [authentication troubleshooting](https://code.claude.com/docs/en/troubleshoot-install.md#login-and-authentication).
3333 
3434### Login prompt still appears after an earlier sign-in
3535 
from line 36
3636If you signed in earlier and first-launch setup shows the login prompt instead of [skipping it](#log-in-to-claude-code), check for causes such as these:
3737 
3838* **Expired sign-in**: your earlier sign-in expired and Claude Code can't refresh it. Log in again at the prompt.
39* **Login restricted to an organization**: an administrator set [`forceLoginOrgUUID`](/docs/en/settings-reference#forceloginorguuid) in managed settings to [require logins from specific organizations](#restrict-login-to-your-organization). The prompt appears whether or not your account belongs to one of them. Log in with an account in a required organization. If you don't have one, ask your administrator to add you.
40* **Required login method**: your sign-in isn't the kind that [`forceLoginMethod`](/docs/en/settings-reference#forceloginmethod) in a settings file requires. With `"claudeai"`, an API key from an earlier Claude Console login doesn't count as an existing sign-in. With `"console"`, a claude.ai account doesn't. Log in with the kind of account that setting names.
41* **Older version**: before v2.1.290, the prompt appeared during setup whether or not you were signed in. [Update Claude Code](/docs/en/setup.md#update-claude-code) to skip it.
39* **Login restricted to an organization**: an administrator set [`forceLoginOrgUUID`](https://code.claude.com/docs/en/settings-reference#forceloginorguuid) in managed settings to [require logins from specific organizations](#restrict-login-to-your-organization). The prompt appears whether or not your account belongs to one of them. Log in with an account in a required organization. If you don't have one, ask your administrator to add you.
40* **Required login method**: your sign-in isn't the kind that [`forceLoginMethod`](https://code.claude.com/docs/en/settings-reference#forceloginmethod) in a settings file requires. With `"claudeai"`, an API key from an earlier Claude Console login doesn't count as an existing sign-in. With `"console"`, a claude.ai account doesn't. Log in with the kind of account that setting names.
41* **Older version**: before v2.1.290, the prompt appeared during setup whether or not you were signed in. [Update Claude Code](https://code.claude.com/docs/en/setup.md#update-claude-code) to skip it.
4242 
4343### Log in with multiple accounts
4444 
45To stay signed in to multiple accounts at once, such as work and personal accounts, give each account its own configuration directory. When you start `claude`, set the [`CLAUDE_CONFIG_DIR`](/docs/en/env-vars#variables) environment variable to the directory for the account you want to use. Each directory has its own settings, session history, and claude.ai login or API key. For example, in Bash or Zsh, add this alias to `~/.bashrc` or `~/.zshrc` so that `claude-work` uses your work account while `claude` keeps your personal one:
45To stay signed in to multiple accounts at once, such as work and personal accounts, give each account its own configuration directory. When you start `claude`, set the [`CLAUDE_CONFIG_DIR`](https://code.claude.com/docs/en/env-vars#variables) environment variable to the directory for the account you want to use. Each directory has its own settings, session history, and claude.ai login or API key. For example, in Bash or Zsh, add this alias to `~/.bashrc` or `~/.zshrc` so that `claude-work` uses your work account while `claude` keeps your personal one:
4646 
4747```bash theme={null}
4848alias claude-work='CLAUDE_CONFIG_DIR=~/.claude-work claude'
from line 56
5656 
5757* [Claude for Teams or Enterprise](#claude-for-teams-or-enterprise), recommended for most teams
5858* [Claude Console](#claude-console-authentication)
59* [Claude apps gateway](/docs/en/claude-apps-gateway), a self-hosted gateway that signs developers in with your IdP and routes inference to the cloud provider you configure
60* [Amazon Bedrock](/docs/en/amazon-bedrock.md)
61* [Google Cloud's Agent Platform](/docs/en/google-vertex-ai.md)
62* [Microsoft Foundry](/docs/en/microsoft-foundry.md)
59* [Claude apps gateway](https://code.claude.com/docs/en/claude-apps-gateway), a self-hosted gateway that signs developers in with your IdP and routes inference to the cloud provider you configure
60* [Amazon Bedrock](https://code.claude.com/docs/en/amazon-bedrock.md)
61* [Google Cloud's Agent Platform](https://code.claude.com/docs/en/google-vertex-ai.md)
62* [Microsoft Foundry](https://code.claude.com/docs/en/microsoft-foundry.md)
6363 
6464### Claude for Teams or Enterprise
6565 
6666[Claude for Teams](https://claude.com/pricing?utm_source=claude_code\&utm_medium=docs\&utm_content=authentication_teams#team-&-enterprise) and [Claude for Enterprise](https://anthropic.com/contact-sales?utm_source=claude_code\&utm_medium=docs\&utm_content=authentication_enterprise) provide the best experience for organizations using Claude Code. Team members get access to both Claude Code and Claude on the web with centralized billing and team management.
6767 
68* **Claude for Teams**: self-service plan with collaboration features, admin tools, SSO, billing management, and [server-managed settings](/docs/en/server-managed-settings.md) for organization-wide Claude Code configuration. Best for smaller teams.
68* **Claude for Teams**: self-service plan with collaboration features, admin tools, SSO, billing management, and [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md) for organization-wide Claude Code configuration. Best for smaller teams.
6969* **Claude for Enterprise**: adds domain capture, role-based permissions, and the compliance API. Best for larger organizations with security and compliance requirements.
7070 
7171**1. Subscribe**
from line 107
107107Each invited user needs to:
108108 
109109* Accept the Console invite
110* [Check system requirements](/docs/en/setup.md#system-requirements)
111* [Install Claude Code](/docs/en/setup.md#install-claude-code)
110* [Check system requirements](https://code.claude.com/docs/en/setup.md#system-requirements)
111* [Install Claude Code](https://code.claude.com/docs/en/setup.md#install-claude-code)
112112* Log in with Console account credentials
113113 
114114#### Sign in without an API key
from line 118
118118* **Sign in with your Console account**, labeled `(recommended)`: Claude Code keeps the OAuth token from that sign-in and stores it as an [Anthropic profile](#anthropic-profiles-and-federation-credentials). It creates no API key
119119* **Create an API key**, labeled `(legacy)`: Claude Code creates a Console API key for you and stores it with your other credentials
120120 
121In practice, the profile stores an OAuth login while an API key is a static credential. Claude Code refreshes the profile's login automatically, and when refresh fails, requests fail with an [expired profile login error](/docs/en/errors.md#anthropic-profile-login-expired) until you sign in again.
121In practice, the profile stores an OAuth login while an API key is a static credential. Claude Code refreshes the profile's login automatically, and when refresh fails, requests fail with an [expired profile login error](https://code.claude.com/docs/en/errors.md#anthropic-profile-login-expired) until you sign in again.
122122 
123123You don't get the choice on every machine. Claude Code creates an API key without asking in these cases:
124124 
125* You run against a cloud provider, such as [Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry](/docs/en/third-party-integrations.md) or [Claude Platform on AWS](/docs/en/claude-platform-on-aws.md)
125* You run against a cloud provider, such as [Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry](https://code.claude.com/docs/en/third-party-integrations.md) or [Claude Platform on AWS](https://code.claude.com/docs/en/claude-platform-on-aws.md)
126126* Any settings file sets [`forceLoginOrgUUID`](#restrict-login-to-your-organization), or sets `forceLoginMethod` to `"claudeai"` or `"console"`
127* A managed settings source on your machine, such as the managed settings file, an MDM profile, or the cached server-managed settings, exists but Claude Code [can't read it](/docs/en/managed-settings.md#invalid-entries-in-managed-settings) and no other managed source supplies a policy
127* A managed settings source on your machine, such as the managed settings file, an MDM profile, or the cached server-managed settings, exists but Claude Code [can't read it](https://code.claude.com/docs/en/managed-settings.md#invalid-entries-in-managed-settings) and no other managed source supplies a policy
128128 
129129Unset `ANTHROPIC_API_KEY` before you sign in without a key.
130130 
from line 142
142142 
143143**1. Follow provider setup**
144144 
145Follow the [Amazon Bedrock docs](/docs/en/amazon-bedrock.md), [Google Cloud's Agent Platform docs](/docs/en/google-vertex-ai.md), or [Microsoft Foundry docs](/docs/en/microsoft-foundry.md).
145Follow the [Amazon Bedrock docs](https://code.claude.com/docs/en/amazon-bedrock.md), [Google Cloud's Agent Platform docs](https://code.claude.com/docs/en/google-vertex-ai.md), or [Microsoft Foundry docs](https://code.claude.com/docs/en/microsoft-foundry.md).
146146 
147147**2. Distribute configuration**
148148 
149Distribute the environment variables and instructions for generating cloud credentials to your users. Read more about how to [manage configuration here](/docs/en/settings.md).
149Distribute the environment variables and instructions for generating cloud credentials to your users. Read more about how to [manage configuration here](https://code.claude.com/docs/en/settings.md).
150150 
151151**3. Install Claude Code**
152152 
153Users can [install Claude Code](/docs/en/setup.md#install-claude-code).
153Users can [install Claude Code](https://code.claude.com/docs/en/setup.md#install-claude-code).
154154 
155155### Restrict login to your organization
156156 
157To require that developers' claude.ai logins belong to a specific Anthropic organization, set [`forceLoginMethod`](/docs/en/settings-reference#forceloginmethod) and [`forceLoginOrgUUID`](/docs/en/settings-reference#forceloginorguuid) in [managed settings](/docs/en/managed-settings.md). Set `forceLoginOrgUUID` to your organization ID, shown in [claude.ai admin settings](https://claude.ai/admin-settings/organization) for Claude for Teams or Enterprise organizations. Claude Code reports an error for a claude.ai login to any other organization and exits at startup if the claude.ai credential in use belongs to an organization that isn't listed.
157To require that developers' claude.ai logins belong to a specific Anthropic organization, set [`forceLoginMethod`](https://code.claude.com/docs/en/settings-reference#forceloginmethod) and [`forceLoginOrgUUID`](https://code.claude.com/docs/en/settings-reference#forceloginorguuid) in [managed settings](https://code.claude.com/docs/en/managed-settings.md). Set `forceLoginOrgUUID` to your organization ID, shown in [claude.ai admin settings](https://claude.ai/admin-settings/organization) for Claude for Teams or Enterprise organizations. Claude Code reports an error for a claude.ai login to any other organization and exits at startup if the claude.ai credential in use belongs to an organization that isn't listed.
158158 
159For Claude Console logins, Claude Code uses `forceLoginOrgUUID` to pre-select the organization on the Console sign-in page when you set it to a single Console organization ID, shown at [platform.claude.com/settings/organization](https://platform.claude.com/settings/organization). It doesn't check which organization the resulting Console credential belongs to, at login or at startup. A developer who logged in with a Console account before you deployed the keys stays logged in, and that saved key is blocked on a machine that also requires the [gateway](/docs/en/claude-apps-gateway) sign-in or in a session that selects a cloud provider.
159For Claude Console logins, Claude Code uses `forceLoginOrgUUID` to pre-select the organization on the Console sign-in page when you set it to a single Console organization ID, shown at [platform.claude.com/settings/organization](https://platform.claude.com/settings/organization). It doesn't check which organization the resulting Console credential belongs to, at login or at startup. A developer who logged in with a Console account before you deployed the keys stays logged in, and that saved key is blocked on a machine that also requires the [gateway](https://code.claude.com/docs/en/claude-apps-gateway) sign-in or in a session that selects a cloud provider.
160160 
161161If you set `forceLoginOrgUUID` in any settings file, Claude Code stops offering the [keyless Console sign-in](#sign-in-without-an-api-key) in the sessions that file applies to and creates an API key instead. To direct developers to claude.ai sign-in instead, set `forceLoginMethod` to `"claudeai"`.
162162 
from line 164
164164 
165165The paths differ on `forceLoginOrgUUID`:
166166 
167* **Terminal, [VS Code extension](/docs/en/vs-code.md), and Agent SDK logins**: verify `forceLoginOrgUUID` for claude.ai account logins
167* **Terminal, [VS Code extension](https://code.claude.com/docs/en/vs-code.md), and Agent SDK logins**: verify `forceLoginOrgUUID` for claude.ai account logins
168168* **`claude setup-token` and `/install-github-app`**: enforce only `forceLoginMethod`, so they can mint a token in a different organization
169* **[Gateway](/docs/en/claude-apps-gateway) sign-in**: selected by `forceLoginMethod: "gateway"` rather than restricted by it, and doesn't authenticate against an Anthropic organization, so `forceLoginOrgUUID` doesn't apply; use your gateway identity provider to restrict access
169* **[Gateway](https://code.claude.com/docs/en/claude-apps-gateway) sign-in**: selected by `forceLoginMethod: "gateway"` rather than restricted by it, and doesn't authenticate against an Anthropic organization, so `forceLoginOrgUUID` doesn't apply; use your gateway identity provider to restrict access
170170 
171Deploy the keys through your device management tooling. [Server-managed settings](/docs/en/server-managed-settings.md) reach only accounts that are already authenticated into your organization, so they can't redirect a developer's first login. If your organization distributes server-managed settings as well, set the keys in both places: managed-settings sources [don't merge](/docs/en/server-managed-settings.md#settings-precedence), and cached server-managed settings replace the device-managed file apart from a few [per-key exceptions](/docs/en/server-managed-settings.md#per-key-exceptions-across-managed-sources). `forceLoginOrgUUID` and the `"claudeai"` and `"console"` values of `forceLoginMethod` aren't among those exceptions, so keep them in both places.
171Deploy the keys through your device management tooling. [Server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md) reach only accounts that are already authenticated into your organization, so they can't redirect a developer's first login. If your organization distributes server-managed settings as well, set the keys in both places: managed-settings sources [don't merge](https://code.claude.com/docs/en/server-managed-settings.md#settings-precedence), and cached server-managed settings replace the device-managed file apart from a few [per-key exceptions](https://code.claude.com/docs/en/server-managed-settings.md#per-key-exceptions-across-managed-sources). `forceLoginOrgUUID` and the `"claudeai"` and `"console"` values of `forceLoginMethod` aren't among those exceptions, so keep them in both places.
172172 
173In a [gateway](/docs/en/claude-apps-gateway) deployment, also keep `forceLoginMethod` and `forceLoginOrgUUID` out of the [settings the gateway serves](/docs/en/claude-apps-gateway-config.md#managed).
173In a [gateway](https://code.claude.com/docs/en/claude-apps-gateway) deployment, also keep `forceLoginMethod` and `forceLoginOrgUUID` out of the [settings the gateway serves](https://code.claude.com/docs/en/claude-apps-gateway-config.md#managed).
174174 
175The keys also decide whether a session that doesn't use a login credential can start. See [`forceLoginOrgUUID`](/docs/en/settings-reference#forceloginorguuid) in the settings reference for the full behavior.
175The keys also decide whether a session that doesn't use a login credential can start. See [`forceLoginOrgUUID`](https://code.claude.com/docs/en/settings-reference#forceloginorguuid) in the settings reference for the full behavior.
176176 
177* **`ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper`**: blocked at startup. Under `forceLoginOrgUUID`, organization membership can't be verified for an environment credential, and under `forceLoginMethod` the credential would stand in for the required sign-in. When the managed settings also require the [gateway](/docs/en/claude-apps-gateway) sign-in, Claude Code blocks an API key saved by an earlier Claude Console login the same way. See [Administrator policy requires a Cloud gateway sign-in](/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in)
177* **`ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper`**: blocked at startup. Under `forceLoginOrgUUID`, organization membership can't be verified for an environment credential, and under `forceLoginMethod` the credential would stand in for the required sign-in. When the managed settings also require the [gateway](https://code.claude.com/docs/en/claude-apps-gateway) sign-in, Claude Code blocks an API key saved by an earlier Claude Console login the same way. See [Administrator policy requires a Cloud gateway sign-in](https://code.claude.com/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in)
178178* **Cloud provider sessions such as Amazon Bedrock**: blocked only while an `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` credential, or an API key saved by an earlier Claude Console login, is still present on the machine. Remove it and the session starts. These sessions authenticate against your cloud provider, whose access policies govern them
179179* **[Anthropic profile or federation credentials](#anthropic-profiles-and-federation-credentials)**: not blocked unless an `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` credential, or an API key saved by an earlier Claude Console login, is also present on the machine. The keys don't check which organization the profile belongs to
180180 
181181### Restrict which API providers a machine may use
182182 
183[`allowedProviders`](/docs/en/settings-reference#allowedproviders) in [managed settings](/docs/en/managed-settings.md) lists which services a managed machine may reach Claude through, such as the Anthropic API, Amazon Bedrock, or an LLM gateway. It complements `forceLoginMethod` and `forceLoginOrgUUID`, which govern which account a session uses when it talks to Anthropic. Requires Claude Code v2.1.285 or later.
183[`allowedProviders`](https://code.claude.com/docs/en/settings-reference#allowedproviders) in [managed settings](https://code.claude.com/docs/en/managed-settings.md) lists which services a managed machine may reach Claude through, such as the Anthropic API, Amazon Bedrock, or an LLM gateway. It complements `forceLoginMethod` and `forceLoginOrgUUID`, which govern which account a session uses when it talks to Anthropic. Requires Claude Code v2.1.285 or later.
184184 
185185```json managed-settings.json theme={null}
186186{
from line 190
190190}
191191```
192192 
193With this file, a developer signed in to your claude.ai organization or configured for Amazon Bedrock starts normally. A session set up for any other provider is refused at startup, and a running session that switches to one is refused on its next request. [Managed settings don't allow this API provider](/docs/en/errors.md#managed-settings-dont-allow-this-api-provider) shows each message.
193With this file, a developer signed in to your claude.ai organization or configured for Amazon Bedrock starts normally. A session set up for any other provider is refused at startup, and a running session that switches to one is refused on its next request. [Managed settings don't allow this API provider](https://code.claude.com/docs/en/errors.md#managed-settings-dont-allow-this-api-provider) shows each message.
194194 
195* **Allow an LLM gateway or proxy**: list `"customEndpoint"` and set the gateway's URL in the managed `env` block of the same source. The [settings reference](/docs/en/settings-reference.md#allowedproviders) lists every value and says which endpoint variables need a managed `env` pin.
196* **Deploy on managed machines**: put the list in the managed source that carries the rest of your policy. The entry's [Scope note](/docs/en/settings-reference.md#allowedproviders) says how a server-managed list combines with it.
197* **Server-managed settings only**: a list you set only in [server-managed settings](/docs/en/server-managed-settings.md) reaches only sessions that fetch your organization's settings, so treat it as a convenience for machines you can't reach with device management, not as enforcement. [Platform availability](/docs/en/server-managed-settings.md#platform-availability) lists which sessions fetch them.
195* **Allow an LLM gateway or proxy**: list `"customEndpoint"` and set the gateway's URL in the managed `env` block of the same source. The [settings reference](https://code.claude.com/docs/en/settings-reference.md#allowedproviders) lists every value and says which endpoint variables need a managed `env` pin.
196* **Deploy on managed machines**: put the list in the managed source that carries the rest of your policy. The entry's [Scope note](https://code.claude.com/docs/en/settings-reference.md#allowedproviders) says how a server-managed list combines with it.
197* **Server-managed settings only**: a list you set only in [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md) reaches only sessions that fetch your organization's settings, so treat it as a convenience for machines you can't reach with device management, not as enforcement. [Platform availability](https://code.claude.com/docs/en/server-managed-settings.md#platform-availability) lists which sessions fetch them.
198198 
199199## Credential management
200200 
from line 201
201201Claude Code securely manages your authentication credentials:
202202 
203203* **Storage location**:
204 * On macOS, credentials are stored in the encrypted macOS Keychain. When the Keychain rejects the write, such as when it's locked in an SSH session, Claude Code stores your login in `~/.claude/.credentials.json` with file mode `0600` instead, the same storage it uses on Linux. A Console login that creates an API key fails until the Keychain is writable. To move your login back into the Keychain, follow [the recovery steps](/docs/en/troubleshoot-install.md#not-logged-in-or-token-expired).
204 * On macOS, credentials are stored in the encrypted macOS Keychain. When the Keychain rejects the write, such as when it's locked in an SSH session, Claude Code stores your login in `~/.claude/.credentials.json` with file mode `0600` instead, the same storage it uses on Linux. A Console login that creates an API key fails until the Keychain is writable. To move your login back into the Keychain, follow [the recovery steps](https://code.claude.com/docs/en/troubleshoot-install.md#not-logged-in-or-token-expired).
205205 * On Linux, credentials are stored in `~/.claude/.credentials.json` with file mode `0600`.
206206 * On Windows, credentials are stored in `%USERPROFILE%\.claude\.credentials.json` and inherit the access controls of your user profile directory, which restricts the file to your user account by default.
207207 * If you've set the `CLAUDE_CONFIG_DIR` environment variable, Claude Code keeps the `.credentials.json` file under that directory instead, including the file the macOS fallback writes, and keys the macOS Keychain entry to that directory too, so a session with a different `CLAUDE_CONFIG_DIR` reads a different entry.
208 * Claude Code manages `.credentials.json` through `/login` and `/logout`. To route requests through a custom API endpoint, set the [`ANTHROPIC_BASE_URL`](/docs/en/env-vars) environment variable instead.
209* **Supported authentication types**: claude.ai credentials, Claude API credentials, Microsoft Foundry Auth, Bedrock Auth, Vertex Auth, Anthropic profile and [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation) credentials, and [Claude apps gateway](/docs/en/claude-apps-gateway) session tokens.
210* **Custom credential scripts**: configure the [`apiKeyHelper`](/docs/en/settings-reference#apikeyhelper) setting to run a shell script that returns an API key.
211* **Refresh intervals**: see [`apiKeyHelper`](/docs/en/settings-reference#apikeyhelper) for the cases in which Claude Code re-runs the helper.
208 * Claude Code manages `.credentials.json` through `/login` and `/logout`. To route requests through a custom API endpoint, set the [`ANTHROPIC_BASE_URL`](https://code.claude.com/docs/en/env-vars) environment variable instead.
209* **Supported authentication types**: claude.ai credentials, Claude API credentials, Microsoft Foundry Auth, Bedrock Auth, Vertex Auth, Anthropic profile and [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation) credentials, and [Claude apps gateway](https://code.claude.com/docs/en/claude-apps-gateway) session tokens.
210* **Custom credential scripts**: configure the [`apiKeyHelper`](https://code.claude.com/docs/en/settings-reference#apikeyhelper) setting to run a shell script that returns an API key.
211* **Refresh intervals**: see [`apiKeyHelper`](https://code.claude.com/docs/en/settings-reference#apikeyhelper) for the cases in which Claude Code re-runs the helper.
212212* **Slow helper notice**: if `apiKeyHelper` takes longer than 10 seconds to return a key, Claude Code displays a warning notice in the prompt bar showing the elapsed time. If you see this notice regularly, check whether your credential script can be optimized.
213* **Helper failures**: when the script exits with an error, times out, or prints nothing, requests fail with [`Your apiKeyHelper script is failing`](/docs/en/errors#your-apikeyhelper-script-is-failing) within three attempts.
213* **Helper failures**: when the script exits with an error, times out, or prints nothing, requests fail with [`Your apiKeyHelper script is failing`](https://code.claude.com/docs/en/errors#your-apikeyhelper-script-is-failing) within three attempts.
214214 
215`apiKeyHelper`, `ANTHROPIC_API_KEY`, and `ANTHROPIC_AUTH_TOKEN` apply to the CLI and the surfaces that wrap it, including the VS Code extension, the Agent SDK, and GitHub Actions. Claude Desktop and cloud sessions do not call `apiKeyHelper` or read these environment variables: they use OAuth, except desktop sessions running a [third-party inference configuration](/docs/en/llm-gateway-connect.md#desktop-app), which authenticate with that configuration's credential.
215`apiKeyHelper`, `ANTHROPIC_API_KEY`, and `ANTHROPIC_AUTH_TOKEN` apply to the CLI and the surfaces that wrap it, including the VS Code extension, the Agent SDK, and GitHub Actions. Claude Desktop and cloud sessions do not call `apiKeyHelper` or read these environment variables: they use OAuth, except desktop sessions running a [third-party inference configuration](https://code.claude.com/docs/en/llm-gateway-connect.md#desktop-app), which authenticate with that configuration's credential.
216216 
217217### Renew an expiring login
218218 
from line 220
220220 
221221Run `/login` to renew. The warning is informational and never blocks a request: authentication keeps working until the login actually expires.
222222 
223Once the stored login expires and can't be refreshed, each model request fails with [`Login expired · Please run /login`](/docs/en/errors#login-expired) until you sign in again.
223Once the stored login expires and can't be refreshed, each model request fails with [`Login expired · Please run /login`](https://code.claude.com/docs/en/errors#login-expired) until you sign in again.
224224 
225You can check for this state before a request fails: [`/status`](/docs/en/commands) shows a `Login` row reading `Expired — log in again`, plus the organization and email it has saved for the expired login. The row appears only when the saved claude.ai login is the active credential. The row requires Claude Code v2.1.210 or later.
225You can check for this state before a request fails: [`/status`](https://code.claude.com/docs/en/commands) shows a `Login` row reading `Expired — log in again`, plus the organization and email it has saved for the expired login. The row appears only when the saved claude.ai login is the active credential. The row requires Claude Code v2.1.210 or later.
226226 
227227The warning appears only when a claude.ai login is the active credential, and not when a cloud provider, `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` supplies the credential.
228228 
229Renewing early matters most for sessions that run unattended. A [background session in agent view](/docs/en/agent-view.md) or a [Remote Control](/docs/en/remote-control.md) session that outlives the login stops making progress once the credential expires and can't recover until you sign in again.
229Renewing early matters most for sessions that run unattended. A [background session in agent view](https://code.claude.com/docs/en/agent-view.md) or a [Remote Control](https://code.claude.com/docs/en/remote-control.md) session that outlives the login stops making progress once the credential expires and can't recover until you sign in again.
230230 
231231### Authentication precedence
232232 
233233When multiple credentials are present, Claude Code chooses one in this order:
234234 
2351. Cloud provider credentials, when `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, or `CLAUDE_CODE_USE_FOUNDRY` is set. See [third-party integrations](/docs/en/third-party-integrations.md) for setup.
2362. `ANTHROPIC_AUTH_TOKEN` environment variable. Sent as the `Authorization: Bearer` header. Use this when routing through an [LLM gateway or proxy](/docs/en/llm-gateway) that authenticates with bearer tokens rather than Anthropic API keys.
2351. Cloud provider credentials, when `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, or `CLAUDE_CODE_USE_FOUNDRY` is set. See [third-party integrations](https://code.claude.com/docs/en/third-party-integrations.md) for setup.
2362. `ANTHROPIC_AUTH_TOKEN` environment variable. Sent as the `Authorization: Bearer` header. Use this when routing through an [LLM gateway or proxy](https://code.claude.com/docs/en/llm-gateway) that authenticates with bearer tokens rather than Anthropic API keys.
2372373. `ANTHROPIC_API_KEY` environment variable. Sent as the `X-Api-Key` header. Use this for direct Anthropic API access with a key from the [Claude Console](https://platform.claude.com). In interactive mode, you are prompted once to approve or decline the key, and your choice is remembered. To change it later, use the "Use custom API key" toggle in `/config`. The toggle only appears while `ANTHROPIC_API_KEY` is set in your environment. In non-interactive mode (`-p`), the key is always used when present.
2384. [`apiKeyHelper`](/docs/en/settings-reference#apikeyhelper) script output. Use this for dynamic or rotating credentials, such as short-lived tokens fetched from a vault.
2395. `CLAUDE_CODE_OAUTH_TOKEN` environment variable. A long-lived OAuth token generated by [`claude setup-token`](#generate-a-long-lived-token). Use this for CI pipelines and scripts where browser login isn't available. If you run `/login` while the variable is set, Claude Code switches the current session to the new login, but reads the variable again in every new session until you remove it from your shell profile or the `env` block of a [settings file](/docs/en/settings.md).
2384. [`apiKeyHelper`](https://code.claude.com/docs/en/settings-reference#apikeyhelper) script output. Use this for dynamic or rotating credentials, such as short-lived tokens fetched from a vault.
2395. `CLAUDE_CODE_OAUTH_TOKEN` environment variable. A long-lived OAuth token generated by [`claude setup-token`](#generate-a-long-lived-token). Use this for CI pipelines and scripts where browser login isn't available. If you run `/login` while the variable is set, Claude Code switches the current session to the new login, but reads the variable again in every new session until you remove it from your shell profile or the `env` block of a [settings file](https://code.claude.com/docs/en/settings.md).
2402406. Anthropic profile and federation credentials, the credentials that the `ant` CLI and Workload Identity Federation use. A profile that `ant auth login` wrote ranks here only when you name it in `ANTHROPIC_PROFILE`; otherwise it ranks below `/login`. See [Anthropic profiles and federation credentials](#anthropic-profiles-and-federation-credentials).
2412417. Subscription OAuth credentials from `/login`. This is the default for Claude Pro, Max, Team, and Enterprise users.
242242 
243A signed-in [Claude apps gateway](/docs/en/claude-apps-gateway) session sits outside this list: it is a provider selection like Amazon Bedrock or Google Cloud's Agent Platform, and it outranks them. When a gateway session exists, the CLI authenticates with the gateway token even if `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, or `CLAUDE_CODE_USE_FOUNDRY` is set, and credential sources above such as the bearer token, API key, `apiKeyHelper`, and profiles are not used.
243A signed-in [Claude apps gateway](https://code.claude.com/docs/en/claude-apps-gateway) session sits outside this list: it is a provider selection like Amazon Bedrock or Google Cloud's Agent Platform, and it outranks them. When a gateway session exists, the CLI authenticates with the gateway token even if `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, or `CLAUDE_CODE_USE_FOUNDRY` is set, and credential sources above such as the bearer token, API key, `apiKeyHelper`, and profiles are not used.
244244 
245If your machine's [managed settings](/docs/en/managed-settings.md) set [`forceLoginMethod`](/docs/en/settings-reference#forceloginmethod) to `"gateway"` or set [`forceLoginGatewayUrl`](/docs/en/settings-reference#forcelogingatewayurl), and you don't select a cloud provider through a variable such as `CLAUDE_CODE_USE_BEDROCK` or `CLAUDE_CODE_USE_VERTEX`, your session uses only the gateway sign-in. Claude Code skips the other credential sources and asks you to sign in with `/login`. See [Administrator policy requires a Cloud gateway sign-in](/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in) for what you see with each leftover credential. Requires Claude Code v2.1.261 or later, or v2.1.265 or later on a machine that sets only `forceLoginGatewayUrl`.
245If your machine's [managed settings](https://code.claude.com/docs/en/managed-settings.md) set [`forceLoginMethod`](https://code.claude.com/docs/en/settings-reference#forceloginmethod) to `"gateway"` or set [`forceLoginGatewayUrl`](https://code.claude.com/docs/en/settings-reference#forcelogingatewayurl), and you don't select a cloud provider through a variable such as `CLAUDE_CODE_USE_BEDROCK` or `CLAUDE_CODE_USE_VERTEX`, your session uses only the gateway sign-in. Claude Code skips the other credential sources and asks you to sign in with `/login`. See [Administrator policy requires a Cloud gateway sign-in](https://code.claude.com/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in) for what you see with each leftover credential. Requires Claude Code v2.1.261 or later, or v2.1.265 or later on a machine that sets only `forceLoginGatewayUrl`.
246246 
247247If you have an active Claude subscription but also have `ANTHROPIC_API_KEY` set in your environment, Claude Code uses the API key once you approve it. This can cause authentication failures if the key belongs to a disabled or expired organization.
248248 
249249Run `unset ANTHROPIC_API_KEY` to fall back to your subscription, and check `/status` to confirm which method is active. When a login and an API key are both configured, `/status` marks the credential that isn't in use.
250250 
251[Cloud sessions](/docs/en/claude-code-on-the-web.md) always use your subscription credentials. If you set `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN` in the cloud environment, it doesn't override your subscription credentials.
251[Cloud sessions](https://code.claude.com/docs/en/claude-code-on-the-web.md) always use your subscription credentials. If you set `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN` in the cloud environment, it doesn't override your subscription credentials.
252252 
253253#### Anthropic profiles and federation credentials
254254 
255255A profile is a named credential configuration file in your [Anthropic configuration directory](https://platform.claude.com/docs/en/manage-claude/wif-reference#configuration-directory), by default `~/.config/anthropic` on macOS and Linux or `%APPDATA%\Anthropic` on Windows. A profile's auth mode is `oidc_federation` when you set it up for [Workload Identity Federation (WIF)](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation) or `user_oauth` when [`ant auth login`](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/authentication) wrote it or you [signed in to a Console account without an API key](#sign-in-without-an-api-key).
256256 
257Claude Code doesn't read profiles or federation variables in [bare mode](/docs/en/headless.md#start-faster-with-bare-mode), in Claude Desktop, or in cloud sessions. In those sessions, `/status` shows no `Profile` row.
257Claude Code doesn't read profiles or federation variables in [bare mode](https://code.claude.com/docs/en/headless.md#start-faster-with-bare-mode), in Claude Desktop, or in cloud sessions. In those sessions, `/status` shows no `Profile` row.
258258 
259259Claude Code checks three sources in this order and stops at the first one that is set. The table shows what sets each source and where it ranks against your `/login` credential.
260260 
from line 268
268268 
269269To confirm which source Claude Code chose, run `/status`. A `Profile` row names the source in place of the `Login method` row. When the profile is the credential in use, `Organization` and `Email` rows show its account.
270270 
271When a `user_oauth` profile's login has expired and Claude Code can't renew it, requests fail with an [expired profile login error](/docs/en/errors.md#anthropic-profile-login-expired).
271When a `user_oauth` profile's login has expired and Claude Code can't renew it, requests fail with an [expired profile login error](https://code.claude.com/docs/en/errors.md#anthropic-profile-login-expired).
272272 
273Features that need your claude.ai login, such as [claude.ai connectors](/docs/en/mcp.md#use-mcp-servers-from-claude-ai) and [`/schedule`](/docs/en/routines), aren't available while one of these sources is selected. To stop Claude Code from selecting a source:
273Features that need your claude.ai login, such as [claude.ai connectors](https://code.claude.com/docs/en/mcp.md#use-mcp-servers-from-claude-ai) and [`/schedule`](https://code.claude.com/docs/en/routines), aren't available while one of these sources is selected. To stop Claude Code from selecting a source:
274274 
275275* **Named profile or federation variables**: unset `ANTHROPIC_PROFILE`, or unset either federation variable
276276* **Active profile**: run `/logout` for a `user_oauth` profile whose current credential you wrote by [signing in to a Console account without an API key](#sign-in-without-an-api-key), run `ant auth logout` for one whose current credential `ant auth login` wrote, or delete the profile's file from `configs/` in your configuration directory for either auth mode
from line 303
303303set CLAUDE_CODE_OAUTH_TOKEN=your-token
304304```
305305 
306This token authenticates with your Claude subscription and requires a Pro, Max, Team, or Enterprise plan. It can only make model requests, so it can't establish [Remote Control](/docs/en/remote-control.md) sessions or fetch [claude.ai connectors](/docs/en/mcp.md#use-mcp-servers-from-claude-ai). MCP servers you configure locally still work.
306This token authenticates with your Claude subscription and requires a Pro, Max, Team, or Enterprise plan. It can only make model requests, so it can't establish [Remote Control](https://code.claude.com/docs/en/remote-control.md) sessions or fetch [claude.ai connectors](https://code.claude.com/docs/en/mcp.md#use-mcp-servers-from-claude-ai). MCP servers you configure locally still work.
307307 
308[Bare mode](/docs/en/headless.md#start-faster-with-bare-mode) does not read `CLAUDE_CODE_OAUTH_TOKEN`. If your script passes `--bare`, authenticate with `ANTHROPIC_API_KEY` or an `apiKeyHelper` instead.
308[Bare mode](https://code.claude.com/docs/en/headless.md#start-faster-with-bare-mode) does not read `CLAUDE_CODE_OAUTH_TOKEN`. If your script passes `--bare`, authenticate with `ANTHROPIC_API_KEY` or an `apiKeyHelper` instead.
309309 

auto-mode-classifier-billing Changed · +12 / -12 lines

from line 2
22 
33> Resolve the Claude Code notice saying this session isn't eligible for auto mode's no-charge classifier requests: what it means, why it appears, and what to do.
44 
5In [auto mode](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), a classifier checks actions such as shell commands and network requests before they run. Wherever [server-side checks are on](/docs/en/permission-modes.md#server-side-classifier-review), the server performs those checks as part of the session's own model requests, at no charge. This notice means the server's checks aren't reaching your session, so Claude Code is making its own classifier requests instead, and on your account those requests count toward your token usage:
5In [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), a classifier checks actions such as shell commands and network requests before they run. Wherever [server-side checks are on](https://code.claude.com/docs/en/permission-modes.md#server-side-classifier-review), the server performs those checks as part of the session's own model requests, at no charge. This notice means the server's checks aren't reaching your session, so Claude Code is making its own classifier requests instead, and on your account those requests count toward your token usage:
66 
77```text theme={null}
88We're changing auto mode to no longer charge for classifier requests in Claude Code. However, this session isn't eligible.
from line 21
2121 
2222To stop using auto mode instead, switch permission modes with `Shift+Tab` after you answer.
2323 
24Where the notice can't wait for an answer, Claude Code reports the same text and the session continues in auto mode, unless a gateway acknowledgment on this machine in the last 24 hours has dismissed it. In [non-interactive mode](/docs/en/headless.md) with `-p` it prints the text to stderr, and in `stream-json` output it emits a `system` warning message, which Agent SDK applications can read from the message stream.
24Where the notice can't wait for an answer, Claude Code reports the same text and the session continues in auto mode, unless a gateway acknowledgment on this machine in the last 24 hours has dismissed it. In [non-interactive mode](https://code.claude.com/docs/en/headless.md) with `-p` it prints the text to stderr, and in `stream-json` output it emits a `system` warning message, which Agent SDK applications can read from the message stream.
2525 
2626## Make the session eligible
2727 
28If a gateway is the cause, ask your company's admin or your gateway provider to pass requests and replies through unchanged. That means forwarding request headers and body fields as they are, including ones the gateway doesn't recognize such as the `safeguards` request field, and returning responses and streaming events without dropping keys such as the `safeguard_results` field or rewriting tool-use IDs, as the [gateway compatibility guide](/docs/en/llm-gateway-protocol.md#feature-pass-through) describes. A gateway that passes traffic through this way keeps working with this feature and with future ones. New sessions then use the server's checks again.
28If a gateway is the cause, ask your company's admin or your gateway provider to pass requests and replies through unchanged. That means forwarding request headers and body fields as they are, including ones the gateway doesn't recognize such as the `safeguards` request field, and returning responses and streaming events without dropping keys such as the `safeguard_results` field or rewriting tool-use IDs, as the [gateway compatibility guide](https://code.claude.com/docs/en/llm-gateway-protocol.md#feature-pass-through) describes. A gateway that passes traffic through this way keeps working with this feature and with future ones. New sessions then use the server's checks again.
2929 
30If you already know that your gateway can't provide the server's checks, tell Claude Code not to ask for them there by setting `CLAUDE_CODE_AUTO_MODE_SERVER` to `0` before you start the session, in your shell or in the [`env` settings key](/docs/en/settings-reference#env):
30If you already know that your gateway can't provide the server's checks, tell Claude Code not to ask for them there by setting `CLAUDE_CODE_AUTO_MODE_SERVER` to `0` before you start the session, in your shell or in the [`env` settings key](https://code.claude.com/docs/en/settings-reference#env):
3131 
3232```bash theme={null}
3333export CLAUDE_CODE_AUTO_MODE_SERVER=0
3434```
3535 
36Classifier requests are then always Claude Code's own, billed the same way, and the notice doesn't appear. On a direct connection to the Anthropic API, the variable requires Claude Code v2.1.281 or later. Setting `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1` while `CLAUDE_CODE_AUTO_MODE_SERVER` is unset turns the server's checks off as well, except as [Disable pre-release capabilities](/docs/en/llm-gateway-protocol.md#disable-pre-release-capabilities) describes.
36Classifier requests are then always Claude Code's own, billed the same way, and the notice doesn't appear. On a direct connection to the Anthropic API, the variable requires Claude Code v2.1.281 or later. Setting `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1` while `CLAUDE_CODE_AUTO_MODE_SERVER` is unset turns the server's checks off as well, except as [Disable pre-release capabilities](https://code.claude.com/docs/en/llm-gateway-protocol.md#disable-pre-release-capabilities) describes.
3737 
3838`CLAUDE_CODE_AUTO_MODE_SERVER` is a temporary setting and may be removed in a later release.
3939 
4040## Why the notice appears
4141 
42[Server-side classifier review](/docs/en/permission-modes.md#server-side-classifier-review) lists which sessions ask the server for the classifier checks. Pro, Max, and Team plans never show the notice. When it appears, the usual causes are:
42[Server-side classifier review](https://code.claude.com/docs/en/permission-modes.md#server-side-classifier-review) lists which sessions ask the server for the classifier checks. Pro, Max, and Team plans never show the notice. When it appears, the usual causes are:
4343 
4444* **An LLM gateway or proxy is in the path**: one that strips or rewrites request headers, drops request fields it doesn't recognize, or edits responses. The server then never receives the request for checks, or Claude Code never receives the results. When your configuration or the responses identify the gateway, the notice names it.
4545* **Server-side checks haven't reached your platform, region, or credential yet**: whether a platform or region performs them depends on that platform's rollout. If you see the notice with no gateway or proxy in the path and it keeps appearing, this is the likely cause. To confirm, contact support or your company's admin, or report it with `/feedback`.
from line 46
4646 
4747To check a session that's in auto mode, run `/status` at the Claude Code prompt: its **Auto mode server** row reads `Enabled` while the server's checks decide the session's actions and `Disabled` once the session has fallen back.
4848 
49When a gateway cuts responses short or rewrites the results into a form Claude Code can't read, you get denials with no verdict in place of this notice; see [Server-side classifier review](/docs/en/permission-modes.md#server-side-classifier-review).
49When a gateway cuts responses short or rewrites the results into a form Claude Code can't read, you get denials with no verdict in place of this notice; see [Server-side classifier review](https://code.claude.com/docs/en/permission-modes.md#server-side-classifier-review).
5050 
5151## Related resources
5252 
53* [Auto mode](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode): what auto mode is and what it blocks by default
54* [Server-side classifier review](/docs/en/permission-modes.md#server-side-classifier-review): which sessions ask the server to check actions, and the Claude Code version each one requires
55* [Gateway compatibility guide](/docs/en/llm-gateway-protocol.md#feature-pass-through): what breaks when a gateway strips headers or body fields
56* [The server returned no safety verdict](/docs/en/errors.md#the-server-returned-no-safety-verdict): the denial you see when the server gives no verdict for an action
57* [Manage costs effectively](/docs/en/costs.md): track token usage and reduce Claude Code costs
53* [Auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode): what auto mode is and what it blocks by default
54* [Server-side classifier review](https://code.claude.com/docs/en/permission-modes.md#server-side-classifier-review): which sessions ask the server to check actions, and the Claude Code version each one requires
55* [Gateway compatibility guide](https://code.claude.com/docs/en/llm-gateway-protocol.md#feature-pass-through): what breaks when a gateway strips headers or body fields
56* [The server returned no safety verdict](https://code.claude.com/docs/en/errors.md#the-server-returned-no-safety-verdict): the denial you see when the server gives no verdict for an action
57* [Manage costs effectively](https://code.claude.com/docs/en/costs.md): track token usage and reduce Claude Code costs
5858 

auto-mode-config Changed · +37 / -37 lines

from line 2
22 
33> Tell the auto mode classifier which repos, buckets, and domains your organization trusts. Set environment context, override the default block and allow rules, and inspect your effective config with the auto-mode CLI subcommands.
44 
5[Auto mode](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) lets Claude Code run without routine permission prompts by routing tool calls through a classifier that blocks anything irreversible, destructive, or aimed outside your environment. Deny and explicit ask rules are evaluated before the classifier and still block or prompt. Use the `autoMode` settings block to tell that classifier which repos, buckets, and domains your organization trusts, so it stops blocking routine internal operations.
5[Auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) lets Claude Code run without routine permission prompts by routing tool calls through a classifier that blocks anything irreversible, destructive, or aimed outside your environment. Deny and explicit ask rules are evaluated before the classifier and still block or prompt. Use the `autoMode` settings block to tell that classifier which repos, buckets, and domains your organization trusts, so it stops blocking routine internal operations.
66 
77> [!NOTE]
88>
99> This page is the configuration reference. Turning auto mode on and off is covered on the Permission modes page:
1010>
11> * **Switch to auto mode mid-session, or back out of it**: see [Switch permission modes](/docs/en/permission-modes.md#switch-permission-modes)
12> * **Start a session in auto mode**: see [Start in a different permission mode](/docs/en/permission-modes.md#start-in-a-different-mode)
11> * **Switch to auto mode mid-session, or back out of it**: see [Switch permission modes](https://code.claude.com/docs/en/permission-modes.md#switch-permission-modes)
12> * **Start a session in auto mode**: see [Start in a different permission mode](https://code.claude.com/docs/en/permission-modes.md#start-in-a-different-mode)
1313 
14Auto mode is available to all users on every provider, including the Anthropic API, [Claude Platform on AWS](/docs/en/claude-platform-on-aws.md), Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, and signed-in [Claude apps gateway](/docs/en/claude-apps-gateway) sessions. If Claude Code reports auto mode as unavailable for your account, check the [full requirements](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), which also cover the supported models and the organization-level control on Team and Enterprise plans.
14Auto mode is available to all users on every provider, including the Anthropic API, [Claude Platform on AWS](https://code.claude.com/docs/en/claude-platform-on-aws.md), Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, and signed-in [Claude apps gateway](https://code.claude.com/docs/en/claude-apps-gateway) sessions. If Claude Code reports auto mode as unavailable for your account, check the [full requirements](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), which also cover the supported models and the organization-level control on Team and Enterprise plans.
1515 
1616By default, the classifier trusts only the working directory and the current repo's configured remotes. Actions like pushing to your company's source-control org or writing to a team cloud bucket are blocked until you add them to `autoMode.environment`.
1717 
from line 30
3030 
3131### Add a human checkpoint
3232 
33The most direct mechanism is [`permissions.ask`](/docs/en/permissions#permission-rule-syntax). Content-scoped ask rules like the ones below are evaluated before the classifier and always force a permission prompt, even in auto mode, because an explicit ask rule is your stated intent to be prompted for that action. Add the rules in your [settings](/docs/en/settings.md#where-settings-live):
33The most direct mechanism is [`permissions.ask`](https://code.claude.com/docs/en/permissions#permission-rule-syntax). Content-scoped ask rules like the ones below are evaluated before the classifier and always force a permission prompt, even in auto mode, because an explicit ask rule is your stated intent to be prompted for that action. Add the rules in your [settings](https://code.claude.com/docs/en/settings.md#where-settings-live):
3434 
3535```json theme={null}
3636{
from line 43
4343}
4444```
4545 
46These rules match commands that begin with `git push` or `gh pr create`. A push Claude writes another way, such as `git -C <dir> push` or `git -c <key>=<value> push`, [doesn't match the rule](/docs/en/permissions.md#bash-rule-limits), so it isn't checkpointed. For a checkpoint that inspects the full command text, add a [PreToolUse hook](/docs/en/hooks.md#pretooluse).
46These rules match commands that begin with `git push` or `gh pr create`. A push Claude writes another way, such as `git -C <dir> push` or `git -c <key>=<value> push`, [doesn't match the rule](https://code.claude.com/docs/en/permissions.md#bash-rule-limits), so it isn't checkpointed. For a checkpoint that inspects the full command text, add a [PreToolUse hook](https://code.claude.com/docs/en/hooks.md#pretooluse).
4747 
4848Pick the mechanism that matches how firm the boundary needs to be:
4949 
from line 51
5151| :- | :- | :- |
5252| Prompt before the action | `permissions.ask` | Always prompts for a command that matches a content-scoped rule like the recipe above. The classifier cannot auto-approve a matching action. |
5353| Never run the action | `permissions.deny` | Blocks before the classifier is consulted. Neither the classifier nor user intent can override it. |
54| One-off boundary for this session | State it in conversation, like "don't push until I review" | The classifier blocks matching actions, but the boundary can be lost if [context compaction](/docs/en/costs.md#reduce-token-usage) removes the message that stated it. Use an ask or deny rule for a durable guarantee. |
54| One-off boundary for this session | State it in conversation, like "don't push until I review" | The classifier blocks matching actions, but the boundary can be lost if [context compaction](https://code.claude.com/docs/en/costs.md#reduce-token-usage) removes the message that stated it. Use an ask or deny rule for a durable guarantee. |
5555 
5656## Where the classifier reads configuration
5757 
58The classifier reads the same [CLAUDE.md](/docs/en/memory.md) content Claude itself loads, so an instruction like "never force push" in your project's CLAUDE.md steers both Claude and the classifier at the same time. Start there for project conventions and behavioral rules.
58The classifier reads the same [CLAUDE.md](https://code.claude.com/docs/en/memory.md) content Claude itself loads, so an instruction like "never force push" in your project's CLAUDE.md steers both Claude and the classifier at the same time. Start there for project conventions and behavioral rules.
5959 
6060For rules that apply across projects, such as trusted infrastructure or organization-wide deny rules, use the `autoMode` settings block. The classifier reads `autoMode` from the following scopes:
6161 
from line 62
6262| Scope | File | Use for |
6363| :- | :- | :- |
6464| One developer | `~/.claude/settings.json` | Personal trusted infrastructure |
65| Organization-wide | [Managed settings](/docs/en/server-managed-settings.md) | Trusted infrastructure distributed to all developers |
65| Organization-wide | [Managed settings](https://code.claude.com/docs/en/server-managed-settings.md) | Trusted infrastructure distributed to all developers |
6666| `--settings` flag or Agent SDK | Inline JSON | Per-invocation overrides for automation |
6767 
6868The classifier doesn't read `autoMode` from project settings in `.claude/settings.json` or `.claude/settings.local.json`. Both files live in the repo directory, so a checked-in repo or a build step could otherwise inject its own allow rules. Move any `autoMode` block in `.claude/settings.local.json` to `~/.claude/settings.json`.
from line 71
7171 
7272> [!NOTE]
7373>
74> The classifier is a second gate that runs after the [permissions system](/docs/en/permissions.md). For actions that must never run regardless of user intent or classifier configuration, use `permissions.deny` in managed settings, which blocks the action before the classifier is consulted and can't be overridden.
74> The classifier is a second gate that runs after the [permissions system](https://code.claude.com/docs/en/permissions.md). For actions that must never run regardless of user intent or classifier configuration, use `permissions.deny` in managed settings, which blocks the action before the classifier is consulted and can't be overridden.
7575 
7676## Define trusted infrastructure
7777 
from line 91
9191 * **Secrets management**
9292 * **CI/CD deploy targets**
9393 * **Network posture**
94 * **Host containment**: defaults to an ordinary developer machine or CI runner with open internet. If Claude Code runs in a container, VM, or pod with an egress allow-list or neighbors it must not touch, name the allowed hosts, whether the cloud metadata endpoint should be reachable, and which cloud project, cluster, or registry the task uses and under what identity. Until this entry names that identity, the classifier [blocks](/docs/en/permission-modes.md#what-the-classifier-blocks-by-default) requests for the host's own credentials. Requires Claude Code v2.1.257 or later
94 * **Host containment**: defaults to an ordinary developer machine or CI runner with open internet. If Claude Code runs in a container, VM, or pod with an egress allow-list or neighbors it must not touch, name the allowed hosts, whether the cloud metadata endpoint should be reachable, and which cloud project, cluster, or registry the task uses and under what identity. Until this entry names that identity, the classifier [blocks](https://code.claude.com/docs/en/permission-modes.md#what-the-classifier-blocks-by-default) requests for the host's own credentials. Requires Claude Code v2.1.257 or later
9595 * **Protected deployment namespaces / environments**: falls back to the Sensitive remote targets heuristic until you name them
9696 * **Data retention / declassification**
9797* **Trust slots**: name what the classifier treats as inside your boundary. The slots are Trusted repo, Source control, Trusted internal domains, Trusted cloud buckets, Key internal services, and Internal package registry. The repo and source-control entries default to the working repository and its configured remotes. Every other trust slot defaults to `None configured`, so nothing else is trusted until you add it. A repository's visibility scopes only confidential material: a private repository is an acceptable destination for confidential material, but making a repository private never clears secrets or personal or entrusted data into it, and the classifier treats content ported, repointed, or first read from outside the working repository as not that repository's own work.
from line 186
186186 
187187Once auto mode has blocked several actions and you still have no `autoMode.environment` entries, Claude Code shows a dialog titled "Teach auto mode about your environment?" at the end of a turn and offers to run `/auto-mode-setup` for you. To stop the offer but keep the command, select **Don't show again** in that dialog.
188188 
189To turn off both the command and the offer, add this [`skillOverrides`](/docs/en/skills#override-skill-visibility-from-settings) entry to `~/.claude/settings.json`:
189To turn off both the command and the offer, add this [`skillOverrides`](https://code.claude.com/docs/en/skills#override-skill-visibility-from-settings) entry to `~/.claude/settings.json`:
190190 
191191```json theme={null}
192192{
from line 196
196196}
197197```
198198 
199`/auto-mode-setup` is a built-in command rather than a [bundled skill](/docs/en/skills.md#bundled-skills), so this `skillOverrides` entry still applies to it, but [`disableBundledSkills`](/docs/en/settings-reference#disablebundledskills) doesn't turn it off.
199`/auto-mode-setup` is a built-in command rather than a [bundled skill](https://code.claude.com/docs/en/skills.md#bundled-skills), so this `skillOverrides` entry still applies to it, but [`disableBundledSkills`](https://code.claude.com/docs/en/settings-reference#disablebundledskills) doesn't turn it off.
200200 
201201### `/auto-mode-setup` returns "Unknown command"
202202 
203203If typing `/auto-mode-setup` at the Claude Code prompt prints `Unknown command: /auto-mode-setup`, check for these causes:
204204 
205* **First session after an install or upgrade**: start a new session. If the command is still missing there, see the [setups where later sessions also start without it](/docs/en/env-vars.md#first-session-after-an-install-or-upgrade).
206* **Outdated version**: run `claude --version` in your shell. If the version is below [the minimum for your plan](#generate-environment-entries), [update Claude Code](/docs/en/setup.md#update-claude-code).
207* **Telemetry off, third-party provider, or Claude apps gateway**: before v2.1.304, the command isn't available in [sessions where feature-flag fetching is off](/docs/en/env-vars.md#features-that-need-feature-flag-fetching). If your session is one of them, [update Claude Code](/docs/en/setup.md#update-claude-code) to v2.1.304 or later.
205* **First session after an install or upgrade**: start a new session. If the command is still missing there, see the [setups where later sessions also start without it](https://code.claude.com/docs/en/env-vars.md#first-session-after-an-install-or-upgrade).
206* **Outdated version**: run `claude --version` in your shell. If the version is below [the minimum for your plan](#generate-environment-entries), [update Claude Code](https://code.claude.com/docs/en/setup.md#update-claude-code).
207* **Telemetry off, third-party provider, or Claude apps gateway**: before v2.1.304, the command isn't available in [sessions where feature-flag fetching is off](https://code.claude.com/docs/en/env-vars.md#features-that-need-feature-flag-fetching). If your session is one of them, [update Claude Code](https://code.claude.com/docs/en/setup.md#update-claude-code) to v2.1.304 or later.
208208 
209In a [cloud session](/docs/en/claude-code-on-the-web.md), the command prints `/auto-mode-setup isn't available in this environment.` instead. Run it in an interactive session in your terminal.
209In a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), the command prints `/auto-mode-setup isn't available in this environment.` instead. Run it in an interactive session in your terminal.
210210 
211211## Override the block and allow rules
212212 
from line 216
216216* `autoMode.soft_deny`: destructive actions that user intent can clear
217217* `autoMode.allow`: exceptions to soft block rules
218218 
219Each is an array of prose descriptions, read as natural-language rules. For tool-pattern-based hard blocks that run before the classifier, use [`permissions.deny`](/docs/en/permissions).
219Each is an array of prose descriptions, read as natural-language rules. For tool-pattern-based hard blocks that run before the classifier, use [`permissions.deny`](https://code.claude.com/docs/en/permissions).
220220 
221221Inside the classifier, precedence works in four tiers:
222222 
from line 271
271271 
272272## Edit rules from `/permissions`
273273 
274To view and edit classifier rules and `environment` entries without opening a settings file, run [`/permissions`](/docs/en/permissions#manage-permissions) and select the **Auto mode** tab. The tab requires Claude Code v2.1.246 or later, and it appears only when [auto mode is available](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) to your session.
274To view and edit classifier rules and `environment` entries without opening a settings file, run [`/permissions`](https://code.claude.com/docs/en/permissions#manage-permissions) and select the **Auto mode** tab. The tab requires Claude Code v2.1.246 or later, and it appears only when [auto mode is available](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) to your session.
275275 
276Claude Code shows entries from [managed settings](/docs/en/server-managed-settings.md) or the `--settings` flag as read-only, and saves every change you make on the tab to `~/.claude/settings.json`.
276Claude Code shows entries from [managed settings](https://code.claude.com/docs/en/server-managed-settings.md) or the `--settings` flag as read-only, and saves every change you make on the tab to `~/.claude/settings.json`.
277277 
278278## Route all shell commands through the classifier
279279 
280By default, narrow Bash and PowerShell allow rules such as `Bash(npm test)` stay in effect in auto mode. Claude Code resolves them before the classifier runs, unless the command carries [per-command allowed domains](/docs/en/sandboxing.md#per-command-allowed-domains-in-auto-mode). Claude Code suspends only the broad rules that grant arbitrary code execution, such as `Bash(*)` or wildcarded interpreters, together with every rule that names [`Monitor`](/docs/en/tools-reference#monitor-tool), because Monitor commands run through the shell. This means a narrow rule can still let a destructive argument through without the classifier seeing it, for example a script path or flag the rule's prefix didn't anticipate.
280By default, narrow Bash and PowerShell allow rules such as `Bash(npm test)` stay in effect in auto mode. Claude Code resolves them before the classifier runs, unless the command carries [per-command allowed domains](https://code.claude.com/docs/en/sandboxing.md#per-command-allowed-domains-in-auto-mode). Claude Code suspends only the broad rules that grant arbitrary code execution, such as `Bash(*)` or wildcarded interpreters, together with every rule that names [`Monitor`](https://code.claude.com/docs/en/tools-reference#monitor-tool), because Monitor commands run through the shell. This means a narrow rule can still let a destructive argument through without the classifier seeing it, for example a script path or flag the rule's prefix didn't anticipate.
281281 
282Set `autoMode.classifyAllShell` to `true` to suspend every Bash and PowerShell allow rule while auto mode is active, so the classifier evaluates every shell command regardless of your allow list, except [critical-path removals](/docs/en/permission-modes.md#critical-paths).
282Set `autoMode.classifyAllShell` to `true` to suspend every Bash and PowerShell allow rule while auto mode is active, so the classifier evaluates every shell command regardless of your allow list, except [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths).
283283 
284284```json theme={null}
285285{
from line 347
347347claude auto-mode reset
348348```
349349 
350The command summarizes what it will remove and asks `Reset auto mode configuration to defaults?` before writing; pass `--yes` to skip the confirmation. Reset changes only `~/.claude/settings.json`: `autoMode` rules from [managed settings](/docs/en/server-managed-settings.md) or the `--settings` flag still apply.
350The command summarizes what it will remove and asks `Reset auto mode configuration to defaults?` before writing; pass `--yes` to skip the confirmation. Reset changes only `~/.claude/settings.json`: `autoMode` rules from [managed settings](https://code.claude.com/docs/en/server-managed-settings.md) or the `--settings` flag still apply.
351351 
352352## Review denials
353353 
354354To review and retry actions the auto mode classifier denied, open `/permissions` and select the **Recently denied** tab, where Claude Code records each denial. Press `r` on a denied action to mark it for retry: when you exit the dialog, Claude Code sends a message telling the model it may retry that tool call and resumes the conversation.
355355 
356When the classifier produces [no verdict on the action](/docs/en/errors.md#auto-mode-cannot-determine-the-safety-of-an-action), because a safety check separate from auto mode refused the classifier's own request or its response didn't parse, Claude Code denies the action without recording it under **Recently denied**. The linked error entry covers what Claude is told and how to run the action if you need it.
356When the classifier produces [no verdict on the action](https://code.claude.com/docs/en/errors.md#auto-mode-cannot-determine-the-safety-of-an-action), because a safety check separate from auto mode refused the classifier's own request or its response didn't parse, Claude Code denies the action without recording it under **Recently denied**. The linked error entry covers what Claude is told and how to run the action if you need it.
357357 
358358### Fix a denial with an allow rule, an environment entry, or a retry
359359 
360360To read the command or URL behind a notice such as `bash denied by auto mode · [Data Exfiltration] · /permissions`, use the **Recently denied** tab, a hook, or the conversation:
361361 
362* **Recently denied tab**: in the `/permissions` dialog, highlight a denied Bash or PowerShell action to read its command below the list. In [screen reader mode](/docs/en/accessibility.md), all the commands appear before the list instead.
363* **Hook**: to capture the exact input of denials programmatically, add a [`PermissionDenied` hook](/docs/en/hooks#permissiondenied), which receives it as `tool_input`.
364* **Conversation**: find the tool call. If the call appears shortened or folded into a summary line such as `Ran 3 shell commands`, press `Ctrl+O` to open the [transcript viewer](/docs/en/interactive-mode.md#transcript-viewer), which expands it.
362* **Recently denied tab**: in the `/permissions` dialog, highlight a denied Bash or PowerShell action to read its command below the list. In [screen reader mode](https://code.claude.com/docs/en/accessibility.md), all the commands appear before the list instead.
363* **Hook**: to capture the exact input of denials programmatically, add a [`PermissionDenied` hook](https://code.claude.com/docs/en/hooks#permissiondenied), which receives it as `tool_input`.
364* **Conversation**: find the tool call. If the call appears shortened or folded into a summary line such as `Ran 3 shell commands`, press `Ctrl+O` to open the [transcript viewer](https://code.claude.com/docs/en/interactive-mode.md#transcript-viewer), which expands it.
365365 
366The text beneath the call tells you whether there is anything to fix. A dim `Not run · auto mode's check had no usable answer` row, or text that reports a problem with the classifier itself, such as `Auto mode could not evaluate this action`, means Claude Code blocked the call without a verdict from the classifier. For a `Not run` row, press `Ctrl+O` to read the full message, then see [Auto mode cannot determine the safety of an action](/docs/en/errors.md#auto-mode-cannot-determine-the-safety-of-an-action) or [The server returned no safety verdict](/docs/en/errors.md#the-server-returned-no-safety-verdict) for what to do.
366The text beneath the call tells you whether there is anything to fix. A dim `Not run · auto mode's check had no usable answer` row, or text that reports a problem with the classifier itself, such as `Auto mode could not evaluate this action`, means Claude Code blocked the call without a verdict from the classifier. For a `Not run` row, press `Ctrl+O` to read the full message, then see [Auto mode cannot determine the safety of an action](https://code.claude.com/docs/en/errors.md#auto-mode-cannot-determine-the-safety-of-an-action) or [The server returned no safety verdict](https://code.claude.com/docs/en/errors.md#the-server-returned-no-safety-verdict) for what to do.
367367 
368368Otherwise, a line reading `Denied by auto mode classifier` with a reason such as `[Production Deploy]` or `Blocked by classifier` means the classifier judged the call unsafe, so pick the fix from what the call was trying to reach or do:
369369 
from line 381
381381 
382382## See also
383383 
384* [Permission modes](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode): what auto mode is, what it blocks by default, and which sessions start in it
385* [Managed settings](/docs/en/server-managed-settings.md): deploy `autoMode` configuration across your organization
386* [Permissions](/docs/en/permissions.md): allow, ask, and deny rules that apply before the classifier runs
387* [All settings](/docs/en/settings-reference.md#automode): every settings key, including `autoMode`
384* [Permission modes](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode): what auto mode is, what it blocks by default, and which sessions start in it
385* [Managed settings](https://code.claude.com/docs/en/server-managed-settings.md): deploy `autoMode` configuration across your organization
386* [Permissions](https://code.claude.com/docs/en/permissions.md): allow, ask, and deny rules that apply before the classifier runs
387* [All settings](https://code.claude.com/docs/en/settings-reference.md#automode): every settings key, including `autoMode`
388388 

best-practices Changed · +42 / -42 lines

from line 8
88 
99But this autonomy still comes with a learning curve. Claude works within certain constraints you need to understand.
1010 
11This guide covers patterns that have proven effective across Anthropic's internal teams and for engineers using Claude Code across various codebases, languages, and environments. For how the agentic loop works, see [How Claude Code works](/docs/en/how-claude-code-works.md).
11This guide covers patterns that have proven effective across Anthropic's internal teams and for engineers using Claude Code across various codebases, languages, and environments. For how the agentic loop works, see [How Claude Code works](https://code.claude.com/docs/en/how-claude-code-works.md).
1212 
1313***
1414 
from line 16
1616 
1717Claude's context window holds your entire conversation, including every message, every file Claude reads, and every command output. However, this can fill up fast. A single debugging session or codebase exploration might generate and consume tens of thousands of tokens.
1818 
19This matters since LLM performance degrades as context fills. When the context window is getting full, Claude may start "forgetting" earlier instructions or making more mistakes. The context window is the most important resource to manage. To see how a session fills up in practice, [watch an interactive walkthrough](/docs/en/context-window.md) of what loads at startup and what each file read costs. Track context usage continuously with a [custom status line](/docs/en/statusline.md), and see [Reduce token usage](/docs/en/costs.md#reduce-token-usage) for strategies on reducing token usage.
19This matters since LLM performance degrades as context fills. When the context window is getting full, Claude may start "forgetting" earlier instructions or making more mistakes. The context window is the most important resource to manage. To see how a session fills up in practice, [watch an interactive walkthrough](https://code.claude.com/docs/en/context-window.md) of what loads at startup and what each file read costs. Track context usage continuously with a [custom status line](https://code.claude.com/docs/en/statusline.md), and see [Reduce token usage](https://code.claude.com/docs/en/costs.md#reduce-token-usage) for strategies on reducing token usage.
2020 
2121***
2222 
from line 28
2828 
2929Claude stops when the work looks done. Without a check it can run, "looks done" is the only signal available, and you become the verification loop: every mistake waits for you to notice it. Give Claude something that produces a pass or fail, and the loop closes on its own. Claude does the work, runs the check, reads the result, and iterates until the check passes.
3030 
31The check is anything that returns a signal Claude can read in the conversation: a test suite, a build exit code, a linter, a script that diffs output against a fixture, or a [browser screenshot](/docs/en/chrome.md) compared against a design. Run [`/verify`](/docs/en/skills#run-and-verify-your-app) yourself after Claude's check passes to confirm the change against the running app.
31The check is anything that returns a signal Claude can read in the conversation: a test suite, a build exit code, a linter, a script that diffs output against a fixture, or a [browser screenshot](https://code.claude.com/docs/en/chrome.md) compared against a design. Run [`/verify`](https://code.claude.com/docs/en/skills#run-and-verify-your-app) yourself after Claude's check passes to confirm the change against the running app.
3232 
3333| Strategy | Before | After |
3434| - | - | - |
from line 39
3939Once the check exists, decide how hard it gates the stop:
4040 
4141* **In one prompt**: ask Claude to run the check and iterate in the same message, as in the table above.
42* **Across a session**: set the check as a [`/goal` condition](/docs/en/goal). A separate evaluator re-checks it after every turn and Claude keeps working until the goal resolves. If Claude stalls, Claude Code eventually stops the run with the goal still set — see [how /goal evaluation works](/docs/en/goal.md#how-evaluation-works).
43* **As a deterministic gate**: a [Stop hook](/docs/en/hooks.md#stop) runs your check as a script and blocks the turn from ending until it passes. [Stop input](/docs/en/hooks.md#stop-input) covers the cap on consecutive blocks.
44* **By a second opinion**: a [verification subagent](/docs/en/sub-agents.md) or a [dynamic workflow](/docs/en/workflows.md) that checks its own findings has a fresh model try to refute the result, so the agent doing the work isn't the one grading it.
42* **Across a session**: set the check as a [`/goal` condition](https://code.claude.com/docs/en/goal). A separate evaluator re-checks it after every turn and Claude keeps working until the goal resolves. If Claude stalls, Claude Code eventually stops the run with the goal still set — see [how /goal evaluation works](https://code.claude.com/docs/en/goal.md#how-evaluation-works).
43* **As a deterministic gate**: a [Stop hook](https://code.claude.com/docs/en/hooks.md#stop) runs your check as a script and blocks the turn from ending until it passes. [Stop input](https://code.claude.com/docs/en/hooks.md#stop-input) covers the cap on consecutive blocks.
44* **By a second opinion**: a [verification subagent](https://code.claude.com/docs/en/sub-agents.md) or a [dynamic workflow](https://code.claude.com/docs/en/workflows.md) that checks its own findings has a fresh model try to refute the result, so the agent doing the work isn't the one grading it.
4545 
4646Each step trades setup for attention. The prompt version works on any task today. The `/goal` and Stop hook versions are what let an unattended run finish correctly without you.
4747 
from line 55
5555>
5656> Separate research and planning from implementation to avoid solving the wrong problem.
5757 
58Letting Claude jump straight to coding can produce code that solves the wrong problem. Use [plan mode](/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) to separate exploration from execution.
58Letting Claude jump straight to coding can produce code that solves the wrong problem. Use [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) to separate exploration from execution.
5959 
6060The recommended workflow has four phases:
6161 
from line 139
139139 
140140## Configure your environment
141141 
142A few setup steps make Claude Code significantly more effective across all your sessions. For a full overview of extension features and when to use each one, see [Extend Claude Code](/docs/en/features-overview.md).
142A few setup steps make Claude Code significantly more effective across all your sessions. For a full overview of extension features and when to use each one, see [Extend Claude Code](https://code.claude.com/docs/en/features-overview.md).
143143 
144144### Write an effective CLAUDE.md
145145 
from line 161
161161- Prefer running single tests, and not the whole test suite, for performance
162162```
163163 
164Run `/context` to confirm Claude loaded the file. CLAUDE.md is loaded every session, so only include things that apply broadly. For domain knowledge or workflows that are only relevant sometimes, use [skills](/docs/en/skills.md) instead. Claude loads them on demand without bloating every conversation.
164Run `/context` to confirm Claude loaded the file. CLAUDE.md is loaded every session, so only include things that apply broadly. For domain knowledge or workflows that are only relevant sometimes, use [skills](https://code.claude.com/docs/en/skills.md) instead. Claude loads them on demand without bloating every conversation.
165165 
166166Keep it concise. For each line, ask: *"Would removing this cause Claude to make mistakes?"* If not, cut it. Bloated CLAUDE.md files cause Claude to ignore your actual instructions!
167167 
from line 175
175175| Developer environment quirks (required env vars) | File-by-file descriptions of the codebase |
176176| Common gotchas or behaviors that aren't self-evident | Self-evident practices like "write clean code" |
177177 
178If Claude keeps doing something you don't want despite having a rule against it, the file is probably too long and the rule is getting lost. If Claude asks you questions that are answered in CLAUDE.md, the phrasing might be ambiguous. Treat CLAUDE.md like code: review it when things go wrong, prune it regularly, and test changes by observing whether Claude's behavior actually shifts. For a checked-in CLAUDE.md, run [`/doctor`](/docs/en/commands#all-commands) and Claude proposes cuts for content it can derive from the codebase.
178If Claude keeps doing something you don't want despite having a rule against it, the file is probably too long and the rule is getting lost. If Claude asks you questions that are answered in CLAUDE.md, the phrasing might be ambiguous. Treat CLAUDE.md like code: review it when things go wrong, prune it regularly, and test changes by observing whether Claude's behavior actually shifts. For a checked-in CLAUDE.md, run [`/doctor`](https://code.claude.com/docs/en/commands#all-commands) and Claude proposes cuts for content it can derive from the codebase.
179179 
180180If Claude keeps skipping one instruction, add emphasis such as "IMPORTANT" to that line alone. If you emphasize many lines, none of them stands out. Check CLAUDE.md into git so your team can contribute. The file compounds in value over time.
181181 
182CLAUDE.md files can import additional files using `@path/to/import` syntax. For import rules and where CLAUDE.md files can live, see [CLAUDE.md files](/docs/en/memory.md#claude-md-files).
182CLAUDE.md files can import additional files using `@path/to/import` syntax. For import rules and where CLAUDE.md files can live, see [CLAUDE.md files](https://code.claude.com/docs/en/memory.md#claude-md-files).
183183 
184184### Configure permissions
185185 
from line 187
187187>
188188> To get fewer prompts without giving up control, pre-approve the tools you trust with `/permissions` and let sandboxed commands run without asking with `/sandbox`. Switch to Manual mode when you want to approve edits and commands yourself.
189189 
190With Claude Code v2.1.283 or later, auto mode is the [built-in starting permission mode](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) for interactive terminal and VS Code sessions: a separate classifier model reviews most actions instead of you and blocks only what looks risky, such as scope escalation, unknown infrastructure, or hostile-content-driven actions. On earlier versions, auto mode is the built-in starting permission mode only on Pro, Max, and Team plans.
190With Claude Code v2.1.283 or later, auto mode is the [built-in starting permission mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) for interactive terminal and VS Code sessions: a separate classifier model reviews most actions instead of you and blocks only what looks risky, such as scope escalation, unknown infrastructure, or hostile-content-driven actions. On earlier versions, auto mode is the built-in starting permission mode only on Pro, Max, and Team plans.
191191 
192192In Manual mode, Claude Code asks before actions that might modify your system: file writes, Bash commands, MCP tools. That's safe but tedious. After the tenth approval you're clicking through rather than reviewing. Two tools cut those interruptions in Manual mode and apply in auto mode as well:
193193 
from line 194
194194* **Permission allowlists**: permit specific tools you know are safe, like `npm run lint` or `git commit`
195195* **Sandboxing**: enable OS-level isolation that restricts filesystem and network access, allowing Claude to work more freely within defined boundaries
196196 
197Read more about [permission modes](/docs/en/permission-modes.md), [permission rules](/docs/en/permissions.md), and [sandboxing](/docs/en/sandboxing.md).
197Read more about [permission modes](https://code.claude.com/docs/en/permission-modes.md), [permission rules](https://code.claude.com/docs/en/permissions.md), and [sandboxing](https://code.claude.com/docs/en/sandboxing.md).
198198 
199199### Use CLI tools
200200 
from line 212
212212>
213213> Run `claude mcp add` with a server name and URL or command to connect external tools like Notion, Figma, or your database. For example: `claude mcp add --transport http notion https://mcp.notion.com/mcp`.
214214 
215With [MCP servers](/docs/en/mcp.md), you can ask Claude to implement features from issue trackers, query databases, analyze monitoring data, integrate designs from Figma, and automate workflows.
215With [MCP servers](https://code.claude.com/docs/en/mcp.md), you can ask Claude to implement features from issue trackers, query databases, analyze monitoring data, integrate designs from Figma, and automate workflows.
216216 
217217### Set up hooks
218218 
from line 220
220220>
221221> Use hooks for actions that must happen every time with zero exceptions.
222222 
223[Hooks](/docs/en/hooks-guide.md) run scripts automatically at specific points in Claude's workflow. Unlike CLAUDE.md instructions which are advisory, hooks are deterministic and guarantee the action happens.
223[Hooks](https://code.claude.com/docs/en/hooks-guide.md) run scripts automatically at specific points in Claude's workflow. Unlike CLAUDE.md instructions which are advisory, hooks are deterministic and guarantee the action happens.
224224 
225225Claude can write hooks for you. Try prompts like *"Write a hook that runs eslint after every file edit"* or *"Write a hook that blocks writes to the migrations folder."* Edit `.claude/settings.json` directly to configure hooks by hand, and run `/hooks` to browse what's configured.
226226 
from line 230
230230>
231231> Create `SKILL.md` files in `.claude/skills/` to give Claude domain knowledge and reusable workflows.
232232 
233[Skills](/docs/en/skills.md) extend Claude's knowledge with information specific to your project, team, or domain. Claude applies them automatically when relevant, or you can invoke them directly with `/skill-name`.
233[Skills](https://code.claude.com/docs/en/skills.md) extend Claude's knowledge with information specific to your project, team, or domain. Claude applies them automatically when relevant, or you can invoke them directly with `/skill-name`.
234234 
235235Create a skill by adding a directory with a `SKILL.md` to `.claude/skills/`:
236236 
from line 274
274274>
275275> Define specialized assistants in `.claude/agents/` that Claude can delegate to for isolated tasks.
276276 
277[Subagents](/docs/en/sub-agents.md) run in their own context with their own set of allowed tools. They're useful for tasks that read many files or need specialized focus without cluttering your main conversation.
277[Subagents](https://code.claude.com/docs/en/sub-agents.md) run in their own context with their own set of allowed tools. They're useful for tasks that read many files or need specialized focus without cluttering your main conversation.
278278 
279279```markdown .claude/agents/security-reviewer.md theme={null}
280280---
from line 300
300300>
301301> Run `/plugin` to browse the marketplace. Plugins add skills, tools, and integrations without configuration.
302302 
303[Plugins](/docs/en/plugins/overview.md) bundle skills, hooks, subagents, and MCP servers into a single installable unit from the community and Anthropic. If you work with a typed language, install a [code intelligence plugin](/docs/en/plugins/code-intelligence.md) to give Claude precise symbol navigation and automatic error detection after edits.
303[Plugins](https://code.claude.com/docs/en/plugins/overview.md) bundle skills, hooks, subagents, and MCP servers into a single installable unit from the community and Anthropic. If you work with a typed language, install a [code intelligence plugin](https://code.claude.com/docs/en/plugins/code-intelligence.md) to give Claude precise symbol navigation and automatic error detection after edits.
304304 
305For guidance on choosing between skills, subagents, hooks, and MCP, see [Extend Claude Code](/docs/en/features-overview.md#match-features-to-your-goal).
305For guidance on choosing between skills, subagents, hooks, and MCP, see [Extend Claude Code](https://code.claude.com/docs/en/features-overview.md#match-features-to-your-goal).
306306 
307307***
308308 
from line 380
380380* Use `/clear` frequently between tasks to reset the context window entirely
381381* When auto compaction triggers, Claude summarizes what matters most, including code patterns, file states, and key decisions
382382* For more control, run `/compact <instructions>`, like `/compact Focus on the API changes`
383* To compact only part of the conversation, use `Esc + Esc` or `/rewind`, select a message checkpoint, and choose **Summarize from here** or **Summarize up to here**. The first condenses messages from that point forward while keeping earlier context intact; the second condenses earlier messages while keeping recent ones in full. See [the rewind menu's summarize options](/docs/en/checkpointing.md#rewind-and-summarize).
383* To compact only part of the conversation, use `Esc + Esc` or `/rewind`, select a message checkpoint, and choose **Summarize from here** or **Summarize up to here**. The first condenses messages from that point forward while keeping earlier context intact; the second condenses earlier messages while keeping recent ones in full. See [the rewind menu's summarize options](https://code.claude.com/docs/en/checkpointing.md#rewind-and-summarize).
384384* Customize compaction behavior in CLAUDE.md with instructions like `"When compacting, always preserve the full list of modified files and any test commands"` to ensure critical context survives summarization
385* For questions that don't need to stay in context, use [`/btw`](/docs/en/interactive-mode#side-questions-with-%2Fbtw). The answer never enters conversation history, so you can check a detail without growing context.
385* For questions that don't need to stay in context, use [`/btw`](https://code.claude.com/docs/en/interactive-mode#side-questions-with-%2Fbtw). The answer never enters conversation history, so you can check a detail without growing context.
386386 
387387### Use subagents for investigation
388388 
from line 405
405405>
406406> Every prompt you send that starts a turn creates a checkpoint. You can restore conversation, code, or both to any previous checkpoint.
407407 
408Claude automatically snapshots files before each change so a checkpoint can restore them. Double-tap `Escape` or run `/rewind` to open the rewind menu. You can restore conversation only, restore code only, restore both, or summarize from a selected message. See [Checkpointing](/docs/en/checkpointing.md) for details.
408Claude automatically snapshots files before each change so a checkpoint can restore them. Double-tap `Escape` or run `/rewind` to open the rewind menu. You can restore conversation only, restore code only, restore both, or summarize from a selected message. See [Checkpointing](https://code.claude.com/docs/en/checkpointing.md) for details.
409409 
410410Instead of carefully planning every move, you can tell Claude to try something risky. If it doesn't work, rewind and try a different approach. Checkpoints are saved with the conversation, so you can close your terminal, resume the session later, and still rewind.
411411 
from line 419
419419>
420420> Name sessions with `/rename` and treat them like branches: each workstream gets its own persistent context.
421421 
422Claude Code saves conversations locally, so when a task spans multiple sittings you don't have to re-explain the context. Run [`claude --continue`](/docs/en/sessions#resume-a-session) to pick up where you left off, or `claude --resume` to choose from a list. Give sessions descriptive names like `oauth-migration` so you can find them later. See [Manage sessions](/docs/en/sessions.md) for the full set of resume, branch, and naming controls.
422Claude Code saves conversations locally, so when a task spans multiple sittings you don't have to re-explain the context. Run [`claude --continue`](https://code.claude.com/docs/en/sessions#resume-a-session) to pick up where you left off, or `claude --resume` to choose from a list. Give sessions descriptive names like `oauth-migration` so you can find them later. See [Manage sessions](https://code.claude.com/docs/en/sessions.md) for the full set of resume, branch, and naming controls.
423423 
424424***
425425 
from line 433
433433>
434434> Use `claude -p "prompt"` in CI, pre-commit hooks, or scripts. Add `--output-format stream-json --verbose` for streaming JSON output.
435435 
436With `claude -p "your prompt"`, you can run Claude non-interactively, without an interactive prompt. The run still creates a resumable session unless you pass `--no-session-persistence`. [Non-interactive mode](/docs/en/headless.md) is how you integrate Claude into CI pipelines, pre-commit hooks, or any automated workflow. The output formats let you parse results programmatically: plain text, JSON, or streaming JSON.
436With `claude -p "your prompt"`, you can run Claude non-interactively, without an interactive prompt. The run still creates a resumable session unless you pass `--no-session-persistence`. [Non-interactive mode](https://code.claude.com/docs/en/headless.md) is how you integrate Claude into CI pipelines, pre-commit hooks, or any automated workflow. The output formats let you parse results programmatically: plain text, JSON, or streaming JSON.
437437 
438438```bash theme={null}
439439# One-off queries
from line 456
456456 
457457Pick the parallel approach that fits how much coordination you want to do yourself, and add messaging when the sessions need to pass findings between them:
458458 
459* [Worktrees](/docs/en/worktrees.md): run separate CLI sessions in isolated git checkouts so edits don't collide
460* [Cross-session messaging](/docs/en/cross-session-messaging.md): let the sessions you run yourself pass findings to each other
461* [Desktop app](/docs/en/desktop.md#work-in-parallel-with-sessions): manage multiple local sessions visually, optionally each in its own worktree
462* [Use Claude Code in the cloud](/docs/en/claude-code-on-the-web.md): run sessions on Anthropic-managed infrastructure by default
463* [Agent view](/docs/en/agent-view.md): research preview. Run `claude agents` to dispatch sessions that keep running in the background and watch them from one screen
464* [Agent teams](/docs/en/agent-teams.md): experimental and disabled by default. Automated coordination of multiple sessions with shared tasks, messaging, and a team lead
459* [Worktrees](https://code.claude.com/docs/en/worktrees.md): run separate CLI sessions in isolated git checkouts so edits don't collide
460* [Cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md): let the sessions you run yourself pass findings to each other
461* [Desktop app](https://code.claude.com/docs/en/desktop.md#work-in-parallel-with-sessions): manage multiple local sessions visually, optionally each in its own worktree
462* [Use Claude Code in the cloud](https://code.claude.com/docs/en/claude-code-on-the-web.md): run sessions on Anthropic-managed infrastructure by default
463* [Agent view](https://code.claude.com/docs/en/agent-view.md): research preview. Run `claude agents` to dispatch sessions that keep running in the background and watch them from one screen
464* [Agent teams](https://code.claude.com/docs/en/agent-teams.md): experimental and disabled by default. Automated coordination of multiple sessions with shared tasks, messaging, and a team lead
465465 
466466Beyond parallelizing work, multiple sessions enable quality-focused workflows. A fresh context improves code review since Claude won't be biased toward code it just wrote.
467467 
from line 481
481481>
482482> Loop through tasks calling `claude -p` for each. Use `--allowedTools` to pre-approve tools for batch operations.
483483 
484For large migrations or analyses, you can distribute work across many parallel Claude invocations. Run [`/batch <instruction>`](/docs/en/commands#all-commands) to have Claude split the change across 5 to 30 subagents. Each subagent works in its own worktree. To drive the fan-out from your own script instead, loop over `claude -p`:
484For large migrations or analyses, you can distribute work across many parallel Claude invocations. Run [`/batch <instruction>`](https://code.claude.com/docs/en/commands#all-commands) to have Claude split the change across 5 to 30 subagents. Each subagent works in its own worktree. To drive the fan-out from your own script instead, loop over `claude -p`:
485485 
486486**1. Generate a task list**
487487 
from line 499
499499 
500500**3. Test on a few files, then run on all of them**
501501 
502Refine your prompt based on what goes wrong with the first 2-3 files, then run on the full set. The `--allowedTools` flag pre-approves the tools the migration needs. [`--permission-mode dontAsk`](/docs/en/permission-modes#allow-only-pre-approved-tools-with-dontask-mode) denies anything else that would need approval, which matters when you're running unattended, though a [mod](/docs/en/plugins/mods/overview.md) you installed can still approve some of those calls.
502Refine your prompt based on what goes wrong with the first 2-3 files, then run on the full set. The `--allowedTools` flag pre-approves the tools the migration needs. [`--permission-mode dontAsk`](https://code.claude.com/docs/en/permission-modes#allow-only-pre-approved-tools-with-dontask-mode) denies anything else that would need approval, which matters when you're running unattended, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve some of those calls.
503503 
504504You can also integrate Claude into existing data/processing pipelines:
505505 
from line 509
509509 
510510### Run autonomously with auto mode
511511 
512For uninterrupted execution with background safety checks, use [auto mode](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode). A classifier model reviews commands before they run, blocking scope escalation, unknown infrastructure, and hostile-content-driven actions while letting routine work proceed without prompts.
512For uninterrupted execution with background safety checks, use [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode). A classifier model reviews commands before they run, blocking scope escalation, unknown infrastructure, and hostile-content-driven actions while letting routine work proceed without prompts.
513513 
514514```bash theme={null}
515515claude --permission-mode auto -p "fix all lint errors"
516516```
517517 
518When the classifier repeatedly blocks actions in a non-interactive run with the `-p` flag, Claude Code doesn't stop the run. See [when auto mode falls back](/docs/en/permission-modes.md#when-auto-mode-falls-back) for what happens instead and for the thresholds.
518When the classifier repeatedly blocks actions in a non-interactive run with the `-p` flag, Claude Code doesn't stop the run. See [when auto mode falls back](https://code.claude.com/docs/en/permission-modes.md#when-auto-mode-falls-back) for what happens instead and for the thresholds.
519519 
520520### Add an adversarial review step
521521 
from line 523
523523>
524524> Before treating a task as done, have a subagent review the diff in a fresh context and report gaps.
525525 
526The longer Claude works unattended, the more an independent check matters before you count the work as done. A reviewer running in a fresh [subagent](/docs/en/sub-agents.md) context sees only the diff and the criteria you give it, not the reasoning that produced the change, so it evaluates the result on its own terms.
526The longer Claude works unattended, the more an independent check matters before you count the work as done. A reviewer running in a fresh [subagent](https://code.claude.com/docs/en/sub-agents.md) context sees only the diff and the criteria you give it, not the reasoning that produced the change, so it evaluates the result on its own terms.
527527 
528For a correctness check, run the bundled [`/code-review` skill](/docs/en/commands), which reviews the current diff for bugs in a fresh subagent and returns findings to the session. To check the diff against your plan instead, write the review prompt yourself. Name the work to check, the plan to check it against, and what counts as a finding:
528For a correctness check, run the bundled [`/code-review` skill](https://code.claude.com/docs/en/commands), which reviews the current diff for bugs in a fresh subagent and returns findings to the session. To check the diff against your plan instead, write the review prompt yourself. Name the work to check, the plan to check it against, and what counts as a finding:
529529 
530530```text wrap theme={null}
531531Use a subagent to review the rate limiter diff against PLAN.md. Check that
from line 568
568568 
569569## Related resources
570570 
571* [How Claude Code works](/docs/en/how-claude-code-works.md): the agentic loop, tools, and context management
572* [Extend Claude Code](/docs/en/features-overview.md): skills, hooks, MCP, subagents, and plugins
573* [Common workflows](/docs/en/common-workflows.md): step-by-step recipes for debugging, testing, PRs, and more
574* [CLAUDE.md](/docs/en/memory.md): store project conventions and persistent context
571* [How Claude Code works](https://code.claude.com/docs/en/how-claude-code-works.md): the agentic loop, tools, and context management
572* [Extend Claude Code](https://code.claude.com/docs/en/features-overview.md): skills, hooks, MCP, subagents, and plugins
573* [Common workflows](https://code.claude.com/docs/en/common-workflows.md): step-by-step recipes for debugging, testing, PRs, and more
574* [CLAUDE.md](https://code.claude.com/docs/en/memory.md): store project conventions and persistent context
575575 

champion-kit Changed · +14 / -14 lines

from line 25
2525| Posting wins and prompts | About 15 minutes | Capture these in the moment with a screenshot and one or two sentences; avoid turning them into formal write-ups. |
2626| Answering questions in a shared channel | About 20 minutes | Answer publicly once, then link back to that answer when the question recurs. |
2727| Hosting a weekly show-and-tell thread | About 5 minutes | You post the opening prompt; the team supplies the content. |
28| Optional pairing or walkthroughs | 0 to 30 minutes | Reserve this for colleagues who are blocked, and offer the [Quickstart](/docs/en/quickstart.md) link before scheduling time. |
28| Optional pairing or walkthroughs | 0 to 30 minutes | Reserve this for colleagues who are blocked, and offer the [Quickstart](https://code.claude.com/docs/en/quickstart.md) link before scheduling time. |
2929 
3030## Share what you discover
3131 
from line 101
101101 
102102| Question | Suggested response | Follow-up resource |
103103| - | - | - |
104| "What should I try it on first?" | Recommend a real but contained task, ideally a bug or chore the person has been postponing because it is tedious rather than difficult. | [Common workflows](/docs/en/common-workflows.md) |
105| "How do I trust it with my code?" | Introduce plan mode: pressing `Shift+Tab` cycles into it, and Claude researches and proposes changes without editing your source. | [Permissions](/docs/en/permissions.md) |
106| "Is the setup worth the effort?" | Installation takes roughly two minutes, runs in the terminal, and requires no IDE extension. Running `/init` once is sufficient to begin working. | [Quickstart](/docs/en/quickstart.md) |
107| "It produced an incorrect result." | Encourage them to provide the failure back to Claude. Pasting the error message or failing test is far more effective than rephrasing the original request. | [Common workflows](/docs/en/common-workflows.md) |
108| "It does not understand our codebase conventions." | Suggest running `/init` to generate a `CLAUDE.md` file, then adding the team's conventions, test commands, and any directories that should be avoided. | [Memory](/docs/en/memory.md) |
104| "What should I try it on first?" | Recommend a real but contained task, ideally a bug or chore the person has been postponing because it is tedious rather than difficult. | [Common workflows](https://code.claude.com/docs/en/common-workflows.md) |
105| "How do I trust it with my code?" | Introduce plan mode: pressing `Shift+Tab` cycles into it, and Claude researches and proposes changes without editing your source. | [Permissions](https://code.claude.com/docs/en/permissions.md) |
106| "Is the setup worth the effort?" | Installation takes roughly two minutes, runs in the terminal, and requires no IDE extension. Running `/init` once is sufficient to begin working. | [Quickstart](https://code.claude.com/docs/en/quickstart.md) |
107| "It produced an incorrect result." | Encourage them to provide the failure back to Claude. Pasting the error message or failing test is far more effective than rephrasing the original request. | [Common workflows](https://code.claude.com/docs/en/common-workflows.md) |
108| "It does not understand our codebase conventions." | Suggest running `/init` to generate a `CLAUDE.md` file, then adding the team's conventions, test commands, and any directories that should be avoided. | [Memory](https://code.claude.com/docs/en/memory.md) |
109109| "Is this just autocomplete?" | Offer a brief demonstration in which Claude explains an unfamiliar file, traces a bug across services, or drafts a migration plan. These tasks require reasoning across the repository rather than completing a single line. | A two-minute live demonstration |
110| "What about security and data handling?" | Refer this question to your administrator. Your organization's deployment and data-handling policy is already configured, and champions should not improvise this answer. | [Security](/docs/en/security.md) · [Data usage](/docs/en/data-usage.md) |
110| "What about security and data handling?" | Refer this question to your administrator. Your organization's deployment and data-handling policy is already configured, and champions should not improvise this answer. | [Security](https://code.claude.com/docs/en/security.md) · [Data usage](https://code.claude.com/docs/en/data-usage.md) |
111111 
112112## Grow the circle
113113 
from line 117
117117 
118118| Pattern | How to run it | Effort required |
119119| - | - | - |
120| A dedicated channel | Create a `#claude-code` channel (or a recurring thread in an existing one), pin the [Quickstart](/docs/en/quickstart.md) link and one strong example, and answer questions publicly so each answer benefits everyone watching. | About five minutes to set up, then ambient |
120| A dedicated channel | Create a `#claude-code` channel (or a recurring thread in an existing one), pin the [Quickstart](https://code.claude.com/docs/en/quickstart.md) link and one strong example, and answer questions publicly so each answer benefits everyone watching. | About five minutes to set up, then ambient |
121121| A weekly show-and-tell thread | Each Friday, post "What did Claude help you with this week?" No preparation, slides, or meeting are required; screenshots and short descriptions are sufficient. | About two minutes per week |
122122| Share a custom skill | Post your most useful `.claude/skills/<name>/SKILL.md` file, for example a `/ship` skill that runs tests and lint before committing, with a one-line description. Because skills are plain Markdown, colleagues can adopt them immediately. | About five minutes per skill |
123123| Generate a setup guide from your own usage | Run `/team-onboarding` in a project you have spent real time in. Claude scans your recent sessions, commands, and MCP servers, then produces a guide a new teammate can paste as their first message to replay your setup. Pin it in the channel. | About two minutes |
from line 130
130130 
131131**1. Week 1: Seed the channel**
132132 
133Create the channel, pin the [Quickstart](/docs/en/quickstart.md), and post two or three of your own examples with the prompts included.
133Create the channel, pin the [Quickstart](https://code.claude.com/docs/en/quickstart.md), and post two or three of your own examples with the prompts included.
134134 
135135**Signal that it is working:** a few colleagues react or reply, and at least one question is asked in the channel.
136136 
from line 154
154154 
155155### When someone wants to go deeper
156156 
157You are the warm introduction rather than the onboarding program. When a colleague moves past "should I try this" into "how do I become effective with it," point them to the [Quickstart](/docs/en/quickstart.md) and [Common workflows](/docs/en/common-workflows.md) pages. They contain short sections covering the features that are useful but difficult to discover on your own.
157You are the warm introduction rather than the onboarding program. When a colleague moves past "should I try this" into "how do I become effective with it," point them to the [Quickstart](https://code.claude.com/docs/en/quickstart.md) and [Common workflows](https://code.claude.com/docs/en/common-workflows.md) pages. They contain short sections covering the features that are useful but difficult to discover on your own.
158158 
159159## Respond to common concerns
160160 
from line 176
176176| - | - |
177177| Provide the right context | Use `@file` or `@directory/` references, or paste the error or log output directly. Supplying relevant context is more effective than elaborate prompting. |
178178| Review the plan before the edit | Press `Shift+Tab` to enter plan mode. Claude researches and proposes changes without editing your source. |
179| Teach it your repository | Run `/init` to generate a `CLAUDE.md` file, then add your conventions, test commands, and any directories that should not be modified. See [Memory](/docs/en/memory.md). |
180| Reuse a workflow | Save a `SKILL.md` file in `.claude/skills/<name>/` to create a `/name` skill that the entire team can use. See [Skills](/docs/en/skills.md). |
181| Stay informed during long tasks | Configure a Stop hook to receive a desktop notification when a long-running task completes. See [Hooks](/docs/en/hooks-guide.md). |
179| Teach it your repository | Run `/init` to generate a `CLAUDE.md` file, then add your conventions, test commands, and any directories that should not be modified. See [Memory](https://code.claude.com/docs/en/memory.md). |
180| Reuse a workflow | Save a `SKILL.md` file in `.claude/skills/<name>/` to create a `/name` skill that the entire team can use. See [Skills](https://code.claude.com/docs/en/skills.md). |
181| Stay informed during long tasks | Configure a Stop hook to receive a desktop notification when a long-running task completes. See [Hooks](https://code.claude.com/docs/en/hooks-guide.md). |
182182| Recover from an incorrect result | Rather than rephrasing the request, paste the failing test or stack trace back to Claude and ask it to address that specific failure. |
183183| Keep edits surgical | Ask for a diff, or specify "only change X." Claude respects scope when scope is stated. |
184184 
185185> [!TIP]
186186>
187> Claude Code is updated frequently. Verify version-specific details against the [documentation home page](/docs/en/overview.md) before distributing this material internally.
187> Claude Code is updated frequently. Verify version-specific details against the [documentation home page](https://code.claude.com/docs/en/overview.md) before distributing this material internally.
188188 

channels Changed · +23 / -23 lines

from line 14
1414 
1515When Claude replies through a channel, you see the inbound message in your terminal but not the reply text. The terminal shows the tool call and a confirmation (like "sent"), and the actual reply appears on the other platform.
1616 
17If you manage a Team, Enterprise, or Console organization, see [Enable channels for your organization](#enterprise-controls). To build your own channel, see the [Channels reference](/docs/en/channels-reference.md).
17If you manage a Team, Enterprise, or Console organization, see [Enable channels for your organization](#enterprise-controls). To build your own channel, see the [Channels reference](https://code.claude.com/docs/en/channels-reference.md).
1818 
1919## Supported channels
2020 
from line 39
3939If the install fails, match the message Claude Code reports:
4040 
4141* `Marketplace "claude-plugins-official" not found`: add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`, then retry the install.
42* `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](/docs/en/plugins/troubleshooting.md#plugin-not-found-in-marketplace).
42* `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](https://code.claude.com/docs/en/plugins/troubleshooting.md#plugin-not-found-in-marketplace).
4343 
44When the install asks for an installation scope, choose the user scope option so the plugin is available across all your projects. Check the install summary: if it reports `Run /reload-plugins to apply.`, see [Apply plugin changes without restarting](/docs/en/plugins/cli-reference.md#reload-plugins) to make the plugin's configure command available.
44When the install asks for an installation scope, choose the user scope option so the plugin is available across all your projects. Check the install summary: if it reports `Run /reload-plugins to apply.`, see [Apply plugin changes without restarting](https://code.claude.com/docs/en/plugins/cli-reference.md#reload-plugins) to make the plugin's configure command available.
4545 
4646**3. Configure your token**
4747 
from line 117
117117If the install fails, match the message Claude Code reports:
118118 
119119* `Marketplace "claude-plugins-official" not found`: add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`, then retry the install.
120* `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](/docs/en/plugins/troubleshooting.md#plugin-not-found-in-marketplace).
120* `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](https://code.claude.com/docs/en/plugins/troubleshooting.md#plugin-not-found-in-marketplace).
121121 
122When the install asks for an installation scope, choose the user scope option so the plugin is available across all your projects. Check the install summary: if it reports `Run /reload-plugins to apply.`, see [Apply plugin changes without restarting](/docs/en/plugins/cli-reference.md#reload-plugins) to make the plugin's configure command available.
122When the install asks for an installation scope, choose the user scope option so the plugin is available across all your projects. Check the install summary: if it reports `Run /reload-plugins to apply.`, see [Apply plugin changes without restarting](https://code.claude.com/docs/en/plugins/cli-reference.md#reload-plugins) to make the plugin's configure command available.
123123 
124124**5. Configure your token**
125125 
from line 182
182182If the install fails, match the message Claude Code reports:
183183 
184184* `Marketplace "claude-plugins-official" not found`: add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`, then retry the install.
185* `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](/docs/en/plugins/troubleshooting.md#plugin-not-found-in-marketplace).
185* `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](https://code.claude.com/docs/en/plugins/troubleshooting.md#plugin-not-found-in-marketplace).
186186 
187187When the install asks for an installation scope, choose the user scope option so the plugin is available across all your projects.
188188 
from line 222
222222 
223223To try the fakechat demo, you'll need:
224224 
225* Claude Code [installed and authenticated](/docs/en/quickstart.md#step-1-install-claude-code) with a claude.ai account or a Claude Console API key
225* Claude Code [installed and authenticated](https://code.claude.com/docs/en/quickstart.md#step-1-install-claude-code) with a claude.ai account or a Claude Console API key
226226* [Bun](https://bun.sh) installed. The pre-built channel plugins are Bun scripts. Check with `bun --version`; if that fails, [install Bun](https://bun.sh/docs/installation).
227227* **Team, Enterprise, or managed Console org**: your admin must [enable channels](#enterprise-controls) in managed settings
228228 
from line 237
237237If the install fails, match the message Claude Code reports:
238238 
239239* `Marketplace "claude-plugins-official" not found`: add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`, then retry the install.
240* `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](/docs/en/plugins/troubleshooting.md#plugin-not-found-in-marketplace).
240* `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](https://code.claude.com/docs/en/plugins/troubleshooting.md#plugin-not-found-in-marketplace).
241241 
242242When the install asks for an installation scope, choose the user scope option so the plugin is available across all your projects.
243243 
from line 267
267267 
268268The message arrives in your Claude Code session. The terminal shows it as an inbound channel line like `← fakechat · web: what's in my working directory?`, while the model receives it as a `<channel source="plugin:fakechat:fakechat">` event, using the plugin's scoped server name. Claude reads it, does the work, and calls fakechat's `reply` tool. If Claude Code asks for permission for the first reply, approve it. The answer shows up in the chat UI.
269269 
270If Claude hits a permission prompt while you're away from the terminal, the session pauses until you respond. Channel servers that declare the [permission relay capability](/docs/en/channels-reference.md#relay-permission-prompts) can forward these prompts to you so you can approve or deny remotely. For unattended use, [`--dangerously-skip-permissions`](/docs/en/permission-modes#skip-all-checks-with-bypasspermissions-mode) bypasses most prompts, but only use it in environments you trust. Even then, the [actions no mode auto-approves](/docs/en/permission-modes.md#actions-no-mode-auto-approves) still apply.
270If Claude hits a permission prompt while you're away from the terminal, the session pauses until you respond. Channel servers that declare the [permission relay capability](https://code.claude.com/docs/en/channels-reference.md#relay-permission-prompts) can forward these prompts to you so you can approve or deny remotely. For unattended use, [`--dangerously-skip-permissions`](https://code.claude.com/docs/en/permission-modes#skip-all-checks-with-bypasspermissions-mode) bypasses most prompts, but only use it in environments you trust. Even then, the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) still apply.
271271 
272272When you run channels in non-interactive mode with `-p`, tools that need terminal input, such as multiple-choice questions and plan mode approval, are disabled so the session never stalls waiting for input.
273273 
from line 288
288288 
289289Being in `.mcp.json` isn't enough to push messages: a server also has to be named in `--channels`.
290290 
291The allowlist also gates [permission relay](/docs/en/channels-reference.md#relay-permission-prompts) if the channel declares it. Anyone who can reply through the channel can approve or deny tool use in your session, so only allowlist senders you trust with that authority.
291The allowlist also gates [permission relay](https://code.claude.com/docs/en/channels-reference.md#relay-permission-prompts) if the channel declares it. Anyone who can reply through the channel can approve or deny tool use in your session, so only allowlist senders you trust with that authority.
292292 
293293## Enterprise controls
294294 
295Admins control availability through two [managed settings](/docs/en/settings.md) that users cannot override. The default depends on how you authenticate:
295Admins control availability through two [managed settings](https://code.claude.com/docs/en/settings.md) that users cannot override. The default depends on how you authenticate:
296296 
297297* **claude.ai Team and Enterprise**: channels are blocked until an Owner [enables them](#enable-channels-for-your-organization).
298298* **Anthropic Console with API key authentication**: channels are permitted by default. You only need this setting if your organization deploys managed settings.
from line 329
329329 
330330If you set an empty array, you block all channel plugins from the allowlist, but `--dangerously-load-development-channels` can still bypass that block for local testing. To block channels entirely including the development flag, leave `channelsEnabled` unset instead.
331331 
332This setting requires `channelsEnabled: true`. If a user passes a plugin to `--channels` that isn't on your list, Claude Code starts normally but the channel doesn't register, and the startup notice explains that the plugin isn't on the organization's approved list. On the v2 MCP client runtime, a channel can also fail to register because Claude Code [doesn't register a channel server that negotiates protocol revision 2026-07-28](/docs/en/mcp.md#push-messages-with-channels).
332This setting requires `channelsEnabled: true`. If a user passes a plugin to `--channels` that isn't on your list, Claude Code starts normally but the channel doesn't register, and the startup notice explains that the plugin isn't on the organization's approved list. On the v2 MCP client runtime, a channel can also fail to register because Claude Code [doesn't register a channel server that negotiates protocol revision 2026-07-28](https://code.claude.com/docs/en/mcp.md#push-messages-with-channels).
333333 
334334## Research preview
335335 
from line 339
339339 
340340During the preview, `--channels` only accepts plugins from an Anthropic-maintained allowlist, or from your organization's allowlist if an admin has set [`allowedChannelPlugins`](#restrict-which-channel-plugins-can-run). The channel plugins in [claude-plugins-official](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins) are the default approved set. If you pass something that isn't on the effective allowlist, Claude Code starts normally but the channel doesn't register, and the startup notice tells you why.
341341 
342To test a channel you're building, pass it to `--dangerously-load-development-channels` in the `plugin:<name>@<marketplace>` or `server:<name>` form. See [Test during the research preview](/docs/en/channels-reference.md#test-during-the-research-preview) for information about testing custom channels that you build.
342To test a channel you're building, pass it to `--dangerously-load-development-channels` in the `plugin:<name>@<marketplace>` or `server:<name>` form. See [Test during the research preview](https://code.claude.com/docs/en/channels-reference.md#test-during-the-research-preview) for information about testing custom channels that you build.
343343 
344344Report issues or feedback on the [Claude Code GitHub repository](https://github.com/anthropics/claude-code/issues).
345345 
from line 349
349349 
350350| Feature | What it does | Good for |
351351| - | - | - |
352| [Cloud sessions](/docs/en/claude-code-on-the-web.md) | Run tasks in a fresh cloud sandbox, cloned from GitHub | Delegating self-contained async work you check on later |
353| [Claude in Slack](/docs/en/slack.md) | Spawns a cloud session from an `@Claude` mention in a channel or thread | Starting tasks directly from team conversation context |
354| Standard [MCP server](/docs/en/mcp.md) | Claude queries it during a task; nothing is pushed to the session | Giving Claude on-demand access to read or query a system |
355| [Remote Control](/docs/en/remote-control.md) | You drive your local session from claude.ai or the Claude mobile app | Steering an in-progress session while away from your desk |
352| [Cloud sessions](https://code.claude.com/docs/en/claude-code-on-the-web.md) | Run tasks in a fresh cloud sandbox, cloned from GitHub | Delegating self-contained async work you check on later |
353| [Claude in Slack](https://code.claude.com/docs/en/slack.md) | Spawns a cloud session from an `@Claude` mention in a channel or thread | Starting tasks directly from team conversation context |
354| Standard [MCP server](https://code.claude.com/docs/en/mcp.md) | Claude queries it during a task; nothing is pushed to the session | Giving Claude on-demand access to read or query a system |
355| [Remote Control](https://code.claude.com/docs/en/remote-control.md) | You drive your local session from claude.ai or the Claude mobile app | Steering an in-progress session while away from your desk |
356356 
357357Channels fill the gap in that list by pushing events from non-Claude sources into your already-running local session.
358358 
359359* **Chat bridge**: ask Claude something from your phone via Telegram, Discord, or iMessage, and the answer comes back in the same chat while the work runs on your machine against your real files.
360* **[Webhook receiver](/docs/en/channels-reference.md#example-build-a-webhook-receiver)**: a webhook from CI, your error tracker, a deploy pipeline, or other external service arrives where Claude already has your files open and remembers what you were debugging.
360* **[Webhook receiver](https://code.claude.com/docs/en/channels-reference.md#example-build-a-webhook-receiver)**: a webhook from CI, your error tracker, a deploy pipeline, or other external service arrives where Claude already has your files open and remembers what you were debugging.
361361 
362362## Next steps
363363 
364364Once you have a channel running, explore these related features:
365365 
366* [Build your own channel](/docs/en/channels-reference.md) for systems that don't have plugins yet
367* [Remote Control](/docs/en/remote-control.md) to drive a local session from your phone instead of forwarding events into it
368* [Session-scoped scheduled tasks](/docs/en/scheduled-tasks.md) to poll on a timer instead of reacting to pushed events
366* [Build your own channel](https://code.claude.com/docs/en/channels-reference.md) for systems that don't have plugins yet
367* [Remote Control](https://code.claude.com/docs/en/remote-control.md) to drive a local session from your phone instead of forwarding events into it
368* [Session-scoped scheduled tasks](https://code.claude.com/docs/en/scheduled-tasks.md) to poll on a timer instead of reacting to pushed events
369369 

channels-reference Changed · +15 / -15 lines

from line 4
44 
55> [!NOTE]
66>
7> Channels are in [research preview](/docs/en/channels.md#research-preview). Team and Enterprise organizations must [explicitly enable them](/docs/en/channels.md#enterprise-controls).
7> Channels are in [research preview](https://code.claude.com/docs/en/channels.md#research-preview). Team and Enterprise organizations must [explicitly enable them](https://code.claude.com/docs/en/channels.md#enterprise-controls).
88 
99A channel is an MCP server that pushes events into a Claude Code session so Claude can react to things happening outside the terminal.
1010 
from line 21
2121* [Gate inbound messages](#gate-inbound-messages): sender checks to prevent prompt injection
2222* [Relay permission prompts](#relay-permission-prompts): forward tool approval prompts to remote channels
2323 
24To use an existing channel instead of building one, see [Channels](/docs/en/channels.md). Telegram, Discord, iMessage, and fakechat are included in the research preview.
24To use an existing channel instead of building one, see [Channels](https://code.claude.com/docs/en/channels.md). Telegram, Discord, iMessage, and fakechat are included in the research preview.
2525 
2626## Overview
2727 
from line 44
4444 
4545The [Server options](#server-options) and [Notification format](#notification-format) sections cover each of these in detail. See [Example: build a webhook receiver](#example-build-a-webhook-receiver) for a full walkthrough.
4646 
47During the research preview, custom channels aren't on the [approved allowlist](/docs/en/channels.md#supported-channels). Use `--dangerously-load-development-channels` to test locally. See [Test during the research preview](#test-during-the-research-preview) for details.
47During the research preview, custom channels aren't on the [approved allowlist](https://code.claude.com/docs/en/channels.md#supported-channels). Use `--dangerously-load-development-channels` to test locally. See [Test during the research preview](#test-during-the-research-preview) for details.
4848 
4949## Example: build a webhook receiver
5050 
from line 140
140140 
141141A dim notice below the startup banner confirms the channel is registered: `Channels (experimental) messages from server:webhook inject directly in this session · restart without --dangerously-load-development-channels to stop`.
142142 
143If you see "blocked by org policy," your organization admin needs to [enable channels](/docs/en/channels.md#enterprise-controls) first.
143If you see "blocked by org policy," your organization admin needs to [enable channels](https://code.claude.com/docs/en/channels.md#enterprise-controls) first.
144144 
145145In a separate terminal, simulate a webhook by sending an HTTP POST with a message to your server. This example sends a CI failure alert to port 8788 (or whichever port you configured):
146146 
from line 167
167167 
168168## Test during the research preview
169169 
170During the research preview, every channel must be on the [approved allowlist](/docs/en/channels.md#research-preview) to register. The development flag bypasses the allowlist for specific entries after a confirmation prompt. This example shows both entry types:
170During the research preview, every channel must be on the [approved allowlist](https://code.claude.com/docs/en/channels.md#research-preview) to register. The development flag bypasses the allowlist for specific entries after a confirmation prompt. This example shows both entry types:
171171 
172172```bash theme={null}
173173# Testing a plugin you're developing
from line 427
427427 
428428Gate on the sender's identity, not the chat or room identity: `message.from.id` in the example, not `message.chat.id`. In group chats, these differ, and gating on the room would let anyone in an allowlisted group inject messages into the session.
429429 
430The [Telegram](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/telegram) and [Discord](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/discord) channels gate on a sender allowlist the same way. They bootstrap the list by [pairing](/docs/en/channels.md#security). See either implementation for the full pairing flow. The [iMessage](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/imessage) channel takes a different approach: it detects the user's own addresses from the Messages database at startup and lets them through automatically, with other senders added by handle.
430The [Telegram](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/telegram) and [Discord](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/discord) channels gate on a sender allowlist the same way. They bootstrap the list by [pairing](https://code.claude.com/docs/en/channels.md#security). See either implementation for the full pairing flow. The [iMessage](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/imessage) channel takes a different approach: it detects the user's own addresses from the Messages database at startup and lets them through automatically, with other senders added by handle.
431431 
432432## Relay permission prompts
433433 
from line 435
435435 
436436Relay covers tool-use approvals like `Bash`, `Write`, and `Edit`. Project trust and MCP server consent dialogs don't relay; those only appear in the local terminal.
437437 
438Claude Code v2.1.234 and later sends permission requests only to servers it registered as channels for the session, so relay sits behind the same [session opt-in and organization controls](/docs/en/channels.md#security) as message delivery. Relay also requires you to opt the server in with `--channels` or the development flag, and requires the server to declare the permission capability.
438Claude Code v2.1.234 and later sends permission requests only to servers it registered as channels for the session, so relay sits behind the same [session opt-in and organization controls](https://code.claude.com/docs/en/channels.md#security) as message delivery. Relay also requires you to opt the server in with `--channels` or the development flag, and requires the server to declare the permission capability.
439439 
440440### How relay works
441441 
from line 764
764764 
765765## Package as a plugin
766766 
767To make your channel installable and shareable, wrap it in a [plugin](/docs/en/plugins/overview.md) and publish it to a [marketplace](/docs/en/plugins/overview.md). Users install it with `/plugin install`, then enable it per session with `--channels plugin:<name>@<marketplace>`.
767To make your channel installable and shareable, wrap it in a [plugin](https://code.claude.com/docs/en/plugins/overview.md) and publish it to a [marketplace](https://code.claude.com/docs/en/plugins/overview.md). Users install it with `/plugin install`, then enable it per session with `--channels plugin:<name>@<marketplace>`.
768768 
769A channel published to your own marketplace still needs `--dangerously-load-development-channels` to run, since it isn't on the [approved allowlist](/docs/en/channels.md#supported-channels). The default allowlist is the channel plugins in `claude-plugins-official`. The community marketplace is not on the channel allowlist.
769A channel published to your own marketplace still needs `--dangerously-load-development-channels` to run, since it isn't on the [approved allowlist](https://code.claude.com/docs/en/channels.md#supported-channels). The default allowlist is the channel plugins in `claude-plugins-official`. The community marketplace is not on the channel allowlist.
770770 
771If you are working with an Anthropic partner contact, reach out to them to coordinate an official-marketplace listing. On Team and Enterprise plans, an admin can instead include your plugin in the organization's own [`allowedChannelPlugins`](/docs/en/channels#restrict-which-channel-plugins-can-run) list, which replaces the default Anthropic allowlist.
771If you are working with an Anthropic partner contact, reach out to them to coordinate an official-marketplace listing. On Team and Enterprise plans, an admin can instead include your plugin in the organization's own [`allowedChannelPlugins`](https://code.claude.com/docs/en/channels#restrict-which-channel-plugins-can-run) list, which replaces the default Anthropic allowlist.
772772 
773773## See also
774774 
775* [Channels](/docs/en/channels.md) to install and use Telegram, Discord, iMessage, or the fakechat demo, and to enable channels for a Team or Enterprise org
775* [Channels](https://code.claude.com/docs/en/channels.md) to install and use Telegram, Discord, iMessage, or the fakechat demo, and to enable channels for a Team or Enterprise org
776776* [Working channel implementations](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins) for complete server code with pairing flows, reply tools, and file attachments
777* [MCP](/docs/en/mcp.md) for the underlying protocol that channel servers implement
778* [Plugins](/docs/en/plugins/overview.md) to package your channel so users can install it with `/plugin install`
777* [MCP](https://code.claude.com/docs/en/mcp.md) for the underlying protocol that channel servers implement
778* [Plugins](https://code.claude.com/docs/en/plugins/overview.md) to package your channel so users can install it with `/plugin install`
779779 

checkpointing Changed · +10 / -10 lines

from line 15
1515* Every prompt you send that starts a turn creates a new checkpoint
1616* Claude Code keeps file snapshots for the 100 most recent checkpoints in a session. Discarding an older checkpoint deletes the snapshot files that no remaining checkpoint references, except each file's first snapshot, which the VS Code extension uses as the baseline for its session diffs.
1717* Claude Code saves checkpoints with the conversation, so you can still run `/rewind` after you resume a session
18* Claude Code deletes a session's file snapshots in the [retention sweep](/docs/en/claude-directory.md#cleaned-up-automatically), by default about 30 days after the session last saved one. Rewinding to a checkpoint whose snapshots are gone can fail with [`No files were restored`](/docs/en/errors#no-files-were-restored). To keep snapshots longer, set [`cleanupPeriodDays`](/docs/en/settings-reference#cleanupperioddays).
18* Claude Code deletes a session's file snapshots in the [retention sweep](https://code.claude.com/docs/en/claude-directory.md#cleaned-up-automatically), by default about 30 days after the session last saved one. Rewinding to a checkpoint whose snapshots are gone can fail with [`No files were restored`](https://code.claude.com/docs/en/errors#no-files-were-restored). To keep snapshots longer, set [`cleanupPeriodDays`](https://code.claude.com/docs/en/settings-reference#cleanupperioddays).
1919 
2020### Rewind and summarize
2121 
from line 54
5454 
5555> [!NOTE]
5656>
57> Summarize keeps you in the same session and compresses context, like a targeted `/compact`. To branch off and try a different approach while preserving the original session intact, use [`/branch`](/docs/en/sessions#branch-a-session) or `claude --continue --fork-session` instead.
57> Summarize keeps you in the same session and compresses context, like a targeted `/compact`. To branch off and try a different approach while preserving the original session intact, use [`/branch`](https://code.claude.com/docs/en/sessions#branch-a-session) or `claude --continue --fork-session` instead.
5858 
5959## Common use cases
6060 
from line 75
7575 
7676### Subagent edits not restored
7777 
78A [subagent](/docs/en/sub-agents.md) makes edits with Claude's file editing tools, but Claude Code usually doesn't capture those edits in your session's checkpoints. Whether rewinding restores them depends on how the subagent runs:
78A [subagent](https://code.claude.com/docs/en/sub-agents.md) makes edits with Claude's file editing tools, but Claude Code usually doesn't capture those edits in your session's checkpoints. Whether rewinding restores them depends on how the subagent runs:
7979 
80* **Foreground forked skill**: a [skill with `context: fork`](/docs/en/skills#run-skills-in-a-subagent) that runs in the foreground edits your working tree during your own turn, so rewinding restores its edits as usual. Set `background: false` to run a fork in the foreground; a few situations, [listed on the skills page](/docs/en/skills.md#run-skills-in-a-subagent), run it there regardless of the setting.
81* **Any other subagent**: rewinding restores only the files Claude had already edited in your conversation. The subagent's edits to other files stay, so use version control, such as Git, to revert them. This includes a forked skill that runs in the background, the default, and a background [`/code-review --fix`](/docs/en/code-review-local) run.
80* **Foreground forked skill**: a [skill with `context: fork`](https://code.claude.com/docs/en/skills#run-skills-in-a-subagent) that runs in the foreground edits your working tree during your own turn, so rewinding restores its edits as usual. Set `background: false` to run a fork in the foreground; a few situations, [listed on the skills page](https://code.claude.com/docs/en/skills.md#run-skills-in-a-subagent), run it there regardless of the setting.
81* **Any other subagent**: rewinding restores only the files Claude had already edited in your conversation. The subagent's edits to other files stay, so use version control, such as Git, to revert them. This includes a forked skill that runs in the background, the default, and a background [`/code-review --fix`](https://code.claude.com/docs/en/code-review-local) run.
8282 
8383### External changes not tracked
8484 
from line 86
8686 
8787### Messages sent mid-turn not checkpointed
8888 
89In the rewind menu, a message you [typed while Claude was still working](/docs/en/interactive-mode.md#queue-messages-while-claude-works) can be marked **No code restore**. Claude read that message before its turn ended. [Checkpoints are taken for prompts that start a turn](#how-checkpoints-work), so this message has none of its own. The edits Claude made after reading it count toward the prompt that started the turn.
89In the rewind menu, a message you [typed while Claude was still working](https://code.claude.com/docs/en/interactive-mode.md#queue-messages-while-claude-works) can be marked **No code restore**. Claude read that message before its turn ended. [Checkpoints are taken for prompts that start a turn](#how-checkpoints-work), so this message has none of its own. The edits Claude made after reading it count toward the prompt that started the turn.
9090 
9191You don't need to do anything about the message itself. To undo the file changes from that part of the session, select the prompt that started the turn and choose **Restore code** or **Restore code and conversation**. That reverts Claude's file edits from the whole turn, including the ones from before your message arrived. Selecting the marked message still offers **Restore conversation**, which rewinds the conversation to it and leaves your files as they are.
9292 
from line 94
9494 
9595Checkpointing doesn't rewind symlinked or hard-linked files. When you pick **Restore code** or **Restore code and conversation** from the `/rewind` menu, Claude Code skips any tracked path that is a symlink or hard link and shows a `Restored the code, but skipped N files` warning. The skipped files keep their current contents. To undo the session's changes to one of them, ask Claude to reverse the edit or edit the file yourself. Config files a dotfile manager symlinks into your project and files pnpm hard-links into place both fall into this category.
9696 
97To see which paths a restore skips, turn on debug logging with `/debug` before you restore: the debug log at `~/.claude/debug/<session-id>.txt` names each skipped path. For every skip reason and the recovery steps, see [the skipped-files entry in the error reference](/docs/en/errors.md#restored-the-code-but-skipped-files).
97To see which paths a restore skips, turn on debug logging with `/debug` before you restore: the debug log at `~/.claude/debug/<session-id>.txt` names each skipped path. For every skip reason and the recovery steps, see [the skipped-files entry in the error reference](https://code.claude.com/docs/en/errors.md#restored-the-code-but-skipped-files).
9898 
9999### Not a replacement for version control
100100 
from line 102
102102 
103103## See also
104104 
105* [Interactive mode](/docs/en/interactive-mode.md) - Keyboard shortcuts and session controls
106* [Commands](/docs/en/commands.md) - Accessing checkpoints using `/rewind`
107* [CLI reference](/docs/en/cli-reference.md) - Command-line options
105* [Interactive mode](https://code.claude.com/docs/en/interactive-mode.md) - Keyboard shortcuts and session controls
106* [Commands](https://code.claude.com/docs/en/commands.md) - Accessing checkpoints using `/rewind`
107* [CLI reference](https://code.claude.com/docs/en/cli-reference.md) - Command-line options
108108 

chrome Changed · +22 / -22 lines

from line 2
22 
33> Connect Claude Code to your Chrome browser to test web apps, debug with console logs, automate form filling, and extract data from web pages.
44 
5Claude Code integrates with the [Claude in Chrome browser extension](https://chromewebstore.google.com/detail/claude/fcoeoabgfenejglbffodgkkbkcdhcgfn) to give you browser automation capabilities from the CLI or the [VS Code extension](/docs/en/vs-code.md#automate-browser-tasks-with-chrome). Build your code, then test and debug in the browser without switching contexts.
5Claude Code integrates with the [Claude in Chrome browser extension](https://chromewebstore.google.com/detail/claude/fcoeoabgfenejglbffodgkkbkcdhcgfn) to give you browser automation capabilities from the CLI or the [VS Code extension](https://code.claude.com/docs/en/vs-code.md#automate-browser-tasks-with-chrome). Build your code, then test and debug in the browser without switching contexts.
66 
77Claude opens new tabs for browser tasks and shares your browser's login state, so it can access any site you're already signed into. Browser actions run in a visible Chrome window in real time. When Claude encounters a login page or CAPTCHA, it pauses and asks you to handle it manually.
88 
from line 34
3434 
3535* [Google Chrome](https://www.google.com/chrome/), [Microsoft Edge](https://www.microsoft.com/edge), or another Chromium-based browser such as Brave, Arc, Vivaldi, or Opera
3636* [Claude in Chrome extension](https://chromewebstore.google.com/detail/claude/fcoeoabgfenejglbffodgkkbkcdhcgfn) version 1.0.36 or later, available in the Chrome Web Store
37* [Claude Code](/docs/en/quickstart.md#step-1-install-claude-code)
37* [Claude Code](https://code.claude.com/docs/en/quickstart.md#step-1-install-claude-code)
3838* A direct Anthropic plan (Pro, Max, Team, or Enterprise)
3939 
40In Enterprise organizations that have HIPAA enabled, Claude in Chrome is off by default, and an [Owner](/docs/en/server-managed-settings.md#access-control) can turn it on in [**Organization settings > Claude in Chrome**](https://claude.ai/admin-settings/browser-extension). Your Business Associate Agreement (BAA) with Anthropic doesn't cover data sent to third-party sites through Claude in Chrome. See the [Implementation Guide](https://trust.anthropic.com/resources?s=l1wrssd9hsbi4gak0tp5a6\&name=%5Banthropic%5D-hipaa-ready-offering-implementation-guide) for a list of Eligible Services.
40In Enterprise organizations that have HIPAA enabled, Claude in Chrome is off by default, and an [Owner](https://code.claude.com/docs/en/server-managed-settings.md#access-control) can turn it on in [**Organization settings > Claude in Chrome**](https://claude.ai/admin-settings/browser-extension). Your Business Associate Agreement (BAA) with Anthropic doesn't cover data sent to third-party sites through Claude in Chrome. See the [Implementation Guide](https://trust.anthropic.com/resources?s=l1wrssd9hsbi4gak0tp5a6\&name=%5Banthropic%5D-hipaa-ready-offering-implementation-guide) for a list of Eligible Services.
4141 
42Chrome integration also requires signing in with `/login`. If you authenticate with an API key or a long-lived token from [`claude setup-token`](/docs/en/authentication#generate-a-long-lived-token), Claude Code keeps Chrome integration off, even when you pass `--chrome`, because the browser extension can't authenticate with those credentials. Before v2.1.216, these sessions could enable Chrome integration, but every attempt to connect to the browser extension failed with a 403 error.
42Chrome integration also requires signing in with `/login`. If you authenticate with an API key or a long-lived token from [`claude setup-token`](https://code.claude.com/docs/en/authentication#generate-a-long-lived-token), Claude Code keeps Chrome integration off, even when you pass `--chrome`, because the browser extension can't authenticate with those credentials. Before v2.1.216, these sessions could enable Chrome integration, but every attempt to connect to the browser extension failed with a 403 error.
4343 
4444> [!NOTE]
4545>
from line 74
7474 
7575If more than one browser is connected, you choose which one Claude uses. When a browser action starts before you've chosen, Claude prompts you to pick one. To switch browsers later, run `/chrome` and select **Select browser…**. Claude keeps using your choice even when another browser connects.
7676 
77For VS Code, see [browser automation in VS Code](/docs/en/vs-code.md#automate-browser-tasks-with-chrome).
77For VS Code, see [browser automation in VS Code](https://code.claude.com/docs/en/vs-code.md#automate-browser-tasks-with-chrome).
7878 
7979### Install the extension when Claude asks
8080 
from line 88
8888 
8989Two managed MCP policies turn the prompt off:
9090 
91* If your organization blocks the `claude-in-chrome` MCP server with the [`deniedMcpServers` managed setting](/docs/en/managed-mcp#policy-based-control-with-allowlists-and-denylists), Claude Code doesn't show the install prompt.
92* If your organization deploys a [`managed-mcp.json`](/docs/en/managed-mcp#exclusive-control-with-managed-mcp-json) file without [allowing Claude in Chrome alongside the managed set](/docs/en/managed-mcp.md#allow-claude-in-chrome-alongside-the-managed-set), Claude Code doesn't show the install prompt.
91* If your organization blocks the `claude-in-chrome` MCP server with the [`deniedMcpServers` managed setting](https://code.claude.com/docs/en/managed-mcp#policy-based-control-with-allowlists-and-denylists), Claude Code doesn't show the install prompt.
92* If your organization deploys a [`managed-mcp.json`](https://code.claude.com/docs/en/managed-mcp#exclusive-control-with-managed-mcp-json) file without [allowing Claude in Chrome alongside the managed set](https://code.claude.com/docs/en/managed-mcp.md#allow-claude-in-chrome-alongside-the-managed-set), Claude Code doesn't show the install prompt.
9393 
9494### Enable Chrome by default
9595 
96To connect Chrome without passing `--chrome` each time, run `/chrome` in a CLI session and select **Enabled by default**. In the [VS Code extension](/docs/en/vs-code.md#automate-browser-tasks-with-chrome), type `/chrome` in the prompt box and turn on the **Enabled by default** switch. The two share one setting, so turning it on in either place turns it on for both the CLI and VS Code.
96To connect Chrome without passing `--chrome` each time, run `/chrome` in a CLI session and select **Enabled by default**. In the [VS Code extension](https://code.claude.com/docs/en/vs-code.md#automate-browser-tasks-with-chrome), type `/chrome` in the prompt box and turn on the **Enabled by default** switch. The two share one setting, so turning it on in either place turns it on for both the CLI and VS Code.
9797 
9898With the setting on and Claude Code v2.1.287 or later, each VS Code session connects to your browser as it starts, so Claude can use it before you type `@browser`. On earlier versions, or with the setting off, a VS Code session connects when you type `@browser`.
9999 
from line 101
101101 
102102> [!NOTE]
103103>
104> Enabling Chrome by default increases context usage since the browser tools and their instructions are always loaded. If you notice increased context consumption, turn the setting off and connect only when needed, with `--chrome` in the CLI or by typing [`@browser`](/docs/en/vs-code#automate-browser-tasks-with-chrome) in the VS Code prompt box.
104> Enabling Chrome by default increases context usage since the browser tools and their instructions are always loaded. If you notice increased context consumption, turn the setting off and connect only when needed, with `--chrome` in the CLI or by typing [`@browser`](https://code.claude.com/docs/en/vs-code#automate-browser-tasks-with-chrome) in the VS Code prompt box.
105105 
106106### Manage site permissions
107107 
108Site-level permissions are inherited from the Chrome extension. Manage permissions in the Chrome extension settings to control which sites Claude can browse, click, and type on. In [auto mode](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), when the auto mode classifier itself approves a browser call to a site, the extension skips its own per-site check for that call, unless your permission rules deny any site to Claude in Chrome.
108Site-level permissions are inherited from the Chrome extension. Manage permissions in the Chrome extension settings to control which sites Claude can browse, click, and type on. In [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), when the auto mode classifier itself approves a browser call to a site, the extension skips its own per-site check for that call, unless your permission rules deny any site to Claude in Chrome.
109109 
110110### Permission prompts in VS Code sessions
111111 
from line 115
115115 
116116### Browser tools in plan mode
117117 
118In [plan mode](/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode), a permission prompt appears before Claude records a GIF, opens a new tab, or runs a shortcut. In an interactive CLI session, if [bypass permissions mode is available](/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) and [feature-flag fetching](/docs/en/env-vars.md#features-that-need-feature-flag-fetching) is off, these calls run without a prompt.
118In [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode), a permission prompt appears before Claude records a GIF, opens a new tab, or runs a shortcut. In an interactive CLI session, if [bypass permissions mode is available](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) and [feature-flag fetching](https://code.claude.com/docs/en/env-vars.md#features-that-need-feature-flag-fetching) is off, these calls run without a prompt.
119119 
120120A `tabs_context_mcp` call also prompts when it sets `createIfEmpty`, and so does a `browser_batch` call that includes any of these actions.
121121 
from line 171
171171 
172172If Claude refuses to attach a file or an upload fails, check for these causes:
173173 
174* **Permissions**: Claude can upload a file only when the session is allowed to read it, so [permission rules](/docs/en/settings-reference.md#permission-settings) that deny `Read` access to a file also block uploading it.
174* **Permissions**: Claude can upload a file only when the session is allowed to read it, so [permission rules](https://code.claude.com/docs/en/settings-reference.md#permission-settings) that deny `Read` access to a file also block uploading it.
175175* **Size**: a single upload can include up to 10 MB of files in total.
176176* **Hard links**: Claude refuses files that have multiple hard links, which is common inside package-manager stores like `node_modules`. Copy the file and upload the copy.
177177* **Credential names**: Claude refuses a file whose name or folder is one that credentials are kept under, such as `.env`, a `.pem` or `.key` file, or anything under `.ssh`. Requires Claude Code v2.1.293 or later.
from line 271
271271Claude Code ignored CLAUDE_CODE_ENABLE_CFC in this project's settings: a project can't turn on Claude in Chrome. To turn it on yourself, run /chrome or start with --chrome.
272272```
273273 
274The project's `.claude/settings.json` or `.claude/settings.local.json` sets [`CLAUDE_CODE_ENABLE_CFC`](/docs/en/env-vars#variables) to `1` in its `env` block to turn Chrome integration on. Claude Code didn't apply that setting, so Chrome integration is off in this session and Claude has no browser tools.
274The project's `.claude/settings.json` or `.claude/settings.local.json` sets [`CLAUDE_CODE_ENABLE_CFC`](https://code.claude.com/docs/en/env-vars#variables) to `1` in its `env` block to turn Chrome integration on. Claude Code didn't apply that setting, so Chrome integration is off in this session and Claude has no browser tools.
275275 
276276Claude Code skips the setting because those files are stored in the project directory, and a repository you check out must not be able to connect Claude to your browser.
277277 
from line 299
299299 
300300If you belong to more than one claude.ai organization, the extension must be signed in to the same organization as Claude Code. If the two differ, Claude's browser tools return "Browser extension is not connected", even when both use the same claude.ai account.
301301 
302To see which organization Claude Code is signed in to, run [`/status`](/docs/en/commands) at the Claude Code prompt and read the `Organization` row.
302To see which organization Claude Code is signed in to, run [`/status`](https://code.claude.com/docs/en/commands) at the Claude Code prompt and read the `Organization` row.
303303 
304304> [!WARNING]
305305>
from line 321
321321 
322322| Error | Cause | Fix |
323323| - | - | - |
324| "Browser extension is not connected" | The extension isn't installed and running in Chrome, the extension is signed in to a different claude.ai account or organization than Claude Code, or your organization's IP allowlist rejects the connection to `bridge.claudeusercontent.com` | Check that the extension is signed in to the same claude.ai account and [organization](#extension-signed-in-to-a-different-organization) as Claude Code, restart Chrome and Claude Code, then run `/chrome` to reconnect. If your organization uses IP allowlisting and the error persists, see [Organization IP allowlists and proxy egress](/docs/en/network-config.md#organization-ip-allowlists-and-proxy-egress) |
324| "Browser extension is not connected" | The extension isn't installed and running in Chrome, the extension is signed in to a different claude.ai account or organization than Claude Code, or your organization's IP allowlist rejects the connection to `bridge.claudeusercontent.com` | Check that the extension is signed in to the same claude.ai account and [organization](#extension-signed-in-to-a-different-organization) as Claude Code, restart Chrome and Claude Code, then run `/chrome` to reconnect. If your organization uses IP allowlisting and the error persists, see [Organization IP allowlists and proxy egress](https://code.claude.com/docs/en/network-config.md#organization-ip-allowlists-and-proxy-egress) |
325325| Extension shows "Not detected" in `/chrome` | Chrome extension is not installed or is disabled | Install or enable the extension in `chrome://extensions` |
326326| "No tab available" | Claude tried to act before a tab was ready | Ask Claude to create a new tab and retry |
327327| "Receiving end does not exist" | Extension service worker went idle | Run `/chrome` and select "Reconnect extension" |
328| "No browsers are connected" | Chrome isn't open with the extension signed in to the same claude.ai account and organization as Claude Code, or Claude Code can't reach `bridge.claudeusercontent.com` | Confirm Chrome is open and the extension is signed in to the same claude.ai account and [organization](#extension-signed-in-to-a-different-organization) as Claude Code. If so, check that your network lets Claude Code reach `bridge.claudeusercontent.com`, listed under [Network access requirements](/docs/en/network-config.md#network-access-requirements) |
328| "No browsers are connected" | Chrome isn't open with the extension signed in to the same claude.ai account and organization as Claude Code, or Claude Code can't reach `bridge.claudeusercontent.com` | Confirm Chrome is open and the extension is signed in to the same claude.ai account and [organization](#extension-signed-in-to-a-different-organization) as Claude Code. If so, check that your network lets Claude Code reach `bridge.claudeusercontent.com`, listed under [Network access requirements](https://code.claude.com/docs/en/network-config.md#network-access-requirements) |
329329 
330330## See also
331331 
332* [Computer use](/docs/en/computer-use.md): control native macOS apps when a task can't be done in a browser
333* [Use Claude Code in VS Code](/docs/en/vs-code.md#automate-browser-tasks-with-chrome): browser automation in the VS Code extension
334* [CLI reference](/docs/en/cli-reference.md): command-line flags including `--chrome`
335* [Common workflows](/docs/en/common-workflows.md): more ways to use Claude Code
336* [Data and privacy](/docs/en/data-usage.md): how Claude Code handles your data
332* [Computer use](https://code.claude.com/docs/en/computer-use.md): control native macOS apps when a task can't be done in a browser
333* [Use Claude Code in VS Code](https://code.claude.com/docs/en/vs-code.md#automate-browser-tasks-with-chrome): browser automation in the VS Code extension
334* [CLI reference](https://code.claude.com/docs/en/cli-reference.md): command-line flags including `--chrome`
335* [Common workflows](https://code.claude.com/docs/en/common-workflows.md): more ways to use Claude Code
336* [Data and privacy](https://code.claude.com/docs/en/data-usage.md): how Claude Code handles your data
337337* [Getting started with Claude in Chrome](https://support.claude.com/en/articles/12012173-getting-started-with-claude-in-chrome): full documentation for the Chrome extension, including shortcuts, scheduling, and permissions
338338 

claude-apps-gateway Changed · +89 / -89 lines

from line 4
44 
55> [!NOTE]
66>
7> The Claude apps gateway is designed for organizations that must, or prefer to, route inference through their own cloud provider, for example to meet [data residency](/docs/en/claude-apps-gateway-deploy.md#compliance-posture) requirements. If you don't have this requirement, and want access to other features such as SCIM provisioning or Claude Code on web and mobile, Claude Enterprise may be a better fit. See the [feature availability](/docs/en/feature-availability.md) page for a full comparison of all deployment methods.
7> The Claude apps gateway is designed for organizations that must, or prefer to, route inference through their own cloud provider, for example to meet [data residency](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#compliance-posture) requirements. If you don't have this requirement, and want access to other features such as SCIM provisioning or Claude Code on web and mobile, Claude Enterprise may be a better fit. See the [feature availability](https://code.claude.com/docs/en/feature-availability.md) page for a full comparison of all deployment methods.
88>
9> Claude Code uses one sign-in at a time: a gateway sign-in takes the place of a Claude for Teams or Enterprise login. Gateway sessions don't fetch the [server-managed settings](/docs/en/server-managed-settings.md) you set in the claude.ai admin console, so deliver them from the gateway's [`managed` block](/docs/en/claude-apps-gateway-config#managed). Leave `forceLoginMethod` and `forceLoginOrgUUID` out of that block, or [some signed-in sessions exit at startup](/docs/en/claude-apps-gateway-config.md#client-side-managed-settings). See [Availability and limitations](#availability-and-limitations) for what gateway sessions lose.
9> Claude Code uses one sign-in at a time: a gateway sign-in takes the place of a Claude for Teams or Enterprise login. Gateway sessions don't fetch the [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md) you set in the claude.ai admin console, so deliver them from the gateway's [`managed` block](https://code.claude.com/docs/en/claude-apps-gateway-config#managed). Leave `forceLoginMethod` and `forceLoginOrgUUID` out of that block, or [some signed-in sessions exit at startup](https://code.claude.com/docs/en/claude-apps-gateway-config.md#client-side-managed-settings). See [Availability and limitations](#availability-and-limitations) for what gateway sessions lose.
1010 
11Claude apps gateway is a self-hosted service that sits between your developers' Claude Code clients and your model provider. Developers sign in with your corporate identity provider (IdP) instead of holding API keys or cloud credentials. The gateway holds the upstream credential, enforces model access and [managed settings](/docs/en/managed-settings.md) by IdP group, and relays usage telemetry to your own observability stack.
11Claude apps gateway is a self-hosted service that sits between your developers' Claude Code clients and your model provider. Developers sign in with your corporate identity provider (IdP) instead of holding API keys or cloud credentials. The gateway holds the upstream credential, enforces model access and [managed settings](https://code.claude.com/docs/en/managed-settings.md) by IdP group, and relays usage telemetry to your own observability stack.
1212 
1313It is included in the `claude` binary, so the same executable that runs Claude Code on a laptop runs the gateway server with `claude gateway --config gateway.yaml`.
1414 
from line 19
1919* [Connecting developers](#connect-developers), including setting the gateway URL through managed settings
2020* [Availability and limitations](#availability-and-limitations) covering which Claude Code features work through the gateway and what the server supports
2121 
22Companion pages go deeper. The [configuration reference](/docs/en/claude-apps-gateway-config.md) covers every option in the YAML file the quickstart writes, and the [deployment guide](/docs/en/claude-apps-gateway-deploy.md) covers per-IdP setup, Kubernetes and Cloud Run deployment, and operations.
22Companion pages go deeper. The [configuration reference](https://code.claude.com/docs/en/claude-apps-gateway-config.md) covers every option in the YAML file the quickstart writes, and the [deployment guide](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md) covers per-IdP setup, Kubernetes and Cloud Run deployment, and operations.
2323 
2424## Why Claude apps gateway
2525 
26The [gateway overview](/docs/en/gateways.md) covers what a gateway does and why you'd run one. Claude apps gateway is Anthropic's own gateway, built into the `claude` binary and tested alongside each Claude Code release, so it forwards the `anthropic-beta` values and request fields Claude Code sends without operators maintaining a separate allowlist. Once deployed it gives you:
26The [gateway overview](https://code.claude.com/docs/en/gateways.md) covers what a gateway does and why you'd run one. Claude apps gateway is Anthropic's own gateway, built into the `claude` binary and tested alongside each Claude Code release, so it forwards the `anthropic-beta` values and request fields Claude Code sends without operators maintaining a separate allowlist. Once deployed it gives you:
2727 
2828* **Credentials**: the upstream API key or cloud credential lives only in your infrastructure. Developers authenticate with corporate SSO and receive short-lived bearer tokens, so offboarding happens in your IdP. Deprovision a user and their gateway access expires within the session lifetime, one hour by default.
29* **Access control**: your IdP groups map to model allowlists and [managed settings](/docs/en/managed-settings.md) policies. The gateway enforces model access server-side, rejecting requests for non-granted models, and selects each group's managed settings policy, which the CLI applies at the [managed settings tier](/docs/en/settings.md#settings-precedence). Different teams get different models, tools, and permissions, and a developer can't override what their policy locks.
30* **Settings delivery**: the gateway delivers managed settings to signed-in clients itself, taking the place of [server-managed settings](/docs/en/server-managed-settings.md) from the claude.ai admin console.
31* **Telemetry**: each configured destination receives [OpenTelemetry Protocol (OTLP) metrics](/docs/en/monitoring-usage.md) with token counts, model, user identity, and latency by default, with logs and traces as per-destination opt-ins.
32* **Upstream routing**: clients speak the Anthropic Messages API to the gateway, and the gateway translates for each upstream, whether Amazon Bedrock, [Claude Platform on AWS](/docs/en/claude-platform-on-aws.md), Google Cloud's Agent Platform, Microsoft Foundry, or the Anthropic API, with failover between them. You can change regions, providers, or failover order without developers noticing or reconfiguring.
29* **Access control**: your IdP groups map to model allowlists and [managed settings](https://code.claude.com/docs/en/managed-settings.md) policies. The gateway enforces model access server-side, rejecting requests for non-granted models, and selects each group's managed settings policy, which the CLI applies at the [managed settings tier](https://code.claude.com/docs/en/settings.md#settings-precedence). Different teams get different models, tools, and permissions, and a developer can't override what their policy locks.
30* **Settings delivery**: the gateway delivers managed settings to signed-in clients itself, taking the place of [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md) from the claude.ai admin console.
31* **Telemetry**: each configured destination receives [OpenTelemetry Protocol (OTLP) metrics](https://code.claude.com/docs/en/monitoring-usage.md) with token counts, model, user identity, and latency by default, with logs and traces as per-destination opt-ins.
32* **Upstream routing**: clients speak the Anthropic Messages API to the gateway, and the gateway translates for each upstream, whether Amazon Bedrock, [Claude Platform on AWS](https://code.claude.com/docs/en/claude-platform-on-aws.md), Google Cloud's Agent Platform, Microsoft Foundry, or the Anthropic API, with failover between them. You can change regions, providers, or failover order without developers noticing or reconfiguring.
3333 
3434![Diagram showing Claude Code clients and Claude Desktop's Chat, Cowork, and Code tabs connecting over HTTPS with bearer tokens to a self-hosted Claude apps gateway inside your infrastructure, which signs users in against your IdP, stores auth state in PostgreSQL, relays telemetry to your OTLP collector, and forwards inference to Amazon Bedrock, Claude Platform on AWS, Google Cloud, Microsoft Foundry, or the Anthropic API](https://mintcdn.com/claude-code/VbyXug8hBU9UK6oT/images/claude-gateway-architecture.svg?fit=max\&auto=format\&n=VbyXug8hBU9UK6oT\&q=85\&s=9e4f1190fc56718144190a3db61c63af)
3535 
3636> [!NOTE]
3737>
38> The gateway's own data plane sends nothing to Anthropic infrastructure unless the Anthropic API is a configured upstream. You control where telemetry, audit logs, managed settings, and your developers' IdP identity go, and the gateway sends none of them to Anthropic. For the remaining traffic the CLI process can send and how to close it, see [Compliance posture](/docs/en/claude-apps-gateway-deploy.md#compliance-posture).
38> The gateway's own data plane sends nothing to Anthropic infrastructure unless the Anthropic API is a configured upstream. You control where telemetry, audit logs, managed settings, and your developers' IdP identity go, and the gateway sends none of them to Anthropic. For the remaining traffic the CLI process can send and how to close it, see [Compliance posture](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#compliance-posture).
3939 
40For which Claude Code features work through the gateway and what the server itself supports, see [Availability and limitations](#availability-and-limitations) below. For decisions such as cost, bypass, running multiple gateways, and serverless platforms, see the [deployment guide](/docs/en/claude-apps-gateway-deploy.md#deployment).
40For which Claude Code features work through the gateway and what the server itself supports, see [Availability and limitations](#availability-and-limitations) below. For decisions such as cost, bypass, running multiple gateways, and serverless platforms, see the [deployment guide](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#deployment).
4141 
4242### Other gateway implementations
4343 
44If you already run an LLM gateway or API gateway that meets your needs, keep using it; [Other LLM gateways](/docs/en/llm-gateway) covers configuring Claude Code against it.
44If you already run an LLM gateway or API gateway that meets your needs, keep using it; [Other LLM gateways](https://code.claude.com/docs/en/llm-gateway) covers configuring Claude Code against it.
4545 
46The [gateway compatibility guide](/docs/en/llm-gateway-protocol.md) documents what Claude Code expects from any gateway: the endpoints it calls, the headers and body fields to forward, and what stops working when they're stripped. A running Claude apps gateway also serves its own protocol reference at `GET /protocol`, which describes the endpoints it exposes to Claude Code clients: SSO sign-in, inference, managed settings delivery, model discovery, and telemetry. Fetch it with `curl https://claude-gateway.internal.example.com/protocol` from any deployed gateway, such as the one the [quickstart](#quickstart) below produces.
46The [gateway compatibility guide](https://code.claude.com/docs/en/llm-gateway-protocol.md) documents what Claude Code expects from any gateway: the endpoints it calls, the headers and body fields to forward, and what stops working when they're stripped. A running Claude apps gateway also serves its own protocol reference at `GET /protocol`, which describes the endpoints it exposes to Claude Code clients: SSO sign-in, inference, managed settings delivery, model discovery, and telemetry. Fetch it with `curl https://claude-gateway.internal.example.com/protocol` from any deployed gateway, such as the one the [quickstart](#quickstart) below produces.
4747 
4848Breaking changes to the protocol are announced in advance, but indefinite backwards compatibility isn't guaranteed.
4949 
from line 53
5353 
5454## Quickstart
5555 
56This quickstart walks the minimal path: register an OAuth client in your IdP, write a `gateway.yaml`, run the gateway alongside Postgres with Docker Compose, and verify sign-in end to end. It uses an Amazon Bedrock upstream; Claude Platform on AWS, Google Cloud's Agent Platform, Microsoft Foundry, and the Anthropic API are equally supported by swapping the `upstreams` block as shown in the [configuration reference](/docs/en/claude-apps-gateway-config.md#upstreams). At the end you have a gateway a developer can `/login` to.
56This quickstart walks the minimal path: register an OAuth client in your IdP, write a `gateway.yaml`, run the gateway alongside Postgres with Docker Compose, and verify sign-in end to end. It uses an Amazon Bedrock upstream; Claude Platform on AWS, Google Cloud's Agent Platform, Microsoft Foundry, and the Anthropic API are equally supported by swapping the `upstreams` block as shown in the [configuration reference](https://code.claude.com/docs/en/claude-apps-gateway-config.md#upstreams). At the end you have a gateway a developer can `/login` to.
5757 
5858> [!NOTE]
5959>
from line 65
6565 
6666| You need | Details |
6767| - | - |
68| Claude Code v2.1.195 or later | The `claude gateway` subcommand and the gateway sign-in flow ship in v2.1.195. Earlier public builds don't include them. Both the machine running the gateway server and each developer's machine must be on v2.1.195 or later; run `claude update` to get the latest release. The [Claude Platform on AWS upstream](/docs/en/claude-apps-gateway-config.md#claude-platform-on-aws) requires Claude Code v2.1.198 or later on the gateway server. |
68| Claude Code v2.1.195 or later | The `claude gateway` subcommand and the gateway sign-in flow ship in v2.1.195. Earlier public builds don't include them. Both the machine running the gateway server and each developer's machine must be on v2.1.195 or later; run `claude update` to get the latest release. The [Claude Platform on AWS upstream](https://code.claude.com/docs/en/claude-apps-gateway-config.md#claude-platform-on-aws) requires Claude Code v2.1.198 or later on the gateway server. |
6969| OpenID Connect (OIDC) identity provider | Okta, Microsoft Entra ID, Google Workspace, Keycloak, or Dex, or any other OIDC-compliant IdP such as PingFederate. The gateway runs standard OIDC discovery and the authorization-code flow against it. SAML and LDAP aren't supported. |
70| PostgreSQL 11 or later | Backs the device sign-in flow and rate-limit counters. A managed PostgreSQL service works, including the smallest tier; see [which databases are supported](/docs/en/claude-apps-gateway-deploy.md#postgres). With [spend limits](/docs/en/claude-apps-gateway-spend-limits.md), it also holds durable spend, audit, and identity tables that should be backed up. TLS via `?sslmode=require` is recommended. PostgreSQL 11, 12, and 13 require Claude Code v2.1.290 or later on the gateway server. The PostgreSQL project no longer maintains those versions, so use a newer one where you can. |
70| PostgreSQL 11 or later | Backs the device sign-in flow and rate-limit counters. A managed PostgreSQL service works, including the smallest tier; see [which databases are supported](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#postgres). With [spend limits](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md), it also holds durable spend, audit, and identity tables that should be backed up. TLS via `?sslmode=require` is recommended. PostgreSQL 11, 12, and 13 require Claude Code v2.1.290 or later on the gateway server. The PostgreSQL project no longer maintains those versions, so use a newer one where you can. |
7171| Model upstream | Amazon Bedrock credentials, Claude Platform on AWS credentials, Google Cloud credentials, a Microsoft Foundry resource, or an Anthropic API key. Multiple upstreams are supported with failover. |
7272| HTTPS | The gateway must be reachable over `https://` from developer laptops and from any browser used for sign-in; the gateway serves the device-verification page on the same listener. Either provide a TLS cert via `listen.tls` or run behind a TLS-terminating ingress, and set `listen.public_url` to the external origin in both cases. At `/login`, Claude Code accepts a plain `http://` origin only when the gateway host is loopback: `localhost`, `127.0.0.1`, or `::1`. |
73| Private-network address | At `/login`, Claude Code requires the gateway's hostname or IP address to resolve only to private addresses: RFC 1918, link-local, CGNAT `100.64.0.0/10`, IPv6 ULA `fc00::/7`, or loopback. For a gateway you host, any public address outside a block you declare is rejected; see the [threat model](/docs/en/claude-apps-gateway-deploy.md#threat-model-summary) in the deployment guide. If developer machines route HTTPS through a corporate proxy, sign-in also requires the proxy host to resolve to private addresses; if it doesn't, add the gateway host to `NO_PROXY` so the CLI connects directly. If your internal network is numbered from public IPv4 space your organization owns, [declare those blocks](#allow-a-gateway-on-public-address-space-you-own) so `/login` accepts a gateway there. |
73| Private-network address | At `/login`, Claude Code requires the gateway's hostname or IP address to resolve only to private addresses: RFC 1918, link-local, CGNAT `100.64.0.0/10`, IPv6 ULA `fc00::/7`, or loopback. For a gateway you host, any public address outside a block you declare is rejected; see the [threat model](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#threat-model-summary) in the deployment guide. If developer machines route HTTPS through a corporate proxy, sign-in also requires the proxy host to resolve to private addresses; if it doesn't, add the gateway host to `NO_PROXY` so the CLI connects directly. If your internal network is numbered from public IPv4 space your organization owns, [declare those blocks](#allow-a-gateway-on-public-address-space-you-own) so `/login` accepts a gateway there. |
7474| Linux runtime | The gateway server runs only on the native Linux binary. macOS works for local development. Windows isn't supported as a server platform. |
7575 
7676### Steps
from line 77
7777 
7878**1. Register an OAuth client in your IdP**
7979 
80Decide the gateway's hostname first, because the redirect URI must match it. Create a new OIDC web application and set the redirect URI to `https://claude-gateway.<your-domain>/oauth/callback`, where the host is the same value you set as [`listen.public_url`](/docs/en/claude-apps-gateway-config#listen) in step 3. Note the `client_id` and `client_secret`. Per-IdP instructions are in [Identity provider setup](/docs/en/claude-apps-gateway-deploy.md#identity-provider-setup).
80Decide the gateway's hostname first, because the redirect URI must match it. Create a new OIDC web application and set the redirect URI to `https://claude-gateway.<your-domain>/oauth/callback`, where the host is the same value you set as [`listen.public_url`](https://code.claude.com/docs/en/claude-apps-gateway-config#listen) in step 3. Note the `client_id` and `client_secret`. Per-IdP instructions are in [Identity provider setup](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#identity-provider-setup).
8181 
8282**2. Provision a PostgreSQL database**
8383 
84Use PostgreSQL 11 or later. The smallest managed tier is enough. The gateway runs its own schema migrations at boot, so the database role needs rights to create and alter tables; see [`store`](/docs/en/claude-apps-gateway-config#store).
84Use PostgreSQL 11 or later. The smallest managed tier is enough. The gateway runs its own schema migrations at boot, so the database role needs rights to create and alter tables; see [`store`](https://code.claude.com/docs/en/claude-apps-gateway-config#store).
8585 
8686**3. Write gateway.yaml**
8787 
from line 122
122122auto_include_builtin_models: true
123123```
124124 
125This config is enough for a working sign-in loop with the default Amazon Bedrock model catalog. Once it's running, add per-group RBAC and managed settings via [`managed.policies`](/docs/en/claude-apps-gateway-config#managed), telemetry fan-out via [`telemetry`](/docs/en/claude-apps-gateway-config#telemetry), and multi-upstream failover, provisioned-throughput ARNs, or non-US regions via [`models`](/docs/en/claude-apps-gateway-config#models).
125This config is enough for a working sign-in loop with the default Amazon Bedrock model catalog. Once it's running, add per-group RBAC and managed settings via [`managed.policies`](https://code.claude.com/docs/en/claude-apps-gateway-config#managed), telemetry fan-out via [`telemetry`](https://code.claude.com/docs/en/claude-apps-gateway-config#telemetry), and multi-upstream failover, provisioned-throughput ARNs, or non-US regions via [`models`](https://code.claude.com/docs/en/claude-apps-gateway-config#models).
126126 
127127> [!NOTE]
128128>
129129> The Amazon Bedrock upstream needs an AWS principal with `bedrock:InvokeModel` and `bedrock:InvokeModelWithResponseStream` on both the `inference-profile/us.anthropic.*` ARNs and the underlying `foundation-model/anthropic.*` ARNs. It also needs Anthropic's one-time use case form submitted for the account from the Bedrock console's Model catalog.
130130>
131> Supply the credential with IRSA on EKS, an ECS task role, or an EC2 instance profile rather than static keys. The [`upstreams` reference](/docs/en/claude-apps-gateway-config#upstreams) has the full IAM details, the cross-cloud credential matrix, and the `auth` blocks for the other providers.
131> Supply the credential with IRSA on EKS, an ECS task role, or an EC2 instance profile rather than static keys. The [`upstreams` reference](https://code.claude.com/docs/en/claude-apps-gateway-config#upstreams) has the full IAM details, the cross-cloud credential matrix, and the `auth` blocks for the other providers.
132132 
133133**4. Run it**
134134 
135Build a container image around the `claude` binary that meets the [image requirements](/docs/en/claude-apps-gateway-deploy.md#container-image), then run it alongside Postgres. The Compose file references the image as `registry.example.com/claude-gateway:2.1.198`; substitute your own registry and image tag:
135Build a container image around the `claude` binary that meets the [image requirements](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#container-image), then run it alongside Postgres. The Compose file references the image as `registry.example.com/claude-gateway:2.1.198`; substitute your own registry and image tag:
136136 
137137```yaml docker-compose.yaml theme={null}
138138services:
from line 179
179179[gateway] 2026-06-10T17:03:21.512Z info claude gateway listening on http://0.0.0.0:8080
180180```
181181 
182The gateway also logs a warning that `access_control.allow_cidrs` is empty. That's expected here, because nothing limits which client addresses the gateway serves until you set an allow list. The [`access_control` reference](/docs/en/claude-apps-gateway-config#http-tuning) has the recommended ranges.
182The gateway also logs a warning that `access_control.allow_cidrs` is empty. That's expected here, because nothing limits which client addresses the gateway serves until you set an allow list. The [`access_control` reference](https://code.claude.com/docs/en/claude-apps-gateway-config#http-tuning) has the recommended ranges.
183183 
184184If boot exits before the `claude gateway listening on` line, the last line of stderr names the problem:
185185 
from line 245
245245 
246246**6. Log a developer in**
247247 
248This last step happens on a developer machine, not the server. Set `forceLoginMethod` to `"gateway"`, `forceLoginGatewayUrl` to your gateway's `public_url`, and `parentSettingsBehavior` to `"merge"` in that machine's [managed settings file](/docs/en/managed-settings.md#delivery-mechanisms), then run `/login`, press Enter on the **Cloud gateway** screen, and complete the browser sign-in. [Set the gateway URL](#set-the-gateway-url) below covers the three keys and distributing them to every developer machine.
248This last step happens on a developer machine, not the server. Set `forceLoginMethod` to `"gateway"`, `forceLoginGatewayUrl` to your gateway's `public_url`, and `parentSettingsBehavior` to `"merge"` in that machine's [managed settings file](https://code.claude.com/docs/en/managed-settings.md#delivery-mechanisms), then run `/login`, press Enter on the **Cloud gateway** screen, and complete the browser sign-in. [Set the gateway URL](#set-the-gateway-url) below covers the three keys and distributing them to every developer machine.
249249 
250250## Connect developers
251251 
252Developers connect from their own laptops with one browser sign-in, using their corporate work account. They don't need a claude.ai account, an API key, or a subscription, because requests to the model go through the gateway using the organization's upstream credential. Connection is driven by the [client-side managed settings](/docs/en/claude-apps-gateway-config.md#client-side-managed-settings) you push via MDM, and this section covers what the admin configures.
252Developers connect from their own laptops with one browser sign-in, using their corporate work account. They don't need a claude.ai account, an API key, or a subscription, because requests to the model go through the gateway using the organization's upstream credential. Connection is driven by the [client-side managed settings](https://code.claude.com/docs/en/claude-apps-gateway-config.md#client-side-managed-settings) you push via MDM, and this section covers what the admin configures.
253253 
254254The CLI fingerprints the gateway's TLS leaf certificate on first connect and pins it per hostname. It checks that pin again during sign-in, on silent session refreshes, and on managed-settings fetches, while inference requests use standard TLS validation without the pin. Requests routed through an HTTPS proxy skip the pin check, so add the gateway host to `NO_PROXY` to keep them direct.
255255 
from line 259
259259openssl x509 -noout -fingerprint -sha256 -in cert.pem | cut -d= -f2 | tr -d : | tr 'A-F' 'a-f'
260260```
261261 
262When the certificate rotates, every developer sees the trust prompt again, so treat rotations as a planned event and republish the fingerprint. If your gateway policy includes [settings that need approval](/docs/en/server-managed-settings.md#security-approval-dialogs), the developer also sees that approval dialog again after accepting the new certificate, because Claude Code keys [approval memory](/docs/en/server-managed-settings.md#approval-memory) to the pinned certificate.
262When the certificate rotates, every developer sees the trust prompt again, so treat rotations as a planned event and republish the fingerprint. If your gateway policy includes [settings that need approval](https://code.claude.com/docs/en/server-managed-settings.md#security-approval-dialogs), the developer also sees that approval dialog again after accepting the new certificate, because Claude Code keys [approval memory](https://code.claude.com/docs/en/server-managed-settings.md#approval-memory) to the pinned certificate.
263263 
264264A gateway can return the optional `email` field in its token response to name the account that a sign-in used. When it does, the developer confirms the account before Claude Code saves the credential. After a confirmed sign-in, `/status` shows the account.
265265 
266266The confirmation requires Claude Code v2.1.275 or later on the developer machine; a client below that version ignores the field. The gateway server in the `claude` binary doesn't return the field, so its sign-ins complete without the confirmation.
267267 
268Once the developer signs in, the [model picker](/docs/en/model-config.md) shows the models in their `availableModels` allowlist. Managed settings apply at startup and refresh hourly, and telemetry routes to your collector.
268Once the developer signs in, the [model picker](https://code.claude.com/docs/en/model-config.md) shows the models in their `availableModels` allowlist. Managed settings apply at startup and refresh hourly, and telemetry routes to your collector.
269269 
270270Sessions refresh silently before `ttl_hours` expiry. When a refresh fails after IdP deprovisioning, Claude Code prompts the developer to log in again.
271271 
272272### Set the gateway URL
273273 
274Three keys go in the per-OS [managed settings file](/docs/en/managed-settings.md#delivery-mechanisms) you deploy via MDM or directly on disk. For a machine with no managed settings, see [Set the gateway URL in user settings](#set-the-gateway-url-in-user-settings) instead. `forceLoginMethod` and `forceLoginGatewayUrl` open `/login` directly on the **Cloud gateway** screen with the URL filled in, and `parentSettingsBehavior: "merge"` lets Claude Desktop deliver the gateway's egress allowlist to the Claude Code sessions it launches, explained in [Deliver policy to Claude Desktop sessions](#deliver-policy-to-claude-desktop-sessions):
274Three keys go in the per-OS [managed settings file](https://code.claude.com/docs/en/managed-settings.md#delivery-mechanisms) you deploy via MDM or directly on disk. For a machine with no managed settings, see [Set the gateway URL in user settings](#set-the-gateway-url-in-user-settings) instead. `forceLoginMethod` and `forceLoginGatewayUrl` open `/login` directly on the **Cloud gateway** screen with the URL filled in, and `parentSettingsBehavior: "merge"` lets Claude Desktop deliver the gateway's egress allowlist to the Claude Code sessions it launches, explained in [Deliver policy to Claude Desktop sessions](#deliver-policy-to-claude-desktop-sessions):
275275 
276276```json theme={null}
277277{
from line 281
281281}
282282```
283283 
284The developer presses Enter to connect. The [first-connect TLS fingerprint prompt](#connect-developers) still appears. Once the file is on a machine, a developer who hasn't completed the gateway sign-in sees one of the messages described under [Administrator policy requires a Cloud gateway sign-in](/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in). Developers who select a cloud provider through an environment variable such as `CLAUDE_CODE_USE_BEDROCK` don't need the gateway sign-in.
284The developer presses Enter to connect. The [first-connect TLS fingerprint prompt](#connect-developers) still appears. Once the file is on a machine, a developer who hasn't completed the gateway sign-in sees one of the messages described under [Administrator policy requires a Cloud gateway sign-in](https://code.claude.com/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in). Developers who select a cloud provider through an environment variable such as `CLAUDE_CODE_USE_BEDROCK` don't need the gateway sign-in.
285285 
286286The login picker has no gateway option, and in managed settings `forceLoginMethod` alone, without a URL, leaves the developer at a "Contact your IT administrator" message. The login keys belong in the file you push to machines, not in the gateway's `managed.policies[].cli` block, which only reaches clients that are already connected.
287287 
from line 299
299299When the developer runs `/login` at the Claude Code prompt, the **Cloud gateway** screen opens on that address and they press Enter to connect. The [first-connect TLS fingerprint prompt](#connect-developers) still appears. These limits apply to keys set this way:
300300 
301301* **User settings only**: Claude Code reads the two keys from `~/.claude/settings.json`, not from a project's `.claude/settings.json` or `.claude/settings.local.json`.
302* **Managed settings turn them off**: once an administrator's settings reach the machine through a managed settings file, a macOS plist or Windows HKLM policy, or a [policy helper](/docs/en/settings-reference.md#policyhelper), Claude Code ignores a gateway named in user settings.
302* **Managed settings turn them off**: once an administrator's settings reach the machine through a managed settings file, a macOS plist or Windows HKLM policy, or a [policy helper](https://code.claude.com/docs/en/settings-reference.md#policyhelper), Claude Code ignores a gateway named in user settings.
303303 
304304### Allow a gateway on public address space you own
305305 
from line 309
309309>
310310> `gatewayInternalNetworks` is for internal networks that happen to be numbered from public address space. It doesn't make it safe to expose a gateway to the internet: a trusted gateway can push settings that run commands on developer machines.
311311>
312> Keep the gateway unreachable from outside your network with your firewall or load balancer rules. Set the gateway's [`access_control.allow_cidrs`](/docs/en/claude-apps-gateway-config#http-tuning) to the same blocks you declare here, so the gateway itself refuses clients from anywhere else. Behind a load balancer or ingress, set `listen.trusted_proxies` to that front end as well, because the gateway otherwise matches `allow_cidrs` against the front end's own address rather than the developer's.
312> Keep the gateway unreachable from outside your network with your firewall or load balancer rules. Set the gateway's [`access_control.allow_cidrs`](https://code.claude.com/docs/en/claude-apps-gateway-config#http-tuning) to the same blocks you declare here, so the gateway itself refuses clients from anywhere else. Behind a load balancer or ingress, set `listen.trusted_proxies` to that front end as well, because the gateway otherwise matches `allow_cidrs` against the front end's own address rather than the developer's.
313313 
314314Add the key to the same managed settings source as the login keys: the managed settings file, MDM profile, or registry policy. Claude Code ignores it in user, project, and server-managed settings.
315315 
from line 330
330330 
331331Blocks from `managed-settings.json` and its `managed-settings.d/` drop-in files combine into one list, and these limits apply to the combined list. To narrow a block, replace its entry rather than add a second, overlapping one in a drop-in; `/login` refuses the overlap.
332332 
333If an entry breaks a rule, or the value isn't a list of strings, Claude Code refuses every new gateway sign-in on that machine and names the problem in the message. Sign-in to a gateway on a private address fails too, and existing sign-ins keep working. Try the value on one machine before you deploy it. Claude Code also lists a wrongly typed value among the [invalid managed settings it reports](/docs/en/managed-settings.md#keys-that-fail-closed).
333If an entry breaks a rule, or the value isn't a list of strings, Claude Code refuses every new gateway sign-in on that machine and names the problem in the message. Sign-in to a gateway on a private address fails too, and existing sign-ins keep working. Try the value on one machine before you deploy it. Claude Code also lists a wrongly typed value among the [invalid managed settings it reports](https://code.claude.com/docs/en/managed-settings.md#keys-that-fail-closed).
334334 
335335With a valid list, `/login` applies three checks to a gateway whose address is inside a listed block:
336336 
from line 346
346346 
347347### Deliver policy to Claude Desktop sessions
348348 
349Claude Desktop runs its Cowork and Code tabs, plus the Chat tab when you enable it, on embedded Claude Code sessions and sends their model requests through the gateway. It passes policy to each of those sessions, built from the configuration the gateway serves it at `/user/bootstrap`: the model allowlist, disabled tools, and egress allowlist derived from the matched policy's `cli` or `code` block, plus the [`desktop` overlay](/docs/en/claude-apps-gateway-config#claude-desktop-overlay).
349Claude Desktop runs its Cowork and Code tabs, plus the Chat tab when you enable it, on embedded Claude Code sessions and sends their model requests through the gateway. It passes policy to each of those sessions, built from the configuration the gateway serves it at `/user/bootstrap`: the model allowlist, disabled tools, and egress allowlist derived from the matched policy's `cli` or `code` block, plus the [`desktop` overlay](https://code.claude.com/docs/en/claude-apps-gateway-config#claude-desktop-overlay).
350350 
351The block's other keys, such as hooks, `env`, and scoped permission rules like `Bash(npm *)`, reach clients that sign in through `/login`. Under `code`, they also reach the Code tab's session when the [conditions for the Code tab](/docs/en/claude-apps-gateway-config.md#apply-code-settings-in-the-code-tab) hold. They don't reach Cowork or Chat sessions. Claude Desktop reads the gateway URL from its own managed configuration and signs in with its own flow, separate from the `forceLoginMethod` and `forceLoginGatewayUrl` keys in [Set the gateway URL](#set-the-gateway-url).
351The block's other keys, such as hooks, `env`, and scoped permission rules like `Bash(npm *)`, reach clients that sign in through `/login`. Under `code`, they also reach the Code tab's session when the [conditions for the Code tab](https://code.claude.com/docs/en/claude-apps-gateway-config.md#apply-code-settings-in-the-code-tab) hold. They don't reach Cowork or Chat sessions. Claude Desktop reads the gateway URL from its own managed configuration and signs in with its own flow, separate from the `forceLoginMethod` and `forceLoginGatewayUrl` keys in [Set the gateway URL](#set-the-gateway-url).
352352 
353Settings passed by a launching process are parent settings. Claude Code ignores parent settings on any machine that has an admin-deployed managed source, unless the [source that delivers the policy](/docs/en/managed-settings.md#which-managed-source-claude-code-uses) sets `parentSettingsBehavior: "merge"`.
353Settings passed by a launching process are parent settings. Claude Code ignores parent settings on any machine that has an admin-deployed managed source, unless the [source that delivers the policy](https://code.claude.com/docs/en/managed-settings.md#which-managed-source-claude-code-uses) sets `parentSettingsBehavior: "merge"`.
354354 
355355#### Which machines need the opt-in
356356 
from line 360
360360 
361361Machines where developers sign in through `/login` don't need it; each Claude Code session fetches its policy from the gateway.
362362 
363Fleets whose [`policyHelper`](/docs/en/settings-reference#policyhelper) supplies managed settings can't use it: Claude Code never merges parent settings on those fleets, because it reads managed settings from the helper's output alone.
363Fleets whose [`policyHelper`](https://code.claude.com/docs/en/settings-reference#policyhelper) supplies managed settings can't use it: Claude Code never merges parent settings on those fleets, because it reads managed settings from the helper's output alone.
364364 
365365#### Set the opt-in
366366 
from line 372
372372 
373373**2. Mirror the snippet to any source that outranks the file**
374374 
375Claude Code reads `parentSettingsBehavior` only from the [selected source](/docs/en/managed-settings.md#which-managed-source-claude-code-uses). Adding any policy key to a source can make that source the selected one, so in a client-side source, mirror the whole snippet rather than `parentSettingsBehavior` alone. [Client-side managed settings](/docs/en/claude-apps-gateway-config.md#client-side-managed-settings) covers fleets that deliver policy through Group Policy or configuration profiles. A managed-preferences plist on macOS or an HKLM policy on Windows outranks the `managed-settings.json` file, and the gateway's own remote managed settings outrank both, so on machines that sign in to the gateway, also set `parentSettingsBehavior` in the gateway policy's [`cli` or `code` block](/docs/en/claude-apps-gateway-config#managed).
375Claude Code reads `parentSettingsBehavior` only from the [selected source](https://code.claude.com/docs/en/managed-settings.md#which-managed-source-claude-code-uses). Adding any policy key to a source can make that source the selected one, so in a client-side source, mirror the whole snippet rather than `parentSettingsBehavior` alone. [Client-side managed settings](https://code.claude.com/docs/en/claude-apps-gateway-config.md#client-side-managed-settings) covers fleets that deliver policy through Group Policy or configuration profiles. A managed-preferences plist on macOS or an HKLM policy on Windows outranks the `managed-settings.json` file, and the gateway's own remote managed settings outrank both, so on machines that sign in to the gateway, also set `parentSettingsBehavior` in the gateway policy's [`cli` or `code` block](https://code.claude.com/docs/en/claude-apps-gateway-config#managed).
376376 
377377**3. Check which source is selected**
378378 
379On a machine that only runs Claude Desktop, call the Agent SDK's [`resolveSettings()`](/docs/en/agent-sdk/typescript#resolvesettings) and read `policyOrigin` on the `managed` entry in its `sources` list. The value names the selected client-side source, `plist`, `hklm`, or `file`, which is the source that must carry the snippet.
379On a machine that only runs Claude Desktop, call the Agent SDK's [`resolveSettings()`](https://code.claude.com/docs/en/agent-sdk/typescript#resolvesettings) and read `policyOrigin` on the `managed` entry in its `sources` list. The value names the selected client-side source, `plist`, `hklm`, or `file`, which is the source that must carry the snippet.
380380 
381381Cowork and Chat sessions don't fetch the gateway policy, so the gateway's block isn't the selected source for them.
382382 
383A Code tab session fetches it when the policy's settings are under `code` and the [conditions for the Code tab](/docs/en/claude-apps-gateway-config.md#apply-code-settings-in-the-code-tab) hold. The gateway's `code` settings are then the selected source for that session.
383A Code tab session fetches it when the policy's settings are under `code` and the [conditions for the Code tab](https://code.claude.com/docs/en/claude-apps-gateway-config.md#apply-code-settings-in-the-code-tab) hold. The gateway's `code` settings are then the selected source for that session.
384384 
385385### Restrict parent settings
386386 
387387Once you deploy `parentSettingsBehavior: "merge"`, any host process that launches Claude Code can supply parent settings, not only Claude Desktop but also an Agent SDK application or an IDE extension.
388388 
389Claude Code filters parent settings against an allowlist of restrictive keys, but some allowed keys can grant access rather than restrict it. Unless you set the `allowManaged*Only` locks, permission allow rules and sandbox allowlists supplied by the host still apply. Your policy's deny and ask rules stay in force either way; [they're evaluated before any allow rule](/docs/en/permissions.md#manage-permissions).
389Claude Code filters parent settings against an allowlist of restrictive keys, but some allowed keys can grant access rather than restrict it. Unless you set the `allowManaged*Only` locks, permission allow rules and sandbox allowlists supplied by the host still apply. Your policy's deny and ask rules stay in force either way; [they're evaluated before any allow rule](https://code.claude.com/docs/en/permissions.md#manage-permissions).
390390 
391Claude Code forwards parent-supplied [`sandbox.credentials`](/docs/en/settings-reference#sandbox-credentials) entries in stripped form:
391Claude Code forwards parent-supplied [`sandbox.credentials`](https://code.claude.com/docs/en/settings-reference#sandbox-credentials) entries in stripped form:
392392 
393393* **`deny` entries**: forwarded with only their `path` or `name` and the mode.
394* **File entries with [`mode: mask`](/docs/en/sandboxing#mask-credential-files)**: forwarded sentinel-only, as a whole-file mask whose `injectHosts` is the empty list, so the proxy never substitutes the real value for a parent-supplied entry on any platform. All structured-masking fields are dropped too, so a parent-supplied extract pattern can't displace a stricter mask another source sets for the same path.
394* **File entries with [`mode: mask`](https://code.claude.com/docs/en/sandboxing#mask-credential-files)**: forwarded sentinel-only, as a whole-file mask whose `injectHosts` is the empty list, so the proxy never substitutes the real value for a parent-supplied entry on any platform. All structured-masking fields are dropped too, so a parent-supplied extract pattern can't displace a stricter mask another source sets for the same path.
395395* **`envVars` entries with `mode: mask`**: not forwarded. `deny` is the only restriction the parent channel can express through `envVars` entries.
396* **[`awsPairs` and `sigv4`](/docs/en/sandboxing#re-sign-aws-requests)**: forwarded restriction-only. From `sigv4`, only `deny` values are kept, and a parent that defines a `sigv4` block at all pins all three request forms, `streaming`, `presigned`, and `sigv4a`, to `deny`. An `awsPairs` pair is never forwarded in a form that can re-sign; a pair that names one of the conventional AWS variables is replaced by an inert entry that keeps the automatic pairing of `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN` suppressed.
396* **[`awsPairs` and `sigv4`](https://code.claude.com/docs/en/sandboxing#re-sign-aws-requests)**: forwarded restriction-only. From `sigv4`, only `deny` values are kept, and a parent that defines a `sigv4` block at all pins all three request forms, `streaming`, `presigned`, and `sigv4a`, to `deny`. An `awsPairs` pair is never forwarded in a form that can re-sign; a pair that names one of the conventional AWS variables is replaced by an inert entry that keeps the automatic pairing of `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN` suppressed.
397397 
398398#### Deploy the locks
399399 
from line 422
422422}
423423```
424424 
425An OS policy, such as an HKLM registry policy or a managed-preferences plist, outranks this file, so deliver the whole snippet through it instead of the file. The gateway's remote managed settings outrank the OS policy and file sources but reach only connected clients. Mirror the locks, the allowlists, and the merge opt-in into the policy's [`cli` or `code` block](/docs/en/claude-apps-gateway-config#managed) and keep this file deployed, because machines that never connect get their policy from the file alone.
425An OS policy, such as an HKLM registry policy or a managed-preferences plist, outranks this file, so deliver the whole snippet through it instead of the file. The gateway's remote managed settings outrank the OS policy and file sources but reach only connected clients. Mirror the locks, the allowlists, and the merge opt-in into the policy's [`cli` or `code` block](https://code.claude.com/docs/en/claude-apps-gateway-config#managed) and keep this file deployed, because machines that never connect get their policy from the file alone.
426426 
427427#### Lock behavior across sources
428428 
429Setting one lock doesn't restrict the others; each key is documented in the [settings reference](/docs/en/settings-reference.md#all-settings).
429Setting one lock doesn't restrict the others; each key is documented in the [settings reference](https://code.claude.com/docs/en/settings-reference.md#all-settings).
430430 
431431From an admin source below the winner, the two sandbox locks still apply, and `allowManagedPermissionRulesOnly` still blocks parent-supplied allow rules and `additionalDirectories`. On Claude Code v2.1.273 or later, the MCP server lock also applies from a source below the winner, and while it is on, the managed `allowedMcpServers` list comes from the highest-priority admin source that sets one.
432432 
433The hooks lock and `allowManagedPermissionRulesOnly`'s effect on the developer's own rules need the winning source by default; under the `managedSourcesBehavior` merge opt-in in [how Claude Code combines managed sources](/docs/en/managed-settings.md#how-claude-code-combines-managed-sources), Claude Code applies the strictest value any source sets for every lock. On [`policyHelper`](/docs/en/settings-reference#policyhelper) fleets, Claude Code reads the locks from the helper's output alone.
433The hooks lock and `allowManagedPermissionRulesOnly`'s effect on the developer's own rules need the winning source by default; under the `managedSourcesBehavior` merge opt-in in [how Claude Code combines managed sources](https://code.claude.com/docs/en/managed-settings.md#how-claude-code-combines-managed-sources), Claude Code applies the strictest value any source sets for every lock. On [`policyHelper`](https://code.claude.com/docs/en/settings-reference#policyhelper) fleets, Claude Code reads the locks from the helper's output alone.
434434 
435435Each lock makes Claude Code ignore the developer's own entries for that setting, so include your organization's allowlists next to the locks:
436436 
from line 450
450450* **`blockedMarketplaces`**: a parent-supplied marketplace blocklist passes and adds to any blocklist that a managed source sets, since a blocklist can only restrict further. Requires Claude Code v2.1.282 or later.
451451* **`strictPluginOnlyCustomization`**: this key passes the filter regardless of any lock, and it makes Claude Code ignore the developer's own customization, including protective hooks. No lock blocks it.
452452 
453Under the default first-wins setting, an admin value blocks the parent's only when it sits in the highest-priority admin source, except for `allowedMcpServers` while the [MCP server lock](#lock-behavior-across-sources) is on. Under the `managedSourcesBehavior` merge opt-in, [how Claude Code combines managed sources](/docs/en/managed-settings.md#how-claude-code-combines-managed-sources) says which source's value applies instead.
453Under the default first-wins setting, an admin value blocks the parent's only when it sits in the highest-priority admin source, except for `allowedMcpServers` while the [MCP server lock](#lock-behavior-across-sources) is on. Under the `managedSourcesBehavior` merge opt-in, [how Claude Code combines managed sources](https://code.claude.com/docs/en/managed-settings.md#how-claude-code-combines-managed-sources) says which source's value applies instead.
454454 
455455#### How hook and skill keys in parent settings take effect
456456 
457If you pass `disableAllHooks: true` as a parent setting through the Agent SDK's `managedSettings` option, not every hook stops. Your [SDK hook callbacks](/docs/en/agent-sdk/hooks.md) still run, and so do the administrator's hooks, which your application can't switch off.
457If you pass `disableAllHooks: true` as a parent setting through the Agent SDK's `managedSettings` option, not every hook stops. Your [SDK hook callbacks](https://code.claude.com/docs/en/agent-sdk/hooks.md) still run, and so do the administrator's hooks, which your application can't switch off.
458458 
459On a machine where an administrator deploys managed settings, Claude Code ignores parent settings unless the administrator [lets an embedding host add policy](/docs/en/managed-settings.md#let-an-embedding-host-add-policy).
459On a machine where an administrator deploys managed settings, Claude Code ignores parent settings unless the administrator [lets an embedding host add policy](https://code.claude.com/docs/en/managed-settings.md#let-an-embedding-host-add-policy).
460460 
461461| What you pass | What happens |
462462| :- | :- |
463| `disableAllHooks: true` | Treated as `allowManagedHooksOnly: true`, so the hooks listed as [blocked under `allowManagedHooksOnly`](/docs/en/settings-reference#what-runs-under-allowmanagedhooksonly) stop, and so do hooks in the SDK's [`settings` option](/docs/en/agent-sdk/typescript#options). |
464| [`disableSkillShellExecution: true`](/docs/en/settings-reference#disableskillshellexecution) | Takes effect. |
463| `disableAllHooks: true` | Treated as `allowManagedHooksOnly: true`, so the hooks listed as [blocked under `allowManagedHooksOnly`](https://code.claude.com/docs/en/settings-reference#what-runs-under-allowmanagedhooksonly) stop, and so do hooks in the SDK's [`settings` option](https://code.claude.com/docs/en/agent-sdk/typescript#options). |
464| [`disableSkillShellExecution: true`](https://code.claude.com/docs/en/settings-reference#disableskillshellexecution) | Takes effect. |
465465| `allowedHttpHookUrls: []` | Takes effect unless the administrator defines `hooks` or enables a plugin. No HTTP hook runs, except for URLs another settings source lists. |
466466| `httpHookAllowedEnvVars: []` | Takes effect unless the administrator defines `hooks` or enables a plugin. HTTP hook headers can include only environment variables another settings source lists. |
467467| `allowedHttpHookUrls` or `httpHookAllowedEnvVars` with entries | Claude Code ignores it, since merging would widen an administrator's list. Use the SDK `settings` option instead. |
from line 470
470470 
471471### Connect Claude Desktop
472472 
473[Claude Desktop](/docs/en/desktop.md) connects to the same gateway through a different MDM key: set `bootstrapUrl` in Claude Desktop's [managed configuration](https://claude.com/docs/third-party/claude-desktop/configuration) to `<listen.public_url>/user/bootstrap`, and opt the user's policy in with a `desktop` key. [Claude Desktop overlay](/docs/en/claude-apps-gateway-config.md#claude-desktop-overlay) covers both halves. Requires Claude Code v2.1.203 or later on the gateway server.
473[Claude Desktop](https://code.claude.com/docs/en/desktop.md) connects to the same gateway through a different MDM key: set `bootstrapUrl` in Claude Desktop's [managed configuration](https://claude.com/docs/third-party/claude-desktop/configuration) to `<listen.public_url>/user/bootstrap`, and opt the user's policy in with a `desktop` key. [Claude Desktop overlay](https://code.claude.com/docs/en/claude-apps-gateway-config.md#claude-desktop-overlay) covers both halves. Requires Claude Code v2.1.203 or later on the gateway server.
474474 
475475Claude Desktop signs the developer in through the gateway's identity provider with the same browser SSO step, then fetches its configuration from the gateway instead of from Anthropic. Model access and policy follow the same per-group rules as the CLI. A developer who uses both the CLI and Claude Desktop signs in to each separately; the gateway session isn't shared between them.
476476 
477Once connected, Claude Desktop sends model requests from every enabled tab through the gateway. It shows the Cowork and Code tabs by default. To turn on the Chat tab as well, set `chatTabEnabled` to `true` in Claude Desktop's [managed configuration](https://claude.com/docs/third-party/claude-desktop/configuration), or in the policy's [`desktop` block](/docs/en/claude-apps-gateway-config#claude-desktop-overlay) on a gateway running Claude Code v2.1.227 or later.
477Once connected, Claude Desktop sends model requests from every enabled tab through the gateway. It shows the Cowork and Code tabs by default. To turn on the Chat tab as well, set `chatTabEnabled` to `true` in Claude Desktop's [managed configuration](https://claude.com/docs/third-party/claude-desktop/configuration), or in the policy's [`desktop` block](https://code.claude.com/docs/en/claude-apps-gateway-config#claude-desktop-overlay) on a gateway running Claude Code v2.1.227 or later.
478478 
479479### CI pipelines and remote machines
480480 
481There is no service-token flow for unattended pipelines. Gateway sign-in always runs the browser device flow, so a CI job with no developer to approve the sign-in can't authenticate; configure those against your provider directly. Deploy `forceLoginMethod` and `forceLoginGatewayUrl` to developer machines and leave them off CI runners. On a machine whose managed settings set them, a session that authenticates with `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` [exits at startup](/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in).
481There is no service-token flow for unattended pipelines. Gateway sign-in always runs the browser device flow, so a CI job with no developer to approve the sign-in can't authenticate; configure those against your provider directly. Deploy `forceLoginMethod` and `forceLoginGatewayUrl` to developer machines and leave them off CI runners. On a machine whose managed settings set them, a session that authenticates with `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` [exits at startup](https://code.claude.com/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in).
482482 
483Once a developer has signed in, each Claude Code session on that machine uses the gateway session, including non-interactive `claude -p` runs and sessions started by the Agent SDK. Claude Code applies the [gateway policy](/docs/en/claude-apps-gateway-config.md#managed) to each of them.
483Once a developer has signed in, each Claude Code session on that machine uses the gateway session, including non-interactive `claude -p` runs and sessions started by the Agent SDK. Claude Code applies the [gateway policy](https://code.claude.com/docs/en/claude-apps-gateway-config.md#managed) to each of them.
484484 
485485The device flow separates the polling CLI from the approving browser, so a remote development box with no display still works: the developer runs `/login` over SSH on the remote machine and opens the verification link in the browser on their laptop.
486486 
from line 488
488488 
489489These guarantees apply to every session signed in through `/login`. The embedded sessions Claude Desktop launches get their policy as described in [Deliver policy to Claude Desktop sessions](#deliver-policy-to-claude-desktop-sessions), and the telemetry bullet says where their exports go.
490490 
491* **Model access**: requests for models the policy doesn't grant return 400, and the `/model` picker is filtered to the policy's `availableModels` allowlist. This includes the model a session starts on before the developer picks one; see [Start sessions on a model the policy allows](/docs/en/claude-apps-gateway-config.md#start-sessions-on-a-model-the-policy-allows).
492* **Telemetry destination**: in sessions signed in through `/login`, the CLI sends its OTLP/HTTP exports to the gateway rather than to a locally set `OTEL_EXPORTER_OTLP_ENDPOINT`, unless a policy [names your collector as the endpoint](/docs/en/claude-apps-gateway-config.md#export-directly-to-your-collector). The gateway relays the exports it receives to the destinations in [`telemetry.forward_to`](/docs/en/claude-apps-gateway-config#telemetry).
491* **Model access**: requests for models the policy doesn't grant return 400, and the `/model` picker is filtered to the policy's `availableModels` allowlist. This includes the model a session starts on before the developer picks one; see [Start sessions on a model the policy allows](https://code.claude.com/docs/en/claude-apps-gateway-config.md#start-sessions-on-a-model-the-policy-allows).
492* **Telemetry destination**: in sessions signed in through `/login`, the CLI sends its OTLP/HTTP exports to the gateway rather than to a locally set `OTEL_EXPORTER_OTLP_ENDPOINT`, unless a policy [names your collector as the endpoint](https://code.claude.com/docs/en/claude-apps-gateway-config.md#export-directly-to-your-collector). The gateway relays the exports it receives to the destinations in [`telemetry.forward_to`](https://code.claude.com/docs/en/claude-apps-gateway-config#telemetry).
493493 * In the embedded sessions [Claude Desktop launches](#connect-claude-desktop), the CLI sends its exports to the configured `OTEL_EXPORTER_OTLP_ENDPOINT`. The CLI attaches the gateway session token to those exports only when that endpoint points at the gateway itself.
494494 * With no destination configured for a signal, the gateway accepts and discards it.
495495 * If you already collect Claude Code telemetry directly, add your collector as a `forward_to` destination, or name it in a policy to skip the relay.
496* **Credentials**: the gateway token is the session's only credential. [Anthropic profiles](/docs/en/authentication.md#anthropic-profiles-and-federation-credentials) and any earlier claude.ai login are ignored while signed in, so developers don't need to log out of claude.ai first. For a configured `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` credential, or an API key saved by an earlier Claude Console login, see [Administrator policy requires a Cloud gateway sign-in](/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in).
497* **Managed settings**: locked keys can't be overridden locally. The CLI applies the policy at startup and applies changes on each hourly poll, apart from the [changes that apply only at the next launch](/docs/en/server-managed-settings.md#fetch-and-caching-behavior).
496* **Credentials**: the gateway token is the session's only credential. [Anthropic profiles](https://code.claude.com/docs/en/authentication.md#anthropic-profiles-and-federation-credentials) and any earlier claude.ai login are ignored while signed in, so developers don't need to log out of claude.ai first. For a configured `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` credential, or an API key saved by an earlier Claude Console login, see [Administrator policy requires a Cloud gateway sign-in](https://code.claude.com/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in).
497* **Managed settings**: locked keys can't be overridden locally. The CLI applies the policy at startup and applies changes on each hourly poll, apart from the [changes that apply only at the next launch](https://code.claude.com/docs/en/server-managed-settings.md#fetch-and-caching-behavior).
498498* **Startup with the gateway unreachable**: signed-in sessions exit at startup with an error after about 10 seconds rather than starting without their settings.
499* **Startup after the gateway ends the session**: see [Enforce fail-closed startup](/docs/en/server-managed-settings.md#enforce-fail-closed-startup) for the launches that open signed out of the gateway and the ones that exit when the gateway answers with a `401`.
499* **Startup after the gateway ends the session**: see [Enforce fail-closed startup](https://code.claude.com/docs/en/server-managed-settings.md#enforce-fail-closed-startup) for the launches that open signed out of the gateway and the ones that exit when the gateway answers with a `401`.
500500* **Deprovisioning**: a session whose user is disabled in the IdP expires within `ttl_hours` when the next refresh fails.
501501* **Sign-out**: `/logout` deletes the gateway credential from the developer's machine.
502502 * When the gateway's discovery document advertises a `revocation_endpoint` on the gateway URL's own scheme, host, and port, `/logout` also sends the stored tokens to that endpoint so the gateway can end the session on its side. The request is best effort, so sign-out completes on the developer's machine whether or not the endpoint answers. The revocation requires Claude Code v2.1.275 or later on the developer's machine.
503 * The gateway server in the `claude` binary advertises none, so a sign-out from it ends the session on the developer's machine only. To force sessions out server-side, see [JWT secret rotation](/docs/en/claude-apps-gateway-deploy.md#jwt-secret-rotation).
503 * The gateway server in the `claude` binary advertises none, so a sign-out from it ends the session on the developer's machine only. To force sessions out server-side, see [JWT secret rotation](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#jwt-secret-rotation).
504504 
505505### What the organization can see
506506 
507Usage telemetry carries the developer's identity, token counts, model, and latency to the organization's collector. The gateway doesn't log or store prompt or completion content. Whether richer telemetry such as logs and traces is collected, which can include commands and file paths, is the organization's [per-destination choice](/docs/en/claude-apps-gateway-config.md#telemetry).
507Usage telemetry carries the developer's identity, token counts, model, and latency to the organization's collector. The gateway doesn't log or store prompt or completion content. Whether richer telemetry such as logs and traces is collected, which can include commands and file paths, is the organization's [per-destination choice](https://code.claude.com/docs/en/claude-apps-gateway-config.md#telemetry).
508508 
509509## Availability and limitations
510510 
from line 514
514514 
515515| Feature | Status | Notes |
516516| - | - | - |
517| Inference forwarding (Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform, Microsoft Foundry, Anthropic) | Available | With per-upstream model translation and failover. The Amazon Bedrock upstream uses the `bedrock-runtime` endpoint and the AWS default credential chain. The [Amazon Bedrock Mantle upstream](/docs/en/claude-apps-gateway-config.md#amazon-bedrock-mantle-endpoint) requires Claude Code v2.1.283 or later on the gateway server, and the [Claude Platform on AWS upstream](/docs/en/claude-apps-gateway-config.md#claude-platform-on-aws) requires v2.1.198 or later. |
518| 1M token context window | Available | Fable models, Sonnet 5 and later, and Opus 4.7 and later run with the 1M window by default; see [Extended context](/docs/en/model-config.md#extended-context). The 1M default for the Fable and Opus models requires Claude Code v2.1.287 or later on the developer machine |
519| Model access and managed settings by IdP group | Available | Model access is enforced server-side; managed settings are delivered per IdP group and applied by the CLI at the [managed settings tier](/docs/en/settings.md#settings-precedence) |
520| Claude Desktop | Available with opt-in | The gateway serves Claude Desktop's configuration at `/user/bootstrap` once a policy [opts in with a `desktop` key](/docs/en/claude-apps-gateway-config#claude-desktop-overlay), and Claude Desktop sends model requests from its Cowork and Code tabs, and from the Chat tab when you enable it, through the gateway. To turn on the Chat tab, see [Connect Claude Desktop](#connect-claude-desktop). Requires Claude Code v2.1.203 or later on the gateway server. |
517| Inference forwarding (Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform, Microsoft Foundry, Anthropic) | Available | With per-upstream model translation and failover. The Amazon Bedrock upstream uses the `bedrock-runtime` endpoint and the AWS default credential chain. The [Amazon Bedrock Mantle upstream](https://code.claude.com/docs/en/claude-apps-gateway-config.md#amazon-bedrock-mantle-endpoint) requires Claude Code v2.1.283 or later on the gateway server, and the [Claude Platform on AWS upstream](https://code.claude.com/docs/en/claude-apps-gateway-config.md#claude-platform-on-aws) requires v2.1.198 or later. |
518| 1M token context window | Available | Fable models, Sonnet 5 and later, and Opus 4.7 and later run with the 1M window by default; see [Extended context](https://code.claude.com/docs/en/model-config.md#extended-context). The 1M default for the Fable and Opus models requires Claude Code v2.1.287 or later on the developer machine |
519| Model access and managed settings by IdP group | Available | Model access is enforced server-side; managed settings are delivered per IdP group and applied by the CLI at the [managed settings tier](https://code.claude.com/docs/en/settings.md#settings-precedence) |
520| Claude Desktop | Available with opt-in | The gateway serves Claude Desktop's configuration at `/user/bootstrap` once a policy [opts in with a `desktop` key](https://code.claude.com/docs/en/claude-apps-gateway-config#claude-desktop-overlay), and Claude Desktop sends model requests from its Cowork and Code tabs, and from the Chat tab when you enable it, through the gateway. To turn on the Chat tab, see [Connect Claude Desktop](#connect-claude-desktop). Requires Claude Code v2.1.203 or later on the gateway server. |
521521| Telemetry fan-out (OTLP/HTTP) | Available | Identity-stamped per export; both protobuf and JSON encodings |
522| OIDC identity providers | Available | Any OIDC-compliant IdP; the gateway runs standard OIDC discovery and the authorization-code flow. See [Identity provider setup](/docs/en/claude-apps-gateway-deploy.md#identity-provider-setup) for per-IdP configuration |
523| Per-user and per-group spend limits | Available | See [Spend limits](/docs/en/claude-apps-gateway-spend-limits.md) |
522| OIDC identity providers | Available | Any OIDC-compliant IdP; the gateway runs standard OIDC discovery and the authorization-code flow. See [Identity provider setup](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#identity-provider-setup) for per-IdP configuration |
523| Per-user and per-group spend limits | Available | See [Spend limits](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md) |
524524| Server-side web search | Not available | The CLI can't see which upstream provider the gateway routes to, so it can't verify web search support and disables WebSearch on gateway sessions |
525| [Remote Control](/docs/en/remote-control.md) | Not available | The CLI shows [an error naming the gateway](/docs/en/errors.md#remote-control-requires-the-anthropic-api) |
526| [`/design-sync`](/docs/en/commands#all-commands) and `/design-login` | Not available | Both need claude.ai, which the CLI doesn't contact on gateway sessions, so neither command appears there |
527| Features that need feature-flag fetching, such as `/import` and `claude import` | Not available | The CLI skips the flag fetch on gateway sessions. [Features that need feature-flag fetching](/docs/en/env-vars.md#features-that-need-feature-flag-fetching) lists what that turns off |
528| Standard prompt caching | Available | The gateway forwards `cache_control` breakpoints to every upstream. [Where the cache lives](/docs/en/prompt-caching.md#where-the-cache-lives) covers which blocks the CLI marks, including the system context it appends mid-conversation |
529| 1-hour cache TTL | Available with opt-in | The CLI uses the 5-minute TTL on gateway sessions by default. To request the 1-hour TTL, set it [in a policy](/docs/en/claude-apps-gateway-config.md#one-hour-prompt-cache). Set it only if your upstreams offer the 1-hour TTL for every model the gateway serves, because the request fails if an upstream rejects the TTL |
530| Auto mode | Available | Follows the [third-party provider rules](/docs/en/permission-modes.md#enable-auto-mode-on-bedrock-agent-platform-or-foundry): only the models eligible on third-party providers can use it. Before v2.1.207, auto mode on gateway sessions required setting `CLAUDE_CODE_ENABLE_AUTO_MODE=1`, deliverable through the managed policy `env` block |
525| [Remote Control](https://code.claude.com/docs/en/remote-control.md) | Not available | The CLI shows [an error naming the gateway](https://code.claude.com/docs/en/errors.md#remote-control-requires-the-anthropic-api) |
526| [`/design-sync`](https://code.claude.com/docs/en/commands#all-commands) and `/design-login` | Not available | Both need claude.ai, which the CLI doesn't contact on gateway sessions, so neither command appears there |
527| Features that need feature-flag fetching, such as `/import` and `claude import` | Not available | The CLI skips the flag fetch on gateway sessions. [Features that need feature-flag fetching](https://code.claude.com/docs/en/env-vars.md#features-that-need-feature-flag-fetching) lists what that turns off |
528| Standard prompt caching | Available | The gateway forwards `cache_control` breakpoints to every upstream. [Where the cache lives](https://code.claude.com/docs/en/prompt-caching.md#where-the-cache-lives) covers which blocks the CLI marks, including the system context it appends mid-conversation |
529| 1-hour cache TTL | Available with opt-in | The CLI uses the 5-minute TTL on gateway sessions by default. To request the 1-hour TTL, set it [in a policy](https://code.claude.com/docs/en/claude-apps-gateway-config.md#one-hour-prompt-cache). Set it only if your upstreams offer the 1-hour TTL for every model the gateway serves, because the request fails if an upstream rejects the TTL |
530| Auto mode | Available | Follows the [third-party provider rules](https://code.claude.com/docs/en/permission-modes.md#enable-auto-mode-on-bedrock-agent-platform-or-foundry): only the models eligible on third-party providers can use it. Before v2.1.207, auto mode on gateway sessions required setting `CLAUDE_CODE_ENABLE_AUTO_MODE=1`, deliverable through the managed policy `env` block |
531531| First-party-only optimizations such as global cache scope and token-efficient tools | Not available | The CLI doesn't enable them on gateway sessions; see the beta-header note above |
532532| OTLP/gRPC | Not supported | OTLP over HTTP only |
533533| SAML, LDAP, and other non-OIDC auth | Not supported | OIDC only. Front with an OIDC bridge if needed |
534534| Multi-tenant (multiple OIDC issuers) | Not supported | One issuer per gateway. Run separate instances |
535535| Windows server | Not supported | Deploy on Linux. macOS for local development only |
536| Helm chart | Not available | The gateway runs as a standard stateless Deployment; see the [deployment guide](/docs/en/claude-apps-gateway-deploy.md#kubernetes) |
536| Helm chart | Not available | The gateway runs as a standard stateless Deployment; see the [deployment guide](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#kubernetes) |
537537| Admin UI | Not available | Configuration is the YAML file; redeploy to change it |
538538 
539539## Next steps
from line 540
540540 
541541The quickstart leaves you with a minimal config running under Docker Compose. To take it further:
542542 
543* Expand `gateway.yaml` beyond the minimal config, for example to add per-group RBAC, multi-upstream failover, or telemetry destinations. The [configuration reference](/docs/en/claude-apps-gateway-config.md) covers every option.
544* Move from Compose to a production deployment on Kubernetes or Cloud Run, set up your IdP properly, and review the security model. The [deployment and operations guide](/docs/en/claude-apps-gateway-deploy.md) covers per-IdP setup, container image requirements, health probes, and troubleshooting.
545* Put spend caps on individual developers or groups so a runaway workload can't consume your whole commitment. [Spend limits](/docs/en/claude-apps-gateway-spend-limits.md) covers the admin API and how enforcement works.
546* For a complete worked example on AWS, with ECS Fargate or EKS, Amazon RDS, and Secrets Manager, see [Deploy on AWS](/docs/en/claude-apps-gateway-on-aws.md).
547* For a complete worked example on Google Cloud, with Cloud Run, Cloud SQL, and Secret Manager, see [Deploy on Google Cloud](/docs/en/claude-apps-gateway-on-gcp.md).
543* Expand `gateway.yaml` beyond the minimal config, for example to add per-group RBAC, multi-upstream failover, or telemetry destinations. The [configuration reference](https://code.claude.com/docs/en/claude-apps-gateway-config.md) covers every option.
544* Move from Compose to a production deployment on Kubernetes or Cloud Run, set up your IdP properly, and review the security model. The [deployment and operations guide](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md) covers per-IdP setup, container image requirements, health probes, and troubleshooting.
545* Put spend caps on individual developers or groups so a runaway workload can't consume your whole commitment. [Spend limits](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md) covers the admin API and how enforcement works.
546* For a complete worked example on AWS, with ECS Fargate or EKS, Amazon RDS, and Secrets Manager, see [Deploy on AWS](https://code.claude.com/docs/en/claude-apps-gateway-on-aws.md).
547* For a complete worked example on Google Cloud, with Cloud Run, Cloud SQL, and Secret Manager, see [Deploy on Google Cloud](https://code.claude.com/docs/en/claude-apps-gateway-on-gcp.md).
548548 

claude-apps-gateway-config Changed · +94 / -94 lines

from line 4
44 
55A Claude apps gateway deployment is configured by one YAML file, conventionally `gateway.yaml`. The file defines everything the gateway does: where it listens, how developers sign in, where inference goes, and which policies and telemetry apply. This page is the reference for every option in that file.
66 
7To write your first one, start from the [quickstart](/docs/en/claude-apps-gateway#quickstart), which builds a minimal working config and runs it. Once you have a config you're happy with, the [deployment guide](/docs/en/claude-apps-gateway-deploy.md) covers containerizing and hosting it on Kubernetes, Cloud Run, or your own platform.
7To write your first one, start from the [quickstart](https://code.claude.com/docs/en/claude-apps-gateway#quickstart), which builds a minimal working config and runs it. Once you have a config you're happy with, the [deployment guide](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md) covers containerizing and hosting it on Kubernetes, Cloud Run, or your own platform.
88 
99The gateway reads the file once, at startup, with `claude gateway --config /path/to/gateway.yaml`. Every option is validated against a schema at boot, so a malformed config fails at start with a field-level error rather than at first use.
1010 
from line 60
6060 
6161The `oidc` block connects the gateway to your identity provider and decides who can sign in. It names the issuer and OAuth client, maps the claims that carry email and groups, and restricts sign-in by email domain or group.
6262 
63OpenID Connect (OIDC) is the SSO protocol the gateway uses with your identity provider; see [Identity provider setup](/docs/en/claude-apps-gateway-deploy.md#identity-provider-setup) for what to register on the IdP side.
63OpenID Connect (OIDC) is the SSO protocol the gateway uses with your identity provider; see [Identity provider setup](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#identity-provider-setup) for what to register on the IdP side.
6464 
6565| Field | Required | Description |
6666| - | - | - |
67| `issuer` | Yes | OIDC discovery base. Must serve discovery at `/.well-known/openid-configuration`. Use HTTPS in production; the gateway accepts an `http://` issuer. A loopback issuer such as `http://localhost:8081` is rejected by the [SSRF guard](/docs/en/claude-apps-gateway-deploy.md#threat-model-summary) unless `CLAUDE_GATEWAY_ALLOW_LOOPBACK=1` is set in the gateway's environment. |
67| `issuer` | Yes | OIDC discovery base. Must serve discovery at `/.well-known/openid-configuration`. Use HTTPS in production; the gateway accepts an `http://` issuer. A loopback issuer such as `http://localhost:8081` is rejected by the [SSRF guard](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#threat-model-summary) unless `CLAUDE_GATEWAY_ALLOW_LOOPBACK=1` is set in the gateway's environment. |
6868| `client_id` | Yes | From your OAuth client registration |
6969| `client_secret` | Unless `token_endpoint_auth_method` is `private_key_jwt` | From your OAuth client registration. Leave it out when you use [certificate client authentication](#certificate-client-authentication). |
7070| `allowed_email_domains` | No | Reject id\_tokens whose `email` claim isn't in one of these domains, case-insensitive. Defense-in-depth against multi-tenant IdP misconfiguration. Independent of this setting, an id\_token whose `email_verified` claim is explicitly `false` is always rejected. |
from line 72
7272| `groups_claim` | No | Which id\_token claim carries group membership. Default `groups`. Microsoft Entra emits app roles under `roles`. Accepts a flat key or an RFC 6901 JSON Pointer such as `/resource_access/gateway/roles` for nested claims. |
7373| `google_groups` | No | Look up the signed-in user's groups through the Google Workspace Admin SDK Directory API, because Google's id\_token carries no groups claim. Set `service_account_json_path` to a service-account key file with domain-wide delegation on the `https://www.googleapis.com/auth/admin.directory.group.readonly` scope, and `admin_email` to a Workspace administrator the service account impersonates; the Directory API requires a real admin subject. Each user's group email addresses become their groups claim, so `allowed_groups` and `managed.policies.match.groups` match on group emails. |
7474| `email_claim` | No | Which id\_token claim carries the user's email. Default `email`. Some IdPs, such as ADFS and Entra B2C, emit `upn` or `preferred_username` instead. Accepts a flat key, a JSON Pointer, or a list of fallback keys where the first present key is used. |
75| `scopes` | No | Full override of the OIDC scopes the gateway requests. Default `[openid, profile, email, offline_access]`. Set when your IdP rejects scopes it doesn't recognize, or requires a custom scope to emit groups or email. Must include `openid`. Dropping `offline_access` disables refresh tokens, so developers re-run the browser login every `session.ttl_hours`. See [Identity provider setup](/docs/en/claude-apps-gateway-deploy.md#identity-provider-setup) for per-IdP scope recipes such as Google's refresh-token flow. |
75| `scopes` | No | Full override of the OIDC scopes the gateway requests. Default `[openid, profile, email, offline_access]`. Set when your IdP rejects scopes it doesn't recognize, or requires a custom scope to emit groups or email. Must include `openid`. Dropping `offline_access` disables refresh tokens, so developers re-run the browser login every `session.ttl_hours`. See [Identity provider setup](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#identity-provider-setup) for per-IdP scope recipes such as Google's refresh-token flow. |
7676| `scope_on_refresh` | No | Also send `scope`, with the same list as the sign-in request, when the gateway exchanges a refresh token. Default `false`: the refresh request omits `scope`. Most IdPs return an id\_token on every refresh and don't need this. Set `true` when your IdP returns an id\_token on refresh only if asked for `openid` again, which Okta documents for its refresh grant. Without an id\_token, every refresh depends on the IdP's userinfo endpoint accepting the refreshed access token. If you gate sign-in or match policies on groups and your IdP's refresh-time id\_token omits them, also set `userinfo_fallback: true` so the gateway fills them from the userinfo endpoint. An IdP that granted fewer scopes than requested can reject the refresh with `invalid_scope`, including for existing sessions if you add entries to `scopes` while this is on. Unset the key if refreshes start failing at `token_endpoint` after you set it. Requires Claude Code v2.1.260 or later on the gateway server. |
7777| `extra_auth_params` | No | Extra query parameters appended to the IdP authorization request, verbatim. This is the override mechanism for IdP-specific behavior, such as `access_type: offline` for Google refresh tokens, `domain_hint` for some Entra tenants, or `acr_values` for step-up flows. Cannot override the gateway-managed protocol params: `state`, `nonce`, `redirect_uri`, PKCE, `scope`, `response_type`, `response_mode`, and `client_id`. |
7878| `userinfo_fallback` | No | When the id\_token omits email or groups, fetch them from `/userinfo`. Needed for Keycloak lightweight access tokens, the Okta org server, and ADFS minimal tokens. The id\_token stays authoritative; userinfo only fills gaps. Default `false`. |
from line 138
138138The gateway reads the key and certificate once at boot, so a changed file takes effect only after a restart. Rotate in this order so that no token request presents a certificate the IdP doesn't have:
139139 
1401401. Upload the new certificate to the IdP alongside the old one.
1412. Replace the key and certificate files that `gateway.yaml` loads, then restart the gateway. If you run several replicas, a [rolling restart](/docs/en/claude-apps-gateway-deploy.md#upgrades) works, because the IdP has both certificates until you remove the old one.
1412. Replace the key and certificate files that `gateway.yaml` loads, then restart the gateway. If you run several replicas, a [rolling restart](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#upgrades) works, because the IdP has both certificates until you remove the old one.
1421423. After every replica has restarted, remove the old certificate from the IdP.
143143 
144144#### IdP requests through a forward proxy
from line 145
145145 
146146The inference upstreams honor `HTTPS_PROXY` and `HTTP_PROXY` on every version. The gateway's own requests to the IdP, discovery, JWKS, token, and userinfo, go direct unless you set `oidc.use_proxy: true`, which requires v2.1.227 or later. When a proxy variable is set, `use_proxy` is unset, and the issuer isn't covered by `NO_PROXY`, the gateway keeps those requests direct and logs a notice at boot asking you to choose; `use_proxy: false` keeps them direct and silences the notice.
147147 
148With `use_proxy: true`, the pod resolves each IdP endpoint's hostname itself and asks the proxy to `CONNECT` to the resolved IP address, so the proxy must accept `CONNECT` to the IP address of every host the discovery document names, not only the issuer. Use an `http://` proxy URL. `ca_cert_pem` and the [SSRF guard](/docs/en/claude-apps-gateway-deploy.md#threat-model-summary) apply on the proxied path as well.
148With `use_proxy: true`, the pod resolves each IdP endpoint's hostname itself and asks the proxy to `CONNECT` to the resolved IP address, so the proxy must accept `CONNECT` to the IP address of every host the discovery document names, not only the issuer. Use an `http://` proxy URL. `ca_cert_pem` and the [SSRF guard](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#threat-model-summary) apply on the proxied path as well.
149149 
150150[Proxy-only egress](#proxy-only-egress) changes both of these: while it's active, IdP requests follow the proxy unless you set `use_proxy: false`, and the gateway hands the proxy each IdP hostname without resolving it first.
151151 
from line 182
182182 
183183> [!WARNING]
184184>
185> Turn this on only when the proxy's allowlist is at least as strict as the gateway's own check. The proxy must refuse cloud metadata endpoints such as `169.254.169.254` and `metadata.google.internal`, link-local addresses, and the proxy host's own loopback, and it must refuse them by the address a name resolves to, not only by name, because the gateway no longer catches a hostname that resolves to one of them. A proxy that connects anywhere it's asked removes the gateway's [SSRF guard](/docs/en/claude-apps-gateway-deploy.md#threat-model-summary) for these requests.
185> Turn this on only when the proxy's allowlist is at least as strict as the gateway's own check. The proxy must refuse cloud metadata endpoints such as `169.254.169.254` and `metadata.google.internal`, link-local addresses, and the proxy host's own loopback, and it must refuse them by the address a name resolves to, not only by name, because the gateway no longer catches a hostname that resolves to one of them. A proxy that connects anywhere it's asked removes the gateway's [SSRF guard](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#threat-model-summary) for these requests.
186186 
187187### `session`
188188 
from line 199
199199 
200200| Field | Required | Description |
201201| - | - | - |
202| `postgres_url` | Yes | `postgres://` or `postgresql://` URL with one host, not a comma-separated list. The gateway runs its own schema migrations at boot and on upgrade, so the role needs rights to create and alter tables on the target schema. See [Upgrades](/docs/en/claude-apps-gateway-deploy.md#upgrades) and [Postgres](/docs/en/claude-apps-gateway-deploy.md#postgres). |
202| `postgres_url` | Yes | `postgres://` or `postgresql://` URL with one host, not a comma-separated list. The gateway runs its own schema migrations at boot and on upgrade, so the role needs rights to create and alter tables on the target schema. See [Upgrades](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#upgrades) and [Postgres](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#postgres). |
203203| `username` | No | Overrides the user in `postgres_url` |
204204| `password` | No | Database credential. Set it here rather than in `postgres_url` so the credential stays out of the URL. Accepts any characters and takes precedence over URL credentials. |
205| `max_connections` | No | Postgres connection-pool size per replica. Default `5`, which is conservative and friendly to shared databases. With [spend limits](#admin) enabled, the gateway makes a few database operations per inference request, so raise it for a dedicated database under load, within what [Size the connection pool](/docs/en/claude-apps-gateway-deploy.md#size-the-connection-pool) allows. |
205| `max_connections` | No | Postgres connection-pool size per replica. Default `5`, which is conservative and friendly to shared databases. With [spend limits](#admin) enabled, the gateway makes a few database operations per inference request, so raise it for a dedicated database under load, within what [Size the connection pool](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#size-the-connection-pool) allows. |
206206| `connect_timeout_seconds` | No | Seconds the gateway waits when it opens a Postgres connection. A whole number from `1` to `60`, default `5`. Raise it if connection attempts time out when a new gateway instance starts. Requires Claude Code v2.1.274 or later on the gateway server. Earlier versions refuse to start when the key is set. |
207| `readiness_grace_seconds` | No | How many seconds `/readyz` keeps reporting ready after Postgres stops answering. A whole number from `0` to `3600`, default `0`. See [Outage behavior](/docs/en/claude-apps-gateway-deploy.md#outage-behavior) for how to pick a value. Requires Claude Code v2.1.282 or later on the gateway server. Earlier versions refuse to start when the key is set. |
207| `readiness_grace_seconds` | No | How many seconds `/readyz` keeps reporting ready after Postgres stops answering. A whole number from `0` to `3600`, default `0`. See [Outage behavior](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#outage-behavior) for how to pick a value. Requires Claude Code v2.1.282 or later on the gateway server. Earlier versions refuse to start when the key is set. |
208208 
209209For local development, point `postgres_url` at a throwaway Postgres container, for example `docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres`.
210210 
from line 231
231231 
232232When the gateway returns an upstream's response, it keeps the upstream's status code. Whether it keeps the upstream's message depends on the provider. An Anthropic API upstream's error body reaches the developer unchanged.
233233 
234The Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform, and Microsoft Foundry upstreams can name your account IDs, role ARNs, and project IDs in their error text. The gateway records that full text in the [operational log](/docs/en/claude-apps-gateway-deploy.md#logs). What the developer sees from those upstreams depends on the rejection:
234The Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform, and Microsoft Foundry upstreams can name your account IDs, role ARNs, and project IDs in their error text. The gateway records that full text in the [operational log](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#logs). What the developer sees from those upstreams depends on the rejection:
235235 
236236* `400` or `413` in Anthropic's standard error envelope: the upstream's own message, such as `prompt is too long`. Claude Platform on AWS, Agent Platform, and Microsoft Foundry return this envelope for model API rejections.
237237* `400` or `413` in the provider's own shape: a `capability_rejected:` token. When the gateway can't classify the rejection, `upstream rejected the request` on a `400` or `request too large for this upstream` on a `413`.
238238* Any other status: generic per-status copy, such as `upstream rate limit exceeded` on a `429`.
239239 
240For example, the gateway replaces Amazon Bedrock's `Input is too long for requested model.` with `capability_rejected: prompt_too_long`. Claude Code [compacts automatically](/docs/en/errors.md#prompt-is-too-long) on that token, as it does on `prompt is too long`.
240For example, the gateway replaces Amazon Bedrock's `Input is too long for requested model.` with `capability_rejected: prompt_too_long`. Claude Code [compacts automatically](https://code.claude.com/docs/en/errors.md#prompt-is-too-long) on that token, as it does on `prompt is too long`.
241241 
242242Keeping a cloud upstream's `400` or `413` message, or replacing it with a `capability_rejected:` token, requires gateway v2.1.233 or later.
243243 
from line 298
298298 
299299When the IdP token carries no email, the gateway sends only `x-claude-gateway-user-id` and omits the two email headers. If your IdP puts the email in a different claim, set [`oidc.email_claim`](#oidc) to that claim.
300300 
301Your proxy doesn't receive the [`x-claude-code-*` headers](/docs/en/llm-gateway-protocol#request-headers) that Claude Code sends, such as `x-claude-code-session-id`. The gateway doesn't pass them to any upstream, so group requests by developer with the headers in the table above.
301Your proxy doesn't receive the [`x-claude-code-*` headers](https://code.claude.com/docs/en/llm-gateway-protocol#request-headers) that Claude Code sends, such as `x-claude-code-session-id`. The gateway doesn't pass them to any upstream, so group requests by developer with the headers in the table above.
302302 
303303When your proxy answers `429` to a request that carried the developer's email, the gateway returns that response to the developer as-is instead of failing over to the next upstream, so your proxy's per-user budget or rate limit holds. The proxy's other responses follow the ordinary [failover rules](#upstreams). If a developer's IdP token carries no email, the gateway forwards their requests without the email headers, so a `429` to one of those requests counts as upstream capacity and fails over. Before v2.1.267 on the gateway server, every `429` failed over.
304304 
from line 306
306306 
307307> [!NOTE]
308308>
309> If you set `forward_user_identity` on an Amazon Bedrock upstream, the gateway exits at startup with `Unrecognized key(s) in object: 'forward_user_identity'`. If your proxy sits in front of Bedrock, list it as a `provider: anthropic` upstream instead. The gateway sends that upstream the Anthropic Messages format, so your proxy has to [translate requests for Bedrock](/docs/en/llm-gateway-protocol.md#format-mismatch-with-the-upstream). To name each developer to AWS instead, see [Per-developer AWS cost attribution](#per-developer-aws-cost-attribution).
309> If you set `forward_user_identity` on an Amazon Bedrock upstream, the gateway exits at startup with `Unrecognized key(s) in object: 'forward_user_identity'`. If your proxy sits in front of Bedrock, list it as a `provider: anthropic` upstream instead. The gateway sends that upstream the Anthropic Messages format, so your proxy has to [translate requests for Bedrock](https://code.claude.com/docs/en/llm-gateway-protocol.md#format-mismatch-with-the-upstream). To name each developer to AWS instead, see [Per-developer AWS cost attribution](#per-developer-aws-cost-attribution).
310310 
311311#### Amazon Bedrock
312312 
313For the client-side Amazon Bedrock deployment that the gateway replaces or fronts, see [Claude Code on Amazon Bedrock](/docs/en/amazon-bedrock.md). The gateway-side upstream:
313For the client-side Amazon Bedrock deployment that the gateway replaces or fronts, see [Claude Code on Amazon Bedrock](https://code.claude.com/docs/en/amazon-bedrock.md). The gateway-side upstream:
314314 
315315```yaml theme={null}
316316upstreams:
from line 336
336336| Setup | How |
337337| - | - |
338338| IAM permissions | Grant the gateway's principal `bedrock:InvokeModel` and `bedrock:InvokeModelWithResponseStream` on both the inference-profile ARNs and the underlying foundation-model ARNs. For the built-in catalog in US regions: `arn:aws:bedrock:<region>:<account>:inference-profile/us.anthropic.*` and `arn:aws:bedrock:*::foundation-model/anthropic.*`. Also grant `bedrock:CountTokens` on the foundation-model ARNs. The gateway uses it, at no charge, to count the input tokens of a request the client abandoned, so [spend limits](#admin) stay accurate. Without it the gateway falls back to a one-token Bedrock request for that count. |
339| Model access | Amazon Bedrock enables model access by default in commercial regions. The remaining account-level gate is Anthropic's one-time use case form: if no one in your AWS account has submitted it, open the Amazon Bedrock console, select an Anthropic model from the Model catalog, and complete the form. See [Submit use case details](/docs/en/amazon-bedrock.md#1-submit-use-case-details) for the AWS Organizations form and the permissions the submitter needs. |
339| Model access | Amazon Bedrock enables model access by default in commercial regions. The remaining account-level gate is Anthropic's one-time use case form: if no one in your AWS account has submitted it, open the Amazon Bedrock console, select an Anthropic model from the Model catalog, and complete the form. See [Submit use case details](https://code.claude.com/docs/en/amazon-bedrock.md#1-submit-use-case-details) for the AWS Organizations form and the permissions the submitter needs. |
340340| EKS (IRSA) | Create an IAM role with the policy above and a trust policy for your cluster's OIDC provider scoped to the gateway's service account. Annotate the service account with `eks.amazonaws.com/role-arn: arn:aws:iam::<acct>:role/claude-gateway`. `auth: {}` picks it up. |
341341| ECS / EC2 | Attach the IAM role to the task definition or instance profile. `auth: {}` picks it up. |
342342| Anywhere else | Pass credentials via the `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN` env vars, or set them explicitly in `auth:` with `${VAR}` expansion |
from line 426
426426 
427427By default the gateway signs every Bedrock request with one credential, so AWS sees all developers' requests under a single IAM principal. Add `session_name: email` to [`assume_role`](#bedrock-in-another-aws-account) and the gateway calls `sts:AssumeRole` once per developer per hour, with the session name set to that developer's email, and signs their requests with the returned credentials, so each developer's requests reach AWS under their own assumed-role session. The role can be in the gateway's own account.
428428 
429Requires a gateway running Claude Code v2.1.281 or later. [Cost attribution on AWS](/docs/en/claude-apps-gateway-on-aws.md#cost-attribution) covers the IAM role and where AWS billing shows the sessions.
429Requires a gateway running Claude Code v2.1.281 or later. [Cost attribution on AWS](https://code.claude.com/docs/en/claude-apps-gateway-on-aws.md#cost-attribution) covers the IAM role and where AWS billing shows the sessions.
430430 
431431```yaml theme={null}
432432upstreams:
from line 442
442442 
443443An active developer costs one STS call per hour per gateway replica, and concurrent first requests share one call.
444444 
445The gateway also makes one call of its own on this role: the token count for a request the client abandoned, so that [spend limits](/docs/en/claude-apps-gateway-spend-limits.md) stay accurate. That count and its [one-token fallback request](#amazon-bedrock) are signed by the shared `claude-apps-gateway` session, so AWS attributes the fallback to `claude-apps-gateway` rather than to the developer.
445The gateway also makes one call of its own on this role: the token count for a request the client abandoned, so that [spend limits](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md) stay accurate. That count and its [one-token fallback request](#amazon-bedrock) are signed by the shared `claude-apps-gateway` session, so AWS attributes the fallback to `claude-apps-gateway` rather than to the developer.
446446 
447447For strict per-developer attribution, set `assume_role` with `session_name` on every Bedrock upstream you list. An upstream without it signs the requests it serves with its own credentials.
448448 
449449#### Amazon Bedrock Mantle endpoint
450450 
451The `mantle` provider sends inference to Amazon Bedrock's [Mantle endpoint](/docs/en/amazon-bedrock.md#use-the-mantle-endpoint). It requires Claude Code v2.1.283 or later on the gateway server. Earlier gateway releases reject it at boot, so upgrade every replica before adding it.
451The `mantle` provider sends inference to Amazon Bedrock's [Mantle endpoint](https://code.claude.com/docs/en/amazon-bedrock.md#use-the-mantle-endpoint). It requires Claude Code v2.1.283 or later on the gateway server. Earlier gateway releases reject it at boot, so upgrade every replica before adding it.
452452 
453453The example below puts Mantle first, with an Amazon Bedrock upstream behind it to serve every model the `models` field leaves out:
454454 
from line 472
472472| `auth` | No | Takes the same keys as the [Amazon Bedrock](#amazon-bedrock) upstream's `auth` block, under the same rules. |
473473| `base_url` | No | Override the derived endpoint. Keep the `/anthropic` path at the end. |
474474 
475Grant the upstream's AWS identity Mantle's own IAM actions for inference and token counting, which [Use the Mantle endpoint](/docs/en/amazon-bedrock.md#use-the-mantle-endpoint) lists.
475Grant the upstream's AWS identity Mantle's own IAM actions for inference and token counting, which [Use the Mantle endpoint](https://code.claude.com/docs/en/amazon-bedrock.md#use-the-mantle-endpoint) lists.
476476 
477477For a Mantle model ID that the gateway doesn't know, add an entry to the top-level [`models:`](#models) block whose `upstream_model` maps this upstream's name to that ID. Then put that entry's `id` in this upstream's `models` field too.
478478 
from line 481
481481* **`guardrail`**: the gateway applies no [Bedrock guardrail](#apply-an-amazon-bedrock-guardrail) to requests it sends to Mantle, so it refuses to start when a `mantle` upstream is listed while any `bedrock` upstream sets `guardrail`.
482482* **`assume_role`**: a `mantle` upstream takes no [`assume_role`](#bedrock-in-another-aws-account). Requests that Mantle serves are sent with the `mantle` upstream's own `auth` credentials, and aren't [attributed per developer](#per-developer-aws-cost-attribution).
483483 
484For what Mantle's own error responses mean, see [Mantle endpoint errors](/docs/en/amazon-bedrock.md#mantle-endpoint-errors).
484For what Mantle's own error responses mean, see [Mantle endpoint errors](https://code.claude.com/docs/en/amazon-bedrock.md#mantle-endpoint-errors).
485485 
486486#### Claude Platform on AWS
487487 
488488Claude Platform on AWS serves the first-party Anthropic API on AWS infrastructure at `aws-external-anthropic.<region>.api.aws`. It uses first-party model IDs, honors `anthropic-beta` headers as sent, and serves `count_tokens`, so none of the Bedrock-specific translation applies. The `anthropicAws` provider requires Claude Code v2.1.198 or later; earlier gateway releases reject it at boot.
489489 
490For the client-side deployment of the same platform, see [Claude Code on Claude Platform on AWS](/docs/en/claude-platform-on-aws.md). The gateway-side upstream:
490For the client-side deployment of the same platform, see [Claude Code on Claude Platform on AWS](https://code.claude.com/docs/en/claude-platform-on-aws.md). The gateway-side upstream:
491491 
492492```yaml theme={null}
493493upstreams:
from line 520
520520 
521521#### Google Cloud Agent Platform
522522 
523For the equivalent client-side setup, see [Claude Code on Google Cloud](/docs/en/google-vertex-ai.md). The gateway-side upstream:
523For the equivalent client-side setup, see [Claude Code on Google Cloud](https://code.claude.com/docs/en/google-vertex-ai.md). The gateway-side upstream:
524524 
525525```yaml theme={null}
526526upstreams:
from line 548
548548 
549549#### Microsoft Foundry
550550 
551For the client-side Microsoft Foundry deployment, see [Claude Code on Microsoft Foundry](/docs/en/microsoft-foundry.md). The gateway-side upstream:
551For the client-side Microsoft Foundry deployment, see [Claude Code on Microsoft Foundry](https://code.claude.com/docs/en/microsoft-foundry.md). The gateway-side upstream:
552552 
553553```yaml theme={null}
554554upstreams:
from line 685
685685 
686686### `admin`
687687 
688Optional. Enables `/v1/organizations/spend_limits`, which mirrors Anthropic's public Admin API, and per-developer spend enforcement on `/v1/messages`. See [Spend limits](/docs/en/claude-apps-gateway-spend-limits.md) for how caps are set and enforced; this section covers the `gateway.yaml` keys that turn the feature on and tune it.
688Optional. Enables `/v1/organizations/spend_limits`, which mirrors Anthropic's public Admin API, and per-developer spend enforcement on `/v1/messages`. See [Spend limits](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md) for how caps are set and enforced; this section covers the `gateway.yaml` keys that turn the feature on and tune it.
689689 
690690```yaml theme={null}
691691admin:
from line 706
706706| Field | Required | Description |
707707| - | - | - |
708708| `write_keys` | No | Array of `{id, key}`. An `x-api-key` matching one of these can list, set, and delete spend limits. Key values must be at least 32 characters; `id`s must be unique across `read_keys` and `write_keys`. |
709| `read_keys` | No | Array of `{id, key}`. Read-only: every `GET` endpoint, including listing caps, fetching one by ID, and reading [`/effective`](/docs/en/claude-apps-gateway-spend-limits#%2Feffective) and [`/audit`](/docs/en/claude-apps-gateway-spend-limits#%2Faudit). |
709| `read_keys` | No | Array of `{id, key}`. Read-only: every `GET` endpoint, including listing caps, fetching one by ID, and reading [`/effective`](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits#%2Feffective) and [`/audit`](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits#%2Faudit). |
710710| `admin_groups` | No | IdP group names. A gateway JWT whose `groups` claim includes one of these has full admin access, read and write, and audits as `oidc:<sub>`. Use this for human admins; use API keys for machines. An empty entry in this list stops the gateway at boot. See [Matcher values that stop the gateway at boot](#matcher-values-that-stop-the-gateway-at-boot). |
711| `blocked_message` | No | Appended verbatim to the `429 billing_error` a blocked developer sees. Write the whole instruction, such as a URL or a Slack channel. When unset, the gateway sends only the default message. See [How enforcement works](/docs/en/claude-apps-gateway-spend-limits.md#how-enforcement-works). |
711| `blocked_message` | No | Appended verbatim to the `429 billing_error` a blocked developer sees. Write the whole instruction, such as a URL or a Slack channel. When unset, the gateway sends only the default message. See [How enforcement works](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md#how-enforcement-works). |
712712| `audit_retention_days` | No | Default `365`. Older `admin_audit` rows are swept. |
713713| `spend_retention_months` | No | Default `13`. `spend` counter rows older than this are swept. The default keeps a full year plus the current partial month for year-over-year reporting. |
714714| `identity_retention_days` | No | Default `90`. Last-seen TTL for `principal_emails` rows, which hold each developer's email, display name, and groups (PII). Deliberately shorter than spend retention so a deprovisioned identity ages out while its anonymous spend counters remain. |
from line 724
724724 
725725### `pricing`
726726 
727The `pricing` block tells the spend meter what to charge instead of USD list price, so caps and [`/effective`](/docs/en/claude-apps-gateway-spend-limits#%2Feffective) reflect your contracted rates. Amounts stay in USD and remain an estimate, not an invoice. Two prerequisites:
727The `pricing` block tells the spend meter what to charge instead of USD list price, so caps and [`/effective`](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits#%2Feffective) reflect your contracted rates. Amounts stay in USD and remain an estimate, not an invoice. Two prerequisites:
728728 
729729* Claude Code v2.1.227 or later on the gateway server. Earlier versions reject the unknown key at boot.
730730* An [`admin:`](#admin) block or, in v2.1.268 or later, a [`managed:`](#managed) block with at least one policy. The gateway refuses to start with `pricing` set and neither block, because nothing would read it.
from line 748
748748 
749749How the meter matches an override row:
750750 
751* A row replaces list price for requests that `upstream`, an [`upstreams[].name`](#upstreams), serves for `model`. That includes the higher [fast mode](/docs/en/fast-mode.md#understand-the-cost-tradeoff) rate, so fast and standard requests meter at the same four rates.
751* A row replaces list price for requests that `upstream`, an [`upstreams[].name`](#upstreams), serves for `model`. That includes the higher [fast mode](https://code.claude.com/docs/en/fast-mode.md#understand-the-cost-tradeoff) rate, so fast and standard requests meter at the same four rates.
752752* A built-in ID such as `claude-sonnet-4-6`, matched like [`models[].id`](#models), covers every dated form, regional Amazon Bedrock form, or Google Cloud's Agent Platform form the meter prices as that model. Any other string, such as an alias or an inference-profile ARN, matches the ID the client sent or the string sent upstream, case-insensitively.
753753* Where rows overlap, the meter picks the most specific row rather than the first row: a row whose `model` is the exact model string sent upstream, then a row matching the exact ID the client sent, then a row naming the built-in model.
754754* An unknown upstream name fails boot, and so do two rows for one upstream that name the same model, including two spellings of one built-in model. The gateway warns at boot about a row no requestable model can use.
from line 775
775775 
776776#### Send the rates to signed-in clients
777777 
778With v2.1.268 or later on the gateway server, the gateway also puts the rates from `pricing` into the [`managed`](#managed) policies it serves, as the [`modelPricing`](/docs/en/settings-reference#modelpricing) managed setting. Developers matched by a policy then see the `pricing` rates for the first upstream that serves each model ID in `/usage`, the status line, and OpenTelemetry. A developer who matches no policy receives no managed settings, so their figures stay at list price. Clients apply the setting in Claude Code v2.1.242 or later.
778With v2.1.268 or later on the gateway server, the gateway also puts the rates from `pricing` into the [`managed`](#managed) policies it serves, as the [`modelPricing`](https://code.claude.com/docs/en/settings-reference#modelpricing) managed setting. Developers matched by a policy then see the `pricing` rates for the first upstream that serves each model ID in `/usage`, the status line, and OpenTelemetry. A developer who matches no policy receives no managed settings, so their figures stay at list price. Clients apply the setting in Claude Code v2.1.242 or later.
779779 
780780* What the gateway adds: unless a policy's `cli` block already sets `modelPricing`, the gateway adds the `multiplier` and, for every model ID a client can request, the override row of the first upstream that serves that ID. A rate that only a failover upstream charges stays on the gateway.
781781* Opt one policy out: set `modelPricing` to `{}` in that policy's `cli` block, and its developers stay at list price.
from line 846
846846>
847847> The gateway keeps no user directory of its own. It authorizes each request from the user's IdP token, reading group membership from the token's `groups` claim and evaluating policies against it. There is no roster to enumerate and no accounts to pre-create, and therefore no SCIM endpoint, because there is nothing for SCIM to sync into.
848848>
849> Run user and group lifecycle management at the source of truth, which is your IdP's native SCIM provisioning or a dedicated identity-governance platform. Membership and deprovisioning governed there flow into the gateway automatically through the token. If you want SCIM provisioning of Claude accounts themselves, that is a [Claude for Enterprise](/docs/en/admin-setup.md) capability.
849> Run user and group lifecycle management at the source of truth, which is your IdP's native SCIM provisioning or a dedicated identity-governance platform. Membership and deprovisioning governed there flow into the gateway automatically through the token. If you want SCIM provisioning of Claude accounts themselves, that is a [Claude for Enterprise](https://code.claude.com/docs/en/admin-setup.md) capability.
850850>
851851> Two propagation clocks apply:
852852>
853> * **Policy contents**: editing a policy and redeploying reaches connected Claude Code clients on their next managed-settings poll, within an hour, apart from the [changes that apply only at the next launch](/docs/en/server-managed-settings.md#fetch-and-caching-behavior)
853> * **Policy contents**: editing a policy and redeploying reaches connected Claude Code clients on their next managed-settings poll, within an hour, apart from the [changes that apply only at the next launch](https://code.claude.com/docs/en/server-managed-settings.md#fetch-and-caching-behavior)
854854> * **Group membership**: changing a user's group membership changes which policy matches them. This takes effect on the next session re-mint, meaning the next silent refresh, bounded by `session.ttl_hours`.
855855>
856856> Claude Desktop follows [its own schedule](#when-a-policy-change-reaches-claude-desktop).
from line 859
859859 
860860If `availableModels` leaves out Claude Code's default model, sessions get `400` responses until the developer picks a listed model, for example with `/model`. In gateway sessions the default is the Opus model the `opus` alias resolves to, and `availableModels` on its own doesn't change it.
861861 
862To fix this, set [`enforceAvailableModels: true`](/docs/en/model-config#enforce-the-allowlist-for-the-default-model) in the same `cli` block, then check which kind of entry the list has:
862To fix this, set [`enforceAvailableModels: true`](https://code.claude.com/docs/en/model-config#enforce-the-allowlist-for-the-default-model) in the same `cli` block, then check which kind of entry the list has:
863863 
864864* **An alias such as `sonnet`, or a built-in ID such as `claude-sonnet-4-6`**: sessions start on one of those models, and the Default option in `/model` resolves to it
865* **No alias or built-in ID in the list**: sessions can keep starting on the built-in default, so also set [`model`](/docs/en/model-config#control-the-model-users-run-on) to one of the listed IDs in that policy's `cli` block
865* **No alias or built-in ID in the list**: sessions can keep starting on the built-in default, so also set [`model`](https://code.claude.com/docs/en/model-config#control-the-model-users-run-on) to one of the listed IDs in that policy's `cli` block
866866 
867867This policy lists one custom ID that [`models`](#models) defines, and starts sessions on that ID:
868868 
from line 925
925925 
926926#### What goes in `cli`
927927 
928Each `code` or `cli` value is a complete Claude Code `managed-settings.json` document, the same schema you would deploy via MDM or `/etc/claude-code/managed-settings.json`, expressed here as YAML. The CLI applies the delivered document at the managed tier, above user and project settings, in place of server-managed settings. It therefore ignores the settings [restricted to OS-level policy sources](/docs/en/server-managed-settings.md#current-limitations), such as `policyHelper` and `wslInheritsWindowsSettings`.
928Each `code` or `cli` value is a complete Claude Code `managed-settings.json` document, the same schema you would deploy via MDM or `/etc/claude-code/managed-settings.json`, expressed here as YAML. The CLI applies the delivered document at the managed tier, above user and project settings, in place of server-managed settings. It therefore ignores the settings [restricted to OS-level policy sources](https://code.claude.com/docs/en/server-managed-settings.md#current-limitations), such as `policyHelper` and `wslInheritsWindowsSettings`.
929929 
930930The gateway validates each document against the CLI's settings schema at boot, so an unrecognized top-level key fails boot with an error naming every offending key. Deliberately open parts of the schema still accept arbitrary values, because newer clients may recognize entries the gateway's schema doesn't. These open keys include `env`, `pluginConfigs`, and keys nested under `permissions`.
931931 
932932Because validation uses the schema bundled with the gateway's installed version, putting a top-level settings key introduced by a newer Claude Code release into managed config requires upgrading the gateway first. Smoke-test a new policy on one client before rolling it out.
933933 
934The full key reference is in [Claude Code settings](/docs/en/settings-reference.md#all-settings). The keys most operators reach for first:
934The full key reference is in [Claude Code settings](https://code.claude.com/docs/en/settings-reference.md#all-settings). The keys most operators reach for first:
935935 
936936```yaml theme={null}
937937managed:
from line 969
969969| Key | Enforced by | Effect |
970970| - | - | - |
971971| `availableModels` | Gateway + CLI | Model allowlist. Also checked at `/v1/messages`, so a patched client can't bypass it. |
972| [`deniedModels`](/docs/en/settings-reference#deniedmodels), [`availableModelsMatch`](/docs/en/settings-reference#availablemodelsmatch) | Gateway + CLI | [Block specific models or versions](/docs/en/model-config.md#block-specific-models-or-versions) that `availableModels` would otherwise permit. A blocked model is rejected with a `400` at `/v1/messages` and is left out of `/v1/models`. The gateway's own check requires Claude Code v2.1.299 or later on the gateway server. The CLI's check requires v2.1.283 or later on clients, and earlier clients ignore both keys. |
973| `permissions.allow` / `.deny` | CLI | Tool and command rules. See [Permissions](/docs/en/permissions.md). |
974| `permissions.disableBypassPermissionsMode` | CLI | Set to `disable` to block [`bypassPermissions`](/docs/en/permission-modes#skip-all-checks-with-bypasspermissions-mode), the mode that skips permission prompts, and the `--dangerously-skip-permissions` flag |
975| `allowManagedPermissionRulesOnly` | CLI | When `true`, managed settings become the only settings source of permission rules. The [`allowManagedPermissionRulesOnly`](/docs/en/settings-reference#allowmanagedpermissionrulesonly) entry lists every source Claude Code then ignores. |
972| [`deniedModels`](https://code.claude.com/docs/en/settings-reference#deniedmodels), [`availableModelsMatch`](https://code.claude.com/docs/en/settings-reference#availablemodelsmatch) | Gateway + CLI | [Block specific models or versions](https://code.claude.com/docs/en/model-config.md#block-specific-models-or-versions) that `availableModels` would otherwise permit. A blocked model is rejected with a `400` at `/v1/messages` and is left out of `/v1/models`. The gateway's own check requires Claude Code v2.1.299 or later on the gateway server. The CLI's check requires v2.1.283 or later on clients, and earlier clients ignore both keys. |
973| `permissions.allow` / `.deny` | CLI | Tool and command rules. See [Permissions](https://code.claude.com/docs/en/permissions.md). |
974| `permissions.disableBypassPermissionsMode` | CLI | Set to `disable` to block [`bypassPermissions`](https://code.claude.com/docs/en/permission-modes#skip-all-checks-with-bypasspermissions-mode), the mode that skips permission prompts, and the `--dangerously-skip-permissions` flag |
975| `allowManagedPermissionRulesOnly` | CLI | When `true`, managed settings become the only settings source of permission rules. The [`allowManagedPermissionRulesOnly`](https://code.claude.com/docs/en/settings-reference#allowmanagedpermissionrulesonly) entry lists every source Claude Code then ignores. |
976976| `env` | CLI | Environment variables merged into the CLI process. Use for telemetry, auto-update, and model-name overrides. |
977| `hooks` | CLI | Org-wide [hooks](/docs/en/hooks.md) |
978| `managedMcpServers` | CLI | Remote MCP servers [provided to every matching developer](/docs/en/managed-mcp.md#provide-servers-through-managed-settings) alongside the servers they add themselves, `http` and `sse` only. See [MCP servers in a policy](#mcp-servers-in-a-policy). Requires Claude Code v2.1.259 or later on the gateway server and on clients. Earlier clients ignore the key. |
977| `hooks` | CLI | Org-wide [hooks](https://code.claude.com/docs/en/hooks.md) |
978| `managedMcpServers` | CLI | Remote MCP servers [provided to every matching developer](https://code.claude.com/docs/en/managed-mcp.md#provide-servers-through-managed-settings) alongside the servers they add themselves, `http` and `sse` only. See [MCP servers in a policy](#mcp-servers-in-a-policy). Requires Claude Code v2.1.259 or later on the gateway server and on clients. Earlier clients ignore the key. |
979979 
980980Because these settings arrive over the network, the CLI shows each developer a security approval dialog before applying the settings listed below:
981981 
from line 983
983983* `env` variables that require the developer's approval, such as proxy and base-URL variables
984984* shell-execution settings such as `apiKeyHelper` and `statusLine`
985985* the sandbox binary settings `sandbox.bwrapPath`, `sandbox.socatPath`, and `sandbox.ripgrep`
986* Sandbox settings that intercept traffic, inject credentials, or weaken isolation, such as `sandbox.network.tlsTerminate` and the proxy port settings. [Security approval dialogs](/docs/en/server-managed-settings.md#security-approval-dialogs) lists them all.
986* Sandbox settings that intercept traffic, inject credentials, or weaken isolation, such as `sandbox.network.tlsTerminate` and the proxy port settings. [Security approval dialogs](https://code.claude.com/docs/en/server-managed-settings.md#security-approval-dialogs) lists them all.
987987 
988[Approval memory](/docs/en/server-managed-settings.md#approval-memory) covers how long an approval lasts and when the dialog appears again.
988[Approval memory](https://code.claude.com/docs/en/server-managed-settings.md#approval-memory) covers how long an approval lasts and when the dialog appears again.
989989 
990990Claude Code applies some delivered `env` variables without showing the developer the approval dialog, such as model selection settings and numeric limits. Other delivered variables can require the developer's approval before they take effect; a non-empty proxy, base-URL, or `OTEL_EXPORTER_OTLP_ENDPOINT` value always does. When a delivered variable needs approval, the dialog names it.
991991 
992[Environment variables and the approval dialog](/docs/en/server-managed-settings.md#environment-variables-and-the-approval-dialog) has the details, including four privacy toggles whose delivered value decides whether they need approval. Before v2.1.218, Claude Code applied fewer variables without asking the developer, so more delivered variables triggered the dialog.
992[Environment variables and the approval dialog](https://code.claude.com/docs/en/server-managed-settings.md#environment-variables-and-the-approval-dialog) has the details, including four privacy toggles whose delivered value decides whether they need approval. Before v2.1.218, Claude Code applied fewer variables without asking the developer, so more delivered variables triggered the dialog.
993993 
994994The gateway's [telemetry](#telemetry) configuration pushes `OTEL_EXPORTER_OTLP_ENDPOINT`, so setting `telemetry.forward_to` triggers the dialog on each interactive client. The dialog protects the developer's machine from a compromised or hostile gateway, not the organization from the developer.
995995 
996A [non-interactive run](/docs/en/server-managed-settings.md#security-approval-dialogs), such as `claude -p`, an Agent SDK session, or a session in Claude Desktop's Code tab, can't show the dialog. It applies the pushed settings for that run only and doesn't record them as approved, so the developer's next interactive session still shows the dialog.
996A [non-interactive run](https://code.claude.com/docs/en/server-managed-settings.md#security-approval-dialogs), such as `claude -p`, an Agent SDK session, or a session in Claude Desktop's Code tab, can't show the dialog. It applies the pushed settings for that run only and doesn't record them as approved, so the developer's next interactive session still shows the dialog.
997997 
998998If a developer declines, Claude Code exits that session rather than applying the policy. When you push a new hook, or any env var that triggers the dialog, to a broad policy, every matching developer therefore sees the dialog in their interactive sessions. A running interactive session shows it on the next hourly poll, and otherwise it appears at the developer's next interactive startup.
999999 
from line 1003
10031003 
10041004Terminal sessions signed in through `/login` use the 1M context window for Opus 4.7 and later, Sonnet 5 and later, and the Fable models. The model ID needs no `[1m]` suffix, and sessions compact at about 967K tokens. Before Claude Code v2.1.287 on the developer's machine, Claude Code treated the Opus and Fable models as having a 200K window unless the model ID ended in `[1m]`.
10051005 
1006To have terminal sessions compact at the 200K boundary instead, set the [auto-compact window](/docs/en/model-config.md#set-the-auto-compact-window) in the policy's `env`:
1006To have terminal sessions compact at the 200K boundary instead, set the [auto-compact window](https://code.claude.com/docs/en/model-config.md#set-the-auto-compact-window) in the policy's `env`:
10071007 
10081008```yaml theme={null}
10091009managed:
from line 1016
10161016 
10171017Claude Code applies this variable without showing the developer the approval dialog. The variable applies to every model, including model IDs that end in `[1m]`.
10181018 
1019To turn off 1M context instead, set [`CLAUDE_CODE_DISABLE_1M_CONTEXT: "1"`](/docs/en/model-config#extended-context) in the same `env` block. Claude Code then treats every model as having a 200K window. In interactive sessions, each developer approves this variable in the [approval dialog](#what-goes-in-cli) before it takes effect.
1019To turn off 1M context instead, set [`CLAUDE_CODE_DISABLE_1M_CONTEXT: "1"`](https://code.claude.com/docs/en/model-config#extended-context) in the same `env` block. Claude Code then treats every model as having a 200K window. In interactive sessions, each developer approves this variable in the [approval dialog](#what-goes-in-cli) before it takes effect.
10201020 
10211021#### One-hour prompt cache
10221022 
1023To request the one-hour [prompt cache TTL](/docs/en/prompt-caching.md#cache-lifetime) instead of the default five minutes, add these keys to a policy's existing [`code`, `cli`, or `settings` block](#choose-cli-or-code) and restart the gateway. The keys need Claude Code v2.1.242 or later on the gateway server and on clients.
1023To request the one-hour [prompt cache TTL](https://code.claude.com/docs/en/prompt-caching.md#cache-lifetime) instead of the default five minutes, add these keys to a policy's existing [`code`, `cli`, or `settings` block](#choose-cli-or-code) and restart the gateway. The keys need Claude Code v2.1.242 or later on the gateway server and on clients.
10241024 
10251025`promptCacheTtl` covers the main conversation. `subagentPromptCacheTtl` is optional and covers subagents, workflows, and background requests. This example adds both to a `match: {}` policy keyed `cli`:
10261026 
from line 1037
10371037>
10381038> Set the keys only if your upstreams offer the one-hour TTL for every model the gateway serves. If an upstream rejects the TTL, the request fails, and neither the gateway nor Claude Code retries it with the five-minute TTL. For Amazon Bedrock, check [supported models, regions, and limits](https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html#prompt-caching-models).
10391039 
1040To confirm `promptCacheTtl`, sign in to the gateway as a user the policy matches and [check which TTL your cache writes used](/docs/en/prompt-caching.md#choose-the-ttl-yourself). Pass `--model` to repeat the check for each model the gateway serves.
1040To confirm `promptCacheTtl`, sign in to the gateway as a user the policy matches and [check which TTL your cache writes used](https://code.claude.com/docs/en/prompt-caching.md#choose-the-ttl-yourself). Pass `--model` to repeat the check for each model the gateway serves.
10411041 
1042One-hour cache writes [cost more](/docs/en/prompt-caching.md#cache-lifetime) than five-minute writes. For [spend limits](/docs/en/claude-apps-gateway-spend-limits.md#how-requests-are-priced) to count that higher rate, you need v2.1.286 or later on the gateway server.
1042One-hour cache writes [cost more](https://code.claude.com/docs/en/prompt-caching.md#cache-lifetime) than five-minute writes. For [spend limits](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md#how-requests-are-priced) to count that higher rate, you need v2.1.286 or later on the gateway server.
10431043 
10441044#### MCP servers in a policy
10451045 
1046To provide MCP servers to the Claude Code clients a policy matches, set [`managedMcpServers`](/docs/en/managed-mcp#provide-servers-through-managed-settings) in that policy's `cli` block. You need Claude Code v2.1.259 or later on the gateway server and on clients.
1046To provide MCP servers to the Claude Code clients a policy matches, set [`managedMcpServers`](https://code.claude.com/docs/en/managed-mcp#provide-servers-through-managed-settings) in that policy's `cli` block. You need Claude Code v2.1.259 or later on the gateway server and on clients.
10471047 
1048The gateway checks each entry at boot with [the same rules Claude Code applies on the client](/docs/en/managed-mcp.md#what-an-entry-can-contain), and if an entry fails a check, the gateway refuses to start and names the entry.
1048The gateway checks each entry at boot with [the same rules Claude Code applies on the client](https://code.claude.com/docs/en/managed-mcp.md#what-an-entry-can-contain), and if an entry fails a check, the gateway refuses to start and names the entry.
10491049 
1050If you write a `${VAR}` reference in `gateway.yaml`, the gateway resolves it from its environment at boot through [secret expansion](#secret-expansion) before it runs the entry checks, so every matching client receives the literal value and can read it. The [header guidance for provided servers](/docs/en/managed-mcp.md#provide-servers-through-managed-settings) applies to the expanded value.
1050If you write a `${VAR}` reference in `gateway.yaml`, the gateway resolves it from its environment at boot through [secret expansion](#secret-expansion) before it runs the entry checks, so every matching client receives the literal value and can read it. The [header guidance for provided servers](https://code.claude.com/docs/en/managed-mcp.md#provide-servers-through-managed-settings) applies to the expanded value.
10511051 
10521052The gateway rejects the `.mcp.json` spelling `mcpServers` in a `cli` block, and its boot error names `managedMcpServers` as the key to use. Before v2.1.259, the gateway rejected any MCP server definition in a `cli` block.
10531053 
10541054#### Claude Desktop overlay
10551055 
1056If your organization also deploys [Claude Desktop](/docs/en/desktop.md), the same gateway serves both clients. Point `bootstrapUrl`, in Claude Desktop's [managed configuration](https://claude.com/docs/third-party/claude-desktop/configuration), at `<listen.public_url>/user/bootstrap`. Claude Desktop derives the OAuth issuer from that URL, runs the same device-code sign-in against this gateway, and fetches its configuration from the response.
1056If your organization also deploys [Claude Desktop](https://code.claude.com/docs/en/desktop.md), the same gateway serves both clients. Point `bootstrapUrl`, in Claude Desktop's [managed configuration](https://claude.com/docs/third-party/claude-desktop/configuration), at `<listen.public_url>/user/bootstrap`. Claude Desktop derives the OAuth issuer from that URL, runs the same device-code sign-in against this gateway, and fetches its configuration from the response.
10571057 
10581058> [!NOTE]
10591059>
from line 1067
10671067 
10681068* The model list, from `availableModels`. The list leaves out models that the policy blocks with [`deniedModels` or `availableModelsMatch: exact`](#what-goes-in-cli). This filter requires Claude Code v2.1.299 or later on the gateway server. [Extended context in Claude Desktop](#extended-context-in-claude-desktop) covers each model's 1M context option
10691069* Disabled tools, from bare tool-name `permissions.deny` entries. If you set `disabledBuiltinTools` in the policy's `desktop` block, the gateway serves the union of your value and the derived list, so you can disable more tools this way but can't re-enable one you disabled through `permissions.deny`
1070* The egress allowlist, from `sandbox.network.allowedDomains`. If you set `coworkEgressAllowedHosts` in the policy's `desktop` block, the gateway uses that value instead of the derived list. If the allowlist the gateway serves includes `*` and the gateway doesn't also serve Claude Desktop's [`allowedWorkspaceFolders`](https://claude.com/docs/third-party/claude-desktop/code#applied-as-managed-policy), Claude Desktop doesn't turn on the [Bash sandbox](/docs/en/sandboxing.md) in the Code tab
1070* The egress allowlist, from `sandbox.network.allowedDomains`. If you set `coworkEgressAllowedHosts` in the policy's `desktop` block, the gateway uses that value instead of the derived list. If the allowlist the gateway serves includes `*` and the gateway doesn't also serve Claude Desktop's [`allowedWorkspaceFolders`](https://claude.com/docs/third-party/claude-desktop/code#applied-as-managed-policy), Claude Desktop doesn't turn on the [Bash sandbox](https://code.claude.com/docs/en/sandboxing.md) in the Code tab
10711071* An OTLP endpoint that points at the gateway itself, and the signed-in user's identity attributes. The gateway relays the exports it receives at that endpoint to your `forward_to` destinations. It includes the endpoint and the attributes when you set both [`telemetry.forward_to`](#telemetry) and `listen.public_url`.
10721072 
10731073 Claude Desktop exports every signal with one encoding: `http/protobuf`, or `http/json` when you set `OTEL_EXPORTER_OTLP_PROTOCOL` or one of its per-signal variants to `http/json` in the policy's `env`. Before Claude Code v2.1.261 on the gateway server, the response set `http/json` regardless, so a collector that accepts only protobuf rejected Claude Desktop's exports
from line 1095
10951095 
10961096When a proxy in front of the gateway answers `/managed/settings` with its own 404, the Code tab also starts without your `code` settings, including on a machine that meets all four conditions.
10971097 
1098In a policy that has a `desktop` key, a `code` block that holds settings turns off the WebSearch tool in Cowork, Chat, and the Code tab. For MCP servers, see [Where `managedMcpServers` applies](/docs/en/managed-mcp#where-managedmcpservers-applies).
1098In a policy that has a `desktop` key, a `code` block that holds settings turns off the WebSearch tool in Cowork, Chat, and the Code tab. For MCP servers, see [Where `managedMcpServers` applies](https://code.claude.com/docs/en/managed-mcp#where-managedmcpservers-applies).
10991099 
11001100##### Set Claude Desktop settings directly
11011101 
from line 1159
11591159 
11601160#### Extended context in Claude Desktop
11611161 
1162If you serve [Claude Desktop](#claude-desktop-overlay) from the gateway, its model picker offers a 1M context option for each listed model that can run with a 1M context window. These include Claude Opus 4.6 and later, Claude Sonnet 4.6 and later, and the Fable models. The option is the model's `[1m]` variant, which [Extended context](/docs/en/model-config.md#extended-context) describes. You need Claude Code v2.1.284 or later on the gateway server.
1162If you serve [Claude Desktop](#claude-desktop-overlay) from the gateway, its model picker offers a 1M context option for each listed model that can run with a 1M context window. These include Claude Opus 4.6 and later, Claude Sonnet 4.6 and later, and the Fable models. The option is the model's `[1m]` variant, which [Extended context](https://code.claude.com/docs/en/model-config.md#extended-context) describes. You need Claude Code v2.1.284 or later on the gateway server.
11631163 
11641164A [`models`](#models) entry gets no 1M option when:
11651165 
from line 1193
11931193 
11941194To remove the option from the picker, set `CLAUDE_CODE_DISABLE_1M_CONTEXT: "1"` in the `env` block under the policy's `cli` key. If you also listed an entry whose `id` ends in `[1m]`, the gateway still serves it, so delete that entry too.
11951195 
1196The variable also reaches the terminal sessions of developers the policy matches. For what it changes there, see [Extended context](/docs/en/model-config.md#extended-context).
1196The variable also reaches the terminal sessions of developers the policy matches. For what it changes there, see [Extended context](https://code.claude.com/docs/en/model-config.md#extended-context).
11971197 
11981198#### Precedence with other managed sources
11991199 
1200If a device also has an MDM-delivered policy or a local `managed-settings.json`, gateway-delivered settings rank first. [Precedence within the managed tier](/docs/en/managed-settings.md#precedence-within-the-managed-tier) on the managed settings page says when the local sources apply, and has the [keys Claude Code reads from every admin source](/docs/en/managed-settings.md#keys-read-from-every-admin-source) regardless of which source it selected, such as the sandbox lock keys, `forceRemoteSettingsRefresh`, and the per-variable `env` merge. A [`policyHelper`](/docs/en/settings-reference#policyhelper) configured in an MDM profile or the managed settings file runs only when the gateway delivers no settings; the entry says what its output replaces.
1200If a device also has an MDM-delivered policy or a local `managed-settings.json`, gateway-delivered settings rank first. [Precedence within the managed tier](https://code.claude.com/docs/en/managed-settings.md#precedence-within-the-managed-tier) on the managed settings page says when the local sources apply, and has the [keys Claude Code reads from every admin source](https://code.claude.com/docs/en/managed-settings.md#keys-read-from-every-admin-source) regardless of which source it selected, such as the sandbox lock keys, `forceRemoteSettingsRefresh`, and the per-variable `env` merge. A [`policyHelper`](https://code.claude.com/docs/en/settings-reference#policyhelper) configured in an MDM profile or the managed settings file runs only when the gateway delivers no settings; the entry says what its output replaces.
12011201 
1202Embedding hosts such as [Claude Desktop](/docs/en/desktop.md) can supply policy through the SDK `managedSettings` option. [Parent settings from embedding hosts](/docs/en/managed-settings.md#parent-settings-from-embedding-hosts) says when Claude Code applies it, and [Restrict parent settings](/docs/en/claude-apps-gateway#restrict-parent-settings) lists which allow-direction settings still apply without the `allowManaged*Only` locks.
1202Embedding hosts such as [Claude Desktop](https://code.claude.com/docs/en/desktop.md) can supply policy through the SDK `managedSettings` option. [Parent settings from embedding hosts](https://code.claude.com/docs/en/managed-settings.md#parent-settings-from-embedding-hosts) says when Claude Code applies it, and [Restrict parent settings](https://code.claude.com/docs/en/claude-apps-gateway#restrict-parent-settings) lists which allow-direction settings still apply without the `allowManaged*Only` locks.
12031203 
12041204Gateway policies apply to every Claude Code invocation on the machine, including non-interactive `claude -p` runs and sessions spawned by the Agent SDK. If the gateway is unreachable at startup, signed-in sessions exit with an error rather than running without their policy.
12051205 
12061206### `telemetry`
12071207 
1208The CLI sends metrics, logs, and, when enabled, traces to the gateway, which relays them verbatim to each configured destination. The exports use OpenTelemetry Protocol (OTLP) over HTTP. To skip the relay and have sessions export straight to your collector, [name the collector in a policy](#export-directly-to-your-collector). See [Monitoring usage](/docs/en/monitoring-usage.md) for the metrics and events the CLI emits.
1208The CLI sends metrics, logs, and, when enabled, traces to the gateway, which relays them verbatim to each configured destination. The exports use OpenTelemetry Protocol (OTLP) over HTTP. To skip the relay and have sessions export straight to your collector, [name the collector in a policy](#export-directly-to-your-collector). See [Monitoring usage](https://code.claude.com/docs/en/monitoring-usage.md) for the metrics and events the CLI emits.
12091209 
1210In sessions signed in through `/login`, the CLI stamps each export with the authenticated user's identity, read from the gateway-issued JWT: the `user.id`, `user.email`, and `user.groups` attributes. Per-developer cost and usage attribution therefore works with no developer-side configuration. Events that Claude Code logs before the developer signs in [don't carry this identity](/docs/en/monitoring-usage.md#standard-attributes). To see which attribute follows a change in a developer's groups, see [Group changes during an open session](#group-changes-during-an-open-session).
1210In sessions signed in through `/login`, the CLI stamps each export with the authenticated user's identity, read from the gateway-issued JWT: the `user.id`, `user.email`, and `user.groups` attributes. Per-developer cost and usage attribution therefore works with no developer-side configuration. Events that Claude Code logs before the developer signs in [don't carry this identity](https://code.claude.com/docs/en/monitoring-usage.md#standard-attributes). To see which attribute follows a change in a developer's groups, see [Group changes during an open session](#group-changes-during-an-open-session).
12111211 
12121212[Claude Desktop](#claude-desktop-overlay) and Cowork sessions signed in through the gateway stamp their telemetry with `user.email` and `user.groups` alongside `enduser.id`, so you can cover terminal, Desktop, and Cowork usage with one query on `user.email` or `user.groups`. `user.groups` is the comma-separated IdP group list.
12131213 
from line 1249
12491249 
12501250Each `forward_to` URL must use `https://`, with one exception for a collector on the gateway's own loopback interface:
12511251 
1252* `http://localhost:<port>` passes config validation, but the [SSRF guard](/docs/en/claude-apps-gateway-deploy.md#threat-model-summary) blocks every export with `ECONNREFUSED_SSRF` unless you set `CLAUDE_GATEWAY_ALLOW_LOOPBACK=1` in the gateway's environment
1252* `http://localhost:<port>` passes config validation, but the [SSRF guard](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#threat-model-summary) blocks every export with `ECONNREFUSED_SSRF` unless you set `CLAUDE_GATEWAY_ALLOW_LOOPBACK=1` in the gateway's environment
12531253* `http://127.0.0.1:<port>` or `http://[::1]:<port>` fails boot unless that variable is set
12541254 
12551255For an in-cluster collector, expose it over HTTPS at its own internal address, or run it as a sidecar with the variable set.
from line 1280
12801280 
12811281Without a `forward_to` destination for a signal, the gateway accepts and discards it. If developers already export Claude Code telemetry to one of your collectors, add it as a `forward_to` destination, with logs or traces enabled if they export those, so it keeps receiving their data after they sign in. To skip the relay instead, [name the collector in a policy](#export-directly-to-your-collector).
12821282 
1283[Traces](/docs/en/monitoring-usage.md#traces-beta) also require `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1` on each client. Set it in a managed policy's `env` block, since the gateway doesn't push it. Developers approve it in the same [security approval dialog](#managed) that the pushed endpoint already triggers.
1283[Traces](https://code.claude.com/docs/en/monitoring-usage.md#traces-beta) also require `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1` on each client. Set it in a managed policy's `env` block, since the gateway doesn't push it. Developers approve it in the same [security approval dialog](#managed) that the pushed endpoint already triggers.
12841284 
12851285Set it to `1` only in the policies whose groups you want traced. A policy that doesn't set it inherits the value from your `match: {}` catch-all policy if that policy sets one, per the [merge rules](#managed). To keep a group's clients from sending traces even when a developer sets the variable locally, set it to `0` in that group's policy.
12861286 
from line 1288
12881288 
12891289#### Send cumulative metrics
12901290 
1291If your collector accepts only cumulative metrics, set [`OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE`](/docs/en/monitoring-usage#common-configuration-variables) to `cumulative`. Claude Code sends delta metrics by default, and the gateway relays them without converting them. Set the variable where each kind of session reads it:
1291If your collector accepts only cumulative metrics, set [`OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE`](https://code.claude.com/docs/en/monitoring-usage#common-configuration-variables) to `cumulative`. Claude Code sends delta metrics by default, and the gateway relays them without converting them. Set the variable where each kind of session reads it:
12921292 
12931293* **Terminal sessions**: in the `env` block under a policy's [`cli` or `code` key](#choose-cli-or-code)
1294* **Cowork sessions that [run on the user's machine](/docs/en/managed-settings.md#where-and-when-a-policy-applies)**: in the `env` block of the [client-side managed settings](#client-side-managed-settings) on that machine
1294* **Cowork sessions that [run on the user's machine](https://code.claude.com/docs/en/managed-settings.md#where-and-when-a-policy-applies)**: in the `env` block of the [client-side managed settings](#client-side-managed-settings) on that machine
12951295* **Code tab sessions under a `code` policy**: in the policy's `env` block, once you meet the [conditions for `code` settings to apply](#apply-code-settings-in-the-code-tab)
12961296* **Code tab sessions under a `cli` policy**: in the `env` block of the client-side managed settings on the machine that runs the session. Over SSH, that's the remote host.
12971297 
1298If you add the variable to a machine's managed settings, also set [`parentSettingsBehavior: "merge"`](/docs/en/claude-apps-gateway#set-the-opt-in) in the highest-priority source on that machine. Without it, Cowork sessions and Code tab sessions under a `cli` policy run without the egress allowlist and other policy that Claude Desktop passes them as parent settings.
1298If you add the variable to a machine's managed settings, also set [`parentSettingsBehavior: "merge"`](https://code.claude.com/docs/en/claude-apps-gateway#set-the-opt-in) in the highest-priority source on that machine. Without it, Cowork sessions and Code tab sessions under a `cli` policy run without the egress allowlist and other policy that Claude Desktop passes them as parent settings.
12991299 
13001300#### Add your own labels
13011301 
from line 1324
13241324 
13251325Terminal sessions signed in through `/login` receive the labels as `OTEL_RESOURCE_ATTRIBUTES`, pushed with the other [telemetry variables](#telemetry). If you set `OTEL_RESOURCE_ATTRIBUTES` in a policy's `env` block, terminal sessions that policy matches get that value instead of the labels. Claude Desktop receives the labels from the gateway alongside `user.email` and the other identity attributes.
13261326 
1327Claude Code also copies each label onto every metric data point, so you can filter metrics by it in a backend that doesn't index resource attributes. To turn that copy off, see [Metrics cardinality control](/docs/en/monitoring-usage.md#metrics-cardinality-control).
1327Claude Code also copies each label onto every metric data point, so you can filter metrics by it in a backend that doesn't index resource attributes. To turn that copy off, see [Metrics cardinality control](https://code.claude.com/docs/en/monitoring-usage.md#metrics-cardinality-control).
13281328 
13291329#### Group changes during an open session
13301330 
from line 1358
13581358* The URL uses `https://`, or `http://` to a loopback address
13591359* The URL resolves to a path ending in `/v1/<signal>`, with no query or fragment. Claude Code builds that path itself from the generic variable. It uses a per-signal variable such as `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` as written, so include the full path there.
13601360* The URL isn't the gateway's own host. An endpoint addressed to the gateway keeps the relay path and its session token.
1361* Neither you nor the developer has configured [`otelHeadersHelper`](/docs/en/settings-reference#otelheadershelper) in any settings source. With a helper configured, every signal stays on the relay.
1361* Neither you nor the developer has configured [`otelHeadersHelper`](https://code.claude.com/docs/en/settings-reference#otelheadershelper) in any settings source. With a helper configured, every signal stays on the relay.
13621362 
13631363The endpoint you name changes only where exports go. You still choose which signals export at all with the `OTEL_*_EXPORTER` selectors.
13641364 
from line 1385
13851385| - | - | - | - |
13861386| `access_control` | `allow_cidrs` / `deny_cidrs` | empty | Inbound IP allow/deny by client address, after `trusted_proxies` resolution. `deny_cidrs` is checked first; a client it matches is rejected even if `allow_cidrs` also matches. If `allow_cidrs` is non-empty the gateway is default-deny. `/healthz` and `/readyz` are exempt from `allow_cidrs`. When a trusted proxy sends an `X-Forwarded-For` entry that isn't an IP address, the real client is unknown and the gateway logs a warning once naming what to check. Where either list applies to the request, it refuses it with `403` and audit reason `xff_unparseable`. Where neither does, it serves the request and uses the proxy's own address as the client IP for per-IP rate limits and audit. |
13871387| `limits` | `max_request_bytes` | 32 MiB | Max inbound request body; oversize requests get `413` before the body is buffered. Raise for large file or image requests. |
1388| `limits` | `max_request_header_bytes` | unset | Lowers the gateway's 256 KiB limit on a request's total headers. A request over the limit returns `431`, and a value above 256 KiB has no effect. If developers get `431` after signing in, see [Request headers too large after sign-in](/docs/en/claude-apps-gateway-deploy.md#request-headers-too-large-after-sign-in). |
1388| `limits` | `max_request_header_bytes` | unset | Lowers the gateway's 256 KiB limit on a request's total headers. A request over the limit returns `431`, and a value above 256 KiB has no effect. If developers get `431` after signing in, see [Request headers too large after sign-in](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#request-headers-too-large-after-sign-in). |
13891389| `limits` | `max_url_length` | unset | When set, an over-long URL returns `414` |
13901390| `timeouts` | `upstream_ttfb_ms` | 120000 | Max wait for the upstream's response headers (time to first byte). The response body then streams with no wall-clock cap. Applies to the direct Anthropic upstream path; on every other provider the gateway waits up to one hour for the response to start. |
1391| `rate_limits` | `device_authorization.max` / `.window_seconds` | 30 / 600 | Per-IP rate limit on the unauthenticated device-authorization endpoint. Raise for a large org behind a shared egress IP or NAT. [Large rollouts](/docs/en/claude-apps-gateway-deploy.md#large-rollouts) shows how to size it. These limits apply only to the device-grant sign-in flow, not to `/v1/messages` inference. See [User-code brute-force resistance](/docs/en/claude-apps-gateway-deploy.md#user-code-brute-force-resistance). |
1392| `rate_limits` | `device_verify.max` / `.window_seconds` | 10 / 600 | Per-IP rate limit on `user_code` submissions at `/device`. It is what stops someone from guessing another developer's code. [Large rollouts](/docs/en/claude-apps-gateway-deploy.md#large-rollouts) shows how far to raise it. |
1391| `rate_limits` | `device_authorization.max` / `.window_seconds` | 30 / 600 | Per-IP rate limit on the unauthenticated device-authorization endpoint. Raise for a large org behind a shared egress IP or NAT. [Large rollouts](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#large-rollouts) shows how to size it. These limits apply only to the device-grant sign-in flow, not to `/v1/messages` inference. See [User-code brute-force resistance](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#user-code-brute-force-resistance). |
1392| `rate_limits` | `device_verify.max` / `.window_seconds` | 10 / 600 | Per-IP rate limit on `user_code` submissions at `/device`. It is what stops someone from guessing another developer's code. [Large rollouts](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#large-rollouts) shows how far to raise it. |
13931393 
13941394If you leave both `access_control` lists empty, which is the default, the gateway serves any client address, so only your network restricts who can reach it. That matters because a gateway can push [managed settings](#managed) that run commands on developer machines.
13951395 
from line 1396
13961396While `allow_cidrs` is empty, the gateway warns in two places, without changing how it answers any request:
13971397 
13981398* **At boot**: a warning in the operational log recommends allowing only the private ranges `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `100.64.0.0/10`, `127.0.0.0/8`, `::1/128`, and `fc00::/7`, plus any other internal ranges your developers connect from. If you bind the gateway to a loopback address and set neither `trusted_proxies` nor `public_url`, as in local development, the warning doesn't appear.
1399* **At runtime**: the first time a request arrives from an address outside those private ranges, the gateway logs a warning and emits an [`access.public_client` audit event](/docs/en/claude-apps-gateway-deploy#logs) carrying the client IP. Both fire once per process. Link-local addresses, `169.254.0.0/16` and `fe80::/10`, don't count as public. The gateway answers `/healthz` and `/readyz` before this check runs, so health probes from public ranges don't trigger it.
1399* **At runtime**: the first time a request arrives from an address outside those private ranges, the gateway logs a warning and emits an [`access.public_client` audit event](https://code.claude.com/docs/en/claude-apps-gateway-deploy#logs) carrying the client IP. Both fire once per process. Link-local addresses, `169.254.0.0/16` and `fe80::/10`, don't count as public. The gateway answers `/healthz` and `/readyz` before this check runs, so health probes from public ranges don't trigger it.
14001400 
14011401Both signals use the client address as the gateway resolves it. If a load balancer, port-forward, or tunnel relays traffic and isn't listed in `listen.trusted_proxies`, the gateway sees the relay's address, which is usually private, so neither the runtime warning nor a private allow list catches traffic relayed through it.
14021402 
from line 1433
14331433 
14341434> [!WARNING]
14351435>
1436> Never turn this on for a gateway that developers use. Every request gets the canned reply and no model is called. The gateway logs a `load_test_mode is on` warning at boot and marks each `inference` [audit event](/docs/en/claude-apps-gateway-deploy.md#logs) with `load_test: true` while the mode is on.
1436> Never turn this on for a gateway that developers use. Every request gets the canned reply and no model is called. The gateway logs a `load_test_mode is on` warning at boot and marks each `inference` [audit event](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#logs) with `load_test: true` while the mode is on.
14371437 
14381438## Complete example
14391439 
1440This full reference config exercises every core section; the [HTTP tuning blocks](#http-tuning) keep their defaults. Copy it, delete what you don't need, and fill in your values. The config in the [Quickstart](/docs/en/claude-apps-gateway#quickstart) is a minimal version of this.
1440This full reference config exercises every core section; the [HTTP tuning blocks](#http-tuning) keep their defaults. Copy it, delete what you don't need, and fill in your values. The config in the [Quickstart](https://code.claude.com/docs/en/claude-apps-gateway#quickstart) is a minimal version of this.
14411441 
14421442```yaml gateway.yaml theme={null}
14431443# Run with:
from line 1598
15981598 
15991599## Client-side managed settings
16001600 
1601Everything above configures the gateway server. You point developer machines at the gateway separately, on each device, through Claude Code's [managed settings](/docs/en/managed-settings.md). The gateway can't push the login keys itself, because they're what tell the client where the gateway is.
1601Everything above configures the gateway server. You point developer machines at the gateway separately, on each device, through Claude Code's [managed settings](https://code.claude.com/docs/en/managed-settings.md). The gateway can't push the login keys itself, because they're what tell the client where the gateway is.
16021602 
16031603For the CLI, set these keys in the per-OS `managed-settings.json`. The two login keys route each developer's `/login` to your gateway:
16041604 
from line 1610
16101610}
16111611```
16121612 
1613`parentSettingsBehavior: "merge"` keeps Claude Desktop's delivery of the egress allowlist to its embedded Claude Code sessions working; [Deliver policy to Claude Desktop sessions](/docs/en/claude-apps-gateway#deliver-policy-to-claude-desktop-sessions) explains the mechanism and where the opt-in must sit.
1613`parentSettingsBehavior: "merge"` keeps Claude Desktop's delivery of the egress allowlist to its embedded Claude Code sessions working; [Deliver policy to Claude Desktop sessions](https://code.claude.com/docs/en/claude-apps-gateway#deliver-policy-to-claude-desktop-sessions) explains the mechanism and where the opt-in must sit.
16141614 
1615To stop developers from bypassing the gateway with a cloud provider variable or an `ANTHROPIC_BASE_URL` of their own, add `"allowedProviders": ["gateway"]` to the same file. Claude Code then refuses every session on the machine that isn't set up for a Cloud gateway, and admits a gateway only when it is the one `forceLoginGatewayUrl` names or one whose URL the file's `env` block sets as `ANTHROPIC_BASE_URL`. `claude gateway` refuses to run on a machine that sets the list, so keep the key off the gateway host. See the [`allowedProviders`](/docs/en/settings-reference#allowedproviders) entry in the settings reference. Requires Claude Code v2.1.285 or later.
1615To stop developers from bypassing the gateway with a cloud provider variable or an `ANTHROPIC_BASE_URL` of their own, add `"allowedProviders": ["gateway"]` to the same file. Claude Code then refuses every session on the machine that isn't set up for a Cloud gateway, and admits a gateway only when it is the one `forceLoginGatewayUrl` names or one whose URL the file's `env` block sets as `ANTHROPIC_BASE_URL`. `claude gateway` refuses to run on a machine that sets the list, so keep the key off the gateway host. See the [`allowedProviders`](https://code.claude.com/docs/en/settings-reference#allowedproviders) entry in the settings reference. Requires Claude Code v2.1.285 or later.
16161616 
1617Deploy the `managed-settings.json` file to each device, typically via your MDM platform. The file path differs by platform. See [where each mechanism stores the policy](/docs/en/managed-settings.md#where-each-mechanism-stores-the-policy).
1617Deploy the `managed-settings.json` file to each device, typically via your MDM platform. The file path differs by platform. See [where each mechanism stores the policy](https://code.claude.com/docs/en/managed-settings.md#where-each-mechanism-stores-the-policy).
16181618 
16191619By default, a registry policy on Windows or a managed-preferences plist on macOS replaces the `managed-settings.json` file rather than merging with it, apart from the [exception keys and cross-source checks above](#precedence-with-other-managed-sources). All three keys in this snippet follow the highest-priority-source rule, so fleets that deliver policy through Group Policy or configuration profiles must put all three in that mechanism instead.
16201620 
16211621For Claude Desktop, set the `bootstrapUrl` key in Claude Desktop's own [managed configuration](https://claude.com/docs/third-party/claude-desktop/configuration) to `<listen.public_url>/user/bootstrap`. The sign-in flow and per-group policy then match the CLI's once a policy opts in server-side with a `desktop` key; without the opt-in, `/user/bootstrap` returns 404. See [Claude Desktop overlay](#claude-desktop-overlay) for the server-side half.
16221622 
1623Claude Code honors [`forceLoginGatewayUrl`](/docs/en/settings-reference#forcelogingatewayurl), [`gatewayInternalNetworks`](/docs/en/settings-reference#gatewayinternalnetworks), and the `"gateway"` value of [`forceLoginMethod`](/docs/en/settings-reference#forceloginmethod) from a managed source on the machine: `managed-settings.json`, the macOS plist or Windows HKLM registry, or a policy helper. Setting them in the gateway payload doesn't configure the gateway sign-in. For a developer's own `~/.claude/settings.json`, see [Set the gateway URL in user settings](/docs/en/claude-apps-gateway#set-the-gateway-url-in-user-settings).
1623Claude Code honors [`forceLoginGatewayUrl`](https://code.claude.com/docs/en/settings-reference#forcelogingatewayurl), [`gatewayInternalNetworks`](https://code.claude.com/docs/en/settings-reference#gatewayinternalnetworks), and the `"gateway"` value of [`forceLoginMethod`](https://code.claude.com/docs/en/settings-reference#forceloginmethod) from a managed source on the machine: `managed-settings.json`, the macOS plist or Windows HKLM registry, or a policy helper. Setting them in the gateway payload doesn't configure the gateway sign-in. For a developer's own `~/.claude/settings.json`, see [Set the gateway URL in user settings](https://code.claude.com/docs/en/claude-apps-gateway#set-the-gateway-url-in-user-settings).
16241624 
1625Leave `forceLoginMethod` and `forceLoginOrgUUID` out of the payload. Claude Code still reads both keys from the payload for its startup credential check, so a developer who keeps an Anthropic-issued credential on the machine gets the startup exit described under [Administrator policy requires a Cloud gateway sign-in](/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in) even after they sign in.
1625Leave `forceLoginMethod` and `forceLoginOrgUUID` out of the payload. Claude Code still reads both keys from the payload for its startup credential check, so a developer who keeps an Anthropic-issued credential on the machine gets the startup exit described under [Administrator policy requires a Cloud gateway sign-in](https://code.claude.com/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in) even after they sign in.
16261626 
16271627## Related
16281628 
1629* [Claude apps gateway overview](/docs/en/claude-apps-gateway): quickstart and developer connection
1630* [Deployment guide](/docs/en/claude-apps-gateway-deploy.md): IdP setup, container image, Kubernetes and Cloud Run, and operations
1631* [Spend limits](/docs/en/claude-apps-gateway-spend-limits.md): per-developer caps and the Admin API
1629* [Claude apps gateway overview](https://code.claude.com/docs/en/claude-apps-gateway): quickstart and developer connection
1630* [Deployment guide](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md): IdP setup, container image, Kubernetes and Cloud Run, and operations
1631* [Spend limits](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md): per-developer caps and the Admin API
16321632 
Feedback