SpyBara
Go Premium

Documentation 2026-07-28 23:57 UTC to 2026-07-29 19:02 UTC

82 files changed +1,794 −737. View all changes and history on the product overview
2026
Wed 29 19:02 Tue 28 23:57 Mon 27 21:02 Sun 26 19:02 Sat 25 21:59 Fri 24 23:01 Thu 23 23:57 Wed 22 23:59 Tue 21 23:00 Mon 20 23:01 Sat 18 16:02 Fri 17 22:57 Thu 16 22:59 Wed 15 22:00 Tue 14 23:01 Mon 13 23:57 Sat 11 19:03 Fri 10 17:00 Thu 9 23:58 Wed 8 16:02 Tue 7 16:02 Mon 6 23:57 Sat 4 03:01 Fri 3 23:00 Thu 2 23:59 Wed 1 21:01
Details

31When the mode is on, the first thing Claude Code prints is a confirmation line naming the method that turned it on: `[Screen Reader Mode: on via flag]`, `[Screen Reader Mode: on via env]`, or `[Screen Reader Mode: on via settings]`. The method-naming format requires Claude Code v2.1.206 or later. When Claude Code relaunches itself, for example to finish installing an update, the new process inherits the mode through the `CLAUDE_AX_SCREEN_READER` environment variable, so its confirmation line reads `[Screen Reader Mode: on via env]` regardless of which method you used.31When the mode is on, the first thing Claude Code prints is a confirmation line naming the method that turned it on: `[Screen Reader Mode: on via flag]`, `[Screen Reader Mode: on via env]`, or `[Screen Reader Mode: on via settings]`. The method-naming format requires Claude Code v2.1.206 or later. When Claude Code relaunches itself, for example to finish installing an update, the new process inherits the mode through the `CLAUDE_AX_SCREEN_READER` environment variable, so its confirmation line reads `[Screen Reader Mode: on via env]` regardless of which method you used.

32{/* max-version: 2.1.205 */}Earlier versions print `[Accessible screen reader mode: on]`.32{/* max-version: 2.1.205 */}Earlier versions print `[Accessible screen reader mode: on]`.

33 33 

34After printing the confirmation line, Claude Code holds the rest of the interface back for three seconds so your screen reader can finish speaking the line, then renders the first prompt. Press any key to end the hold early. To change the hold's length, set the `CLAUDE_AX_STARTUP_QUIET_MS` environment variable to a number of milliseconds. The default is `3000`; set it to `0` to skip the hold. Claude Code caps the hold at `600000` milliseconds, 10 minutes. Requires Claude Code v2.1.217 or later.

35 

34## Turn off screen reader mode36## Turn off screen reader mode

35 37 

36Reverse whichever method turned the mode on: start without the flag, unset the environment variable, or set `axScreenReader` to `false`. Setting `CLAUDE_AX_SCREEN_READER=0` keeps the mode off even when the setting is `true`.38Reverse whichever method turned the mode on: start without the flag, unset the environment variable, or set `axScreenReader` to `false`. Setting `CLAUDE_AX_SCREEN_READER=0` keeps the mode off even when the setting is `true`.


62 64 

63The terminal cursor follows the input caret, so a screen reader's read-current-line command answers "where am I" with the prompt you're editing.65The terminal cursor follows the input caret, so a screen reader's read-current-line command answers "where am I" with the prompt you're editing.

64 66 

67{/* min-version: 2.1.219 */}As you type at the end of the input line, Claude Code writes only the characters you type, so your screen reader echoes only those characters. Requires Claude Code v2.1.219 or later; earlier versions rewrite the whole input line on every keystroke, so the screen reader re-reads it as you type.

68 

65{/* min-version: 2.1.218 */}When you delete a word or a line in the input, Claude Code announces the deleted text. Requires Claude Code v2.1.218 or later. The announcement covers:69{/* min-version: 2.1.218 */}When you delete a word or a line in the input, Claude Code announces the deleted text. Requires Claude Code v2.1.218 or later. The announcement covers:

66 70 

67* Deleting a word with `Ctrl+W`, `Option+Delete` on macOS, or `Ctrl+Backspace` on Windows71* Deleting a word with `Ctrl+W`, `Option+Delete` on macOS, or `Ctrl+Backspace` on Windows

Details

14 14 

15Every agent session follows the same cycle:15Every agent session follows the same cycle:

16 16 

17<img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/agent-loop-diagram.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=1c6e8f28d80dba14a7287419656f1237" alt="Diagram of the agent loop: your prompt enters the agentic loop, where Claude evaluates and either requests tool calls, whose results feed back into another evaluation, or returns the final answer" width="720" height="212" data-path="images/agent-loop-diagram.svg" />17<img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/agent-loop-diagram.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=1c6e8f28d80dba14a7287419656f1237" className="dark:hidden" alt="Diagram of the agent loop: your prompt enters the agentic loop, where Claude evaluates and either requests tool calls, whose results feed back into another evaluation, or returns the final answer" width="720" height="212" data-path="images/agent-loop-diagram.svg" />

18 

19<img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/agent-loop-diagram-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=afe723c52a324d3c61fa72fb02432ab6" className="hidden dark:block" alt="Diagram of the agent loop: your prompt enters the agentic loop, where Claude evaluates and either requests tool calls, whose results feed back into another evaluation, or returns the final answer" width="720" height="212" data-path="images/agent-loop-diagram-dark.svg" />

18 20 

191. **Receive prompt.** Claude receives your prompt, along with the system prompt, tool definitions, and conversation history. The SDK yields a [`SystemMessage`](#message-types) with subtype `"init"` containing session metadata.211. **Receive prompt.** Claude receives your prompt, along with the system prompt, tool definitions, and conversation history. The SDK yields a [`SystemMessage`](#message-types) with subtype `"init"` containing session metadata.

202. **Evaluate and respond.** Claude evaluates the current state and determines how to proceed. It may respond with text, request one or more tool calls, or both. The SDK yields an [`AssistantMessage`](#message-types) containing the text and any tool call requests.222. **Evaluate and respond.** Claude evaluates the current state and determines how to proceed. It may respond with text, request one or more tool calls, or both. The SDK yields an [`AssistantMessage`](#message-types) containing the text and any tool call requests.

Details

8 8 

9The Claude Agent SDK provides detailed token usage information for each interaction with Claude. This guide explains how to properly track usage and understand cost reporting, especially when dealing with parallel tool uses and multi-step conversations.9The Claude Agent SDK provides detailed token usage information for each interaction with Claude. This guide explains how to properly track usage and understand cost reporting, especially when dealing with parallel tool uses and multi-step conversations.

10 10 

11For complete API documentation, see the [TypeScript SDK reference](/en/agent-sdk/typescript) and [Python SDK reference](/en/agent-sdk/python).11For complete API documentation, see the [TypeScript SDK reference](/docs/en/agent-sdk/typescript) and [Python SDK reference](/docs/en/agent-sdk/python).

12 12 

13<Warning>13<Warning>

14 The `total_cost_usd` and `costUSD` fields are client-side estimates, not authoritative billing data. The SDK computes them locally from a price table bundled at build time, so they can drift from what you are actually billed when:14 The `total_cost_usd` and `costUSD` fields are client-side estimates, not authoritative billing data. The SDK computes them locally from a price table bundled at build time, so they can drift from what you are actually billed when:


31 31 

32Cost tracking depends on understanding how the SDK scopes usage data:32Cost tracking depends on understanding how the SDK scopes usage data:

33 33 

34* **`query()` call:** one invocation of the SDK's `query()` function. A single call can involve multiple steps (Claude responds, uses tools, gets results, responds again). Each call produces one [`result`](/en/agent-sdk/typescript#sdkresultmessage) message at the end.34* **`query()` call:** one invocation of the SDK's `query()` function. A single call can involve multiple steps (Claude responds, uses tools, gets results, responds again). Each call produces one [`result`](/docs/en/agent-sdk/typescript#sdkresultmessage) message at the end.

35* **Step:** a single request/response cycle within a `query()` call. Each step produces assistant messages with token usage.35* **Step:** a single request/response cycle within a `query()` call. Each step produces assistant messages with token usage.

36* **Session:** a series of `query()` calls linked by a session ID (using the `resume` option). Each `query()` call within a session reports its own cost independently.36* **Session:** a series of `query()` calls linked by a session ID (using the `resume` option). Each `query()` call within a session reports its own cost independently.

37 37 

38The following diagram shows the message stream from a single `query()` call, with token usage reported at each step and the cumulative estimate at the end:38The following diagram shows the message stream from a single `query()` call, with token usage reported at each step and the cumulative estimate at the end:

39 39 

40<img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/agent-sdk/message-usage-flow.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=68497aee338e01cc745323af7aea378e" alt="Diagram showing a query producing two steps of messages. Step 1 has four assistant messages sharing the same ID and usage (count once), Step 2 has one assistant message with a new ID, and the final result message shows the estimated total_cost_usd." width="760" height="520" data-path="images/agent-sdk/message-usage-flow.svg" />40<img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/agent-sdk/message-usage-flow.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=68497aee338e01cc745323af7aea378e" className="dark:hidden" alt="Diagram showing a query producing two steps of messages. Step 1 has four assistant messages sharing the same ID and usage (count once), Step 2 has one assistant message with a new ID, and the final result message shows the estimated total_cost_usd." width="760" height="520" data-path="images/agent-sdk/message-usage-flow.svg" />

41 

42<img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/agent-sdk/message-usage-flow-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=8ea95085abc0a6b7f55ecef498bd4d14" className="hidden dark:block" alt="Diagram showing a query producing two steps of messages. Step 1 has four assistant messages sharing the same ID and usage (count once), Step 2 has one assistant message with a new ID, and the final result message shows the estimated total_cost_usd." width="760" height="520" data-path="images/agent-sdk/message-usage-flow-dark.svg" />

41 43 

42<Steps>44<Steps>

43 <Step title="Each step produces assistant messages">45 <Step title="Each step produces assistant messages">


45 </Step>47 </Step>

46 48 

47 <Step title="The result message provides the cumulative estimate">49 <Step title="The result message provides the cumulative estimate">

48 When the `query()` call completes, the SDK emits a result message with `total_cost_usd` and cumulative `usage`. This is available in both TypeScript ([`SDKResultMessage`](/en/agent-sdk/typescript#sdkresultmessage)) and Python ([`ResultMessage`](/en/agent-sdk/python#resultmessage)). If you make multiple `query()` calls (for example, in a multi-turn session), each result only reflects the cost of that individual call. If you only need the estimated total, you can ignore the per-step usage and read this single value.50 When the `query()` call completes, the SDK emits a result message with `total_cost_usd` and cumulative `usage`. This is available in both TypeScript ([`SDKResultMessage`](/docs/en/agent-sdk/typescript#sdkresultmessage)) and Python ([`ResultMessage`](/docs/en/agent-sdk/python#resultmessage)). If you make multiple `query()` calls (for example, in a multi-turn session), each result only reflects the cost of that individual call. If you only need the estimated total, you can ignore the per-step usage and read this single value.

49 </Step>51 </Step>

50</Steps>52</Steps>

51 53 

52## Get the total cost of a query54## Get the total cost of a query

53 55 

54The result message ([TypeScript](/en/agent-sdk/typescript#sdkresultmessage), [Python](/en/agent-sdk/python#resultmessage)) marks the end of the agent loop for a `query()` call. It includes `total_cost_usd`, the cumulative estimated cost across all steps in that call. This works for both success and error results. If you use sessions to make multiple `query()` calls, each result only reflects the cost of that individual call.56The result message ([TypeScript](/docs/en/agent-sdk/typescript#sdkresultmessage), [Python](/docs/en/agent-sdk/python#resultmessage)) marks the end of the agent loop for a `query()` call. It includes `total_cost_usd`, the cumulative estimated cost across all steps in that call. This works for both success and error results. If you use sessions to make multiple `query()` calls, each result only reflects the cost of that individual call.

55 57 

56The three result-level fields differ in what they count when the agent spawns [subagents](/en/agent-sdk/subagents). Use `modelUsage`, or `model_usage` in Python, for whole-tree token accounting; the `usage` field undercounts as soon as nesting occurs.58The three result-level fields differ in what they count when the agent spawns [subagents](/docs/en/agent-sdk/subagents). Use `modelUsage`, or `model_usage` in Python, for whole-tree token accounting; the `usage` field undercounts as soon as nesting occurs.

57 59 

58| Field | Subagent activity |60| Field | Subagent activity |

59| ---------------------------- | ------------------------------------------------------------------------------------------------- |61| ---------------------------- | ------------------------------------------------------------------------------------------------- |


106 108 

107## Track per-step and per-model usage109## Track per-step and per-model usage

108 110 

109The examples in this section use TypeScript field names. In Python, the equivalent fields are [`AssistantMessage.usage`](/en/agent-sdk/python#assistantmessage) and `AssistantMessage.message_id` for per-step usage, and [`ResultMessage.model_usage`](/en/agent-sdk/python#resultmessage) for per-model breakdowns.111The examples in this section use TypeScript field names. In Python, the equivalent fields are [`AssistantMessage.usage`](/docs/en/agent-sdk/python#assistantmessage) and `AssistantMessage.message_id` for per-step usage, and [`ResultMessage.model_usage`](/docs/en/agent-sdk/python#resultmessage) for per-model breakdowns.

110 112 

111### Track per-step usage113### Track per-step usage

112 114 


151 153 

152### Break down usage per model154### Break down usage per model

153 155 

154The result message includes [`modelUsage`](/en/agent-sdk/typescript#modelusage), a map of model name to per-model token counts and cost. This is useful when you run multiple models (for example, Haiku for subagents and Opus for the main agent) and want to see where tokens are going.156The result message includes [`modelUsage`](/docs/en/agent-sdk/typescript#modelusage), a map of model name to per-model token counts and cost. This is useful when you run multiple models (for example, Haiku for subagents and Opus for the main agent) and want to see where tokens are going.

155 157 

156The following example runs a query and prints the cost and token breakdown for each model used:158The following example runs a query and prints the cost and token breakdown for each model used:

157 159 


274* `cache_creation_input_tokens`: tokens used to create new cache entries (charged at a higher rate than standard input tokens).276* `cache_creation_input_tokens`: tokens used to create new cache entries (charged at a higher rate than standard input tokens).

275* `cache_read_input_tokens`: tokens read from existing cache entries (charged at a reduced rate).277* `cache_read_input_tokens`: tokens read from existing cache entries (charged at a reduced rate).

276 278 

277Track these separately from `input_tokens` to understand caching savings. In TypeScript, these fields are typed on the [`Usage`](/en/agent-sdk/typescript#usage) object. In Python, they appear as keys in the [`ResultMessage.usage`](/en/agent-sdk/python#resultmessage) dict (for example, `message.usage.get("cache_read_input_tokens", 0)`).279Track these separately from `input_tokens` to understand caching savings. In TypeScript, these fields are typed on the [`Usage`](/docs/en/agent-sdk/typescript#usage) object. In Python, they appear as keys in the [`ResultMessage.usage`](/docs/en/agent-sdk/python#resultmessage) dict (for example, `message.usage.get("cache_read_input_tokens", 0)`).

278 280 

279### Extend the prompt cache TTL to one hour281### Extend the prompt cache TTL to one hour

280 282 

281Cache entries written by the SDK use a 5-minute TTL by default when you authenticate with an API key or run on Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry. If your workload runs many short sessions against the same system prompt and context with gaps longer than 5 minutes between them, the cache expires between sessions and each new session pays full input price.283Cache entries written by the SDK use a 5-minute TTL by default when you authenticate with an API key or run on Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry. If your workload runs many short sessions against the same system prompt and context with gaps longer than 5 minutes between them, the cache expires between sessions and each new session pays full input price.

282 284 

283To request a 1-hour TTL on cache writes, set the [`ENABLE_PROMPT_CACHING_1H`](/en/env-vars) environment variable. You can export it in your shell or container environment, or pass it through `options.env`.285To request a 1-hour TTL on cache writes, set the [`ENABLE_PROMPT_CACHING_1H`](/docs/en/env-vars) environment variable. You can export it in your shell or container environment, or pass it through `options.env`.

284 286 

285The following example enables 1-hour TTL for an agent running on Amazon Bedrock. Because it sets `CLAUDE_CODE_USE_BEDROCK`, it requires working AWS credentials for [Amazon Bedrock](/en/amazon-bedrock); without them the query fails.287The following example enables 1-hour TTL for an agent running on Amazon Bedrock. Because it sets `CLAUDE_CODE_USE_BEDROCK`, it requires working AWS credentials for [Amazon Bedrock](/docs/en/amazon-bedrock); without them the query fails.

286 288 

287<CodeGroup>289<CodeGroup>

288 ```python Python theme={null}290 ```python Python theme={null}


326 328 

327## Related documentation329## Related documentation

328 330 

329* [TypeScript SDK Reference](/en/agent-sdk/typescript) - Complete API documentation331* [TypeScript SDK Reference](/docs/en/agent-sdk/typescript) - Complete API documentation

330* [SDK Overview](/en/agent-sdk/overview) - Getting started with the SDK332* [SDK Overview](/docs/en/agent-sdk/overview) - Getting started with the SDK

331* [SDK Permissions](/en/agent-sdk/permissions) - Managing tool permissions333* [SDK Permissions](/docs/en/agent-sdk/permissions) - Managing tool permissions

Details

14 14 

15| If you want to... | Do this |15| If you want to... | Do this |

16| :------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |16| :------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

17| Define a tool | Use [`@tool`](/en/agent-sdk/python#tool) (Python) or [`tool()`](/en/agent-sdk/typescript#tool) (TypeScript) with a name, description, schema, and handler. See [Create a custom tool](#create-a-custom-tool). |17| Define a tool | Use [`@tool`](/docs/en/agent-sdk/python#tool) (Python) or [`tool()`](/docs/en/agent-sdk/typescript#tool) (TypeScript) with a name, description, schema, and handler. See [Create a custom tool](#create-a-custom-tool). |

18| Register a tool with Claude | Wrap in `create_sdk_mcp_server` / `createSdkMcpServer` and pass to `mcpServers` in `query()`. See [Call a custom tool](#call-a-custom-tool). |18| Register a tool with Claude | Wrap in `create_sdk_mcp_server` / `createSdkMcpServer` and pass to `mcpServers` in `query()`. See [Call a custom tool](#call-a-custom-tool). |

19| Pre-approve a tool | Add to your allowed tools. See [Configure allowed tools](#configure-allowed-tools). |19| Pre-approve a tool | Add to your allowed tools. See [Configure allowed tools](#configure-allowed-tools). |

20| Remove a built-in tool from Claude's context | Pass a `tools` array listing only the built-ins you want. See [Configure allowed tools](#configure-allowed-tools). |20| Remove a built-in tool from Claude's context | Pass a `tools` array listing only the built-ins you want. See [Configure allowed tools](#configure-allowed-tools). |


22| Control the error message Claude reads | Return `isError: true` to compose the message instead of surfacing the raw exception. See [Handle errors](#handle-errors). |22| Control the error message Claude reads | Return `isError: true` to compose the message instead of surfacing the raw exception. See [Handle errors](#handle-errors). |

23| Return images or files | Use `image` or `resource` blocks in the content array. See [Return images and resources](#return-images-and-resources). |23| Return images or files | Use `image` or `resource` blocks in the content array. See [Return images and resources](#return-images-and-resources). |

24| Return a machine-readable JSON result | Set `structuredContent` on the result. See [Return structured data](#return-structured-data). |24| Return a machine-readable JSON result | Set `structuredContent` on the result. See [Return structured data](#return-structured-data). |

25| Scale to many tools | Use [tool search](/en/agent-sdk/tool-search) to load tools on demand. |25| Scale to many tools | Use [tool search](/docs/en/agent-sdk/tool-search) to load tools on demand. |

26 26 

27## Create a custom tool27## Create a custom tool

28 28 

29A tool is defined by four parts, passed as arguments to the [`tool()`](/en/agent-sdk/typescript#tool) helper in TypeScript or the [`@tool`](/en/agent-sdk/python#tool) decorator in Python:29A tool is defined by four parts, passed as arguments to the [`tool()`](/docs/en/agent-sdk/typescript#tool) helper in TypeScript or the [`@tool`](/docs/en/agent-sdk/python#tool) decorator in Python:

30 30 

31* **Name:** a unique identifier Claude uses to call the tool.31* **Name:** a unique identifier Claude uses to call the tool.

32* **Description:** what the tool does. Claude reads this to decide when to call it.32* **Description:** what the tool does. Claude reads this to decide when to call it.


36 * `structuredContent` (optional): a JSON object holding the result as machine-readable data, returned alongside `content`. See [Return structured data](#return-structured-data).36 * `structuredContent` (optional): a JSON object holding the result as machine-readable data, returned alongside `content`. See [Return structured data](#return-structured-data).

37 * `isError` (optional): set to `true` to signal a tool failure so Claude can react to it. See [Handle errors](#handle-errors).37 * `isError` (optional): set to `true` to signal a tool failure so Claude can react to it. See [Handle errors](#handle-errors).

38 38 

39After defining a tool, wrap it in a server with [`createSdkMcpServer`](/en/agent-sdk/typescript#createsdkmcpserver) (TypeScript) or [`create_sdk_mcp_server`](/en/agent-sdk/python#create_sdk_mcp_server) (Python). The server runs in-process inside your application, not as a separate process.39After defining a tool, wrap it in a server with [`createSdkMcpServer`](/docs/en/agent-sdk/typescript#createsdkmcpserver) (TypeScript) or [`create_sdk_mcp_server`](/docs/en/agent-sdk/python#create_sdk_mcp_server) (Python). The server runs in-process inside your application, not as a separate process.

40 40 

41### Weather tool example41### Weather tool example

42 42 


122 ```122 ```

123</CodeGroup>123</CodeGroup>

124 124 

125See the [`tool()`](/en/agent-sdk/typescript#tool) TypeScript reference or the [`@tool`](/en/agent-sdk/python#tool) Python reference for full parameter details, including JSON Schema input formats and return value structure.125See the [`tool()`](/docs/en/agent-sdk/typescript#tool) TypeScript reference or the [`@tool`](/docs/en/agent-sdk/python#tool) Python reference for full parameter details, including JSON Schema input formats and return value structure.

126 126 

127<Tip>127<Tip>

128 To make a parameter optional: in TypeScript, add `.default()` to the Zod field. In Python, the dict schema treats every key as required, so leave the parameter out of the schema, mention it in the description string, and read it with `args.get()` in the handler. The [`get_precipitation_chance` tool below](#add-more-tools) shows both patterns.128 To make a parameter optional: in TypeScript, add `.default()` to the Zod field. In Python, the dict schema treats every key as required, so leave the parameter out of the schema, mention it in the description string, and read it with `args.get()` in the handler. The [`get_precipitation_chance` tool below](#add-more-tools) shows both patterns.


265 ```265 ```

266</CodeGroup>266</CodeGroup>

267 267 

268[Tool search](/en/agent-sdk/tool-search) is on by default and defers SDK MCP tools: Claude sees each tool's name in a compact list and loads its full schema on demand. With tool search disabled, every tool in this array consumes context window space on every turn. In TypeScript, pass `alwaysLoad: true` in the `extras` argument of [`tool()`](/en/agent-sdk/typescript#tool) or in the options of [`createSdkMcpServer()`](/en/agent-sdk/typescript#createsdkmcpserver) to keep a tool's full schema in the initial prompt.268[Tool search](/docs/en/agent-sdk/tool-search) is on by default and defers SDK MCP tools: Claude sees each tool's name in a compact list and loads its full schema on demand. With tool search disabled, every tool in this array consumes context window space on every turn. In TypeScript, pass `alwaysLoad: true` in the `extras` argument of [`tool()`](/docs/en/agent-sdk/typescript#tool) or in the options of [`createSdkMcpServer()`](/docs/en/agent-sdk/typescript#createsdkmcpserver) to keep a tool's full schema in the initial prompt.

269 269 

270### Add tool annotations270### Add tool annotations

271 271 


313 ```313 ```

314</CodeGroup>314</CodeGroup>

315 315 

316See `ToolAnnotations` in the [TypeScript](/en/agent-sdk/typescript#toolannotations) or [Python](/en/agent-sdk/python#toolannotations) reference.316See `ToolAnnotations` in the [TypeScript](/docs/en/agent-sdk/typescript#toolannotations) or [Python](/docs/en/agent-sdk/python#toolannotations) reference.

317 317 

318## Control tool access318## Control tool access

319 319 


334| :------------------------ | :----------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |334| :------------------------ | :----------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

335| `tools: ["Read", "Grep"]` | Availability | Only the listed built-ins are in Claude's context. Unlisted built-ins are removed. MCP tools are unaffected. |335| `tools: ["Read", "Grep"]` | Availability | Only the listed built-ins are in Claude's context. Unlisted built-ins are removed. MCP tools are unaffected. |

336| `tools: []` | Availability | All built-ins are removed. Claude can only use your MCP tools. |336| `tools: []` | Availability | All built-ins are removed. Claude can only use your MCP tools. |

337| allowed tools | Permission | Listed tools run without a permission prompt. Unlisted tools remain available; calls go through the [permission flow](/en/agent-sdk/permissions). |337| allowed tools | Permission | Listed tools run without a permission prompt. Unlisted tools remain available; calls go through the [permission flow](/docs/en/agent-sdk/permissions). |

338| disallowed tools | Both | A bare tool name such as `"Bash"` removes the tool from Claude's context, the same as omitting it from `tools`. A scoped rule such as `"Bash(rm *)"` leaves the tool in context and denies only matching calls. |338| disallowed tools | Both | A bare tool name such as `"Bash"` removes the tool from Claude's context, the same as omitting it from `tools`. A scoped rule such as `"Bash(rm *)"` leaves the tool in context and denies only matching calls. |

339 339 

340To remove a built-in entirely, omit it from `tools` or list its bare name in `disallowedTools` (Python: `disallowed_tools`); both keep the tool out of context so Claude never attempts it. A scoped `disallowedTools` rule blocks matching calls but leaves the tool visible, so Claude may waste a turn trying it. See [Configure permissions](/en/agent-sdk/permissions) for the full evaluation order.340To remove a built-in entirely, omit it from `tools` or list its bare name in `disallowedTools` (Python: `disallowed_tools`); both keep the tool out of context so Claude never attempts it. A scoped `disallowedTools` rule blocks matching calls but leaves the tool visible, so Claude may waste a turn trying it. See [Configure permissions](/docs/en/agent-sdk/permissions) for the full evaluation order.

341 341 

342## Handle errors342## Handle errors

343 343 


452 452 

453## Return images and resources453## Return images and resources

454 454 

455The `content` array in a tool result accepts `text`, `image`, `audio`, `resource`, and `resource_link` blocks. You can mix them in the same response. In TypeScript, audio blocks are saved to disk and Claude receives a text block with the saved file path; in Python, the SDK drops audio blocks from the tool result and logs a warning. Resource link blocks are converted to a text block containing the link's name, URI, and description.455The `content` array in a tool result accepts `text`, `image`, `audio`, `resource`, and `resource_link` blocks. You can mix them in the same response. In TypeScript, the SDK saves audio blocks to disk and Claude receives a text block with the saved file path; in Python, the SDK drops audio blocks from the tool result and logs a warning. The SDK converts resource link blocks to a text block containing the link's name, URI, and description.

456 456 

457### Images457### Images

458 458 


595```595```

596 596 

597<Note>597<Note>

598 The Python `@tool` decorator forwards only `content` and `is_error` from the handler's return dict. To return `structuredContent` from Python, run a [standalone MCP server](/en/agent-sdk/mcp) instead of an in-process SDK server.598 The Python `@tool` decorator forwards only `content` and `is_error` from the handler's return dict. To return `structuredContent` from Python, run a [standalone MCP server](/docs/en/agent-sdk/mcp) instead of an in-process SDK server.

599</Note>599</Note>

600 600 

601## Example: unit converter601## Example: unit converter


766 766 

767Once the server is defined, pass it to `query` the same way as the weather example. This example sends three different prompts in a loop to show the same tool handling different unit types. For each response, it inspects `AssistantMessage` objects (which contain the tool calls Claude made during that turn) and prints each `ToolUseBlock` before printing the final `ResultMessage` text. This lets you see when Claude is using the tool versus answering from its own knowledge.767Once the server is defined, pass it to `query` the same way as the weather example. This example sends three different prompts in a loop to show the same tool handling different unit types. For each response, it inspects `AssistantMessage` objects (which contain the tool calls Claude made during that turn) and prints each `ToolUseBlock` before printing the final `ResultMessage` text. This lets you see when Claude is using the tool versus answering from its own knowledge.

768 768 

769Because [tool search](/en/agent-sdk/tool-search) is on by default, the output may also include a `ToolSearch` call as Claude loads the deferred tool schema.769Because [tool search](/docs/en/agent-sdk/tool-search) is on by default, the output may also include a `ToolSearch` call as Claude loads the deferred tool schema.

770 770 

771<CodeGroup>771<CodeGroup>

772 ```python Python theme={null}772 ```python Python theme={null}


855 855 

856From here:856From here:

857 857 

858* If your server grows to dozens of tools, see [tool search](/en/agent-sdk/tool-search) to defer loading them until Claude needs them.858* If your server grows to dozens of tools, see [tool search](/docs/en/agent-sdk/tool-search) to defer loading them until Claude needs them.

859* To connect to external MCP servers (filesystem, GitHub, Slack) instead of building your own, see [Connect MCP servers](/en/agent-sdk/mcp).859* To connect to external MCP servers (filesystem, GitHub, Slack) instead of building your own, see [Connect MCP servers](/docs/en/agent-sdk/mcp).

860* To control which tools run automatically versus requiring approval, see [Configure permissions](/en/agent-sdk/permissions).860* To control which tools run automatically versus requiring approval, see [Configure permissions](/docs/en/agent-sdk/permissions).

861 861 

862## Related documentation862## Related documentation

863 863 

864* [TypeScript SDK Reference](/en/agent-sdk/typescript)864* [TypeScript SDK Reference](/docs/en/agent-sdk/typescript)

865* [Python SDK Reference](/en/agent-sdk/python)865* [Python SDK Reference](/docs/en/agent-sdk/python)

866* [MCP Documentation](https://modelcontextprotocol.io)866* [MCP Documentation](https://modelcontextprotocol.io)

867* [SDK Overview](/en/agent-sdk/overview)867* [SDK Overview](/docs/en/agent-sdk/overview)

Details

20 20 

21Every hosting decision on this page follows from how the SDK runs the agent. When your code calls `query()`, the SDK spawns a separate `claude` CLI process and talks to it over stdio. That subprocess owns the shell, the working directory, and the JSONL session transcripts on local disk.21Every hosting decision on this page follows from how the SDK runs the agent. When your code calls `query()`, the SDK spawns a separate `claude` CLI process and talks to it over stdio. That subprocess owns the shell, the working directory, and the JSONL session transcripts on local disk.

22 22 

23<img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/agent-sdk/hosting-subprocess.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=9dac857ca9d3b1410c3734900c386004" alt="Request flow: client to your app, which spawns a claude CLI subprocess over stdio inside the container; the subprocess writes to local disk and calls api.anthropic.com over HTTPS" width="920" height="220" data-path="images/agent-sdk/hosting-subprocess.svg" />23<img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/agent-sdk/hosting-subprocess.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=9dac857ca9d3b1410c3734900c386004" className="dark:hidden" alt="Request flow: client to your app, which spawns a claude CLI subprocess over stdio inside the container; the subprocess writes to local disk and calls api.anthropic.com over HTTPS" width="920" height="220" data-path="images/agent-sdk/hosting-subprocess.svg" />

24 

25<img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/agent-sdk/hosting-subprocess-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=3fdeff3d7f44b2b67762668acfbb25f5" className="hidden dark:block" alt="Request flow: client to your app, which spawns a claude CLI subprocess over stdio inside the container; the subprocess writes to local disk and calls api.anthropic.com over HTTPS" width="920" height="220" data-path="images/agent-sdk/hosting-subprocess-dark.svg" />

24 26 

25One agent session maps to one subprocess. Running N concurrent sessions means N subprocesses, each with its own process tree and transcript file. By default they all inherit your application's working directory, so pass `cwd` on each `query()` call when sessions need separate filesystems:27One agent session maps to one subprocess. Running N concurrent sessions means N subprocesses, each with its own process tree and transcript file. By default they all inherit your application's working directory, so pass `cwd` on each `query()` call when sessions need separate filesystems:

26 28 

agent-sdk/mcp.md +29 −25

Details

11MCP servers can run as local processes, connect over HTTP, or execute directly within your SDK application.11MCP servers can run as local processes, connect over HTTP, or execute directly within your SDK application.

12 12 

13<Note>13<Note>

14 This page covers MCP configuration for the Agent SDK. To add MCP servers to the Claude Code CLI so they load in every project, see [MCP installation scopes](/en/mcp#mcp-installation-scopes).14 This page covers MCP configuration for the Agent SDK. To add MCP servers to the Claude Code CLI so they load in every project, see [MCP installation scopes](/docs/en/mcp#mcp-installation-scopes).

15</Note>15</Note>

16 16 

17## Quickstart17## Quickstart


148 148 

149Servers you pass in `options.mcpServers` start connecting as soon as the query starts. Connection is non-blocking by default: the first turn begins without waiting, and each server's tools become available once its connection completes. {/* min-version: 2.1.142 */}Before Claude Code v2.1.142, startup blocked on the connection batch for up to 5 seconds.149Servers you pass in `options.mcpServers` start connecting as soon as the query starts. Connection is non-blocking by default: the first turn begins without waiting, and each server's tools become available once its connection completes. {/* min-version: 2.1.142 */}Before Claude Code v2.1.142, startup blocked on the connection batch for up to 5 seconds.

150 150 

151To restore a bounded startup wait for every server, set the [`MCP_CONNECTION_NONBLOCKING`](/en/env-vars) environment variable to `0`. The wait is capped at 5 seconds by [`MCP_CONNECT_TIMEOUT_MS`](/en/env-vars), and servers still pending at that deadline keep connecting in the background.151To restore a bounded startup wait for every server, set the [`MCP_CONNECTION_NONBLOCKING`](/docs/en/env-vars) environment variable to `0`. The wait is capped at 5 seconds by [`MCP_CONNECT_TIMEOUT_MS`](/docs/en/env-vars), and servers still pending at that deadline keep connecting in the background.

152 152 

153To make one server's tools available before the first turn, set `alwaysLoad: true` on its config. Startup then waits for that server to connect, capped at the same 5-second startup deadline, while other servers keep connecting in the background. The `alwaysLoad` field requires Claude Code v2.1.121 or later. See [Exempt a server from deferral](/en/mcp#exempt-a-server-from-deferral) for the `alwaysLoad` field's effect on tool search.153To make one server's tools available before the first turn, set `alwaysLoad: true` on its config. Startup then waits for that server to connect, capped at the same 5-second startup deadline, while other servers keep connecting in the background. The `alwaysLoad` field requires Claude Code v2.1.121 or later. See [Exempt a server from deferral](/docs/en/mcp#exempt-a-server-from-deferral) for the `alwaysLoad` field's effect on tool search.

154 154 

155The `system` message with subtype `init` reports each server's status at the moment it's emitted. A server that's still connecting has status `pending`. Check for status `failed` or `needs-auth` when you want to detect servers that won't be usable, rather than treating every status other than `connected` as a failure; see [Error handling](#error-handling) for the full status check.155The `system` message with subtype `init` reports each server's status at the moment it's emitted. A server that's still connecting has status `pending`. Check for status `failed` or `needs-auth` when you want to detect servers that won't be usable, rather than treating every status other than `connected` as a failure; see [Error handling](#error-handling) for the full status check.

156 156 


199Wildcards (`*`) let you allow all tools from a server without listing each one individually.199Wildcards (`*`) let you allow all tools from a server without listing each one individually.

200 200 

201<Note>201<Note>

202 **Prefer `allowedTools` over permission modes for MCP access.** `permissionMode: "acceptEdits"` does not auto-approve MCP tools (only file edits and filesystem Bash commands). `permissionMode: "bypassPermissions"` does auto-approve MCP tools but also disables most other safety prompts, which is broader than necessary; see [How permissions are evaluated](/en/agent-sdk/permissions#how-permissions-are-evaluated) for the prompts that remain. A wildcard in `allowedTools` grants exactly the MCP server you want and nothing more. See [Permission modes](/en/agent-sdk/permissions#permission-modes) for a full comparison.202 **Prefer `allowedTools` over permission modes for MCP access.** `permissionMode: "acceptEdits"` does not auto-approve MCP tools (only file edits and filesystem Bash commands). `permissionMode: "bypassPermissions"` does auto-approve MCP tools but also disables most other safety prompts, which is broader than necessary; see [How permissions are evaluated](/docs/en/agent-sdk/permissions#how-permissions-are-evaluated) for the prompts that remain. A wildcard in `allowedTools` grants exactly the MCP server you want and nothing more. See [Permission modes](/docs/en/agent-sdk/permissions#permission-modes) for a full comparison.

203</Note>203</Note>

204 204 

205### Discover available tools205### Discover available tools

206 206 

207To see what tools an MCP server provides, check the server's documentation or inspect the `tools` array in the `system` init message. MCP tool names start with `mcp__`.207To see what tools an MCP server provides, check the server's documentation or inspect the `tools` array in the `system` init message. MCP tool names start with `mcp__`.

208 208 

209MCP servers connect in the background by default, so the init message arrives before they finish: the `tools` array lists only built-in tools and `mcp_servers` shows a `pending` status for each server. Set the [`MCP_CONNECTION_NONBLOCKING`](/en/env-vars) environment variable to `0` to wait up to 5 seconds for servers to connect before the init message is sent; servers that connect in time list their `mcp__` tools there, and slower ones keep connecting in the background:209MCP servers connect in the background by default, so the init message arrives before they finish: the `tools` array lists only built-in tools and `mcp_servers` shows a `pending` status for each server. Set the [`MCP_CONNECTION_NONBLOCKING`](/docs/en/env-vars) environment variable to `0` to wait up to 5 seconds for servers to connect before the init message is sent; servers that connect in time list their `mcp__` tools there, and slower ones keep connecting in the background:

210 210 

211```bash theme={null}211```bash theme={null}

212export MCP_CONNECTION_NONBLOCKING=0212export MCP_CONNECTION_NONBLOCKING=0


376 376 

377### SDK MCP servers377### SDK MCP servers

378 378 

379Define custom tools directly in your application code instead of running a separate server process. See the [custom tools guide](/en/agent-sdk/custom-tools) for implementation details.379Define custom tools directly in your application code instead of running a separate server process. See the [custom tools guide](/docs/en/agent-sdk/custom-tools) for implementation details.

380 380 

381{/* min-version: 2.1.210 */}An SDK MCP server registered by an [`initialize` control request](/en/agent-sdk/typescript#sdkcontrolinitializeresponse) begins connecting as soon as Claude Code processes the request.381{/* min-version: 2.1.210 */}An SDK MCP server registered by an [`initialize` control request](/docs/en/agent-sdk/typescript#sdkcontrolinitializeresponse) begins connecting as soon as Claude Code processes the request.

382 382 

383## MCP tool search383## MCP tool search

384 384 

385When you have many MCP tools configured, tool definitions can consume a significant portion of your context window. Tool search solves this by withholding tool definitions from context and loading only the ones Claude needs for each turn.385When you have many MCP tools configured, tool definitions can consume a significant portion of your context window. Tool search solves this by withholding tool definitions from context and loading only the ones Claude needs for each turn.

386 386 

387Tool search is enabled by default. See [Tool search](/en/agent-sdk/tool-search) for configuration options, best practices, and using tool search with custom SDK tools.387Tool search is enabled by default. See [Tool search](/docs/en/agent-sdk/tool-search) for configuration options, best practices, and using tool search with custom SDK tools.

388 388 

389## Authentication389## Authentication

390 390 


510 510 

511### OAuth2 authentication511### OAuth2 authentication

512 512 

513The [MCP specification supports OAuth 2.1](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization) for authorization. The SDK doesn't open a browser or run an interactive OAuth flow. When a configured server returns an authorization challenge and no stored token is available, the agent run continues without that server's tools, and the server reports status `needs-auth`. Because servers connect in the background by default, the `mcp_servers` array of the [system init message](/en/agent-sdk/typescript#sdksystemmessage) may still show `pending` for that server. To confirm whether a server needs credentials, poll `mcpServerStatus()` in the TypeScript SDK or [`get_mcp_status()`](/en/agent-sdk/python#methods) in Python, or set `MCP_CONNECTION_NONBLOCKING=0` to wait for connections before the init message.513The [MCP specification supports OAuth 2.1](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization) for authorization. The SDK doesn't open a browser or run an interactive OAuth flow. When a configured server returns an authorization challenge and no stored token is available, the agent run continues without that server's tools, and the server reports status `needs-auth`. Because servers connect in the background by default, the `mcp_servers` array of the [system init message](/docs/en/agent-sdk/typescript#sdksystemmessage) may still show `pending` for that server. To confirm whether a server needs credentials, poll `mcpServerStatus()` in the TypeScript SDK or [`get_mcp_status()`](/docs/en/agent-sdk/python#methods) in Python, or set `MCP_CONNECTION_NONBLOCKING=0` to wait for connections before the init message.

514 514 

515To supply credentials, complete the OAuth flow in your own application and pass the resulting access token in the server's `headers`:515To supply credentials, complete the OAuth flow in your own application and pass the resulting access token in the server's `headers`:

516 516 


768 }768 }

769 }769 }

770 } catch (error) {770 } catch (error) {

771 // A single-shot query() throws after yielding an error result.771 // A single-shot query() throws after yielding an error result. If the

772 // If the failure was an error result, the error subtype branch above772 // failure was an error result, the error subtype branch above has

773 // has already run; connection or process failures yield no result773 // already run; a failure to start or reach the Claude Code process

774 // message.774 // yields no result message. MCP servers that fail to connect don't

775 // throw: use the status check above, and note that servers still

776 // "pending" at init need a later status check.

775 console.log(`Session ended with an error: ${error}`);777 console.log(`Session ended with an error: ${error}`);

776 }778 }

777 ```779 ```


803 ):805 ):

804 print("Execution failed")806 print("Execution failed")

805 except Exception as error:807 except Exception as error:

806 # A single-shot query() raises after yielding an error result.808 # A single-shot query() raises after yielding an error result. If the

807 # If the failure was an error result, the error subtype branch809 # failure was an error result, the error subtype branch above has

808 # above has already run; connection or process failures yield810 # already run; a failure to start or reach the Claude Code process

809 # no result message.811 # yields no result message. MCP servers that fail to connect don't

812 # raise: use the status check above, and note that servers still

813 # "pending" at init need a later status check.

810 print(f"Session ended with an error: {error}")814 print(f"Session ended with an error: {error}")

811 815 

812 816 


839 ```843 ```

840</CodeGroup>844</CodeGroup>

841 845 

842A `"pending"` status means the server is still connecting, not that it failed. To get updated statuses later in the session, call the query's `mcpServerStatus()` method in the TypeScript SDK, or [`ClaudeSDKClient.get_mcp_status()`](/en/agent-sdk/python#methods) in Python.846A `"pending"` status means the server is still connecting, not that it failed. To get updated statuses later in the session, call the query's `mcpServerStatus()` method in the TypeScript SDK, or [`ClaudeSDKClient.get_mcp_status()`](/docs/en/agent-sdk/python#methods) in Python.

843 847 

844Common causes:848Common causes:

845 849 


876 880 

877### Connection timeouts881### Connection timeouts

878 882 

879MCP server connections time out after 30 seconds by default. If your server takes longer to start, the connection fails. Raise the limit with the [`MCP_TIMEOUT`](/en/env-vars) environment variable, in milliseconds. For servers that need more startup time, also consider:883MCP server connections time out after 30 seconds by default. If your server takes longer to start, the connection fails. Raise the limit with the [`MCP_TIMEOUT`](/docs/en/env-vars) environment variable, in milliseconds. For servers that need more startup time, also consider:

880 884 

881* Using a lighter-weight server if available885* Using a lighter-weight server if available

882* Pre-warming the server before starting your agent886* Pre-warming the server before starting your agent


884 888 

885### Tool output exceeds maximum allowed tokens889### Tool output exceeds maximum allowed tokens

886 890 

887The SDK applies the same MCP output limit as Claude Code. When a tool result is larger than 25,000 tokens, the full output is saved to a file and the tool result is replaced with an error message that names the file path, so the agent can read the output back in portions. Raise the limit with the [`MAX_MCP_OUTPUT_TOKENS`](/en/env-vars) environment variable. See [MCP output limits and warnings](/en/mcp#mcp-output-limits-and-warnings) for the full behavior, including how a server can declare a higher per-tool limit.891The SDK applies the same MCP output limit as Claude Code. When a tool result is larger than 25,000 tokens, the full output is saved to a file and the tool result is replaced with an error message that names the file path, so the agent can read the output back in portions. Raise the limit with the [`MAX_MCP_OUTPUT_TOKENS`](/docs/en/env-vars) environment variable. See [MCP output limits and warnings](/docs/en/mcp#mcp-output-limits-and-warnings) for the full behavior, including how a server can declare a higher per-tool limit.

888 892 

889## Related resources893## Related resources

890 894 

891* **[Custom tools guide](/en/agent-sdk/custom-tools)**: Build your own MCP server that runs in-process with your SDK application895* **[Custom tools guide](/docs/en/agent-sdk/custom-tools)**: Build your own MCP server that runs in-process with your SDK application

892* **[Permissions](/en/agent-sdk/permissions)**: Control which MCP tools your agent can use with `allowedTools` and `disallowedTools`896* **[Permissions](/docs/en/agent-sdk/permissions)**: Control which MCP tools your agent can use with `allowedTools` and `disallowedTools`

893* **[MCP output limits and warnings](/en/mcp#mcp-output-limits-and-warnings)**: How the SDK handles tool results that exceed `MAX_MCP_OUTPUT_TOKENS`, including the persist-to-disk fallback and the `anthropic/maxResultSizeChars` per-tool annotation897* **[MCP output limits and warnings](/docs/en/mcp#mcp-output-limits-and-warnings)**: How the SDK handles tool results that exceed `MAX_MCP_OUTPUT_TOKENS`, including the persist-to-disk fallback and the `anthropic/maxResultSizeChars` per-tool annotation

894* **[TypeScript SDK reference](/en/agent-sdk/typescript)**: Full API reference including MCP configuration options898* **[TypeScript SDK reference](/docs/en/agent-sdk/typescript)**: Full API reference including MCP configuration options

895* **[Python SDK reference](/en/agent-sdk/python)**: Full API reference including MCP configuration options899* **[Python SDK reference](/docs/en/agent-sdk/python)**: Full API reference including MCP configuration options

896* **[MCP server directory](https://github.com/modelcontextprotocol/servers)**: Browse available MCP servers for databases, APIs, and more900* **[MCP server directory](https://github.com/modelcontextprotocol/servers)**: Browse available MCP servers for databases, APIs, and more

Details

150 150 

151The `llm_request`, `tool`, and `hook` spans are children of the enclosing `claude_code.interaction` span. When the agent spawns a subagent through the Task tool, the subagent's `llm_request` and `tool` spans nest under the parent agent's `claude_code.tool` span, so the full delegation chain appears as one trace.151The `llm_request`, `tool`, and `hook` spans are children of the enclosing `claude_code.interaction` span. When the agent spawns a subagent through the Task tool, the subagent's `llm_request` and `tool` spans nest under the parent agent's `claude_code.tool` span, so the full delegation chain appears as one trace.

152 152 

153Spans carry a `session.id` attribute by default. When you make several `query()` calls against the same [session](/docs/en/agent-sdk/sessions), filter on `session.id` in your backend to see them as one timeline. The attribute is omitted if `OTEL_METRICS_INCLUDE_SESSION_ID` is set to a falsy value.153Spans carry a `session.id` attribute by default. When you make several `query()` calls against the same [session](/docs/en/agent-sdk/sessions), filter on `session.id` in your backend to see them as one timeline. Claude Code omits the attribute if you set `OTEL_METRICS_INCLUDE_SESSION_ID` to a falsy value.

154 154 

155<Note>155<Note>

156 Tracing is in beta. Span names and attributes may change between releases. See156 Tracing is in beta. Span names and attributes may change between releases. See

Details

6 6 

7> Control how your agent uses tools with permission modes, hooks, and declarative allow/deny rules.7> Control how your agent uses tools with permission modes, hooks, and declarative allow/deny rules.

8 8 

9The Claude Agent SDK provides permission controls to manage how Claude uses tools. Use permission modes and rules to define what's allowed automatically, and the [`canUseTool` callback](/en/agent-sdk/user-input) to handle everything else at runtime.9The Claude Agent SDK provides permission controls to manage how Claude uses tools. Use permission modes and rules to define what's allowed automatically, and the [`canUseTool` callback](/docs/en/agent-sdk/user-input) to handle everything else at runtime.

10 10 

11<Note>11<Note>

12 This page covers permission modes and rules. To build interactive approval flows where users approve or deny tool requests at runtime, see [Handle approvals and user input](/en/agent-sdk/user-input).12 This page covers permission modes and rules. To build interactive approval flows where users approve or deny tool requests at runtime, see [Handle approvals and user input](/docs/en/agent-sdk/user-input).

13</Note>13</Note>

14 14 

15## How permissions are evaluated15## How permissions are evaluated


18 18 

19<Steps>19<Steps>

20 <Step title="Hooks">20 <Step title="Hooks">

21 Run [hooks](/en/agent-sdk/hooks) first. A hook can deny the call outright or pass it on. A hook that returns `allow` does not skip the deny and ask rules below; those are evaluated regardless of the hook result.21 Run [hooks](/docs/en/agent-sdk/hooks) first. A hook can deny the call outright or pass it on. A hook that returns `allow` does not skip the deny and ask rules below; those are evaluated regardless of the hook result.

22 </Step>22 </Step>

23 23 

24 <Step title="Deny rules">24 <Step title="Deny rules">

25 Check `deny` rules (from `disallowed_tools` and [settings.json](/en/settings#permission-settings)). If a deny rule matches, the tool is blocked, even in `bypassPermissions` mode. Bare-name deny rules like `Bash` remove the tool from Claude's context before this evaluation begins, so only scoped rules like `Bash(rm *)` are checked at this step.25 Check `deny` rules (from `disallowed_tools` and [settings.json](/docs/en/settings#permission-settings)). If a deny rule matches, the tool is blocked, even in `bypassPermissions` mode. Bare-name deny rules like `Bash` remove the tool from Claude's context before this evaluation begins, so only scoped rules like `Bash(rm *)` are checked at this step.

26 </Step>26 </Step>

27 27 

28 <Step title="Ask rules">28 <Step title="Ask rules">

29 Check `ask` rules from [settings.json](/en/settings#permission-settings). If an ask rule matches, the call falls through to your [`canUseTool` callback](/en/agent-sdk/user-input) for confirmation, even in `bypassPermissions` mode.29 Check `ask` rules from [settings.json](/docs/en/settings#permission-settings). If an ask rule matches, the call falls through to your [`canUseTool` callback](/docs/en/agent-sdk/user-input) for confirmation, even in `bypassPermissions` mode.

30 30 

31 Tools that require user interaction behave the same way: `AskUserQuestion` and MCP tools whose server sets [`_meta["anthropic/requiresUserInteraction"]`](/en/mcp#require-approval-for-a-specific-tool) always fall through to the callback, even when an allow rule matches. In `dontAsk` mode both cases are denied instead, because that mode never prompts. {/* min-version: 2.1.199 */}The MCP annotation requires Claude Code v2.1.199 or later.31 Tools that require user interaction behave the same way: `AskUserQuestion` and MCP tools whose server sets [`_meta["anthropic/requiresUserInteraction"]`](/docs/en/mcp#require-approval-for-a-specific-tool) always fall through to the callback, even when an allow rule matches. In `dontAsk` mode both cases are denied instead, because that mode never prompts. {/* min-version: 2.1.199 */}The MCP annotation requires Claude Code v2.1.199 or later.

32 32 

33 [claude.ai connector](/en/mcp#organization-controls-on-connector-tools) tools your organization has set to `ask` also leave the flow at this step. Every call falls through to the callback, even in `bypassPermissions` mode and even when an allow rule matches. The callback receives the reason `Your organization requires approval for this tool`. In `dontAsk` mode the call is denied instead, because that mode never prompts.33 [claude.ai connector](/docs/en/mcp#organization-controls-on-connector-tools) tools your organization has set to `ask` also leave the flow at this step. Every call falls through to the callback, even in `bypassPermissions` mode and even when an allow rule matches. The callback receives the reason `Your organization requires approval for this tool`. In `dontAsk` mode the call is denied instead, because that mode never prompts.

34 </Step>34 </Step>

35 35 

36 <Step title="Permission mode">36 <Step title="Permission mode">


42 </Step>42 </Step>

43 43 

44 <Step title="canUseTool callback">44 <Step title="canUseTool callback">

45 If not resolved by any of the above, call your [`canUseTool` callback](/en/agent-sdk/user-input) for a decision. In `dontAsk` mode, this step is skipped and the tool is denied.45 If not resolved by any of the above, call your [`canUseTool` callback](/docs/en/agent-sdk/user-input) for a decision. In `dontAsk` mode, this step is skipped and the tool is denied.

46 </Step>46 </Step>

47</Steps>47</Steps>

48 48 

49<img src="https://mintcdn.com/claude-code/jYgs7qigNjO1Badj/images/agent-sdk/permissions-flow.svg?fit=max&auto=format&n=jYgs7qigNjO1Badj&q=85&s=c771ad9085b1277d3708027a49c744bc" alt="Diagram of the six-step permission evaluation flow matching the steps above: a tool request passes through hooks, deny rules, ask rules, permission mode, allow rules, and canUseTool. Hooks, deny rules, and canUseTool can route down to Blocked; permission mode bypass, allow rules, and canUseTool can route up to Execute; ask rules route to canUseTool." width="1180" height="260" data-path="images/agent-sdk/permissions-flow.svg" />49<img src="https://mintcdn.com/claude-code/jYgs7qigNjO1Badj/images/agent-sdk/permissions-flow.svg?fit=max&auto=format&n=jYgs7qigNjO1Badj&q=85&s=c771ad9085b1277d3708027a49c744bc" className="dark:hidden" alt="Diagram of the six-step permission evaluation flow matching the steps above: a tool request passes through hooks, deny rules, ask rules, permission mode, allow rules, and canUseTool. Hooks, deny rules, and canUseTool can route down to Blocked; permission mode bypass, allow rules, and canUseTool can route up to Execute; ask rules route to canUseTool." width="1180" height="260" data-path="images/agent-sdk/permissions-flow.svg" />

50 

51<img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/agent-sdk/permissions-flow-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=e53a91e9059cbf51852b7cedb4dd4251" className="hidden dark:block" alt="Diagram of the six-step permission evaluation flow matching the steps above: a tool request passes through hooks, deny rules, ask rules, permission mode, allow rules, and canUseTool. Hooks, deny rules, and canUseTool can route down to Blocked; permission mode bypass, allow rules, and canUseTool can route up to Execute; ask rules route to canUseTool." width="1180" height="260" data-path="images/agent-sdk/permissions-flow-dark.svg" />

50 52 

51As of v2.1.198, if you pass a `canUseTool` callback that this evaluation order can never reach, the TypeScript SDK emits a Node.js process warning once when the query is constructed. The warning's code is `CLAUDE_SDK_CAN_USE_TOOL_SHADOWED`. Two configurations trigger it:53As of v2.1.198, if you pass a `canUseTool` callback that this evaluation order can never reach, the TypeScript SDK emits a Node.js process warning once when the query is constructed. The warning's code is `CLAUDE_SDK_CAN_USE_TOOL_SHADOWED`. Two configurations trigger it:

52 54 


55 57 

56Entries with a specifier such as `Bash(ls *)` and the `acceptEdits` mode don't trigger it, and allow rules coming from settings files aren't visible to the check.58Entries with a specifier such as `Bash(ls *)` and the `acceptEdits` mode don't trigger it, and allow rules coming from settings files aren't visible to the check.

57 59 

58Listen with `process.on('warning', ...)` and match the code to log or suppress it. To gate every tool call regardless of mode and rules, use a [`PreToolUse` hook](/en/agent-sdk/hooks) instead.60Listen with `process.on('warning', ...)` and match the code to log or suppress it. To gate every tool call regardless of mode and rules, use a [`PreToolUse` hook](/docs/en/agent-sdk/hooks) instead.

59 61 

60This page focuses on **allow and deny rules** and **permission modes**. For the other steps:62This page focuses on **allow and deny rules** and **permission modes**. For the other steps:

61 63 

62* **Hooks:** run custom code to allow, deny, or modify tool requests. See [Control execution with hooks](/en/agent-sdk/hooks).64* **Hooks:** run custom code to allow, deny, or modify tool requests. See [Control execution with hooks](/docs/en/agent-sdk/hooks).

63* **canUseTool callback:** prompt users for approval at runtime, when no earlier step resolves the call. See [Handle approvals and user input](/en/agent-sdk/user-input).65* **canUseTool callback:** prompt users for approval at runtime, when no earlier step resolves the call. See [Handle approvals and user input](/docs/en/agent-sdk/user-input).

64 66 

65## Allow and deny rules67## Allow and deny rules

66 68 


77 79 

78Scoped rules for `Read` and `Edit` take a path pattern. `Edit(path)` rules govern all built-in tools that write files, including `Write` and `NotebookEdit`; a `Write(path)` rule is never matched by the file permission checks.80Scoped rules for `Read` and `Edit` take a path pattern. `Edit(path)` rules govern all built-in tools that write files, including `Write` and `NotebookEdit`; a `Write(path)` rule is never matched by the file permission checks.

79 81 

80Use `//path` for an absolute filesystem path: a deny rule of `Edit(//secrets/**)` blocks writes anywhere under `/secrets` on disk. With a single leading slash, `Edit(/secrets/**)` anchors at the rule's source instead. For rules passed through `allowed_tools` or `disallowed_tools`, that means the session's working directory, so the rule doesn't block `/secrets` on disk. See [Read and Edit rules](/en/permissions#read-and-edit) for the four anchor forms and how rules from settings files resolve.82Use `//path` for an absolute filesystem path: a deny rule of `Edit(//secrets/**)` blocks writes anywhere under `/secrets` on disk. With a single leading slash, `Edit(/secrets/**)` anchors at the rule's source instead. For rules passed through `allowed_tools` or `disallowed_tools`, that means the session's working directory, so the rule doesn't block `/secrets` on disk. See [Read and Edit rules](/docs/en/permissions#read-and-edit) for the four anchor forms and how rules from settings files resolve.

81 83 

82<Warning>84<Warning>

83 **Auto-approved tools never reach `canUseTool`.** A tool call approved at any earlier step, by `acceptEdits` or `bypassPermissions`, or by an allow rule, skips your `canUseTool` callback, so permission checks you put there are silently bypassed for that tool. `AskUserQuestion`, MCP tools marked [`_meta["anthropic/requiresUserInteraction"]`](/en/mcp#require-approval-for-a-specific-tool), and connector tools [your organization set to `ask`](/en/mcp#organization-controls-on-connector-tools) still reach the callback, even when an allow rule matches.85 **Auto-approved tools never reach `canUseTool`.** A tool call approved at any earlier step, by `acceptEdits` or `bypassPermissions`, or by an allow rule, skips your `canUseTool` callback, so permission checks you put there are silently bypassed for that tool. `AskUserQuestion`, MCP tools marked [`_meta["anthropic/requiresUserInteraction"]`](/docs/en/mcp#require-approval-for-a-specific-tool), and connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools) still reach the callback, even when an allow rule matches.

84 86 

85 Coverage depends on the entry's form: a bare name like `Read` or `mcp__github__get_issue` auto-approves every call to that tool, while a scoped rule like `Bash(ls *)` auto-approves only matching calls and other `Bash` calls still fall through to the callback. For checks that must run on every tool call, use a [`PreToolUse` hook](/en/agent-sdk/hooks): hooks run before every other step, and a hook deny applies even in `bypassPermissions` mode.87 Coverage depends on the entry's form: a bare name like `Read` or `mcp__github__get_issue` auto-approves every call to that tool, while a scoped rule like `Bash(ls *)` auto-approves only matching calls and other `Bash` calls still fall through to the callback. For checks that must run on every tool call, use a [`PreToolUse` hook](/docs/en/agent-sdk/hooks): hooks run before every other step, and a hook deny applies even in `bypassPermissions` mode.

86</Warning>88</Warning>

87 89 

88For a locked-down agent, pair `allowedTools` with `permissionMode: "dontAsk"`. Listed tools are approved, apart from the always-prompt tools in the Warning above; anything else is denied outright instead of prompting:90For a locked-down agent, pair `allowedTools` with `permissionMode: "dontAsk"`. Listed tools are approved, apart from the always-prompt tools in the Warning above; anything else is denied outright instead of prompting:


98 **`allowed_tools` does not constrain `bypassPermissions`.** `allowed_tools` only pre-approves the tools you list. Unlisted tools are not matched by any allow rule and fall through to the permission mode, where `bypassPermissions` approves them. Setting `allowed_tools=["Read"]` alongside `permission_mode="bypassPermissions"` still approves every tool, including `Bash`, `Write`, and `Edit`. If you need `bypassPermissions` but want specific tools blocked, use `disallowed_tools`.100 **`allowed_tools` does not constrain `bypassPermissions`.** `allowed_tools` only pre-approves the tools you list. Unlisted tools are not matched by any allow rule and fall through to the permission mode, where `bypassPermissions` approves them. Setting `allowed_tools=["Read"]` alongside `permission_mode="bypassPermissions"` still approves every tool, including `Bash`, `Write`, and `Edit`. If you need `bypassPermissions` but want specific tools blocked, use `disallowed_tools`.

99</Warning>101</Warning>

100 102 

101You can also configure allow, deny, and ask rules declaratively in `.claude/settings.json`. These rules are read when the `project` setting source is enabled, which it is for default `query()` options. If you set `setting_sources` (TypeScript: `settingSources`) explicitly, include `"project"` for them to apply. See [Permission settings](/en/settings#permission-settings) for the rule syntax.103You can also configure allow, deny, and ask rules declaratively in `.claude/settings.json`. These rules are read when the `project` setting source is enabled, which it is for default `query()` options. If you set `setting_sources` (TypeScript: `settingSources`) explicitly, include `"project"` for them to apply. See [Permission settings](/docs/en/settings#permission-settings) for the rule syntax.

102 104 

103## Permission modes105## Permission modes

104 106 


111| Mode | Description | Tool behavior |113| Mode | Description | Tool behavior |

112| :------------------ | :--------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |114| :------------------ | :--------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

113| `default` | Standard permission behavior | No auto-approvals; unmatched tools trigger your `canUseTool` callback |115| `default` | Standard permission behavior | No auto-approvals; unmatched tools trigger your `canUseTool` callback |

114| `dontAsk` | Deny instead of prompting | Anything not pre-approved by `allowed_tools` or rules is denied; connector tools [your organization set to `ask`](/en/mcp#organization-controls-on-connector-tools) and tools that require user interaction are denied even if you've pre-approved them. `canUseTool` is never called |116| `dontAsk` | Deny instead of prompting | Anything not pre-approved by `allowed_tools` or rules is denied; connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools) and tools that require user interaction are denied even if you've pre-approved them. `canUseTool` is never called |

115| `acceptEdits` | Auto-accept file edits | File edits and [filesystem operations](#accept-edits-mode-acceptedits) (`mkdir`, `rm`, `mv`, etc.) are automatically approved |117| `acceptEdits` | Auto-accept file edits | File edits and [filesystem operations](#accept-edits-mode-acceptedits) (`mkdir`, `rm`, `mv`, etc.) are automatically approved |

116| `bypassPermissions` | Bypass permission checks | Tools run without permission prompts, except tools matched by an explicit [`ask` rule](#how-permissions-are-evaluated), connector tools [your organization set to `ask`](/en/mcp#organization-controls-on-connector-tools), and tools that require user interaction (use with caution) |118| `bypassPermissions` | Bypass permission checks | Tools run without permission prompts, except tools matched by an explicit [`ask` rule](#how-permissions-are-evaluated), connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), and tools that require user interaction (use with caution) |

117| `plan` | Planning mode | Claude explores and plans without editing your source files; file edits are never auto-approved and prompt through your `canUseTool` callback |119| `plan` | Planning mode | Claude explores and plans without editing your source files; file edits are never auto-approved and prompt through your `canUseTool` callback |

118| `auto` | Model-classified approvals | A model classifier approves or denies permission prompts. See [Auto mode](/en/permission-modes#eliminate-prompts-with-auto-mode) for availability |120| `auto` | Model-classified approvals | A model classifier approves or denies permission prompts. See [Auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode) for availability |

119 121 

120<Warning>122<Warning>

121 **Subagent inheritance:** Subagents inherit the parent session's permission mode. An [`AgentDefinition`'s `permissionMode`](/en/agent-sdk/typescript#agentdefinition) can override it, except when the parent uses `bypassPermissions`, `acceptEdits`, or `auto`: those modes apply to every subagent and can't be overridden per subagent.123 **Subagent inheritance:** Subagents inherit the parent session's permission mode. An [`AgentDefinition`'s `permissionMode`](/docs/en/agent-sdk/typescript#agentdefinition) can override it, except when the parent uses `bypassPermissions`, `acceptEdits`, or `auto`: those modes apply to every subagent and can't be overridden per subagent.

122 124 

123 Subagents may have different system prompts and less constrained behavior than your main agent, so inheriting `bypassPermissions` grants them full, autonomous system access. Explicit [`ask` rules](#how-permissions-are-evaluated), connector tools [your organization set to `ask`](/en/mcp#organization-controls-on-connector-tools), and tools that require user interaction still force a prompt.125 Subagents may have different system prompts and less constrained behavior than your main agent, so inheriting `bypassPermissions` grants them full, autonomous system access. Explicit [`ask` rules](#how-permissions-are-evaluated), connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), and tools that require user interaction still force a prompt.

124</Warning>126</Warning>

125 127 

126### Set permission mode128### Set permission mode


246 248 

247#### Don't ask mode (`dontAsk`)249#### Don't ask mode (`dontAsk`)

248 250 

249Converts any permission prompt into a denial. Tools pre-approved by `allowed_tools`, `settings.json` allow rules, or a hook run as normal. Connector tools [your organization set to `ask`](/en/mcp#organization-controls-on-connector-tools) and tools that require user interaction are denied even when an allow rule matches. Everything else is denied without calling `canUseTool`.251Converts any permission prompt into a denial. Tools pre-approved by `allowed_tools`, `settings.json` allow rules, or a hook run as normal. Connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools) and tools that require user interaction are denied even when an allow rule matches. Everything else is denied without calling `canUseTool`.

250 252 

251**Use when:** you want a fixed, explicit tool surface for a headless agent and prefer a hard deny over silent reliance on `canUseTool` being absent.253**Use when:** you want a fixed, explicit tool surface for a headless agent and prefer a hard deny over silent reliance on `canUseTool` being absent.

252 254 


257<Warning>259<Warning>

258 Use with extreme caution. Claude has full system access in this mode. Only use in controlled environments where you trust all possible operations.260 Use with extreme caution. Claude has full system access in this mode. Only use in controlled environments where you trust all possible operations.

259 261 

260 `allowed_tools` does not constrain this mode. Every tool is approved, not just the ones you listed. Deny rules (`disallowed_tools`), explicit `ask` rules, and hooks are evaluated before the mode check and can still block a tool. Connector tools [your organization set to `ask`](/en/mcp#organization-controls-on-connector-tools) and tools that require user interaction still fall through to your `canUseTool` callback.262 `allowed_tools` does not constrain this mode. Every tool is approved, not just the ones you listed. Deny rules (`disallowed_tools`), explicit `ask` rules, and hooks are evaluated before the mode check and can still block a tool. Connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools) and tools that require user interaction still fall through to your `canUseTool` callback.

261</Warning>263</Warning>

262 264 

263#### Plan mode (`plan`)265#### Plan mode (`plan`)


266 268 

267File edits are never auto-approved in plan mode, even when an allow rule matches. They prompt through your `canUseTool` callback instead. {/* min-version: 2.1.212 */}On Claude Code v2.1.212 or later, shell commands that modify files, such as `touch` and `rm`, reach your `canUseTool` callback the same way.269File edits are never auto-approved in plan mode, even when an allow rule matches. They prompt through your `canUseTool` callback instead. {/* min-version: 2.1.212 */}On Claude Code v2.1.212 or later, shell commands that modify files, such as `touch` and `rm`, reach your `canUseTool` callback the same way.

268 270 

269Claude may use `AskUserQuestion` to clarify requirements before finalizing the plan. See [Handle approvals and user input](/en/agent-sdk/user-input#handle-clarifying-questions) for handling these prompts.271Claude may use `AskUserQuestion` to clarify requirements before finalizing the plan. See [Handle approvals and user input](/docs/en/agent-sdk/user-input#handle-clarifying-questions) for handling these prompts.

270 272 

271**Use when:** you want Claude to propose changes without executing them, such as during code review or when you need to approve changes before they're made.273**Use when:** you want Claude to propose changes without executing them, such as during code review or when you need to approve changes before they're made.

272 274 


274 276 

275For the other steps in the permission evaluation flow:277For the other steps in the permission evaluation flow:

276 278 

277* [Handle approvals and user input](/en/agent-sdk/user-input): interactive approval prompts and clarifying questions279* [Handle approvals and user input](/docs/en/agent-sdk/user-input): interactive approval prompts and clarifying questions

278* [Hooks guide](/en/agent-sdk/hooks): run custom code at key points in the agent lifecycle280* [Hooks guide](/docs/en/agent-sdk/hooks): run custom code at key points in the agent lifecycle

279* [Permission rules](/en/settings#permission-settings): declarative allow/deny rules in `settings.json`281* [Permission rules](/docs/en/settings#permission-settings): declarative allow/deny rules in `settings.json`

Details

45 npm install --save-dev tsx45 npm install --save-dev tsx

46 ```46 ```

47 47 

48 Setting `"type": "module"` in `package.json` lets your agent script use top-level `await`, and [tsx](https://tsx.is) runs TypeScript files directly. npm prints `added N packages` when the install succeeds.48 Setting `"type": "module"` in `package.json` lets your agent script use top-level `await`, and [tsx](https://tsx.hirok.io) runs TypeScript files directly. npm prints `added N packages` when the install succeeds.

49 </Tab>49 </Tab>

50 50 

51 <Tab title="TypeScript (existing project)">51 <Tab title="TypeScript (existing project)">


54 npm install --save-dev tsx54 npm install --save-dev tsx

55 ```55 ```

56 56 

57 [tsx](https://tsx.is) runs TypeScript files directly. If your project uses CommonJS, name your agent script `agent.mts` instead of `agent.ts`. The `.mts` extension makes tsx treat the file as an ES module, so top-level `await` works without converting your whole project to ES modules. Use `agent.mts` in place of `agent.ts` in the create and run steps later in this quickstart.57 [tsx](https://tsx.hirok.io) runs TypeScript files directly. If your project uses CommonJS, name your agent script `agent.mts` instead of `agent.ts`. The `.mts` extension makes tsx treat the file as an ES module, so top-level `await` works without converting your whole project to ES modules. Use `agent.mts` in place of `agent.ts` in the create and run steps later in this quickstart.

58 </Tab>58 </Tab>

59 59 

60 <Tab title="Python (uv)">60 <Tab title="Python (uv)">

agent-sdk/secure-deployment.md +349 −0 created

Details

1> ## Documentation Index

2> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt

3> Use this file to discover all available pages before exploring further.

4 

5# Securely deploying AI agents

6 

7> A guide to securing Claude Code and Agent SDK deployments with isolation, credential management, and network controls

8 

9Claude Code and the Agent SDK are powerful tools that can execute code, access files, and interact with external services on your behalf. Like any tool with these capabilities, deploying them thoughtfully ensures you get the benefits while maintaining appropriate controls.

10 

11Unlike traditional software that follows predetermined code paths, these tools generate their actions dynamically based on context and goals. This flexibility is what makes them useful, but it also means their behavior can be influenced by the content they process: files, webpages, or user input. This is sometimes called prompt injection. For example, if a repository's README contains unusual instructions, Claude Code might incorporate those into its actions in ways the operator didn't anticipate. This guide covers practical ways to reduce this risk.

12 

13The good news is that securing an agent deployment doesn't require exotic infrastructure. The same principles that apply to running any semi-trusted code apply here: isolation, least privilege, and defense in depth. Claude Code includes several security features that help with common concerns, and this guide walks through these along with additional hardening options for those who need them.

14 

15Not every deployment needs maximum security. A developer running Claude Code on their laptop has different requirements than a company processing customer data in a multi-tenant environment. This guide presents options ranging from Claude Code's built-in security features to hardened production architectures, so you can choose what fits your situation.

16 

17## Threat model

18 

19Agents can take unintended actions due to prompt injection (instructions embedded in content they process) or model error. Claude models are designed to resist this; see the [model overview](https://platform.claude.com/docs/en/about-claude/models/overview) and the system card for the model you deploy for evaluation details.

20 

21Defense in depth is still good practice though. For example, if an agent processes a malicious file that instructs it to send customer data to an external server, network controls can block that request entirely.

22 

23## Built-in security features

24 

25Claude Code includes several security features that address common concerns. See the [security documentation](/docs/en/security) for full details.

26 

27* **Permissions system**: Every tool and bash command can be configured to allow, block, or prompt the user for approval. Use glob patterns to create rules like "allow all npm commands" or "block any command with sudo". Organizations can set policies that apply across all users. See [permissions](/docs/en/permissions).

28* **Command parsing for permissions**: Before executing bash commands, Claude Code parses them into an AST and matches the result against your permission rules. Commands that cannot be parsed cleanly, or that do not match an allow rule, require explicit approval. A small set of constructs such as `eval` always require approval regardless of allow rules. This is a permission gate, not a sandbox; it does not infer whether a command is dangerous from its target path or effects.

29* **Web search summarization**: Search results are summarized rather than passing raw content directly into the context, reducing the risk of prompt injection from malicious web content.

30* **Sandbox mode**: Bash commands can run in a sandboxed environment that restricts filesystem and network access. See the [sandboxing documentation](/docs/en/sandboxing) for details.

31 

32## Security principles

33 

34For deployments that require additional hardening beyond Claude Code's defaults, these principles guide the available options.

35 

36### Security boundaries

37 

38A security boundary separates components with different trust levels. For high-security deployments, you can place sensitive resources (like credentials) outside the boundary containing the agent. If something goes wrong in the agent's environment, resources outside that boundary remain protected.

39 

40For example, rather than giving an agent direct access to an API key, you could run a proxy outside the agent's environment that injects the key into requests. The agent can make API calls, but it never sees the credential itself. This pattern is useful for multi-tenant deployments or when processing untrusted content.

41 

42### Least privilege

43 

44When needed, you can restrict the agent to only the capabilities required for its specific task:

45 

46| Resource | Restriction options |

47| ------------------- | ----------------------------------------------- |

48| Filesystem | Mount only needed directories, prefer read-only |

49| Network | Restrict to specific endpoints via proxy |

50| Credentials | Inject via proxy rather than exposing directly |

51| System capabilities | Drop Linux capabilities in containers |

52 

53### Defense in depth

54 

55For high-security environments, layering multiple controls provides additional protection. Options include:

56 

57* Container isolation

58* Network restrictions

59* Filesystem controls

60* Request validation at a proxy

61 

62The right combination depends on your threat model and operational requirements.

63 

64## Isolation technologies

65 

66Different isolation technologies offer different tradeoffs between security strength, performance, and operational complexity.

67 

68<Info>

69 In all of these configurations, Claude Code (or your Agent SDK application) runs inside the isolation boundary (the sandbox, container, or VM). The security controls described below restrict what the agent can access from within that boundary.

70</Info>

71 

72| Technology | Isolation strength | Performance overhead | Complexity |

73| ----------------------- | ------------------------------ | -------------------- | ----------- |

74| Sandbox runtime | Good (secure defaults) | Very low | Low |

75| Containers (Docker) | Setup dependent | Low | Medium |

76| gVisor | Excellent (with correct setup) | Medium/High | Medium |

77| VMs (Firecracker, QEMU) | Excellent (with correct setup) | High | Medium/High |

78 

79### Sandbox runtime

80 

81For lightweight isolation without containers, [sandbox-runtime](https://github.com/anthropic-experimental/sandbox-runtime) enforces filesystem and network restrictions at the OS level.

82 

83The main advantage is simplicity: no Docker configuration, container images, or networking setup required. The proxy and filesystem restrictions are built in. You provide a settings file specifying allowed domains and paths.

84 

85**How it works:**

86 

87* **Filesystem**: Uses OS primitives (`bubblewrap` on Linux, `sandbox-exec` on macOS) to restrict read/write access to configured paths

88* **Network**: Removes network namespace (Linux) or uses Seatbelt profiles (macOS) to route network traffic through a built-in proxy

89* **Configuration**: JSON-based allowlists for domains and filesystem paths

90 

91**Setup:**

92 

93```bash theme={null}

94npm install @anthropic-ai/sandbox-runtime

95```

96 

97Then create a configuration file specifying allowed paths and domains.

98 

99**Security considerations:**

100 

1011. **Same-host kernel**: Unlike VMs, sandboxed processes share the host kernel. A kernel vulnerability could theoretically enable escape. For some threat models this is acceptable, but if you need kernel-level isolation, use gVisor or a separate VM.

102 

1032. **No TLS inspection**: The proxy allowlists domains based on the client-supplied hostname and does not terminate or inspect encrypted traffic. Code running inside the sandbox can potentially use [domain fronting](https://en.wikipedia.org/wiki/Domain_fronting) or similar techniques to reach hosts outside the allowlist. If your threat model requires stronger guarantees, configure a [TLS-terminating proxy](#traffic-forwarding). See the [sandboxing security limitations](/docs/en/sandboxing#security-limitations) for more detail. Separately, if the agent has permissive credentials for an allowed domain, ensure it cannot use that domain to trigger other network requests or to exfiltrate data.

104 

105For many single-developer and CI/CD use cases, sandbox-runtime raises the bar significantly with minimal setup. The sections below cover containers and VMs for deployments requiring stronger isolation.

106 

107### Containers

108 

109Containers provide isolation through Linux namespaces. Each container has its own view of the filesystem, process tree, and network stack, while sharing the host kernel.

110 

111A security-hardened container configuration might look like this:

112 

113```bash theme={null}

114docker run \

115 --cap-drop ALL \

116 --security-opt no-new-privileges \

117 --security-opt seccomp=/path/to/seccomp-profile.json \

118 --read-only \

119 --tmpfs /tmp:rw,noexec,nosuid,size=100m \

120 --tmpfs /home/agent:rw,noexec,nosuid,size=500m \

121 --network none \

122 --memory 2g \

123 --cpus 2 \

124 --pids-limit 100 \

125 --user 1000:1000 \

126 -v /path/to/code:/workspace:ro \

127 -v /var/run/proxy.sock:/var/run/proxy.sock:ro \

128 agent-image

129```

130 

131Here's what each option does:

132 

133| Option | Purpose |

134| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |

135| `--cap-drop ALL` | Removes Linux capabilities like `NET_ADMIN` and `SYS_ADMIN` that could enable privilege escalation |

136| `--security-opt no-new-privileges` | Prevents processes from gaining privileges through setuid binaries |

137| `--security-opt seccomp=...` | Restricts available syscalls; Docker's default blocks \~44, custom profiles can block more |

138| `--read-only` | Makes the container's root filesystem immutable, preventing the agent from persisting changes |

139| `--tmpfs /tmp:...` | Provides a writable temporary directory that's cleared when the container stops |

140| `--network none` | Removes all network interfaces; the agent communicates through the mounted Unix socket below |

141| `--memory 2g` | Limits memory usage to prevent resource exhaustion |

142| `--pids-limit 100` | Limits process count to prevent fork bombs |

143| `--user 1000:1000` | Runs as a non-root user |

144| `-v ...:/workspace:ro` | Mounts code read-only so the agent can analyze but not modify it. **Avoid mounting sensitive host directories like `~/.ssh`, `~/.aws`, or `~/.config`** |

145| `-v .../proxy.sock:...` | Mounts a Unix socket connected to a proxy running outside the container (see below) |

146 

147**Unix socket architecture:**

148 

149With `--network none`, the container has no network interfaces at all. The only way for the agent to reach the outside world is through the mounted Unix socket, which connects to a proxy running on the host. This proxy can enforce domain allowlists, inject credentials, and log all traffic.

150 

151This is the same architecture used by [sandbox-runtime](https://github.com/anthropic-experimental/sandbox-runtime). Even if the agent is compromised via prompt injection, it cannot exfiltrate data to arbitrary servers. It can only communicate through the proxy, which controls what domains are reachable. For more details, see the [Claude Code sandboxing blog post](https://www.anthropic.com/engineering/claude-code-sandboxing).

152 

153**Additional hardening options:**

154 

155| Option | Purpose |

156| ---------------- | -------------------------------------------------------------------------------------------------------------------- |

157| `--userns-remap` | Maps container root to unprivileged host user; requires daemon configuration but limits damage from container escape |

158| `--ipc private` | Isolates inter-process communication to prevent cross-container attacks |

159 

160### gVisor

161 

162Standard containers share the host kernel: when code inside a container makes a system call, it goes directly to the same kernel that runs the host. This means a kernel vulnerability could allow container escape. gVisor addresses this by intercepting system calls in userspace before they reach the host kernel, implementing its own compatibility layer that handles most syscalls without involving the real kernel.

163 

164If an agent runs malicious code (perhaps due to prompt injection), that code runs in the container and could attempt kernel exploits. With gVisor, the attack surface is much smaller: the malicious code would need to exploit gVisor's userspace implementation first and would have limited access to the real kernel.

165 

166To use gVisor with Docker, install the `runsc` runtime and configure the daemon:

167 

168```json /etc/docker/daemon.json theme={null}

169{

170 "runtimes": {

171 "runsc": {

172 "path": "/usr/local/bin/runsc"

173 }

174 }

175}

176```

177 

178Then run containers with:

179 

180```bash theme={null}

181docker run --runtime=runsc agent-image

182```

183 

184**Performance considerations:**

185 

186| Workload | Overhead |

187| --------------------- | -------------------------------------------------- |

188| CPU-bound computation | \~0% (no syscall interception) |

189| Simple syscalls | \~2× slower |

190| File I/O intensive | Up to 10-200× slower for heavy open/close patterns |

191 

192For multi-tenant environments or when processing untrusted content, the additional isolation is often worth the overhead.

193 

194### Virtual machines

195 

196VMs provide hardware-level isolation through CPU virtualization extensions. Each VM runs its own kernel, creating a strong boundary. A vulnerability in the guest kernel doesn't directly compromise the host. However, VMs aren't automatically "more secure" than alternatives like gVisor. VM security depends heavily on the hypervisor and device emulation code.

197 

198Firecracker is designed for lightweight microVM isolation. It can boot VMs in under 125ms with less than 5 MiB memory overhead, stripping away unnecessary device emulation to reduce attack surface.

199 

200With this approach, the agent VM has no external network interface. Instead, it communicates through `vsock` (virtual sockets). All traffic routes through vsock to a proxy on the host, which enforces allowlists and injects credentials before forwarding requests.

201 

202### Cloud deployments

203 

204For cloud deployments, you can combine any of the above isolation technologies with cloud-native network controls:

205 

2061. Run agent containers in a private subnet with no internet gateway

2072. Configure cloud firewall rules (AWS Security Groups, GCP VPC firewall) to block all egress except to your proxy

2083. Run a proxy (such as [Envoy](https://www.envoyproxy.io/) with its `credential_injector` filter) that validates requests, enforces domain allowlists, injects credentials, and forwards to external APIs

2094. Assign minimal IAM permissions to the agent's service account, routing sensitive access through the proxy where possible

2105. Log all traffic at the proxy for audit purposes

211 

212## Credential management

213 

214Agents often need credentials to call APIs, access repositories, or interact with cloud services. The challenge is providing this access without exposing the credentials themselves.

215 

216### The proxy pattern

217 

218The recommended approach is to run a proxy outside the agent's security boundary that injects credentials into outgoing requests. The agent sends requests without credentials, the proxy adds them, and forwards the request to its destination.

219 

220This pattern has several benefits:

221 

2221. The agent never sees the actual credentials

2232. The proxy can enforce an allowlist of permitted endpoints

2243. The proxy can log all requests for auditing

2254. Credentials are stored in one secure location rather than distributed to each agent

226 

227### Configuring Claude Code to use a proxy

228 

229Claude Code supports two methods for routing sampling requests through a proxy:

230 

231**Option 1: ANTHROPIC\_BASE\_URL (simple but only for sampling API requests)**

232 

233```bash theme={null}

234export ANTHROPIC_BASE_URL="http://localhost:8080"

235```

236 

237This tells Claude Code and the Agent SDK to send sampling requests to your proxy instead of the Claude API directly. Your proxy receives plaintext HTTP requests, can inspect and modify them (including injecting credentials), then forwards to the real API.

238 

239**Option 2: HTTP\_PROXY / HTTPS\_PROXY (system-wide)**

240 

241```bash theme={null}

242export HTTP_PROXY="http://localhost:8080"

243export HTTPS_PROXY="http://localhost:8080"

244```

245 

246Claude Code and the Agent SDK respect these standard environment variables, routing all HTTP traffic through the proxy. For HTTPS, the proxy creates an encrypted CONNECT tunnel: it cannot see or modify request contents without TLS interception.

247 

248### Implementing a proxy

249 

250You can build your own proxy or use an existing one:

251 

252* [Envoy Proxy](https://www.envoyproxy.io/): production-grade proxy with `credential_injector` filter for adding auth headers

253* [mitmproxy](https://mitmproxy.org/): TLS-terminating proxy for inspecting and modifying HTTPS traffic

254* [Squid](http://www.squid-cache.org/): caching proxy with access control lists

255* [LiteLLM](https://github.com/BerriAI/litellm): LLM gateway with credential injection and rate limiting

256 

257### Credentials for other services

258 

259Beyond sampling from the Claude API, agents often need authenticated access to other services, such as git repositories, databases, and internal APIs. There are two main approaches:

260 

261#### Custom tools

262 

263Provide access through an MCP server or custom tool that routes requests to a service running outside the agent's security boundary. The agent calls the tool, but the actual authenticated request happens outside. The tool calls to a proxy which injects the credentials.

264 

265For example, a git MCP server could accept commands from the agent but forward them to a git proxy running on the host, which adds authentication before contacting the remote repository. The agent never sees the credentials.

266 

267Advantages:

268 

269* **No TLS interception**: The external service makes authenticated requests directly

270* **Credentials stay outside**: The agent only sees the tool interface, not the underlying credentials

271 

272#### Traffic forwarding

273 

274For Claude API calls, `ANTHROPIC_BASE_URL` lets you route requests to a proxy that can inspect and modify them in plaintext. But for other HTTPS services (GitHub, npm registries, internal APIs), the traffic is often encrypted end-to-end. Even if you route it through a proxy via `HTTP_PROXY`, the proxy only sees an opaque TLS tunnel and can't inject credentials.

275 

276To modify HTTPS traffic to arbitrary services, without using a custom tool, you need a TLS-terminating proxy that decrypts traffic, inspects or modifies it, then re-encrypts it before forwarding. This requires:

277 

2781. Running the proxy outside the agent's container

2792. Installing the proxy's CA certificate in the agent's trust store (so the agent trusts the proxy's certificates)

2803. Configuring `HTTP_PROXY`/`HTTPS_PROXY` to route traffic through the proxy

281 

282This approach handles any HTTP-based service without writing custom tools, but adds complexity around certificate management.

283 

284Note that not all programs respect `HTTP_PROXY`/`HTTPS_PROXY`. Most tools (curl, pip, npm, git) do, but some may bypass these variables and connect directly. For example, Node.js `fetch()` ignores these variables by default; in Node 24+ you can set `NODE_USE_ENV_PROXY=1` to enable support. For comprehensive coverage, you can use [proxychains](https://github.com/haad/proxychains) to intercept network calls, or configure iptables to redirect outbound traffic to a transparent proxy.

285 

286<Info>

287 A **transparent proxy** intercepts traffic at the network level, so the client doesn't need to be configured to use it. Regular proxies require clients to explicitly connect and speak HTTP CONNECT or SOCKS. Transparent proxies (like Squid or mitmproxy in transparent mode) can handle raw redirected TCP connections.

288</Info>

289 

290Both approaches still require the TLS-terminating proxy and trusted CA certificate. They just ensure traffic actually reaches the proxy.

291 

292## Filesystem configuration

293 

294Filesystem controls determine what files the agent can read and write.

295 

296### Read-only code mounting

297 

298When the agent needs to analyze code but not modify it, mount the directory read-only:

299 

300```bash theme={null}

301docker run -v /path/to/code:/workspace:ro agent-image

302```

303 

304<Warning>

305 Even read-only access to a code directory can expose credentials. Common files to exclude or sanitize before mounting:

306 

307 | File | Risk |

308 | ------------------------------------------------------- | ------------------------------------- |

309 | `.env`, `.env.local` | API keys, database passwords, secrets |

310 | `~/.git-credentials` | Git passwords/tokens in plaintext |

311 | `~/.aws/credentials` | AWS access keys |

312 | `~/.config/gcloud/application_default_credentials.json` | Google Cloud ADC tokens |

313 | `~/.azure/` | Azure CLI credentials |

314 | `~/.docker/config.json` | Docker registry auth tokens |

315 | `~/.kube/config` | Kubernetes cluster credentials |

316 | `.npmrc`, `.pypirc` | Package registry tokens |

317 | `*-service-account.json` | GCP service account keys |

318 | `*.pem`, `*.key` | Private keys |

319 

320 Consider copying only the source files needed, or using `.dockerignore`-style filtering.

321</Warning>

322 

323### Writable locations

324 

325If the agent needs to write files, you have a few options depending on whether you want changes to persist:

326 

327For ephemeral workspaces in containers, use `tmpfs` mounts that exist only in memory and are cleared when the container stops:

328 

329```bash theme={null}

330docker run \

331 --read-only \

332 --tmpfs /tmp:rw,noexec,nosuid,size=100m \

333 --tmpfs /workspace:rw,noexec,size=500m \

334 agent-image

335```

336 

337If you want to review changes before persisting them, an overlay filesystem lets the agent write without modifying underlying files. Changes are stored in a separate layer you can inspect, apply, or discard. For fully persistent output, mount a dedicated volume but keep it separate from sensitive directories.

338 

339## Further reading

340 

341* [Claude Code security documentation](/docs/en/security)

342* [Hosting the Agent SDK](/docs/en/agent-sdk/hosting)

343* [Handling permissions](/docs/en/agent-sdk/permissions)

344* [Sandbox runtime](https://github.com/anthropic-experimental/sandbox-runtime)

345* [The Lethal Trifecta for AI Agents](https://simonwillison.net/2025/Jun/16/the-lethal-trifecta/)

346* [OWASP Top 10 for LLM Applications](https://owasp.org/www-project-top-10-for-large-language-model-applications/)

347* [Docker Security Best Practices](https://docs.docker.com/engine/security/)

348* [gVisor Documentation](https://gvisor.dev/docs/)

349* [Firecracker Documentation](https://firecracker-microvm.github.io/)

Details

11Returning to a session means the agent has full context from before: files it already read, analysis it already performed, decisions it already made. You can ask a follow-up question, recover from an interruption, or branch off to try a different approach.11Returning to a session means the agent has full context from before: files it already read, analysis it already performed, decisions it already made. You can ask a follow-up question, recover from an interruption, or branch off to try a different approach.

12 12 

13<Note>13<Note>

14 Sessions persist the **conversation**, not the filesystem. To snapshot and revert file changes the agent made, use [file checkpointing](/en/agent-sdk/file-checkpointing).14 Sessions persist the **conversation**, not the filesystem. To snapshot and revert file changes the agent made, use [file checkpointing](/docs/en/agent-sdk/file-checkpointing).

15</Note>15</Note>

16 16 

17This guide covers how to pick the right approach for your app, the SDK interfaces that track sessions automatically, how to capture session IDs and use `resume` and `fork` manually, and what to know about resuming sessions across hosts.17This guide covers how to pick the right approach for your app, the SDK interfaces that track sessions automatically, how to capture session IDs and use `resume` and `fork` manually, and what to know about resuming sessions across hosts.

18 18 

19## Choose an approach19## Choose an approach

20 20 

21How much session handling you need depends on your application's shape. Session management comes into play when you send multiple prompts that should share context. Within a single `query()` call, the agent already takes as many turns as it needs, and permission prompts and `AskUserQuestion` are [handled in-loop](/en/agent-sdk/user-input) (they don't end the call).21How much session handling you need depends on your application's shape. Session management comes into play when you send multiple prompts that should share context. Within a single `query()` call, the agent already takes as many turns as it needs, and permission prompts and `AskUserQuestion` are [handled in-loop](/docs/en/agent-sdk/user-input) (they don't end the call).

22 22 

23| What you're building | What to use |23| What you're building | What to use |

24| :-------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- |24| :-------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- |


27| Pick up where you left off after a process restart | `continue_conversation=True` (Python) / `continue: true` (TypeScript). Resumes the most recent session in the directory, no ID needed. |27| Pick up where you left off after a process restart | `continue_conversation=True` (Python) / `continue: true` (TypeScript). Resumes the most recent session in the directory, no ID needed. |

28| Resume a specific past session (not the most recent) | Capture the session ID and pass it to `resume`. |28| Resume a specific past session (not the most recent) | Capture the session ID and pass it to `resume`. |

29| Try an alternative approach without losing the original | Fork the session. |29| Try an alternative approach without losing the original | Fork the session. |

30| Stateless task, don't want anything written to disk (TypeScript only) | Set [`persistSession: false`](/en/agent-sdk/typescript#options). The session exists only in memory for the duration of the call. Python always persists to disk. |30| Stateless task, don't want anything written to disk (TypeScript only) | Set [`persistSession: false`](/docs/en/agent-sdk/typescript#options). The session exists only in memory for the duration of the call. Python always persists to disk. |

31 31 

32### Continue, resume, and fork32### Continue, resume, and fork

33 33 

34Continue, resume, and fork are option fields you set on `query()` ([`ClaudeAgentOptions`](/en/agent-sdk/python#claudeagentoptions) in Python, [`Options`](/en/agent-sdk/typescript#options) in TypeScript).34Continue, resume, and fork are option fields you set on `query()` ([`ClaudeAgentOptions`](/docs/en/agent-sdk/python#claudeagentoptions) in Python, [`Options`](/docs/en/agent-sdk/typescript#options) in TypeScript).

35 35 

36**Continue** and **resume** both pick up an existing session and add to it. The difference is how they find that session:36**Continue** and **resume** both pick up an existing session and add to it. The difference is how they find that session:

37 37 


46 46 

47### Python: `ClaudeSDKClient`47### Python: `ClaudeSDKClient`

48 48 

49[`ClaudeSDKClient`](/en/agent-sdk/python#claudesdkclient) handles session IDs internally. Each call to `client.query()` automatically continues the same session. Call [`client.receive_response()`](/en/agent-sdk/python#claudesdkclient) to iterate over the messages for the current query. Use the client as an async context manager so connection setup and teardown are handled for you, or call `connect()` and `disconnect()` manually.49[`ClaudeSDKClient`](/docs/en/agent-sdk/python#claudesdkclient) handles session IDs internally. Each call to `client.query()` automatically continues the same session. Call [`client.receive_response()`](/docs/en/agent-sdk/python#claudesdkclient) to iterate over the messages for the current query. Use the client as an async context manager so connection setup and teardown are handled for you, or call `connect()` and `disconnect()` manually.

50 50 

51This example runs two queries against the same `client`. The first asks the agent to analyze a module; the second asks it to refactor that module. Because both calls go through the same client instance, the second query has full context from the first without any explicit `resume` or session ID:51This example runs two queries against the same `client`. The first asks the agent to analyze a module; the second asks it to refactor that module. Because both calls go through the same client instance, the second query has full context from the first without any explicit `resume` or session ID:

52 52 


98 98 

99Each query prints the agent's text response followed by a status line from the result message, such as `[done: success, cost: $0.0042]`.99Each query prints the agent's text response followed by a status line from the result message, such as `[done: success, cost: $0.0042]`.

100 100 

101See the [Python SDK reference](/en/agent-sdk/python#choosing-between-query-and-claudesdkclient) for details on when to use `ClaudeSDKClient` vs the standalone `query()` function.101See the [Python SDK reference](/docs/en/agent-sdk/python#choosing-between-query-and-claudesdkclient) for details on when to use `ClaudeSDKClient` vs the standalone `query()` function.

102 102 

103### TypeScript: `continue: true`103### TypeScript: `continue: true`

104 104 


140```140```

141 141 

142<Note>142<Note>

143 The experimental [V2 session API](/en/agent-sdk/typescript-v2-preview), which provided `createSession()` with a `send` / `stream` pattern, was removed in TypeScript Agent SDK 0.3.142. Use the `query()` function and the session options described on this page instead.143 The experimental [V2 session API](/docs/en/agent-sdk/typescript-v2-preview), which provided `createSession()` with a `send` / `stream` pattern, was removed in TypeScript Agent SDK 0.3.142. Use the `query()` function and the session options described on this page instead.

144</Note>144</Note>

145 145 

146## Use session options with `query()`146## Use session options with `query()`

147 147 

148### Capture the session ID148### Capture the session ID

149 149 

150Resume and fork require a session ID. Read it from the `session_id` field on the result message ([`ResultMessage`](/en/agent-sdk/python#resultmessage) in Python, [`SDKResultMessage`](/en/agent-sdk/typescript#sdkresultmessage) in TypeScript), which is present on every result regardless of success or error. In TypeScript the ID is also available earlier as a direct field on the init `SystemMessage`; in Python it's nested inside `SystemMessage.data`.150Resume and fork require a session ID. Read it from the `session_id` field on the result message ([`ResultMessage`](/docs/en/agent-sdk/python#resultmessage) in Python, [`SDKResultMessage`](/docs/en/agent-sdk/typescript#sdkresultmessage) in TypeScript), which is present on every result regardless of success or error. In TypeScript the ID is also available earlier as a direct field on the init `SystemMessage`; in Python it's nested inside `SystemMessage.data`.

151 151 

152<CodeGroup>152<CodeGroup>

153 ```python Python theme={null}153 ```python Python theme={null}


170 if message.subtype == "success":170 if message.subtype == "success":

171 print(message.result)171 print(message.result)

172 except Exception as error:172 except Exception as error:

173 # A single-shot query() raises after yielding an error result.173 # A single-shot query() raises after yielding an error result. If the

174 # If the failure was an error result, session_id was already174 # failure was an error result, the loop above already captured session_id;

175 # captured by the loop above; connection or process failures175 # process failures yield no result message, so session_id stays None.

176 # yield no result message.

177 print(f"Session ended with an error: {error}")176 print(f"Session ended with an error: {error}")

178 177 

179 print(f"Session ID: {session_id}")178 print(f"Session ID: {session_id}")


201 }200 }

202 }201 }

203 } catch (error) {202 } catch (error) {

204 // A single-shot query() throws after yielding an error result.203 // A single-shot query() throws after yielding an error result. If the

205 // If the failure was an error result, sessionId was already captured204 // failure was an error result, the loop above already captured sessionId;

206 // by the loop above; connection or process failures yield no result205 // process failures yield no result message, so sessionId stays undefined.

207 // message.

208 console.error(`Session ended with an error: ${error}`);206 console.error(`Session ended with an error: ${error}`);

209 }207 }

210 208 


219Pass a session ID to `resume` to return to that specific session. The agent picks up with full context from wherever the session left off. Common reasons to resume:217Pass a session ID to `resume` to return to that specific session. The agent picks up with full context from wherever the session left off. Common reasons to resume:

220 218 

221* **Follow up on a completed task.** The agent already analyzed something; now you want it to act on that analysis without re-reading files.219* **Follow up on a completed task.** The agent already analyzed something; now you want it to act on that analysis without re-reading files.

222* **Recover from a limit.** The first run ended with `error_max_turns` or `error_max_budget_usd` (see [Handle the result](/en/agent-sdk/agent-loop#handle-the-result)); resume with a higher limit. In a single-shot `query()` call the SDK raises after yielding that error result, so catch the error before resuming.220* **Recover from a limit.** The first run ended with `error_max_turns` or `error_max_budget_usd` (see [Handle the result](/docs/en/agent-sdk/agent-loop#handle-the-result)); resume with a higher limit. In a single-shot `query()` call the SDK raises after yielding that error result, so catch the error before resuming.

223* **Restart your process.** You captured the ID before shutdown and want to restore the conversation.221* **Restart your process.** You captured the ID before shutdown and want to restore the conversation.

224 222 

225This example resumes the session from [Capture the session ID](#capture-the-session-id) with a follow-up prompt. Because you're resuming, the agent already has the prior analysis in context:223This example resumes the session from [Capture the session ID](#capture-the-session-id) with a follow-up prompt. Because you're resuming, the agent already has the prior analysis in context:


274 If a `resume` call returns a fresh session instead of the expected history, the most common cause is a mismatched `cwd`. Sessions are stored under `~/.claude/projects/<encoded-cwd>/*.jsonl`, or under `$CLAUDE_CONFIG_DIR/projects/<encoded-cwd>/*.jsonl` if you set the `CLAUDE_CONFIG_DIR` environment variable, where `<encoded-cwd>` is the absolute working directory with every non-alphanumeric character replaced by `-` (so `/Users/me/proj` becomes `-Users-me-proj`). If your resume call runs from a different directory, the SDK looks in the wrong place. The session file also needs to exist on the current machine.272 If a `resume` call returns a fresh session instead of the expected history, the most common cause is a mismatched `cwd`. Sessions are stored under `~/.claude/projects/<encoded-cwd>/*.jsonl`, or under `$CLAUDE_CONFIG_DIR/projects/<encoded-cwd>/*.jsonl` if you set the `CLAUDE_CONFIG_DIR` environment variable, where `<encoded-cwd>` is the absolute working directory with every non-alphanumeric character replaced by `-` (so `/Users/me/proj` becomes `-Users-me-proj`). If your resume call runs from a different directory, the SDK looks in the wrong place. The session file also needs to exist on the current machine.

275</Tip>273</Tip>

276 274 

277To resume sessions across machines or in serverless environments, mirror transcripts to shared storage with a [`SessionStore` adapter](/en/agent-sdk/session-storage).275To resume sessions across machines or in serverless environments, mirror transcripts to shared storage with a [`SessionStore` adapter](/docs/en/agent-sdk/session-storage).

278 276 

279### Fork to explore alternatives277### Fork to explore alternatives

280 278 

281Forking creates a new session that starts with a copy of the original's history but diverges from that point. The fork gets its own session ID; the original's ID and history stay unchanged. You end up with two independent sessions you can resume separately.279Forking creates a new session that starts with a copy of the original's history but diverges from that point. The fork gets its own session ID; the original's ID and history stay unchanged. You end up with two independent sessions you can resume separately.

282 280 

283<Note>281<Note>

284 Forking branches the conversation history, not the filesystem. If a forked agent edits files, those changes are real and visible to any session working in the same directory. To branch and revert file changes, use [file checkpointing](/en/agent-sdk/file-checkpointing).282 Forking branches the conversation history, not the filesystem. If a forked agent edits files, those changes are real and visible to any session working in the same directory. To branch and revert file changes, use [file checkpointing](/docs/en/agent-sdk/file-checkpointing).

285</Note>283</Note>

286 284 

287This example builds on [Capture the session ID](#capture-the-session-id): you've already analyzed an auth module in `session_id` and want to explore OAuth2 without losing the JWT-focused thread. The first block forks the session and captures the fork's ID (`forked_id`); the second block resumes the original `session_id` to continue down the JWT path. You now have two session IDs pointing at two separate histories:285This example builds on [Capture the session ID](#capture-the-session-id): you've already analyzed an auth module in `session_id` and want to explore OAuth2 without losing the JWT-focused thread. The first block forks the session and captures the fork's ID (`forked_id`); the second block resumes the original `session_id` to continue down the JWT path. You now have two session IDs pointing at two separate histories:


393* **Move the session file.** Persist `~/.claude/projects/<encoded-cwd>/<session-id>.jsonl` from the first run and restore it to the same path on the new host before calling `resume`. The `cwd` must match.391* **Move the session file.** Persist `~/.claude/projects/<encoded-cwd>/<session-id>.jsonl` from the first run and restore it to the same path on the new host before calling `resume`. The `cwd` must match.

394* **Don't rely on session resume.** Capture the results you need (analysis output, decisions, file diffs) as application state and pass them into a fresh session's prompt. This is often more robust than shipping transcript files around.392* **Don't rely on session resume.** Capture the results you need (analysis output, decisions, file diffs) as application state and pass them into a fresh session's prompt. This is often more robust than shipping transcript files around.

395 393 

396Both SDKs expose functions for enumerating sessions on disk and reading their messages: [`listSessions()`](/en/agent-sdk/typescript#listsessions) and [`getSessionMessages()`](/en/agent-sdk/typescript#getsessionmessages) in TypeScript, [`list_sessions()`](/en/agent-sdk/python#list_sessions) and [`get_session_messages()`](/en/agent-sdk/python#get_session_messages) in Python. Use them to build custom session pickers, cleanup logic, or transcript viewers.394Both SDKs expose functions for enumerating sessions on disk and reading their messages: [`listSessions()`](/docs/en/agent-sdk/typescript#listsessions) and [`getSessionMessages()`](/docs/en/agent-sdk/typescript#getsessionmessages) in TypeScript, [`list_sessions()`](/docs/en/agent-sdk/python#list_sessions) and [`get_session_messages()`](/docs/en/agent-sdk/python#get_session_messages) in Python. Use them to build custom session pickers, cleanup logic, or transcript viewers.

397 395 

398Both SDKs also expose functions for looking up and mutating individual sessions: [`get_session_info()`](/en/agent-sdk/python#get_session_info), [`rename_session()`](/en/agent-sdk/python#rename_session), and [`tag_session()`](/en/agent-sdk/python#tag_session) in Python, and [`getSessionInfo()`](/en/agent-sdk/typescript#getsessioninfo), [`renameSession()`](/en/agent-sdk/typescript#renamesession), and [`tagSession()`](/en/agent-sdk/typescript#tagsession) in TypeScript. Use them to organize sessions by tag or give them human-readable titles.396Both SDKs also expose functions for looking up and mutating individual sessions: [`get_session_info()`](/docs/en/agent-sdk/python#get_session_info), [`rename_session()`](/docs/en/agent-sdk/python#rename_session), and [`tag_session()`](/docs/en/agent-sdk/python#tag_session) in Python, and [`getSessionInfo()`](/docs/en/agent-sdk/typescript#getsessioninfo), [`renameSession()`](/docs/en/agent-sdk/typescript#renamesession), and [`tagSession()`](/docs/en/agent-sdk/typescript#tagsession) in TypeScript. Use them to organize sessions by tag or give them human-readable titles.

399 397 

400## Related resources398## Related resources

401 399 

402* [How the agent loop works](/en/agent-sdk/agent-loop): Understand turns, messages, and context accumulation within a session400* [How the agent loop works](/docs/en/agent-sdk/agent-loop): Understand turns, messages, and context accumulation within a session

403* [File checkpointing](/en/agent-sdk/file-checkpointing): Snapshot and revert file changes the agent made within a session401* [File checkpointing](/docs/en/agent-sdk/file-checkpointing): Snapshot and revert file changes the agent made within a session

404* [Python `ClaudeAgentOptions`](/en/agent-sdk/python#claudeagentoptions): Full session option reference for Python402* [Python `ClaudeAgentOptions`](/docs/en/agent-sdk/python#claudeagentoptions): Full session option reference for Python

405* [TypeScript `Options`](/en/agent-sdk/typescript#options): Full session option reference for TypeScript403* [TypeScript `Options`](/docs/en/agent-sdk/typescript#options): Full session option reference for TypeScript

Details

16 16 

17When using the Claude Agent SDK, Skills are:17When using the Claude Agent SDK, Skills are:

18 18 

191. **Defined as filesystem artifacts**: Created as `SKILL.md` files in specific directories (`.claude/skills/`)191. **Defined as filesystem artifacts**: you create each Skill as a `SKILL.md` file in its own directory, such as `.claude/skills/<name>/SKILL.md`

202. **Loaded from filesystem**: Skills are loaded from filesystem locations governed by `settingSources` (TypeScript) or `setting_sources` (Python)202. **Loaded from filesystem**: the SDK loads Skills from the filesystem locations governed by `settingSources` (TypeScript) or `setting_sources` (Python)

213. **Automatically discovered**: Once filesystem settings are loaded, Skill metadata is discovered at startup from user and project directories; full content loaded when triggered213. **Automatically discovered**: once filesystem settings load, the SDK discovers Skill metadata at startup from user and project directories, and loads the full content when Claude invokes the Skill

224. **Model-invoked**: Claude autonomously chooses when to use them based on context224. **Model-invoked**: Claude autonomously chooses when to use them based on context

235. **Filtered via the `skills` option**: Discovered skills are enabled by default. Pass a list of skill names, `"all"`, or `[]` to control which are available in the session235. **Filtered via the `skills` option**: discovered skills are enabled by default. Pass a list of skill names, `"all"`, or `[]` to control which are available in the session

24 24 

25Unlike subagents (which can be defined programmatically), Skills must be created as filesystem artifacts. The SDK does not provide a programmatic API for registering Skills.25Unlike subagents (which can be defined programmatically), Skills must be created as filesystem artifacts. The SDK does not provide a programmatic API for registering Skills.

26 26 


108 108 

109## Creating Skills109## Creating Skills

110 110 

111Skills are defined as directories containing a `SKILL.md` file with YAML frontmatter and Markdown content. The `description` field determines when Claude invokes your Skill.111Create each Skill as a directory containing a `SKILL.md` file with YAML frontmatter and Markdown content. The `description` field determines when Claude invokes your Skill.

112 112 

113**Example directory structure**:113**Example directory structure**:

114 114 

Details

219 219 

220## Creating Custom Slash Commands220## Creating Custom Slash Commands

221 221 

222In addition to using built-in slash commands, you can create your own custom commands that are available through the SDK. Custom commands are defined as markdown files in specific directories, similar to how subagents are configured.222In addition to using built-in slash commands, you can create your own custom commands that are available through the SDK. You define custom commands as markdown files in specific directories, the same way you configure subagents.

223 223 

224<Note>224<Note>

225 The `.claude/commands/` directory is the legacy format. The recommended format is `.claude/skills/<name>/SKILL.md`, which supports the same slash-command invocation (`/name`) plus autonomous invocation by Claude. See [Skills](/docs/en/agent-sdk/skills) for the current format. The CLI continues to support both formats, and the examples below remain accurate for `.claude/commands/`.225 The `.claude/commands/` directory is the legacy format. The recommended format is `.claude/skills/<name>/SKILL.md`, which supports the same slash-command invocation (`/name`) plus autonomous invocation by Claude. See [Skills](/docs/en/agent-sdk/skills) for the current format. The CLI continues to support both formats, and the examples below remain accurate for `.claude/commands/`.


227 227 

228### File Locations228### File Locations

229 229 

230Custom slash commands are stored in designated directories based on their scope:230Save custom slash commands in one of these directories, depending on their scope:

231 231 

232* **Project commands**: `.claude/commands/` - Available only in the current project (legacy; prefer `.claude/skills/`)232* **Project commands**: `.claude/commands/` - Available only in the current project (legacy; prefer `.claude/skills/`)

233* **Personal commands**: `~/.claude/commands/` - Available across all your projects (legacy; prefer `~/.claude/skills/`)233* **Personal commands**: `~/.claude/commands/` - Available across all your projects (legacy; prefer `~/.claude/skills/`)

Details

385 385 

386## Error handling386## Error handling

387 387 

388Structured 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](/en/model-config#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 result message to tell the two causes apart before debugging your schema.388Structured 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#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 result message to tell the two causes apart before debugging your schema.

389 389 

390When an error occurs, the result message has a `subtype` indicating what went wrong:390When an error occurs, the result message has a `subtype` indicating what went wrong:

391 391 


431 }431 }

432 }432 }

433 } catch (error) {433 } catch (error) {

434 // A single-shot query() throws after yielding an error result.434 // A single-shot query() throws after yielding an error result. If the

435 // If the failure was an error result, the subtype branches above435 // failure was an error result, the error subtype branches above have

436 // have already run; connection or process failures yield no result436 // already run; connection or process failures yield no result message.

437 // message. Handle the failure here - retry with a simpler prompt,

438 // fall back to unstructured, etc.

439 console.log(`Session ended with an error: ${error}`);437 console.log(`Session ended with an error: ${error}`);

440 }438 }

441 ```439 ```


471 else:469 else:

472 print("Run ended without a structured output")470 print("Run ended without a structured output")

473 except Exception as error:471 except Exception as error:

474 # A single-shot query() raises after yielding an error result.472 # A single-shot query() raises after yielding an error result. If the

475 # If the failure was an error result, the subtype branches above473 # failure was an error result, the error subtype branches above have

476 # have already run; connection or process failures yield no474 # already run; connection or process failures yield no result message.

477 # result message. Handle the failure here - retry with a simpler

478 # prompt, fall back to unstructured, etc.

479 print(f"Session ended with an error: {error}")475 print(f"Session ended with an error: {error}")

480 476 

481 477 


493 489 

494* [JSON Schema documentation](https://json-schema.org/): learn JSON Schema syntax for defining complex schemas with nested objects, arrays, enums, and validation constraints490* [JSON Schema documentation](https://json-schema.org/): learn JSON Schema syntax for defining complex schemas with nested objects, arrays, enums, and validation constraints

495* [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 use491* [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

496* [Custom tools](/en/agent-sdk/custom-tools): give your agent custom tools to call during execution before returning structured output492* [Custom tools](/docs/en/agent-sdk/custom-tools): give your agent custom tools to call during execution before returning structured output

Details

560 560 

561* **Main conversation compaction**: when the main conversation compacts, subagent transcripts are unaffected. They're stored in separate files.561* **Main conversation compaction**: when the main conversation compacts, subagent transcripts are unaffected. They're stored in separate files.

562* **Session persistence**: subagent transcripts persist within their session. You can resume a subagent after restarting Claude Code by resuming the same session.562* **Session persistence**: subagent transcripts persist within their session. You can resume a subagent after restarting Claude Code by resuming the same session.

563* **Automatic cleanup**: transcripts are cleaned up based on the `cleanupPeriodDays` setting, which defaults to 30 days.563* **Automatic cleanup**: Claude Code deletes subagent transcripts after the `cleanupPeriodDays` retention period, 30 days by default.

564 564 

565## Tool restrictions565## Tool restrictions

566 566 

Details

14 14 

15### Todo Lifecycle15### Todo Lifecycle

16 16 

17Todos follow a predictable lifecycle:17Claude moves each todo through a predictable lifecycle:

18 18 

191. **Created** as `pending` when tasks are identified191. **Created**: Claude adds the todo as `pending` when it identifies a task

202. **Activated** to `in_progress` when work begins202. **Activated**: Claude sets the todo to `in_progress` when it starts the work

213. **Completed** when the task finishes successfully213. **Completed**: Claude marks it completed when the task finishes successfully

224. **Removed** when all tasks in a group are completed224. **Removed**: Claude deletes a todo it no longer needs by setting `status: "deleted"` in a `TaskUpdate` call

23 23 

24### When Todos Are Used24### When Todos Are Used

25 25 

26The SDK creates todos for most multi-step work, such as:26Claude creates todos for most multi-step work, such as:

27 27 

28* **Complex multi-step tasks** requiring 3 or more distinct actions28* **Complex multi-step tasks** requiring 3 or more distinct actions

29* **User-provided task lists** when multiple items are mentioned29* **User-provided task lists** when multiple items are mentioned


34 34 

35## Examples35## Examples

36 36 

37Before running these examples, install the Claude Agent SDK by following the [quickstart](/en/agent-sdk/quickstart).37Before running these examples, install the Claude Agent SDK by following the [quickstart](/docs/en/agent-sdk/quickstart).

38 38 

39Each 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.39Each 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.

40 40 

41These 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.41These 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.

42 42 

43See [Handle the result](/en/agent-sdk/agent-loop#handle-the-result) for the result subtypes.43See [Handle the result](/docs/en/agent-sdk/agent-loop#handle-the-result) for the result subtypes.

44 44 

45### Monitoring Todo Changes45### Monitoring Todo Changes

46 46 


324 324 

325## Related Documentation325## Related Documentation

326 326 

327* [TypeScript SDK Reference](/en/agent-sdk/typescript)327* [TypeScript SDK Reference](/docs/en/agent-sdk/typescript)

328* [Python SDK Reference](/en/agent-sdk/python)328* [Python SDK Reference](/docs/en/agent-sdk/python)

329* [Streaming vs Single Mode](/en/agent-sdk/streaming-vs-single-mode)329* [Streaming vs Single Mode](/docs/en/agent-sdk/streaming-vs-single-mode)

330* [Custom Tools](/en/agent-sdk/custom-tools)330* [Custom Tools](/docs/en/agent-sdk/custom-tools)

Details

2500| `name` | `string` | Name of a built-in workflow or one saved in `.claude/workflows/`. Resolved to a script |2500| `name` | `string` | Name of a built-in workflow or one saved in `.claude/workflows/`. Resolved to a script |

2501| `scriptPath` | `string` | Path to a workflow script file on disk. Takes precedence over `script` and `name`. Every invocation persists its script and returns the path in the result, so you can edit that file and re-invoke with the same `scriptPath` to iterate |2501| `scriptPath` | `string` | Path to a workflow script file on disk. Takes precedence over `script` and `name`. Every invocation persists its script and returns the path in the result, so you can edit that file and re-invoke with the same `scriptPath` to iterate |

2502| `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 |2502| `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 |

2503| `resumeFromRunId` | `string` | Run ID of a prior `Workflow` invocation to resume. Completed `agent()` calls with unchanged inputs return cached results; only changed or new calls run live. Same session only |2503| `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#resume-after-a-pause) covers which completed calls re-run. Same session only |

2504| `title` | `string` | Ignored; the script's `meta` block sets the title |2504| `title` | `string` | Ignored; the script's `meta` block sets the title |

2505| `description` | `string` | Ignored; the script's `meta` block sets the description |2505| `description` | `string` | Ignored; the script's `meta` block sets the description |

2506 2506 


4303};4303};

4304```4304```

4305 4305 

4306Claude Code prepends a notice to every task notification it sends to the model. The notice states that no human input has occurred, so the model doesn't treat the notification as a user instruction or approval. To detect a task-notification turn, check `origin.kind === "task-notification"` on [`SDKUserMessage`](#sdkusermessage) or [`SDKResultMessage`](#sdkresultmessage) rather than matching on the notice text. Before v2.1.205, Claude Code left the notice off notifications that arrived while the session was idle.

4307 

4306### `SDKToolUseSummaryMessage`4308### `SDKToolUseSummaryMessage`

4307 4309 

4308Summary of tool usage in a conversation.4310Summary of tool usage in a conversation.

agent-teams.md +10 −10

Details

67 67 

68This example works well because the three roles are independent and can explore the problem without waiting on each other:68This example works well because the three roles are independent and can explore the problem without waiting on each other:

69 69 

70```text theme={null}70```text wrap theme={null}

71I'm designing a CLI tool that helps developers track TODO comments across71I'm designing a CLI tool that helps developers track TODO comments across

72their codebase. Spawn three teammates to explore this from different angles:72their codebase. Spawn three teammates to explore this from different angles:

73one on UX, one on technical architecture, one playing devil's advocate.73one on UX, one on technical architecture, one playing devil's advocate.


133 133 

134Claude decides the number of teammates to spawn based on your task, or you can specify exactly what you want:134Claude decides the number of teammates to spawn based on your task, or you can specify exactly what you want:

135 135 

136```text theme={null}136```text wrap theme={null}

137Spawn 4 teammates to refactor these modules in parallel. Use Sonnet for137Spawn 4 teammates to refactor these modules in parallel. Use Sonnet for

138each teammate.138each teammate.

139```139```


146 146 

147For complex or risky tasks, you can require teammates to plan before implementing. The teammate works in read-only plan mode until the lead approves their approach:147For complex or risky tasks, you can require teammates to plan before implementing. The teammate works in read-only plan mode until the lead approves their approach:

148 148 

149```text theme={null}149```text wrap theme={null}

150Spawn an architect teammate to refactor the authentication module.150Spawn an architect teammate to refactor the authentication module.

151Require plan approval before they make any changes.151Require plan approval before they make any changes.

152```152```


181 181 

182To gracefully end a teammate's session, refer to it by name. For example, with a teammate named researcher:182To gracefully end a teammate's session, refer to it by name. For example, with a teammate named researcher:

183 183 

184```text theme={null}184```text wrap theme={null}

185Ask the researcher teammate to shut down185Ask the researcher teammate to shut down

186```186```

187 187 


225 225 

226Each 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. Before v2.1.207, a single malformed mailbox entry caused a repeated error every second and blocked delivery for that mailbox until you deleted the file manually.226Each 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. Before v2.1.207, a single malformed mailbox entry caused a repeated error every second and blocked delivery for that mailbox until you deleted the file manually.

227 227 

228The system manages task dependencies automatically. When a teammate completes a task that other tasks depend on, blocked tasks unblock without manual intervention.228Claude 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.

229 229 

230Teams and tasks are stored locally under a session-derived name. The name is `session-` followed by the first eight characters of the session ID:230Teams and tasks are stored locally under a session-derived name. The name is `session-` followed by the first eight characters of the session ID:

231 231 


248 248 

249To use a subagent definition, mention it by name when asking Claude to spawn the teammate:249To use a subagent definition, mention it by name when asking Claude to spawn the teammate:

250 250 

251```text theme={null}251```text wrap theme={null}

252Spawn a teammate using the security-reviewer agent type to audit the auth module.252Spawn a teammate using the security-reviewer agent type to audit the auth module.

253```253```

254 254 


291 291 

292A single reviewer tends to gravitate toward one type of issue at a time. Splitting review criteria into independent domains means security, performance, and test coverage all get thorough attention simultaneously. The prompt assigns each teammate a distinct lens so they don't overlap:292A single reviewer tends to gravitate toward one type of issue at a time. Splitting review criteria into independent domains means security, performance, and test coverage all get thorough attention simultaneously. The prompt assigns each teammate a distinct lens so they don't overlap:

293 293 

294```text theme={null}294```text wrap theme={null}

295Spawn three teammates to review PR #142:295Spawn three teammates to review PR #142:

296- One focused on security implications296- One focused on security implications

297- One checking performance impact297- One checking performance impact


305 305 

306When the root cause is unclear, a single agent tends to find one plausible explanation and stop looking. The prompt fights this by making teammates explicitly adversarial: each one's job is not only to investigate its own theory but to challenge the others'.306When the root cause is unclear, a single agent tends to find one plausible explanation and stop looking. The prompt fights this by making teammates explicitly adversarial: each one's job is not only to investigate its own theory but to challenge the others'.

307 307 

308```text theme={null}308```text wrap theme={null}

309Users report the app exits after one message instead of staying connected.309Users report the app exits after one message instead of staying connected.

310Spawn 5 agent teammates to investigate different hypotheses. Have them talk to310Spawn 5 agent teammates to investigate different hypotheses. Have them talk to

311each other to try to disprove each other's theories, like a scientific311each other to try to disprove each other's theories, like a scientific


322 322 

323Teammates load project context automatically, including CLAUDE.md, MCP servers, and skills, but they don't inherit the lead's conversation history. See [Context and communication](#context-and-communication) for details. Include task-specific details in the spawn prompt:323Teammates load project context automatically, including CLAUDE.md, MCP servers, and skills, but they don't inherit the lead's conversation history. See [Context and communication](#context-and-communication) for details. Include task-specific details in the spawn prompt:

324 324 

325```text theme={null}325```text wrap theme={null}

326Spawn a security reviewer teammate with the prompt: "Review the authentication module326Spawn a security reviewer teammate with the prompt: "Review the authentication module

327at src/auth/ for security vulnerabilities. Focus on token handling, session327at src/auth/ for security vulnerabilities. Focus on token handling, session

328management, and input validation. The app uses JWT tokens stored in328management, and input validation. The app uses JWT tokens stored in


357 357 

358Sometimes the lead starts implementing tasks itself instead of waiting for teammates. If you notice this:358Sometimes the lead starts implementing tasks itself instead of waiting for teammates. If you notice this:

359 359 

360```text theme={null}360```text wrap theme={null}

361Wait for your teammates to complete their tasks before proceeding361Wait for your teammates to complete their tasks before proceeding

362```362```

363 363 

agent-view.md +4 −4

Details

78claude agents --cwd ~/projects/my-app78claude agents --cwd ~/projects/my-app

79```79```

80 80 

81This shows only sessions started under that directory. A session that has [moved into a worktree](#how-file-edits-are-isolated) under `~/projects/my-app/.claude/worktrees/` still counts as belonging to `~/projects/my-app`.81This 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/`.

82 82 

83Interactive sessions you have open in other terminals don't appear until you [background them](#from-inside-a-session). [Subagents](/docs/en/sub-agents) and [teammates](/docs/en/agent-teams) a session spawns aren't listed as separate rows.83Interactive sessions you have open in other terminals don't appear until you [background them](#from-inside-a-session). [Subagents](/docs/en/sub-agents) and [teammates](/docs/en/agent-teams) a session spawns aren't listed as separate rows.

84 84 


528 528 

529The active defaults appear in the footer below the dispatch input.529The active defaults appear in the footer below the dispatch input.

530 530 

531Using `bypassPermissions` with `claude --bg --permission-mode` is refused until you have accepted the bypass disclaimer by running `claude --dangerously-skip-permissions` once interactively, 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.531Claude Code refuses `claude --bg --permission-mode bypassPermissions` until you've accepted the bypass disclaimer by running `claude --dangerously-skip-permissions` once interactively, 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.

532 532 

533### Settings, plugins, and MCP servers533### Settings, plugins, and MCP servers

534 534 


589 589 

590## How background sessions are hosted590## How background sessions are hosted

591 591 

592Every session listed in agent view is considered 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).592Claude 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).

593 593 

594### The supervisor process594### The supervisor process

595 595 


614 614 

615When the supervisor stops an idle session and you later wake it by attaching, peeking, or replying, your environment's gateway is forwarded again under the same conditions as a fresh dispatch. Waking a session from a shell without the gateway restarts it against your settings and stored credentials instead.615When the supervisor stops an idle session and you later wake it by attaching, peeking, or replying, your environment's gateway is forwarded again under the same conditions as a fresh dispatch. Waking a session from a shell without the gateway restarts it against your settings and stored credentials instead.

616 616 

617Each background session is its own Claude Code process, managed by the supervisor rather than tied to your terminal. A session that's actively working, waiting for your input, or has a terminal attached keeps its process running. A running background shell command, subagent, dynamic workflow, or monitor counts as active work, so a long-running process such as a dev server keeps the session alive.617Each background session is its own Claude Code process, managed by the supervisor rather than tied to your terminal. A session that's actively working, waiting for your input, or has a terminal attached keeps its process running. The supervisor counts a running background shell command, subagent, dynamic workflow, or monitor as active work, so a long-running process such as a dev server keeps the session alive.

618 618 

619Once a session finishes and sits unattached for about an hour, the supervisor stops its process to free resources. A session you have [pinned](#organize-the-list) with `Ctrl+T` is exempt and keeps its process running while idle. The transcript and state stay on disk either way, and the next time you attach, peek, or reply to a stopped session, the supervisor starts a fresh process from where it left off. When every session has finished and no terminal is connected, the supervisor itself exits and starts again the next time you need it.619Once a session finishes and sits unattached for about an hour, the supervisor stops its process to free resources. A session you have [pinned](#organize-the-list) with `Ctrl+T` is exempt and keeps its process running while idle. The transcript and state stay on disk either way, and the next time you attach, peek, or reply to a stopped session, the supervisor starts a fresh process from where it left off. When every session has finished and no terminal is connected, the supervisor itself exits and starts again the next time you need it.

620 620 

Details

115 115 

116### 1. Submit use case details116### 1. Submit use case details

117 117 

118First-time users of Anthropic models are required to submit use case details before invoking a model. This is done once per AWS account.118Before you invoke an Anthropic model for the first time, submit use case details. You do this once per AWS account.

119 119 

1201. Ensure you have the right IAM permissions described below1201. Ensure you have the right IAM permissions described below

1212. Navigate to the [Amazon Bedrock console](https://console.aws.amazon.com/bedrock/)1212. Navigate to the [Amazon Bedrock console](https://console.aws.amazon.com/bedrock/)

Details

140 * If you've set the `CLAUDE_CONFIG_DIR` environment variable on Linux or Windows, the `.credentials.json` file lives under that directory instead.140 * If you've set the `CLAUDE_CONFIG_DIR` environment variable on Linux or Windows, the `.credentials.json` file lives under that directory instead.

141 * 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.141 * 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.

142* **Supported authentication types**: Claude.ai credentials, Claude API credentials, Microsoft Foundry Auth, Bedrock Auth, Vertex Auth, and [Claude apps gateway](/docs/en/claude-apps-gateway) session tokens.142* **Supported authentication types**: Claude.ai credentials, Claude API credentials, Microsoft Foundry Auth, Bedrock Auth, Vertex Auth, and [Claude apps gateway](/docs/en/claude-apps-gateway) session tokens.

143* **Custom credential scripts**: the [`apiKeyHelper`](/docs/en/settings#available-settings) setting can be configured to run a shell script that returns an API key.143* **Custom credential scripts**: configure the [`apiKeyHelper`](/docs/en/settings#available-settings) setting to run a shell script that returns an API key.

144* **Refresh intervals**: by default, `apiKeyHelper` is called after 5 minutes or on HTTP 401 response. Set `CLAUDE_CODE_API_KEY_HELPER_TTL_MS` environment variable for custom refresh intervals.144* **Refresh intervals**: by default, `apiKeyHelper` is called after 5 minutes or on HTTP 401 response. Set `CLAUDE_CODE_API_KEY_HELPER_TTL_MS` environment variable for custom refresh intervals.

145* **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.145* **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.

146* **Helper failures**: {/* min-version: 2.1.208 */}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. Before v2.1.208, helper failures surfaced as a generic 401 after about ten silent retries.146* **Helper failures**: {/* min-version: 2.1.208 */}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. Before v2.1.208, helper failures surfaced as a generic 401 after about ten silent retries.

Details

9[Auto mode](/docs/en/permission-modes#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.9[Auto mode](/docs/en/permission-modes#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.

10 10 

11<Note>11<Note>

12 Auto mode is available to all users on every provider, including the Anthropic API, [Claude Platform on AWS](/docs/en/claude-platform-on-aws), 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#eliminate-prompts-with-auto-mode), which also cover the supported models and Owner enablement on Team and Enterprise plans. {/* min-version: 2.1.207 */}In v2.1.158 through v2.1.206, auto mode on Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, and Claude apps gateway sessions required setting `CLAUDE_CODE_ENABLE_AUTO_MODE=1`; v2.1.207 removed the requirement.12 Auto mode is available to all users on every provider, including the Anthropic API, [Claude Platform on AWS](/docs/en/claude-platform-on-aws), 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#eliminate-prompts-with-auto-mode), which also cover the supported models and the organization-level control on Team and Enterprise plans. {/* min-version: 2.1.207 */}In v2.1.158 through v2.1.206, auto mode on Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, and Claude apps gateway sessions required setting `CLAUDE_CODE_ENABLE_AUTO_MODE=1`; v2.1.207 removed the requirement.

13</Note>13</Note>

14 14 

15By 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`.15By 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`.

Details

67 <Step title="Explore">67 <Step title="Explore">

68 Enter plan mode. Claude reads files and answers questions without making changes.68 Enter plan mode. Claude reads files and answers questions without making changes.

69 69 

70 ```txt claude (plan mode) theme={null}70 ```txt title="claude (plan mode)" wrap theme={null}

71 read /src/auth and understand how we handle sessions and login.71 read /src/auth and understand how we handle sessions and login.

72 also look at how we manage environment variables for secrets.72 also look at how we manage environment variables for secrets.

73 ```73 ```


76 <Step title="Plan">76 <Step title="Plan">

77 Ask Claude to create a detailed implementation plan.77 Ask Claude to create a detailed implementation plan.

78 78 

79 ```txt claude (plan mode) theme={null}79 ```txt title="claude (plan mode)" wrap theme={null}

80 I want to add Google OAuth. What files need to change?80 I want to add Google OAuth. What files need to change?

81 What's the session flow? Create a plan.81 What's the session flow? Create a plan.

82 ```82 ```


87 <Step title="Implement">87 <Step title="Implement">

88 Switch out of plan mode and let Claude code, verifying against its plan.88 Switch out of plan mode and let Claude code, verifying against its plan.

89 89 

90 ```txt claude (default mode) theme={null}90 ```txt title="claude (default mode)" wrap theme={null}

91 implement the OAuth flow from your plan. write tests for the91 implement the OAuth flow from your plan. write tests for the

92 callback handler, run the test suite and fix any failures.92 callback handler, run the test suite and fix any failures.

93 ```93 ```


96 <Step title="Commit">96 <Step title="Commit">

97 Ask Claude to commit with a descriptive message and create a PR.97 Ask Claude to commit with a descriptive message and create a PR.

98 98 

99 ```txt claude (default mode) theme={null}99 ```txt title="claude (default mode)" wrap theme={null}

100 commit with a descriptive message and open a PR100 commit with a descriptive message and open a PR

101 ```101 ```

102 </Step>102 </Step>


359 359 

360Claude asks about things you might not have considered yet, including technical implementation, UI/UX, edge cases, and tradeoffs. Replace `[brief description]` with your feature before sending the prompt.360Claude asks about things you might not have considered yet, including technical implementation, UI/UX, edge cases, and tradeoffs. Replace `[brief description]` with your feature before sending the prompt.

361 361 

362```text theme={null}362```text wrap theme={null}

363I want to build [brief description]. Interview me in detail using the AskUserQuestion tool.363I want to build [brief description]. Interview me in detail using the AskUserQuestion tool.

364 364 

365Ask about technical implementation, UI/UX, edge cases, concerns, and tradeoffs. Don't ask obvious questions, dig into the hard parts I might not have considered.365Ask about technical implementation, UI/UX, edge cases, concerns, and tradeoffs. Don't ask obvious questions, dig into the hard parts I might not have considered.


417 417 

418Since context is your fundamental constraint, subagents are one of the most powerful tools available. When Claude researches a codebase it reads lots of files, all of which consume your context. Subagents run in separate context windows and report back summaries:418Since context is your fundamental constraint, subagents are one of the most powerful tools available. When Claude researches a codebase it reads lots of files, all of which consume your context. Subagents run in separate context windows and report back summaries:

419 419 

420```text theme={null}420```text wrap theme={null}

421Use subagents to investigate how our authentication system handles token421Use subagents to investigate how our authentication system handles token

422refresh, and whether we have any existing OAuth utilities I should reuse.422refresh, and whether we have any existing OAuth utilities I should reuse.

423```423```


426 426 

427You can also use subagents for verification after Claude implements something:427You can also use subagents for verification after Claude implements something:

428 428 

429```text theme={null}429```text wrap theme={null}

430use a subagent to review this code for edge cases430use a subagent to review this code for edge cases

431```431```

432 432 


561 561 

562For 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:562For 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:

563 563 

564```text theme={null}564```text wrap theme={null}

565Use a subagent to review the rate limiter diff against PLAN.md. Check that565Use a subagent to review the rate limiter diff against PLAN.md. Check that

566every requirement is implemented, the listed edge cases have tests, and566every requirement is implemented, the listed edge cases have tests, and

567nothing outside the task's scope changed. Report gaps, not style preferences.567nothing outside the task's scope changed. Report gaps, not style preferences.

Details

7> Build an MCP server that pushes webhooks, alerts, and chat messages into a Claude Code session. Reference for the channel contract: capability declaration, notification events, reply tools, sender gating, and permission relay.7> Build an MCP server that pushes webhooks, alerts, and chat messages into a Claude Code session. Reference for the channel contract: capability declaration, notification events, reply tools, sender gating, and permission relay.

8 8 

9<Note>9<Note>

10 Channels are in [research preview](/en/channels#research-preview). Team and Enterprise organizations must [explicitly enable them](/en/channels#enterprise-controls).10 Channels are in [research preview](/docs/en/channels#research-preview). Team and Enterprise organizations must [explicitly enable them](/docs/en/channels#enterprise-controls).

11</Note>11</Note>

12 12 

13A channel is an MCP server that pushes events into a Claude Code session so Claude can react to things happening outside the terminal.13A channel is an MCP server that pushes events into a Claude Code session so Claude can react to things happening outside the terminal.


25* [Gate inbound messages](#gate-inbound-messages): sender checks to prevent prompt injection25* [Gate inbound messages](#gate-inbound-messages): sender checks to prevent prompt injection

26* [Relay permission prompts](#relay-permission-prompts): forward tool approval prompts to remote channels26* [Relay permission prompts](#relay-permission-prompts): forward tool approval prompts to remote channels

27 27 

28To use an existing channel instead of building one, see [Channels](/en/channels). Telegram, Discord, iMessage, and fakechat are included in the research preview.28To use an existing channel instead of building one, see [Channels](/docs/en/channels). Telegram, Discord, iMessage, and fakechat are included in the research preview.

29 29 

30## Overview30## Overview

31 31 


34* **Chat platforms** (Telegram, Discord): your plugin runs locally and polls the platform's API for new messages. When someone DMs your bot, the plugin receives the message and forwards it to Claude. No URL to expose.34* **Chat platforms** (Telegram, Discord): your plugin runs locally and polls the platform's API for new messages. When someone DMs your bot, the plugin receives the message and forwards it to Claude. No URL to expose.

35* **Webhooks** (CI, monitoring): your server listens on a local HTTP port. External systems POST to that port, and your server pushes the payload to Claude.35* **Webhooks** (CI, monitoring): your server listens on a local HTTP port. External systems POST to that port, and your server pushes the payload to Claude.

36 36 

37<img src="https://mintcdn.com/claude-code/9FG0ZKj9uKYiHmbi/images/channel-architecture.svg?fit=max&auto=format&n=9FG0ZKj9uKYiHmbi&q=85&s=9a037b7da80184ae49015c0256b21a1f" alt="Architecture diagram showing external systems connecting to your local channel server, which communicates with Claude Code over stdio" width="600" height="220" data-path="images/channel-architecture.svg" />37<img src="https://mintcdn.com/claude-code/9FG0ZKj9uKYiHmbi/images/channel-architecture.svg?fit=max&auto=format&n=9FG0ZKj9uKYiHmbi&q=85&s=9a037b7da80184ae49015c0256b21a1f" className="dark:hidden" alt="Architecture diagram showing external systems connecting to your local channel server, which communicates with Claude Code over stdio" width="600" height="220" data-path="images/channel-architecture.svg" />

38 

39<img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/channel-architecture-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=ae1e494440806a6a5d74a1279e22e162" className="hidden dark:block" alt="Architecture diagram showing external systems connecting to your local channel server, which communicates with Claude Code over stdio" width="600" height="220" data-path="images/channel-architecture-dark.svg" />

38 40 

39## What you need41## What you need

40 42 


48 50 

49The [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.51The [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.

50 52 

51During the research preview, custom channels aren't on the [approved allowlist](/en/channels#supported-channels). Use `--dangerously-load-development-channels` to test locally. See [Test during the research preview](#test-during-the-research-preview) for details.53During the research preview, custom channels aren't on the [approved allowlist](/docs/en/channels#supported-channels). Use `--dangerously-load-development-channels` to test locally. See [Test during the research preview](#test-during-the-research-preview) for details.

52 54 

53## Example: build a webhook receiver55## Example: build a webhook receiver

54 56 


144 146 

145 A 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`.147 A 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`.

146 148 

147 If you see "blocked by org policy," your organization admin needs to [enable channels](/en/channels#enterprise-controls) first.149 If you see "blocked by org policy," your organization admin needs to [enable channels](/docs/en/channels#enterprise-controls) first.

148 150 

149 In 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):151 In 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):

150 152 


171 173 

172## Test during the research preview174## Test during the research preview

173 175 

174During the research preview, every channel must be on the [approved allowlist](/en/channels#research-preview) to register. The development flag bypasses the allowlist for specific entries after a confirmation prompt. This example shows both entry types:176During the research preview, every channel must be on the [approved allowlist](/docs/en/channels#research-preview) to register. The development flag bypasses the allowlist for specific entries after a confirmation prompt. This example shows both entry types:

175 177 

176```bash theme={null}178```bash theme={null}

177# Testing a plugin you're developing179# Testing a plugin you're developing


247</channel>249</channel>

248```250```

249 251 

250Notifications are not acknowledged. The `await` on `mcp.notification()` resolves when the message is written to the transport, not when Claude has processed it. If the session hasn't loaded your server as a channel, or the organization policy blocks it, events are dropped silently with no error returned to your server.252Claude Code doesn't acknowledge notifications. The `await` on `mcp.notification()` resolves when the message is written to the transport, not when Claude has processed it. If the session hasn't loaded your server as a channel, or the organization policy blocks it, Claude Code drops the events silently and returns no error to your server.

251 253 

252If you need delivery confirmation, track event state in your server and expose a [reply tool](#expose-a-reply-tool) that Claude can call to report status back.254If you need delivery confirmation, track event state in your server and expose a [reply tool](#expose-a-reply-tool) that Claude can call to report status back.

253 255 


452 454 

453The local terminal dialog stays open through all of this. If someone at the terminal answers before the remote verdict arrives, that answer is applied instead and the pending remote request is dropped.455The local terminal dialog stays open through all of this. If someone at the terminal answers before the remote verdict arrives, that answer is applied instead and the pending remote request is dropped.

454 456 

455<img src="https://mintcdn.com/claude-code/9FG0ZKj9uKYiHmbi/images/channel-permission-relay.svg?fit=max&auto=format&n=9FG0ZKj9uKYiHmbi&q=85&s=97d57f128f0da55f105ab1e3a7e10240" alt="Sequence diagram: Claude Code sends a permission_request notification to the channel server, the server formats and sends the prompt to the chat app, the human replies with a verdict, and the server parses that reply into a permission notification back to Claude Code" width="600" height="230" data-path="images/channel-permission-relay.svg" />457<img src="https://mintcdn.com/claude-code/9FG0ZKj9uKYiHmbi/images/channel-permission-relay.svg?fit=max&auto=format&n=9FG0ZKj9uKYiHmbi&q=85&s=97d57f128f0da55f105ab1e3a7e10240" className="dark:hidden" alt="Sequence diagram: Claude Code sends a permission_request notification to the channel server, the server formats and sends the prompt to the chat app, the human replies with a verdict, and the server parses that reply into a permission notification back to Claude Code" width="600" height="230" data-path="images/channel-permission-relay.svg" />

458 

459<img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/channel-permission-relay-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=368c8d9119a9a9cff5d826d806724842" className="hidden dark:block" alt="Sequence diagram: Claude Code sends a permission_request notification to the channel server, the server formats and sends the prompt to the chat app, the human replies with a verdict, and the server parses that reply into a permission notification back to Claude Code" width="600" height="230" data-path="images/channel-permission-relay-dark.svg" />

456 460 

457### Permission request fields461### Permission request fields

458 462 


752 756 

753## Package as a plugin757## Package as a plugin

754 758 

755To make your channel installable and shareable, wrap it in a [plugin](/en/plugins) and publish it to a [marketplace](/en/plugin-marketplaces). Users install it with `/plugin install`, then enable it per session with `--channels plugin:<name>@<marketplace>`.759To make your channel installable and shareable, wrap it in a [plugin](/docs/en/plugins) and publish it to a [marketplace](/docs/en/plugin-marketplaces). Users install it with `/plugin install`, then enable it per session with `--channels plugin:<name>@<marketplace>`.

756 760 

757A channel published to your own marketplace still needs `--dangerously-load-development-channels` to run, since it isn't on the [approved allowlist](/en/channels#supported-channels). The default allowlist is the channel plugins in `claude-plugins-official`, which Anthropic curates at its discretion. The [in-app submission forms](/en/plugins#submit-your-plugin-to-the-community-marketplace) add plugins to the community marketplace, which is not on the channel allowlist.761A 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#supported-channels). The default allowlist is the channel plugins in `claude-plugins-official`, which Anthropic curates at its discretion. The [in-app submission forms](/docs/en/plugins#submit-your-plugin-to-the-community-marketplace) add plugins to the community marketplace, which is not on the channel allowlist.

758 762 

759If 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`](/en/channels#restrict-which-channel-plugins-can-run) list, which replaces the default Anthropic allowlist.763If 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.

760 764 

761## See also765## See also

762 766 

763* [Channels](/en/channels) to install and use Telegram, Discord, iMessage, or the fakechat demo, and to enable channels for a Team or Enterprise org767* [Channels](/docs/en/channels) to install and use Telegram, Discord, iMessage, or the fakechat demo, and to enable channels for a Team or Enterprise org

764* [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 attachments768* [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

765* [MCP](/en/mcp) for the underlying protocol that channel servers implement769* [MCP](/docs/en/mcp) for the underlying protocol that channel servers implement

766* [Plugins](/en/plugins) to package your channel so users can install it with `/plugin install`770* [Plugins](/docs/en/plugins) to package your channel so users can install it with `/plugin install`

Details

18 18 

19* Every user prompt creates a new checkpoint19* Every user prompt creates a new checkpoint

20* 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. {/* min-version: 2.1.208 */}Before v2.1.208, those superseded snapshot files stayed on disk until the session was cleaned up.20* 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. {/* min-version: 2.1.208 */}Before v2.1.208, those superseded snapshot files stayed on disk until the session was cleaned up.

21* Checkpoints are saved with the conversation, so a resumed session can still `/rewind` to them21* Claude Code saves checkpoints with the conversation, so you can still run `/rewind` after you resume a session

22* Automatically cleaned up along with sessions after 30 days, configurable via [`cleanupPeriodDays`](/docs/en/settings#available-settings)22* Claude Code deletes checkpoints along with sessions after 30 days; change the period with [`cleanupPeriodDays`](/docs/en/settings#available-settings)

23 23 

24### Rewind and summarize24### Rewind and summarize

25 25 

chrome.md +11 −11

Details

60 <Step title="Ask Claude to use the browser">60 <Step title="Ask Claude to use the browser">

61 This example navigates to a page, interacts with it, and reports what it finds, all from your terminal or editor:61 This example navigates to a page, interacts with it, and reports what it finds, all from your terminal or editor:

62 62 

63 ```text theme={null}63 ```text wrap theme={null}

64 Go to code.claude.com/docs, click on the search box,64 Go to code.claude.com/docs, click on the search box,

65 type "hooks", and tell me what results appear65 type "hooks", and tell me what results appear

66 ```66 ```

67 67 

68 The first browser action asks for permission to use the `claude-in-chrome` skill. Approve it and Claude opens a new tab and starts the task.68 Before Claude's first browser action, Claude Code asks for permission to use the `claude-in-chrome` skill. Approve it and Claude opens a new tab and starts the task.

69 </Step>69 </Step>

70</Steps>70</Steps>

71 71 


118 118 

119When developing a web app, ask Claude to verify your changes work correctly:119When developing a web app, ask Claude to verify your changes work correctly:

120 120 

121```text theme={null}121```text wrap theme={null}

122I just updated the login form validation. Can you open localhost:3000,122I just updated the login form validation. Can you open localhost:3000,

123try submitting the form with invalid data, and check if the error123try submitting the form with invalid data, and check if the error

124messages appear correctly?124messages appear correctly?


130 130 

131Claude can read console output to help diagnose problems. Tell Claude what patterns to look for rather than asking for all console output, since logs can be verbose:131Claude can read console output to help diagnose problems. Tell Claude what patterns to look for rather than asking for all console output, since logs can be verbose:

132 132 

133```text theme={null}133```text wrap theme={null}

134Open the dashboard page and check the console for any errors when134Open the dashboard page and check the console for any errors when

135the page loads.135the page loads.

136```136```


141 141 

142Speed up repetitive data entry tasks:142Speed up repetitive data entry tasks:

143 143 

144```text theme={null}144```text wrap theme={null}

145I have a spreadsheet of customer contacts in contacts.csv. For each row,145I have a spreadsheet of customer contacts in contacts.csv. For each row,

146go to the CRM at crm.example.com, click "Add Contact", and fill in the146go to the CRM at crm.example.com, click "Add Contact", and fill in the

147name, email, and phone fields.147name, email, and phone fields.


155 155 

156This example attaches a log file to a form:156This example attaches a log file to a form:

157 157 

158```text theme={null}158```text wrap theme={null}

159Open the bug tracker at bugs.example.com, create a new issue,159Open the bug tracker at bugs.example.com, create a new issue,

160and attach logs/session.log to it160and attach logs/session.log to it

161```161```


170 170 

171Use Claude to write directly in your documents without API setup:171Use Claude to write directly in your documents without API setup:

172 172 

173```text theme={null}173```text wrap theme={null}

174Draft a project update based on the recent commits and add it to my174Draft a project update based on the recent commits and add it to my

175Google Doc at docs.google.com/document/d/abc123175Google Doc at docs.google.com/document/d/abc123

176```176```


181 181 

182Pull structured information from websites:182Pull structured information from websites:

183 183 

184```text theme={null}184```text wrap theme={null}

185Go to the product listings page and extract the name, price, and185Go to the product listings page and extract the name, price, and

186availability for each item. Save the results as a CSV file.186availability for each item. Save the results as a CSV file.

187```187```


192 192 

193Coordinate tasks across multiple websites:193Coordinate tasks across multiple websites:

194 194 

195```text theme={null}195```text wrap theme={null}

196Check my calendar for meetings tomorrow, then for each meeting with196Check my calendar for meetings tomorrow, then for each meeting with

197an external attendee, look up their company website and add a note197an external attendee, look up their company website and add a note

198about what they do.198about what they do.


204 204 

205Create shareable recordings of browser interactions:205Create shareable recordings of browser interactions:

206 206 

207```text theme={null}207```text wrap theme={null}

208Record a GIF showing how to complete the checkout flow, from adding208Record a GIF showing how to complete the checkout flow, from adding

209an item to the cart through to the confirmation page.209an item to the cart through to the confirmation page.

210```210```


215 215 

216Ask Claude to keep a screenshot as a file:216Ask Claude to keep a screenshot as a file:

217 217 

218```text theme={null}218```text wrap theme={null}

219Take a screenshot of the checkout page and save it to disk219Take a screenshot of the checkout page and save it to disk

220```220```

221 221 

Details

129 This 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).129 This 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).

130 130 

131 <Note>131 <Note>

132 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, and model access enabled in the Amazon Bedrock console for the Claude models you want. 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.132 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, and Anthropic's one-time use case form submitted for the account from the Bedrock console's Model catalog. 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.

133 </Note>133 </Note>

134 </Step>134 </Step>

135 135 


414* 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) covers every option.414* 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) covers every option.

415* 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) covers per-IdP setup, container image requirements, health probes, and troubleshooting.415* 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) covers per-IdP setup, container image requirements, health probes, and troubleshooting.

416* 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) covers the admin API and how enforcement works.416* 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) covers the admin API and how enforcement works.

417* 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).

417* 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).418* 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).

Details

485| `env` | CLI | Environment variables merged into the CLI process. Use for telemetry, auto-update, and model-name overrides. |485| `env` | CLI | Environment variables merged into the CLI process. Use for telemetry, auto-update, and model-name overrides. |

486| `hooks` | CLI | Org-wide [hooks](/docs/en/hooks) |486| `hooks` | CLI | Org-wide [hooks](/docs/en/hooks) |

487 487 

488Because these settings arrive over the network, the CLI shows each developer a one-time security approval dialog before applying anything that can run a shell command or alter where traffic goes. The dialog covers:488Because these settings arrive over the network, the CLI shows each developer a one-time security approval dialog before applying the settings listed below:

489 489 

490* `hooks`490* `hooks`

491* `env` variables that aren't on the CLI's built-in safe list491* `env` variables that require the developer's approval, such as proxy and base-URL variables

492* shell-execution settings such as `apiKeyHelper` and `statusLine`492* shell-execution settings such as `apiKeyHelper` and `statusLine`

493* managed CLAUDE.md content493* managed CLAUDE.md content

494 494 

495The safe list determines which `env` variables apply without approval:495Claude 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.

496 496 

497* **On the safe list**: auto-update and model-name vars497[Environment variables and the approval dialog](/docs/en/server-managed-settings#environment-variables-and-the-approval-dialog) has the details, including four privacy toggles whose delivered value decides whether they need approval. {/* min-version: 2.1.218 */}Before v2.1.218, Claude Code applied fewer variables without asking the developer, so more delivered variables triggered the dialog.

498* **Not on the safe list**: proxy vars, base-URL vars, and `OTEL_EXPORTER_OTLP_ENDPOINT`

499 498 

500The 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.499The 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.

501 500 

502A non-interactive run with the `-p` flag 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. Before v2.1.207, a non-interactive run saved the settings as approved and no later interactive session showed the dialog for them.501A non-interactive run with the `-p` flag 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. Before v2.1.207, a non-interactive run saved the settings as approved and no later interactive session showed the dialog for them.

503 502 

504If a developer declines, Claude Code exits rather than applying the policy. Pushing a new hook or non-safe env var to a broad policy therefore means an approval prompt on every matching developer's next startup.503If a developer declines, Claude Code exits rather than applying the policy. Pushing a new hook, or any env var that triggers the dialog, to a broad policy therefore means an approval prompt on every matching developer's next startup.

505 504 

506The `cli` key was named `settings` in earlier releases. That spelling is still accepted as an alias, but new deployments should use `cli`.505The `cli` key was named `settings` in earlier releases. That spelling is still accepted as an alias, but new deployments should use `cli`.

507 506 


624 623 

625The pushed endpoint is built from the public URL, so metrics and logs need no OTEL configuration from developers or policies. The pushed configuration is applied at the managed tier, overriding `OTEL_*` variables a developer sets locally.624The pushed endpoint is built from the public URL, so metrics and logs need no OTEL configuration from developers or policies. The pushed configuration is applied at the managed tier, overriding `OTEL_*` variables a developer sets locally.

626 625 

627[Traces](/docs/en/monitoring-usage#traces-beta) additionally require `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1` on each client. The gateway doesn't push that variable, so set it through a managed policy's `env` block. It isn't on the CLI's safe list, so delivering it through a policy is covered by the same [security approval dialog](#managed) that the pushed OTLP endpoint already triggers.626[Traces](/docs/en/monitoring-usage#traces-beta) additionally require `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1` on each client. The gateway doesn't push that variable, so set it through a managed policy's `env` block. It isn't among the variables Claude Code applies without the developer's approval, so delivering it through a policy is covered by the same [security approval dialog](#managed) that the pushed OTLP endpoint already triggers.

628 627 

629Both protobuf and JSON OTLP encodings are relayed, and any OpenTelemetry-compatible backend works as a destination.628Both protobuf and JSON OTLP encodings are relayed, and any OpenTelemetry-compatible backend works as a destination.

630 629 


780 779 

781## Client-side managed settings780## Client-side managed settings

782 781 

783Everything above configures the gateway server. Pointing developer machines at it is configured separately, on each device, through Claude Code's [managed settings](/docs/en/settings#settings-files). The gateway can't push the login keys itself, because they're what tell the client where the gateway is.782Everything above configures the gateway server. You point developer machines at the gateway separately, on each device, through Claude Code's [managed settings](/docs/en/settings#settings-files). The gateway can't push the login keys itself, because they're what tell the client where the gateway is.

784 783 

785For the CLI, set these keys in the per-OS `managed-settings.json`. The two login keys route each developer's `/login` to your gateway:784For the CLI, set these keys in the per-OS `managed-settings.json`. The two login keys route each developer's `/login` to your gateway:

786 785 

Details

62* **Multiple gateways**: each gateway is a separate deployment with its own config. The CLI stores its trust fingerprint and credentials per gateway hostname, so different teams can connect to different gateways without conflict. To serve multiple OIDC issuers, run separate instances.62* **Multiple gateways**: each gateway is a separate deployment with its own config. The CLI stores its trust fingerprint and credentials per gateway hostname, so different teams can connect to different gateways without conflict. To serve multiple OIDC issuers, run separate instances.

63* **Serverless**: Cloud Run works; set `min-instances: 1` to avoid cold OIDC discovery. Lambda and Cloud Functions don't, because the gateway is a long-running HTTP server.63* **Serverless**: Cloud Run works; set `min-instances: 1` to avoid cold OIDC discovery. Lambda and Cloud Functions don't, because the gateway is a long-running HTTP server.

64 64 

65Every production topology here puts an L7 proxy, such as an Ingress, Cloud Run's front end, or an ALB, in front of plain-HTTP replicas. Set [`listen.trusted_proxies`](/docs/en/claude-apps-gateway-config#listen) to the proxy's source ranges so the gateway reads client IPs from `X-Forwarded-For`. The gateway honors the header only when the TCP peer is trusted; the [Google Cloud worked example](/docs/en/claude-apps-gateway-on-gcp) has concrete values per topology. Without trusted proxies, every request appears to come from the proxy's IP, which collapses per-IP rate limits into one shared bucket and records the proxy's IP in audit events.65Every production topology here puts an L7 proxy, such as an Ingress, Cloud Run's front end, or an ALB, in front of plain-HTTP replicas. Set [`listen.trusted_proxies`](/docs/en/claude-apps-gateway-config#listen) to the proxy's source ranges so the gateway reads client IPs from `X-Forwarded-For`. The gateway honors the header only when the TCP peer is trusted; the [Google Cloud](/docs/en/claude-apps-gateway-on-gcp) and [AWS](/docs/en/claude-apps-gateway-on-aws) worked examples have concrete values per topology. Without trusted proxies, every request appears to come from the proxy's IP, which collapses per-IP rate limits into one shared bucket and records the proxy's IP in audit events.

66 66 

67### Container image67### Container image

68 68 


88* Terminate TLS at the Ingress and set `listen.public_url` to the Ingress hostname88* Terminate TLS at the Ingress and set `listen.public_url` to the Ingress hostname

89* Point the readiness probe at `GET /readyz` and the liveness probe at `GET /healthz`89* Point the readiness probe at `GET /readyz` and the liveness probe at `GET /healthz`

90 90 

91For a complete worked example on AWS, covering ECS Fargate or EKS, Amazon RDS, and AWS Secrets Manager, see [Deploy on AWS](/docs/en/claude-apps-gateway-on-aws).

92 

91<Note>93<Note>

92 **Workload identity**94 **Workload identity**

93 95 

claude-apps-gateway-on-aws.md +526 −0 created

Details

1> ## Documentation Index

2> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt

3> Use this file to discover all available pages before exploring further.

4 

5# Deploy Claude apps gateway on AWS

6 

7> A worked example of running Claude apps gateway on AWS: ECS Fargate or EKS, Amazon RDS for PostgreSQL, AWS Secrets Manager, and IAM-role auth to Amazon Bedrock.

8 

9<Note>

10 This page walks through one way to run Claude apps gateway on AWS. The configuration is a working example for customer-managed infrastructure rather than a supported production deployment; use it to see how the pieces fit together before adapting it to your own environment. For the platform-agnostic requirements, see the [deployment guide](/docs/en/claude-apps-gateway-deploy).

11</Note>

12 

13This example provisions Claude apps gateway on AWS with Amazon Bedrock as the model upstream, using either [Amazon ECS](https://aws.amazon.com/ecs/) on [AWS Fargate](https://aws.amazon.com/fargate/) or [Amazon EKS](https://aws.amazon.com/eks/) for compute. [Okta](https://www.okta.com/) is the example identity provider (IdP), but any OpenID Connect (OIDC) compliant IdP works; see [Identity provider setup](/docs/en/claude-apps-gateway-deploy#identity-provider-setup) for per-IdP details.

14 

15<Note>

16 Bedrock isn't the only Claude upstream on AWS. The gateway also supports Claude Platform on AWS, the Anthropic-operated Claude API with AWS authentication and AWS Marketplace billing, in place of Bedrock or alongside it. Its upstream entry, credentials, and IAM permissions differ from this page's Bedrock-scoped ones; the [Claude Platform on AWS upstream reference](/docs/en/claude-apps-gateway-config#claude-platform-on-aws) covers what changes, and the rest of this page applies unchanged.

17</Note>

18 

19## Architecture

20 

21<Frame caption="The example architecture, with Amazon Bedrock as the model upstream. A Claude Platform on AWS upstream occupies the same position.">

22 <img src="https://mintcdn.com/claude-code/PHweeRmDUYEKff49/images/claude-gateway-aws-architecture.svg?fit=max&auto=format&n=PHweeRmDUYEKff49&q=85&s=8599cc34aa28522cde208ee831439bb4" alt="Diagram of Claude apps gateway on AWS: Claude Code clients connect over HTTPS to an internal Application Load Balancer fronting the gateway (ECS Fargate or EKS), which runs in private subnets alongside an Amazon RDS for PostgreSQL instance for session state. The gateway signs users in via OIDC against the corporate IdP, reads secrets from AWS Secrets Manager, forwards model requests to Amazon Bedrock using its IAM role, and pulls its image from Amazon ECR at deploy." width="820" height="430" data-path="images/claude-gateway-aws-architecture.svg" />

23</Frame>

24 

25The gateway runs as a private HTTPS endpoint on your network that developers sign in to through your IdP. Their Claude Code sessions reach Claude models on Amazon Bedrock through the gateway's IAM role, so no model credentials land on developer machines. The reference configuration provisions:

26 

27* **Amazon ECS on AWS Fargate** service or **Amazon EKS** Deployment running the gateway container

28* **Amazon ECR** repository for the gateway image

29* **Amazon RDS for PostgreSQL** instance in private subnets, not publicly accessible, for the gateway's [store](/docs/en/claude-apps-gateway-config#store)

30* **AWS Secrets Manager** secrets for the JWT signing key, the OIDC client secret, and the Postgres URL

31* **IAM role** with `bedrock:InvokeModel` and `bedrock:InvokeModelWithResponseStream`, attached as the ECS task role or bound via IAM Roles for Service Accounts (IRSA) on EKS

32* **Internal Application Load Balancer** for HTTPS

33 

34## Prerequisites

35 

36The walkthrough creates the gateway's own resources, but it builds on network and identity infrastructure you already have. Before you start, you need:

37 

38* An AWS account with permission to create the [resources above](#architecture)

39* The [AWS CLI v2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) installed and [authenticated](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-authentication.html), and [Docker](https://docs.docker.com/get-started/get-docker/) installed locally

40* A [VPC](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html) with at least two [private subnets](https://docs.aws.amazon.com/vpc/latest/userguide/configure-subnets.html) in different Availability Zones, with outbound internet access through a [NAT gateway](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html); the internal load balancer needs subnets in two AZs, and the gateway needs egress to Bedrock and your IdP

41* An Okta OIDC web application with redirect URI `https://<gateway-host>/oauth/callback`; see [Identity provider setup](/docs/en/claude-apps-gateway-deploy#identity-provider-setup)

42* A TLS hostname for the gateway, typically an internal DNS name in a [Route 53 private hosted zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-private.html) pointing at the load balancer, with an [ACM certificate](https://docs.aws.amazon.com/acm/latest/userguide/gs.html) for that name, imported or issued by [AWS Private CA](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html)

43 

44### Set your environment variables

45 

46Every command on this page reads four values from your shell: `AWS_REGION`, `ACCOUNT_ID`, `VPC_ID`, and `PRIVATE_SUBNETS`.

47 

48Pick a US region where Bedrock serves the Claude models you need. The walkthrough relies on the gateway's built-in model catalog, which resolves to `us.anthropic.*` inference profiles, and the IAM policy grants those ARNs. In a non-US region, add a [`models:` block](/docs/en/claude-apps-gateway-config#models) with that geo's inference-profile IDs and change the IAM policy's ARN prefix to match.

49 

50If you don't have the VPC ID at hand, list your VPCs with `aws ec2 describe-vpcs`, then list that VPC's subnets to find two private ones in different Availability Zones:

51 

52```bash theme={null}

53aws ec2 describe-subnets --filters "Name=vpc-id,Values=<your-vpc-id>" \

54 --query 'Subnets[].{ID:SubnetId,AZ:AvailabilityZone,CIDR:CidrBlock}' --output table

55```

56 

57Export all four before continuing:

58 

59```bash theme={null}

60export AWS_REGION=us-east-1 # a US region where Bedrock serves the Claude models you need

61export ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"

62export VPC_ID=<your-vpc-id>

63export PRIVATE_SUBNETS="<subnet-id-a> <subnet-id-b>"

64```

65 

66## Deploy the gateway

67 

68The steps below provision the full deployment with `aws` commands.

69 

70<Steps>

71 <Step title="Create the security groups">

72 Three security groups chain the traffic path: your corporate network reaches the load balancer on 443, the load balancer reaches the gateway on 8080, and the gateway reaches Postgres on 5432. Nothing else is reachable. How you attach them depends on the compute track:

73 

74 * On ECS Fargate, the deploy step attaches `$ALB_SG` to the load balancer and `$GW_SG` to the service.

75 * On EKS, the AWS Load Balancer Controller creates its own frontend security group for the ALB, so `$ALB_SG` and `$GW_SG` go unused: the deploy step's `inbound-cidrs` annotation restricts the listener to your corporate network, and the database security group admits the cluster's security group instead.

76 

77 ```bash theme={null}

78 ALB_SG="$(aws ec2 create-security-group --group-name claude-gateway-alb \

79 --description "Claude gateway ALB" --vpc-id "$VPC_ID" \

80 --query GroupId --output text)"

81 GW_SG="$(aws ec2 create-security-group --group-name claude-gateway-svc \

82 --description "Claude gateway service" --vpc-id "$VPC_ID" \

83 --query GroupId --output text)"

84 DB_SG="$(aws ec2 create-security-group --group-name claude-gateway-db \

85 --description "Claude gateway Postgres" --vpc-id "$VPC_ID" \

86 --query GroupId --output text)"

87 

88 aws ec2 authorize-security-group-ingress --group-id "$ALB_SG" \

89 --protocol tcp --port 443 --cidr <your-corporate-cidr>

90 aws ec2 authorize-security-group-ingress --group-id "$GW_SG" \

91 --protocol tcp --port 8080 --source-group "$ALB_SG"

92 aws ec2 authorize-security-group-ingress --group-id "$DB_SG" \

93 --protocol tcp --port 5432 --source-group "$GW_SG"

94 ```

95 </Step>

96 

97 <Step title="Create the IAM roles and submit the use case form">

98 The gateway runs with a dedicated task role whose only permission is invoking Claude models on Bedrock. Per the [Bedrock upstream reference](/docs/en/claude-apps-gateway-config#amazon-bedrock), the policy must cover both the cross-region inference-profile ARNs and the underlying foundation-model ARNs:

99 

100 ```bash theme={null}

101 cat > bedrock-invoke.json <<EOF

102 {

103 "Version": "2012-10-17",

104 "Statement": [{

105 "Effect": "Allow",

106 "Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"],

107 "Resource": [

108 "arn:aws:bedrock:${AWS_REGION}:${ACCOUNT_ID}:inference-profile/us.anthropic.*",

109 "arn:aws:bedrock:*::foundation-model/anthropic.*"

110 ]

111 }]

112 }

113 EOF

114 cat > ecs-trust.json <<'EOF'

115 {

116 "Version": "2012-10-17",

117 "Statement": [{

118 "Effect": "Allow",

119 "Principal": { "Service": "ecs-tasks.amazonaws.com" },

120 "Action": "sts:AssumeRole"

121 }]

122 }

123 EOF

124 

125 aws iam create-role --role-name claude-gateway-task \

126 --assume-role-policy-document file://ecs-trust.json

127 aws iam put-role-policy --role-name claude-gateway-task \

128 --policy-name bedrock-invoke --policy-document file://bedrock-invoke.json

129 ```

130 

131 ECS also needs an execution role, which the ECS agent itself uses to pull the image from ECR and inject the Secrets Manager values created later. It is separate from the task role the gateway's AWS SDK uses at runtime:

132 

133 ```bash theme={null}

134 aws iam create-role --role-name claude-gateway-execution \

135 --assume-role-policy-document file://ecs-trust.json

136 aws iam attach-role-policy --role-name claude-gateway-execution \

137 --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

138 cat > secrets-read.json <<EOF

139 {

140 "Version": "2012-10-17",

141 "Statement": [{

142 "Effect": "Allow",

143 "Action": ["secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret"],

144 "Resource": [

145 "arn:aws:secretsmanager:${AWS_REGION}:${ACCOUNT_ID}:secret:gateway-jwt-secret-??????",

146 "arn:aws:secretsmanager:${AWS_REGION}:${ACCOUNT_ID}:secret:gateway-oidc-client-secret-??????",

147 "arn:aws:secretsmanager:${AWS_REGION}:${ACCOUNT_ID}:secret:gateway-postgres-url-??????"

148 ]

149 }]

150 }

151 EOF

152 aws iam put-role-policy --role-name claude-gateway-execution \

153 --policy-name read-gateway-secrets --policy-document file://secrets-read.json

154 ```

155 

156 The policy names one ARN per secret rather than a bare `gateway-*` wildcard, which in a shared account would also match unrelated secrets; the trailing `-??????` matches exactly the random six-character suffix Secrets Manager appends to every secret's ARN. A trailing `-*` would be a plain prefix glob and would also match longer names such as `gateway-postgres-url-prod`.

157 

158 The IAM policy grants the gateway permission to call Bedrock, and 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 account has submitted it, open the [Amazon Bedrock console](https://console.aws.amazon.com/bedrock/), select an Anthropic model from the Model catalog, and complete the form. Access is granted immediately after submission; see [Claude Code on Amazon Bedrock](/docs/en/amazon-bedrock#1-submit-use-case-details) for the AWS Organizations form and the IAM permissions the submitter needs.

159 

160 The EKS track reuses both policy documents on an IRSA role instead of the two ECS roles; see the deploy step.

161 </Step>

162 

163 <Step title="Provision Amazon RDS for PostgreSQL">

164 The instance runs in the private subnets with no public address and storage encryption on. The engine version is pinned to Postgres 16, which satisfies the gateway's supported floor of PostgreSQL 14 and guarantees the parameter-group family below matches the instance.

165 

166 First, create the subnet group that places the database in the private subnets, and a parameter group with `rds.force_ssl=1` so the server rejects plaintext connections. The engine version is pinned once because the parameter group's family must match the engine major version the instance runs:

167 

168 ```bash theme={null}

169 aws rds create-db-subnet-group --db-subnet-group-name claude-gateway-db \

170 --db-subnet-group-description "Claude gateway" --subnet-ids $PRIVATE_SUBNETS

171 

172 PG_VERSION=16

173 PG_FAMILY="postgres${PG_VERSION}"

174 aws rds create-db-parameter-group --db-parameter-group-name claude-gateway-db \

175 --db-parameter-group-family "$PG_FAMILY" \

176 --description "Claude gateway - require TLS on every connection"

177 aws rds modify-db-parameter-group --db-parameter-group-name claude-gateway-db \

178 --parameters "ParameterName=rds.force_ssl,ParameterValue=1,ApplyMethod=immediate"

179 ```

180 

181 Then create the instance with a generated master password:

182 

183 ```bash theme={null}

184 PGPASS="$(openssl rand -hex 24)"

185 aws rds create-db-instance --db-instance-identifier claude-gateway-db \

186 --engine postgres --engine-version "$PG_VERSION" \

187 --db-instance-class db.t4g.micro \

188 --allocated-storage 20 --db-name claude_gateway \

189 --master-username gateway --master-user-password "$PGPASS" \

190 --db-subnet-group-name claude-gateway-db \

191 --db-parameter-group-name claude-gateway-db \

192 --vpc-security-group-ids "$DB_SG" \

193 --no-publicly-accessible --storage-encrypted

194 ```

195 

196 The literal `--master-user-password` argument is visible in the process table and in audit/EDR logs while the command runs, the same exposure the secrets step's note covers. On a shared or monitored host, pass the password via `--cli-input-json` from a `0600` file instead, the way the bundle's `setup.sh` does.

197 

198 Wait for the instance to come up, which can take several minutes, then read its private endpoint and assemble the connection string the gateway will use:

199 

200 ```bash theme={null}

201 aws rds wait db-instance-available --db-instance-identifier claude-gateway-db

202 DB_HOST="$(aws rds describe-db-instances --db-instance-identifier claude-gateway-db \

203 --query 'DBInstances[0].Endpoint.Address' --output text)"

204 GATEWAY_POSTGRES_URL="postgres://gateway:${PGPASS}@${DB_HOST}:5432/claude_gateway?sslmode=verify-full"

205 ```

206 

207 `sslmode=verify-full` makes the gateway verify the RDS server certificate's chain and hostname, not only encrypt. The trust anchor is the [AWS RDS certificate bundle](https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem), which the image build step below copies to `/etc/claude/rds-global-bundle.pem` and trusts via `NODE_EXTRA_CA_CERTS`. Don't append a libpq-style `sslrootcert=` parameter to the URL: the gateway's driver reads only `sslmode` from the query string and would forward `sslrootcert` to Postgres as a startup parameter, which the server rejects.

208 

209 The ECS service or EKS pods must run in this VPC so they can reach the instance's private endpoint, and the `claude-gateway-db` security group only admits the gateway's security group.

210 </Step>

211 

212 <Step title="Write gateway.yaml">

213 The `upstreams` block points at Bedrock with `auth: {}`, so the gateway authenticates via the AWS default credential chain from the task role on ECS or the IRSA role on EKS. See the [configuration reference](/docs/en/claude-apps-gateway-config) for every field.

214 

215 Two `listen` fields depend on what fronts the gateway:

216 

217 * `public_url`: required behind a load balancer. The gateway builds the IdP `redirect_uri` and its discovery document only from this value, never from `X-Forwarded-*` headers.

218 * `trusted_proxies`: the front end's source ranges. The gateway honors `X-Forwarded-For` only when the TCP peer is in this list, then walks the chain past trusted hops, so per-IP sign-in rate limits and audit events record developer IPs instead of the load balancer's.

219 

220 On both tracks the front end is an internal ALB, whether created directly or by the AWS Load Balancer Controller, and an ALB's nodes take addresses from the subnets it is attached to, so set `trusted_proxies` to those subnets' CIDRs. This trusts every host in those subnets as a proxy. Keep the ALB's ingress source, your corporate CIDR, from overlapping them, and don't share the subnets with untrusted workloads that could spoof client IPs via `X-Forwarded-For`.

221 

222 ```yaml gateway.yaml theme={null}

223 listen:

224 host: 0.0.0.0

225 port: 8080

226 public_url: https://claude-gateway.internal.example.com

227 trusted_proxies: [<your-alb-subnet-cidrs>]

228 

229 oidc:

230 issuer: https://example.okta.com

231 client_id: 0oa1example2

232 client_secret: ${OIDC_CLIENT_SECRET} # EKS: ${file:/secrets/oidc-client-secret}

233 allowed_email_domains: [example.com]

234 # The Okta org authorization server returns a thin id_token that omits

235 # email and groups; the gateway fills them from /userinfo.

236 userinfo_fallback: true

237 # Okta emits groups only when the `groups` scope is requested and the

238 # app's groups claim filter allows them.

239 scopes: [openid, profile, email, offline_access, groups]

240 

241 session:

242 jwt_secret: ${GATEWAY_JWT_SECRET} # EKS: ${file:/secrets/jwt-secret}

243 ttl_hours: 8 # bounds deprovision latency; lower

244 # toward 1 for tighter revocation

245 

246 store:

247 postgres_url: ${GATEWAY_POSTGRES_URL} # EKS: ${file:/secrets/postgres-url}

248 

249 upstreams:

250 - provider: bedrock

251 region: <your-region> # match $AWS_REGION so the IAM

252 # policy's ARNs cover it

253 auth: {} # AWS default credential chain:

254 # ECS task role, or IRSA on EKS

255 ```

256 

257 <Note>

258 Only the `oidc` block is Okta-specific. To use Microsoft Entra ID instead, set `issuer` to `https://login.microsoftonline.com/<tenant-id>/v2.0`, drop `userinfo_fallback` and the `groups` scope, and note that Entra emits group Object IDs rather than names, so [`managed.policies`](/docs/en/claude-apps-gateway-config#managed) must match on the GUIDs, or on App Roles with `oidc.groups_claim: roles`. See [Identity provider setup](/docs/en/claude-apps-gateway-deploy#identity-provider-setup).

259 </Note>

260 </Step>

261 

262 <Step title="Store secrets in AWS Secrets Manager">

263 Create three secrets; the execution role from the IAM step can already read them:

264 

265 ```bash theme={null}

266 aws secretsmanager create-secret --name gateway-jwt-secret \

267 --secret-string "$(openssl rand -base64 32)"

268 aws secretsmanager create-secret --name gateway-oidc-client-secret \

269 --secret-string '<your-okta-client-secret>'

270 aws secretsmanager create-secret --name gateway-postgres-url \

271 --secret-string "$GATEWAY_POSTGRES_URL"

272 ```

273 

274 Note the ARN each call prints; the ECS task definition references secrets by ARN.

275 

276 <Note>

277 Literal `--secret-string` arguments are visible in the process table and in audit/EDR logs while each command runs. On a shared or monitored host, put the value in a `0600` file and pass `--secret-string file://<path>` instead. The bundle's `setup.sh` keeps secret values off process argv the same way, passing `0600` temporary files to `--cli-input-json`.

278 </Note>

279 

280 Unlike the secrets, `gateway.yaml` itself contains no secret values, because every credential resolves at boot through [`${VAR}` or `${file:...}` expansion](/docs/en/claude-apps-gateway-config#secret-expansion). How everything reaches the container differs by track:

281 

282 * On ECS, the next step's build copies `gateway.yaml` into the image at `/etc/claude/gateway.yaml`, and the task definition injects the three secrets as environment variables via its `secrets` field, so the YAML references `${GATEWAY_JWT_SECRET}`, `${OIDC_CLIENT_SECRET}`, and `${GATEWAY_POSTGRES_URL}`.

283 * On EKS, mount `gateway.yaml` from a ConfigMap and the secrets as files at `/secrets`, referenced as `${file:/secrets/...}`. Source the Kubernetes Secrets from Secrets Manager with External Secrets Operator or the Secrets Store CSI driver's AWS provider, or create them directly with `kubectl`.

284 </Step>

285 

286 <Step title="Build and push the image to Amazon ECR">

287 Build the image per the [container image requirements](/docs/en/claude-apps-gateway-deploy#container-image), placing the `linux-x64` glibc binary at `./claude` in the build context. Write your own Dockerfile per those requirements or start from the bundle's [`Dockerfile`](https://github.com/anthropics/claude-code/blob/main/examples/gateway/aws/Dockerfile), which copies the filled-in `gateway.yaml` from the previous steps into the image at `/etc/claude/gateway.yaml`. On ECS that embedded copy is how the configuration reaches the container, which is why the build comes after the file is written. The EKS track instead mounts `gateway.yaml` from a ConfigMap at deploy, so the embedded copy is unused there.

288 

289 The image also carries the AWS RDS certificate bundle as the trust anchor for the connection string's `sslmode=verify-full`, so download it into the build context first. AWS rotates the bundle (new regional CAs get appended), so download it per build rather than pinning a checksum or committing it:

290 

291 ```bash theme={null}

292 curl -fL --proto '=https' -o rds-global-bundle.pem \

293 https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem

294 ```

295 

296 The container image requirements don't cover the bundle, so if you write your own Dockerfile, add the two lines that copy and trust it; the bundle's `Dockerfile` already includes both:

297 

298 ```dockerfile theme={null}

299 COPY rds-global-bundle.pem /etc/claude/rds-global-bundle.pem

300 ENV NODE_EXTRA_CA_CERTS=/etc/claude/rds-global-bundle.pem

301 ```

302 

303 Create the ECR repository and sign Docker in to it. Immutable tags mean the `<version>` tag the deploy step pins cannot later be silently re-pointed at a different image:

304 

305 ```bash theme={null}

306 aws ecr create-repository --repository-name claude-gateway \

307 --image-tag-mutability IMMUTABLE \

308 --image-scanning-configuration scanOnPush=true

309 aws ecr get-login-password --region "$AWS_REGION" \

310 | docker login --username AWS --password-stdin \

311 "${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"

312 ```

313 

314 Build and push the image. The task definition below runs `linux/amd64`, so the platform must match here; for Fargate on ARM64 (Graviton), build `linux/arm64` with the `linux-arm64` binary and set `cpuArchitecture` to `ARM64` instead:

315 

316 ```bash theme={null}

317 docker build --platform=linux/amd64 \

318 -t "${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/claude-gateway:<version>" .

319 docker push "${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/claude-gateway:<version>"

320 ```

321 </Step>

322 

323 <Step title="Deploy">

324 <Tabs>

325 <Tab title="ECS Fargate">

326 Create the cluster and a log group for the gateway's stderr, which carries both its audit events and operational logs. Retention is a separate call, and without one CloudWatch keeps the logs forever; align the 90 days with your audit retention policy:

327 

328 ```bash theme={null}

329 aws ecs create-cluster --cluster-name claude-gateway

330 aws logs create-log-group --log-group-name /ecs/claude-gateway

331 aws logs put-retention-policy --log-group-name /ecs/claude-gateway \

332 --retention-in-days 90

333 ```

334 

335 Write the task definition. The task role carries the Bedrock permission and the execution role injects the secrets; use the secret ARNs from the Secrets Manager step:

336 

337 ```json claude-gateway-task.json theme={null}

338 {

339 "family": "claude-gateway",

340 "networkMode": "awsvpc",

341 "requiresCompatibilities": ["FARGATE"],

342 "cpu": "1024",

343 "memory": "2048",

344 "runtimePlatform": { "cpuArchitecture": "X86_64", "operatingSystemFamily": "LINUX" },

345 "executionRoleArn": "arn:aws:iam::<account-id>:role/claude-gateway-execution",

346 "taskRoleArn": "arn:aws:iam::<account-id>:role/claude-gateway-task",

347 "containerDefinitions": [

348 {

349 "name": "gateway",

350 "image": "<account-id>.dkr.ecr.<region>.amazonaws.com/claude-gateway:<version>",

351 "portMappings": [{ "containerPort": 8080 }],

352 "secrets": [

353 { "name": "GATEWAY_JWT_SECRET", "valueFrom": "<gateway-jwt-secret ARN>" },

354 { "name": "OIDC_CLIENT_SECRET", "valueFrom": "<gateway-oidc-client-secret ARN>" },

355 { "name": "GATEWAY_POSTGRES_URL", "valueFrom": "<gateway-postgres-url ARN>" }

356 ],

357 "logConfiguration": {

358 "logDriver": "awslogs",

359 "options": {

360 "awslogs-group": "/ecs/claude-gateway",

361 "awslogs-region": "<region>",

362 "awslogs-stream-prefix": "gateway"

363 }

364 }

365 }

366 ]

367 }

368 ```

369 

370 Register it:

371 

372 ```bash theme={null}

373 aws ecs register-task-definition --cli-input-json file://claude-gateway-task.json

374 ```

375 

376 Put an internal ALB in front with a target group that health-checks the gateway. `--ip-address-type ipv4` matters: an internal dual-stack ALB publishes public-range AAAA records, which the `/login` private-network check rejects:

377 

378 ```bash theme={null}

379 ALB_ARN="$(aws elbv2 create-load-balancer --name claude-gateway \

380 --scheme internal --type application --ip-address-type ipv4 \

381 --subnets $PRIVATE_SUBNETS --security-groups "$ALB_SG" \

382 --query 'LoadBalancers[0].LoadBalancerArn' --output text)"

383 

384 TG_ARN="$(aws elbv2 create-target-group --name claude-gateway \

385 --protocol HTTP --port 8080 --vpc-id "$VPC_ID" --target-type ip \

386 --health-check-path /readyz \

387 --query 'TargetGroups[0].TargetGroupArn' --output text)"

388 ```

389 

390 Add the HTTPS listener and raise the idle timeout. `--ssl-policy` pins a modern TLS floor, since omitting it falls back to the legacy `ELBSecurityPolicy-2016-08` default, which still accepts TLS 1.0/1.1. The idle timeout matters for streaming: the ALB closes a connection after 60 seconds with no data by default, which cuts off streams during quiet periods, such as long prompt processing before the first token:

391 

392 ```bash theme={null}

393 aws elbv2 create-listener --load-balancer-arn "$ALB_ARN" \

394 --protocol HTTPS --port 443 \

395 --ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06 \

396 --certificates CertificateArn=<your-acm-certificate-arn> \

397 --default-actions Type=forward,TargetGroupArn="$TG_ARN"

398 

399 aws elbv2 modify-load-balancer-attributes --load-balancer-arn "$ALB_ARN" \

400 --attributes Key=idle_timeout.timeout_seconds,Value=3600

401 ```

402 

403 Create the service. The deployment circuit breaker rolls a deployment whose tasks keep failing, from a bad image or an unbootable config, back to the last steady state instead of relaunching failing tasks forever:

404 

405 ```bash theme={null}

406 aws ecs create-service --cluster claude-gateway --service-name claude-gateway \

407 --task-definition claude-gateway --desired-count 1 --launch-type FARGATE \

408 --deployment-configuration "deploymentCircuitBreaker={enable=true,rollback=true}" \

409 --health-check-grace-period-seconds 60 \

410 --network-configuration "awsvpcConfiguration={subnets=[$(echo $PRIVATE_SUBNETS | tr ' ' ',')],securityGroups=[$GW_SG],assignPublicIp=DISABLED}" \

411 --load-balancers "targetGroupArn=$TG_ARN,containerName=gateway,containerPort=8080"

412 ```

413 

414 The 60-second grace period gives a cold task time to pull the image, connect to the store, and answer its first health check before ECS starts counting failures against the deployment. The target group's health check on `GET /readyz` verifies the store is reachable, so a task that can't reach Postgres never enters rotation; see [Outage behavior](/docs/en/claude-apps-gateway-deploy#outage-behavior) for the tradeoff and the `/healthz` alternative.

415 

416 The tasks run in private subnets with no public IP, so all egress (to Bedrock, your IdP, Secrets Manager, ECR, and CloudWatch Logs) goes through the NAT gateway. To keep Bedrock traffic off the public path, create a `bedrock-runtime` interface VPC endpoint and point the upstream's `base_url` at it, as shown in the [Bedrock upstream reference](/docs/en/claude-apps-gateway-config#amazon-bedrock); the IdP still needs internet egress.

417 

418 Finish by giving developers a privately resolvable hostname: in a Route 53 private hosted zone, alias the gateway's internal DNS name to the ALB, and set `listen.public_url` to that hostname. The ALB's own `*.elb.amazonaws.com` name resolves to private addresses on an internal ALB, but it can't carry your ACM certificate, so use your own name.

419 

420 Update the OAuth client's authorized redirect URI to `<public_url>/oauth/callback` before the first sign-in. After changing `public_url`, rebuild and push the image under a new tag, register a new task definition revision, and redeploy. On ECS the setting lives in the image's embedded `gateway.yaml`, and the gateway builds its public origin only from that setting, ignoring `X-Forwarded-Host` and `X-Forwarded-Proto`. `X-Forwarded-For` is honored for client IPs only when `listen.trusted_proxies` is set.

421 </Tab>

422 

423 <Tab title="EKS">

424 This track needs `kubectl` and `eksctl` installed locally, and an existing EKS cluster with an IAM OIDC provider and the AWS Load Balancer Controller installed. The cluster must be on `$VPC_ID` so pods can reach the RDS private endpoint, and the `claude-gateway-db` security group must admit the cluster's pod or node security group in place of `$GW_SG`.

425 

426 On EKS the gateway gets its Bedrock credentials through IRSA rather than the ECS roles. The `ecs-tasks.amazonaws.com` trust policy from the IAM step does not apply here; IRSA needs a role whose trust policy federates on the cluster's OIDC provider, scoped to `system:serviceaccount:claude-gateway:gateway`. `eksctl create iamserviceaccount` creates that role, attaches the policies, and annotates the Kubernetes service account with the role ARN in one step. Turn the two policy documents from the IAM step into managed policies it can attach:

427 

428 ```bash theme={null}

429 BEDROCK_POLICY_ARN="$(aws iam create-policy --policy-name claude-gateway-bedrock-invoke \

430 --policy-document file://bedrock-invoke.json --query Policy.Arn --output text)"

431 SECRETS_POLICY_ARN="$(aws iam create-policy --policy-name claude-gateway-secrets-read \

432 --policy-document file://secrets-read.json --query Policy.Arn --output text)"

433 

434 kubectl create namespace claude-gateway

435 eksctl create iamserviceaccount --cluster <your-cluster> --region "$AWS_REGION" \

436 --namespace claude-gateway --name gateway --role-name claude-gateway \

437 --attach-policy-arn "$BEDROCK_POLICY_ARN" \

438 --attach-policy-arn "$SECRETS_POLICY_ARN" \

439 --approve

440 ```

441 

442 The secrets policy is needed only when the pods read Secrets Manager themselves, as the Secrets Store CSI driver's AWS provider does using the mounting pod's service account; drop it if you create the Kubernetes Secrets another way. The provider needs both of the policy's actions: it calls `DescribeSecret` when it reconciles rotated secrets, so a `GetSecretValue`-only grant mounts on the first deploy but stops picking up rotations.

443 

444 Deploy the gateway as a standard Deployment plus a Service and an Ingress, as described in [Kubernetes deployment](/docs/en/claude-apps-gateway-deploy#kubernetes), with:

445 

446 * `serviceAccountName: gateway`

447 * `gateway.yaml` mounted from a ConfigMap and the secrets mounted at `/secrets`

448 * the readiness probe pointed at `GET /readyz`

449 

450 For the front end, an Ingress managed by the AWS Load Balancer Controller provisions the internal ALB. Annotate it with:

451 

452 * `alb.ingress.kubernetes.io/scheme: internal` and `alb.ingress.kubernetes.io/target-type: ip`

453 * `alb.ingress.kubernetes.io/ip-address-type: ipv4`, so no public-range AAAA records are published for the `/login` [private-network check](/docs/en/claude-apps-gateway#prerequisites) to reject

454 * `alb.ingress.kubernetes.io/inbound-cidrs: <your-corporate-cidr>`, so the controller-managed frontend security group admits only your corporate network in place of its `0.0.0.0/0` default

455 * `alb.ingress.kubernetes.io/certificate-arn` with the ACM certificate

456 * `alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS13-1-2-2021-06`, so the listener doesn't fall back to the legacy default policy that accepts TLS 1.0 and 1.1

457 * `alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=3600`, so a 60-second data gap in a stream doesn't close the connection

458 

459 With IRSA, the AWS SDK reads a projected service-account token and exchanges it with AWS STS, so the pod never needs the EC2 instance metadata service; an egress NetworkPolicy may block `169.254.169.254` for gateway pods. The node hop-limit problem in [Troubleshooting](#troubleshooting) below applies only to clusters that skip IRSA and rely on node instance roles.

460 </Tab>

461 </Tabs>

462 </Step>

463 

464 <Step title="Push the gateway URL to developer machines">

465 The gateway is now running, but developers can't reach it from `/login` until the gateway URL is on their machines. Set `forceLoginMethod` and `forceLoginGatewayUrl` in the [managed settings file](/docs/en/claude-apps-gateway#set-the-gateway-url) you deploy to each device via MDM. There is no gateway option in the login picker for a developer to select manually.

466 </Step>

467</Steps>

468 

469## Terraform reference

470 

471The companion bundle at [`examples/gateway/aws`](https://github.com/anthropics/claude-code/tree/main/examples/gateway/aws) packages this page as code:

472 

473* **`setup.sh`** scripts the provisioning walkthrough above with the same `aws` commands, on the ECS Fargate track. It is idempotent: existing resources are detected and skipped, so re-running it is safe, and any default can be overridden via environment variable. You still create the Okta OIDC client secret and the ACM certificate yourself: a run without them skips the ECS/ALB deploy, names the missing inputs, and prints the `create-secret` command; create both and re-run. The Bedrock use case form and the Route 53 alias print as next steps rather than running automatically, and the client MDM push stays a manual step from this page.

474* **`gateway.yaml.example`** is the configuration template from the gateway.yaml step, with the optional keys included commented out. Copy it to `gateway.yaml` and replace every `REPLACE_ME` before building.

475* **`Dockerfile`** builds the runtime image from the prebuilt `linux-x64` binary and copies in your filled-in `gateway.yaml` at `/etc/claude/gateway.yaml`, plus the AWS RDS certificate bundle that anchors the store's `sslmode=verify-full`. `setup.sh` downloads the bundle only when it isn't already in the build context; delete the file and rebuild under a new tag to pick up an AWS CA rotation. The config file holds no secret values, since every credential resolves at boot through `${VAR}` expansion. A config edit therefore means a rebuild under a new tag; `setup.sh` automates this by tagging images with a hash of the file.

476* **`terraform/`** provisions the same ECS Fargate scope declaratively: the security groups, IAM roles, ECR repository, RDS instance, Secrets Manager secrets, and the ECS service behind the internal ALB. The VPC and private subnets stay prerequisites, passed in as variables. Terraform creates the ECR repository but doesn't build the image, and the service definition references the image, so the apply is two passes: a targeted apply for the repository, then the build and push, then the full apply. The bundle's `terraform/README.md` covers the variables, remote state, and teardown.

477 

478Like this page, the bundle is a working example for customer-managed infrastructure rather than a supported production deployment; review and adapt it to your own environment before relying on it.

479 

480## Troubleshooting

481 

482For gateway boot and login errors, see the platform-agnostic [troubleshooting table](/docs/en/claude-apps-gateway-deploy#troubleshooting). The entries below are specific to AWS.

483 

484| Symptom | Cause | Fix |

485| ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

486| CLI `/login`: `Gateway hosts must be on your organization's private network; <host> resolves to the public (or unrecognized) address <ip>` | The gateway name resolves to at least one public address. A dual-stack internal ALB publishes public-range AAAA records, and the [private-network check](/docs/en/claude-apps-gateway#prerequisites) requires every resolved address to be private | Create the ALB with `--ip-address-type ipv4`, or serve a separate internal-only DNS name with no public AAAA record |

487| Every Bedrock request returns 502; log shows `Could not load credentials from any providers` | The task runs on the ECS EC2 launch type without a task role, or the pod runs on an EKS node without IRSA, so credentials come from instance metadata, which IMDSv2's default hop limit of 1 stops inside a container. Neither track on this page is affected: Fargate task roles and IRSA don't use instance metadata | Prefer task roles and IRSA. Where instance credentials are unavoidable, raise the hop limit with `aws ec2 modify-instance-metadata-options --instance-id <id> --http-put-response-hop-limit 2`; the [platform-agnostic table](/docs/en/claude-apps-gateway-deploy#troubleshooting) covers the tradeoffs |

488| Bedrock requests return `403 AccessDeniedException` | The account hasn't submitted Anthropic's one-time use case form, the automatic AWS Marketplace subscription that starts on the account's first invoke hasn't finished yet, or the task role's policy is missing the inference-profile or foundation-model ARNs | Submit the use case form from the Bedrock console's Model catalog; if it was just submitted or this is the account's first invoke, retry after a few minutes. Grant `bedrock:InvokeModel` and `bedrock:InvokeModelWithResponseStream` on both ARN families. |

489| Bedrock returns a `ValidationException` saying on-demand throughput isn't supported | A custom `models:` entry maps to a bare foundation-model ID that the region serves only through inference profiles | Map the model to its cross-region inference profile ID (`us.anthropic.*`) instead; the built-in catalog already does this |

490| ECS task stops with `ResourceInitializationError` before the gateway logs anything | The execution role can't read the Secrets Manager secrets, or the private subnets have no path to Secrets Manager or ECR | Grant `secretsmanager:GetSecretValue` on the three `gateway-` secrets' ARNs to the execution role, and provide egress via the NAT gateway, or, without one, interface endpoints for Secrets Manager, ECR, and CloudWatch Logs, which the `awslogs` driver needs at the same stage, plus an S3 gateway endpoint |

491| Gateway boot exits with a Postgres connection-timeout error | The database security group doesn't admit the gateway's security group on 5432, or the service runs outside the database's VPC; the store stops waiting after 5 seconds | Allow 5432 from the gateway's security group on the database's, and run the service in the same VPC as the DB subnet group |

492| Gateway boot exits with a Postgres TLS certificate verification error | The connection string sets `sslmode=verify-full` but the image doesn't trust the RDS CA bundle: the bundle wasn't copied into the image, or `NODE_EXTRA_CA_CERTS` doesn't point at it | Add the build step's two Dockerfile lines that copy the bundle and set `NODE_EXTRA_CA_CERTS`, then rebuild, push under a new tag, and redeploy |

493| Streaming responses drop mid-stream after a quiet period | The ALB idle timeout closes the connection after 60 seconds with no data by default. A stream that is actively emitting tokens isn't affected; one that goes quiet, during long prompt processing before the first token or extended thinking with no streamed output, is cut at the gap | Set the `idle_timeout.timeout_seconds` attribute to `3600`, via `modify-load-balancer-attributes` or the `load-balancer-attributes` Ingress annotation on EKS |

494 

495## Telemetry

496 

497The gateway gives you per-developer usage metrics without any per-machine OTEL configuration. Claude Code emits OpenTelemetry (OTLP) metrics, logs, and opt-in traces; [Monitoring usage](/docs/en/monitoring-usage) covers everything the CLI reports. On gateway sessions the CLI stamps each export with the authenticated IdP identity attributes `user.id`, `user.email`, and `user.groups`, so usage rolls up per developer with no `OTEL_RESOURCE_ATTRIBUTES` plumbing.

498 

499The gateway itself is an authenticated OTLP relay. Set [`telemetry.forward_to`](/docs/en/claude-apps-gateway-config#telemetry) together with `listen.public_url`, and it pushes the OTEL exporter settings to every connected client and forwards their OTLP traffic verbatim to each destination you list. Each destination opts into metrics, logs, and traces independently, and the default is metrics only; see the [`telemetry` reference](/docs/en/claude-apps-gateway-config#telemetry) for the per-signal fields and their sensitivity tradeoffs. The gateway doesn't buffer, aggregate, or store telemetry, so where the data lands is entirely the collector's exporter configuration.

500 

501Client telemetry is off by default; configuring `telemetry.forward_to` is what turns it on for connected developers, and each interactive client shows a one-time security approval dialog for the pushed settings, as described in the [configuration reference](/docs/en/claude-apps-gateway-config#telemetry). On AWS, each signal maps to a destination as follows.

502 

503### Client metrics, logs, and traces

504 

505Point `telemetry.forward_to` at an OpenTelemetry collector, such as the [AWS Distro for OpenTelemetry (ADOT) collector](https://aws-otel.github.io/), and export from there to Amazon CloudWatch, Amazon Managed Service for Prometheus, or any OTLP backend.

506 

507Run the collector as its own internal service reachable over `https://`: the gateway accepts plaintext `http://` only for loopback URLs, and even then its [SSRF guard](/docs/en/claude-apps-gateway-deploy#threat-model-summary) blocks loopback connections at send time by default. A sidecar collector on `http://localhost:4318` passes config validation but receives no traffic, with exports failing as `ECONNREFUSED_SSRF` in the gateway logs, unless `CLAUDE_GATEWAY_ALLOW_LOOPBACK=1` is set in the gateway's environment. That variable relaxes the loopback block for every operator-configured URL, not only telemetry, so prefer the internal-service pattern and reserve the sidecar-plus-flag setup for tasks whose network is otherwise locked down.

508 

509### Gateway logs

510 

511On ECS Fargate, no extra setup: the `awslogs` driver delivers the gateway's stderr, which carries its audit events and operational logs, to the `/ecs/claude-gateway` log group created above. On EKS, pod logs don't reach CloudWatch by default, so the audit trail is lost until you install log collection: the Amazon CloudWatch Observability add-on with container log capture enabled, or a Fluent Bit DaemonSet. On either track, query the logs with CloudWatch Logs Insights and drive alarms from metric filters.

512 

513### Container metrics

514 

515Enable Container Insights on the cluster with `aws ecs update-cluster-settings --cluster claude-gateway --settings name=containerInsights,value=enabled` for per-task CPU, memory, and network. On EKS, install the Amazon CloudWatch Observability add-on.

516 

517### Spend

518 

519Telemetry shows usage after the fact; [spend limits](/docs/en/claude-apps-gateway-spend-limits) are the gateway's live per-developer view and enforcement on top of the shared upstream credential.

520 

521## Next steps

522 

523* [Configuration reference](/docs/en/claude-apps-gateway-config): every `gateway.yaml` option, including `managed.policies` and `telemetry`

524* [Deployment and operations](/docs/en/claude-apps-gateway-deploy): IdP setup, health checks, JWT secret rotation, upgrades, and the security model

525* [Claude apps gateway overview](/docs/en/claude-apps-gateway): quickstart and connecting developers

526* [AWS samples for Claude apps gateway](https://github.com/aws-samples/anthropic-on-aws/tree/main/claude-apps-gateway): AWS-maintained deployment samples covering a range of customer environments

Details

6 6 

7> Cap each developer's spend through the Claude apps gateway by day, week, or month. Set limits with an Admin API and the gateway enforces them live on every request.7> Cap each developer's spend through the Claude apps gateway by day, week, or month. Set limits with an Admin API and the gateway enforces them live on every request.

8 8 

9Spend limits cap how much each developer can spend through your [Claude apps gateway](/en/claude-apps-gateway) in a given day, week, or month. When a developer passes their cap, the gateway returns `429` on their next request and blocks them until the period resets or an admin raises the cap. Use spend limits to give each developer, group, or the whole organization a ceiling on a credential everyone shares.9Spend limits cap how much each developer can spend through your [Claude apps gateway](/docs/en/claude-apps-gateway) in a given day, week, or month. When a developer passes their cap, the gateway returns `429` on their next request and blocks them until the period resets or an admin raises the cap. Use spend limits to give each developer, group, or the whole organization a ceiling on a credential everyone shares.

10 10 

11A Claude apps gateway forwards all inference through one shared upstream credential, so your provider's bill attributes everything to that credential, not to individual developers. Without per-developer limits, one runaway agent fleet can spend the organization's entire commitment. Spend limits are the gateway's per-developer view and circuit breaker on top of that shared bill.11A Claude apps gateway forwards all inference through one shared upstream credential, so your provider's bill attributes everything to that credential, not to individual developers. Without per-developer limits, one runaway agent fleet can spend the organization's entire commitment. Spend limits are the gateway's per-developer view and circuit breaker on top of that shared bill.

12 12 

13## Set a cap13## Set a cap

14 14 

15With the [`admin:`](/en/claude-apps-gateway-config#admin) block configured in `gateway.yaml`, the gateway serves an admin API at `/v1/organizations/spend_limits` and enforces caps live on every inference request. Caps themselves are set through that API, not in `gateway.yaml`; each `POST /v1/organizations/spend_limits` request creates or replaces one cap from `{scope, amount, period}`. The API mirrors the wire shapes of Anthropic's public [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) spend-limits endpoints, so an HTTP client written against that contract can target the gateway by changing its base URL.15With the [`admin:`](/docs/en/claude-apps-gateway-config#admin) block configured in `gateway.yaml`, the gateway serves an admin API at `/v1/organizations/spend_limits` and enforces caps live on every inference request. Caps themselves are set through that API, not in `gateway.yaml`; each `POST /v1/organizations/spend_limits` request creates or replaces one cap from `{scope, amount, period}`. The API mirrors the wire shapes of Anthropic's public [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) spend-limits endpoints, so an HTTP client written against that contract can target the gateway by changing its base URL.

16 16 

17This request sets an org-wide default of \$500 per month for every developer:17This request sets an org-wide default of \$500 per month for every developer:

18 18 


34 34 

35| Field | Values | Description |35| Field | Values | Description |

36| ------------ | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |36| ------------ | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

37| `scope.type` | `user`, `rbac_group`, `organization` | `user` targets one developer by their OpenID Connect (OIDC) `sub`, the stable user ID your identity provider assigns; pass it as `scope.user_id`. `rbac_group` targets an [IdP group](/en/claude-apps-gateway-config#managed) by name; pass it as `scope.rbac_group_id`. `organization` is the org-wide default. The gateway accepts all three; Anthropic's public `POST` is user-only today. |37| `scope.type` | `user`, `rbac_group`, `organization` | `user` targets one developer by their OpenID Connect (OIDC) `sub`, the stable user ID your identity provider assigns; pass it as `scope.user_id`. `rbac_group` targets an [IdP group](/docs/en/claude-apps-gateway-config#managed) by name; pass it as `scope.rbac_group_id`. `organization` is the org-wide default. The gateway accepts all three; Anthropic's public `POST` is user-only today. |

38| `amount` | Whole-number string of USD cents, or `null` | `null` is unlimited. `"0"` is a zero cap, which blocks every request. |38| `amount` | Whole-number string of USD cents, or `null` | `null` is unlimited. `"0"` is a zero cap, which blocks every request. |

39| `period` | `daily`, `weekly`, `monthly` | A scope can hold one cap per period, and each enforces independently: a developer is blocked if over any of them. |39| `period` | `daily`, `weekly`, `monthly` | A scope can hold one cap per period, and each enforces independently: a developer is blocked if over any of them. |

40 40 

41A group or organization cap is a per-seat default that each member inherits, not a shared pool. Per period, a developer's effective cap resolves in this order: a per-user override, then the most restrictive of their group caps, then the org default, then unlimited. [`admin.group_limit_mode: max`](/en/claude-apps-gateway-config#admin) flips the multi-group tie-break to least-restrictive instead.41A group or organization cap is a per-seat default that each member inherits, not a shared pool. Per period, a developer's effective cap resolves in this order: a per-user override, then the most restrictive of their group caps, then the org default, then unlimited. [`admin.group_limit_mode: max`](/docs/en/claude-apps-gateway-config#admin) flips the multi-group tie-break to least-restrictive instead.

42 42 

43### Authenticate to the admin API43### Authenticate to the admin API

44 44 

45Send one of:45Send one of:

46 46 

47* An `x-api-key` header matching a key in [`admin.write_keys`](/en/claude-apps-gateway-config#admin) for full access, or `admin.read_keys` for `GET`-only access. Each key carries an `id` that appears in the audit log as `admin-key:<id>`, so give Terraform, CI, and each automation its own.47* An `x-api-key` header matching a key in [`admin.write_keys`](/docs/en/claude-apps-gateway-config#admin) for full access, or `admin.read_keys` for `GET`-only access. Each key carries an `id` that appears in the audit log as `admin-key:<id>`, so give Terraform, CI, and each automation its own.

48* A gateway bearer token whose `groups` claim includes one of [`admin.admin_groups`](/en/claude-apps-gateway-config#admin). This is full access and audits as `oidc:<sub>`, so prefer it for human admins.48* A gateway bearer token whose `groups` claim includes one of [`admin.admin_groups`](/docs/en/claude-apps-gateway-config#admin). This is full access and audits as `oidc:<sub>`, so prefer it for human admins.

49 49 

50## How enforcement works50## How enforcement works

51 51 

52On each `/v1/messages` request, the gateway resolves the developer's caps and period-to-date spend in one Postgres query. If they're over any cap, the request returns `429` with `error.type: billing_error` and the header `x-should-retry: false`. The message is `spend limit reached`, followed by your [`admin.blocked_message`](/en/claude-apps-gateway-config#admin) if set.52On each `/v1/messages` request, the gateway resolves the developer's caps and period-to-date spend in one Postgres query. If they're over any cap, the request returns `429` with `error.type: billing_error` and the header `x-should-retry: false`. The message is `spend limit reached`, followed by your [`admin.blocked_message`](/docs/en/claude-apps-gateway-config#admin) if set.

53 53 

54`/v1/messages/count_tokens` is exempt. Token counting is free, so it runs regardless of cap state.54`/v1/messages/count_tokens` is exempt. Token counting is free, so it runs regardless of cap state.

55 55 


57 57 

58Spend limits estimate spend from token counts at USD list price; they're a circuit breaker, not an invoice. For authoritative billing, reconcile against your provider's own usage reporting, such as the Anthropic Usage & Cost Admin API, invocation logs on Amazon Bedrock, or Cloud Monitoring on Google Cloud.58Spend limits estimate spend from token counts at USD list price; they're a circuit breaker, not an invoice. For authoritative billing, reconcile against your provider's own usage reporting, such as the Anthropic Usage & Cost Admin API, invocation logs on Amazon Bedrock, or Cloud Monitoring on Google Cloud.

59 59 

60Pricing uses the same table the Claude Code CLI uses for its own cost display, with the same model-ID canonicalization across Anthropic, Amazon Bedrock (`us.anthropic.…-v1:0`), Google Cloud's Agent Platform (`claude-…@date`), and Microsoft Foundry ID forms. A model ID the table can't place, such as a Microsoft Foundry deployment name or an inference-profile ARN, is priced at the unknown-model default tier of \$5/\$25 per million input/output tokens rather than zero, so an unrecognized ID can't bypass a cap by going unmetered. The gateway warns at boot and once per ID at runtime when a model prices through the fallback.60Pricing uses the same table the Claude Code CLI uses for its own cost display, with the same model-ID canonicalization across Anthropic, Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry ID forms, such as Bedrock's `us.anthropic.…-v1:0` and Agent Platform's `claude-…@date`. The meter resolves each request's rate tier in order:

61 

621. Exact rates for the upstream model ID, the model string the gateway sends to the provider. When the table recognizes it, such as `us.anthropic.claude-…`, the meter prices the request by the model that served it.

632. {/* min-version: 2.1.218 */}Rates for the configured [`models[].id`](/docs/en/claude-apps-gateway-config#models) you mapped to the upstream ID. This step covers upstream strings that carry no model name, such as an Amazon Bedrock application-inference-profile ARN or a Microsoft Foundry deployment name, and requires Claude Code v2.1.218 or later on the gateway server.

643. The unknown-model default tier of \$5/\$25 per million input/output tokens. The meter prices an ID that neither the table nor your `models` config can place, including a `models[].id` that is itself a custom alias, at this tier rather than zero, so an unrecognized ID can't bypass a cap by going unmetered.

65 

66The gateway warns at boot and once per ID at runtime when it prices a model at the unknown-model tier. Before v2.1.218, the meter skipped step 2: it priced any upstream ID the table couldn't place at the unknown-model tier and warned about it even when the configured ID's rates were known.

61 67 

62Client aborts are billed too. The upstream reports output tokens only in the stream's terminal frame, so an aborted stream doesn't carry them. The meter keeps a conservative floor estimate from the streamed content size, about four characters per token, and bills it when and only when the terminal usage frame is missing. A complete stream always bills the upstream-reported count. Without this, a capped developer could stream output and abort each request immediately before the end, spending without ever being counted.68Client aborts are billed too. The upstream reports output tokens only in the stream's terminal frame, so an aborted stream doesn't carry them. The meter keeps a conservative floor estimate from the streamed content size, about four characters per token, and bills it when and only when the terminal usage frame is missing. A complete stream always bills the upstream-reported count. Without this, a capped developer could stream output and abort each request immediately before the end, spending without ever being counted.

63 69 

64### Postgres availability70### Postgres availability

65 71 

66The pre-check queries Postgres with a two-second timeout. If the store is unreachable or times out, enforcement fails open by default: the request proceeds and the gateway logs a warning. Set [`enforcement.fail_closed_on_error: true`](/en/claude-apps-gateway-config#enforcement) to fail closed instead, which returns the same `429 billing_error` with the message `spend limit unavailable`. Fail-open keeps a store outage from becoming an inference outage; fail-closed guarantees no unmetered spend.72The pre-check queries Postgres with a two-second timeout. If the store is unreachable or times out, enforcement fails open by default: the request proceeds and the gateway logs a warning. Set [`enforcement.fail_closed_on_error: true`](/docs/en/claude-apps-gateway-config#enforcement) to fail closed instead, which returns the same `429 billing_error` with the message `spend limit unavailable`. Fail-open keeps a store outage from becoming an inference outage; fail-closed guarantees no unmetered spend.

67 73 

68## Admin API reference74## Admin API reference

69 75 


127 133 

128| Table | Contents | Retention |134| Table | Contents | Retention |

129| ------------------ | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |135| ------------------ | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |

130| `spend` | Per-principal period-to-date counters in cents | [`admin.spend_retention_months`](/en/claude-apps-gateway-config#admin), default 13 |136| `spend` | Per-principal period-to-date counters in cents | [`admin.spend_retention_months`](/docs/en/claude-apps-gateway-config#admin), default 13 |

131| `spend_limits` | The configured caps | Until deleted via the API |137| `spend_limits` | The configured caps | Until deleted via the API |

132| `admin_audit` | The mutation trail | [`admin.audit_retention_days`](/en/claude-apps-gateway-config#admin), default 365 |138| `admin_audit` | The mutation trail | [`admin.audit_retention_days`](/docs/en/claude-apps-gateway-config#admin), default 365 |

133| `principal_emails` | Each principal's last-seen email, display name, and IdP groups. Contains PII. | [`admin.identity_retention_days`](/en/claude-apps-gateway-config#admin) since last activity, default 90 |139| `principal_emails` | Each principal's last-seen email, display name, and IdP groups. Contains PII. | [`admin.identity_retention_days`](/docs/en/claude-apps-gateway-config#admin) since last activity, default 90 |

134 140 

135`identity_retention_days` is deliberately shorter than `spend_retention_months`: a deprovisioned identity stops refreshing and ages out, while its anonymous spend counters remain for year-over-year reporting.141`identity_retention_days` is deliberately shorter than `spend_retention_months`: a deprovisioned identity stops refreshing and ages out, while its anonymous spend counters remain for year-over-year reporting.

136 142 


138 144 

139## Related145## Related

140 146 

141* [`admin` and `enforcement` configuration](/en/claude-apps-gateway-config#admin): enabling the admin API and tuning retention147* [`admin` and `enforcement` configuration](/docs/en/claude-apps-gateway-config#admin): enabling the admin API and tuning retention

142* [Deployment guide](/en/claude-apps-gateway-deploy#postgres): Postgres schema and backup guidance148* [Deployment guide](/docs/en/claude-apps-gateway-deploy#postgres): Postgres schema and backup guidance

Details

6 6 

7> Step-by-step guides for exploring codebases, fixing bugs, refactoring, testing, and other everyday tasks with Claude Code.7> Step-by-step guides for exploring codebases, fixing bugs, refactoring, testing, and other everyday tasks with Claude Code.

8 8 

9This page collects short recipes for everyday development. For higher-level guidance on prompting and context management, see [Best practices](/en/best-practices).9This page collects short recipes for everyday development. For higher-level guidance on prompting and context management, see [Best practices](/docs/en/best-practices).

10 10 

11This page covers:11This page covers:

12 12 


23 23 

24### Understand new codebases24### Understand new codebases

25 25 

26For configuring Claude Code in a monorepo or large codebase, see [Monorepos and large repos](/en/large-codebases).26For configuring Claude Code in a monorepo or large codebase, see [Monorepos and large repos](/docs/en/large-codebases).

27 27 

28#### Get a quick codebase overview28#### Get a quick codebase overview

29 29 


45 </Step>45 </Step>

46 46 

47 <Step title="Ask for a high-level overview">47 <Step title="Ask for a high-level overview">

48 ```text theme={null}48 ```text wrap theme={null}

49 give me an overview of this codebase49 give me an overview of this codebase

50 ```50 ```

51 </Step>51 </Step>

52 52 

53 <Step title="Dive deeper into specific components">53 <Step title="Dive deeper into specific components">

54 ```text theme={null}54 ```text wrap theme={null}

55 explain the main architecture patterns used here55 explain the main architecture patterns used here

56 ```56 ```

57 57 

58 ```text theme={null}58 ```text wrap theme={null}

59 what are the key data models?59 what are the key data models?

60 ```60 ```

61 61 

62 ```text theme={null}62 ```text wrap theme={null}

63 how is authentication handled?63 how is authentication handled?

64 ```64 ```

65 </Step>65 </Step>


79 79 

80<Steps>80<Steps>

81 <Step title="Ask Claude to find relevant files">81 <Step title="Ask Claude to find relevant files">

82 ```text theme={null}82 ```text wrap theme={null}

83 find the files that handle user authentication83 find the files that handle user authentication

84 ```84 ```

85 </Step>85 </Step>

86 86 

87 <Step title="Get context on how components interact">87 <Step title="Get context on how components interact">

88 ```text theme={null}88 ```text wrap theme={null}

89 how do these authentication files work together?89 how do these authentication files work together?

90 ```90 ```

91 </Step>91 </Step>

92 92 

93 <Step title="Understand the execution flow">93 <Step title="Understand the execution flow">

94 ```text theme={null}94 ```text wrap theme={null}

95 trace the login process from front-end to database95 trace the login process from front-end to database

96 ```96 ```

97 </Step>97 </Step>


102 102 

103 * Be specific about what you're looking for103 * Be specific about what you're looking for

104 * Use domain language from the project104 * Use domain language from the project

105 * Install a [code intelligence plugin](/en/discover-plugins#code-intelligence) for your language to give Claude precise "go to definition" and "find references" navigation105 * Install a [code intelligence plugin](/docs/en/discover-plugins#code-intelligence) for your language to give Claude precise "go to definition" and "find references" navigation

106</Tip>106</Tip>

107 107 

108***108***


113 113 

114<Steps>114<Steps>

115 <Step title="Share the error with Claude">115 <Step title="Share the error with Claude">

116 ```text theme={null}116 ```text wrap theme={null}

117 I'm seeing an error when I run npm test117 I'm seeing an error when I run npm test

118 ```118 ```

119 </Step>119 </Step>

120 120 

121 <Step title="Ask for fix recommendations">121 <Step title="Ask for fix recommendations">

122 ```text theme={null}122 ```text wrap theme={null}

123 suggest a few ways to fix the @ts-ignore in user.ts123 suggest a few ways to fix the @ts-ignore in user.ts

124 ```124 ```

125 </Step>125 </Step>

126 126 

127 <Step title="Apply the fix">127 <Step title="Apply the fix">

128 ```text theme={null}128 ```text wrap theme={null}

129 update user.ts to add the null check you suggested129 update user.ts to add the null check you suggested

130 ```130 ```

131 </Step>131 </Step>


147 147 

148<Steps>148<Steps>

149 <Step title="Identify legacy code for refactoring">149 <Step title="Identify legacy code for refactoring">

150 ```text theme={null}150 ```text wrap theme={null}

151 find deprecated API usage in our codebase151 find deprecated API usage in our codebase

152 ```152 ```

153 </Step>153 </Step>

154 154 

155 <Step title="Get refactoring recommendations">155 <Step title="Get refactoring recommendations">

156 ```text theme={null}156 ```text wrap theme={null}

157 suggest how to refactor utils.js to use modern JavaScript features157 suggest how to refactor utils.js to use modern JavaScript features

158 ```158 ```

159 </Step>159 </Step>

160 160 

161 <Step title="Apply the changes safely">161 <Step title="Apply the changes safely">

162 ```text theme={null}162 ```text wrap theme={null}

163 refactor utils.js to use ES2024 features while maintaining the same behavior163 refactor utils.js to use ES2024 features while maintaining the same behavior

164 ```164 ```

165 </Step>165 </Step>

166 166 

167 <Step title="Verify the refactoring">167 <Step title="Verify the refactoring">

168 ```text theme={null}168 ```text wrap theme={null}

169 run tests for the refactored code169 run tests for the refactored code

170 ```170 ```

171 </Step>171 </Step>


187 187 

188<Steps>188<Steps>

189 <Step title="Identify untested code">189 <Step title="Identify untested code">

190 ```text theme={null}190 ```text wrap theme={null}

191 find functions in NotificationsService.swift that are not covered by tests191 find functions in NotificationsService.swift that are not covered by tests

192 ```192 ```

193 </Step>193 </Step>

194 194 

195 <Step title="Generate test scaffolding">195 <Step title="Generate test scaffolding">

196 ```text theme={null}196 ```text wrap theme={null}

197 add tests for the notification service197 add tests for the notification service

198 ```198 ```

199 </Step>199 </Step>

200 200 

201 <Step title="Add meaningful test cases">201 <Step title="Add meaningful test cases">

202 ```text theme={null}202 ```text wrap theme={null}

203 add test cases for edge conditions in the notification service203 add test cases for edge conditions in the notification service

204 ```204 ```

205 </Step>205 </Step>

206 206 

207 <Step title="Run and verify tests">207 <Step title="Run and verify tests">

208 ```text theme={null}208 ```text wrap theme={null}

209 run the new tests and fix any failures209 run the new tests and fix any failures

210 ```210 ```

211 </Step>211 </Step>


223 223 

224<Steps>224<Steps>

225 <Step title="Summarize your changes">225 <Step title="Summarize your changes">

226 ```text theme={null}226 ```text wrap theme={null}

227 summarize the changes I've made to the authentication module227 summarize the changes I've made to the authentication module

228 ```228 ```

229 </Step>229 </Step>

230 230 

231 <Step title="Generate a pull request">231 <Step title="Generate a pull request">

232 ```text theme={null}232 ```text wrap theme={null}

233 create a pr233 create a pr

234 ```234 ```

235 </Step>235 </Step>

236 236 

237 <Step title="Review and refine">237 <Step title="Review and refine">

238 ```text theme={null}238 ```text wrap theme={null}

239 enhance the PR description with more context about the security improvements239 enhance the PR description with more context about the security improvements

240 ```240 ```

241 </Step>241 </Step>

242</Steps>242</Steps>

243 243 

244When you create a PR using `gh pr create`, the session is automatically linked to that PR. To find it later, run `claude --from-pr 1234` with your own PR number, which opens the session picker filtered to sessions linked to that PR, or paste the PR URL into the [`/resume` picker](/en/sessions#use-the-session-picker) search.244When you create a PR using `gh pr create`, the session is automatically linked to that PR. To find it later, run `claude --from-pr 1234` with your own PR number, which opens the session picker filtered to sessions linked to that PR, or paste the PR URL into the [`/resume` picker](/docs/en/sessions#use-the-session-picker) search.

245 245 

246<Tip>246<Tip>

247 Review Claude's generated PR before submitting and ask Claude to highlight potential risks or considerations.247 Review Claude's generated PR before submitting and ask Claude to highlight potential risks or considerations.


253 253 

254<Steps>254<Steps>

255 <Step title="Identify undocumented code">255 <Step title="Identify undocumented code">

256 ```text theme={null}256 ```text wrap theme={null}

257 find functions without proper JSDoc comments in the auth module257 find functions without proper JSDoc comments in the auth module

258 ```258 ```

259 </Step>259 </Step>

260 260 

261 <Step title="Generate documentation">261 <Step title="Generate documentation">

262 ```text theme={null}262 ```text wrap theme={null}

263 add JSDoc comments to the undocumented functions in auth.js263 add JSDoc comments to the undocumented functions in auth.js

264 ```264 ```

265 </Step>265 </Step>

266 266 

267 <Step title="Review and enhance">267 <Step title="Review and enhance">

268 ```text theme={null}268 ```text wrap theme={null}

269 improve the generated documentation with more context and examples269 improve the generated documentation with more context and examples

270 ```270 ```

271 </Step>271 </Step>

272 272 

273 <Step title="Verify documentation">273 <Step title="Verify documentation">

274 ```text theme={null}274 ```text wrap theme={null}

275 check if the documentation follows our project standards275 check if the documentation follows our project standards

276 ```276 ```

277 </Step>277 </Step>


309 </Step>309 </Step>

310 310 

311 <Step title="Ask Claude to analyze the image">311 <Step title="Ask Claude to analyze the image">

312 ```text theme={null}312 ```text wrap theme={null}

313 What does this image show?313 What does this image show?

314 ```314 ```

315 315 

316 ```text theme={null}316 ```text wrap theme={null}

317 Describe the UI elements in this screenshot317 Describe the UI elements in this screenshot

318 ```318 ```

319 319 

320 ```text theme={null}320 ```text wrap theme={null}

321 Are there any problematic elements in this diagram?321 Are there any problematic elements in this diagram?

322 ```322 ```

323 </Step>323 </Step>

324 324 

325 <Step title="Use images for context">325 <Step title="Use images for context">

326 ```text theme={null}326 ```text wrap theme={null}

327 Here's a screenshot of the error. What's causing it?327 Here's a screenshot of the error. What's causing it?

328 ```328 ```

329 329 

330 ```text theme={null}330 ```text wrap theme={null}

331 This is our current database schema. How should we modify it for the new feature?331 This is our current database schema. How should we modify it for the new feature?

332 ```332 ```

333 </Step>333 </Step>

334 334 

335 <Step title="Get code suggestions from visual content">335 <Step title="Get code suggestions from visual content">

336 ```text theme={null}336 ```text wrap theme={null}

337 Generate CSS to match this design mockup337 Generate CSS to match this design mockup

338 ```338 ```

339 339 

340 ```text theme={null}340 ```text wrap theme={null}

341 What HTML structure would recreate this component?341 What HTML structure would recreate this component?

342 ```342 ```

343 </Step>343 </Step>


361 361 

362<Steps>362<Steps>

363 <Step title="Reference a single file">363 <Step title="Reference a single file">

364 ```text theme={null}364 ```text wrap theme={null}

365 Explain the logic in @src/utils/auth.js365 Explain the logic in @src/utils/auth.js

366 ```366 ```

367 367 


369 </Step>369 </Step>

370 370 

371 <Step title="Reference a directory">371 <Step title="Reference a directory">

372 ```text theme={null}372 ```text wrap theme={null}

373 What's the structure of @src/components?373 What's the structure of @src/components?

374 ```374 ```

375 375 


377 </Step>377 </Step>

378 378 

379 <Step title="Reference MCP resources">379 <Step title="Reference MCP resources">

380 ```text theme={null}380 ```text wrap theme={null}

381 Show me the data from @github:repos/owner/repo/issues381 Show me the data from @github:repos/owner/repo/issues

382 ```382 ```

383 383 

384 This fetches data from connected MCP servers using the format @server:resource. See [MCP resources](/en/mcp#use-mcp-resources) for details.384 This fetches data from connected MCP servers using the format @server:resource. See [MCP resources](/docs/en/mcp#use-mcp-resources) for details.

385 </Step>385 </Step>

386</Steps>386</Steps>

387 387 


405 405 

406| Option | Where it runs | Best for |406| Option | Where it runs | Best for |

407| :----------------------------------------------------- | :-------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |407| :----------------------------------------------------- | :-------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

408| [Routines](/en/routines) | Anthropic-managed infrastructure | Tasks that should run even when your computer is off. Can also trigger on API calls or GitHub events in addition to a schedule. Configure at [claude.ai/code/routines](https://claude.ai/code/routines). |408| [Routines](/docs/en/routines) | Anthropic-managed infrastructure | Tasks that should run even when your computer is off. Can also trigger on API calls or GitHub events in addition to a schedule. Configure at [claude.ai/code/routines](https://claude.ai/code/routines). |

409| [Desktop scheduled tasks](/en/desktop-scheduled-tasks) | Your machine, via the desktop app | Tasks that need direct access to local files, tools, or uncommitted changes. |409| [Desktop scheduled tasks](/docs/en/desktop-scheduled-tasks) | Your machine, via the desktop app | Tasks that need direct access to local files, tools, or uncommitted changes. |

410| [GitHub Actions](/en/github-actions) | Your CI pipeline | Tasks tied to repo events like opened PRs, or cron schedules that should live alongside your workflow config. |410| [GitHub Actions](/docs/en/github-actions) | Your CI pipeline | Tasks tied to repo events like opened PRs, or cron schedules that should live alongside your workflow config. |

411| [`/loop`](/en/scheduled-tasks) | The current CLI session | Quick polling while a session is open. Tasks stop when you start a new conversation; `--resume` and `--continue` restore unexpired ones. |411| [`/loop`](/docs/en/scheduled-tasks) | The current CLI session | Quick polling while a session is open. Tasks stop when you start a new conversation; `--resume` and `--continue` restore unexpired ones. |

412 412 

413<Tip>413<Tip>

414 When writing prompts for scheduled tasks, be explicit about what success looks like and what to do with results. The task runs autonomously, so it can't ask clarifying questions. For example: "Review open PRs labeled `needs-review`, leave inline comments on any issues, and post a summary in the `#eng-reviews` Slack channel."414 When writing prompts for scheduled tasks, be explicit about what success looks like and what to do with results. The task runs autonomously, so it can't ask clarifying questions. For example: "Review open PRs labeled `needs-review`, leave inline comments on any issues, and post a summary in the `#eng-reviews` Slack channel."


422 422 

423#### Example questions423#### Example questions

424 424 

425```text theme={null}425```text wrap theme={null}

426can Claude Code create pull requests?426can Claude Code create pull requests?

427```427```

428 428 

429```text theme={null}429```text wrap theme={null}

430how does Claude Code handle permissions?430how does Claude Code handle permissions?

431```431```

432 432 

433```text theme={null}433```text wrap theme={null}

434what skills are available?434what skills are available?

435```435```

436 436 

437```text theme={null}437```text wrap theme={null}

438how do I use MCP with Claude Code?438how do I use MCP with Claude Code?

439```439```

440 440 

441```text theme={null}441```text wrap theme={null}

442how do I configure Claude Code for Amazon Bedrock?442how do I configure Claude Code for Amazon Bedrock?

443```443```

444 444 

445```text theme={null}445```text wrap theme={null}

446what are the limitations of Claude Code?446what are the limitations of Claude Code?

447```447```

448 448 


468claude --continue468claude --continue

469```469```

470 470 

471This resumes the most recent session in the current directory; if there isn't one yet, it prints `No conversation found to continue` and exits. Use `claude --resume` to choose from a list, or `/resume` from inside a running session. See [Manage sessions](/en/sessions) for naming, branching, and the full picker reference.471This resumes the most recent session in the current directory; if there isn't one yet, it prints `No conversation found to continue` and exits. Use `claude --resume` to choose from a list, or `/resume` from inside a running session. See [Manage sessions](/docs/en/sessions) for naming, branching, and the full picker reference.

472 472 

473## Run parallel sessions with worktrees473## Run parallel sessions with worktrees

474 474 


478claude --worktree feature-auth478claude --worktree feature-auth

479```479```

480 480 

481Run the same command with a different name in a second terminal to start an isolated parallel session. In a repository with no commits, the command fails with `Failed to resolve base branch "HEAD": git rev-parse failed`. See [Worktrees](/en/worktrees) for cleanup, `.worktreeinclude`, and non-git VCS support. To monitor parallel sessions from one screen instead of separate terminals, see [background agents](/en/agent-view).481Run the same command with a different name in a second terminal to start an isolated parallel session. In a repository with no commits, the command fails with `Failed to resolve base branch "HEAD": git rev-parse failed`. See [Worktrees](/docs/en/worktrees) for cleanup, `.worktreeinclude`, and non-git VCS support. To monitor parallel sessions from one screen instead of separate terminals, see [background agents](/docs/en/agent-view).

482 482 

483## Plan before editing483## Plan before editing

484 484 


488claude --permission-mode plan488claude --permission-mode plan

489```489```

490 490 

491You can also press `Shift+Tab` mid-session to cycle to plan mode. The cycle runs `default` → `acceptEdits` → `plan`. See [Plan mode](/en/permission-modes#analyze-before-you-edit-with-plan-mode) for the approval flow and editing the plan in your text editor.491You can also press `Shift+Tab` mid-session to cycle to plan mode. The cycle runs `default` → `acceptEdits` → `plan`. See [Plan mode](/docs/en/permission-modes#analyze-before-you-edit-with-plan-mode) for the approval flow and editing the plan in your text editor.

492 492 

493## Delegate research to subagents493## Delegate research to subagents

494 494 

495Exploring a large codebase fills your context with file reads. Delegate the exploration so only the findings come back.495Exploring a large codebase fills your context with file reads. Delegate the exploration so only the findings come back.

496 496 

497```text theme={null}497```text wrap theme={null}

498use a subagent to investigate how our auth system handles token refresh498use a subagent to investigate how our auth system handles token refresh

499```499```

500 500 

501The subagent reads files in its own context window and reports a summary. See [Subagents](/en/sub-agents) for defining custom agents with their own tools and prompts.501The subagent reads files in its own context window and reports a summary. See [Subagents](/docs/en/sub-agents) for defining custom agents with their own tools and prompts.

502 502 

503## Pipe Claude into scripts503## Pipe Claude into scripts

504 504 


508git log --oneline -20 | claude -p "summarize these recent commits"508git log --oneline -20 | claude -p "summarize these recent commits"

509```509```

510 510 

511See [Non-interactive mode](/en/headless) for output formats, permission flags, and fan-out patterns.511See [Non-interactive mode](/docs/en/headless) for output formats, permission flags, and fan-out patterns.

512 512 

513## Next steps513## Next steps

514 514 

515<CardGroup cols={2}>515<CardGroup cols={2}>

516 <Card title="Best practices" icon="lightbulb" href="/en/best-practices">516 <Card title="Best practices" icon="lightbulb" href="/docs/en/best-practices">

517 Patterns for getting the most out of Claude Code517 Patterns for getting the most out of Claude Code

518 </Card>518 </Card>

519 519 

520 <Card title="Manage sessions" icon="rotate-left" href="/en/sessions">520 <Card title="Manage sessions" icon="rotate-left" href="/docs/en/sessions">

521 Resume, name, and branch conversations521 Resume, name, and branch conversations

522 </Card>522 </Card>

523 523 

524 <Card title="Worktrees" icon="code-branch" href="/en/worktrees">524 <Card title="Worktrees" icon="code-branch" href="/docs/en/worktrees">

525 Run isolated parallel sessions525 Run isolated parallel sessions

526 </Card>526 </Card>

527 527 

528 <Card title="Extend Claude Code" icon="puzzle-piece" href="/en/features-overview">528 <Card title="Extend Claude Code" icon="puzzle-piece" href="/docs/en/features-overview">

529 Add skills, hooks, MCP, subagents, and plugins529 Add skills, hooks, MCP, subagents, and plugins

530 </Card>530 </Card>

531</CardGroup>531</CardGroup>

data-usage.md +3 −1

Details

67 67 

68The diagram below shows how Claude Code connects to external services during installation and normal operation. Solid lines indicate required connections, while dashed lines represent optional or user-initiated data flows.68The diagram below shows how Claude Code connects to external services during installation and normal operation. Solid lines indicate required connections, while dashed lines represent optional or user-initiated data flows.

69 69 

70<img src="https://mintcdn.com/claude-code/YR4DRZyI3CdsXkiT/images/claude-code-data-flow.svg?fit=max&auto=format&n=YR4DRZyI3CdsXkiT&q=85&s=2846ea92cfc2297b8620c31c82b482ad" alt="Diagram showing Claude Code's external connections: install/update connects to the distribution server, and user requests connect to Anthropic's Console auth and public-api, with optional telemetry flows carrying metrics and error reports to Anthropic and third-party services. Feedback sent with /feedback goes to Google Cloud Storage and optionally creates a GitHub issue" width="720" height="520" data-path="images/claude-code-data-flow.svg" />70<img src="https://mintcdn.com/claude-code/YR4DRZyI3CdsXkiT/images/claude-code-data-flow.svg?fit=max&auto=format&n=YR4DRZyI3CdsXkiT&q=85&s=2846ea92cfc2297b8620c31c82b482ad" className="dark:hidden" alt="Diagram showing Claude Code's external connections: install/update connects to the distribution server, and user requests connect to Anthropic's Console auth and public-api, with optional telemetry flows carrying metrics and error reports to Anthropic and third-party services. Feedback sent with /feedback goes to Google Cloud Storage and optionally creates a GitHub issue" width="720" height="520" data-path="images/claude-code-data-flow.svg" />

71 

72<img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/claude-code-data-flow-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=4fb6e8c88a9740845217bf2a2b040877" className="hidden dark:block" alt="Diagram showing Claude Code's external connections: install/update connects to the distribution server, and user requests connect to Anthropic's Console auth and public-api, with optional telemetry flows carrying metrics and error reports to Anthropic and third-party services. Feedback sent with /feedback goes to Google Cloud Storage and optionally creates a GitHub issue" width="720" height="520" data-path="images/claude-code-data-flow-dark.svg" />

71 73 

72Claude Code runs locally. To interact with the LLM, Claude Code sends data over the network. This data includes all user prompts and model outputs, encrypted in transit via TLS 1.2+. Claude Code is compatible with most popular VPNs and LLM proxies.74Claude Code runs locally. To interact with the LLM, Claude Code sends data over the network. This data includes all user prompts and model outputs, encrypted in transit via TLS 1.2+. Claude Code is compatible with most popular VPNs and LLM proxies.

73 75 

desktop.md +24 −7

Details

33* Watch Claude [run and test your iOS app](/docs/en/desktop-ios-simulator) in the iOS Simulator pane33* Watch Claude [run and test your iOS app](/docs/en/desktop-ios-simulator) in the iOS Simulator pane

34* [Arrange panes](#arrange-your-workspace) for the chat, diff, browser, terminal, and file editor side by side34* [Arrange panes](#arrange-your-workspace) for the chat, diff, browser, terminal, and file editor side by side

35* Ask a [side question](#ask-a-side-question-without-derailing-the-session) that uses the session's context without derailing it35* Ask a [side question](#ask-a-side-question-without-derailing-the-session) that uses the session's context without derailing it

36* Let Claude [check on, message, or archive your other sessions](#work-across-sessions)

36* [Connect external tools](#connect-external-tools) like GitHub, Slack, and Linear37* [Connect external tools](#connect-external-tools) like GitHub, Slack, and Linear

37* Let Claude [open apps and control your screen](#let-claude-use-your-computer)38* Let Claude [open apps and control your screen](#let-claude-use-your-computer)

38* Run on your machine, in the [cloud](#run-long-running-tasks-remotely), or over [SSH](#ssh-sessions)39* Run on your machine, in the [cloud](#run-long-running-tasks-remotely), or over [SSH](#ssh-sessions)


74To set a default mode for new local sessions, add `permissions.defaultMode` to your [settings file](/docs/en/settings#settings-files). The desktop app reads the same settings files as the CLI. A mode you pick in the selector is remembered per folder and takes precedence over `defaultMode` for that folder, except Plan, which applies to the current session only.75To set a default mode for new local sessions, add `permissions.defaultMode` to your [settings file](/docs/en/settings#settings-files). The desktop app reads the same settings files as the CLI. A mode you pick in the selector is remembered per folder and takes precedence over `defaultMode` for that folder, except Plan, which applies to the current session only.

75 76 

76| Mode | Settings key | Behavior |77| Mode | Settings key | Behavior |

77| ---------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |78| ---------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

78| **Manual** | `default` | Claude asks before editing files or running commands. You see a diff and can accept or reject each change. Recommended for new users. |79| **Manual** | `default` | Claude asks before editing files or running commands. You see a diff and can accept or reject each change. Recommended for new users. |

79| **Accept edits** | `acceptEdits` | Claude auto-accepts file edits and common filesystem commands like `mkdir`, `touch`, and `mv`, but still asks before running other terminal commands. Use this when you trust file changes and want faster iteration. |80| **Accept edits** | `acceptEdits` | Claude auto-accepts file edits and common filesystem commands like `mkdir`, `touch`, and `mv`, but still asks before running other terminal commands. Use this when you trust file changes and want faster iteration. |

80| **Plan** | `plan` | Claude reads files and runs commands to explore, then proposes a plan without editing your source code. Good for complex tasks where you want to review the approach first. |81| **Plan** | `plan` | Claude reads files and runs commands to explore, then proposes a plan without editing your source code. Good for complex tasks where you want to review the approach first. |

81| **Auto** | `auto` | Claude executes all actions with background safety checks that verify alignment with your request. Reduces permission prompts while maintaining oversight. Appears when your account meets the [availability requirements](#auto-mode-availability) below; there is no separate Settings toggle for it. |82| **Auto** | `auto` | Claude executes all actions with background safety checks that verify alignment with your request. Reduces permission prompts while maintaining oversight. Appears when your account meets the [availability requirements](#auto-mode-availability) below; there is no separate Settings toggle for it. |

82| **Bypass permissions** | `bypassPermissions` | Claude runs without permission prompts, except those forced by explicit [ask rules](/docs/en/permissions#manage-permissions), connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), MCP tools marked [`requiresUserInteraction`](/docs/en/mcp#require-approval-for-a-specific-tool), or safety classifiers when Claude [acts on external sites](#browse-external-sites); equivalent to `--dangerously-skip-permissions` in the CLI. On Pro and Max plans, enable it in your Settings → Claude Code under "Allow bypass permissions mode"; on Team and Enterprise plans there is no Settings toggle, and organization policy controls it instead. Only use this in sandboxed containers or VMs. |83| **Bypass permissions** | `bypassPermissions` | Claude runs without permission prompts, except those forced by explicit [ask rules](/docs/en/permissions#manage-permissions), connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), MCP tools marked [`requiresUserInteraction`](/docs/en/mcp#require-approval-for-a-specific-tool), safety classifiers when Claude [acts on external sites](#browse-external-sites), or desktop actions where Claude always asks first, such as [archiving a session](#work-across-sessions); equivalent to `--dangerously-skip-permissions` in the CLI. On Pro and Max plans, enable it in your Settings → Claude Code under "Allow bypass permissions mode"; on Team and Enterprise plans there is no Settings toggle, and organization policy controls it instead. Only use this in sandboxed containers or VMs. |

83 84 

84Earlier versions of the Code tab labeled these modes Ask permissions, Auto accept edits, and Plan mode.85Earlier versions of the Code tab labeled these modes Ask permissions, Auto accept edits, and Plan mode.

85 86 


166After you open a pull request, a CI status bar appears in the session. Claude Code uses the GitHub CLI to poll check results and surface failures.167After you open a pull request, a CI status bar appears in the session. Claude Code uses the GitHub CLI to poll check results and surface failures.

167 168 

168* **Auto-fix**: when enabled, Claude automatically attempts to fix failing CI checks by reading the failure output and iterating.169* **Auto-fix**: when enabled, Claude automatically attempts to fix failing CI checks by reading the failure output and iterating.

169* **Auto-merge**: when enabled, Claude merges the PR once all checks pass. The merge method is squash. Auto-merge must be [enabled in your GitHub repository settings](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-auto-merge-for-pull-requests-in-your-repository) for this to work.170* **Auto-merge**: when enabled, Claude merges the PR once all checks pass. The merge method is squash. Enable auto-merge in your [GitHub repository settings](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-auto-merge-for-pull-requests-in-your-repository) first; without it, Claude can't merge the PR.

170 171 

171Use the **Auto-fix** and **Auto-merge** toggles in the CI status bar to enable either option. Claude Code also sends a desktop notification when CI finishes. To archive the session automatically once the PR merges or closes, turn on [auto-archive](#work-in-parallel-with-sessions) in Settings → Claude Code.172Use the **Auto-fix** and **Auto-merge** toggles in the CI status bar to enable either option. Claude Code also sends a desktop notification when CI finishes. To archive the session automatically once the PR merges or closes, turn on [auto-archive](#work-in-parallel-with-sessions) in Settings → Claude Code.

172 173 


315 316 

316## Manage sessions317## Manage sessions

317 318 

318Each session is an independent conversation with its own context and changes. You can run multiple sessions in parallel, branch off side chats, send work to the cloud, or let Dispatch start sessions for you from your phone.319Each session is an independent conversation with its own context and changes. You can run multiple sessions in parallel, branch off side chats, let Claude check on and message your other sessions, send work to the cloud, or let Dispatch start sessions for you from your phone.

319 320 

320### Work in parallel with sessions321### Work in parallel with sessions

321 322 


345 346 

346The tasks pane shows the background work running inside the current session: subagents, background shell commands, and [dynamic workflows](/docs/en/workflows). Open it from the **Views** menu or drag it into your layout.347The tasks pane shows the background work running inside the current session: subagents, background shell commands, and [dynamic workflows](/docs/en/workflows). Open it from the **Views** menu or drag it into your layout.

347 348 

348Click any entry to see its output in the subagent pane or stop it. To see what other sessions are doing, use the [sidebar](#work-in-parallel-with-sessions).349Click any entry to see its output in the subagent pane or stop it. To see what other sessions are doing, use the [sidebar](#work-in-parallel-with-sessions), or ask Claude to [check on them for you](#work-across-sessions).

350 

351### Work across sessions

352 

353Claude can list your other Code tab sessions, read what each has been doing, and send messages between them. Ask in plain language: "which session touched the auth refactor?", "what did the API session conclude?", or "tell the payments session the schema changed". You can also ask Claude to rename or archive a session. Claude archives a session the same way the sidebar's archive icon does, so ask it to clean up sessions whose PRs have merged.

354 

355Claude sees only the sessions the desktop app runs itself: local, [SSH](#ssh-sessions), and [WSL](/docs/en/desktop-wsl) sessions in the Code tab. Claude doesn't see cloud sessions, and doesn't see sessions you started from the terminal CLI or the VS Code extension, even in worktrees of the same project, so with nine terminal worktrees open and two desktop sessions, Claude answering in one of them reports the one other desktop session. Claude never lists the session you're asking from. By default it sees the 20 most recently active sessions and skips archived sessions unless you ask for them.

356 

357When Claude sends a message to another session, Claude Code shows it there as a card labeled with the sending session's title and a link back, so you can always tell where a message came from. If the receiving session is mid-task, Claude Code holds the message and Claude reads it once the current work finishes. Claude can't deliver to an archived session, and tells you when a message doesn't go through.

358 

359Claude Code applies three safety behaviors across sessions:

360 

361* Before archiving any session, Claude asks you first. You see the approval card in every permission mode, including Auto and Bypass permissions.

362* Claude can't send cross-session messages from a session nobody is watching, such as a scheduled-task run, and can't deliver messages into one.

363* Claude Code quotes each incoming message and attributes it to the session that sent it, and Claude still follows the receiving session's own permission settings when acting on one.

364 

365Claude can also suggest new sessions. When it notices something worth fixing that's out of scope for the current task, it offers the work as a task chip in the chat. Click the chip to start that work in a new session with its own worktree; Claude continues your current session uninterrupted.

349 366 

350### Run long-running tasks remotely367### Run long-running tasks remotely

351 368 


499 516 

500Localhost addresses open directly, exactly like the default port address. This includes `localhost`, any `*.localhost` subdomain, `127.0.0.1`, and `::1`. For security, a localhost `url` must be just your server's origin — no path or query, and the port must match the entry's port. To show a specific page, ask Claude to navigate there after the preview opens. A localhost `url` with a path, query, or mismatched port is reported as a configuration error that names the url and shows the fix.517Localhost addresses open directly, exactly like the default port address. This includes `localhost`, any `*.localhost` subdomain, `127.0.0.1`, and `::1`. For security, a localhost `url` must be just your server's origin — no path or query, and the port must match the entry's port. To show a specific page, ask Claude to navigate there after the preview opens. A localhost `url` with a path, query, or mismatched port is reported as a configuration error that names the url and shows the fix.

501 518 

502Any other address asks for your permission the first time it opens, the same way browsing to a new site in the preview does. External addresses may include paths. Choose **Always allow** to skip the prompt for that site in the future. Organization policies that restrict external sites in the preview still apply.519For any other address, Desktop asks for your permission the first time the preview opens it, the same as when you browse to a new site in the preview. External addresses may include paths. Choose **Always allow** to skip the prompt for that site in the future. Organization policies that restrict external sites in the preview still apply.

503 520 

504To preview a server you already run yourself, set `url` without a command. Claude attaches the preview to your running server instead of starting one:521To preview a server you already run yourself, set `url` without a command. Claude attaches the preview to your running server instead of starting one:

505 522 


862* **Third-party providers**: Desktop connects to Anthropic's API by default. To route Desktop through a gateway, see [connect the desktop app to a gateway](/docs/en/llm-gateway-connect#desktop-app). Enterprise deployments can configure Google Cloud's Agent Platform and gateway providers via [managed settings](https://claude.com/docs/third-party/claude-desktop/configuration). For Amazon Bedrock or Microsoft Foundry in the CLI, see the [quickstart](/docs/en/quickstart). As an exception to the section above, [Claude Desktop on 3P](https://claude.com/docs/third-party/claude-desktop/overview) runs the Code tab on Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, or a self-hosted LLM gateway.879* **Third-party providers**: Desktop connects to Anthropic's API by default. To route Desktop through a gateway, see [connect the desktop app to a gateway](/docs/en/llm-gateway-connect#desktop-app). Enterprise deployments can configure Google Cloud's Agent Platform and gateway providers via [managed settings](https://claude.com/docs/third-party/claude-desktop/configuration). For Amazon Bedrock or Microsoft Foundry in the CLI, see the [quickstart](/docs/en/quickstart). As an exception to the section above, [Claude Desktop on 3P](https://claude.com/docs/third-party/claude-desktop/overview) runs the Code tab on Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, or a self-hosted LLM gateway.

863* **Linux (beta)**: Computer Use isn't yet available in the Linux desktop app. See [Claude Desktop on Linux](/docs/en/desktop-linux).880* **Linux (beta)**: Computer Use isn't yet available in the Linux desktop app. See [Claude Desktop on Linux](/docs/en/desktop-linux).

864* **Inline code suggestions**: Desktop does not provide autocomplete-style suggestions. It works through conversational prompts and explicit code changes.881* **Inline code suggestions**: Desktop does not provide autocomplete-style suggestions. It works through conversational prompts and explicit code changes.

865* **Agent teams**: parallel Claude Code sessions that message each other are available in the [CLI](/docs/en/agent-teams), not in Desktop. For multi-agent work inside one session, use [dynamic workflows](/docs/en/workflows), which run in Desktop.882* **Agent teams**: coordinated teams, where Claude as the team lead assigns tasks to teammates from a shared task list, are available in the [CLI](/docs/en/agent-teams), not in Desktop. For multi-agent work inside one session, use [dynamic workflows](/docs/en/workflows), which run in Desktop; Claude can also [message and manage your other sessions](#work-across-sessions) directly.

866* **Terminal-dialog commands**: built-in commands that open an interactive panel in the terminal behave differently in the Code tab. Edit [settings files](/docs/en/settings) directly to manage permission rules and configuration, or run the commands from the standalone CLI.883* **Terminal-dialog commands**: built-in commands that open an interactive panel in the terminal behave differently in the Code tab. Edit [settings files](/docs/en/settings) directly to manage permission rules and configuration, or run the commands from the standalone CLI.

867 * Commands with no argument form, such as `/permissions`, reply with `isn't available in this environment`.884 * Commands with no argument form, such as `/permissions`, reply with `isn't available in this environment`.

868 * `/config` opens Settings → Claude Code. Text after the command is ignored, so `/config theme=dark` doesn't set the theme.885 * `/config` opens Settings → Claude Code. Text after the command is ignored, so `/config theme=dark` doesn't set the theme.

Details

65 65 

66Scheduled tasks run on your machine. Desktop checks the schedule every minute while the app is open and starts a fresh session when a task is due, independent of any manual sessions you have open. Each task gets a small delay of a few minutes after the scheduled time to stagger API traffic. The delay is deterministic: the same task always starts at the same offset.66Scheduled tasks run on your machine. Desktop checks the schedule every minute while the app is open and starts a fresh session when a task is due, independent of any manual sessions you have open. Each task gets a small delay of a few minutes after the scheduled time to stagger API traffic. The delay is deterministic: the same task always starts at the same offset.

67 67 

68When a task fires, you get a desktop notification and a new session appears under a **Scheduled** section in the sidebar. Open it to see what Claude did, review changes, or respond to permission prompts. The session works like any other: Claude can edit files, run commands, create commits, and open pull requests.68When a task fires, you get a desktop notification and a new session appears under a **Scheduled** section in the sidebar. Open it to see what Claude did, review changes, or respond to permission prompts. The session works like any other, except that Claude can't send or receive [cross-session messages](/docs/en/desktop#work-across-sessions) in a scheduled run: Claude can edit files, run commands, create commits, and open pull requests.

69 69 

70Tasks only run while the desktop app is running and your computer is awake. If your computer sleeps through a scheduled time, the run is skipped. To prevent idle-sleep, enable **Keep computer awake** in Settings under **Desktop app → General**. Closing the laptop lid still puts it to sleep. For tasks that need to run even when your computer is off, or that should trigger on an API call or GitHub event, create a remote [routine](/docs/en/routines) instead.70Tasks only run while the desktop app is running and your computer is awake. If your computer sleeps through a scheduled time, the run is skipped. To prevent idle-sleep, enable **Keep computer awake** in Settings under **Desktop app → General**. Closing the laptop lid still puts it to sleep. For tasks that need to run even when your computer is off, or that should trigger on an API call or GitHub event, create a remote [routine](/docs/en/routines) instead.

71 71 

desktop-wsl.md +2 −2

Details

28 </Step>28 </Step>

29 29 

30 <Step title="Trust the folder">30 <Step title="Trust the folder">

31 The first session in a folder shows the workspace trust dialog. Trust is granted per distribution and folder; trusting a folder in one distribution doesn't apply to another distribution or to the same path on Windows.31 The first session in a folder shows the workspace trust dialog. You grant trust per distribution and folder. A folder you trust in one distribution isn't trusted in another distribution or at the same path on Windows.

32 </Step>32 </Step>

33</Steps>33</Steps>

34 34 


44 44 

45## Managed devices45## Managed devices

46 46 

47On devices managed by an organization, WSL sessions may be unavailable. If session start fails with a message that the device is managed, that's controlled by your administrator. Administrators: see [how settings reach devices](/en/admin-setup#decide-how-settings-reach-devices) in the deployment guide.47On devices managed by an organization, WSL sessions may be unavailable. If session start fails with a message that the device is managed, that's controlled by your administrator. Administrators: see [how settings reach devices](/docs/en/admin-setup#decide-how-settings-reach-devices) in the deployment guide.

devcontainer.md +1 −1

Details

20<Accordion title="How dev containers work with your editor">20<Accordion title="How dev containers work with your editor">

21 <img src="https://mintcdn.com/claude-code/YvJyjZfd9yMihr0i/images/devcontainer-architecture.svg?fit=max&auto=format&n=YvJyjZfd9yMihr0i&q=85&s=9017b1d16a446c6cc37ba562f35b9aae" className="dark:hidden" alt="Diagram showing an editor on the host connecting to a Docker dev container. Claude Code, the terminal, and build tools run inside the container. The host repository is bind-mounted into the container as the workspace." width="640" height="300" data-path="images/devcontainer-architecture.svg" />21 <img src="https://mintcdn.com/claude-code/YvJyjZfd9yMihr0i/images/devcontainer-architecture.svg?fit=max&auto=format&n=YvJyjZfd9yMihr0i&q=85&s=9017b1d16a446c6cc37ba562f35b9aae" className="dark:hidden" alt="Diagram showing an editor on the host connecting to a Docker dev container. Claude Code, the terminal, and build tools run inside the container. The host repository is bind-mounted into the container as the workspace." width="640" height="300" data-path="images/devcontainer-architecture.svg" />

22 22 

23 <img src="https://mintcdn.com/claude-code/YvJyjZfd9yMihr0i/images/devcontainer-architecture-dark.svg?fit=max&auto=format&n=YvJyjZfd9yMihr0i&q=85&s=ef00c8e25b1ea7a3a152895f1488831b" className="hidden dark:block" alt="Diagram showing an editor on the host connecting to a Docker dev container. Claude Code, the terminal, and build tools run inside the container. The host repository is bind-mounted into the container as the workspace." width="640" height="300" data-path="images/devcontainer-architecture-dark.svg" />23 <img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/devcontainer-architecture-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=a0a340b1f2afc6a590696102c8acaaca" className="hidden dark:block" alt="Diagram showing an editor on the host connecting to a Docker dev container. Claude Code, the terminal, and build tools run inside the container. The host repository is bind-mounted into the container as the workspace." width="640" height="300" data-path="images/devcontainer-architecture-dark.svg" />

24 24 

25 A dev container runs as a Docker container, either on your machine or on a cloud host such as GitHub Codespaces. An editor that supports the Dev Containers spec, such as VS Code, GitHub Codespaces, a JetBrains IDE, or Cursor, connects to that container: you browse and edit files in the editor as usual, but the integrated terminal, language servers, and build tools all run inside the container rather than on your host. Editors without dev container support, such as plain Vim, are not part of this workflow.25 A dev container runs as a Docker container, either on your machine or on a cloud host such as GitHub Codespaces. An editor that supports the Dev Containers spec, such as VS Code, GitHub Codespaces, a JetBrains IDE, or Cursor, connects to that container: you browse and edit files in the editor as usual, but the integrated terminal, language servers, and build tools all run inside the container rather than on your host. Editors without dev container support, such as plain Vim, are not part of this workflow.

26 26 

Details

52 52 

53Code intelligence plugins enable Claude Code's built-in LSP tool, giving Claude the ability to jump to definitions, find references, and see type errors immediately after edits. These plugins configure [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) connections, the same technology that powers VS Code's code intelligence.53Code intelligence plugins enable Claude Code's built-in LSP tool, giving Claude the ability to jump to definitions, find references, and see type errors immediately after edits. These plugins configure [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) connections, the same technology that powers VS Code's code intelligence.

54 54 

55These plugins require the language server binary to be installed on your system. If you already have a language server installed, Claude may prompt you to install the corresponding plugin when you open a project.55Install the language server binary from the table below before using these plugins; the plugin doesn't install it for you. If you already have a language server installed, Claude may prompt you to install the corresponding plugin when you open a project.

56 56 

57| Language | Plugin | Binary required |57| Language | Plugin | Binary required |

58| :--------- | :------------------ | :--------------------------- |58| :--------- | :------------------ | :--------------------------- |

env-vars.md +44 −29

Details

115 115 

116Numeric variables such as timeouts, token budgets, and retry counts accept scientific notation and digit-separator spellings in addition to plain digits, except where a variable's row notes it takes plain digits only. For example, Claude Code reads `2e3` as 2000 and `64_000` as 64000. Before v2.1.211, these spellings could silently set a much smaller value, such as `1e6` setting a timeout to 1.116Numeric variables such as timeouts, token budgets, and retry counts accept scientific notation and digit-separator spellings in addition to plain digits, except where a variable's row notes it takes plain digits only. For example, Claude Code reads `2e3` as 2000 and `64_000` as 64000. Before v2.1.211, these spellings could silently set a much smaller value, such as `1e6` setting a timeout to 1.

117 117 

118<Note>

119 For variables that turn a behavior on or off, set `1` or `true` to turn it on and `0` or `false` to turn it off, in any casing.

120 

121 Some variables read only whether you set them at all, so any non-empty value including `0` turns the behavior on, and you turn the behavior off by unsetting the variable or setting it to an empty value. These variables work that way:

122 

123 * `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`

124 * `DISABLE_TELEMETRY`

125 * `DISABLE_ERROR_REPORTING`

126 * `CLAUDE_CODE_TMUX_TRUECOLOR`

127 * `FALLBACK_FOR_ALL_PRIMARY_MODELS`

128 * `IS_DEMO`

129 

130 One other variable has its own rule: `FORCE_HYPERLINK` reads a number, so only `0` turns it off. Each variable's row also states its own rule.

131</Note>

132 

118| Variable | Purpose |133| Variable | Purpose |

119| :------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |134| :------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

120| `ANTHROPIC_API_KEY` | API key sent as `X-Api-Key` header. When set, this key is used instead of your Claude Pro, Max, Team, or Enterprise subscription even if you are logged in. In non-interactive mode (`-p`), the key is always used when present. In interactive mode, you are prompted to approve the key once before it overrides your subscription. To use your subscription instead, run `unset ANTHROPIC_API_KEY` |135| `ANTHROPIC_API_KEY` | API key sent as `X-Api-Key` header. When set, this key is used instead of your Claude Pro, Max, Team, or Enterprise subscription even if you are logged in. In non-interactive mode (`-p`), the key is always used when present. In interactive mode, you are prompted to approve the key once before it overrides your subscription. To use your subscription instead, run `unset ANTHROPIC_API_KEY` |


131| `ANTHROPIC_CUSTOM_MODEL_OPTION` | Model ID to add as a custom entry in the `/model` picker. Use this to make a non-standard or gateway-specific model selectable without replacing built-in aliases. See [Model configuration](/docs/en/model-config#add-a-custom-model-option) |146| `ANTHROPIC_CUSTOM_MODEL_OPTION` | Model ID to add as a custom entry in the `/model` picker. Use this to make a non-standard or gateway-specific model selectable without replacing built-in aliases. See [Model configuration](/docs/en/model-config#add-a-custom-model-option) |

132| `ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION` | Display description for the custom model entry in the `/model` picker. Defaults to `Custom model (<model-id>)` when not set |147| `ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION` | Display description for the custom model entry in the `/model` picker. Defaults to `Custom model (<model-id>)` when not set |

133| `ANTHROPIC_CUSTOM_MODEL_OPTION_NAME` | Display name for the custom model entry in the `/model` picker. Defaults to the model ID when not set |148| `ANTHROPIC_CUSTOM_MODEL_OPTION_NAME` | Display name for the custom model entry in the `/model` picker. Defaults to the model ID when not set |

134| `ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |149| `ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES` | Comma-separated list of [capabilities](/docs/en/model-config#customize-pinned-model-display-and-capabilities) the custom model supports, for example `effort,thinking`. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

135| `ANTHROPIC_DEFAULT_FABLE_MODEL` | See [Model configuration](/docs/en/model-config#environment-variables) |150| `ANTHROPIC_DEFAULT_FABLE_MODEL` | Model ID that the `fable` alias resolves to, and the ID Claude Code recognizes as Fable 5 for [automatic model fallback](/docs/en/model-config#automatic-model-fallback) on third-party providers. See [Model configuration](/docs/en/model-config#environment-variables) |

136| `ANTHROPIC_DEFAULT_FABLE_MODEL_DESCRIPTION` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |151| `ANTHROPIC_DEFAULT_FABLE_MODEL_DESCRIPTION` | Display description for the pinned Fable model in the `/model` picker. Defaults to `Custom Fable model` when not set. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

137| `ANTHROPIC_DEFAULT_FABLE_MODEL_NAME` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |152| `ANTHROPIC_DEFAULT_FABLE_MODEL_NAME` | Display name for the pinned Fable model in the `/model` picker. Defaults to the model ID when not set. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

138| `ANTHROPIC_DEFAULT_FABLE_MODEL_SUPPORTED_CAPABILITIES` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |153| `ANTHROPIC_DEFAULT_FABLE_MODEL_SUPPORTED_CAPABILITIES` | Comma-separated list of [capabilities](/docs/en/model-config#customize-pinned-model-display-and-capabilities) the pinned Fable model supports, for example `effort,thinking`. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

139| `ANTHROPIC_DEFAULT_HAIKU_MODEL` | See [Model configuration](/docs/en/model-config#environment-variables) |154| `ANTHROPIC_DEFAULT_HAIKU_MODEL` | Model ID that the `haiku` alias resolves to, also used for [background functionality](/docs/en/costs#background-token-usage). See [Model configuration](/docs/en/model-config#environment-variables) |

140| `ANTHROPIC_DEFAULT_HAIKU_MODEL_DESCRIPTION` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |155| `ANTHROPIC_DEFAULT_HAIKU_MODEL_DESCRIPTION` | Display description for the pinned Haiku model in the `/model` picker. Defaults to `Custom Haiku model` when not set. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

141| `ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |156| `ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME` | Display name for the pinned Haiku model in the `/model` picker. Defaults to the model ID when not set. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

142| `ANTHROPIC_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |157| `ANTHROPIC_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES` | Comma-separated list of [capabilities](/docs/en/model-config#customize-pinned-model-display-and-capabilities) the pinned Haiku model supports, for example `effort,thinking`. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

143| `ANTHROPIC_DEFAULT_OPUS_MODEL` | See [Model configuration](/docs/en/model-config#environment-variables) |158| `ANTHROPIC_DEFAULT_OPUS_MODEL` | Model ID that the `opus` alias resolves to, and that `opusplan` uses while Plan Mode is active. See [Model configuration](/docs/en/model-config#environment-variables) |

144| `ANTHROPIC_DEFAULT_OPUS_MODEL_DESCRIPTION` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |159| `ANTHROPIC_DEFAULT_OPUS_MODEL_DESCRIPTION` | Display description for the pinned Opus model in the `/model` picker. When not set, defaults to `Custom Opus model`, or `Custom Opus model (1M context)` if the pinned model ID has the `[1m]` suffix and `CLAUDE_CODE_DISABLE_1M_CONTEXT` isn't turned on. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

145| `ANTHROPIC_DEFAULT_OPUS_MODEL_NAME` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |160| `ANTHROPIC_DEFAULT_OPUS_MODEL_NAME` | Display name for the pinned Opus model in the `/model` picker. Defaults to the model ID when not set. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

146| `ANTHROPIC_DEFAULT_OPUS_MODEL_SUPPORTED_CAPABILITIES` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |161| `ANTHROPIC_DEFAULT_OPUS_MODEL_SUPPORTED_CAPABILITIES` | Comma-separated list of [capabilities](/docs/en/model-config#customize-pinned-model-display-and-capabilities) the pinned Opus model supports, for example `effort,thinking`. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

147| `ANTHROPIC_DEFAULT_SONNET_MODEL` | See [Model configuration](/docs/en/model-config#environment-variables) |162| `ANTHROPIC_DEFAULT_SONNET_MODEL` | Model ID that the `sonnet` alias resolves to, and that `opusplan` uses when Plan Mode is not active. See [Model configuration](/docs/en/model-config#environment-variables) |

148| `ANTHROPIC_DEFAULT_SONNET_MODEL_DESCRIPTION` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |163| `ANTHROPIC_DEFAULT_SONNET_MODEL_DESCRIPTION` | Display description for the pinned Sonnet model in the `/model` picker. When not set, defaults to `Custom Sonnet model`, or `Custom Sonnet model (1M context)` if the pinned model ID has the `[1m]` suffix and `CLAUDE_CODE_DISABLE_1M_CONTEXT` isn't turned on. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

149| `ANTHROPIC_DEFAULT_SONNET_MODEL_NAME` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |164| `ANTHROPIC_DEFAULT_SONNET_MODEL_NAME` | Display name for the pinned Sonnet model in the `/model` picker. Defaults to the model ID when not set. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

150| `ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES` | See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |165| `ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES` | Comma-separated list of [capabilities](/docs/en/model-config#customize-pinned-model-display-and-capabilities) the pinned Sonnet model supports, for example `effort,thinking`. See [Model configuration](/docs/en/model-config#customize-pinned-model-display-and-capabilities) |

151| `ANTHROPIC_FOUNDRY_API_KEY` | API key for Microsoft Foundry authentication (see [Microsoft Foundry](/docs/en/microsoft-foundry)) |166| `ANTHROPIC_FOUNDRY_API_KEY` | API key for Microsoft Foundry authentication (see [Microsoft Foundry](/docs/en/microsoft-foundry)) |

152| `ANTHROPIC_FOUNDRY_AUTH_TOKEN` | {/* min-version: 2.1.203 */}Bearer token for Microsoft Foundry authentication, such as a Microsoft Entra access token. Claude Code sends it as the `Authorization: Bearer` header. Takes precedence over `ANTHROPIC_FOUNDRY_API_KEY` and over the Azure default credential chain. See [Microsoft Foundry](/docs/en/microsoft-foundry). Requires Claude Code v2.1.203 or later |167| `ANTHROPIC_FOUNDRY_AUTH_TOKEN` | {/* min-version: 2.1.203 */}Bearer token for Microsoft Foundry authentication, such as a Microsoft Entra access token. Claude Code sends it as the `Authorization: Bearer` header. Takes precedence over `ANTHROPIC_FOUNDRY_API_KEY` and over the Azure default credential chain. See [Microsoft Foundry](/docs/en/microsoft-foundry). Requires Claude Code v2.1.203 or later |

153| `ANTHROPIC_FOUNDRY_BASE_URL` | Full base URL for the Microsoft Foundry resource (for example, `https://my-resource.services.ai.azure.com/anthropic`). Alternative to `ANTHROPIC_FOUNDRY_RESOURCE` (see [Microsoft Foundry](/docs/en/microsoft-foundry)) |168| `ANTHROPIC_FOUNDRY_BASE_URL` | Full base URL for the Microsoft Foundry resource (for example, `https://my-resource.services.ai.azure.com/anthropic`). Alternative to `ANTHROPIC_FOUNDRY_RESOURCE` (see [Microsoft Foundry](/docs/en/microsoft-foundry)) |


219| `CLAUDE_CODE_DISABLE_LEGACY_MODEL_REMAP` | Set to `1` to prevent automatic remapping of Opus 4.0 and 4.1 to the current Opus version on the Anthropic API. Use when you intentionally want to pin an older model. The remap does not run on Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry |234| `CLAUDE_CODE_DISABLE_LEGACY_MODEL_REMAP` | Set to `1` to prevent automatic remapping of Opus 4.0 and 4.1 to the current Opus version on the Anthropic API. Use when you intentionally want to pin an older model. The remap does not run on Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry |

220| `CLAUDE_CODE_DISABLE_MOUSE` | Set to `1` to disable mouse tracking in [fullscreen rendering](/docs/en/fullscreen). Keyboard scrolling with `PgUp` and `PgDn` still works. Use this to keep your terminal's native copy-on-select behavior |235| `CLAUDE_CODE_DISABLE_MOUSE` | Set to `1` to disable mouse tracking in [fullscreen rendering](/docs/en/fullscreen). Keyboard scrolling with `PgUp` and `PgDn` still works. Use this to keep your terminal's native copy-on-select behavior |

221| `CLAUDE_CODE_DISABLE_MOUSE_CLICKS` | {/* min-version: 2.1.195 */}Set to `1` to disable click, drag, and hover handling in [fullscreen rendering](/docs/en/fullscreen) while keeping mouse-wheel scrolling. Use this when you want wheel scroll to work inside Claude Code but don't want clicks to position the cursor, expand tool output, or open links. `CLAUDE_CODE_DISABLE_MOUSE` takes precedence when both are set. Requires Claude Code v2.1.195 or later |236| `CLAUDE_CODE_DISABLE_MOUSE_CLICKS` | {/* min-version: 2.1.195 */}Set to `1` to disable click, drag, and hover handling in [fullscreen rendering](/docs/en/fullscreen) while keeping mouse-wheel scrolling. Use this when you want wheel scroll to work inside Claude Code but don't want clicks to position the cursor, expand tool output, or open links. `CLAUDE_CODE_DISABLE_MOUSE` takes precedence when both are set. Requires Claude Code v2.1.195 or later |

222| `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` | Set to any non-empty value to disable nonessential network traffic: auto-updates, telemetry, error reporting, the `/feedback` command, release notes, [gateway model discovery](/docs/en/llm-gateway-connect#add-gateway-models-to-the-model-picker) refreshes, and availability checks such as the [fast mode](/docs/en/fast-mode#use-fast-mode-behind-proxies-and-llm-gateways) check. Also disables feature-flag fetching, which makes [Remote Control](/docs/en/remote-control#requirements) unavailable. Official plugin marketplace auto-install isn't covered; disable it with `CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL` |237| `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` | Set to any non-empty value, such as `1`, to disable nonessential network traffic: auto-updates, telemetry, error reporting, the `/feedback` command, release notes, [gateway model discovery](/docs/en/llm-gateway-connect#add-gateway-models-to-the-model-picker) refreshes, and availability checks such as the [fast mode](/docs/en/fast-mode#use-fast-mode-behind-proxies-and-llm-gateways) check. **Setting it to `0` or `false` still disables this traffic**, unlike most on/off variables; unset the variable to allow it again. Also disables feature-flag fetching, which makes [Remote Control](/docs/en/remote-control#requirements) unavailable. Official plugin marketplace auto-install isn't covered; disable it with `CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL` |

223| `CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK` | Set to `1` to disable the non-streaming fallback when a streaming request fails mid-stream. Streaming errors propagate to the retry layer instead. Useful when a proxy or gateway causes the fallback to produce duplicate tool execution |238| `CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK` | Set to `1` to disable the non-streaming fallback when a streaming request fails mid-stream. Streaming errors propagate to the retry layer instead. Useful when a proxy or gateway causes the fallback to produce duplicate tool execution |

224| `CLAUDE_CODE_DISABLE_NOTIFICATION_PRESENCE_CHECK` | {/* min-version: 2.1.193 */}Set to `1` to send the `PushNotification` tool's desktop notification even while you are typing in or focused on the terminal. By default the tool skips both the desktop notification and the [mobile push](/docs/en/remote-control#mobile-push-notifications) when it detects recent keyboard activity or terminal focus. This variable disables only that local check, so the server can still suppress the mobile push when it detects that you are active. Requires Claude Code v2.1.193 or later |239| `CLAUDE_CODE_DISABLE_NOTIFICATION_PRESENCE_CHECK` | {/* min-version: 2.1.193 */}Set to `1` to send the `PushNotification` tool's desktop notification even while you are typing in or focused on the terminal. By default the tool skips both the desktop notification and the [mobile push](/docs/en/remote-control#mobile-push-notifications) when it detects recent keyboard activity or terminal focus. This variable disables only that local check, so the server can still suppress the mobile push when it detects that you are active. Requires Claude Code v2.1.193 or later |

225| `CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL` | Set to `1` to skip automatic addition of the official plugin marketplace on first run |240| `CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL` | Set to `1` to skip automatic addition of the official plugin marketplace on first run |


259| `CLAUDE_CODE_IDE_SKIP_VALID_CHECK` | Set to `1` to skip validation of IDE lockfile entries during connection. Use when auto-connect fails to find your IDE despite it running |274| `CLAUDE_CODE_IDE_SKIP_VALID_CHECK` | Set to `1` to skip validation of IDE lockfile entries during connection. Use when auto-connect fails to find your IDE despite it running |

260| `CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS` | {/* min-version: 2.1.217 */}How many [subagents](/docs/en/sub-agents#concurrent-subagent-limit) can be running in one session before the Agent tool refuses to spawn another (default: 20). Accepts a positive whole number in plain digits; anything else is ignored, so the variable can adjust the cap but can't disable it. Requires Claude Code v2.1.217 or later |275| `CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS` | {/* min-version: 2.1.217 */}How many [subagents](/docs/en/sub-agents#concurrent-subagent-limit) can be running in one session before the Agent tool refuses to spawn another (default: 20). Accepts a positive whole number in plain digits; anything else is ignored, so the variable can adjust the cap but can't disable it. Requires Claude Code v2.1.217 or later |

261| `CLAUDE_CODE_MAX_CONTEXT_TOKENS` | Override the context window size Claude Code assumes for the active model. {/* min-version: 2.1.193 */}As of v2.1.193, applied directly for model names Claude Code does not recognize as a Claude model; for recognized Claude models it only takes effect when `DISABLE_COMPACT` is also set. Use this when routing to a model through `ANTHROPIC_BASE_URL` whose context window does not match the built-in size for its name |276| `CLAUDE_CODE_MAX_CONTEXT_TOKENS` | Override the context window size Claude Code assumes for the active model. {/* min-version: 2.1.193 */}As of v2.1.193, applied directly for model names Claude Code does not recognize as a Claude model; for recognized Claude models it only takes effect when `DISABLE_COMPACT` is also set. Use this when routing to a model through `ANTHROPIC_BASE_URL` whose context window does not match the built-in size for its name |

262| `CLAUDE_CODE_MAX_OUTPUT_TOKENS` | Set the maximum number of output tokens for most requests. Defaults and caps vary by model; see [max output tokens](https://platform.claude.com/docs/en/about-claude/models/overview#latest-models-comparison). Increasing this value reduces the effective context window available before [auto-compaction](/docs/en/costs#reduce-token-usage) triggers |277| `CLAUDE_CODE_MAX_OUTPUT_TOKENS` | Set the maximum number of output tokens for most requests. Defaults and caps vary by model; see [max output tokens](https://platform.claude.com/docs/en/about-claude/models/overview#latest-models-comparison). Claude Code defaults to 32000 for model IDs it doesn't recognize, such as gateway-specific names, and lowers values above a model's cap to the cap. Increasing this value reduces the effective context window available before [auto-compaction](/docs/en/costs#reduce-token-usage) triggers |

263| `CLAUDE_CODE_MAX_RETRIES` | Override the number of times to retry failed API requests (default: 10). {/* min-version: 2.1.186 */}Capped at 15 as of v2.1.186; {/* min-version: 2.1.199 */}as of v2.1.199, `CLAUDE_CODE_RETRY_WATCHDOG` raises the default and removes the cap. For unattended sessions that need to wait through longer outages, set `CLAUDE_CODE_RETRY_WATCHDOG` instead |278| `CLAUDE_CODE_MAX_RETRIES` | Override the number of times to retry failed API requests (default: 10). {/* min-version: 2.1.186 */}Capped at 15 as of v2.1.186; {/* min-version: 2.1.199 */}as of v2.1.199, `CLAUDE_CODE_RETRY_WATCHDOG` raises the default and removes the cap. For unattended sessions that need to wait through longer outages, set `CLAUDE_CODE_RETRY_WATCHDOG` instead |

264| `CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION` | {/* min-version: 2.1.212 */}Cap on the number of [subagents](/docs/en/sub-agents#session-subagent-limit) one session can spawn with the Agent tool (default: 200). When Claude reaches the cap, spawning another subagent fails with an error telling Claude to finish the remaining work directly. Accepts a positive whole number in plain digits with no upper bound; this variable doesn't take the scientific notation or digit-separator spellings. Anything else is ignored and the default applies, so the cap can be raised but not turned off. Requires Claude Code v2.1.212 or later |279| `CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION` | {/* min-version: 2.1.212 */}Cap on the number of [subagents](/docs/en/sub-agents#session-subagent-limit) one session can spawn with the Agent tool (default: 200). When Claude reaches the cap, spawning another subagent fails with an error telling Claude to finish the remaining work directly. Accepts a positive whole number in plain digits with no upper bound; this variable doesn't take the scientific notation or digit-separator spellings. Anything else is ignored and the default applies, so the cap can be raised but not turned off. Requires Claude Code v2.1.212 or later |

265| `CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH` | {/* min-version: 2.1.217 */}Number of [subagent layers](/docs/en/sub-agents#let-subagents-spawn-their-own-subagents) allowed below the main conversation {/* min-version: 2.1.219 */}(default: 3). At the default, subagents can spawn their own subagents, and a subagent at the third layer can't spawn further; set `1` to turn nesting off. In v2.1.217 through v2.1.218, the default was 1, so a subagent couldn't spawn its own unless you raised the limit; v2.1.219 raised the default to 3. Accepts a positive whole number in plain digits; anything else is ignored, so the limit can be adjusted but not removed. Requires Claude Code v2.1.217 or later |280| `CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH` | {/* min-version: 2.1.217 */}Number of [subagent layers](/docs/en/sub-agents#let-subagents-spawn-their-own-subagents) allowed below the main conversation {/* min-version: 2.1.219 */}(default: 3). At the default, subagents can spawn their own subagents, and a subagent at the third layer can't spawn further; set `1` to turn nesting off. In v2.1.217 through v2.1.218, the default was 1, so a subagent couldn't spawn its own unless you raised the limit; v2.1.219 raised the default to 3. Accepts a positive whole number in plain digits; anything else is ignored, so the limit can be adjusted but not removed. Requires Claude Code v2.1.217 or later |


296| `CLAUDE_CODE_PROXY_RESOLVES_HOSTS` | Set to `1` to allow the proxy to perform DNS resolution instead of the caller. Opt-in for environments where the proxy should handle hostname resolution |311| `CLAUDE_CODE_PROXY_RESOLVES_HOSTS` | Set to `1` to allow the proxy to perform DNS resolution instead of the caller. Opt-in for environments where the proxy should handle hostname resolution |

297| `CLAUDE_CODE_REMOTE` | Set automatically to `true` when Claude Code is running as a [cloud session](/docs/en/claude-code-on-the-web). Read this from a hook or setup script to detect whether you are in a cloud session |312| `CLAUDE_CODE_REMOTE` | Set automatically to `true` when Claude Code is running as a [cloud session](/docs/en/claude-code-on-the-web). Read this from a hook or setup script to detect whether you are in a cloud session |

298| `CLAUDE_CODE_REMOTE_SESSION_ID` | Set automatically in [cloud sessions](/docs/en/claude-code-on-the-web) to the current session's ID. Read this to construct a link back to the session transcript. See [Link output back to the session](/docs/en/cloud-environments#link-output-back-to-the-session) |313| `CLAUDE_CODE_REMOTE_SESSION_ID` | Set automatically in [cloud sessions](/docs/en/claude-code-on-the-web) to the current session's ID. Read this to construct a link back to the session transcript. See [Link output back to the session](/docs/en/cloud-environments#link-output-back-to-the-session) |

299| `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` | Set to `1` to automatically resume if the previous session ended mid-turn. Used in SDK mode so the model continues without requiring the SDK to re-send the prompt |314| `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` | Set to `1` to automatically resume if the previous session ended mid-turn. Used in SDK mode so the model continues without requiring the SDK to re-send the prompt. To turn this off, unset the variable, because setting it to `0` still triggers the resume in non-interactive mode |

300| `CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS` | {/* min-version: 2.1.211 */}Maximum age in milliseconds of the last transcript message for a session that ended mid-turn to continue automatically on resume. When the last message is older than this bound, Claude Code skips both the `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` automatic resume and the injected `CLAUDE_CODE_RESUME_PROMPT` continuation message, and the session starts idle so you continue explicitly. Unset or `0` means no bound; a negative or non-numeric value applies a one-hour bound. Spawn scripts for long-running agents can set this so a restart against an old transcript doesn't re-run a stale prompt. Claude Code sets a one-hour bound itself when it restarts a crashed [agent view](/docs/en/agent-view) session that inherited its conversation from an interactive session. Requires Claude Code v2.1.211 or later |315| `CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS` | {/* min-version: 2.1.211 */}Maximum age in milliseconds of the last transcript message for a session that ended mid-turn to continue automatically on resume. When the last message is older than this bound, Claude Code skips both the `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` automatic resume and the injected `CLAUDE_CODE_RESUME_PROMPT` continuation message, and the session starts idle so you continue explicitly. Unset or `0` means no bound; a negative or non-numeric value applies a one-hour bound. Spawn scripts for long-running agents can set this so a restart against an old transcript doesn't re-run a stale prompt. Claude Code sets a one-hour bound itself when it restarts a crashed [agent view](/docs/en/agent-view) session that inherited its conversation from an interactive session. Requires Claude Code v2.1.211 or later |

301| `CLAUDE_CODE_RESUME_PROMPT` | Override the continuation message injected when resuming a session that ended mid-turn. Defaults to `Continue from where you left off.`. Spawn scripts for long-running agents can set this to a more directive boot message. An empty string uses the default |316| `CLAUDE_CODE_RESUME_PROMPT` | Override the continuation message injected when resuming a session that ended mid-turn. Defaults to `Continue from where you left off.`. Spawn scripts for long-running agents can set this to a more directive boot message. An empty string uses the default |

302| `CLAUDE_CODE_RETRY_WATCHDOG` | {/* min-version: 2.1.186 */}Set to `1` for unattended sessions such as eval harnesses, CI jobs, or remote workers. Retries `429` and `529` capacity errors indefinitely instead of failing after `CLAUDE_CODE_MAX_RETRIES` attempts. The watchdog backs off up to 5 minutes between attempts, or until the limit resets when the response carries a rate-limit reset time, so a session that hits a usage limit waits out the remaining window. {/* min-version: 2.1.199 */}As of v2.1.199 it also raises the default retry count for other transient errors, such as server errors, timeouts, and dropped connections, to 300, roughly three hours of backoff, and removes the cap of 15 on `CLAUDE_CODE_MAX_RETRIES` if you set that variable explicitly. Requires Claude Code v2.1.186 or later |317| `CLAUDE_CODE_RETRY_WATCHDOG` | {/* min-version: 2.1.186 */}Set to `1` for unattended sessions such as eval harnesses, CI jobs, or remote workers. Retries `429` and `529` capacity errors indefinitely instead of failing after `CLAUDE_CODE_MAX_RETRIES` attempts. The watchdog backs off up to 5 minutes between attempts, or until the limit resets when the response carries a rate-limit reset time, so a session that hits a usage limit waits out the remaining window. {/* min-version: 2.1.199 */}As of v2.1.199 it also raises the default retry count for other transient errors, such as server errors, timeouts, and dropped connections, to 300, roughly three hours of backoff, and removes the cap of 15 on `CLAUDE_CODE_MAX_RETRIES` if you set that variable explicitly. Requires Claude Code v2.1.186 or later |


319| `CLAUDE_CODE_SKIP_PROMPT_HISTORY` | Set to `1` to skip writing prompt history and session transcripts to disk. Sessions started with this variable set do not appear in `--resume`, `--continue`, or up-arrow history. Useful for ephemeral scripted sessions |334| `CLAUDE_CODE_SKIP_PROMPT_HISTORY` | Set to `1` to skip writing prompt history and session transcripts to disk. Sessions started with this variable set do not appear in `--resume`, `--continue`, or up-arrow history. Useful for ephemeral scripted sessions |

320| `CLAUDE_CODE_SKIP_VERTEX_AUTH` | Skip Google authentication for Google Cloud's Agent Platform (for example, when using an LLM gateway) |335| `CLAUDE_CODE_SKIP_VERTEX_AUTH` | Skip Google authentication for Google Cloud's Agent Platform (for example, when using an LLM gateway) |

321| `CLAUDE_CODE_STOP_HOOK_BLOCK_CAP` | Maximum number of consecutive times a [Stop](/docs/en/hooks#stop) or [SubagentStop](/docs/en/hooks#subagentstop) hook may block the turn from ending before Claude Code overrides it and ends the turn anyway (default: 8). Set to `0` to disable the cap. Raise this if your hook legitimately needs more iterations to resolve |336| `CLAUDE_CODE_STOP_HOOK_BLOCK_CAP` | Maximum number of consecutive times a [Stop](/docs/en/hooks#stop) or [SubagentStop](/docs/en/hooks#subagentstop) hook may block the turn from ending before Claude Code overrides it and ends the turn anyway (default: 8). Set to `0` to disable the cap. Raise this if your hook legitimately needs more iterations to resolve |

322| `CLAUDE_CODE_SUBAGENT_MODEL` | See [Model configuration](/docs/en/model-config). {/* min-version: 2.1.196 */}As of v2.1.196, setting it to `inherit` is the same as leaving it unset; earlier versions treated `inherit` as an override that forced every subagent onto the main conversation's model |337| `CLAUDE_CODE_SUBAGENT_MODEL` | The model Claude Code uses for all [subagents](/docs/en/sub-agents#choose-a-model), [agent teams](/docs/en/agent-teams), and agents in a [workflow](/docs/en/workflows). Accepts an alias such as `haiku` or a full model name, and takes precedence over the per-invocation `model` parameter and the subagent definition's `model` frontmatter. See [Model configuration](/docs/en/model-config#environment-variables). {/* min-version: 2.1.196 */}Setting it to `inherit` is the same as leaving it unset; before v2.1.196, `inherit` was an override that forced every subagent onto the main conversation's model |

323| `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` | Set to `1` to strip Anthropic and cloud provider credentials from subprocess environments (Bash tool, hooks, MCP stdio servers). The parent Claude process keeps these credentials for API calls, but child processes cannot read them, reducing exposure to prompt injection attacks that attempt to exfiltrate secrets via shell expansion. On Linux, this also runs Bash subprocesses in an isolated PID namespace so they cannot read host process environments via `/proc`; as a side effect, `ps`, `pgrep`, and `kill` cannot see or signal host processes. `claude-code-action` sets this automatically when `allowed_non_write_users` is configured |338| `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` | Set to `1` to strip Anthropic and cloud provider credentials from subprocess environments (Bash tool, hooks, MCP stdio servers). The parent Claude process keeps these credentials for API calls, but child processes cannot read them, reducing exposure to prompt injection attacks that attempt to exfiltrate secrets via shell expansion. On Linux, this also runs Bash subprocesses in an isolated PID namespace so they cannot read host process environments via `/proc`; as a side effect, `ps`, `pgrep`, and `kill` cannot see or signal host processes. `claude-code-action` sets this automatically when `allowed_non_write_users` is configured |

324| `CLAUDE_CODE_SYNC_PLUGIN_INSTALL` | Set to `1` in non-interactive mode (the `-p` flag) to wait for plugin installation to complete before the first query. Without this, plugins install in the background and may not be available on the first turn. Combine with `CLAUDE_CODE_SYNC_PLUGIN_INSTALL_TIMEOUT_MS` to bound the wait |339| `CLAUDE_CODE_SYNC_PLUGIN_INSTALL` | Set to `1` in non-interactive mode (the `-p` flag) to wait for plugin installation to complete before the first query. Without this, plugins install in the background and may not be available on the first turn. Combine with `CLAUDE_CODE_SYNC_PLUGIN_INSTALL_TIMEOUT_MS` to bound the wait |

325| `CLAUDE_CODE_SYNC_PLUGIN_INSTALL_TIMEOUT_MS` | Timeout in milliseconds for synchronous plugin installation. When exceeded, Claude Code proceeds without plugins and logs an error. No default: without this variable, synchronous installation waits until complete |340| `CLAUDE_CODE_SYNC_PLUGIN_INSTALL_TIMEOUT_MS` | Timeout in milliseconds for synchronous plugin installation. When exceeded, Claude Code proceeds without plugins and logs an error. No default: without this variable, synchronous installation waits until complete |


330| `CLAUDE_CODE_TASK_LIST_ID` | Share a task list across sessions. Set the same ID in multiple Claude Code instances to coordinate on a shared task list. See [Task list](/docs/en/interactive-mode#task-list) |345| `CLAUDE_CODE_TASK_LIST_ID` | Share a task list across sessions. Set the same ID in multiple Claude Code instances to coordinate on a shared task list. See [Task list](/docs/en/interactive-mode#task-list) |

331| `CLAUDE_CODE_TEAM_TEARDOWN_PARK_TIMEOUT_MS` | {/* min-version: 2.1.206 */}Override, in milliseconds, how long a non-interactive session waits at exit for its [agent team](/docs/en/agent-teams) to finish tearing down. Accepts 1000 to 60000; an out-of-range value is ignored and the default of 10000 applies. Requires Claude Code v2.1.206 or later |346| `CLAUDE_CODE_TEAM_TEARDOWN_PARK_TIMEOUT_MS` | {/* min-version: 2.1.206 */}Override, in milliseconds, how long a non-interactive session waits at exit for its [agent team](/docs/en/agent-teams) to finish tearing down. Accepts 1000 to 60000; an out-of-range value is ignored and the default of 10000 applies. Requires Claude Code v2.1.206 or later |

332| `CLAUDE_CODE_TMPDIR` | Override the temp directory used for internal temp files. Claude Code appends `/claude-{uid}/` on Unix or `/claude/` on Windows to this path. Default: `/tmp` on macOS, `os.tmpdir()` on Linux and Windows. {/* min-version: 2.1.161 */}As of v2.1.161, on macOS and Linux, [sandboxed](/docs/en/sandboxing) Bash subprocesses receive a short fallback `$TMPDIR` under the system default when your override is a long path, since some tools fail when temp paths get too long. Unsandboxed Bash commands inherit your shell's `$TMPDIR` unchanged. Claude Code's own temp files always use your override |347| `CLAUDE_CODE_TMPDIR` | Override the temp directory used for internal temp files. Claude Code appends `/claude-{uid}/` on Unix or `/claude/` on Windows to this path. Default: `/tmp` on macOS, `os.tmpdir()` on Linux and Windows. {/* min-version: 2.1.161 */}As of v2.1.161, on macOS and Linux, [sandboxed](/docs/en/sandboxing) Bash subprocesses receive a short fallback `$TMPDIR` under the system default when your override is a long path, since some tools fail when temp paths get too long. Unsandboxed Bash commands inherit your shell's `$TMPDIR` unchanged. Claude Code's own temp files always use your override |

333| `CLAUDE_CODE_TMUX_TRUECOLOR` | Set to `1` to allow 24-bit truecolor output inside tmux. By default, Claude Code clamps to 256 colors when `$TMUX` is set because tmux does not pass through truecolor escape sequences unless configured to. Set this after adding `set -ga terminal-overrides ',*:Tc'` to your `~/.tmux.conf`. See [Terminal configuration](/docs/en/terminal-config) for other tmux settings |348| `CLAUDE_CODE_TMUX_TRUECOLOR` | Set to any non-empty value, such as `1`, to allow 24-bit truecolor output inside tmux. **Setting it to `0` or `false` still allows truecolor**, unlike most on/off variables; unset the variable to restore the 256-color clamp. By default, Claude Code clamps to 256 colors when `$TMUX` is set because tmux does not pass through truecolor escape sequences unless configured to. Set this after adding `set -ga terminal-overrides ',*:Tc'` to your `~/.tmux.conf`. See [Terminal configuration](/docs/en/terminal-config) for other tmux settings |

334| `CLAUDE_CODE_USE_ANTHROPIC_AWS` | Use [Claude Platform on AWS](/docs/en/claude-platform-on-aws) |349| `CLAUDE_CODE_USE_ANTHROPIC_AWS` | Use [Claude Platform on AWS](/docs/en/claude-platform-on-aws) |

335| `CLAUDE_CODE_USE_BEDROCK` | Use [Amazon Bedrock](/docs/en/amazon-bedrock) |350| `CLAUDE_CODE_USE_BEDROCK` | Use [Amazon Bedrock](/docs/en/amazon-bedrock) |

336| `CLAUDE_CODE_USE_FOUNDRY` | Use [Microsoft Foundry](/docs/en/microsoft-foundry) |351| `CLAUDE_CODE_USE_FOUNDRY` | Use [Microsoft Foundry](/docs/en/microsoft-foundry) |


354| `DISABLE_COMPACT` | Set to `1` to disable all compaction: both automatic compaction and the manual `/compact` command |369| `DISABLE_COMPACT` | Set to `1` to disable all compaction: both automatic compaction and the manual `/compact` command |

355| `DISABLE_COST_WARNINGS` | Set to `1` to disable cost warning messages |370| `DISABLE_COST_WARNINGS` | Set to `1` to disable cost warning messages |

356| `DISABLE_DOCTOR_COMMAND` | Set to `1` to hide the [`/doctor`](/docs/en/commands#all-commands) setup checkup skill and its `/checkup` alias. Useful for managed deployments where users shouldn't run setup diagnostics from a session. Doesn't affect the `claude doctor` terminal command. {/* min-version: 2.1.205 */}Before v2.1.205, this variable hid the `/doctor` diagnostics screen command |371| `DISABLE_DOCTOR_COMMAND` | Set to `1` to hide the [`/doctor`](/docs/en/commands#all-commands) setup checkup skill and its `/checkup` alias. Useful for managed deployments where users shouldn't run setup diagnostics from a session. Doesn't affect the `claude doctor` terminal command. {/* min-version: 2.1.205 */}Before v2.1.205, this variable hid the `/doctor` diagnostics screen command |

357| `DISABLE_ERROR_REPORTING` | Set to `1` to opt out of error reporting |372| `DISABLE_ERROR_REPORTING` | Set to any non-empty value, such as `1`, to opt out of error reporting. **Setting it to `0` or `false` still opts out**, unlike most on/off variables; unset the variable to turn error reporting back on |

358| `DISABLE_EXTRA_USAGE_COMMAND` | Set to `1` to hide the `/usage-credits` command that lets users purchase additional usage beyond rate limits |373| `DISABLE_EXTRA_USAGE_COMMAND` | Set to `1` to hide the `/usage-credits` command that lets users purchase additional usage beyond rate limits |

359| `DISABLE_FEEDBACK_COMMAND` | Set to `1` to disable the `/feedback` command. {/* min-version: 2.1.212 */}Also disables `/bug` and `/share`, which report through the same path; before v2.1.212 they were aliases of `/feedback`, so the command was disabled under every name. The older name `DISABLE_BUG_COMMAND` is also accepted |374| `DISABLE_FEEDBACK_COMMAND` | Set to `1` to disable the `/feedback` command. {/* min-version: 2.1.212 */}Also disables `/bug` and `/share`, which report through the same path; before v2.1.212 they were aliases of `/feedback`, so the command was disabled under every name. The older name `DISABLE_BUG_COMMAND` is also accepted |

360| `DISABLE_GROWTHBOOK` | Set to `1` to disable GrowthBook feature-flag fetching and use code defaults for every flag. This makes [Remote Control](/docs/en/remote-control#requirements) unavailable. Telemetry event logging stays on unless `DISABLE_TELEMETRY` is also set |375| `DISABLE_GROWTHBOOK` | Set to `1` to disable GrowthBook feature-flag fetching and use code defaults for every flag. This makes [Remote Control](/docs/en/remote-control#requirements) unavailable. Telemetry event logging stays on unless `DISABLE_TELEMETRY` is also set |


368| `DISABLE_PROMPT_CACHING_HAIKU` | Set to `1` to disable prompt caching for Haiku models |383| `DISABLE_PROMPT_CACHING_HAIKU` | Set to `1` to disable prompt caching for Haiku models |

369| `DISABLE_PROMPT_CACHING_OPUS` | Set to `1` to disable prompt caching for Opus models |384| `DISABLE_PROMPT_CACHING_OPUS` | Set to `1` to disable prompt caching for Opus models |

370| `DISABLE_PROMPT_CACHING_SONNET` | Set to `1` to disable prompt caching for Sonnet models |385| `DISABLE_PROMPT_CACHING_SONNET` | Set to `1` to disable prompt caching for Sonnet models |

371| `DISABLE_TELEMETRY` | Set to `1` to opt out of telemetry. Telemetry events do not include user data like code, file paths, or bash commands. Also disables feature-flag fetching with the same effect as `DISABLE_GROWTHBOOK`, which makes [Remote Control](/docs/en/remote-control#requirements) unavailable |386| `DISABLE_TELEMETRY` | Set to any non-empty value, such as `1`, to opt out of telemetry. **Setting it to `0` or `false` still opts out**, unlike most on/off variables; unset the variable to turn telemetry back on. Telemetry events do not include user data like code, file paths, or bash commands. Also disables feature-flag fetching with the same effect as `DISABLE_GROWTHBOOK`, which makes [Remote Control](/docs/en/remote-control#requirements) unavailable |

372| `DISABLE_UPDATES` | Set to `1` to block all updates including manual `claude update` and `claude install`. Stricter than `DISABLE_AUTOUPDATER`. Use when distributing Claude Code through your own channels and users should not self-update |387| `DISABLE_UPDATES` | Set to `1` to block all updates including manual `claude update` and `claude install`. Stricter than `DISABLE_AUTOUPDATER`. Use when distributing Claude Code through your own channels and users should not self-update |

373| `DISABLE_UPGRADE_COMMAND` | Set to `1` to hide the `/upgrade` command |388| `DISABLE_UPGRADE_COMMAND` | Set to `1` to hide the `/upgrade` command |

374| `DO_NOT_TRACK` | Set to `1` to opt out of telemetry. Equivalent to setting `DISABLE_TELEMETRY`, including its effect of making [Remote Control](/docs/en/remote-control#requirements) unavailable. Claude Code honors this as the cross-tool convention recognized by many developer CLIs |389| `DO_NOT_TRACK` | Set to `1` to opt out of telemetry, with the same effect as `DISABLE_TELEMETRY`, including making [Remote Control](/docs/en/remote-control#requirements) unavailable. Claude Code reads this variable as a standard boolean, so `0` leaves telemetry on, and honors it as the cross-tool convention recognized by many developer CLIs |

375| `ENABLE_CLAUDEAI_MCP_SERVERS` | Set to `false` to disable [claude.ai MCP servers](/docs/en/mcp#use-mcp-servers-from-claude-ai) in Claude Code. Enabled by default for logged-in users. To disable per-project or per-org, set [`disableClaudeAiConnectors`](/docs/en/settings#available-settings) in settings instead |390| `ENABLE_CLAUDEAI_MCP_SERVERS` | Set to `false` to disable [claude.ai MCP servers](/docs/en/mcp#use-mcp-servers-from-claude-ai) in Claude Code. Enabled by default for logged-in users. To disable per-project or per-org, set [`disableClaudeAiConnectors`](/docs/en/settings#available-settings) in settings instead |

376| `ENABLE_PROMPT_CACHING_1H` | Set to `1` to request a 1-hour [prompt cache TTL](/docs/en/prompt-caching#cache-lifetime) instead of the default 5 minutes. Intended for API key, [Amazon Bedrock](/docs/en/amazon-bedrock), [Google Cloud's Agent Platform](/docs/en/google-vertex-ai), [Microsoft Foundry](/docs/en/microsoft-foundry), and [Claude Platform on AWS](/docs/en/claude-platform-on-aws) users. Subscription users within included usage receive 1-hour TTL automatically. 1-hour cache writes are billed at a higher rate |391| `ENABLE_PROMPT_CACHING_1H` | Set to `1` to request a 1-hour [prompt cache TTL](/docs/en/prompt-caching#cache-lifetime) instead of the default 5 minutes. Intended for API key, [Amazon Bedrock](/docs/en/amazon-bedrock), [Google Cloud's Agent Platform](/docs/en/google-vertex-ai), [Microsoft Foundry](/docs/en/microsoft-foundry), and [Claude Platform on AWS](/docs/en/claude-platform-on-aws) users. Subscription users within included usage receive 1-hour TTL automatically. 1-hour cache writes are billed at a higher rate |

377| `ENABLE_PROMPT_CACHING_1H_BEDROCK` | Deprecated. Use `ENABLE_PROMPT_CACHING_1H` instead |392| `ENABLE_PROMPT_CACHING_1H_BEDROCK` | Deprecated. Use `ENABLE_PROMPT_CACHING_1H` instead |

378| `ENABLE_TOOL_SEARCH` | Controls [MCP tool search](/docs/en/mcp#scale-with-mcp-tool-search). Unset: all MCP tools deferred by default, but loaded upfront on Google Cloud's Agent Platform, when `ANTHROPIC_BASE_URL` points to a non-first-party host, or on a Microsoft Foundry deployment hosted on Azure. Values: `true` (always defer and send the beta header, except on a Microsoft Foundry deployment hosted on Azure, where the server-side rejection still forces upfront loading; requests fail on Google Cloud's Agent Platform models earlier than Sonnet 4.5 or Opus 4.5, or on proxies that do not support `tool_reference`), `auto` (threshold mode: load upfront if tools fit within 10% of context), `auto:N` (custom threshold, e.g., `auto:5` for 5%), `false` (load all upfront). Ignored when `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS` is set, which forces all tools to load upfront |393| `ENABLE_TOOL_SEARCH` | Controls [MCP tool search](/docs/en/mcp#scale-with-mcp-tool-search). Unset: all MCP tools deferred by default, but loaded upfront on Google Cloud's Agent Platform, when `ANTHROPIC_BASE_URL` points to a non-first-party host, or on a Microsoft Foundry deployment hosted on Azure. Values: `true` (always defer and send the beta header, except on a Microsoft Foundry deployment hosted on Azure, where the server-side rejection still forces upfront loading; requests fail on Google Cloud's Agent Platform models earlier than Sonnet 4.5 or Opus 4.5, or on proxies that do not support `tool_reference`), `auto` (threshold mode: load upfront if tools fit within 10% of context), `auto:N` (custom threshold, e.g., `auto:5` for 5%), `false` (load all upfront). Ignored when `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS` is set, which forces all tools to load upfront |

379| `FALLBACK_FOR_ALL_PRIMARY_MODELS` | Set to any non-empty value to make all models, not only Opus, stop retrying with a repeated-overload error when no fallback model is configured. {/* min-version: 2.1.160 */}As of v2.1.160, a configured [fallback model chain](/docs/en/model-config#fallback-model-chains) triggers on repeated overload errors for any primary model, so this variable does not affect switching to a fallback model |394| `FALLBACK_FOR_ALL_PRIMARY_MODELS` | Set to any non-empty value, such as `1`, to make every model stop retrying with a repeated-overload error when no fallback model is configured. **Setting it to `0` or `false` still enables this**, unlike most on/off variables; unset the variable to restore the default retry behavior. Without it, models Claude Code recognizes as Opus, Fable 5, or Mythos models stop retrying this way when you authenticate with an API key or a [third-party provider](/docs/en/third-party-integrations) rather than a Claude subscription. {/* min-version: 2.1.160 */}As of v2.1.160, a configured [fallback model chain](/docs/en/model-config#fallback-model-chains) triggers on repeated overload errors for any primary model, so this variable does not affect switching to a fallback model |

380| `FORCE_AUTOUPDATE_PLUGINS` | Set to `1` to force plugin auto-updates even when the main auto-updater is disabled via `DISABLE_AUTOUPDATER` |395| `FORCE_AUTOUPDATE_PLUGINS` | Set to `1` to force plugin auto-updates even when the main auto-updater is disabled via `DISABLE_AUTOUPDATER` |

381| `FORCE_HYPERLINK` | Set to `1` to enable clickable OSC 8 hyperlinks when your terminal supports them but isn't auto-detected, or `0` to disable them |396| `FORCE_HYPERLINK` | Set to `1` to enable clickable OSC 8 hyperlinks when your terminal supports them but isn't auto-detected, or `0` to disable them. Claude Code parses this value as a number, not a boolean, so word spellings such as `false`, `no`, or `off` enable hyperlinks rather than disabling them |

382| `FORCE_PROMPT_CACHING_5M` | Set to `1` to force the 5-minute prompt cache TTL even when 1-hour TTL would otherwise apply. Overrides `ENABLE_PROMPT_CACHING_1H` |397| `FORCE_PROMPT_CACHING_5M` | Set to `1` to force the 5-minute prompt cache TTL even when 1-hour TTL would otherwise apply. Overrides `ENABLE_PROMPT_CACHING_1H` |

383| `HTTP_PROXY` | Specify HTTP proxy server for network connections |398| `HTTP_PROXY` | Specify HTTP proxy server for network connections |

384| `HTTPS_PROXY` | Specify HTTPS proxy server for network connections |399| `HTTPS_PROXY` | Specify HTTPS proxy server for network connections |

385| `IS_DEMO` | Set to `1` to enable demo mode: hides your email and organization name from the header and `/status` output, and skips onboarding. Useful when streaming or recording a session |400| `IS_DEMO` | Set to any non-empty value, such as `1`, to enable demo mode: hides your email and organization name from the header and `/status` output, and skips onboarding. **Setting it to `0` or `false` still enables demo mode**, unlike most on/off variables; unset the variable to turn it off. Useful when streaming or recording a session |

386| `MAX_MCP_OUTPUT_TOKENS` | Maximum number of tokens allowed in MCP tool responses. Claude Code displays a warning when output exceeds 10,000 tokens. Tools that declare [`anthropic/maxResultSizeChars`](/docs/en/mcp#raise-the-limit-for-a-specific-tool) use that character limit for text content instead, but image content from those tools is still subject to this variable (default: 25000) |401| `MAX_MCP_OUTPUT_TOKENS` | Maximum number of tokens allowed in MCP tool responses. Claude Code displays a warning when output exceeds 10,000 tokens. Tools that declare [`anthropic/maxResultSizeChars`](/docs/en/mcp#raise-the-limit-for-a-specific-tool) use that character limit for text content instead, but image content from those tools is still subject to this variable (default: 25000) |

387| `MAX_STRUCTURED_OUTPUT_RETRIES` | Number of times to retry when the model's response fails validation against the [`--json-schema`](/docs/en/cli-reference#cli-flags) in non-interactive mode (the `-p` flag). Defaults to 5 |402| `MAX_STRUCTURED_OUTPUT_RETRIES` | Number of times to retry when the model's response fails validation against the [`--json-schema`](/docs/en/cli-reference#cli-flags) in non-interactive mode (the `-p` flag). Defaults to 5 |

388| `MAX_THINKING_TOKENS` | Override the [extended thinking](https://platform.claude.com/docs/en/build-with-claude/extended-thinking) token budget. The ceiling is the model's [max output tokens](https://platform.claude.com/docs/en/about-claude/models/overview#latest-models-comparison) minus one. Set to `0` to disable thinking on the Anthropic API except on Fable 5, which cannot have thinking turned off. On [third-party providers](/docs/en/third-party-integrations), `0` omits the `thinking` parameter instead, and models with [adaptive reasoning](/docs/en/model-config#adjust-effort-level) may still think. For nonzero values on adaptive reasoning models, the budget is ignored unless adaptive reasoning is disabled via `CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING` |403| `MAX_THINKING_TOKENS` | Fixed token budget for [extended thinking](https://platform.claude.com/docs/en/build-with-claude/extended-thinking). Claude Code caps it at one token below the request's max output tokens and never below 1,024; see `CLAUDE_CODE_MAX_OUTPUT_TOKENS` for how that limit is set. When unset and thinking is enabled, models with [adaptive reasoning](/docs/en/model-config#adjust-effort-level) choose their own thinking depth, and other models use the cap. Set to `0` to disable thinking on the Anthropic API, except on Fable 5, which cannot have thinking turned off; on [third-party providers](/docs/en/third-party-integrations), `0` omits the `thinking` parameter instead. Nonzero values are ignored on adaptive reasoning models unless `CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING` is set |

389| `MCP_CLIENT_SECRET` | OAuth client secret for MCP servers that require [pre-configured credentials](/docs/en/mcp#use-pre-configured-oauth-credentials). Avoids the interactive prompt when adding a server with `--client-secret` |404| `MCP_CLIENT_SECRET` | OAuth client secret for MCP servers that require [pre-configured credentials](/docs/en/mcp#use-pre-configured-oauth-credentials). Avoids the interactive prompt when adding a server with `--client-secret` |

390| `MCP_CONNECTION_NONBLOCKING` | Controls whether startup waits for MCP servers to connect before the first query. {/* min-version: 2.1.142 */}As of Claude Code v2.1.142, MCP startup is non-blocking by default: servers connect in the background and their tools become available as they finish. Set to `0` to restore the blocking 5-second connection wait. Servers configured with [`alwaysLoad: true`](/docs/en/mcp#exempt-a-server-from-deferral) still block startup regardless, since their tools must be present when the first prompt is built |405| `MCP_CONNECTION_NONBLOCKING` | Controls whether startup waits for MCP servers to connect before the first query. {/* min-version: 2.1.142 */}As of Claude Code v2.1.142, MCP startup is non-blocking by default: servers connect in the background and their tools become available as they finish. Set to `0` to restore the blocking 5-second connection wait. Servers configured with [`alwaysLoad: true`](/docs/en/mcp#exempt-a-server-from-deferral) still block startup regardless, since their tools must be present when the first prompt is built |

391| `MCP_CONNECT_TIMEOUT_MS` | How long blocking MCP startup waits, in milliseconds, for the connection batch before snapshotting the tool list (default: 5000). Applies when `MCP_CONNECTION_NONBLOCKING=0` or for servers marked [`alwaysLoad: true`](/docs/en/mcp#exempt-a-server-from-deferral). Servers still pending at the deadline keep connecting in the background but won't appear until the next query. Distinct from `MCP_TIMEOUT`, which bounds an individual server's connect attempt |406| `MCP_CONNECT_TIMEOUT_MS` | How long blocking MCP startup waits, in milliseconds, for the connection batch before snapshotting the tool list (default: 5000). Applies when `MCP_CONNECTION_NONBLOCKING=0` or for servers marked [`alwaysLoad: true`](/docs/en/mcp#exempt-a-server-from-deferral). Servers still pending at the deadline keep connecting in the background but won't appear until the next query. Distinct from `MCP_TIMEOUT`, which bounds an individual server's connect attempt |

errors.md +20 −1

Details

109| `Claude Code process exited with code N` | [Wrapper and IDE errors](#claude-code-process-exited-with-code-n) |109| `Claude Code process exited with code N` | [Wrapper and IDE errors](#claude-code-process-exited-with-code-n) |

110| `Restored the code, but skipped N files` | [Rewind warnings](#restored-the-code-but-skipped-files) |110| `Restored the code, but skipped N files` | [Rewind warnings](#restored-the-code-but-skipped-files) |

111| `Ignoring N permissions.allow entries from ... this workspace has not been trusted` | [Configuration warnings](#workspace-has-not-been-trusted) |111| `Ignoring N permissions.allow entries from ... this workspace has not been trusted` | [Configuration warnings](#workspace-has-not-been-trusted) |

112| `... is not matched by file permission checks` | [Configuration warnings](#is-not-matched-by-file-permission-checks) |

112| Responses seem lower quality than usual | [Response quality](#responses-seem-lower-quality-than-usual) |113| Responses seem lower quality than usual | [Response quality](#responses-seem-lower-quality-than-usual) |

113 114 

114## Automatic retries115## Automatic retries


1605 1606 

1606## Configuration warnings1607## Configuration warnings

1607 1608 

1608Claude Code writes these messages to stderr at startup rather than showing an error in the conversation. They report configuration it read but didn't apply.1609Claude Code writes these messages to stderr at startup rather than showing an error in the conversation, except where an entry notes that it writes the message to the debug log instead. They report configuration it read but didn't apply.

1609 1610 

1610### Workspace has not been trusted1611### Workspace has not been trusted

1611 1612 


1621* In [non-interactive mode](/docs/en/headless) with `-p` no dialog is shown. Set the `hasTrustDialogAccepted` entry in `~/.claude.json` using the exact `projects` key the message prints.1622* In [non-interactive mode](/docs/en/headless) with `-p` no dialog is shown. Set the `hasTrustDialogAccepted` entry in `~/.claude.json` using the exact `projects` key the message prints.

1622* {/* min-version: 2.1.200 */}If the message names `.claude/settings.local.json` and you started Claude Code outside a git repository or in your home directory, update to v2.1.200 or later. Versions 2.1.196 through 2.1.199 treated your own `.claude/settings.local.json` as repository-supplied in those workspaces. {/* min-version: 2.1.207 */}On v2.1.207 and later, updating isn't enough outside a git repository if you haven't trusted the folder: determining that a folder isn't inside a repository runs git, and Claude Code runs that check only after you accept the trust dialog, so use the first step. Your home directory and any other [configuration home](/docs/en/permissions#project-allow-rules-and-workspace-trust) are exempt and don't wait for the dialog. See [Project allow rules and workspace trust](/docs/en/permissions#project-allow-rules-and-workspace-trust).1623* {/* min-version: 2.1.200 */}If the message names `.claude/settings.local.json` and you started Claude Code outside a git repository or in your home directory, update to v2.1.200 or later. Versions 2.1.196 through 2.1.199 treated your own `.claude/settings.local.json` as repository-supplied in those workspaces. {/* min-version: 2.1.207 */}On v2.1.207 and later, updating isn't enough outside a git repository if you haven't trusted the folder: determining that a folder isn't inside a repository runs git, and Claude Code runs that check only after you accept the trust dialog, so use the first step. Your home directory and any other [configuration home](/docs/en/permissions#project-allow-rules-and-workspace-trust) are exempt and don't wait for the dialog. See [Project allow rules and workspace trust](/docs/en/permissions#project-allow-rules-and-workspace-trust).

1623 1624 

1625### Is not matched by file permission checks

1626 

1627{/* min-version: 2.1.210 */}Claude Code found a `Write`, `NotebookEdit`, `MultiEdit`, or `Glob` [permission rule](/docs/en/permissions#read-and-edit) with a path in one of your [settings files](/docs/en/settings#settings-files), in [managed settings](/docs/en/permissions#managed-settings), or in a `--allowedTools`, `--disallowedTools`, or `--settings` flag value. It checks file permissions against `Edit` and `Read` rules only, so it never consults a path rule that names one of the other file tools. It keeps the rule and changes nothing else; the warning names the rule, its source in parentheses, and the replacement to write:

1628 

1629```text theme={null}

1630Permission deny rule (.claude/settings.json): Write(docs/**) is not matched by file permission checks — only Edit(path) rules are. Use Edit(docs/**) instead (Edit rules cover all file-editing tools).

1631```

1632 

1633**What to do:**

1634 

1635* Replace `Write(path)`, `NotebookEdit(path)`, and legacy `MultiEdit(path)` rules with `Edit(path)`. `Edit` rules cover all file-editing tools.

1636* Except in `--allowedTools`, where Claude Code accepts a `Glob` rule without warning, replace `Glob(path)` rules with `Read(path)`.

1637* Fix the rule at the source the warning names in parentheses: a settings file path, or the flag itself for `--allowed-tools` and `--disallowed-tools`. A `claude-settings-<hash>.json` path that doesn't exist on disk stands for an inline `--settings` value; fix the JSON you pass to that flag.

1638* Leave bare tool-name rules such as `Write` or `Glob` alone. Claude Code matches them at the [tool level](/docs/en/permissions#match-all-uses-of-a-tool) and doesn't warn about them.

1639* If the source reads `managed policy settings`, forward the warning to whoever maintains your managed settings; you can't clear it yourself.

1640 

1641In a [background session](/docs/en/agent-view) or with `--output-format json` or `stream-json`, Claude Code writes the warning to the debug log instead of stderr, so machine-read output stays clean; run with `--debug` to capture it at `~/.claude/debug/<session-id>.txt`. Before v2.1.210, Claude Code accepted these rules without a warning.

1642 

1624## Responses seem lower quality than usual1643## Responses seem lower quality than usual

1625 1644 

1626If Claude's answers seem less capable than you expect but no error is shown, the cause is usually conversation state rather than the model itself. Claude Code doesn't silently change model versions. It can switch to a fallback model in three specific cases:1645If Claude's answers seem less capable than you expect but no error is shown, the cause is usually conversation state rather than the model itself. Claude Code doesn't silently change model versions. It can switch to a fallback model in three specific cases:

Details

6 6 

7> Understand when to use CLAUDE.md, Skills, subagents, hooks, MCP, and plugins.7> Understand when to use CLAUDE.md, Skills, subagents, hooks, MCP, and plugins.

8 8 

9Claude Code combines a model that reasons about your code with [built-in tools](/en/how-claude-code-works#tools) for file operations, search, execution, and web access. The built-in tools cover most coding tasks. This guide covers the extension layer: features you add to customize what Claude knows, connect it to external services, and automate workflows.9Claude Code combines a model that reasons about your code with [built-in tools](/docs/en/how-claude-code-works#tools) for file operations, search, execution, and web access. The built-in tools cover most coding tasks. This guide covers the extension layer: features you add to customize what Claude knows, connect it to external services, and automate workflows.

10 10 

11<Note>11<Note>

12 For how the core agentic loop works, see [How Claude Code works](/en/how-claude-code-works).12 For how the core agentic loop works, see [How Claude Code works](/docs/en/how-claude-code-works).

13</Note>13</Note>

14 14 

15**New to Claude Code?** Start with [CLAUDE.md](/en/memory) for project conventions, then add other extensions [as specific triggers come up](#build-your-setup-over-time).15**New to Claude Code?** Start with [CLAUDE.md](/docs/en/memory) for project conventions, then add other extensions [as specific triggers come up](#build-your-setup-over-time).

16 16 

17## Overview17## Overview

18 18 

19Extensions plug into different parts of the agentic loop:19Extensions plug into different parts of the agentic loop:

20 20 

21* **[CLAUDE.md](/en/memory)** adds persistent context Claude sees every session21* **[CLAUDE.md](/docs/en/memory)** adds persistent context Claude sees every session

22* **[Skills](/en/skills)** add reusable knowledge and invocable workflows22* **[Skills](/docs/en/skills)** add reusable knowledge and invocable workflows

23* **[Code intelligence](/en/tools-reference#lsp-tool-behavior)** connects Claude to a language server for symbol-level navigation and live type errors23* **[Code intelligence](/docs/en/tools-reference#lsp-tool-behavior)** connects Claude to a language server for symbol-level navigation and live type errors

24* **[MCP](/en/mcp)** connects Claude to external services and tools24* **[MCP](/docs/en/mcp)** connects Claude to external services and tools

25* **[Subagents](/en/sub-agents)** run their own loops in isolated context, returning summaries25* **[Subagents](/docs/en/sub-agents)** run their own loops in isolated context, returning summaries

26* **[Agent teams](/en/agent-teams)** coordinate multiple independent sessions with shared tasks and peer-to-peer messaging26* **[Agent teams](/docs/en/agent-teams)** coordinate multiple independent sessions with shared tasks and peer-to-peer messaging

27* **[Hooks](/en/hooks-guide)** fire on lifecycle events and can run a script, HTTP request, prompt, or subagent27* **[Hooks](/docs/en/hooks-guide)** run your script, HTTP request, prompt, or subagent when Claude Code reaches a lifecycle event

28* **[Plugins](/en/plugins)** and **[marketplaces](/en/plugin-marketplaces)** package and distribute these features28* **[Plugins](/docs/en/plugins)** and **[marketplaces](/docs/en/plugin-marketplaces)** package and distribute these features

29 29 

30[Skills](/en/skills) are the most flexible extension. A skill is a markdown file containing knowledge, workflows, or instructions. You can invoke skills with a command like `/deploy`, or Claude can load them automatically when relevant. Skills can run in your current conversation or in an isolated context via subagents.30[Skills](/docs/en/skills) are the most flexible extension. A skill is a markdown file containing knowledge, workflows, or instructions. You can invoke skills with a command like `/deploy`, or Claude can load them automatically when relevant. Skills can run in your current conversation or in an isolated context via subagents.

31 31 

32## Match features to your goal32## Match features to your goal

33 33 


38| **CLAUDE.md** | Persistent context loaded every conversation | Project conventions, "always do X" rules | "Use pnpm, not npm. Run tests before committing." |38| **CLAUDE.md** | Persistent context loaded every conversation | Project conventions, "always do X" rules | "Use pnpm, not npm. Run tests before committing." |

39| **Skill** | Instructions, knowledge, and workflows Claude can use | Reusable content, reference docs, repeatable tasks | `/deploy` runs your deployment checklist; API docs skill with endpoint patterns |39| **Skill** | Instructions, knowledge, and workflows Claude can use | Reusable content, reference docs, repeatable tasks | `/deploy` runs your deployment checklist; API docs skill with endpoint patterns |

40| **Subagent** | Isolated execution context that returns summarized results | Context isolation, parallel tasks, specialized workers | Research task that reads many files but returns only key findings |40| **Subagent** | Isolated execution context that returns summarized results | Context isolation, parallel tasks, specialized workers | Research task that reads many files but returns only key findings |

41| **[Agent teams](/en/agent-teams)** | Coordinate multiple independent Claude Code sessions | Parallel research, new feature development, debugging with competing hypotheses | Spawn reviewers to check security, performance, and tests simultaneously |41| **[Agent teams](/docs/en/agent-teams)** | Coordinate multiple independent Claude Code sessions | Parallel research, new feature development, debugging with competing hypotheses | Spawn reviewers to check security, performance, and tests simultaneously |

42| **[Code intelligence](/en/tools-reference#lsp-tool-behavior)** | Language-server navigation and diagnostics | Typed languages, large codebases where grep is slow or imprecise | Jump to a symbol's definition instead of reading the whole file |42| **[Code intelligence](/docs/en/tools-reference#lsp-tool-behavior)** | Language-server navigation and diagnostics | Typed languages, large codebases where grep is slow or imprecise | Jump to a symbol's definition instead of reading the whole file |

43| **MCP** | Connect to external services | External data or actions | Query your database, post to Slack, control a browser |43| **MCP** | Connect to external services | External data or actions | Query your database, post to Slack, control a browser |

44| **Hook** | Script, HTTP request, prompt, or subagent triggered by events | Automation that must run on every matching event | Run ESLint after every file edit |44| **Hook** | Script, HTTP request, prompt, or subagent triggered by events | Automation that must run on every matching event | Run ESLint after every file edit |

45| **[Artifact](/en/artifacts)** | Publish session output as a private, interactive web page | Output you want to see or share visually rather than as terminal text | An incident timeline that updates as Claude investigates |45| **[Artifact](/docs/en/artifacts)** | Publish session output as a private, interactive web page | Output you want to see or share visually rather than as terminal text | An incident timeline that updates as Claude investigates |

46 46 

47**[Plugins](/en/plugins)** are the packaging layer. A plugin bundles skills, hooks, subagents, and MCP servers into a single installable unit. Plugin skills are namespaced (like `/my-plugin:review`) so multiple plugins can coexist. Use plugins when you want to reuse the same setup across multiple repositories or distribute to others via a **[marketplace](/en/plugin-marketplaces)**.47**[Plugins](/docs/en/plugins)** are the packaging layer. A plugin bundles skills, hooks, subagents, and MCP servers into a single installable unit. Plugin skills are namespaced (like `/my-plugin:review`) so multiple plugins can coexist. Use plugins when you want to reuse the same setup across multiple repositories or distribute to others via a **[marketplace](/docs/en/plugin-marketplaces)**.

48 48 

49### Build your setup over time49### Build your setup over time

50 50 


52 52 

53| Trigger | Add |53| Trigger | Add |

54| :------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------- |54| :------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------- |

55| Claude gets a convention or command wrong twice | Add it to [CLAUDE.md](/en/memory) |55| Claude gets a convention or command wrong twice | Add it to [CLAUDE.md](/docs/en/memory) |

56| You keep typing the same prompt to start a task | Save it as a user-invocable [skill](/en/skills) |56| You keep typing the same prompt to start a task | Save it as a user-invocable [skill](/docs/en/skills) |

57| You paste the same playbook or multi-step procedure into chat for the third time | Capture it as a [skill](/en/skills) |57| You paste the same playbook or multi-step procedure into chat for the third time | Capture it as a [skill](/docs/en/skills) |

58| You keep copying data from a browser tab Claude can't see | Connect that system as an [MCP server](/en/mcp) |58| You keep copying data from a browser tab Claude can't see | Connect that system as an [MCP server](/docs/en/mcp) |

59| Claude reads many files to find where a symbol is defined or used | Install a [code intelligence plugin](/en/discover-plugins#code-intelligence) for your language |59| Claude reads many files to find where a symbol is defined or used | Install a [code intelligence plugin](/docs/en/discover-plugins#code-intelligence) for your language |

60| A side task floods your conversation with output you won't reference again | Route it through a [subagent](/en/sub-agents) |60| A side task floods your conversation with output you won't reference again | Route it through a [subagent](/docs/en/sub-agents) |

61| You want something to happen every time without asking | Write a [hook](/en/hooks-guide) |61| You want something to happen every time without asking | Write a [hook](/docs/en/hooks-guide) |

62| A second repository needs the same setup | Package it as a [plugin](/en/plugins) |62| A second repository needs the same setup | Package it as a [plugin](/docs/en/plugins) |

63 63 

64The same triggers tell you when to update what you already have. A repeated mistake or a recurring review comment is a CLAUDE.md edit, not a one-off correction in chat. A workflow you keep tweaking by hand is a skill that needs another revision.64The same triggers tell you when to update what you already have. A repeated mistake or a recurring review comment is a CLAUDE.md edit, not a one-off correction in chat. A workflow you keep tweaking by hand is a skill that needs another revision.

65 65 


78 | ----------------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------- |78 | ----------------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------- |

79 | **What it is** | Reusable instructions, knowledge, or workflows | Isolated worker with its own context |79 | **What it is** | Reusable instructions, knowledge, or workflows | Isolated worker with its own context |

80 | **Key benefit** | Share content across contexts | Context isolation. Work happens separately, only summary returns |80 | **Key benefit** | Share content across contexts | Context isolation. Work happens separately, only summary returns |

81 | **[Context window](/en/context-window) impact** | Adds to your main window | Uses a separate window with its own input and output tokens |81 | **[Context window](/docs/en/context-window) impact** | Adds to your main window | Uses a separate window with its own input and output tokens |

82 | **Best for** | Reference material, invocable workflows | Tasks that read many files, parallel work, specialized workers |82 | **Best for** | Reference material, invocable workflows | Tasks that read many files, parallel work, specialized workers |

83 83 

84 **Skills can be reference or action.** Reference skills provide knowledge Claude uses throughout your session (like your API style guide). Action skills tell Claude to do something specific (like `/deploy` that runs your deployment workflow).84 **Skills can be reference or action.** Reference skills provide knowledge Claude uses throughout your session (like your API style guide). Action skills tell Claude to do something specific (like `/deploy` that runs your deployment workflow).

85 85 

86 **Use a subagent** when you need context isolation or when your context window is getting full. The subagent might read dozens of files or run extensive searches, but your main conversation only receives a summary. Since subagent work doesn't consume your main context, this is also useful when you don't need the intermediate work to remain visible. Custom subagents can have their own instructions and can preload skills.86 **Use a subagent** when you need context isolation or when your context window is getting full. The subagent might read dozens of files or run extensive searches, but your main conversation only receives a summary. Since subagent work doesn't consume your main context, this is also useful when you don't need the intermediate work to remain visible. Custom subagents can have their own instructions and can preload skills.

87 87 

88 **They can combine.** A subagent can preload specific skills (`skills:` field). A skill can run in isolated context using `context: fork`. See [Skills](/en/skills) for details.88 **They can combine.** A subagent can preload specific skills (`skills:` field). A skill can run in isolated context using `context: fork`. See [Skills](/docs/en/skills) for details.

89 </Tab>89 </Tab>

90 90 

91 <Tab title="CLAUDE.md vs Skill">91 <Tab title="CLAUDE.md vs Skill">


102 102 

103 **Put it in a skill** if it's reference material Claude needs sometimes (API docs, style guides) or a workflow you trigger with `/<name>` (deploy, review, release).103 **Put it in a skill** if it's reference material Claude needs sometimes (API docs, style guides) or a workflow you trigger with `/<name>` (deploy, review, release).

104 104 

105 **Rule of thumb:** Keep CLAUDE.md under 200 lines. If it's growing, move reference content to skills or split into [`.claude/rules/`](/en/memory#organize-rules-with-claude/rules/) files.105 **Rule of thumb:** Keep CLAUDE.md under 200 lines. If it's growing, move reference content to skills or split into [`.claude/rules/`](/docs/en/memory#organize-rules-with-claude/rules/) files.

106 </Tab>106 </Tab>

107 107 

108 <Tab title="CLAUDE.md vs Rules vs Skills">108 <Tab title="CLAUDE.md vs Rules vs Skills">


116 116 

117 **Use CLAUDE.md** for instructions every session needs: build commands, test conventions, project architecture.117 **Use CLAUDE.md** for instructions every session needs: build commands, test conventions, project architecture.

118 118 

119 **Use rules** to keep CLAUDE.md focused. Rules with [`paths` frontmatter](/en/memory#path-specific-rules) only load when Claude works with matching files, saving context.119 **Use rules** to keep CLAUDE.md focused. Rules with [`paths` frontmatter](/docs/en/memory#path-specific-rules) only load when Claude works with matching files, saving context.

120 120 

121 **Use skills** for content Claude only needs sometimes, like API documentation or a deployment checklist you trigger with `/<name>`.121 **Use skills** for content Claude only needs sometimes, like API documentation or a deployment checklist you trigger with `/<name>`.

122 </Tab>122 </Tab>


142 **Transition point:** If you're running parallel subagents but hitting context limits, or if your subagents need to communicate with each other, agent teams are the natural next step.142 **Transition point:** If you're running parallel subagents but hitting context limits, or if your subagents need to communicate with each other, agent teams are the natural next step.

143 143 

144 <Note>144 <Note>

145 Agent teams are experimental and disabled by default. See [agent teams](/en/agent-teams) for setup and current limitations.145 Agent teams are experimental and disabled by default. See [agent teams](/docs/en/agent-teams) for setup and current limitations.

146 </Note>146 </Note>

147 </Tab>147 </Tab>

148 148 


165 </Tab>165 </Tab>

166 166 

167 <Tab title="Hook vs Skill">167 <Tab title="Hook vs Skill">

168 A hook fires on a lifecycle event; a skill is loaded into context for Claude to apply.168 Claude Code runs a hook at a lifecycle event; it loads a skill into context for Claude to apply.

169 169 

170 | Aspect | Hook | Skill |170 | Aspect | Hook | Skill |

171 | ---------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------- |171 | ---------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------- |

172 | **Runs** | A shell command, HTTP request, LLM prompt, or subagent | Instructions Claude reads and follows |172 | **Runs** | A shell command, HTTP request, LLM prompt, or subagent | Instructions Claude reads and follows |

173 | **Triggered by** | [Lifecycle events](/en/hooks#hook-events) such as `PostToolUse` or `SessionStart` | You typing `/<name>`, or Claude matching the description to your task |173 | **Triggered by** | [Lifecycle events](/docs/en/hooks#hook-events) such as `PostToolUse` or `SessionStart` | You typing `/<name>`, or Claude matching the description to your task |

174 | **Determinism** | Always fires on its event; the trigger is guaranteed | Claude interprets the instructions; outcome can vary |174 | **Determinism** | Always fires on its event; the trigger is guaranteed | Claude interprets the instructions; outcome can vary |

175 | **Context cost** | Zero unless the hook returns output | Description loads each session; full content loads when used |175 | **Context cost** | Zero unless the hook returns output | Description loads each session; full content loads when used |

176 | **Best for** | Linting after edits, blocking unsafe commands, logging, notifications | Workflows that need reasoning, reference material, multi-step tasks |176 | **Best for** | Linting after edits, blocking unsafe commands, logging, notifications | Workflows that need reasoning, reference material, multi-step tasks |


189 189 

190Features can be defined at multiple levels: user-wide, per-project, via plugins, or through managed policies. You can also nest CLAUDE.md files in subdirectories or place skills in specific packages of a monorepo. When the same feature exists at multiple levels, here's how they layer:190Features can be defined at multiple levels: user-wide, per-project, via plugins, or through managed policies. You can also nest CLAUDE.md files in subdirectories or place skills in specific packages of a monorepo. When the same feature exists at multiple levels, here's how they layer:

191 191 

192* **CLAUDE.md files** are additive: all levels contribute content to Claude's context simultaneously. Files from your working directory and above load at launch; subdirectories load as you work in them. When instructions conflict, Claude uses judgment to reconcile them, with more specific instructions typically taking precedence. See [how CLAUDE.md files load](/en/memory#how-claude-md-files-load).192* **CLAUDE.md files** are additive: all levels contribute content to Claude's context simultaneously. Files from your working directory and above load at launch; subdirectories load as you work in them. When instructions conflict, Claude uses judgment to reconcile them, with more specific instructions typically taking precedence. See [how CLAUDE.md files load](/docs/en/memory#how-claude-md-files-load).

193* **Skills and subagents** override by name: when the same name exists at multiple levels, one definition wins based on priority (managed > user > project for skills; managed > CLI flag > project > user > plugin for subagents). Plugin skills are [namespaced](/en/plugins#add-skills-to-your-plugin) to avoid conflicts. See [skill discovery](/en/skills#where-skills-live) and [subagent scope](/en/sub-agents#choose-the-subagent-scope).193* **Skills and subagents** override by name: when the same name exists at multiple levels, one definition wins based on priority (managed > user > project for skills; managed > CLI flag > project > user > plugin for subagents). Plugin skills are [namespaced](/docs/en/plugins#add-skills-to-your-plugin) to avoid conflicts. See [skill discovery](/docs/en/skills#where-skills-live) and [subagent scope](/docs/en/sub-agents#choose-the-subagent-scope).

194* **MCP servers** override by name: local > project > user. See [MCP scope](/en/mcp#scope-hierarchy-and-precedence).194* **MCP servers** override by name: local > project > user. See [MCP scope](/docs/en/mcp#scope-hierarchy-and-precedence).

195* **Hooks** merge: all registered hooks fire for their matching events regardless of source. See [hooks](/en/hooks).195* **Hooks** merge: all registered hooks fire for their matching events regardless of source. See [hooks](/docs/en/hooks).

196 196 

197### Combine features197### Combine features

198 198 


209 209 

210## Understand context costs210## Understand context costs

211 211 

212Every feature you add consumes some of Claude's context. Too much can fill up your context window, but it can also add noise that makes Claude less effective; skills may not trigger correctly, or Claude may lose track of your conventions. Understanding these trade-offs helps you build an effective setup. For an interactive view of how these features combine in a running session, see [Explore the context window](/en/context-window).212Every feature you add consumes some of Claude's context. Too much can fill up your context window, but it can also add noise that makes Claude less effective; skills may not trigger correctly, or Claude may lose track of your conventions. Understanding these trade-offs helps you build an effective setup. For an interactive view of how these features combine in a running session, see [Explore the context window](/docs/en/context-window).

213 213 

214### Context cost by feature214### Context cost by feature

215 215 


224| **Subagents** | When spawned | Fresh context with specified skills | Isolated from main session |224| **Subagents** | When spawned | Fresh context with specified skills | Isolated from main session |

225| **Hooks** | On trigger | Nothing (runs externally) | Zero, unless hook returns additional context |225| **Hooks** | On trigger | Nothing (runs externally) | Zero, unless hook returns additional context |

226 226 

227\*By default, skill descriptions load at session start so Claude can decide when to use them. Set `disable-model-invocation: true` in a skill's frontmatter to hide it from Claude entirely until you invoke it manually. This reduces context cost to zero for skills you only trigger yourself. For a skill you didn't write, set [`skillOverrides`](/en/skills#override-skill-visibility-from-settings) in settings to do the same without editing its file.227\*By default, skill descriptions load at session start so Claude can decide when to use them. Set `disable-model-invocation: true` in a skill's frontmatter to hide it from Claude entirely until you invoke it manually. This reduces context cost to zero for skills you only trigger yourself. For a skill you didn't write, set [`skillOverrides`](/docs/en/skills#override-skill-visibility-from-settings) in settings to do the same without editing its file.

228 228 

229### Understand how features load229### Understand how features load

230 230 

231Each feature loads at different points in your session. The tabs below explain when each one loads and what goes into context.231Each feature loads at different points in your session. The tabs below explain when each one loads and what goes into context.

232 232 

233<img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/context-loading.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=aab139e750494a237ae2e0c8f9139b0a" alt="Context loading: CLAUDE.md loads at session start and stays in every request. MCP tool names load at start with full schemas deferred until use. Skills load descriptions at start, full content on invocation. Subagents get isolated context. Hooks run externally." width="720" height="382" data-path="images/context-loading.svg" />233<img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/context-loading.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=aab139e750494a237ae2e0c8f9139b0a" className="dark:hidden" alt="Context loading: CLAUDE.md loads at session start and stays in every request. MCP tool names load at start with full schemas deferred until use. Skills load descriptions at start, full content on invocation. Subagents get isolated context. Hooks run externally." width="720" height="382" data-path="images/context-loading.svg" />

234 

235<img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/context-loading-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=b274089ef9612d9c760bca9838557626" className="hidden dark:block" alt="Context loading: CLAUDE.md loads at session start and stays in every request. MCP tool names load at start with full schemas deferred until use. Skills load descriptions at start, full content on invocation. Subagents get isolated context. Hooks run externally." width="720" height="382" data-path="images/context-loading-dark.svg" />

234 236 

235<Tabs>237<Tabs>

236 <Tab title="CLAUDE.md">238 <Tab title="CLAUDE.md">


238 240 

239 **What loads:** Full content of all CLAUDE.md files (managed, user, and project levels).241 **What loads:** Full content of all CLAUDE.md files (managed, user, and project levels).

240 242 

241 **Inheritance:** Claude reads CLAUDE.md files from your working directory up to the root, and discovers nested ones in subdirectories as it accesses those files. See [How CLAUDE.md files load](/en/memory#how-claude-md-files-load) for details.243 **Inheritance:** Claude reads CLAUDE.md files from your working directory up to the root, and discovers nested ones in subdirectories as it accesses those files. See [How CLAUDE.md files load](/docs/en/memory#how-claude-md-files-load) for details.

242 244 

243 <Tip>Keep CLAUDE.md under 200 lines. Move reference material to skills, which load on-demand.</Tip>245 <Tip>Keep CLAUDE.md under 200 lines. Move reference material to skills, which load on-demand.</Tip>

244 </Tab>246 </Tab>

245 247 

246 <Tab title="Skills">248 <Tab title="Skills">

247 Skills are extra capabilities in Claude's toolkit. They can be reference material (like an API style guide) or invocable workflows you trigger with `/<name>` (like `/deploy`). Claude Code includes [bundled skills](/en/commands) like `/code-review`, `/batch`, and `/debug` that work out of the box. You can also create your own. Claude uses skills when appropriate, or you can invoke one directly.249 Skills are extra capabilities in Claude's toolkit. They can be reference material (like an API style guide) or invocable workflows you trigger with `/<name>` (like `/deploy`). Claude Code includes [bundled skills](/docs/en/commands) like `/code-review`, `/batch`, and `/debug` that work out of the box. You can also create your own. Claude uses skills when appropriate, or you can invoke one directly.

248 250 

249 **When:** Depends on the skill's configuration. By default, descriptions load at session start and full content loads when used. For user-only skills (`disable-model-invocation: true`), nothing loads until you invoke them.251 **When:** Depends on the skill's configuration. By default, descriptions load at session start and full content loads when used. For user-only skills (`disable-model-invocation: true`), nothing loads until you invoke them.

250 252 


264 266 

265 **What loads:** Tool names from connected servers. Full JSON schemas stay deferred until Claude needs a specific tool.267 **What loads:** Tool names from connected servers. Full JSON schemas stay deferred until Claude needs a specific tool.

266 268 

267 **Context cost:** [Tool search](/en/mcp#scale-with-mcp-tool-search) is on by default, so idle MCP tools consume minimal context.269 **Context cost:** [Tool search](/docs/en/mcp#scale-with-mcp-tool-search) is on by default, so idle MCP tools consume minimal context.

268 270 

269 <Tip>Run `/mcp` to see connection status and token costs per server. Claude Code [reconnects to remote servers automatically](/en/mcp#automatic-reconnection) if they drop, and you can disconnect servers you're not actively using.</Tip>271 <Tip>Run `/mcp` to see connection status and token costs per server. Claude Code [reconnects to remote servers automatically](/docs/en/mcp#automatic-reconnection) if they drop, and you can disconnect servers you're not actively using.</Tip>

270 </Tab>272 </Tab>

271 273 

272 <Tab title="Code intelligence">274 <Tab title="Code intelligence">


276 278 

277 **Context cost:** Low. Symbol lookups often replace broad file reads, so net context use can go down.279 **Context cost:** Low. Symbol lookups often replace broad file reads, so net context use can go down.

278 280 

279 <Tip>The LSP tool is inactive until you install a [code intelligence plugin](/en/discover-plugins#code-intelligence) for your language.</Tip>281 <Tip>The LSP tool is inactive until you install a [code intelligence plugin](/docs/en/discover-plugins#code-intelligence) for your language.</Tip>

280 </Tab>282 </Tab>

281 283 

282 <Tab title="Subagents">284 <Tab title="Subagents">


286 288 

287 * The agent's own system prompt, not the full Claude Code system prompt289 * The agent's own system prompt, not the full Claude Code system prompt

288 * Full content of skills listed in the agent's `skills:` field290 * Full content of skills listed in the agent's `skills:` field

289 * CLAUDE.md and git status, except the built-in Explore and Plan agents [omit both](/en/sub-agents#what-loads-at-startup)291 * CLAUDE.md and git status, except the built-in Explore and Plan agents [omit both](/docs/en/sub-agents#what-loads-at-startup)

290 * Whatever context the lead agent passes in the prompt292 * Whatever context the lead agent passes in the prompt

291 293 

292 **Context cost:** Isolated from main session. Subagents don't inherit your conversation history or invoked skills.294 **Context cost:** Isolated from main session. Subagents don't inherit your conversation history or invoked skills.


295 </Tab>297 </Tab>

296 298 

297 <Tab title="Hooks">299 <Tab title="Hooks">

298 **When:** On trigger. Hooks fire at specific lifecycle events like tool execution, session boundaries, prompt submission, permission requests, and compaction. See [Hooks](/en/hooks) for the full list.300 **When:** On trigger. Claude Code runs hooks at specific lifecycle events like tool execution, session boundaries, prompt submission, permission requests, and compaction. See [Hooks](/docs/en/hooks) for the full list.

299 301 

300 **What loads:** Nothing by default. Hooks execute outside the main conversation.302 **What loads:** Nothing by default. Hooks execute outside the main conversation.

301 303 


310Each feature has its own guide with setup instructions, examples, and configuration options.312Each feature has its own guide with setup instructions, examples, and configuration options.

311 313 

312<CardGroup cols={2}>314<CardGroup cols={2}>

313 <Card title="CLAUDE.md" icon="file-lines" href="/en/memory">315 <Card title="CLAUDE.md" icon="file-lines" href="/docs/en/memory">

314 Store project context, conventions, and instructions316 Store project context, conventions, and instructions

315 </Card>317 </Card>

316 318 

317 <Card title="Skills" icon="brain" href="/en/skills">319 <Card title="Skills" icon="brain" href="/docs/en/skills">

318 Give Claude domain expertise and reusable workflows320 Give Claude domain expertise and reusable workflows

319 </Card>321 </Card>

320 322 

321 <Card title="Subagents" icon="users" href="/en/sub-agents">323 <Card title="Subagents" icon="users" href="/docs/en/sub-agents">

322 Offload work to isolated context324 Offload work to isolated context

323 </Card>325 </Card>

324 326 

325 <Card title="Agent teams" icon="network" href="/en/agent-teams">327 <Card title="Agent teams" icon="network" href="/docs/en/agent-teams">

326 Coordinate multiple sessions working in parallel328 Coordinate multiple sessions working in parallel

327 </Card>329 </Card>

328 330 

329 <Card title="MCP" icon="plug" href="/en/mcp">331 <Card title="MCP" icon="plug" href="/docs/en/mcp">

330 Connect Claude to external services332 Connect Claude to external services

331 </Card>333 </Card>

332 334 

333 <Card title="Hooks" icon="bolt" href="/en/hooks-guide">335 <Card title="Hooks" icon="bolt" href="/docs/en/hooks-guide">

334 Automate actions with hooks336 Automate actions with hooks

335 </Card>337 </Card>

336 338 

337 <Card title="Plugins" icon="puzzle-piece" href="/en/plugins">339 <Card title="Plugins" icon="puzzle-piece" href="/docs/en/plugins">

338 Bundle and share feature sets340 Bundle and share feature sets

339 </Card>341 </Card>

340 342 

341 <Card title="Marketplaces" icon="store" href="/en/plugin-marketplaces">343 <Card title="Marketplaces" icon="store" href="/docs/en/plugin-marketplaces">

342 Host and distribute plugin collections344 Host and distribute plugin collections

343 </Card>345 </Card>

344</CardGroup>346</CardGroup>

gateways.md +16 −16

Details

8 8 

9A gateway is a proxy your organization runs between Claude Code and a model provider. Claude Code sends API traffic to the gateway instead of directly to the provider, and the gateway forwards it using a credential your organization holds. Developers authenticate to the gateway rather than holding provider credentials, so authentication, usage tracking, budgets, and audit logging happen in one place you control.9A gateway is a proxy your organization runs between Claude Code and a model provider. Claude Code sends API traffic to the gateway instead of directly to the provider, and the gateway forwards it using a credential your organization holds. Developers authenticate to the gateway rather than holding provider credentials, so authentication, usage tracking, budgets, and audit logging happen in one place you control.

10 10 

11Claude Code includes a self-hosted gateway, [Claude apps gateway](/en/claude-apps-gateway), in the `claude` binary, so you don't have to adopt a separate gateway product to run one. If your organization already runs an [LLM gateway](/en/llm-gateway), Claude Code works with that too.11Claude Code includes a self-hosted gateway, [Claude apps gateway](/docs/en/claude-apps-gateway), in the `claude` binary, so you don't have to adopt a separate gateway product to run one. If your organization already runs an [LLM gateway](/docs/en/llm-gateway), Claude Code works with that too.

12 12 

13This page covers:13This page covers:

14 14 


19 19 

20## How a gateway works20## How a gateway works

21 21 

22Each developer's Claude Code is pointed at the gateway's address and authenticates with a gateway-issued credential.22Each developer's Claude Code sends its requests to the gateway's address and authenticates with a gateway-issued credential.

23 23 

24The gateway authenticates the developer, applies whatever access and budget rules you configure, and forwards the request to your provider with the organization's credential. The provider can be Anthropic's API or a [cloud provider](/en/third-party-integrations) such as Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry; the gateway's configuration decides. With Claude apps gateway, or another gateway that exposes a single Anthropic-format endpoint, changing provider doesn't require touching developer machines.24The gateway authenticates the developer, applies whatever access and budget rules you configure, and forwards the request to your provider with the organization's credential. The provider can be Anthropic's API or a [cloud provider](/docs/en/third-party-integrations) such as Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry; the gateway's configuration decides. With Claude apps gateway, or another gateway that exposes a single Anthropic-format endpoint, changing provider doesn't require touching developer machines.

25 25 

26<Frame>26<Frame>

27 <img src="https://mintcdn.com/claude-code/-uq-4JE0W_JO5Er5/images/llm-gateway-flow.svg?fit=max&auto=format&n=-uq-4JE0W_JO5Er5&q=85&s=1c1a8dcc0cfcc3a58652cc8e28cd3e20" alt="Diagram showing Claude Code routing through a gateway. In a developer machines zone, the Claude Code CLI and VS Code extension send requests to the gateway address with a per-developer credential. In a zone labeled your infrastructure, the gateway handles authentication, usage tracking, budgets, and routing, and forwards requests with your organization's credential. In a model providers zone, a solid arrow leads to the provider you configure, shown as the Anthropic API, and dashed arrows lead to other provider options, illustrated with Amazon Bedrock, Google Cloud, and Microsoft Foundry as examples." width="780" height="322" data-path="images/llm-gateway-flow.svg" />27 <img src="https://mintcdn.com/claude-code/-uq-4JE0W_JO5Er5/images/llm-gateway-flow.svg?fit=max&auto=format&n=-uq-4JE0W_JO5Er5&q=85&s=1c1a8dcc0cfcc3a58652cc8e28cd3e20" alt="Diagram showing Claude Code routing through a gateway. In a developer machines zone, the Claude Code CLI and VS Code extension send requests to the gateway address with a per-developer credential. In a zone labeled your infrastructure, the gateway handles authentication, usage tracking, budgets, and routing, and forwards requests with your organization's credential. In a model providers zone, a solid arrow leads to the provider you configure, shown as the Anthropic API, and dashed arrows lead to other provider options, illustrated with Amazon Bedrock, Google Cloud, and Microsoft Foundry as examples." width="780" height="322" data-path="images/llm-gateway-flow.svg" />


38 38 

39### Claude apps gateway39### Claude apps gateway

40 40 

41Claude apps gateway is Anthropic's self-hosted gateway, included in the `claude` binary. It routes to Amazon Bedrock, Claude Platform on AWS, Google Cloud, Microsoft Foundry, or the Anthropic API as the upstream. Developers sign in with your corporate identity provider through `/login`, the gateway enforces model access and [managed settings](/en/permissions#managed-settings) by IdP group, and it emits [OpenTelemetry Protocol (OTLP)](/en/monitoring-usage) usage metrics to your own observability stack.41Claude apps gateway is Anthropic's self-hosted gateway, included in the `claude` binary. It routes to Amazon Bedrock, Claude Platform on AWS, Google Cloud, Microsoft Foundry, or the Anthropic API as the upstream. Developers sign in with your corporate identity provider through `/login`, the gateway enforces model access and [managed settings](/docs/en/permissions#managed-settings) by IdP group, and it emits [OpenTelemetry Protocol (OTLP)](/docs/en/monitoring-usage) usage metrics to your own observability stack.

42 42 

43Because it is built and tested alongside each Claude Code release, it forwards the headers and request fields Claude Code sends. A gateway maintained separately needs its [forwarding rules updated](/en/llm-gateway-protocol#forward-as-open-lists) as those headers and fields change with each release; Claude apps gateway releases with the CLI, so there is no list to keep current. See [Availability and limitations](/en/claude-apps-gateway#availability-and-limitations) for the small set of features that behave differently on a gateway session.43Because it is built and tested alongside each Claude Code release, it forwards the headers and request fields Claude Code sends. A gateway maintained separately needs its [forwarding rules updated](/docs/en/llm-gateway-protocol#forward-as-open-lists) as those headers and fields change with each release; Claude apps gateway releases with the CLI, so there is no list to keep current. See [Availability and limitations](/docs/en/claude-apps-gateway#availability-and-limitations) for the small set of features that behave differently on a gateway session.

44 44 

45The gateway sign-in is a browser SSO step, and there is no service-token flow, so a CI pipeline with no developer to approve the sign-in can't authenticate through it; configure those against your provider directly. Agent SDK sessions and `claude -p` runs on a machine where a developer has signed in use that machine's gateway session and are governed by its policies. See [CI pipelines and remote machines](/en/claude-apps-gateway#ci-pipelines-and-remote-machines).45The gateway sign-in is a browser SSO step, and there is no service-token flow, so a CI pipeline with no developer to approve the sign-in can't authenticate through it; configure those against your provider directly. Agent SDK sessions and `claude -p` runs on a machine where a developer has signed in use that machine's gateway session and are governed by its policies. See [CI pipelines and remote machines](/docs/en/claude-apps-gateway#ci-pipelines-and-remote-machines).

46 46 

47See [Claude apps gateway](/en/claude-apps-gateway) to deploy it.47See [Claude apps gateway](/docs/en/claude-apps-gateway) to deploy it.

48 48 

49### Other gateways49### Other gateways

50 50 

51If your organization already runs an LLM gateway or API gateway, you can use it instead. Anthropic doesn't endorse, maintain, or audit other gateway products, and doesn't support routing Claude Code to non-Claude models through any gateway. See [Other LLM gateways](/en/llm-gateway) for the admin rollout checklist, what a gateway must implement, and how to point Claude Code at it.51If your organization already runs an LLM gateway or API gateway, you can use it instead. Anthropic doesn't endorse, maintain, or audit other gateway products, and doesn't support routing Claude Code to non-Claude models through any gateway. See [Other LLM gateways](/docs/en/llm-gateway) for the admin rollout checklist, what a gateway must implement, and how to point Claude Code at it.

52 52 

53## Subscriptions and gateways53## Subscriptions and gateways

54 54 

55When developers connect through a gateway with a gateway credential, usage is billed to your organization's provider account at API rates, and their claude.ai subscriptions aren't used or charged. Setting [`ANTHROPIC_AUTH_TOKEN`](/en/env-vars) for a gateway you run, or signing in to a Claude apps gateway with `/login`, turns off subscription login for that session. Every request forwarded under that credential is charged to the account behind the gateway's provider credential.55When developers connect through a gateway with a gateway credential, usage is billed to your organization's provider account at API rates, and their claude.ai subscriptions aren't used or charged. Setting [`ANTHROPIC_AUTH_TOKEN`](/docs/en/env-vars) for a gateway you run, or signing in to a Claude apps gateway with `/login`, turns off subscription login for that session. Every request forwarded under that credential is charged to the account behind the gateway's provider credential.

56 56 

57The exception is setting only `ANTHROPIC_BASE_URL`, with no gateway credential. Requests still route through the gateway, but a saved claude.ai login stays the active credential, so the subscription's usage limits and billing apply. [Other LLM gateways](/en/llm-gateway#subscriptions-and-gateways) covers that configuration and what the gateway has to forward for it to work.57The exception is setting only `ANTHROPIC_BASE_URL`, with no gateway credential. Requests still route through the gateway, but a saved claude.ai login stays the active credential, so the subscription's usage limits and billing apply. [Other LLM gateways](/docs/en/llm-gateway#subscriptions-and-gateways) covers that configuration and what the gateway has to forward for it to work.

58 58 

59## Configure separately from the gateway59## Configure separately from the gateway

60 60 

61A gateway routes model API requests. A few things you might expect it to handle are configured elsewhere:61A gateway routes model API requests. A few things you might expect it to handle are configured elsewhere:

62 62 

63* **Which model answers**: pick the model with the `/model` command or [model environment variables](/en/model-config#setting-your-model). The gateway decides where requests go, not which model the developer selects. Claude apps gateway can bound the choice with a per-group `availableModels` allowlist, but the developer still picks within it.63* **Which model answers**: pick the model with the `/model` command or [model environment variables](/docs/en/model-config#setting-your-model). The gateway decides where requests go, not which model the developer selects. Claude apps gateway can bound the choice with a per-group `availableModels` allowlist, but the developer still picks within it.

64* **Other network traffic**: Claude Code itself sends version checks and downloads directly to Anthropic, separate from the gateway path. Whether the optional client telemetry stream is also on depends on your provider; the [telemetry defaults table](/en/data-usage#telemetry-services) covers each case. On a signed-in Claude apps gateway session, the gateway credential disables the Anthropic-bound analytics and, when [telemetry forwarding](/en/claude-apps-gateway-config#telemetry) is configured, pins OTLP export to the gateway. Your network still needs egress to the [required domains](/en/network-config), or set [`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`](/en/env-vars) to turn off the optional streams.64* **Other network traffic**: Claude Code itself sends version checks and downloads directly to Anthropic, separate from the gateway path. Whether the optional client telemetry stream is also on depends on your provider; the [telemetry defaults table](/docs/en/data-usage#telemetry-services) covers each case. On a signed-in Claude apps gateway session, the gateway credential disables the Anthropic-bound analytics and, when [telemetry forwarding](/docs/en/claude-apps-gateway-config#telemetry) is configured, pins OTLP export to the gateway. Your network still needs egress to the [required domains](/docs/en/network-config), or set [`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`](/docs/en/env-vars) to turn off the optional streams.

65* **Corporate HTTP proxies**: an `HTTPS_PROXY` sits between Claude Code and every server it talks to, including the gateway. If your network requires one, [configure the proxy](/en/network-config) in addition to the gateway. For a Claude apps gateway you host, [sign-in checks that the proxy host is also on a private network](/en/claude-apps-gateway#prerequisites); if it isn't, add the gateway host to `NO_PROXY` so the CLI connects to it directly.65* **Corporate HTTP proxies**: an `HTTPS_PROXY` sits between Claude Code and every server it talks to, including the gateway. If your network requires one, [configure the proxy](/docs/en/network-config) in addition to the gateway. For a Claude apps gateway you host, [sign-in checks that the proxy host is also on a private network](/docs/en/claude-apps-gateway#prerequisites); if it isn't, add the gateway host to `NO_PROXY` so the CLI connects to it directly.

66 66 

67## Next steps67## Next steps

68 68 

69The next page depends on who runs the gateway. Anthropic's gateway runs from the `claude` binary and has its own setup guide; a gateway your organization already runs has a protocol to implement and an admin rollout checklist.69The next page depends on who runs the gateway. Anthropic's gateway runs from the `claude` binary and has its own setup guide; a gateway your organization already runs has a protocol to implement and an admin rollout checklist.

70 70 

71* [Claude apps gateway](/en/claude-apps-gateway) to deploy Anthropic's self-hosted gateway with SSO sign-in and OTLP telemetry71* [Claude apps gateway](/docs/en/claude-apps-gateway) to deploy Anthropic's self-hosted gateway with SSO sign-in and OTLP telemetry

72* [Other LLM gateways](/en/llm-gateway) for what a gateway your organization already runs must implement, and how to point Claude Code at it72* [Other LLM gateways](/docs/en/llm-gateway) for what a gateway your organization already runs must implement, and how to point Claude Code at it

73* [Set up Claude Code for your organization](/en/admin-setup) for the wider rollout decisions a gateway is one part of73* [Set up Claude Code for your organization](/docs/en/admin-setup) for the wider rollout decisions a gateway is one part of

gitlab-ci-cd.md +4 −4

Details

13</Info>13</Info>

14 14 

15<Note>15<Note>

16 This integration is built on top of the [Claude Code CLI and Agent SDK](/en/agent-sdk/overview), enabling programmatic use of Claude in your CI/CD jobs and custom automation workflows.16 This integration is built on top of the [Claude Code CLI and Agent SDK](/docs/en/agent-sdk/overview), enabling programmatic use of Claude in your CI/CD jobs and custom automation workflows.

17</Note>17</Note>

18 18 

19## Why use Claude Code with GitLab?19## Why use Claude Code with GitLab?


126 126 

127In an issue comment:127In an issue comment:

128 128 

129```text theme={null}129```text wrap theme={null}

130@claude implement this feature based on the issue description130@claude implement this feature based on the issue description

131```131```

132 132 


136 136 

137In an MR discussion:137In an MR discussion:

138 138 

139```text theme={null}139```text wrap theme={null}

140@claude suggest a concrete approach to cache the results of this API call140@claude suggest a concrete approach to cache the results of this API call

141```141```

142 142 


146 146 

147In an issue or MR comment:147In an issue or MR comment:

148 148 

149```text theme={null}149```text wrap theme={null}

150@claude fix the TypeError in the user dashboard component150@claude fix the TypeError in the user dashboard component

151```151```

152 152 

goal.md +1 −1

Details

123 123 

124## How evaluation works124## How evaluation works

125 125 

126`/goal` is a wrapper around a session-scoped [prompt-based Stop hook](/docs/en/hooks#prompt-based-hooks). Each time Claude finishes a turn, the condition and the conversation so far are sent to your configured [small fast model](/docs/en/model-config), which defaults to Haiku on the Claude API; on a third-party provider, check your [provider page](/docs/en/third-party-integrations) for the platform's default. The model answers yes or no and gives a short reason.126`/goal` is a wrapper around a session-scoped [prompt-based Stop hook](/docs/en/hooks#prompt-based-hooks). Each time Claude finishes a turn, Claude Code sends the condition and the conversation so far to your configured [small fast model](/docs/en/model-config), which defaults to Haiku on the Claude API; on a third-party provider, check your [provider page](/docs/en/third-party-integrations) for the platform's default. The model answers yes or no and gives a short reason.

127 127 

128* **No**: Claude keeps working and takes the reason as guidance for the next turn.128* **No**: Claude keeps working and takes the reason as guidance for the next turn.

129* **Yes**: Claude Code clears the goal and records an achieved entry in the transcript.129* **Yes**: Claude Code clears the goal and records an achieved entry in the transcript.

Details

168}168}

169```169```

170 170 

171The command's output is displayed to the user, but interactive input isn't supported. This works well for browser-based authentication flows where the CLI shows a URL and you complete authentication in the browser. The refresh command times out after three minutes if authentication does not complete. If you set `gcpAuthRefresh` in project settings such as `.claude/settings.json`, the command runs only after you accept the workspace trust prompt.171Claude Code shows you the command's output, but can't send the command interactive input. This works well for browser-based authentication flows where the CLI shows a URL and you complete authentication in the browser. The refresh command times out after three minutes if authentication does not complete. If you set `gcpAuthRefresh` in project settings such as `.claude/settings.json`, the command runs only after you accept the workspace trust prompt.

172 172 

173### 4. Configure Claude Code173### 4. Configure Claude Code

174 174 

headless.md +31 −10

Details

52| Custom agents | `--agents <json>` |52| Custom agents | `--agents <json>` |

53| A plugin | `--plugin-dir <path>`, `--plugin-url <url>` |53| A plugin | `--plugin-dir <path>`, `--plugin-url <url>` |

54 54 

55Bare mode skips OAuth and keychain reads. Anthropic authentication must come from `ANTHROPIC_API_KEY` or an `apiKeyHelper` in the JSON passed to `--settings`. Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry use their usual provider credentials.55Bare mode skips OAuth and keychain reads. For Anthropic authentication, set `ANTHROPIC_API_KEY` or configure an `apiKeyHelper` in the JSON you pass to `--settings`. Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry use their usual provider credentials.

56 56 

57<Note>57<Note>

58 `--bare` is the recommended mode for scripted and SDK calls, and will become the default for `-p` in a future release.58 `--bare` is the recommended mode for scripted and SDK calls, and will become the default for `-p` in a future release.


153 153 

154The last line of the stream is a `result` message with the final response text, cost, and session metadata.154The last line of the stream is a `result` message with the final response text, cost, and session metadata.

155 155 

156{/* min-version: 2.1.214 */}If your consumer reads the stream slowly, Claude Code waits for the queued output to drain before exiting, scaling the wait with how much is still queued, capped at 30 seconds. {/* min-version: 2.1.208 */}Before v2.1.214 the exit wait was capped at about two seconds, which could cut off the end of a large response, and before v2.1.208 piping a large response could truncate the final line and omit the `result` message.156{/* min-version: 2.1.214 */}If your consumer reads the stream slowly, Claude Code waits for the queued output to drain before exiting, scaling the wait with how much is still queued, capped at 30 seconds. Before v2.1.214 the exit wait was capped at about two seconds, which could cut off the end of a large response.

157 

158Messages from [subagents](/docs/en/sub-agents) appear in the stream as `assistant` and `user` messages whose `parent_tool_use_id` field is the ID of the tool call that spawned the subagent. Messages from the main conversation carry `null` in that field.

159 

160By default, Claude Code emits only subagent `tool_use` and `tool_result` blocks. {/* min-version: 2.1.211 */}Pass [`--forward-subagent-text`](/docs/en/cli-reference#cli-flags) or set [`CLAUDE_CODE_FORWARD_SUBAGENT_TEXT`](/docs/en/env-vars) to also emit subagent text and thinking blocks, so you can reconstruct each subagent's transcript. This requires Claude Code v2.1.211 or later.

161 157 

162The following example uses [jq](https://jqlang.org/) to filter for text deltas and display just the streaming text. The `-r` flag outputs raw strings (no quotes) and `-j` joins without newlines so tokens stream continuously:158The following example uses [jq](https://jqlang.org/) to filter for text deltas and display just the streaming text. The `-r` flag outputs raw strings (no quotes) and `-j` joins without newlines so tokens stream continuously:

163 159 


166 jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'162 jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'

167```163```

168 164 

165For programmatic streaming with callbacks and message objects, see [Stream responses in real-time](/docs/en/agent-sdk/streaming-output) in the Agent SDK documentation.

166 

167#### Follow subagent messages

168 

169Messages from [subagents](/docs/en/sub-agents) appear in the stream as `assistant` and `user` messages whose `parent_tool_use_id` field is the ID of the tool call that spawned the subagent. Messages from the main conversation carry `null` in that field.

170 

171By default, Claude Code emits only subagent `tool_use` and `tool_result` blocks. {/* min-version: 2.1.211 */}Pass [`--forward-subagent-text`](/docs/en/cli-reference#cli-flags) or set [`CLAUDE_CODE_FORWARD_SUBAGENT_TEXT`](/docs/en/env-vars) to also emit subagent text and thinking blocks, so you can reconstruct each subagent's transcript. This requires Claude Code v2.1.211 or later.

172 

173When you enable either option, Claude Code forwards messages from [subagents at every nesting depth](/docs/en/sub-agents#let-subagents-spawn-their-own-subagents): when a subagent spawns its own subagent, the nested subagent's messages carry the ID of the Agent tool call that spawned it in `parent_tool_use_id`, so you can rebuild the full nesting tree by following those IDs. Before v2.1.219, messages from nested subagents didn't appear in the stream.

174 

175#### Handle API retries

176 

169When an API request fails with a retryable error, Claude Code emits a `system/api_retry` event before retrying. You can use this to surface retry progress or implement custom backoff logic.177When an API request fails with a retryable error, Claude Code emits a `system/api_retry` event before retrying. You can use this to surface retry progress or implement custom backoff logic.

170 178 

171| Field | Type | Description |179| Field | Type | Description |


180| `uuid` | string | unique event identifier |188| `uuid` | string | unique event identifier |

181| `session_id` | string | session the event belongs to |189| `session_id` | string | session the event belongs to |

182 190 

191#### Read session metadata

192 

183The `system/init` event reports session metadata including the model, tools, MCP servers, and loaded plugins. It is the first event in the stream unless startup events precede it:193The `system/init` event reports session metadata including the model, tools, MCP servers, and loaded plugins. It is the first event in the stream unless startup events precede it:

184 194 

185* `plugin_install` events, when [`CLAUDE_CODE_SYNC_PLUGIN_INSTALL`](/docs/en/env-vars) is set.195* `plugin_install` events, when [`CLAUDE_CODE_SYNC_PLUGIN_INSTALL`](/docs/en/env-vars) is set.

186* {/* min-version: 2.1.204 */}[`hook_started`, `hook_progress`, and `hook_response` events](/docs/en/agent-sdk/typescript#sdkhookstartedmessage), while a configured [`SessionStart`](/docs/en/hooks#sessionstart) or [`Setup`](/docs/en/hooks#setup) hook runs. These stream as the hook produces them. Claude Code v2.1.169 through v2.1.203 delivered them in one batch after the hook completed, still ahead of `system/init`; v2.1.204 restored live delivery.196* {/* min-version: 2.1.204 */}[`hook_started`, `hook_progress`, and `hook_response` events](/docs/en/agent-sdk/typescript#sdkhookstartedmessage), while a configured [`SessionStart`](/docs/en/hooks#sessionstart) or [`Setup`](/docs/en/hooks#setup) hook runs. These stream as the hook produces them. Claude Code v2.1.169 through v2.1.203 delivered them in one batch after the hook completed, still ahead of `system/init`; v2.1.204 restored live delivery.

187 197 

188The event also carries an optional `capabilities` array of strings naming the protocol behaviors this Claude Code version implements, such as `interrupt_receipt_v1`. Check it to feature-detect instead of comparing version strings, and ignore values you don't recognize. The field requires Claude Code v2.1.205 or later and is absent from earlier versions. See [`SDKSystemMessage`](/docs/en/agent-sdk/typescript#sdksystemmessage) for the capability list.198The event also carries an optional `capabilities` array of strings naming the protocol behaviors this Claude Code version implements, such as `interrupt_receipt_v1` or `interrupt_cancel_queued_v1`. Check it to feature-detect instead of comparing version strings, and ignore values you don't recognize. The field requires Claude Code v2.1.205 or later and is absent from earlier versions. See [`SDKSystemMessage`](/docs/en/agent-sdk/typescript#sdksystemmessage) for the capability list.

189 199 

190Use the plugin fields to fail CI when a plugin did not load:200#### Fail CI when a plugin or MCP server doesn't load

201 

202Use the plugin fields in the `system/init` event to catch a plugin that didn't load:

191 203 

192| Field | Type | Description |204| Field | Type | Description |

193| --------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |205| --------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

194| `plugins` | array | plugins that loaded successfully, each with `name` and `path` |206| `plugins` | array | plugins that loaded successfully, each with `name` and `path` |

195| `plugin_errors` | array | plugin load-time errors, each with `plugin`, `type`, and `message`. Includes unsatisfied dependency versions and `--plugin-dir` load failures such as a missing path or invalid archive. Affected plugins are demoted and absent from `plugins`. The key is omitted when there are no errors |207| `plugin_errors` | array | plugin load-time errors, each with `plugin`, `type`, and `message`. Includes unsatisfied dependency versions and `--plugin-dir` load failures such as a missing path or invalid archive. Affected plugins are demoted and absent from `plugins`. The key is omitted when there are no errors |

196 208 

209Use the MCP server fields the same way. Claude Code validates each [`--mcp-config`](/docs/en/cli-reference#cli-flags) entry at startup and skips entries that fail validation, for example a `url` entry with no `type`; the run continues and exits cleanly, so check these fields to catch a server that never loaded:

210 

211| Field | Type | Description |

212| ------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

213| `mcp_servers` | array | MCP servers in the session, each with `name` and `status` |

214| `mcp_server_errors` | array | {/* min-version: 2.1.219 */}`--mcp-config` entries skipped by config validation, each with `name`, `type`, and `message`. `type` is a skip category such as `unknown_type`, `url_missing_type`, `invalid_config`, or `reserved_name`; treat values you don't recognize as a generic skip. Affected servers are absent from `mcp_servers`. The key is omitted when there are no errors, so a CI gate can fail on a non-empty array. Requires Claude Code v2.1.219 or later |

215 

216When you run the command by hand in a terminal, Claude Code also prints a startup warning to stderr, such as `Warning: 1 MCP server skipped due to invalid config:`, followed by the reason for each skipped entry. When you redirect stderr, or when a program such as a CI runner or an SDK host captures it, Claude Code prints no warning and reports the skipped entries only in the `mcp_server_errors` field. The warning requires Claude Code v2.1.219 or later.

217 

218#### Track plugin installs

219 

197When [`CLAUDE_CODE_SYNC_PLUGIN_INSTALL`](/docs/en/env-vars) is set, Claude Code emits `system/plugin_install` events while marketplace plugins install before the first turn. Use these to surface install progress in your own UI.220When [`CLAUDE_CODE_SYNC_PLUGIN_INSTALL`](/docs/en/env-vars) is set, Claude Code emits `system/plugin_install` events while marketplace plugins install before the first turn. Use these to surface install progress in your own UI.

198 221 

199| Field | Type | Description |222| Field | Type | Description |


206| `uuid` | string | unique event identifier |229| `uuid` | string | unique event identifier |

207| `session_id` | string | session the event belongs to |230| `session_id` | string | session the event belongs to |

208 231 

209For programmatic streaming with callbacks and message objects, see [Stream responses in real-time](/docs/en/agent-sdk/streaming-output) in the Agent SDK documentation.

210 

211### Auto-approve tools232### Auto-approve tools

212 233 

213Use `--allowedTools` to let Claude use certain tools without prompting. This example runs a test suite and fixes failures, allowing Claude to execute Bash commands and read/edit files without asking for permission:234Use `--allowedTools` to let Claude use certain tools without prompting. This example runs a test suite and fixes failures, allowing Claude to execute Bash commands and read/edit files without asking for permission:

hooks.md +7 −3

Details

14 14 

15## Hook lifecycle15## Hook lifecycle

16 16 

17Hooks fire at specific points during a Claude Code session. When an event fires and a matcher matches, Claude Code passes JSON context about the event to your hook handler. For command hooks, input arrives on stdin. For HTTP hooks, it arrives as the POST request body. Your handler can then inspect the input, take action, and optionally return a decision.17Claude Code runs hooks at specific points during a session. When an event fires and a matcher matches, Claude Code passes JSON context about the event to your hook handler. For command hooks, input arrives on stdin. For HTTP hooks, it arrives as the POST request body. Your handler can then inspect the input, take action, and optionally return a decision.

18 18 

19Events fall into three cadences:19Events fall into three cadences:

20 20 


24 24 

25<div style={{maxWidth: "500px", margin: "0 auto"}}>25<div style={{maxWidth: "500px", margin: "0 auto"}}>

26 <Frame>26 <Frame>

27 <img src="https://mintcdn.com/claude-code/uLsR38F1U_5zPppm/images/hooks-lifecycle.svg?fit=max&auto=format&n=uLsR38F1U_5zPppm&q=85&s=fbdbd78ad9f474da7d344879341341f0" alt="Hook lifecycle diagram showing optional Setup feeding into SessionStart, then a per-turn loop containing UserPromptSubmit, UserPromptExpansion for slash commands, the nested agentic loop (PreToolUse, PermissionRequest, PostToolUse, PostToolUseFailure, PostToolBatch, SubagentStart/Stop, TaskCreated, TaskCompleted), and Stop or StopFailure, followed by TeammateIdle, PreCompact, PostCompact, and SessionEnd, with Elicitation and ElicitationResult nested inside MCP tool execution, PermissionDenied as a side branch from PermissionRequest for auto-mode denials, WorktreeCreate, WorktreeRemove, Notification, ConfigChange, InstructionsLoaded, CwdChanged, and FileChanged as standalone async events, and MessageDisplay as a display-only event that runs while assistant message text streams" width="520" height="1228" data-path="images/hooks-lifecycle.svg" />27 <img src="https://mintcdn.com/claude-code/uLsR38F1U_5zPppm/images/hooks-lifecycle.svg?fit=max&auto=format&n=uLsR38F1U_5zPppm&q=85&s=fbdbd78ad9f474da7d344879341341f0" className="dark:hidden" alt="Hook lifecycle diagram showing optional Setup feeding into SessionStart, then a per-turn loop containing UserPromptSubmit, UserPromptExpansion for slash commands, the nested agentic loop (PreToolUse, PermissionRequest, PostToolUse, PostToolUseFailure, PostToolBatch, SubagentStart/Stop, TaskCreated, TaskCompleted), and Stop or StopFailure, followed by TeammateIdle, PreCompact, PostCompact, and SessionEnd, with Elicitation and ElicitationResult nested inside MCP tool execution, PermissionDenied as a side branch from PermissionRequest for auto-mode denials, WorktreeCreate, WorktreeRemove, Notification, ConfigChange, InstructionsLoaded, CwdChanged, and FileChanged as standalone async events, and MessageDisplay as a display-only event that runs while assistant message text streams" width="520" height="1228" data-path="images/hooks-lifecycle.svg" />

28 

29 <img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/hooks-lifecycle-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=1499b14a84a22ccff55daddf870d6c3c" className="hidden dark:block" alt="Hook lifecycle diagram showing optional Setup feeding into SessionStart, then a per-turn loop containing UserPromptSubmit, UserPromptExpansion for slash commands, the nested agentic loop (PreToolUse, PermissionRequest, PostToolUse, PostToolUseFailure, PostToolBatch, SubagentStart/Stop, TaskCreated, TaskCompleted), and Stop or StopFailure, followed by TeammateIdle, PreCompact, PostCompact, and SessionEnd, with Elicitation and ElicitationResult nested inside MCP tool execution, PermissionDenied as a side branch from PermissionRequest for auto-mode denials, WorktreeCreate, WorktreeRemove, Notification, ConfigChange, InstructionsLoaded, CwdChanged, and FileChanged as standalone async events, and MessageDisplay as a display-only event that runs while assistant message text streams" width="520" height="1228" data-path="images/hooks-lifecycle-dark.svg" />

28 </Frame>30 </Frame>

29</div>31</div>

30 32 


114Now suppose Claude Code decides to run `Bash "rm -rf /tmp/build"`. Here's what happens:116Now suppose Claude Code decides to run `Bash "rm -rf /tmp/build"`. Here's what happens:

115 117 

116<Frame>118<Frame>

117 <img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/hook-resolution.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=be0bf3053550c26de5f54cd64674c197" alt="Diagram of hook resolution: PreToolUse fires, the matcher checks for a Bash match, then the if condition checks for a Bash(rm *) match. If both match, the hook command runs and returns permissionDecision deny, so the tool call is blocked and Claude Code continues. If either check fails to match, the hook is skipped and the tool call is allowed to proceed." width="930" height="270" data-path="images/hook-resolution.svg" />119 <img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/hook-resolution.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=be0bf3053550c26de5f54cd64674c197" className="dark:hidden" alt="Diagram of hook resolution: PreToolUse fires, the matcher checks for a Bash match, then the if condition checks for a Bash(rm *) match. If both match, the hook command runs and returns permissionDecision deny, so the tool call is blocked and Claude Code continues. If either check fails to match, the hook is skipped and the tool call is allowed to proceed." width="930" height="270" data-path="images/hook-resolution.svg" />

120 

121 <img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/hook-resolution-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=e80af91f8507cee6bd51ac3c2dd92f63" className="hidden dark:block" alt="Diagram of hook resolution: PreToolUse fires, the matcher checks for a Bash match, then the if condition checks for a Bash(rm *) match. If both match, the hook command runs and returns permissionDecision deny, so the tool call is blocked and Claude Code continues. If either check fails to match, the hook is skipped and the tool call is allowed to proceed." width="930" height="270" data-path="images/hook-resolution-dark.svg" />

118</Frame>122</Frame>

119 123 

120<Steps>124<Steps>

hooks-guide.md +5 −5

Details

6 6 

7> Run shell commands automatically when Claude Code edits files, finishes tasks, or needs input. Format code, send notifications, validate commands, and enforce project rules.7> Run shell commands automatically when Claude Code edits files, finishes tasks, or needs input. Format code, send notifications, validate commands, and enforce project rules.

8 8 

9Hooks are user-defined shell commands that execute at specific points in Claude Code's lifecycle. They provide deterministic control over Claude Code's behavior, ensuring certain actions always happen rather than relying on the LLM to choose to run them. Use hooks to enforce project rules, automate repetitive tasks, and integrate Claude Code with your existing tools.9Hooks are user-defined shell commands. Claude Code runs them at specific points in its lifecycle, which gives you deterministic control: certain actions always happen rather than relying on the LLM to choose to run them. Use hooks to enforce project rules, automate repetitive tasks, and integrate Claude Code with your existing tools.

10 10 

11For decisions that require judgment rather than deterministic rules, you can also use [prompt-based hooks](#prompt-based-hooks) or [agent-based hooks](#agent-based-hooks) that use a Claude model to evaluate conditions.11For decisions that require judgment rather than deterministic rules, you can also use [prompt-based hooks](#prompt-based-hooks) or [agent-based hooks](#agent-based-hooks) that use a Claude model to evaluate conditions.

12 12 


91 91 

92Get a desktop notification whenever Claude finishes working and needs your input, so you can switch to other tasks without checking the terminal.92Get a desktop notification whenever Claude finishes working and needs your input, so you can switch to other tasks without checking the terminal.

93 93 

94This hook uses the `Notification` event, which fires when Claude is waiting for input or permission. Each tab below uses the platform's native notification command. Add this to `~/.claude/settings.json`:94This hook uses the `Notification` event, which Claude Code fires when Claude is waiting for input or permission. Each tab below uses the platform's native notification command. Add this to `~/.claude/settings.json`:

95 95 

96<Tabs>96<Tabs>

97 <Tab title="macOS">97 <Tab title="macOS">


394 394 

395Skip the approval dialog for tool calls you always allow. This example auto-approves `ExitPlanMode`, the tool Claude calls when it finishes presenting a plan and asks to proceed, so you aren't prompted every time a plan is ready.395Skip the approval dialog for tool calls you always allow. This example auto-approves `ExitPlanMode`, the tool Claude calls when it finishes presenting a plan and asks to proceed, so you aren't prompted every time a plan is ready.

396 396 

397Unlike the exit-code examples above, auto-approval requires your hook to write a JSON decision to stdout. A `PermissionRequest` hook fires when Claude Code is about to ask you for permission, and returning `"behavior": "allow"` answers the request on your behalf.397Unlike the exit-code examples above, auto-approval requires your hook to write a JSON decision to stdout. Claude Code runs `PermissionRequest` hooks when it's about to ask you for permission, and if your hook returns `"behavior": "allow"`, Claude Code answers the request on your behalf.

398 398 

399The matcher scopes the hook to `ExitPlanMode` only, so no other prompts are affected. Add this to `~/.claude/settings.json`:399The matcher scopes the hook to `ExitPlanMode` only, so no other prompts are affected. Add this to `~/.claude/settings.json`:

400 400 


444 444 

445## How hooks work445## How hooks work

446 446 

447Hook events fire at specific lifecycle points in Claude Code. When an event fires, all matching hooks run in parallel, and identical hook commands are automatically deduplicated. The table below shows each event and when it triggers:447Claude Code fires hook events at specific points in its lifecycle. When an event fires, Claude Code runs all matching hooks in parallel and deduplicates identical hook commands automatically. The table below shows each event and when it triggers:

448 448 

449| Event | When it fires |449| Event | When it fires |

450| :-------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- |450| :-------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- |


560The exit code determines what happens next:560The exit code determines what happens next:

561 561 

562* **Exit 0**: the hook reports no objection and the action proceeds normally. For a `PreToolUse` hook this doesn't approve the tool call: the normal [permission flow](/docs/en/permissions) still applies. For `UserPromptSubmit`, `UserPromptExpansion`, and `SessionStart` hooks, anything you write to stdout is added to Claude's context.562* **Exit 0**: the hook reports no objection and the action proceeds normally. For a `PreToolUse` hook this doesn't approve the tool call: the normal [permission flow](/docs/en/permissions) still applies. For `UserPromptSubmit`, `UserPromptExpansion`, and `SessionStart` hooks, anything you write to stdout is added to Claude's context.

563* **Exit 2**: the action is blocked. Write a reason to stderr, and Claude receives it as feedback so it can adjust. Some events can't be blocked: for `SessionStart`, `Setup`, `Notification`, and others, exit 2 shows stderr to the user and execution continues. See [exit code 2 behavior per event](/docs/en/hooks#exit-code-2-behavior-per-event) for the full list.563* **Exit 2**: Claude Code blocks the action. Write a reason to stderr, and Claude receives it as feedback so it can adjust. Some events can't be blocked: for `SessionStart`, `Setup`, `Notification`, and others, exit 2 shows stderr to the user and execution continues. See [exit code 2 behavior per event](/docs/en/hooks#exit-code-2-behavior-per-event) for the full list.

564* **Any other exit code**: the action proceeds. The transcript shows a `<hook name> hook error` notice followed by the first line of stderr; the full stderr goes to the [debug log](/docs/en/hooks#debug-hooks).564* **Any other exit code**: the action proceeds. The transcript shows a `<hook name> hook error` notice followed by the first line of stderr; the full stderr goes to the [debug log](/docs/en/hooks#debug-hooks).

565 565 

566#### Structured JSON output566#### Structured JSON output

Details

14 14 

15When you give Claude a task, it works through three phases: **gather context**, **take action**, and **verify results**. These phases blend together. Claude uses tools throughout, whether searching files to understand your code, editing to make changes, or running tests to check its work.15When you give Claude a task, it works through three phases: **gather context**, **take action**, and **verify results**. These phases blend together. Claude uses tools throughout, whether searching files to understand your code, editing to make changes, or running tests to check its work.

16 16 

17<img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/agentic-loop.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=4a30fb7ce2815012a9f27c955e2c6bb0" alt="Diagram of the agentic loop: Your prompt leads to Claude gathering context, taking action, verifying results, and repeating until task complete. You can interrupt at any point." width="720" height="280" data-path="images/agentic-loop.svg" />17<img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/agentic-loop.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=4a30fb7ce2815012a9f27c955e2c6bb0" className="dark:hidden" alt="Diagram of the agentic loop: Your prompt leads to Claude gathering context, taking action, verifying results, and repeating until task complete. You can interrupt at any point." width="720" height="280" data-path="images/agentic-loop.svg" />

18 

19<img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/agentic-loop-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=75e1d55ed76857a952f9a2dffbab02df" className="hidden dark:block" alt="Diagram of the agentic loop: Your prompt leads to Claude gathering context, taking action, verifying results, and repeating until task complete. You can interrupt at any point." width="720" height="280" data-path="images/agentic-loop-dark.svg" />

18 20 

19The loop adapts to what you ask. A question about your codebase might only need context gathering. A bug fix cycles through all three phases repeatedly. A refactor might involve extensive verification. Claude decides what each step requires based on what it learned from the previous step, chaining dozens of actions together and course-correcting along the way.21The loop adapts to what you ask. A question about your codebase might only need context gathering. A bug fix cycles through all three phases repeatedly. A refactor might involve extensive verification. Claude decides what each step requires based on what it learned from the previous step, chaining dozens of actions together and course-correcting along the way.

20 22 


110 112 

111Resuming a session with `claude --continue` or `claude --resume` reopens it under the same session ID and appends new messages to the existing conversation. Forking with `--fork-session` or `/branch` copies the history into a new session ID, leaving the original unchanged.113Resuming a session with `claude --continue` or `claude --resume` reopens it under the same session ID and appends new messages to the existing conversation. Forking with `--fork-session` or `/branch` copies the history into a new session ID, leaving the original unchanged.

112 114 

113<img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/session-continuity.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=04ed0984a58e4127e05b3640265241a3" alt="Diagram of session continuity: resume continues the same session, fork creates a new branch with a new ID." width="560" height="280" data-path="images/session-continuity.svg" />115<img src="https://mintcdn.com/claude-code/ikqp3_70mqIahteV/images/session-continuity.svg?fit=max&auto=format&n=ikqp3_70mqIahteV&q=85&s=04ed0984a58e4127e05b3640265241a3" className="dark:hidden" alt="Diagram of session continuity: resume continues the same session, fork creates a new branch with a new ID." width="560" height="280" data-path="images/session-continuity.svg" />

116 

117<img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/session-continuity-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=886a384bce8298594e43f124617ea665" className="hidden dark:block" alt="Diagram of session continuity: resume continues the same session, fork creates a new branch with a new ID." width="560" height="280" data-path="images/session-continuity-dark.svg" />

114 118 

115For the resume flags, the `/resume` picker, naming, and what happens when the same session is open in two terminals, see [Manage sessions](/docs/en/sessions).119For the resume flags, the `/resume` picker, naming, and what happens when the same session is open in two terminals, see [Manage sessions](/docs/en/sessions).

116 120 

Details

177| `/` | Open reverse history search, same as `Ctrl+R`. {/* min-version: 2.1.191 */}As of v2.1.191, the empty search prompt shows a hint: press `Esc` then `i` then `/` to open the command menu instead |177| `/` | Open reverse history search, same as `Ctrl+R`. {/* min-version: 2.1.191 */}As of v2.1.191, the empty search prompt shows a hint: press `Esc` then `i` then `/` to open the command menu instead |

178 178 

179<Note>179<Note>

180 In vim normal mode, if the cursor is at the beginning or end of input and can't move further, `j`/`k` and the arrow keys navigate command history instead.180 In vim NORMAL mode, if the cursor is at the beginning or end of input and can't move further, `j`/`k` and `↑`/`↓` navigate command history instead. {/* min-version: 2.1.219 */}`←` on an empty prompt opens [agent view](/docs/en/agent-view) from NORMAL mode as well as INSERT; before v2.1.219, `←` on an empty prompt did nothing in NORMAL mode.

181</Note>181</Note>

182 182 

183### Editing (NORMAL mode)183### Editing (NORMAL mode)


283 283 

284* Output is written to a file and Claude can retrieve it using the Read tool284* Output is written to a file and Claude can retrieve it using the Read tool

285* Background tasks have unique IDs for tracking and output retrieval285* Background tasks have unique IDs for tracking and output retrieval

286* Background tasks are automatically cleaned up when Claude Code exits. Backgrounding the session instead of exiting it hands them to the background session, where they keep running. See [background a running session](/docs/en/agent-view#from-inside-a-session)286* Background tasks are automatically cleaned up when Claude Code exits. If you background the session instead of exiting it, Claude Code hands them to the background session, where they keep running. See [background a running session](/docs/en/agent-view#from-inside-a-session)

287* Background tasks are automatically terminated if output exceeds 5GB, with a note in stderr explaining why287* Background tasks are automatically terminated if output exceeds 5GB, with a note in stderr explaining why

288* {/* min-version: 2.1.193 */}On macOS and Linux, Claude Code terminates running background tasks when the operating system signals memory pressure, provided the session has been idle for at least 30 minutes and no turn or subagent is running. Set [`CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP`](/docs/en/env-vars) to `1` to turn this off. Requires Claude Code v2.1.193 or later. Background commands owned by a [subagent](/docs/en/sub-agents) are instead terminated after 60 minutes, configurable in milliseconds with [`CLAUDE_SUBAGENT_BG_SHELL_MAX_MS`](/docs/en/env-vars). {/* min-version: 2.1.218 */}Before v2.1.218, neither limit covered commands moved to the background with `Ctrl+B`288* {/* min-version: 2.1.193 */}On macOS and Linux, Claude Code terminates running background tasks when the operating system signals memory pressure, provided the session has been idle for at least 30 minutes and no turn or subagent is running. Set [`CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP`](/docs/en/env-vars) to `1` to turn this off. Requires Claude Code v2.1.193 or later. Background commands owned by a [subagent](/docs/en/sub-agents) are instead terminated after 60 minutes, configurable in milliseconds with [`CLAUDE_SUBAGENT_BG_SHELL_MAX_MS`](/docs/en/env-vars). {/* min-version: 2.1.218 */}Before v2.1.218, neither limit covered commands moved to the background with `Ctrl+B`

289 289 

jetbrains.md +1 −1

Details

22## Features22## Features

23 23 

24* **Quick launch**: use `Cmd+Esc` (Mac) or `Ctrl+Esc` (Windows/Linux) to open Claude Code directly from your editor, or click the Claude Code button in the UI24* **Quick launch**: use `Cmd+Esc` (Mac) or `Ctrl+Esc` (Windows/Linux) to open Claude Code directly from your editor, or click the Claude Code button in the UI

25* **Diff viewing**: code changes can be displayed directly in the IDE diff viewer instead of the terminal25* **Diff viewing**: Claude Code opens code changes in the IDE diff viewer instead of the terminal; change this with the **Diff tool** setting in `/config`

26* **Selection context**: the current selection or tab in the IDE is automatically shared with Claude Code. [`Read` deny rules](/docs/en/permissions#read-and-edit) block this sharing for matching files26* **Selection context**: the current selection or tab in the IDE is automatically shared with Claude Code. [`Read` deny rules](/docs/en/permissions#read-and-edit) block this sharing for matching files

27* **File reference shortcuts**: use `Cmd+Option+K` (Mac) or `Alt+Ctrl+K` (Linux/Windows) to insert file references such as `@src/auth.ts#L1-99`27* **File reference shortcuts**: use `Cmd+Option+K` (Mac) or `Alt+Ctrl+K` (Linux/Windows) to insert file references such as `@src/auth.ts#L1-99`

28* **Diagnostic sharing**: diagnostic errors from the IDE, such as lint and syntax errors, are automatically shared with Claude as you work28* **Diagnostic sharing**: diagnostic errors from the IDE, such as lint and syntax errors, are automatically shared with Claude as you work

Details

301 301 

302### Add gateway models to the model picker302### Add gateway models to the model picker

303 303 

304Model discovery queries the gateway for its model list at startup and adds those names to the `/model` picker alongside the built-in entries.304With model discovery enabled, Claude Code queries the gateway for its model list at startup and adds those names to the `/model` picker alongside the built-in entries.

305 305 

306Enable it if your gateway serves model names that aren't in Claude Code's built-in list and you want to select them from the picker. If the built-in models are what you use, you don't need discovery; your administrator may also have already enabled it through managed settings.306Enable it if your gateway serves model names that aren't in Claude Code's built-in list and you want to select them from the picker. If the built-in models are what you use, you don't need discovery; your administrator may also have already enabled it through managed settings.

307 307 

mcp.md +20 −20

Details

313 313 

314* **Automatic lifecycle**: servers connect and disconnect at these points:314* **Automatic lifecycle**: servers connect and disconnect at these points:

315 * At session startup, Claude Code connects the servers for enabled plugins automatically315 * At session startup, Claude Code connects the servers for enabled plugins automatically

316 * If you enable or disable a plugin during a session, run `/reload-plugins` to connect or disconnect its MCP servers316 * If you enable or disable a plugin during a session, run `/reload-plugins` to connect or disconnect its MCP servers. When you reload, Claude Code keeps the live connections of plugin servers whose configuration is unchanged, and does the same when you [replace the session's MCP server list](/docs/en/agent-sdk/typescript#mcpsetserversresult) from the Agent SDK without naming them. {/* min-version: 2.1.210 */}Before v2.1.210, Claude Code disconnected plugin-provided MCP servers that the new SDK server list didn't name

317 * In [web sessions](/docs/en/claude-code-on-the-web), an MCP call to a plugin server that isn't connected yet, such as right after an idle session wakes, starts the server on demand and waits for it to connect. {/* min-version: 2.1.211 */}Before v2.1.211, plugin servers in a web session reconnected only when the next message started a turn, so MCP calls after an idle session woke failed until then317 * In [web sessions](/docs/en/claude-code-on-the-web), an MCP call to a plugin server that isn't connected yet, such as right after an idle session wakes, starts the server on demand and waits for it to connect. {/* min-version: 2.1.211 */}Before v2.1.211, plugin servers in a web session reconnected only when the next message started a turn, so MCP calls after an idle session woke failed until then

318* **Path placeholders**: `${CLAUDE_PLUGIN_ROOT}` resolves to the plugin's installation directory, `${CLAUDE_PLUGIN_DATA}` to its [persistent state](/docs/en/plugins-reference#persistent-data-directory) directory, and `${CLAUDE_PROJECT_DIR}` to the stable project root. Substitution applies to:318* **Path placeholders**: `${CLAUDE_PLUGIN_ROOT}` resolves to the plugin's installation directory, `${CLAUDE_PLUGIN_DATA}` to its [persistent state](/docs/en/plugins-reference#persistent-data-directory) directory, and `${CLAUDE_PROJECT_DIR}` to the stable project root. Substitution applies to:

319 * `stdio` servers: `command`, `args`, `env`319 * `stdio` servers: `command`, `args`, `env`


395 395 

396### Project scope396### Project scope

397 397 

398Project-scoped servers enable team collaboration by storing configurations in a `.mcp.json` file at your project's root directory. This file is designed to be checked into version control, ensuring all team members have access to the same MCP tools and services. When you add a project-scoped server, Claude Code automatically creates or updates this file with the appropriate configuration structure.398Project-scoped servers enable team collaboration by storing configurations in a `.mcp.json` file at your project's root directory. When you add a project-scoped server, Claude Code automatically creates or updates this file with the appropriate configuration structure. Check `.mcp.json` into version control so everyone on your team gets the same MCP tools and services.

399 399 

400```bash theme={null}400```bash theme={null}

401# Add a project-scoped server401# Add a project-scoped server


490 490 

491Authenticate with your Sentry account:491Authenticate with your Sentry account:

492 492 

493```text theme={null}493```text wrap theme={null}

494/mcp494/mcp

495```495```

496 496 


498 498 

499Then debug production issues:499Then debug production issues:

500 500 

501```text theme={null}501```text wrap theme={null}

502What are the most common errors in the last 24 hours?502What are the most common errors in the last 24 hours?

503```503```

504 504 

505```text theme={null}505```text wrap theme={null}

506Show me the stack trace for error ID abc123506Show me the stack trace for error ID abc123

507```507```

508 508 

509```text theme={null}509```text wrap theme={null}

510Which deployment introduced these new errors?510Which deployment introduced these new errors?

511```511```

512 512 


523 523 

524Then work with GitHub:524Then work with GitHub:

525 525 

526```text theme={null}526```text wrap theme={null}

527Review PR #456 and suggest improvements527Review PR #456 and suggest improvements

528```528```

529 529 

530```text theme={null}530```text wrap theme={null}

531Create a new issue for the bug we just found531Create a new issue for the bug we just found

532```532```

533 533 

534```text theme={null}534```text wrap theme={null}

535Show me all open PRs assigned to me535Show me all open PRs assigned to me

536```536```

537 537 


548 548 

549Then query your database naturally:549Then query your database naturally:

550 550 

551```text theme={null}551```text wrap theme={null}

552What's our total revenue this month?552What's our total revenue this month?

553```553```

554 554 

555```text theme={null}555```text wrap theme={null}

556Show me the schema for the orders table556Show me the schema for the orders table

557```557```

558 558 

559```text theme={null}559```text wrap theme={null}

560Find customers who haven't made a purchase in 90 days560Find customers who haven't made a purchase in 90 days

561```561```

562 562 


590 <Step title="Use the /mcp command within Claude Code">590 <Step title="Use the /mcp command within Claude Code">

591 In Claude Code, use the command:591 In Claude Code, use the command:

592 592 

593 ```text theme={null}593 ```text wrap theme={null}

594 /mcp594 /mcp

595 ```595 ```

596 596 


901 <Step title="View and manage servers in Claude Code">901 <Step title="View and manage servers in Claude Code">

902 In Claude Code, use the command:902 In Claude Code, use the command:

903 903 

904 ```text theme={null}904 ```text wrap theme={null}

905 /mcp905 /mcp

906 ```906 ```

907 907 


1125 <Step title="Reference a specific resource">1125 <Step title="Reference a specific resource">

1126 Use the format `@server:protocol://resource/path` to reference a resource:1126 Use the format `@server:protocol://resource/path` to reference a resource:

1127 1127 

1128 ```text theme={null}1128 ```text wrap theme={null}

1129 Can you analyze @github:issue://123 and suggest a fix?1129 Can you analyze @github:issue://123 and suggest a fix?

1130 ```1130 ```

1131 1131 

1132 ```text theme={null}1132 ```text wrap theme={null}

1133 Please review the API documentation at @docs:file://api/authentication1133 Please review the API documentation at @docs:file://api/authentication

1134 ```1134 ```

1135 </Step>1135 </Step>


1137 <Step title="Multiple resource references">1137 <Step title="Multiple resource references">

1138 You can reference multiple resources in a single prompt:1138 You can reference multiple resources in a single prompt:

1139 1139 

1140 ```text theme={null}1140 ```text wrap theme={null}

1141 Compare @postgres:schema://users with @docs:file://database/user-model1141 Compare @postgres:schema://users with @docs:file://database/user-model

1142 ```1142 ```

1143 </Step>1143 </Step>


1250 </Step>1250 </Step>

1251 1251 

1252 <Step title="Execute a prompt without arguments">1252 <Step title="Execute a prompt without arguments">

1253 ```text theme={null}1253 ```text wrap theme={null}

1254 /mcp__github__list_prs1254 /mcp__github__list_prs

1255 ```1255 ```

1256 </Step>1256 </Step>


1258 <Step title="Execute a prompt with arguments">1258 <Step title="Execute a prompt with arguments">

1259 Many prompts accept arguments. Pass them space-separated after the command:1259 Many prompts accept arguments. Pass them space-separated after the command:

1260 1260 

1261 ```text theme={null}1261 ```text wrap theme={null}

1262 /mcp__github__pr_review 4561262 /mcp__github__pr_review 456

1263 ```1263 ```

1264 1264 

1265 ```text theme={null}1265 ```text wrap theme={null}

1266 /mcp__jira__create_issue "Bug in login flow" high1266 /mcp__jira__create_issue "Bug in login flow" high

1267 ```1267 ```

1268 </Step>1268 </Step>

mcp-quickstart.md +21 −21

Details

14 You can also add MCP servers from other surfaces, including the desktop app, VS Code, and the web. See [Connect from other surfaces](#connect-from-other-surfaces).14 You can also add MCP servers from other surfaces, including the desktop app, VS Code, and the web. See [Connect from other surfaces](#connect-from-other-surfaces).

15</Note>15</Note>

16 16 

17For every way to connect and configure MCP servers in Claude Code, see the [MCP reference](/en/mcp).17For every way to connect and configure MCP servers in Claude Code, see the [MCP reference](/docs/en/mcp).

18 18 

19## Before you begin19## Before you begin

20 20 

21Make sure you have:21Make sure you have:

22 22 

23* [Claude Code installed](/en/quickstart) and authenticated23* [Claude Code installed](/docs/en/quickstart) and authenticated

24* A terminal open in a project directory. Any directory works, including an empty one.24* A terminal open in a project directory. Any directory works, including an empty one.

25 25 

26## Add and verify a server26## Add and verify a server

27 27 

28The example below connects to the [Claude Code documentation MCP server](https://code.claude.com/docs/mcp), a hosted server with full-text search over the Claude Code docs. It doesn't require authentication or any special configuration, so it works well as a first server to test the setup flow with.28The example below connects to the [Claude Code documentation MCP server](https://code.claude.com/docs/mcp), a hosted server with full-text search over the Claude Code docs. It doesn't require authentication or any special configuration, so it works well as a first server to test the setup flow with.

29 29 

30The steps are the same for any server: add it, check the connection status, then use it in a session, with an optional cleanup step at the end. Some servers add a step, like a browser sign-in, shown in [Additional MCP server examples](#additional-mcp-server-examples). For more servers to connect, browse the [Anthropic Directory](/en/mcp#find-and-build-mcp-servers).30The steps are the same for any server: add it, check the connection status, then use it in a session, with an optional cleanup step at the end. Some servers add a step, like a browser sign-in, shown in [Additional MCP server examples](#additional-mcp-server-examples). For more servers to connect, browse the [Anthropic Directory](/docs/en/mcp#find-and-build-mcp-servers).

31 31 

32<Steps>32<Steps>

33 <Step title="Add the MCP server">33 <Step title="Add the MCP server">


75 claude75 claude

76 ```76 ```

77 77 

78 ```text theme={null}78 ```text wrap theme={null}

79 Use the claude-code-docs server to look up what MCP_TIMEOUT does79 Use the claude-code-docs server to look up what MCP_TIMEOUT does

80 ```80 ```

81 81 


96 The command confirms with `Removed MCP server "claude-code-docs" from local config` and a `File modified:` line showing the file it updated.96 The command confirms with `Removed MCP server "claude-code-docs" from local config` and a `File modified:` line showing the file it updated.

97 97 

98 <Note>98 <Note>

99 Each connected server takes some space in [Claude's context window](/en/how-claude-code-works#the-context-window) because its tool names and server instructions load into every session. Removing servers you no longer use keeps that space free.99 Each connected server takes some space in [Claude's context window](/docs/en/how-claude-code-works#the-context-window) because its tool names and server instructions load into every session. Removing servers you no longer use keeps that space free.

100 </Note>100 </Note>

101 </Step>101 </Step>

102</Steps>102</Steps>


125| `project` | `.mcp.json` in your project root | Everyone who clones the project |125| `project` | `.mcp.json` in your project root | Everyone who clones the project |

126| `user` | `~/.claude.json`, under the top-level `mcpServers` key | Only you, all projects |126| `user` | `~/.claude.json`, under the top-level `mcpServers` key | Only you, all projects |

127 127 

128On Windows, `~/.claude.json` resolves to `%USERPROFILE%\.claude.json`, typically `C:\Users\YourName\.claude.json`. If you've set [`CLAUDE_CONFIG_DIR`](/en/env-vars), Claude Code reads `.claude.json` from inside that directory instead.128On Windows, `~/.claude.json` resolves to `%USERPROFILE%\.claude.json`, typically `C:\Users\YourName\.claude.json`. If you've set [`CLAUDE_CONFIG_DIR`](/docs/en/env-vars), Claude Code reads `.claude.json` from inside that directory instead.

129 129 

130Run `claude mcp get claude-code-docs` to see which scope holds a server's definition. For how the scopes interact when the same server is defined in more than one, see [MCP installation scopes](/en/mcp#mcp-installation-scopes).130Run `claude mcp get claude-code-docs` to see which scope holds a server's definition. For how the scopes interact when the same server is defined in more than one, see [MCP installation scopes](/docs/en/mcp#mcp-installation-scopes).

131 131 

132## Change server scope132## Change server scope

133 133 


197 <Step title="Use the browser">197 <Step title="Use the browser">

198 Give Claude a task that needs the browser:198 Give Claude a task that needs the browser:

199 199 

200 ```text theme={null}200 ```text wrap theme={null}

201 Use playwright to open https://example.com and tell me the page title201 Use playwright to open https://example.com and tell me the page title

202 ```202 ```

203 203 


211 211 

212Hosted services like Sentry, Linear, and Notion run their MCP servers behind OAuth: you add the server's URL, then sign in through your browser.212Hosted services like Sentry, Linear, and Notion run their MCP servers behind OAuth: you add the server's URL, then sign in through your browser.

213 213 

214The steps below use Sentry as the example. To connect a different service, substitute its URL, which you can find in the [Anthropic Directory](/en/mcp#find-and-build-mcp-servers) or the service's documentation.214The steps below use Sentry as the example. To connect a different service, substitute its URL, which you can find in the [Anthropic Directory](/docs/en/mcp#find-and-build-mcp-servers) or the service's documentation.

215 215 

216<Steps>216<Steps>

217 <Step title="Add the server">217 <Step title="Add the server">


227 <Step title="Authenticate in your browser">227 <Step title="Authenticate in your browser">

228 Start a Claude Code session and open the MCP panel:228 Start a Claude Code session and open the MCP panel:

229 229 

230 ```text theme={null}230 ```text wrap theme={null}

231 /mcp231 /mcp

232 ```232 ```

233 233 


241 </Step>241 </Step>

242</Steps>242</Steps>

243 243 

244Servers that authenticate with a static token instead of OAuth take the token at add time with `--header "Authorization: Bearer <token>"`. See the [GitHub example](/en/mcp#example-connect-to-github-for-code-reviews) for a worked version.244Servers that authenticate with a static token instead of OAuth take the token at add time with `--header "Authorization: Bearer <token>"`. See the [GitHub example](/docs/en/mcp#example-connect-to-github-for-code-reviews) for a worked version.

245 245 

246## Edit .mcp.json directly246## Edit .mcp.json directly

247 247 


280 280 

281This guide uses the `claude mcp` CLI commands, but every Claude Code surface can connect to MCP servers:281This guide uses the `claude mcp` CLI commands, but every Claude Code surface can connect to MCP servers:

282 282 

283* **Claude Code desktop app**: add servers through the [Connectors UI](/en/desktop#connect-external-tools).283* **Claude Code desktop app**: add servers through the [Connectors UI](/docs/en/desktop#connect-external-tools).

284* **Claude Desktop chat app**: a separate app from Claude Code. To copy servers from its `claude_desktop_config.json` into the CLI, run `claude mcp add-from-claude-desktop` on macOS or WSL.284* **Claude Desktop chat app**: a separate app from Claude Code. To copy servers from its `claude_desktop_config.json` into the CLI, run `claude mcp add-from-claude-desktop` on macOS or WSL.

285* **VS Code**: see [Connect to external tools with MCP](/en/vs-code#connect-to-external-tools-with-mcp).285* **VS Code**: see [Connect to external tools with MCP](/docs/en/vs-code#connect-to-external-tools-with-mcp).

286* **Claude Code on the web**: reads `.mcp.json` from your repository. See [Edit .mcp.json directly](#edit-mcp-json-directly).286* **Claude Code on the web**: reads `.mcp.json` from your repository. See [Edit .mcp.json directly](#edit-mcp-json-directly).

287* **Claude.ai**: connectors you add at [claude.ai/customize/connectors](https://claude.ai/customize/connectors) load automatically in the CLI when you sign in with that account. See [Use MCP servers from Claude.ai](/en/mcp#use-mcp-servers-from-claude-ai).287* **Claude.ai**: connectors you add at [claude.ai/customize/connectors](https://claude.ai/customize/connectors) load automatically in the CLI when you sign in with that account. See [Use MCP servers from Claude.ai](/docs/en/mcp#use-mcp-servers-from-claude-ai).

288 288 

289## Troubleshooting289## Troubleshooting

290 290 


330 </Accordion>330 </Accordion>

331 331 

332 <Accordion title="Connection timed out at startup">332 <Accordion title="Connection timed out at startup">

333 The server took longer than the default 30-second startup timeout. A stdio server's first run can be slow while `npx` downloads the package. Increase the limit with the [`MCP_TIMEOUT`](/en/env-vars) environment variable, in milliseconds:333 The server took longer than the default 30-second startup timeout. A stdio server's first run can be slow while `npx` downloads the package. Increase the limit with the [`MCP_TIMEOUT`](/docs/en/env-vars) environment variable, in milliseconds:

334 334 

335 ```bash theme={null}335 ```bash theme={null}

336 MCP_TIMEOUT=60000 claude336 MCP_TIMEOUT=60000 claude


372 </Accordion>372 </Accordion>

373 373 

374 <Accordion title="OAuth sign-in fails or browser doesn't open">374 <Accordion title="OAuth sign-in fails or browser doesn't open">

375 Run `/mcp`, select the server, and choose `Authenticate` again. If the browser doesn't open automatically, copy the URL shown in the terminal and open it manually. See [Authenticate with remote MCP servers](/en/mcp#authenticate-with-remote-mcp-servers) for fixed callback ports and pre-configured credentials.375 Run `/mcp`, select the server, and choose `Authenticate` again. If the browser doesn't open automatically, copy the URL shown in the terminal and open it manually. See [Authenticate with remote MCP servers](/docs/en/mcp#authenticate-with-remote-mcp-servers) for fixed callback ports and pre-configured credentials.

376 </Accordion>376 </Accordion>

377</AccordionGroup>377</AccordionGroup>

378 378 


380 380 

381With one server connected, explore the rest of what MCP enables:381With one server connected, explore the rest of what MCP enables:

382 382 

383* [Find more MCP servers](/en/mcp#find-and-build-mcp-servers) in the Anthropic Directory383* [Find more MCP servers](/docs/en/mcp#find-and-build-mcp-servers) in the Anthropic Directory

384* [Share servers with your team](/en/mcp#mcp-installation-scopes) using installation scopes384* [Share servers with your team](/docs/en/mcp#mcp-installation-scopes) using installation scopes

385* [Manage MCP access for an organization](/en/managed-mcp) with managed settings and policy controls385* [Manage MCP access for an organization](/docs/en/managed-mcp) with managed settings and policy controls

386* [Reference MCP resources](/en/mcp#use-mcp-resources) in prompts with @ mentions386* [Reference MCP resources](/docs/en/mcp#use-mcp-resources) in prompts with @ mentions

387* [Run MCP prompts as commands](/en/mcp#use-mcp-prompts-as-commands) from the `/` menu387* [Run MCP prompts as commands](/docs/en/mcp#use-mcp-prompts-as-commands) from the `/` menu

388* [Build your own server](https://modelcontextprotocol.io/quickstart/server) with the MCP SDK388* [Build your own server](https://modelcontextprotocol.io/quickstart/server) with the MCP SDK

model-config.md +5 −5

Details

412 412 

413#### Ask before switching413#### Ask before switching

414 414 

415To decide what happens each time a request is flagged, rather than switching automatically, run `/config` and turn off "switch models when a message is flagged". A flagged request then pauses the session with two options: switch to the fallback model, or edit the prompt and retry on the current model.415To decide what happens each time a request is flagged, rather than switching automatically, run `/config` and turn off **Switch models when a message is flagged**, or set [`switchModelsOnFlag`](/docs/en/settings#available-settings) to `false` in your settings file. A flagged request then pauses the session with two options: switch to the fallback model, or edit the prompt and retry on the current model.

416 416 

417Some cases behave differently:417Some cases behave differently:

418 418 


603You can use the following environment variables to control the model names that the aliases map to. Each value must be a full model name, or the equivalent identifier for your API provider.603You can use the following environment variables to control the model names that the aliases map to. Each value must be a full model name, or the equivalent identifier for your API provider.

604 604 

605| Environment variable | Description |605| Environment variable | Description |

606| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |606| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

607| `ANTHROPIC_DEFAULT_FABLE_MODEL` | The model to use for `fable`, and the model ID Claude Code recognizes as Fable 5 for [automatic model fallback](#automatic-model-fallback) on third-party providers |607| `ANTHROPIC_DEFAULT_FABLE_MODEL` | The model to use for `fable`, and the model ID Claude Code recognizes as Fable 5 for [automatic model fallback](#automatic-model-fallback) on third-party providers |

608| `ANTHROPIC_DEFAULT_OPUS_MODEL` | The model to use for `opus`, or for `opusplan` when Plan Mode is active. |608| `ANTHROPIC_DEFAULT_OPUS_MODEL` | The model to use for `opus`, or for `opusplan` when Plan Mode is active. |

609| `ANTHROPIC_DEFAULT_SONNET_MODEL` | The model to use for `sonnet`, or for `opusplan` when Plan Mode is not active. |609| `ANTHROPIC_DEFAULT_SONNET_MODEL` | The model to use for `sonnet`, or for `opusplan` when Plan Mode is not active. |

610| `ANTHROPIC_DEFAULT_HAIKU_MODEL` | The model to use for `haiku`, or [background functionality](/docs/en/costs#background-token-usage) |610| `ANTHROPIC_DEFAULT_HAIKU_MODEL` | The model to use for `haiku`, or [background functionality](/docs/en/costs#background-token-usage) |

611| `CLAUDE_CODE_SUBAGENT_MODEL` | The model to use for all [subagents](/docs/en/sub-agents#choose-a-model), [agent teams](/docs/en/agent-teams), and the agents a [workflow](/docs/en/workflows) runs. Accepts an alias such as `haiku` or a full model name, and overrides the per-invocation `model` parameter and the subagent definition's `model` frontmatter. Set to `inherit` to use normal model resolution instead |611| `CLAUDE_CODE_SUBAGENT_MODEL` | The model Claude Code uses for all [subagents](/docs/en/sub-agents#choose-a-model), [agent teams](/docs/en/agent-teams), and agents in a [workflow](/docs/en/workflows). Accepts an alias such as `haiku` or a full model name, and overrides the per-invocation `model` parameter and the subagent definition's `model` frontmatter. Set to `inherit` to use normal model resolution instead |

612 612 

613Note: `ANTHROPIC_SMALL_FAST_MODEL` is deprecated in favor of613Note: `ANTHROPIC_SMALL_FAST_MODEL` is deprecated in favor of

614`ANTHROPIC_DEFAULT_HAIKU_MODEL`.614`ANTHROPIC_DEFAULT_HAIKU_MODEL`.


658These variables take effect on third-party providers such as Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry. The `_NAME` and `_DESCRIPTION` variables also take effect when `ANTHROPIC_BASE_URL` points to an [LLM gateway](/docs/en/llm-gateway). They have no effect when connecting directly to `api.anthropic.com`.658These variables take effect on third-party providers such as Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry. The `_NAME` and `_DESCRIPTION` variables also take effect when `ANTHROPIC_BASE_URL` points to an [LLM gateway](/docs/en/llm-gateway). They have no effect when connecting directly to `api.anthropic.com`.

659 659 

660| Environment variable | Description |660| Environment variable | Description |

661| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |661| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

662| `ANTHROPIC_DEFAULT_OPUS_MODEL_NAME` | Display name for the pinned Opus model in the `/model` picker. Defaults to the model ID when not set |662| `ANTHROPIC_DEFAULT_OPUS_MODEL_NAME` | Display name for the pinned Opus model in the `/model` picker. Defaults to the model ID when not set |

663| `ANTHROPIC_DEFAULT_OPUS_MODEL_DESCRIPTION` | Display description for the pinned Opus model in the `/model` picker. Defaults to `Custom Opus model` when not set |663| `ANTHROPIC_DEFAULT_OPUS_MODEL_DESCRIPTION` | Display description for the pinned Opus model in the `/model` picker. When not set, defaults to `Custom Opus model`, or `Custom Opus model (1M context)` if the pinned model ID has the `[1m]` suffix and `CLAUDE_CODE_DISABLE_1M_CONTEXT` isn't turned on |

664| `ANTHROPIC_DEFAULT_OPUS_MODEL_SUPPORTED_CAPABILITIES` | Comma-separated list of capabilities the pinned Opus model supports |664| `ANTHROPIC_DEFAULT_OPUS_MODEL_SUPPORTED_CAPABILITIES` | Comma-separated list of capabilities the pinned Opus model supports |

665 665 

666The same `_NAME`, `_DESCRIPTION`, and `_SUPPORTED_CAPABILITIES` suffixes are available for `ANTHROPIC_DEFAULT_SONNET_MODEL`, `ANTHROPIC_DEFAULT_HAIKU_MODEL`, `ANTHROPIC_DEFAULT_FABLE_MODEL`, and `ANTHROPIC_CUSTOM_MODEL_OPTION`.666The same `_NAME`, `_DESCRIPTION`, and `_SUPPORTED_CAPABILITIES` suffixes are available for `ANTHROPIC_DEFAULT_SONNET_MODEL`, `ANTHROPIC_DEFAULT_HAIKU_MODEL`, `ANTHROPIC_DEFAULT_FABLE_MODEL`, and `ANTHROPIC_CUSTOM_MODEL_OPTION`.

output-styles.md +15 −15

Details

10 10 

11A custom output style adds your instructions to the system prompt and lets you choose whether to keep Claude Code's built-in software engineering instructions. Keep them when you're changing how Claude communicates but still coding, like always answering with a diagram. Leave them out when Claude isn't doing software engineering at all, like a writing assistant or data analyst.11A custom output style adds your instructions to the system prompt and lets you choose whether to keep Claude Code's built-in software engineering instructions. Keep them when you're changing how Claude communicates but still coding, like always answering with a diagram. Leave them out when Claude isn't doing software engineering at all, like a writing assistant or data analyst.

12 12 

13For instructions about your project, conventions, or codebase, use [CLAUDE.md](/en/memory) instead.13For instructions about your project, conventions, or codebase, use [CLAUDE.md](/docs/en/memory) instead.

14 14 

15## Built-in output styles15## Built-in output styles

16 16 


18 18 

19There are three additional built-in output styles:19There are three additional built-in output styles:

20 20 

21* **Proactive**: Claude executes immediately, makes reasonable assumptions instead of pausing for routine decisions, and prefers action over planning. This is stronger autonomous-execution guidance than [auto mode](/en/permission-modes#eliminate-prompts-with-auto-mode) applies, and it works without changing your permission mode, so you still see permission prompts before tools run.21* **Proactive**: Claude executes immediately, makes reasonable assumptions instead of pausing for routine decisions, and prefers action over planning. This is stronger autonomous-execution guidance than [auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode) applies, and it works without changing your permission mode, so you still see permission prompts before tools run.

22 22 

23* **Explanatory**: Provides educational "Insights" in between helping you complete software engineering tasks. Helps you understand implementation choices and codebase patterns.23* **Explanatory**: Provides educational "Insights" in between helping you complete software engineering tasks. Helps you understand implementation choices and codebase patterns.

24 24 


26 26 

27## Change your output style27## Change your output style

28 28 

29Run `/config` and select **Output style** to pick a style from a menu. Your selection is saved to `.claude/settings.local.json` at the [local project level](/en/settings).29Run `/config` and select **Output style** to pick a style from a menu. Your selection is saved to `.claude/settings.local.json` at the [local project level](/docs/en/settings).

30 30 

31<Note>{/* max-version: 2.1.90 */}The standalone `/output-style` command was deprecated in v2.1.73 and removed in v2.1.91. Use `/config` or edit the `outputStyle` setting directly.</Note>31<Note>{/* max-version: 2.1.90 */}The standalone `/output-style` command was deprecated in v2.1.73 and removed in v2.1.91. Use `/config` or edit the `outputStyle` setting directly.</Note>

32 32 


38}38}

39```39```

40 40 

41Output style is part of the system prompt, which Claude Code reads once at session start. Changes take effect after `/clear` or a new session. See [How Claude Code uses prompt caching](/en/prompt-caching#changing-output-style) for what an output style change does to the cache.41Output style is part of the system prompt, which Claude Code reads once at session start. Changes take effect after `/clear` or a new session. See [How Claude Code uses prompt caching](/docs/en/prompt-caching#changing-output-style) for what an output style change does to the cache.

42 42 

43## Create a custom output style43## Create a custom output style

44 44 


50 50 

51 * User: `~/.claude/output-styles`51 * User: `~/.claude/output-styles`

52 * Project: `.claude/output-styles`52 * Project: `.claude/output-styles`

53 * Managed policy: `.claude/output-styles` inside the [managed settings directory](/en/settings#settings-files)53 * Managed policy: `.claude/output-styles` inside the [managed settings directory](/docs/en/settings#settings-files)

54 54 

55 Project output styles load from every `.claude/output-styles/` between the working directory and the repository root. {/* min-version: 2.1.178 */}As of v2.1.178, when more than one of these nested directories defines a style with the same name, Claude Code uses the one closest to the working directory.55 Project output styles load from every `.claude/output-styles/` between the working directory and the repository root. {/* min-version: 2.1.178 */}As of v2.1.178, when more than one of these nested directories defines a style with the same name, Claude Code uses the one closest to the working directory.

56 </Step>56 </Step>


80 </Step>80 </Step>

81</Steps>81</Steps>

82 82 

83[Plugins](/en/plugins-reference) can also ship output styles in an `output-styles/` directory.83[Plugins](/docs/en/plugins-reference) can also ship output styles in an `output-styles/` directory.

84 84 

85### Frontmatter85### Frontmatter

86 86 


97 97 

98Output styles directly modify Claude Code's system prompt.98Output styles directly modify Claude Code's system prompt.

99 99 

100* All output styles have their own custom instructions added to the end of the system prompt.100* Claude Code adds each output style's custom instructions to the end of the system prompt.

101* All output styles trigger reminders for Claude to adhere to the output style instructions during the conversation.101* All output styles trigger reminders for Claude to adhere to the output style instructions during the conversation.

102* Custom output styles leave out Claude Code's built-in software engineering instructions, such as how to scope changes, write comments, and verify work, unless `keep-coding-instructions` is set to `true`.102* Custom output styles leave out Claude Code's built-in software engineering instructions, such as how to scope changes, write comments, and verify work, unless `keep-coding-instructions` is set to `true`.

103 103 

104Output styles apply to the main conversation only: a [subagent runs its own system prompt](/en/sub-agents#what-loads-at-startup), so styles don't change how subagents respond. A [fork](/en/sub-agents#fork-the-current-conversation) is the exception, because it inherits the parent's full system prompt.104Output styles apply to the main conversation only: a [subagent runs its own system prompt](/docs/en/sub-agents#what-loads-at-startup), so styles don't change how subagents respond. A [fork](/docs/en/sub-agents#fork-the-current-conversation) is the exception, because it inherits the parent's full system prompt.

105 105 

106Token usage depends on the style. Adding instructions to the system prompt increases input tokens, though prompt caching reduces this cost after the first request in a session. The built-in Explanatory and Learning styles produce longer responses than Default by design, which increases output tokens. For custom styles, output token usage depends on what your instructions tell Claude to produce.106Token usage depends on the style. Adding instructions to the system prompt increases input tokens, though prompt caching reduces this cost after the first request in a session. The built-in Explanatory and Learning styles produce longer responses than Default by design, which increases output tokens. For custom styles, output token usage depends on what your instructions tell Claude to produce.

107 107 


112| Feature | How it works | Use it when |112| Feature | How it works | Use it when |

113| :----------------------- | :----------------------------------------------------------- | :---------------------------------------------------------------------- |113| :----------------------- | :----------------------------------------------------------- | :---------------------------------------------------------------------- |

114| Output styles | Modifies the system prompt | You want a different role, tone, or default response format every turn |114| Output styles | Modifies the system prompt | You want a different role, tone, or default response format every turn |

115| [CLAUDE.md](/en/memory) | Adds a user message after the system prompt | Claude should always know your project conventions and codebase context |115| [CLAUDE.md](/docs/en/memory) | Adds a user message after the system prompt | Claude should always know your project conventions and codebase context |

116| `--append-system-prompt` | Appends to the system prompt without removing anything | You want a one-off addition for a single invocation |116| `--append-system-prompt` | Appends to the system prompt without removing anything | You want a one-off addition for a single invocation |

117| [Agents](/en/sub-agents) | Runs a subagent with its own system prompt, model, and tools | You want a separately scoped helper for a focused task |117| [Agents](/docs/en/sub-agents) | Runs a subagent with its own system prompt, model, and tools | You want a separately scoped helper for a focused task |

118| [Skills](/en/skills) | Loads task-specific instructions when invoked or relevant | You have a reusable workflow |118| [Skills](/docs/en/skills) | Loads task-specific instructions when invoked or relevant | You have a reusable workflow |

119 119 

120## Related resources120## Related resources

121 121 

122* [Settings](/en/settings): where the `outputStyle` field lives and how settings precedence works122* [Settings](/docs/en/settings): where the `outputStyle` field lives and how settings precedence works

123* [Permission modes](/en/permission-modes): how the Proactive style compares to auto mode123* [Permission modes](/docs/en/permission-modes): how the Proactive style compares to auto mode

124* [Plugins](/en/plugins): package and distribute output styles alongside skills, hooks, and agents124* [Plugins](/docs/en/plugins): package and distribute output styles alongside skills, hooks, and agents

125* [Debug your configuration](/en/debug-your-config): diagnose why an output style isn't taking effect125* [Debug your configuration](/docs/en/debug-your-config): diagnose why an output style isn't taking effect

Details

207Auto mode is available only when your account meets all of these requirements:207Auto mode is available only when your account meets all of these requirements:

208 208 

209* **Plan**: All plans.209* **Plan**: All plans.

210* **Owner**: on Team and Enterprise, an Owner must enable it in [Claude Code admin settings](https://claude.ai/admin-settings/claude-code) before users can turn it on. Administrators can also turn auto mode off by setting `permissions.disableAutoMode` to `"disable"` in [managed settings](/docs/en/permissions#managed-settings). For the desktop app's Code tab, `disableAutoMode` is the organization-level control, and the admin settings toggle doesn't apply.210* **Organization**: on Team and Enterprise, auto mode is available by default. Administrators can turn it off for the organization by setting `permissions.disableAutoMode` to `"disable"` in [managed settings](/docs/en/permissions#managed-settings).

211* **Model**: on the Anthropic API and [Claude Platform on AWS](/docs/en/claude-platform-on-aws), Claude Opus 4.6 or later, Sonnet 4.6 or later, or [Fable 5](/docs/en/model-config#work-with-fable-5). On Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, and signed-in [Claude apps gateway](/docs/en/claude-apps-gateway) sessions, only Claude Sonnet 5, Opus 4.7 or later, and Fable 5. Older models, including Sonnet 4.5, Opus 4.5, Haiku, and claude-3 models, are not supported on any provider.211* **Model**: on the Anthropic API and [Claude Platform on AWS](/docs/en/claude-platform-on-aws), Claude Opus 4.6 or later, Sonnet 4.6 or later, or [Fable 5](/docs/en/model-config#work-with-fable-5). On Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, and signed-in [Claude apps gateway](/docs/en/claude-apps-gateway) sessions, only Claude Sonnet 5, Opus 4.7 or later, and Fable 5. Older models, including Sonnet 4.5, Opus 4.5, Haiku, and claude-3 models, are not supported on any provider.

212* **Provider**: available by default on the Anthropic API, Claude Platform on AWS, Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, and signed-in Claude apps gateway sessions. {/* min-version: 2.1.207 */}In v2.1.158 through v2.1.206, auto mode was off on all of these providers except the Anthropic API and Claude Platform on AWS until you set `CLAUDE_CODE_ENABLE_AUTO_MODE=1`; v2.1.207 removed the requirement.212* **Provider**: available by default on the Anthropic API, Claude Platform on AWS, Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, and signed-in Claude apps gateway sessions. {/* min-version: 2.1.207 */}In v2.1.158 through v2.1.206, auto mode was off on all of these providers except the Anthropic API and Claude Platform on AWS until you set `CLAUDE_CODE_ENABLE_AUTO_MODE=1`; v2.1.207 removed the requirement.

213 213 

permissions.md +4 −4

Details

6 6 

7> Control what Claude Code can access and do with fine-grained permission rules, modes, and managed policies.7> Control what Claude Code can access and do with fine-grained permission rules, modes, and managed policies.

8 8 

9Claude Code supports fine-grained permissions so that you can specify exactly what the agent is allowed to do and what it can't. Permission settings can be checked into version control and distributed to all developers in your organization, as well as customized by individual developers.9Claude Code supports fine-grained permissions so that you can specify exactly what the agent is allowed to do and what it can't. You can check permission settings into version control to share them with every developer in your organization, and each developer can customize their own.

10 10 

11## Permission system11## Permission system

12 12 


110* The value is compared against the literal input Claude sends, before any normalization. `Agent(model:opus)` matches the alias `opus` but not a full model ID. Run with [`--verbose`](/docs/en/cli-reference) to see the exact parameter names and values in each tool call110* The value is compared against the literal input Claude sends, before any normalization. `Agent(model:opus)` matches the alias `opus` but not a full model ID. Run with [`--verbose`](/docs/en/cli-reference) to see the exact parameter names and values in each tool call

111* Whitespace around the colon is ignored111* Whitespace around the colon is ignored

112 112 

113Fields that a tool already matches with its own canonicalizing rules are not matchable this way: `command` for Bash and PowerShell, `file_path` for Read, Edit, and Write, `path` for Grep and Glob, `notebook_path` for NotebookEdit, and `url` for WebFetch. A rule like `Bash(command:rm *)` would be bypassable by a compound command, so Claude Code ignores it and emits a startup warning. Use `Bash(rm *)`, `Read(./path)`, or `WebFetch(domain:host)` instead.113You can't match a tool's primary content field this way: `command` for Bash and PowerShell, `file_path` for Read, Edit, and Write, `path` for Grep and Glob, `notebook_path` for NotebookEdit, and `url` for WebFetch. A rule like `Bash(command:rm *)` would be bypassable by a compound command, so Claude Code ignores it and emits a startup warning. Use `Bash(rm *)`, `Read(./path)`, or `WebFetch(domain:host)` instead.

114 114 

115### Wildcard patterns115### Wildcard patterns

116 116 


260 260 

261{/* min-version: 2.1.208 */}A `Read` deny rule also blocks the [Edit tool](/docs/en/errors#file-is-covered-by-a-read-deny-rule) on the same path, including creating a new file there. Write and NotebookEdit aren't covered, so add an `Edit` deny rule for paths no tool may change. Requires Claude Code v2.1.208 or later.261{/* min-version: 2.1.208 */}A `Read` deny rule also blocks the [Edit tool](/docs/en/errors#file-is-covered-by-a-read-deny-rule) on the same path, including creating a new file there. Write and NotebookEdit aren't covered, so add an `Edit` deny rule for paths no tool may change. Requires Claude Code v2.1.208 or later.

262 262 

263{/* min-version: 2.1.210 */}The file permission checks match only `Edit(path)` and `Read(path)` rules. A `Write(path)`, `NotebookEdit(path)`, or `Glob(path)` rule is accepted but never matched by those checks, so Claude Code warns at startup for each allow, deny, or ask rule in one of these unmatched forms. Use `Edit(docs/**)` in place of `Write(docs/**)` or `NotebookEdit(docs/**)`, and `Read(docs/**)` in place of `Glob(docs/**)`. A tool-name rule with no path, such as a deny rule for `Write`, isn't affected: it matches the tool everywhere and produces no warning. Requires Claude Code v2.1.210 or later.263{/* min-version: 2.1.210 */}Claude Code checks file permissions against `Edit(path)` and `Read(path)` rules only. If you write a path rule for `Write`, `NotebookEdit`, `Glob`, or the legacy `MultiEdit` tool instead, Claude Code accepts the rule but never consults it, and [warns at startup](/docs/en/errors#is-not-matched-by-file-permission-checks), except for a `Glob` rule passed in `--allowedTools`. Use `Edit(docs/**)` in place of `Write(docs/**)`, `NotebookEdit(docs/**)`, or `MultiEdit(docs/**)`, and `Read(docs/**)` in place of `Glob(docs/**)`. Claude Code doesn't warn about a tool-name rule with no path, such as a deny rule for `Write`; it matches that rule at the tool level everywhere. Requires Claude Code v2.1.210 or later.

264 264 

265A deny rule `Write(docs/**)` in project settings produces this startup warning:265If you put a deny rule `Write(docs/**)` in project settings, Claude Code prints this startup warning:

266 266 

267```text theme={null}267```text theme={null}

268Permission deny rule (.claude/settings.json): Write(docs/**) is not matched by file permission checks — only Edit(path) rules are. Use Edit(docs/**) instead (Edit rules cover all file-editing tools).268Permission deny rule (.claude/settings.json): Write(docs/**) is not matched by file permission checks — only Edit(path) rules are. Use Edit(docs/**) instead (Edit rules cover all file-editing tools).

plugin-hints.md +9 −9

Details

10 10 

11Claude Code strips the hint line from the command output before sending it to the model, so the marker never appears in the conversation and is not counted toward token usage. The protocol requires no extra commands and does not change what your CLI prints for users outside Claude Code.11Claude Code strips the hint line from the command output before sending it to the model, so the marker never appears in the conversation and is not counted toward token usage. The protocol requires no extra commands and does not change what your CLI prints for users outside Claude Code.

12 12 

13This page is for CLI and SDK maintainers. If you are looking to install plugins, see [Discover and install plugins](/en/discover-plugins).13This page is for CLI and SDK maintainers. If you are looking to install plugins, see [Discover and install plugins](/docs/en/discover-plugins).

14 14 

15## How it works15## How it works

16 16 

17Claude Code sets the [`CLAUDECODE`](/en/env-vars) environment variable to `1` for every command it runs through the Bash and PowerShell tools, and for [hook](/en/hooks) commands. {/* min-version: 2.1.172 */}From v2.1.172 it also sets [`CLAUDE_CODE_CHILD_SESSION`](/en/env-vars) to `1` in those same subprocesses. When your CLI sees one of these variables, it writes a self-closing `<claude-code-hint />` tag to stderr. In hook commands the hint tag is stripped and ignored. Only Bash and PowerShell tool output triggers the install prompt.17Claude Code sets the [`CLAUDECODE`](/docs/en/env-vars) environment variable to `1` for every command it runs through the Bash and PowerShell tools, and for [hook](/docs/en/hooks) commands. {/* min-version: 2.1.172 */}From v2.1.172 it also sets [`CLAUDE_CODE_CHILD_SESSION`](/docs/en/env-vars) to `1` in those same subprocesses. When your CLI sees one of these variables, it writes a self-closing `<claude-code-hint />` tag to stderr. In hook commands the hint tag is stripped and ignored. Only Bash and PowerShell tool output triggers the install prompt.

18 18 

19When Claude Code receives the command output, it:19When Claude Code receives the command output, it:

20 20 


32Gate emission on an environment variable so the marker is unlikely to appear when a human runs your CLI directly, then write the tag to stderr on its own line. Choose which variable to check:32Gate emission on an environment variable so the marker is unlikely to appear when a human runs your CLI directly, then write the tag to stderr on its own line. Choose which variable to check:

33 33 

34* `CLAUDECODE`: set on every Claude Code version, so it reaches the most sessions. It is also set in tmux sessions and stdio MCP server subprocesses that Claude Code starts. IDE extensions also set it in their integrated terminals, where a human may be running your CLI directly.34* `CLAUDECODE`: set on every Claude Code version, so it reaches the most sessions. It is also set in tmux sessions and stdio MCP server subprocesses that Claude Code starts. IDE extensions also set it in their integrated terminals, where a human may be running your CLI directly.

35* {/* min-version: 2.1.172 */}`CLAUDE_CODE_CHILD_SESSION`: set only in subprocesses Claude Code itself spawns, such as tool calls, hook commands, and [status line](/en/statusline) commands, so the tag does not normally reach a human terminal. A long-lived process that was started inside a session, such as a tmux server, captures the variable, so shells later launched from that process still show the raw tag. Requires Claude Code v2.1.172 or later, so sessions on older versions miss the hint.35* {/* min-version: 2.1.172 */}`CLAUDE_CODE_CHILD_SESSION`: set only in subprocesses Claude Code itself spawns, such as tool calls, hook commands, and [status line](/docs/en/statusline) commands, so the tag does not normally reach a human terminal. A long-lived process that was started inside a session, such as a tmux server, captures the variable, so shells later launched from that process still show the raw tag. Requires Claude Code v2.1.172 or later, so sessions on older versions miss the hint.

36 36 

37The following examples gate on `CLAUDECODE` for maximum reach and emit a hint for a plugin named `example-cli` in the official marketplace:37The following examples gate on `CLAUDECODE` for maximum reach and emit a hint for a plugin named `example-cli` in the official marketplace:

38 38 


104─────────────────────────────────────────────────────────────104─────────────────────────────────────────────────────────────

105```105```

106 106 

107The prompt names the command that produced the hint so users can spot a mismatch between the tool and the plugin it recommends. If the user does not respond within 30 seconds, the prompt dismisses as **No**.107The prompt names the command that produced the hint so users can spot a mismatch between the tool and the plugin it recommends. If the user doesn't respond within 30 seconds, Claude Code dismisses the prompt as **No**.

108 108 

109Prompt frequency is bounded, and some sessions never prompt:109Prompt frequency is bounded, and some sessions never prompt:

110 110 

111* **Once per plugin**: after the prompt is shown, Claude Code records the plugin and never prompts for it again, regardless of the user's answer.111* **Once per plugin**: after the prompt is shown, Claude Code records the plugin and never prompts for it again, regardless of the user's answer.

112* **Once per session**: across all CLIs on the machine, at most one hint prompt appears per Claude Code session.112* **Once per session**: across all CLIs on the machine, at most one hint prompt appears per Claude Code session.

113* **Telemetry opt-outs**: sessions where analytics are disabled never show hint prompts. This includes sessions with `DISABLE_TELEMETRY` or `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` set, and sessions on third-party providers such as Amazon Bedrock or Google Cloud's Agent Platform where the [automatic telemetry opt-out](/en/data-usage#default-behaviors-by-api-provider) applies.113* **Telemetry opt-outs**: sessions where analytics are disabled never show hint prompts. This includes sessions with `DISABLE_TELEMETRY` or `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` set, and sessions on third-party providers such as Amazon Bedrock or Google Cloud's Agent Platform where the [automatic telemetry opt-out](/docs/en/data-usage#default-behaviors-by-api-provider) applies.

114 114 

115Selecting **Yes** installs the plugin to user scope. Selecting **No, and don't show plugin installation hints again** disables all future hint prompts for the user.115Selecting **Yes** installs the plugin to user scope. Selecting **No, and don't show plugin installation hints again** disables all future hint prompts for the user.

116 116 


146 146 

147## Get your plugin into the official marketplace147## Get your plugin into the official marketplace

148 148 

149The hint protocol only takes effect for plugins listed in the official Anthropic marketplace, `claude-plugins-official`. Anthropic curates that marketplace at its discretion, and the in-app submission forms add plugins to the [community marketplace](/en/plugins#submit-your-plugin-to-the-community-marketplace) instead, which the hint protocol does not check. If you are working with an Anthropic partner contact, reach out to them to coordinate an official-marketplace listing.149The hint protocol only takes effect for plugins listed in the official Anthropic marketplace, `claude-plugins-official`. Anthropic curates that marketplace at its discretion, and the in-app submission forms add plugins to the [community marketplace](/docs/en/plugins#submit-your-plugin-to-the-community-marketplace) instead, which the hint protocol does not check. If you are working with an Anthropic partner contact, reach out to them to coordinate an official-marketplace listing.

150 150 

151## See also151## See also

152 152 

153* [Create plugins](/en/plugins): build the plugin your CLI recommends153* [Create plugins](/docs/en/plugins): build the plugin your CLI recommends

154* [Create and distribute a plugin marketplace](/en/plugin-marketplaces): host plugins outside the official marketplace154* [Create and distribute a plugin marketplace](/docs/en/plugin-marketplaces): host plugins outside the official marketplace

155* [Environment variables](/en/env-vars): full reference for `CLAUDECODE` and related variables155* [Environment variables](/docs/en/env-vars): full reference for `CLAUDECODE` and related variables

Details

259 259 

260On most git hosts, including GitHub, GitLab, and Bitbucket, this means installation succeeds even if the branch or tag named by `ref` has since been deleted upstream, as long as the commit is still reachable from the repository. Some servers, such as AWS CodeCommit, don't support fetching commits by SHA. On those servers the `ref` must still exist and the pinned commit must be reachable from it.260On most git hosts, including GitHub, GitLab, and Bitbucket, this means installation succeeds even if the branch or tag named by `ref` has since been deleted upstream, as long as the commit is still reachable from the repository. Some servers, such as AWS CodeCommit, don't support fetching commits by SHA. On those servers the `ref` must still exist and the pinned commit must be reachable from it.

261 261 

262<Note>

263 If you distribute this marketplace through [Organization settings > Plugins](https://claude.ai/admin-settings/plugins) on a Team or Enterprise plan, different source rules apply:

264 

265 * The marketplace repository must be private or internal. Organization sync reads it through the Claude GitHub App or your organization's GitHub Enterprise App.

266 * Plugin sources of type `github`, `url`, and `git-subdir` are supported. `npm` sources are not.

267 * A plugin source can be private in two cases: a github.com source that shares the marketplace repository's owner, or a source on your organization's GitHub Enterprise host with the GHE App installed on the repository. Organization sync fetches every other source without credentials, so github.com repositories under a different owner and repositories on other hosts, such as GitLab or Bitbucket, must be public.

268 

269 To include private plugins, place the plugin folders inside the marketplace repository and reference them with a [relative path](#relative-paths). Organization sync packages each plugin during distribution, so users never need access to a separate source repository. See [Manage plugins for your organization](https://support.claude.com/en/articles/13837433) for the admin workflow.

270</Note>

271 

262### Relative paths272### Relative paths

263 273 

264For plugins in the same repository, use a path starting with `./`:274For plugins in the same repository, use a path starting with `./`:


536 546 

537### Private repositories547### Private repositories

538 548 

539Claude Code supports installing plugins from private repositories. For manual installation and updates, Claude Code uses your existing git credential helpers, so HTTPS access via `gh auth login`, macOS Keychain, or `git-credential-store` works the same as in your terminal. SSH access works as long as the host is already in your `known_hosts` file and the key is loaded in `ssh-agent`, since Claude Code suppresses interactive SSH prompts for the host fingerprint and key passphrase. GitHub `owner/repo` shorthand sources clone over SSH by default; set [`CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1`](/docs/en/env-vars#variables) to clone them over HTTPS instead.549Claude Code supports installing plugins from private repositories. If you distribute your marketplace through [Organization settings > Plugins](https://claude.ai/admin-settings/plugins) instead, your git credentials aren't involved: organization sync reads the marketplace repository through the Claude GitHub App or your organization's GitHub Enterprise App, and a plugin source it can't authenticate to must be public. The note under [Plugin sources](#plugin-sources) has the full rules.

540 550 

541Background auto-updates work differently. By default, the background refresh disables git credential helpers for its `git pull`, so the pull can't authenticate to private repositories over HTTPS even when a helper is configured. SSH remotes aren't affected: a key loaded in `ssh-agent` authenticates background pulls the same way as manual operations. When the background pull fails, Claude Code falls back to re-cloning the marketplace from scratch. The re-clone does use your stored git credentials, but it can [time out on large repositories](#git-operations-time-out), so private-marketplace auto-updates may fail intermittently.551#### Commands you run

552 

553When you run `/plugin marketplace add`, `/plugin install`, `/plugin update`, or `/plugin marketplace update`, Claude Code uses your existing git credential helpers, so HTTPS access via `gh auth login`, macOS Keychain, or `git-credential-store` works the same as in your terminal. SSH access works as long as the host is already in your `known_hosts` file and the key is loaded in `ssh-agent`, since Claude Code suppresses interactive SSH prompts for the host fingerprint and key passphrase. GitHub `owner/repo` shorthand sources clone over SSH by default; set [`CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1`](/docs/en/env-vars#variables) to clone them over HTTPS instead.

554 

555#### Background auto-updates

556 

557By default, the background refresh disables git credential helpers for its `git pull`, so the pull can't authenticate to private repositories over HTTPS even when a helper is configured. SSH remotes aren't affected: a key loaded in `ssh-agent` authenticates background pulls the same way as the commands you run. When the background pull fails, Claude Code falls back to re-cloning the marketplace from scratch. The re-clone does use your stored git credentials, but it can [time out on large repositories](#git-operations-time-out), so private-marketplace auto-updates may fail intermittently.

542 558 

543Two settings make private marketplaces behave predictably:559Two settings make private marketplaces behave predictably:

544 560 


657When `strictKnownMarketplaces` is configured in managed settings, the restriction behavior depends on the value:673When `strictKnownMarketplaces` is configured in managed settings, the restriction behavior depends on the value:

658 674 

659| Value | Behavior |675| Value | Behavior |

660| ------------------- | ---------------------------------------------------------------- |676| ------------------- | ------------------------------------------------------------------------------------------------ |

661| Undefined (default) | No restrictions. Users can add any marketplace |677| Undefined (default) | No restrictions. Users can add any marketplace |

662| Empty array `[]` | Complete lockdown. Users can't add any new marketplaces |678| Empty array `[]` | Complete lockdown. Blocks every marketplace source, including the official Anthropic marketplace |

663| List of sources | Users can only add marketplaces that match the allowlist exactly |679| List of sources | Users can only add marketplaces that match the allowlist exactly |

664 680 

665#### Common configurations681#### Common configurations

666 682 

667Disable all marketplace additions:683Disable all marketplace additions, including the official Anthropic marketplace:

668 684 

669```json theme={null}685```json theme={null}

670{686{


672}688}

673```689```

674 690 

691Allow only the official Anthropic marketplace. Matching is exact, so this entry doesn't cover `ref` or `path` variants of the same repository:

692 

693```json theme={null}

694{

695 "strictKnownMarketplaces": [

696 {

697 "source": "github",

698 "repo": "anthropics/claude-plugins-official"

699 }

700 ]

701}

702```

703 

704With this entry, the official marketplace registers itself automatically the first time you start Claude Code interactively, so you don't need to pair it with `extraKnownMarketplaces`. In a non-interactive environment that runs before that first interactive launch, add it explicitly with `claude plugin marketplace add anthropics/claude-plugins-official` or include it in `extraKnownMarketplaces`.

705 

675Allow specific marketplaces only:706Allow specific marketplaces only:

676 707 

677```json theme={null}708```json theme={null}


732 763 

733The allowlist uses exact matching for most source types. For a marketplace to be allowed, all specified fields must match exactly:764The allowlist uses exact matching for most source types. For a marketplace to be allowed, all specified fields must match exactly:

734 765 

735* For GitHub sources: `repo` is required, and `ref` or `path` must also match if specified in the allowlist766* For GitHub sources: `repo` is required, and `ref` and `path` must each match exactly or be absent from both the marketplace source and the allowlist entry

736* For URL sources: the full URL must match exactly767* For URL sources: the full URL must match exactly

737* For `hostPattern` sources: the marketplace host is matched against the regex pattern768* For `hostPattern` sources: the marketplace host is matched against the regex pattern

738* For `pathPattern` sources: the marketplace's filesystem path is matched against the regex pattern769* For `pathPattern` sources: the marketplace's filesystem path is matched against the regex pattern

Details

189* Servers appear as standard MCP tools in Claude's toolkit189* Servers appear as standard MCP tools in Claude's toolkit

190* Server capabilities integrate seamlessly with Claude's existing tools190* Server capabilities integrate seamlessly with Claude's existing tools

191* Plugin servers can be configured independently of user MCP servers191* Plugin servers can be configured independently of user MCP servers

192* If you run [`/reload-plugins`](/docs/en/discover-plugins#apply-plugin-changes-without-restarting) mid-session, Claude Code keeps the live connections of servers whose configuration is unchanged

192 193 

193### LSP servers194### LSP servers

194 195 


332 333 

333A monitor `command` can't reference [`${user_config.*}`](#user-configuration) values. The command runs through a shell, so Claude Code rejects the monitor with an [error](/docs/en/errors#plugin-command-references-user-config) instead of substituting the value. Monitor processes don't receive `CLAUDE_PLUGIN_OPTION_<KEY>` environment variables, so have the monitor script read the value from a config file it owns. Before v2.1.207, monitor commands substituted `${user_config.*}` values.334A monitor `command` can't reference [`${user_config.*}`](#user-configuration) values. The command runs through a shell, so Claude Code rejects the monitor with an [error](/docs/en/errors#plugin-command-references-user-config) instead of substituting the value. Monitor processes don't receive `CLAUDE_PLUGIN_OPTION_<KEY>` environment variables, so have the monitor script read the value from a config file it owns. Before v2.1.207, monitor commands substituted `${user_config.*}` values.

334 335 

335Disabling a plugin mid-session does not stop monitors that are already running. They stop when the session ends.336If you disable a plugin mid-session, Claude Code doesn't stop monitors that are already running; they stop when the session ends.

336 337 

337### Themes338### Themes

338 339 


350}351}

351```352```

352 353 

353Selecting a plugin theme persists `custom:<plugin-name>:<slug>` in the user's config. Plugin themes are read-only; pressing `Ctrl+E` on one in `/theme` copies it into `~/.claude/themes/` so the user can edit the copy.354When a user selects a plugin theme, Claude Code saves `custom:<plugin-name>:<slug>` in their config. Plugin themes are read-only: when a user presses `Ctrl+E` on one in `/theme`, Claude Code copies it into `~/.claude/themes/` so they can edit the copy.

354 355 

355***356***

356 357 

Details

18 18 

19<img src="https://mintcdn.com/claude-code/VbDJw--l6T9a9Wvm/images/prompt-caching-prefix.svg?fit=max&auto=format&n=VbDJw--l6T9a9Wvm&q=85&s=f2e8f0b8298a50305fe428ca3f1d1594" className="dark:hidden" alt="Four turns shown as growing horizontal bars. Each turn's request contains everything from the previous turn plus the latest exchange appended at the end. On turns two and three, the unchanged prefix is read from cache and only the new exchange is processed. On turn four, the system prompt changed, so the prefix no longer matches and the entire request is reprocessed and written." width="720" height="454" data-path="images/prompt-caching-prefix.svg" />19<img src="https://mintcdn.com/claude-code/VbDJw--l6T9a9Wvm/images/prompt-caching-prefix.svg?fit=max&auto=format&n=VbDJw--l6T9a9Wvm&q=85&s=f2e8f0b8298a50305fe428ca3f1d1594" className="dark:hidden" alt="Four turns shown as growing horizontal bars. Each turn's request contains everything from the previous turn plus the latest exchange appended at the end. On turns two and three, the unchanged prefix is read from cache and only the new exchange is processed. On turn four, the system prompt changed, so the prefix no longer matches and the entire request is reprocessed and written." width="720" height="454" data-path="images/prompt-caching-prefix.svg" />

20 20 

21<img src="https://mintcdn.com/claude-code/VbDJw--l6T9a9Wvm/images/prompt-caching-prefix-dark.svg?fit=max&auto=format&n=VbDJw--l6T9a9Wvm&q=85&s=7434a04e08187edd26ec6c3dd332f624" className="hidden dark:block" alt="Four turns shown as growing horizontal bars. Each turn's request contains everything from the previous turn plus the latest exchange appended at the end. On turns two and three, the unchanged prefix is read from cache and only the new exchange is processed. On turn four, the system prompt changed, so the prefix no longer matches and the entire request is reprocessed and written." width="720" height="454" data-path="images/prompt-caching-prefix-dark.svg" />21<img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/prompt-caching-prefix-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=297dc1c639f0915cae858d0c4b6f3be5" className="hidden dark:block" alt="Four turns shown as growing horizontal bars. Each turn's request contains everything from the previous turn plus the latest exchange appended at the end. On turns two and three, the unchanged prefix is read from cache and only the new exchange is processed. On turn four, the system prompt changed, so the prefix no longer matches and the entire request is reprocessed and written." width="720" height="454" data-path="images/prompt-caching-prefix-dark.svg" />

22 22 

23To get the most out of prefix matching, Claude Code orders each request so content that rarely changes between turns comes first:23To get the most out of prefix matching, Claude Code orders each request so content that rarely changes between turns comes first:

24 24 

prompt-library.md +25 −25

Details

998 998 

999This is a library of prompts to copy into Claude Code. Use it to explore ways of working you haven't tried, or when you're not sure where to start.999This is a library of prompts to copy into Claude Code. Use it to explore ways of working you haven't tried, or when you're not sure where to start.

1000 1000 

1001The prompts are collected from various Anthropic guides, including [Common workflows](/en/common-workflows), [Best practices](/en/best-practices), and [How Anthropic teams use Claude Code](https://claude.com/blog/how-anthropic-teams-use-claude-code). They're starting points rather than scripts. Open **Why this works** under any prompt to see the pattern behind it so you can write your own.1001The prompts are collected from various Anthropic guides, including [Common workflows](/docs/en/common-workflows), [Best practices](/docs/en/best-practices), and [How Anthropic teams use Claude Code](https://claude.com/blog/how-anthropic-teams-use-claude-code). They're starting points rather than scripts. Open **Why this works** under any prompt to see the pattern behind it so you can write your own.

1002 1002 

1003export const labels = {1003export const labels = {

1004 startHere: "Start here",1004 startHere: "Start here",


1029 },1029 },

1030 needsLabel: "Needs",1030 needsLabel: "Needs",

1031 needs: {1031 needs: {

1032 tracker: "your issue tracker added as a [claude.ai connector](/en/mcp#use-mcp-servers-from-claude-ai) or [MCP server](/en/mcp).",1032 tracker: "your issue tracker added as a [claude.ai connector](/docs/en/mcp#use-mcp-servers-from-claude-ai) or [MCP server](/docs/en/mcp).",

1033 gh: "the [gh CLI](https://cli.github.com) authenticated, or GitHub added as a [claude.ai connector](/en/mcp#use-mcp-servers-from-claude-ai).",1033 gh: "the [gh CLI](https://cli.github.com) authenticated, or GitHub added as a [claude.ai connector](/docs/en/mcp#use-mcp-servers-from-claude-ai).",

1034 browser: "a way for Claude to render and screenshot the result. The [Desktop app](/en/desktop#preview-your-app) has this built in. In the terminal, install the [Chrome extension](/en/chrome) or a Playwright [MCP](/en/mcp) server.",1034 browser: "a way for Claude to render and screenshot the result. The [Desktop app](/docs/en/desktop#preview-your-app) has this built in. In the terminal, install the [Chrome extension](/docs/en/chrome) or a Playwright [MCP](/docs/en/mcp) server.",

1035 db: "your data warehouse or log store added as a [claude.ai connector](/en/mcp#use-mcp-servers-from-claude-ai) or [MCP server](/en/mcp)."1035 db: "your data warehouse or log store added as a [claude.ai connector](/docs/en/mcp#use-mcp-servers-from-claude-ai) or [MCP server](/docs/en/mcp)."

1036 }1036 }

1037};1037};

1038 1038 


1127 },1127 },

1128 "plan-a-multi-file": {1128 "plan-a-multi-file": {

1129 title: "Plan a multi-file change before touching code",1129 title: "Plan a multi-file change before touching code",

1130 teaches: "Adding \"don't edit yet\" separates exploration from changes, so you see the approach before any code moves. To make plan-first the default on every prompt, press Shift+Tab for [plan mode](/en/permission-modes#analyze-before-you-edit-with-plan-mode)."1130 teaches: "Adding \"don't edit yet\" separates exploration from changes, so you see the approach before any code moves. To make plan-first the default on every prompt, press Shift+Tab for [plan mode](/docs/en/permission-modes#analyze-before-you-edit-with-plan-mode)."

1131 },1131 },

1132 "draft-a-spec-by": {1132 "draft-a-spec-by": {

1133 title: "Draft a spec by interview",1133 title: "Draft a spec by interview",


1136 },1136 },

1137 "turn-a-meeting-into": {1137 "turn-a-meeting-into": {

1138 title: "Turn a meeting into tickets",1138 title: "Turn a meeting into tickets",

1139 teaches: "Skip the transcription step. Claude pulls action items from the unstructured input and writes them straight into your tracker via [MCP](/en/mcp), so you review the tickets, not the transcript.",1139 teaches: "Skip the transcription step. Claude pulls action items from the unstructured input and writes them straight into your tracker via [MCP](/docs/en/mcp), so you review the tickets, not the transcript.",

1140 next: "Save this as a `/tickets` skill"1140 next: "Save this as a `/tickets` skill"

1141 },1141 },

1142 "map-edge-cases-before": {1142 "map-edge-cases-before": {


1230 },1230 },

1231 "run-a-security-review": {1231 "run-a-security-review": {

1232 title: "Run a security review with a subagent",1232 title: "Run a security review with a subagent",

1233 teaches: "A [subagent](/en/sub-agents) runs the audit in its own context window and reports back a summary, so a long security review doesn't fill up your main session. The built-in general-purpose subagent handles this without extra setup.",1233 teaches: "A [subagent](/docs/en/sub-agents) runs the audit in its own context window and reports back a summary, so a long security review doesn't fill up your main session. The built-in general-purpose subagent handles this without extra setup.",

1234 next: "Set up a dedicated security-review subagent your whole team can use"1234 next: "Set up a dedicated security-review subagent your whole team can use"

1235 },1235 },

1236 "review-content-before-sending": {1236 "review-content-before-sending": {


1249 },1249 },

1250 "turn-a-correction-into": {1250 "turn-a-correction-into": {

1251 title: "Turn a correction into a rule",1251 title: "Turn a correction into a rule",

1252 teaches: "A correction in chat isn't shared with your team. A rule in the project's [CLAUDE.md](/en/memory) is shared once you commit it, and Claude reads it at the start of every session.",1252 teaches: "A correction in chat isn't shared with your team. A rule in the project's [CLAUDE.md](/docs/en/memory) is shared once you commit it, and Claude reads it at the start of every session.",

1253 next: "Open `/memory` to review what Claude wrote"1253 next: "Open `/memory` to review what Claude wrote"

1254 },1254 },

1255 "resolve-merge-conflicts": {1255 "resolve-merge-conflicts": {


1311 },1311 },

1312 "turn-a-recurring-task": {1312 "turn-a-recurring-task": {

1313 title: "Turn a recurring task into a skill",1313 title: "Turn a recurring task into a skill",

1314 teaches: "Name the steps once; reuse them as a command. Claude writes a [skill](/en/skills) anyone on your team can run."1314 teaches: "Name the steps once; reuse them as a command. Claude writes a [skill](/docs/en/skills) anyone on your team can run."

1315 },1315 },

1316 "add-a-hook-for": {1316 "add-a-hook-for": {

1317 title: "Add a hook for repeat behavior",1317 title: "Add a hook for repeat behavior",

1318 teaches: "Hooks make a behavior automatic instead of something you have to remember to ask for. Describe the trigger and action and Claude writes the [hook](/en/hooks) configuration."1318 teaches: "Hooks make a behavior automatic instead of something you have to remember to ask for. Describe the trigger and action and Claude writes the [hook](/docs/en/hooks) configuration."

1319 },1319 },

1320 "connect-a-tool-with": {1320 "connect-a-tool-with": {

1321 title: "Connect a tool with MCP",1321 title: "Connect a tool with MCP",

1322 teaches: "Connect the source once instead of pasting data every session. After [MCP](/en/mcp) setup, Claude reads from the tool directly when you ask about it."1322 teaches: "Connect the source once instead of pasting data every session. After [MCP](/docs/en/mcp) setup, Claude reads from the tool directly when you ask about it."

1323 },1323 },

1324 "capture-what-to-remember": {1324 "capture-what-to-remember": {

1325 title: "Capture what to remember for next time",1325 title: "Capture what to remember for next time",

1326 teaches: "Ask before you forget. Claude knows what it had to figure out this session and proposes [CLAUDE.md](/en/memory) entries so the next session starts with that context."1326 teaches: "Ask before you forget. Claude knows what it had to figure out this session and proposes [CLAUDE.md](/docs/en/memory) entries so the next session starts with that context."

1327 }1327 }

1328};1328};

1329 1329 


1335 1335 

1336**Describe the outcome, not the steps.** Say what you want and let Claude find the files. The prompt below works without naming a single file path.1336**Describe the outcome, not the steps.** Say what you want and let Claude find the files. The prompt below works without naming a single file path.

1337 1337 

1338```text theme={null}1338```text wrap theme={null}

1339add rate limiting to the public API and make sure existing tests still pass1339add rate limiting to the public API and make sure existing tests still pass

1340```1340```

1341 1341 

1342**Give it a way to check its own work.** Ask for run, test, compare, or verify in the same prompt so Claude iterates instead of stopping after one attempt.1342**Give it a way to check its own work.** Ask for run, test, compare, or verify in the same prompt so Claude iterates instead of stopping after one attempt.

1343 1343 

1344```text theme={null}1344```text wrap theme={null}

1345write the migration, run it against the dev database, and confirm the schema matches1345write the migration, run it against the dev database, and confirm the schema matches

1346```1346```

1347 1347 

1348**Point at a reference.** Name an existing file, test, or pattern to match so the new code is consistent with what you already have.1348**Point at a reference.** Name an existing file, test, or pattern to match so the new code is consistent with what you already have.

1349 1349 

1350```text theme={null}1350```text wrap theme={null}

1351add a settings page that follows the same layout as the profile page1351add a settings page that follows the same layout as the profile page

1352```1352```

1353 1353 

1354**State the measurable target.** When the goal is performance or coverage, give the metric and threshold so completion is unambiguous.1354**State the measurable target.** When the goal is performance or coverage, give the metric and threshold so completion is unambiguous.

1355 1355 

1356```text theme={null}1356```text wrap theme={null}

1357get the bundle size under 200KB and show me what you removed1357get the bundle size under 200KB and show me what you removed

1358```1358```

1359 1359 

1360**Give it the artifact.** Paste errors, logs, screenshots, and plan output directly in the prompt, or type `@` to reference a file. Claude reads the source instead of your description of it.1360**Give it the artifact.** Paste errors, logs, screenshots, and plan output directly in the prompt, or type `@` to reference a file. Claude reads the source instead of your description of it.

1361 1361 

1362```text theme={null}1362```text wrap theme={null}

1363why is the build failing? @build.log1363why is the build failing? @build.log

1364```1364```

1365 1365 

1366**Say how you want the answer.** Name the format, length, or audience so the explanation fits how you'll use it. To make a format the default for every response, set an [output style](/en/output-styles).1366**Say how you want the answer.** Name the format, length, or audience so the explanation fits how you'll use it. To make a format the default for every response, set an [output style](/docs/en/output-styles).

1367 1367 

1368```text theme={null}1368```text wrap theme={null}

1369explain how the payment retry logic works as an HTML page with a diagram, then open it in my browser1369explain how the payment retry logic works as an HTML page with a diagram, then open it in my browser

1370```1370```

1371 1371 

1372For more on each pattern, see [best practices](/en/best-practices).1372For more on each pattern, see [best practices](/docs/en/best-practices).

1373 1373 

1374## Where these come from1374## Where these come from

1375 1375 

1376These prompts are based on patterns from published Anthropic resources. Each card links to its source:1376These prompts are based on patterns from published Anthropic resources. Each card links to its source:

1377 1377 

1378* [Common workflows](/en/common-workflows): step-by-step guides for the core tasks1378* [Common workflows](/docs/en/common-workflows): step-by-step guides for the core tasks

1379* [Best practices](/en/best-practices): prompting patterns and project setup1379* [Best practices](/docs/en/best-practices): prompting patterns and project setup

1380* [How Anthropic teams use Claude Code](https://claude.com/blog/how-anthropic-teams-use-claude-code): real workflows from engineering, product, design, and data teams, with deep dives on [legal](https://claude.com/blog/how-anthropic-uses-claude-legal), [marketing](https://claude.com/blog/how-anthropic-uses-claude-marketing), and [cybersecurity](https://claude.com/blog/how-anthropic-uses-claude-cybersecurity)1380* [How Anthropic teams use Claude Code](https://claude.com/blog/how-anthropic-teams-use-claude-code): real workflows from engineering, product, design, and data teams, with deep dives on [legal](https://claude.com/blog/how-anthropic-uses-claude-legal), [marketing](https://claude.com/blog/how-anthropic-uses-claude-marketing), and [cybersecurity](https://claude.com/blog/how-anthropic-uses-claude-cybersecurity)

1381* [Scaling agentic coding guide](https://resources.anthropic.com/hubfs/Scaling%20agentic%20coding%20across%20your%20organization.pdf): the enterprise adoption guide1381* [Scaling agentic coding guide](https://resources.anthropic.com/hubfs/Scaling%20agentic%20coding%20across%20your%20organization.pdf): the enterprise adoption guide

1382 1382 


1384 1384 

1385## Related resources1385## Related resources

1386 1386 

1387The prompts on this page are starting points. Once one works for your project, the next step is making it repeatable: save it as a [skill](/en/skills) so anyone on your team can run it as a `/command`, and record the conventions Claude learned in [CLAUDE.md](/en/memory) so every session starts with that context instead of Claude relearning it. For larger or riskier changes, [plan mode](/en/permission-modes#analyze-before-you-edit-with-plan-mode) shows you the file list before any edits happen.1387The prompts on this page are starting points. Once one works for your project, the next step is making it repeatable: save it as a [skill](/docs/en/skills) so anyone on your team can run it as a `/command`, and record the conventions Claude learned in [CLAUDE.md](/docs/en/memory) so every session starts with that context instead of Claude relearning it. For larger or riskier changes, [plan mode](/docs/en/permission-modes#analyze-before-you-edit-with-plan-mode) shows you the file list before any edits happen.

1388 1388 

1389If you're introducing Claude Code across a team, see [administration](/en/admin-setup) for managed settings and policy, and [costs and usage](/en/costs) for how this work is billed on your plan.1389If you're introducing Claude Code across a team, see [administration](/docs/en/admin-setup) for managed settings and policy, and [costs and usage](/docs/en/costs) for how this work is billed on your plan.

quickstart.md +23 −23

Details

99 99 

100For Claude subscription or Console accounts, follow the prompts to complete authentication in your browser. If you've set the `ANTHROPIC_API_KEY` environment variable, Claude Code skips the login prompt and asks you to approve the key instead. To switch accounts later or re-authenticate, type `/login` inside the running session:100For Claude subscription or Console accounts, follow the prompts to complete authentication in your browser. If you've set the `ANTHROPIC_API_KEY` environment variable, Claude Code skips the login prompt and asks you to approve the key instead. To switch accounts later or re-authenticate, type `/login` inside the running session:

101 101 

102```text theme={null}102```text wrap theme={null}

103/login103/login

104```104```

105 105 


133 133 

134Let's start with understanding your codebase. Try one of these commands:134Let's start with understanding your codebase. Try one of these commands:

135 135 

136```text theme={null}136```text wrap theme={null}

137what does this project do?137what does this project do?

138```138```

139 139 

140Claude will analyze your files and provide a summary. You can also ask more specific questions:140Claude will analyze your files and provide a summary. You can also ask more specific questions:

141 141 

142```text theme={null}142```text wrap theme={null}

143what technologies does this project use?143what technologies does this project use?

144```144```

145 145 

146```text theme={null}146```text wrap theme={null}

147where is the main entry point?147where is the main entry point?

148```148```

149 149 

150```text theme={null}150```text wrap theme={null}

151explain the folder structure151explain the folder structure

152```152```

153 153 

154You can also ask Claude about its own capabilities:154You can also ask Claude about its own capabilities:

155 155 

156```text theme={null}156```text wrap theme={null}

157what can Claude Code do?157what can Claude Code do?

158```158```

159 159 

160```text theme={null}160```text wrap theme={null}

161how do I create custom skills in Claude Code?161how do I create custom skills in Claude Code?

162```162```

163 163 

164```text theme={null}164```text wrap theme={null}

165can Claude Code work with Docker?165can Claude Code work with Docker?

166```166```

167 167 


173 173 

174Now let's make Claude Code do some actual coding. Try a simple task:174Now let's make Claude Code do some actual coding. Try a simple task:

175 175 

176```text theme={null}176```text wrap theme={null}

177add a hello world function to the main file177add a hello world function to the main file

178```178```

179 179 


192 192 

193Claude Code makes Git operations conversational:193Claude Code makes Git operations conversational:

194 194 

195```text theme={null}195```text wrap theme={null}

196what files have I changed?196what files have I changed?

197```197```

198 198 

199```text theme={null}199```text wrap theme={null}

200commit my changes with a descriptive message200commit my changes with a descriptive message

201```201```

202 202 

203You can also prompt for more complex Git operations:203You can also prompt for more complex Git operations:

204 204 

205```text theme={null}205```text wrap theme={null}

206create a new branch called feature/quickstart206create a new branch called feature/quickstart

207```207```

208 208 

209```text theme={null}209```text wrap theme={null}

210show me the last 5 commits210show me the last 5 commits

211```211```

212 212 

213```text theme={null}213```text wrap theme={null}

214help me resolve merge conflicts214help me resolve merge conflicts

215```215```

216 216 


220 220 

221Describe what you want in natural language:221Describe what you want in natural language:

222 222 

223```text theme={null}223```text wrap theme={null}

224add input validation to the user registration form224add input validation to the user registration form

225```225```

226 226 

227Or fix existing issues:227Or fix existing issues:

228 228 

229```text theme={null}229```text wrap theme={null}

230there's a bug where users can submit empty forms - fix it230there's a bug where users can submit empty forms - fix it

231```231```

232 232 


243 243 

244**Refactor code**244**Refactor code**

245 245 

246```text theme={null}246```text wrap theme={null}

247refactor the authentication module to use async/await instead of callbacks247refactor the authentication module to use async/await instead of callbacks

248```248```

249 249 

250**Write tests**250**Write tests**

251 251 

252```text theme={null}252```text wrap theme={null}

253write unit tests for the calculator functions253write unit tests for the calculator functions

254```254```

255 255 

256**Update documentation**256**Update documentation**

257 257 

258```text theme={null}258```text wrap theme={null}

259update the README with installation instructions259update the README with installation instructions

260```260```

261 261 

262**Code review**262**Code review**

263 263 

264```text theme={null}264```text wrap theme={null}

265review my changes and suggest improvements265review my changes and suggest improvements

266```266```

267 267 


307 <Accordion title="Use step-by-step instructions">307 <Accordion title="Use step-by-step instructions">

308 Break complex tasks into steps:308 Break complex tasks into steps:

309 309 

310 ```text theme={null}310 ```text wrap theme={null}

311 1. create a new database table for user profiles311 1. create a new database table for user profiles

312 2. create an API endpoint to get and update user profiles312 2. create an API endpoint to get and update user profiles

313 3. build a webpage that allows users to see and edit their information313 3. build a webpage that allows users to see and edit their information


317 <Accordion title="Let Claude explore first">317 <Accordion title="Let Claude explore first">

318 Before making changes, let Claude understand your code:318 Before making changes, let Claude understand your code:

319 319 

320 ```text theme={null}320 ```text wrap theme={null}

321 analyze the database schema321 analyze the database schema

322 ```322 ```

323 323 

324 ```text theme={null}324 ```text wrap theme={null}

325 build a dashboard showing products that are most frequently returned by our UK customers325 build a dashboard showing products that are most frequently returned by our UK customers

326 ```326 ```

327 </Accordion>327 </Accordion>

routines.md +8 −8

Details

50 50 

51The creation form sets up the routine's prompt, repositories, environment, connectors, and triggers.51The creation form sets up the routine's prompt, repositories, environment, connectors, and triggers.

52 52 

53Routines run autonomously as full Claude Code cloud sessions: there is no permission-mode picker and no approval prompts during a run. The session can run shell commands, use [skills](/docs/en/skills) committed to the cloned repository, and call any connectors you include. What a routine can reach is determined by the repositories you select and their branch-push setting, the [environment's](/docs/en/cloud-environments) network access and variables, and the connectors you include. Scope each of those to what the routine actually needs.53Routines run autonomously as full Claude Code cloud sessions: there is no permission-mode picker and no approval prompts during a run. The session can run shell commands, use [skills](/docs/en/skills) committed to the cloned repository, and call any connectors you include. What a routine can reach is determined by the repositories you select, the [environment's](/docs/en/cloud-environments) network access and variables, and the connectors you include. Scope each of those to what the routine actually needs.

54 54 

55Routines belong to your individual claude.ai account. They are not shared with teammates, and they count against your account's daily run allowance. Anything a routine does through your connected GitHub identity or connectors appears as you: commits and pull requests carry your GitHub user, and Slack messages, Linear tickets, or other connector actions use your linked accounts for those services.55Routines belong to your individual claude.ai account. They are not shared with teammates, and they count against your account's daily run allowance. Anything a routine does through your connected GitHub identity or connectors appears as you: commits and pull requests carry your GitHub user, and Slack messages, Linear tickets, or other connector actions use your linked accounts for those services.

56 56 


101 </Tabs>101 </Tabs>

102 </Step>102 </Step>

103 103 

104 <Step title="Review connectors and permissions">104 <Step title="Review connectors">

105 The **Connectors** and **Permissions** tabs at the bottom of the form control what the routine can reach.105 Under **Connectors** at the bottom of the form, all of your connected [MCP connectors](/docs/en/mcp) are included by default. Remove any the routine doesn't need: Claude can use every tool from an included connector, including writes, without asking for permission during a run.

106 

107 Under Connectors, all of your connected [MCP connectors](/docs/en/mcp) are included by default. Remove any the routine doesn't need. Claude can use every tool from an included connector, including writes, without asking for permission during a run.

108 

109 Under Permissions, enable **Allow unrestricted branch pushes** for any repository where Claude should be able to push to existing branches instead of only `claude/`-prefixed ones.

110 </Step>106 </Step>

111 107 

112 <Step title="Create the routine">108 <Step title="Create the routine">


326 322 

327Each repository you add is cloned on every run. Claude starts from the repository's default branch unless your prompt specifies otherwise.323Each repository you add is cloned on every run. Claude starts from the repository's default branch unless your prompt specifies otherwise.

328 324 

329By default, Claude can only push to branches prefixed with `claude/`. This prevents routines from accidentally modifying protected or long-lived branches. To remove this restriction for a specific repository, enable **Allow unrestricted branch pushes** for that repository when creating or editing the routine.325Claude pushes its work to branches prefixed with `claude/`, which are always accepted. When your prompt directs Claude to push to another branch, Claude Code checks the push first and rejects it if any of the following is true:

326 

327* The branch is protected on GitHub

328* Someone else has an open pull request from that branch

329* The branch carries commits authored by someone other than you

330 330 

331### Connectors331### Connectors

332 332 

sandboxing.md +2 −2

Details

46 </Step>46 </Step>

47</Steps>47</Steps>

48 48 

49Selecting a mode in the panel writes to your project's local settings at `.claude/settings.local.json`, which apply to the current project. Claude Code adds that file to your global gitignore when it saves a setting there. To enable the sandbox across all of your projects, set [`sandbox.enabled`](/docs/en/settings#sandbox-settings) to `true` in your user settings at `~/.claude/settings.json`. To enforce sandboxing for every developer in an organization, use [managed settings](#enforce-sandboxing-with-managed-settings).49When you select a mode in the panel, Claude Code saves it to your project's local settings at `.claude/settings.local.json`, which apply to the current project. Claude Code adds that file to your global gitignore when it saves a setting there. To enable the sandbox across all of your projects, set [`sandbox.enabled`](/docs/en/settings#sandbox-settings) to `true` in your user settings at `~/.claude/settings.json`. To enforce sandboxing for every developer in an organization, use [managed settings](#enforce-sandboxing-with-managed-settings).

50 50 

51<Warning>51<Warning>

52 By default, if the sandbox cannot start because dependencies are missing or the platform is unsupported, Claude Code shows a warning and runs commands without sandboxing. To make this a hard failure instead, set [`sandbox.failIfUnavailable`](/docs/en/settings#sandbox-settings) to `true`. This is intended for managed deployments that require sandboxing as a security gate.52 By default, if the sandbox cannot start because dependencies are missing or the platform is unsupported, Claude Code shows a warning and runs commands without sandboxing. To make this a hard failure instead, set [`sandbox.failIfUnavailable`](/docs/en/settings#sandbox-settings) to `true`. This is intended for managed deployments that require sandboxing as a security gate.


117 117 

118Claude Code offers two sandbox modes:118Claude Code offers two sandbox modes:

119 119 

120**Auto-allow mode**: Bash commands will attempt to run inside the sandbox and are automatically allowed without requiring permission. Commands that cannot be sandboxed, such as those needing network access to non-allowed hosts, fall back to the regular permission flow, where Claude Code checks your [permission rules](/docs/en/permissions) and gates any command those rules do not already allow, with a prompt in default mode or the classifier in [auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode).120**Auto-allow mode**: when a command can be sandboxed, Claude Code runs it inside the sandbox and approves it automatically, without asking your permission. Commands that cannot be sandboxed, such as those needing network access to non-allowed hosts, fall back to the regular permission flow, where Claude Code checks your [permission rules](/docs/en/permissions) and gates any command those rules do not already allow, with a prompt in default mode or the classifier in [auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode).

121 121 

122Even in auto-allow mode, the following still apply:122Even in auto-allow mode, the following still apply:

123 123 

Details

24 24 

25## Choose between server-managed and endpoint-managed settings25## Choose between server-managed and endpoint-managed settings

26 26 

27Claude Code supports two approaches for centralized configuration. Server-managed settings deliver configuration from Anthropic's servers. [Endpoint-managed settings](/en/settings#settings-files) are deployed directly to devices through native OS policies (macOS managed preferences, Windows registry) or managed settings files.27Claude Code supports two approaches for centralized configuration. Server-managed settings deliver configuration from Anthropic's servers. [Endpoint-managed settings](/docs/en/settings#settings-files) are deployed directly to devices through native OS policies (macOS managed preferences, Windows registry) or managed settings files.

28 28 

29| Approach | Best for | Security model |29| Approach | Best for | Security model |

30| :----------------------------------------------------------- | :------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------- |30| :----------------------------------------------------------- | :------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------- |

31| **Server-managed settings** | Organizations without MDM, or users on unmanaged devices | Settings delivered from Anthropic's servers at authentication time |31| **Server-managed settings** | Organizations without MDM, or users on unmanaged devices | Settings delivered from Anthropic's servers at authentication time |

32| **[Endpoint-managed settings](/en/settings#settings-files)** | Organizations with MDM or endpoint management | Settings deployed to devices via MDM configuration profiles, registry policies, or managed settings files |32| **[Endpoint-managed settings](/docs/en/settings#settings-files)** | Organizations with MDM or endpoint management | Settings deployed to devices via MDM configuration profiles, registry policies, or managed settings files |

33 33 

34If your devices are enrolled in an MDM or endpoint management solution, endpoint-managed settings provide stronger security guarantees because the settings file can be protected from user modification at the OS level. Endpoint-managed settings don't reach [cloud sessions](/en/model-config#surface-coverage), so organizations using Claude Code on the web should configure server-managed settings as well.34If your devices are enrolled in an MDM or endpoint management solution, endpoint-managed settings provide stronger security guarantees because the settings file can be protected from user modification at the OS level. Endpoint-managed settings don't reach [cloud sessions](/docs/en/model-config#surface-coverage), so organizations using Claude Code on the web should configure server-managed settings as well.

35 35 

36## Configure server-managed settings36## Configure server-managed settings

37 37 


43 </Step>43 </Step>

44 44 

45 <Step title="Define your settings">45 <Step title="Define your settings">

46 Add your configuration as JSON. All [settings available in `settings.json`](/en/settings#available-settings) are supported except those restricted to OS-level policy delivery; see [Current limitations](#current-limitations) for that short list. This includes [hooks](/en/hooks), [environment variables](/en/env-vars), and [managed-only settings](/en/permissions#managed-only-settings) like `allowManagedPermissionRulesOnly`.46 Add your configuration as JSON. All [settings available in `settings.json`](/docs/en/settings#available-settings) are supported except those restricted to OS-level policy delivery; see [Current limitations](#current-limitations) for that short list. This includes [hooks](/docs/en/hooks), [environment variables](/docs/en/env-vars), and [managed-only settings](/docs/en/permissions#managed-only-settings) like `allowManagedPermissionRulesOnly`.

47 47 

48 This example enforces a permission deny list, prevents users from bypassing permissions, and restricts permission rules to those defined in managed settings:48 This example enforces a permission deny list, prevents users from bypassing permissions, and restricts permission rules to those defined in managed settings:

49 49 


81 }81 }

82 ```82 ```

83 83 

84 To configure the [auto mode](/en/permission-modes#eliminate-prompts-with-auto-mode) classifier so it knows which repos, buckets, and domains your organization trusts:84 To configure the [auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode) classifier so it knows which repos, buckets, and domains your organization trusts:

85 85 

86 ```json theme={null}86 ```json theme={null}

87 {87 {


95 }95 }

96 ```96 ```

97 97 

98 Because hooks execute shell commands, users see a [security approval dialog](#security-approval-dialogs) before they're applied. See [Configure auto mode](/en/auto-mode-config) for how the `autoMode` entries affect what the classifier blocks and important warnings about the `environment`, `allow`, `soft_deny`, and `hard_deny` fields.98 Because hooks execute shell commands, users see a [security approval dialog](#security-approval-dialogs) before they're applied. See [Configure auto mode](/docs/en/auto-mode-config) for how the `autoMode` entries affect what the classifier blocks and important warnings about the `environment`, `allow`, `soft_deny`, and `hard_deny` fields.

99 </Step>99 </Step>

100 100 

101 <Step title="Save and deploy">101 <Step title="Save and deploy">


118 118 

119### Managed-only settings119### Managed-only settings

120 120 

121Most [settings keys](/en/settings#available-settings) work in any scope. A handful of keys are only read from managed settings and have no effect when placed in user or project settings files. See [managed-only settings](/en/permissions#managed-only-settings) for the full list. Any setting not on that list can still be placed in managed settings and takes the highest precedence.121Most [settings keys](/docs/en/settings#available-settings) work in any scope. A handful of keys are only read from managed settings and have no effect when placed in user or project settings files. See [managed-only settings](/docs/en/permissions#managed-only-settings) for the full list. Any setting not on that list can still be placed in managed settings and takes the highest precedence.

122 122 

123### Current limitations123### Current limitations

124 124 

125Server-managed settings have the following limitations:125Server-managed settings have the following limitations:

126 126 

127* Settings apply uniformly to all users in the organization. Per-group configurations are not yet supported.127* Settings apply uniformly to all users in the organization. Per-group configurations are not yet supported.

128* A [`managed-mcp.json`](/en/managed-mcp) file can't be distributed through server-managed settings. Deliver the `allowedMcpServers` and `deniedMcpServers` policy keys there instead.128* A [`managed-mcp.json`](/docs/en/managed-mcp) file can't be distributed through server-managed settings. Deliver the `allowedMcpServers` and `deniedMcpServers` policy keys there instead.

129* Settings restricted to OS-level policy sources, such as `policyHelper` and `wslInheritsWindowsSettings`, are not honored. Deploy them through MDM or a system `managed-settings.json` file instead.129* Settings restricted to OS-level policy sources, such as `policyHelper` and `wslInheritsWindowsSettings`, are not honored. Deploy them through MDM or a system `managed-settings.json` file instead.

130 130 

131## Settings delivery131## Settings delivery

132 132 

133### Settings precedence133### Settings precedence

134 134 

135Server-managed settings and [endpoint-managed settings](/en/settings#settings-files) both occupy the highest tier in the Claude Code [settings hierarchy](/en/settings#settings-precedence). No other settings level can override them, including command line arguments.135Server-managed settings and [endpoint-managed settings](/docs/en/settings#settings-files) both occupy the highest tier in the Claude Code [settings hierarchy](/docs/en/settings#settings-precedence). No other settings level can override them, including command line arguments.

136 136 

137Within the managed tier, a configured [`policyHelper`](/en/settings#compute-managed-settings-with-a-policy-helper) preempts every other managed source, including server-managed settings: its output becomes the only managed configuration for the run.137Within the managed tier, a configured [`policyHelper`](/docs/en/settings#compute-managed-settings-with-a-policy-helper) preempts every other managed source, including server-managed settings: its output becomes the only managed configuration for the run.

138 138 

139Otherwise, Claude Code uses the first source that delivers a non-empty configuration. Server-managed settings are checked first, then endpoint-managed settings. Sources don't merge: if server-managed settings deliver any keys at all, other endpoint-managed settings are ignored. If server-managed settings deliver nothing, endpoint-managed settings apply.139Otherwise, Claude Code uses the first source that delivers a non-empty configuration. Server-managed settings are checked first, then endpoint-managed settings. Sources don't merge: if server-managed settings deliver any keys at all, other endpoint-managed settings are ignored. If server-managed settings deliver nothing, endpoint-managed settings apply.

140 140 

141A small set of [cross-source lock keys](/en/settings#settings-precedence), such as the sandbox allowlist locks, is honored when any admin-controlled managed source sets them; the user-writable HKCU registry tier is excluded, and when a [`policyHelper`](/en/settings#compute-managed-settings-with-a-policy-helper) is configured, its output is the only source these checks read.141A small set of [cross-source lock keys](/docs/en/settings#settings-precedence), such as the sandbox allowlist locks, is honored when any admin-controlled managed source sets them; the user-writable HKCU registry tier is excluded, and when a [`policyHelper`](/docs/en/settings#compute-managed-settings-with-a-policy-helper) is configured, its output is the only source these checks read.

142 142 

143If you clear your server-managed configuration in the admin console with the intent of falling back to an endpoint-managed plist or registry policy, be aware that [cached settings](#fetch-and-caching-behavior) persist on client machines until the next successful fetch. Run `/status` to see which managed source is active.143If you clear your server-managed configuration in the admin console with the intent of falling back to an endpoint-managed plist or registry policy, be aware that [cached settings](#fetch-and-caching-behavior) persist on client machines until the next successful fetch. Run `/status` to see which managed source is active.

144 144 


158* Claude Code fetches fresh settings in the background158* Claude Code fetches fresh settings in the background

159* Cached settings persist through network failures. The withheld environment variables remain withheld until a fetch succeeds159* Cached settings persist through network failures. The withheld environment variables remain withheld until a fetch succeeds

160 160 

161As of v2.1.198, Claude Code withholds three categories of variables in the cached `env` block until the server confirms the payload for the session. This keeps a cached proxy, certificate authority, endpoint, or credential value from redirecting, intercepting, or re-authenticating the settings fetch that confirms the payload. The hardening applies only to the server-fetched settings cache: [endpoint-managed settings](/en/settings#settings-files) deployed through MDM or `managed-settings.json` are unaffected. The withheld categories are:161As of v2.1.198, Claude Code withholds three categories of variables in the cached `env` block until the server confirms the payload for the session. This keeps a cached proxy, certificate authority, endpoint, or credential value from redirecting, intercepting, or re-authenticating the settings fetch that confirms the payload. The hardening applies only to the server-fetched settings cache: [endpoint-managed settings](/docs/en/settings#settings-files) deployed through MDM or `managed-settings.json` are unaffected. The withheld categories are:

162 162 

163* Proxy and TLS configuration, such as `HTTPS_PROXY`, `NODE_EXTRA_CA_CERTS`, and the mTLS client certificate variables `CLAUDE_CODE_CLIENT_CERT` and `CLAUDE_CODE_CLIENT_KEY`163* Proxy and TLS configuration, such as `HTTPS_PROXY`, `NODE_EXTRA_CA_CERTS`, and the mTLS client certificate variables `CLAUDE_CODE_CLIENT_CERT` and `CLAUDE_CODE_CLIENT_KEY`

164* API routing and provider selection, including `ANTHROPIC_BASE_URL`, the provider selection variables such as `CLAUDE_CODE_USE_BEDROCK` and `CLAUDE_CODE_USE_VERTEX`, and the provider endpoint URLs such as `ANTHROPIC_BEDROCK_BASE_URL`164* API routing and provider selection, including `ANTHROPIC_BASE_URL`, the provider selection variables such as `CLAUDE_CODE_USE_BEDROCK` and `CLAUDE_CODE_USE_VERTEX`, and the provider endpoint URLs such as `ANTHROPIC_BEDROCK_BASE_URL`


166 166 

167Every other key in the cached `env` block, such as telemetry and OpenTelemetry configuration, applies at startup as before. Once the fetch succeeds, the withheld variables apply for the rest of the session.167Every other key in the cached `env` block, such as telemetry and OpenTelemetry configuration, applies at startup as before. Once the fetch succeeds, the withheld variables apply for the rest of the session.

168 168 

169If your organization needs a proxy to reach `api.anthropic.com`, set it in the shell environment or in [user settings](/en/settings#settings-files) rather than only in the managed `env` block. The first launch has no cache, so those sources were already required for the initial fetch.169If your organization needs a proxy to reach `api.anthropic.com`, set it in the shell environment or in [user settings](/docs/en/settings#settings-files) rather than only in the managed `env` block. The first launch has no cache, so those sources were already required for the initial fetch.

170 170 

171Claude Code applies settings updates automatically without a restart, except for advanced settings like OpenTelemetry configuration, which require a full restart to take effect.171Claude Code applies settings updates automatically without a restart, except for advanced settings like OpenTelemetry configuration, which require a full restart to take effect.

172 172 

173### Invalid entries in delivered settings173### Invalid entries in delivered settings

174 174 

175Delivered payloads parse tolerantly with the same rules as the other managed sources. When a payload contains an entry that fails schema validation, Claude Code strips that entry, surfaces a validation error, and applies every remaining valid setting. See [Invalid entries in managed settings](/en/settings#invalid-entries-in-managed-settings) for the field-level behavior, including how security-enforcement fields are handled. Requires Claude Code v2.1.169 or later.175Delivered payloads parse tolerantly with the same rules as the other managed sources. When a payload contains an entry that fails schema validation, Claude Code strips that entry, surfaces a validation error, and applies every remaining valid setting. See [Invalid entries in managed settings](/docs/en/settings#invalid-entries-in-managed-settings) for the field-level behavior, including how security-enforcement fields are handled. Requires Claude Code v2.1.169 or later.

176 176 

177Server-managed delivery adds these behaviors:177Server-managed delivery adds these behaviors:

178 178 


196}196}

197```197```

198 198 

199You can also set this key in an [endpoint-managed](/en/settings#settings-files) MDM profile or system `managed-settings.json` file to enforce fail-closed behavior on first launch, before any server payload has been delivered. As of v2.1.191, this flag is an exception to the [precedence rule](#settings-precedence) above: it is honored when set in any admin-controlled managed source even if a cached server-managed payload is also present, so an MDM-delivered value is not ignored when server-managed settings exist. When a [`policyHelper`](/en/settings#compute-managed-settings-with-a-policy-helper) is configured, its output replaces every other managed source, this key included.199You can also set this key in an [endpoint-managed](/docs/en/settings#settings-files) MDM profile or system `managed-settings.json` file to enforce fail-closed behavior on first launch, before any server payload has been delivered. As of v2.1.191, this flag is an exception to the [precedence rule](#settings-precedence) above: it is honored when set in any admin-controlled managed source even if a cached server-managed payload is also present, so an MDM-delivered value is not ignored when server-managed settings exist. When a [`policyHelper`](/docs/en/settings#compute-managed-settings-with-a-policy-helper) is configured, its output replaces every other managed source, this key included.

200 200 

201The settings fetch also sends a `Cache-Control: no-cache` header so intermediate HTTP proxies don't serve a stale response.201The settings fetch also sends a `Cache-Control: no-cache` header so intermediate HTTP proxies don't serve a stale response.

202 202 


209Certain settings that could pose security risks require explicit user approval before Claude Code applies them:209Certain settings that could pose security risks require explicit user approval before Claude Code applies them:

210 210 

211* **Shell command settings**: settings that execute shell commands211* **Shell command settings**: settings that execute shell commands

212* **Custom environment variables**: variables not in the known safe allowlist212* **Custom environment variables**: delivered `env` variables that require the user's approval, such as proxy and base-URL variables; see [Environment variables and the approval dialog](#environment-variables-and-the-approval-dialog)

213* **Hook configurations**: any hook definition213* **Hook configurations**: any hook definition

214* **Managed CLAUDE.md content**: a `claudeMd` value delivered through managed settings214* **Managed CLAUDE.md content**: a `claudeMd` value delivered through managed settings

215 215 


221 A non-interactive run, such as `claude -p` or an Agent SDK session, can't show the dialog. When the delivered settings would require approval, Claude Code applies them for that run only: it doesn't record them as approved or write them to the [local cache](#fetch-and-caching-behavior), and the next interactive session shows the dialog. Until a user approves in an interactive session, each non-interactive run fetches the settings again at startup. Before v2.1.207, a non-interactive run saved the settings as approved, so later interactive sessions never showed the dialog for them.221 A non-interactive run, such as `claude -p` or an Agent SDK session, can't show the dialog. When the delivered settings would require approval, Claude Code applies them for that run only: it doesn't record them as approved or write them to the [local cache](#fetch-and-caching-behavior), and the next interactive session shows the dialog. Until a user approves in an interactive session, each non-interactive run fetches the settings again at startup. Before v2.1.207, a non-interactive run saved the settings as approved, so later interactive sessions never showed the dialog for them.

222</Note>222</Note>

223 223 

224#### Environment variables and the approval dialog

225 

226Claude Code applies some delivered `env` variables without showing the user the approval dialog, including:

227 

228* Feature and command toggles

229* Model selection and behavior settings, such as `ANTHROPIC_MODEL`, `DISABLE_PROMPT_CACHING`, and `CLAUDE_CODE_EFFORT_LEVEL`

230* Context window and compaction settings, such as `DISABLE_AUTO_COMPACT`

231* Terminal UI and accessibility options

232* Numeric limits, budgets, and timeouts

233 

234Other delivered variables can require the user'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, so the user sees exactly what the policy is asking to set. Before v2.1.218, Claude Code applied fewer variables without asking the user, so settings such as `DISABLE_AUTO_COMPACT` triggered the dialog at any non-empty value.

235 

236Claude Code decides whether four privacy toggles need approval by the delivered value rather than by the variable name: `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`, `DISABLE_ERROR_REPORTING`, `DISABLE_TELEMETRY`, and `DO_NOT_TRACK`. A truthy value such as `1` or `true` only turns tracking, reporting, or other nonessential traffic off, so Claude Code applies it without asking the user. For any other non-empty value, Claude Code shows the dialog. Before v2.1.218, all of them except `DO_NOT_TRACK` applied without approval at any value, and `DO_NOT_TRACK` triggered the dialog at any non-empty value.

237 

224## Platform availability238## Platform availability

225 239 

226Server-managed settings require a direct connection to `api.anthropic.com`, and delivery requires the session to authenticate with an organization OAuth login or a directly configured API key. Keys returned by an [`apiKeyHelper`](/en/settings#available-settings) script don't trigger the settings fetch.240Server-managed settings require a direct connection to `api.anthropic.com`, and delivery requires the session to authenticate with an organization OAuth login or a directly configured API key. Keys returned by an [`apiKeyHelper`](/docs/en/settings#available-settings) script don't trigger the settings fetch.

227 241 

228Server-managed settings are not available when using third-party model providers:242Server-managed settings are not available when using third-party model providers:

229 243 

230* Amazon Bedrock244* Amazon Bedrock

231* Google Cloud's Agent Platform245* Google Cloud's Agent Platform

232* Microsoft Foundry246* Microsoft Foundry

233* [Claude Platform on AWS](/en/claude-platform-on-aws)247* [Claude Platform on AWS](/docs/en/claude-platform-on-aws)

234* Custom API endpoints via `ANTHROPIC_BASE_URL` or third-party [LLM gateways](/en/llm-gateway)248* Custom API endpoints via `ANTHROPIC_BASE_URL` or third-party [LLM gateways](/docs/en/llm-gateway)

235 249 

236If you export a `CLAUDE_CODE_USE_*` provider variable or a non-default `ANTHROPIC_BASE_URL` in your shell, Claude Code skips the settings fetch for your sessions. You can't clear the export with a server-managed `env` block, because the block arrives through the fetch that the export prevents. An [endpoint-managed settings](/en/settings#settings-files) `env` block doesn't restore the fetch either: Claude Code checks eligibility before it applies managed `env` blocks, so the override changes the session's provider selection but the fetch stays skipped.250If you export a `CLAUDE_CODE_USE_*` provider variable or a non-default `ANTHROPIC_BASE_URL` in your shell, Claude Code skips the settings fetch for your sessions. You can't clear the export with a server-managed `env` block, because the block arrives through the fetch that the export prevents. An [endpoint-managed settings](/docs/en/settings#settings-files) `env` block doesn't restore the fetch either: Claude Code checks eligibility before it applies managed `env` blocks, so the override changes the session's provider selection but the fetch stays skipped.

237 251 

238To restore server-managed delivery, remove the export from your shell, or set the variable to `""` in your user settings `env` block, which applies before the eligibility check. To enforce policy without relying on users to change their shells, deliver the settings through the endpoint-managed channel instead.252To restore server-managed delivery, remove the export from your shell, or set the variable to `""` in your user settings `env` block, which applies before the eligibility check. To enforce policy without relying on users to change their shells, deliver the settings through the endpoint-managed channel instead.

239 253 

240For Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry deployments, a self-hosted [Claude apps gateway](/en/claude-apps-gateway) provides the equivalent remote managed-settings delivery: gateway-signed-in clients fetch managed settings from the gateway instead of `api.anthropic.com`. The failure semantics differ at startup: a gateway client that can't reach the gateway exits with an error instead of falling back to cached settings, while the hourly background refresh is fail-open on both channels.254For Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry deployments, a self-hosted [Claude apps gateway](/docs/en/claude-apps-gateway) provides the equivalent remote managed-settings delivery: gateway-signed-in clients fetch managed settings from the gateway instead of `api.anthropic.com`. The failure semantics differ at startup: a gateway client that can't reach the gateway exits with an error instead of falling back to cached settings, while the hourly background refresh is fail-open on both channels.

241 255 

242## Audit logging256## Audit logging

243 257 


260| User configures a [third-party model provider](#platform-availability) | Server-managed settings are bypassed. This includes setting `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_MANTLE`, `CLAUDE_CODE_USE_VERTEX`, `CLAUDE_CODE_USE_FOUNDRY`, `CLAUDE_CODE_USE_ANTHROPIC_AWS`, or a non-default `ANTHROPIC_BASE_URL` |274| User configures a [third-party model provider](#platform-availability) | Server-managed settings are bypassed. This includes setting `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_MANTLE`, `CLAUDE_CODE_USE_VERTEX`, `CLAUDE_CODE_USE_FOUNDRY`, `CLAUDE_CODE_USE_ANTHROPIC_AWS`, or a non-default `ANTHROPIC_BASE_URL` |

261| Network traffic is intercepted or redirected | Disabled TLS validation or intercepted traffic can alter the settings the client receives |275| Network traffic is intercepted or redirected | Disabled TLS validation or intercepted traffic can alter the settings the client receives |

262 276 

263To detect runtime configuration changes, use [`ConfigChange` hooks](/en/hooks#configchange) to log modifications or block unauthorized changes before they take effect.277To detect runtime configuration changes, use [`ConfigChange` hooks](/docs/en/hooks#configchange) to log modifications or block unauthorized changes before they take effect.

264 278 

265To restrict which organizations your users can access with credentials the client supplies, see [Enforce network-level access control with Tenant Restrictions](https://support.claude.com/en/articles/13198485-enforce-network-level-access-control-with-tenant-restrictions) in the Claude Help Center. For stronger enforcement guarantees, use [endpoint-managed settings](/en/settings#settings-files) on devices enrolled in an MDM solution.279To restrict which organizations your users can access with credentials the client supplies, see [Enforce network-level access control with Tenant Restrictions](https://support.claude.com/en/articles/13198485-enforce-network-level-access-control-with-tenant-restrictions) in the Claude Help Center. For stronger enforcement guarantees, use [endpoint-managed settings](/docs/en/settings#settings-files) on devices enrolled in an MDM solution.

266 280 

267## See also281## See also

268 282 

269Related pages for managing Claude Code configuration:283Related pages for managing Claude Code configuration:

270 284 

271* [Settings](/en/settings): complete configuration reference including all available settings285* [Settings](/docs/en/settings): complete configuration reference including all available settings

272* [Endpoint-managed settings](/en/settings#settings-files): managed settings deployed to devices by IT286* [Endpoint-managed settings](/docs/en/settings#settings-files): managed settings deployed to devices by IT

273* [Authentication](/en/authentication): set up user access to Claude Code287* [Authentication](/docs/en/authentication): set up user access to Claude Code

274* [Security](/en/security): security safeguards and best practices288* [Security](/docs/en/security): security safeguards and best practices

sessions.md +1 −1

Details

62 62 

63{/* min-version: 2.1.169 */}From v2.1.169, moving a session with [`/cd`](/docs/en/commands) relocates it to the new directory's project storage, so it appears in that directory's picker afterward. {/* min-version: 2.1.196 */}As of v2.1.196, a moved session stays out of the old directory's picker even after a crash or forced exit. On earlier versions, it could also reappear in the old directory's list after an exit that wasn't clean when the old path contained special characters such as underscores.63{/* min-version: 2.1.169 */}From v2.1.169, moving a session with [`/cd`](/docs/en/commands) relocates it to the new directory's project storage, so it appears in that directory's picker afterward. {/* min-version: 2.1.196 */}As of v2.1.196, a moved session stays out of the old directory's picker even after a crash or forced exit. On earlier versions, it could also reappear in the old directory's list after an exit that wasn't clean when the old path contained special characters such as underscores.

64 64 

65Selecting a session from another worktree of the same repository resumes it in place. Selecting a session from an unrelated project copies a `cd` and resume command to your clipboard instead.65When you select a session from another worktree of the same repository, Claude Code resumes it in place. When you select a session from an unrelated project, Claude Code copies a `cd` and resume command to your clipboard instead.

66 66 

67Resuming by name resolves across the current repository and its worktrees. Both forms look for an exact match and resume it directly even if it lives in a different worktree:67Resuming by name resolves across the current repository and its worktrees. Both forms look for an exact match and resume it directly even if it lives in a different worktree:

68 68 

settings.md +22 −13

Details

326| `statusLine` | Configure a custom status line to display context. The object's optional `padding`, `refreshInterval`, and `hideVimModeIndicator` fields control spacing, periodic re-runs, and whether the built-in vim mode indicator below the prompt is hidden. See [`statusLine` documentation](/docs/en/statusline#manually-configure-a-status-line) | `{"type": "command", "command": "~/.claude/statusline.sh"}` |326| `statusLine` | Configure a custom status line to display context. The object's optional `padding`, `refreshInterval`, and `hideVimModeIndicator` fields control spacing, periodic re-runs, and whether the built-in vim mode indicator below the prompt is hidden. See [`statusLine` documentation](/docs/en/statusline#manually-configure-a-status-line) | `{"type": "command", "command": "~/.claude/statusline.sh"}` |

327| `strictKnownMarketplaces` | (Managed settings only) Allowlist of plugin marketplace sources. Undefined = no restrictions, empty array = lockdown. Enforced on marketplace add and on plugin install, update, refresh, and auto-update, so a marketplace added before the policy was set cannot be used to fetch plugins. See [Managed marketplace restrictions](/docs/en/plugin-marketplaces#managed-marketplace-restrictions) | `[{ "source": "github", "repo": "acme-corp/plugins" }]` |327| `strictKnownMarketplaces` | (Managed settings only) Allowlist of plugin marketplace sources. Undefined = no restrictions, empty array = lockdown. Enforced on marketplace add and on plugin install, update, refresh, and auto-update, so a marketplace added before the policy was set cannot be used to fetch plugins. See [Managed marketplace restrictions](/docs/en/plugin-marketplaces#managed-marketplace-restrictions) | `[{ "source": "github", "repo": "acme-corp/plugins" }]` |

328| `strictPluginOnlyCustomization` | (Managed settings only) Block skills, agents, hooks, and MCP servers from user and project sources, so they can only come from plugins or managed settings. `true` locks all four surfaces; an array locks only the named ones. See [`strictPluginOnlyCustomization`](#strictpluginonlycustomization) | `["skills", "hooks"]` |328| `strictPluginOnlyCustomization` | (Managed settings only) Block skills, agents, hooks, and MCP servers from user and project sources, so they can only come from plugins or managed settings. `true` locks all four surfaces; an array locks only the named ones. See [`strictPluginOnlyCustomization`](#strictpluginonlycustomization) | `["skills", "hooks"]` |

329| `switchModelsOnFlag` | {/* min-version: 2.1.170 */}**Default**: `true`. When a [safety classifier flags a request](/docs/en/model-config#automatic-model-fallback), switch to the fallback model automatically and continue the session. Set to `false` to pause instead and choose between switching and editing the prompt. See [Ask before switching](/docs/en/model-config#ask-before-switching). Appears in `/config` as **Switch models when a message is flagged**. Requires Claude Code v2.1.170 or later | `false` |

329| `syntaxHighlightingDisabled` | Disable syntax highlighting in diffs, code blocks, and file previews | `true` |330| `syntaxHighlightingDisabled` | Disable syntax highlighting in diffs, code blocks, and file previews | `true` |

330| `teammateMode` | **Default**: `in-process`. How [agent team](/docs/en/agent-teams) teammates display: `in-process`, `auto` (split panes when running inside tmux, or inside iTerm2 with `it2` on your `PATH`; in-process otherwise), `tmux` (split panes using tmux or iTerm2, detected from your terminal), or {/* min-version: 2.1.186 */}`iterm2` (iTerm2 native split panes via the `it2` CLI, added in v2.1.186). The default changed from `auto` in v2.1.179. `--teammate-mode` overrides this for one session. See [choose a display mode](/docs/en/agent-teams#choose-a-display-mode) | `"auto"` |331| `teammateMode` | **Default**: `in-process`. How [agent team](/docs/en/agent-teams) teammates display: `in-process`, `auto` (split panes when running inside tmux, or inside iTerm2 with `it2` on your `PATH`; in-process otherwise), `tmux` (split panes using tmux or iTerm2, detected from your terminal), or {/* min-version: 2.1.186 */}`iterm2` (iTerm2 native split panes via the `it2` CLI, added in v2.1.186). The default changed from `auto` in v2.1.179. `--teammate-mode` overrides this for one session. See [choose a display mode](/docs/en/agent-teams#choose-a-display-mode) | `"auto"` |

331| `terminalProgressBarEnabled` | **Default**: `true`. Show the terminal progress bar in supported terminals: ConEmu, Ghostty 1.2.0+, and iTerm2 3.6.6+. Appears in `/config` as **Terminal progress bar** | `false` |332| `terminalProgressBarEnabled` | **Default**: `true`. Show the terminal progress bar in supported terminals: ConEmu, Ghostty 1.2.0+, and iTerm2 3.6.6+. Appears in `/config` as **Terminal progress bar** | `false` |


747 748 

748## Subagent configuration749## Subagent configuration

749 750 

750Claude Code supports custom AI subagents that can be configured at both user and project levels. These subagents are stored as Markdown files with YAML frontmatter:751Claude Code supports custom AI subagents that can be configured at both user and project levels. You define each subagent as a Markdown file with YAML frontmatter, saved in one of these locations:

751 752 

752* **User subagents**: `~/.claude/agents/`, available across all your projects753* **User subagents**: `~/.claude/agents/`, available across all your projects

753* **Project subagents**: `.claude/agents/`, specific to your project and shareable with your team754* **Project subagents**: `.claude/agents/`, specific to your project and shareable with your team


921**Allowlist behavior**:922**Allowlist behavior**:

922 923 

923* `undefined` (default): no restrictions, so users can add any marketplace924* `undefined` (default): no restrictions, so users can add any marketplace

924* Empty array `[]`: complete lockdown, so users can't add any new marketplaces925* Empty array `[]`: complete lockdown that blocks every marketplace source, including the official Anthropic marketplace, so users can't add any new marketplaces

925* List of sources: users can only add marketplaces that match exactly926* List of sources: users can only add marketplaces that match exactly

926 927 

927**All supported source types**:928**All supported source types**:


1045}1046}

1046```1047```

1047 1048 

1048Example: disable all marketplace additions:1049Example: disable all marketplace additions, including the official Anthropic marketplace:

1049 1050 

1050```json theme={null}1051```json theme={null}

1051{1052{


1053}1054}

1054```1055```

1055 1056 

1057Example: allow only the official Anthropic marketplace. Matching is exact, so this entry doesn't cover `ref` or `path` variants of the same repository:

1058 

1059```json theme={null}

1060{

1061 "strictKnownMarketplaces": [

1062 {

1063 "source": "github",

1064 "repo": "anthropics/claude-plugins-official"

1065 }

1066 ]

1067}

1068```

1069 

1070With this entry, the official marketplace registers itself automatically the first time you start Claude Code interactively, so you don't need to pair it with `extraKnownMarketplaces`. In a non-interactive environment that runs before that first interactive launch, add it explicitly with `claude plugin marketplace add anthropics/claude-plugins-official` or include it in `extraKnownMarketplaces`.

1071 

1056Example: allow all marketplaces from an internal git server:1072Example: allow all marketplaces from an internal git server:

1057 1073 

1058```json theme={null}1074```json theme={null}


1074* The `ref` field must match exactly (or both be undefined)1090* The `ref` field must match exactly (or both be undefined)

1075* The `path` field must match exactly (or both be undefined)1091* The `path` field must match exactly (or both be undefined)

1076 1092 

1077Examples of sources that don't match:1093For example, Claude Code treats each pair below as two different sources:

1078 1094 

1079```json theme={null}1095* `{ "source": "github", "repo": "acme-corp/plugins" }` and `{ "source": "github", "repo": "acme-corp/plugins", "ref": "main" }`

1080// These are DIFFERENT sources:1096* `{ "source": "github", "repo": "acme-corp/plugins", "path": "marketplace" }` and `{ "source": "github", "repo": "acme-corp/plugins" }`

1081{ "source": "github", "repo": "acme-corp/plugins" }

1082{ "source": "github", "repo": "acme-corp/plugins", "ref": "main" }

1083 

1084// These are also DIFFERENT:

1085{ "source": "github", "repo": "acme-corp/plugins", "path": "marketplace" }

1086{ "source": "github", "repo": "acme-corp/plugins" }

1087```

1088 1097 

1089**Comparison with `extraKnownMarketplaces`**:1098**Comparison with `extraKnownMarketplaces`**:

1090 1099 

skills.md +5 −1

Details

48 48 

49`/run-skill-generator` records the recipe instead. It gets your app running from a clean environment, captures what worked (the install commands, the env vars, the launch script), and commits it as a per-project skill at `.claude/skills/run-<name>/`. After that, `/run`, `/verify`, and any other agent in the repo follow the recorded recipe instead of rediscovering it. Run `/run-skill-generator` once per project, and again if the build or launch process changes.49`/run-skill-generator` records the recipe instead. It gets your app running from a clean environment, captures what worked (the install commands, the env vars, the launch script), and commits it as a per-project skill at `.claude/skills/run-<name>/`. After that, `/run`, `/verify`, and any other agent in the repo follow the recorded recipe instead of rediscovering it. Run `/run-skill-generator` once per project, and again if the build or launch process changes.

50 50 

51`/verify` can also record its own recipe. When it has to build and drive your app without a recorded recipe, it writes what worked to `.claude/skills/verify/SKILL.md` at the repo root, or in the touched package directory in a monorepo, so later runs and other agents follow the same steps. At the repo root, the recorded skill replaces the bundled `/verify`. This requires Claude Code v2.1.200 or later.

52 

53Claude edits the recorded file only when it steered a run wrong, such as a command that failed or a missing step, so you can commit the file without per-session diffs. Before v2.1.205, the bundled skill told Claude to fold in anything a run learned, which caused frequent merge conflicts.

54 

51## Getting started55## Getting started

52 56 

53### Create your first skill57### Create your first skill


137 141 

138#### Live change detection142#### Live change detection

139 143 

140Claude Code watches skill directories for file changes. Adding, editing, or removing a skill under `~/.claude/skills/`, the project `.claude/skills/`, or a `.claude/skills/` inside an `--add-dir` directory takes effect within the current session without restarting. Creating a top-level skills directory that did not exist when the session started requires restarting Claude Code so the new directory can be watched.144Claude Code watches skill directories for file changes. When you add, edit, or remove a skill under `~/.claude/skills/`, the project `.claude/skills/`, or a `.claude/skills/` inside an `--add-dir` directory, Claude Code picks up the change within the current session, without a restart. If you create a top-level skills directory that didn't exist when the session started, restart Claude Code so it can watch the new directory.

141 145 

142<Note>146<Note>

143 Live change detection covers `SKILL.md` text only. For a skill folder that is also a [plugin](/docs/en/plugins-reference#skills-directory-plugins), changes to `hooks/`, `.mcp.json`, `agents/`, and `output-styles/` need `/reload-plugins` to take effect.147 Live change detection covers `SKILL.md` text only. For a skill folder that is also a [plugin](/docs/en/plugins-reference#skills-directory-plugins), changes to `hooks/`, `.mcp.json`, `agents/`, and `output-styles/` need `/reload-plugins` to take effect.

sub-agents.md +7 −3

Details

273The following fields can be used in the YAML frontmatter. Only `name` and `description` are required.273The following fields can be used in the YAML frontmatter. Only `name` and `description` are required.

274 274 

275| Field | Required | Description |275| Field | Required | Description |

276| :---------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |276| :---------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

277| `name` | Yes | Unique identifier using lowercase letters and hyphens. [Hooks](/docs/en/hooks#subagentstart) receive this value as `agent_type`. The filename doesn't have to match |277| `name` | Yes | Unique identifier using lowercase letters and hyphens. [Hooks](/docs/en/hooks#subagentstart) receive this value as `agent_type`. The filename doesn't have to match. {/* min-version: 2.1.218 */}Names can't contain `:`, which is reserved for [plugin-scoped identifiers](/docs/en/plugins) such as `my-plugin:reviewer`. Claude Code doesn't load a file whose name contains one and logs an error to the debug log. Before v2.1.218, such names were accepted |

278| `description` | Yes | When Claude should delegate to this subagent |278| `description` | Yes | When Claude should delegate to this subagent |

279| `tools` | No | [Tools](#available-tools) the subagent can use. Inherits every tool available to subagents if omitted. If no entry in the list resolves to a tool, the subagent usually [fails to launch](/docs/en/errors#agent-would-be-spawned-with-zero-tools) with an error naming the entries. To preload Skills into context, use the `skills` field rather than listing `Skill` here |279| `tools` | No | [Tools](#available-tools) the subagent can use. Inherits every tool available to subagents if omitted. If no entry in the list resolves to a tool, the subagent usually [fails to launch](/docs/en/errors#agent-would-be-spawned-with-zero-tools) with an error naming the entries. To preload Skills into context, use the `skills` field rather than listing `Skill` here |

280| `disallowedTools` | No | Tools to deny, removed from inherited or specified list |280| `disallowedTools` | No | Tools to deny, removed from inherited or specified list |


620 Frontmatter hooks fire when the agent is spawned as a subagent through the Agent tool or an @-mention, and when the agent runs as the main session via [`--agent`](#invoke-subagents-explicitly) or the `agent` setting. In the main-session case they run alongside any hooks defined in [`settings.json`](/docs/en/hooks).620 Frontmatter hooks fire when the agent is spawned as a subagent through the Agent tool or an @-mention, and when the agent runs as the main session via [`--agent`](#invoke-subagents-explicitly) or the `agent` setting. In the main-session case they run alongside any hooks defined in [`settings.json`](/docs/en/hooks).

621</Note>621</Note>

622 622 

623{/* min-version: 2.1.218 */}To let a project-level subagent's frontmatter hooks run, accept the [workspace trust dialog](/docs/en/permissions#project-allow-rules-and-workspace-trust) for the folder that contains the agent file. Hooks from user-level subagents in `~/.claude/agents/` and from definitions you pass with `--agents` run without this step. If you added a folder with `--add-dir` from outside your trusted workspace's repository, trust that folder separately: its `.claude/agents/` hooks don't inherit the workspace's grant.

624 

625Until you trust the folder, the subagent still runs, but Claude Code skips its frontmatter hooks and logs an error to the debug log explaining how to trust the folder. The grant is the same workspace trust approval that covers project settings and project-level hooks. Before v2.1.218, frontmatter hooks could run from folders you hadn't trusted, including in non-interactive sessions.

626 

623All [hook events](/docs/en/hooks#hook-events) are supported. The most common events for subagents are:627All [hook events](/docs/en/hooks#hook-events) are supported. The most common events for subagents are:

624 628 

625| Event | Matcher input | When it fires |629| Event | Matcher input | When it fires |


966 970 

967* **Main conversation compaction**: when the main conversation compacts, subagent transcripts are unaffected. They're stored in separate files.971* **Main conversation compaction**: when the main conversation compacts, subagent transcripts are unaffected. They're stored in separate files.

968* **Session persistence**: subagent transcripts persist within their session. You can [resume a subagent](#resume-subagents) after restarting Claude Code by resuming the same session.972* **Session persistence**: subagent transcripts persist within their session. You can [resume a subagent](#resume-subagents) after restarting Claude Code by resuming the same session.

969* **Automatic cleanup**: transcripts are cleaned up based on the `cleanupPeriodDays` setting, which defaults to 30 days.973* **Automatic cleanup**: Claude Code deletes subagent transcripts after the `cleanupPeriodDays` retention period, 30 days by default.

970 974 

971#### Auto-compaction975#### Auto-compaction

972 976 

ultrareview.md +1 −1

Details

107 107 

108A review typically takes 5 to 10 minutes. The review runs as a background task, so you can keep working in your session, start other commands, or close the terminal entirely.108A review typically takes 5 to 10 minutes. The review runs as a background task, so you can keep working in your session, start other commands, or close the terminal entirely.

109 109 

110Use `/tasks` to see running and completed reviews, open the detail view for a review, or stop a review that is in progress. Stopping a review archives the cloud session, and partial findings are not returned. When the review finishes, the verified findings appear as a notification in your session. Each finding includes the file location and an explanation of the issue so you can ask Claude to fix it directly.110Use `/tasks` to see running and completed reviews, open the detail view for a review, or stop a review that is in progress. If you stop a review, Claude Code archives the cloud session and doesn't return partial findings. When the review finishes, the verified findings appear as a notification in your session. Each finding includes the file location and an explanation of the issue so you can ask Claude to fix it directly.

111 111 

112## Run ultrareview non-interactively112## Run ultrareview non-interactively

113 113 

voice-dictation.md +14 −14

Details

12 Tap mode requires Claude Code v2.1.116 or later. Check your version with `claude --version`.12 Tap mode requires Claude Code v2.1.116 or later. Check your version with `claude --version`.

13</Note>13</Note>

14 14 

15Dictation also works in [agent view](/en/agent-view#peek-and-reply). Hold or tap your push-to-talk key while the dispatch input or a peek-panel reply is focused to dictate to a background session.15Dictation also works in [agent view](/docs/en/agent-view#peek-and-reply). Hold or tap your push-to-talk key while the dispatch input or a peek-panel reply is focused to dictate to a background session.

16 16 

17## Requirements17## Requirements

18 18 


20 20 

21* **A Claude.ai account**: the speech-to-text service is only available when you authenticate with one, and is not available when Claude Code is configured to use an Anthropic API key directly, Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry.21* **A Claude.ai account**: the speech-to-text service is only available when you authenticate with one, and is not available when Claude Code is configured to use an Anthropic API key directly, Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry.

22* **An organization without HIPAA compliance enabled**: `/voice` shows `Voice mode is disabled by your organization's policy` when this restriction applies.22* **An organization without HIPAA compliance enabled**: `/voice` shows `Voice mode is disabled by your organization's policy` when this restriction applies.

23* **A local microphone**: voice dictation does not work in remote environments such as [Claude Code on the web](/en/claude-code-on-the-web) or SSH sessions.23* **A local microphone**: voice dictation does not work in remote environments such as [Claude Code on the web](/docs/en/claude-code-on-the-web) or SSH sessions.

24* **WSLg, if you run Claude Code in WSL**: WSLg is included with WSL2 when installed from the Microsoft Store on Windows 10 or 11. If WSLg is not available, for example on WSL1, run Claude Code in native Windows instead.24* **WSLg, if you run Claude Code in WSL**: WSLg is included with WSL2 when installed from the Microsoft Store on Windows 10 or 11. If WSLg is not available, for example on WSL1, run Claude Code in native Windows instead.

25 25 

26Transcription does not consume Claude messages or tokens and does not count toward the limits shown in `/usage`. See [data usage](/en/data-usage) for how Anthropic handles your data.26Transcription does not consume Claude messages or tokens and does not count toward the limits shown in `/usage`. See [data usage](/docs/en/data-usage) for how Anthropic handles your data.

27 27 

28Audio recording uses a built-in native module on macOS, Linux, and Windows. On Linux, if the native module cannot load, Claude Code falls back to `arecord` from ALSA utils or `rec` from SoX. If neither is available, `/voice` prints an install command for your package manager.28Audio recording uses a built-in native module on macOS, Linux, and Windows. On Linux, if the native module cannot load, Claude Code falls back to `arecord` from ALSA utils or `rec` from SoX. If neither is available, `/voice` prints an install command for your package manager.

29 29 

30The Claude Code [VS Code extension](/en/vs-code) also supports voice dictation with the same Claude.ai account requirement. It is not available in VS Code Remote sessions, including SSH, Dev Containers, and Codespaces, because the microphone is on your local machine and the extension runs on the remote host.30The Claude Code [VS Code extension](/docs/en/vs-code) also supports voice dictation with the same Claude.ai account requirement. It is not available in VS Code Remote sessions, including SSH, Dev Containers, and Codespaces, because the microphone is on your local machine and the extension runs on the remote host.

31 31 

32## Enable voice dictation32## Enable voice dictation

33 33 


47| `/voice tap` | Enable in [tap mode](#tap-to-record-and-send) |47| `/voice tap` | Enable in [tap mode](#tap-to-record-and-send) |

48| `/voice off` | Disable |48| `/voice off` | Disable |

49 49 

50Voice dictation persists across sessions. Set it directly in your [user settings file](/en/settings) instead of running `/voice`:50Voice dictation persists across sessions. Set it directly in your [user settings file](/docs/en/settings) instead of running `/voice`:

51 51 

52```json theme={null}52```json theme={null}

53{53{


58}58}

59```59```

60 60 

61While voice dictation is enabled, the input footer shows a `hold space to speak` hint when the prompt is empty. The hint reflects your current `voice:pushToTalk` binding and updates if you [rebind the dictation key](#rebind-the-dictation-key). The hint text is the same in both modes, and it does not appear if you have a [custom status line](/en/statusline) configured.61While voice dictation is enabled, the input footer shows a `hold space to speak` hint when the prompt is empty. The hint reflects your current `voice:pushToTalk` binding and updates if you [rebind the dictation key](#rebind-the-dictation-key). The hint text is the same in both modes, and it does not appear if you have a [custom status line](/docs/en/statusline) configured.

62 62 

63Transcription is tuned for coding vocabulary in both modes. Common development terms like `regex`, `OAuth`, `JSON`, and `localhost` are recognized correctly, and your current project name and git branch name are added as recognition hints automatically.63Transcription is tuned for coding vocabulary in both modes. Common development terms like `regex`, `OAuth`, `JSON`, and `localhost` are recognized correctly, and your current project name and git branch name are added as recognition hints automatically.

64 64 


82> refactor the auth middleware to use the new token validation helper▮82> refactor the auth middleware to use the new token validation helper▮

83```83```

84 84 

85By default, releasing the key inserts the transcript and waits for you to press `Enter`. Set `"autoSubmit": true` in the `voice` settings object to send the prompt automatically when you release the key, as long as the transcript is at least three words long.85By default, when you release the key, Claude Code inserts the transcript and waits for you to press `Enter`. Set `"autoSubmit": true` in the `voice` settings object to send the prompt automatically when you release the key, as long as the transcript is at least three words long.

86 86 

87## Tap to record and send87## Tap to record and send

88 88 


98 98 

99## Change the dictation language99## Change the dictation language

100 100 

101Voice dictation uses the same [`language` setting](/en/settings) that controls Claude's response language. If that setting is empty, dictation defaults to English. In the VS Code extension, if `language` is empty, dictation uses VS Code's `accessibility.voice.speechLanguage` setting before defaulting to English.101Voice dictation uses the same [`language` setting](/docs/en/settings) that controls Claude's response language. If that setting is empty, dictation defaults to English. In the VS Code extension, if `language` is empty, dictation uses VS Code's `accessibility.voice.speechLanguage` setting before defaulting to English.

102 102 

103<Accordion title="Supported dictation languages">103<Accordion title="Supported dictation languages">

104 | Language | Code |104 | Language | Code |


137 137 

138## Rebind the dictation key138## Rebind the dictation key

139 139 

140The dictation key is bound to `voice:pushToTalk` in the `Chat` context and defaults to `Space`. The same binding controls both hold and tap modes. Rebind it in [`~/.claude/keybindings.json`](/en/keybindings):140The dictation key is bound to `voice:pushToTalk` in the `Chat` context and defaults to `Space`. The same binding controls both hold and tap modes. Rebind it in [`~/.claude/keybindings.json`](/docs/en/keybindings):

141 141 

142```json theme={null}142```json theme={null}

143{143{


157 157 

158In hold mode, avoid binding a bare letter key like `v` since hold detection relies on key-repeat and the letter types into the prompt during warmup. Use `Space`, or use a modifier combination like `meta+k` to start recording on the first keypress with no warmup. Tap mode has no warmup, so most keys work.158In hold mode, avoid binding a bare letter key like `v` since hold detection relies on key-repeat and the letter types into the prompt during warmup. Use `Space`, or use a modifier combination like `meta+k` to start recording on the first keypress with no warmup. Tap mode has no warmup, so most keys work.

159 159 

160Some keys are not delivered to terminal applications and can't be bound at all. For example, `Caps Lock` shows an error if you try to bind it. See [customize keyboard shortcuts](/en/keybindings) for the full keybinding syntax and the list of reserved shortcuts.160Some keys are not delivered to terminal applications and can't be bound at all. For example, `Caps Lock` shows an error if you try to bind it. See [customize keyboard shortcuts](/docs/en/keybindings) for the full keybinding syntax and the list of reserved shortcuts.

161 161 

162## Troubleshooting162## Troubleshooting

163 163 


201 201 

202## See also202## See also

203 203 

204* [Customize keyboard shortcuts](/en/keybindings): rebind `voice:pushToTalk` and other CLI keyboard actions204* [Customize keyboard shortcuts](/docs/en/keybindings): rebind `voice:pushToTalk` and other CLI keyboard actions

205* [Configure settings](/en/settings): full reference for `voice`, `language`, and other settings keys205* [Configure settings](/docs/en/settings): full reference for `voice`, `language`, and other settings keys

206* [Interactive mode](/en/interactive-mode): keyboard shortcuts, input modes, and session controls206* [Interactive mode](/docs/en/interactive-mode): keyboard shortcuts, input modes, and session controls

207* [Commands](/en/commands): reference for `/voice`, `/config`, and all other commands207* [Commands](/docs/en/commands): reference for `/voice`, `/config`, and all other commands

vs-code.md +10 −10

Details

108 108 

109Use @-mentions to give Claude context about specific files or folders. When you type `@` followed by a file or folder name, Claude reads that content and can answer questions about it or make changes to it. Claude Code supports fuzzy matching, so you can type partial names to find what you need:109Use @-mentions to give Claude context about specific files or folders. When you type `@` followed by a file or folder name, Claude reads that content and can answer questions about it or make changes to it. Claude Code supports fuzzy matching, so you can type partial names to find what you need:

110 110 

111```text theme={null}111```text wrap theme={null}

112> Explain the logic in @auth (fuzzy matches auth.js, AuthService.ts, etc.)112Explain the logic in @auth (fuzzy matches auth.js, AuthService.ts, etc.)

113> What's in @src/components/ (include a trailing slash for folders)113What's in @src/components/ (include a trailing slash for folders)

114```114```

115 115 

116For large PDFs, you can ask Claude to read specific pages instead of the whole file: a single page, a range like pages 1-10, or an open-ended range like page 3 onward.116For large PDFs, you can ask Claude to read specific pages instead of the whole file: a single page, a range like pages 1-10, or an open-ended range like page 3 onward.


210* Click the refresh icon to update a marketplace's plugin list210* Click the refresh icon to update a marketplace's plugin list

211* Click the trash icon to remove a marketplace211* Click the trash icon to remove a marketplace

212 212 

213After making changes, a banner prompts you to restart Claude Code to apply the updates.213After you make changes, a banner prompts you to restart Claude Code to apply them.

214 214 

215<Note>215<Note>

216 Plugin management in VS Code uses the same CLI commands under the hood. Plugins and marketplaces you configure in the extension are also available in the CLI, and vice versa.216 Plugin management in VS Code uses the same CLI commands under the hood. Plugins and marketplaces you configure in the extension are also available in the CLI, and vice versa.


224 224 

225Type `@browser` in the prompt box followed by what you want Claude to do:225Type `@browser` in the prompt box followed by what you want Claude to do:

226 226 

227```text theme={null}227```text wrap theme={null}

228@browser go to localhost:3000 and check the console for errors228@browser go to localhost:3000 and check the console for errors

229```229```

230 230 


405 405 

406Claude can stage changes, write commit messages, and create pull requests based on your work:406Claude can stage changes, write commit messages, and create pull requests based on your work:

407 407 

408```text theme={null}408```text wrap theme={null}

409> commit my changes with a descriptive message409commit my changes with a descriptive message

410> create a pr for this feature410create a pr for this feature

411> summarize the changes I've made to the auth module411summarize the changes I've made to the auth module

412```412```

413 413 

414When creating pull requests, Claude generates descriptions based on the actual code changes and can add context about testing or implementation decisions.414When creating pull requests, Claude generates descriptions based on the actual code changes and can add context about testing or implementation decisions.


5282. Search for "Claude Code"5282. Search for "Claude Code"

5293. Click **Uninstall**5293. Click **Uninstall**

530 530 

531Running `claude` in a VS Code integrated terminal reinstalls the extension automatically. To keep it uninstalled, turn off **Auto-install IDE extension** in `/config`, or set [`autoInstallIdeExtension`](/docs/en/settings#global-config-settings) to `false`. You can also set the [`CLAUDE_CODE_IDE_SKIP_AUTO_INSTALL`](/docs/en/env-vars) environment variable to `1`.531If you run `claude` in a VS Code integrated terminal, Claude Code reinstalls the extension automatically. To keep it uninstalled, turn off **Auto-install IDE extension** in `/config`, or set [`autoInstallIdeExtension`](/docs/en/settings#global-config-settings) to `false`. You can also set the [`CLAUDE_CODE_IDE_SKIP_AUTO_INSTALL`](/docs/en/env-vars) environment variable to `1`.

532 532 

533To also remove extension data and reset all settings, delete the extension's storage directory for your platform.533To also remove extension data and reset all settings, delete the extension's storage directory for your platform.

534 534 

Details

7> Auto mode for hands-off permissions, computer use built in, PR auto-fix in the cloud, transcript search, and a PowerShell tool for Windows.7> Auto mode for hands-off permissions, computer use built in, PR auto-fix in the cloud, transcript search, and a PowerShell tool for Windows.

8 8 

9<div className="digest-meta">9<div className="digest-meta">

10 <span>Releases <a href="/docs/en/changelog#2-1-83">v2.1.83 → v2.1.85</a></span>10 <span>Releases <a href="/docs/docs/en/changelog#2-1-83">v2.1.83 → v2.1.85</a></span>

11 <span>6 features · March 23–27</span>11 <span>6 features · March 23–27</span>

12</div>12</div>

13 13 


33 }33 }

34 ```34 ```

35 35 

36 <a className="digest-feature-link" href="/docs/en/permission-modes">Permission modes guide</a>36 <a className="digest-feature-link" href="/docs/docs/en/permission-modes">Permission modes guide</a>

37</div>37</div>

38 38 

39<div className="digest-feature">39<div className="digest-feature">


50 50 

51 <p className="digest-feature-try">Enable it in Settings, grant the OS permissions, then ask Claude to verify a change end to end:</p>51 <p className="digest-feature-try">Enable it in Settings, grant the OS permissions, then ask Claude to verify a change end to end:</p>

52 52 

53 ```text Claude Code theme={null}53 ```text title="Claude Code" wrap theme={null}

54 > Open the iOS simulator, tap through the onboarding flow, and screenshot each step54 Open the iOS simulator, tap through the onboarding flow, and screenshot each step

55 ```55 ```

56 56 

57 <a className="digest-feature-link" href="/docs/en/desktop#let-claude-use-your-computer">Computer use guide</a>57 <a className="digest-feature-link" href="/docs/docs/en/desktop#let-claude-use-your-computer">Computer use guide</a>

58</div>58</div>

59 59 

60<div className="digest-feature">60<div className="digest-feature">


71 71 

72 <p className="digest-feature-try">After creating a PR on Claude Code web, toggle Auto fix in the CI panel.</p>72 <p className="digest-feature-try">After creating a PR on Claude Code web, toggle Auto fix in the CI panel.</p>

73 73 

74 <a className="digest-feature-link" href="/docs/en/claude-code-on-the-web#auto-fix-pull-requests">Auto-fix pull requests</a>74 <a className="digest-feature-link" href="/docs/docs/en/claude-code-on-the-web#auto-fix-pull-requests">Auto-fix pull requests</a>

75</div>75</div>

76 76 

77<div className="digest-feature">77<div className="digest-feature">


91 N # previous match91 N # previous match

92 ```92 ```

93 93 

94 <a className="digest-feature-link" href="/docs/en/fullscreen#search-and-review-the-conversation">Fullscreen guide</a>94 <a className="digest-feature-link" href="/docs/docs/en/fullscreen#search-and-review-the-conversation">Fullscreen guide</a>

95</div>95</div>

96 96 

97<div className="digest-feature">97<div className="digest-feature">


113 }113 }

114 ```114 ```

115 115 

116 <a className="digest-feature-link" href="/docs/en/tools-reference#powershell-tool">PowerShell tool docs</a>116 <a className="digest-feature-link" href="/docs/docs/en/tools-reference#powershell-tool">PowerShell tool docs</a>

117</div>117</div>

118 118 

119<div className="digest-feature">119<div className="digest-feature">


140 }140 }

141 ```141 ```

142 142 

143 <a className="digest-feature-link" href="/docs/en/hooks">Hooks reference</a>143 <a className="digest-feature-link" href="/docs/docs/en/hooks">Hooks reference</a>

144</div>144</div>

145 145 

146<div className="digest-wins">146<div className="digest-wins">


161 </div>161 </div>

162</div>162</div>

163 163 

164[Full changelog for v2.1.83–v2.1.85 →](/en/changelog#2-1-83)164[Full changelog for v2.1.83–v2.1.85 →](/docs/en/changelog#2-1-83)

Details

7> Computer use in the CLI, interactive in-product lessons, flicker-free rendering, per-tool MCP result-size overrides, and plugin executables on PATH.7> Computer use in the CLI, interactive in-product lessons, flicker-free rendering, per-tool MCP result-size overrides, and plugin executables on PATH.

8 8 

9<div className="digest-meta">9<div className="digest-meta">

10 <span>Releases <a href="/docs/en/changelog#2-1-86">v2.1.86 → v2.1.91</a></span>10 <span>Releases <a href="/docs/docs/en/changelog#2-1-86">v2.1.86 → v2.1.91</a></span>

11 <span>5 features · March 30 – April 3</span>11 <span>5 features · March 30 – April 3</span>

12</div>12</div>

13 13 


25 25 

26 <p className="digest-feature-try">Requires macOS and a Pro or Max plan; otherwise, <code>computer-use</code> won't appear in <code>/mcp</code>. Run <code>/mcp</code>, find <code>computer-use</code>, and toggle it on. Then ask Claude to verify a change end to end:</p>26 <p className="digest-feature-try">Requires macOS and a Pro or Max plan; otherwise, <code>computer-use</code> won't appear in <code>/mcp</code>. Run <code>/mcp</code>, find <code>computer-use</code>, and toggle it on. Then ask Claude to verify a change end to end:</p>

27 27 

28 ```text Claude Code theme={null}28 ```text title="Claude Code" wrap theme={null}

29 > Open the iOS simulator, tap through onboarding, and screenshot each step29 Open the iOS simulator, tap through onboarding, and screenshot each step

30 ```30 ```

31 31 

32 <a className="digest-feature-link" href="/docs/en/computer-use">Computer use guide</a>32 <a className="digest-feature-link" href="/docs/docs/en/computer-use">Computer use guide</a>

33</div>33</div>

34 34 

35<div className="digest-feature">35<div className="digest-feature">


46 46 

47 <p className="digest-feature-try">Run it:</p>47 <p className="digest-feature-try">Run it:</p>

48 48 

49 ```text Claude Code theme={null}49 ```text title="Claude Code" wrap theme={null}

50 > /powerup50 /powerup

51 ```51 ```

52 52 

53 <a className="digest-feature-link" href="/docs/en/commands">Commands reference</a>53 <a className="digest-feature-link" href="/docs/docs/en/commands">Commands reference</a>

54</div>54</div>

55 55 

56<div className="digest-feature">56<div className="digest-feature">


72 claude72 claude

73 ```73 ```

74 74 

75 <a className="digest-feature-link" href="/docs/en/fullscreen">Fullscreen rendering</a>75 <a className="digest-feature-link" href="/docs/docs/en/fullscreen">Fullscreen rendering</a>

76</div>76</div>

77 77 

78<div className="digest-feature">78<div className="digest-feature">


95 }95 }

96 ```96 ```

97 97 

98 <a className="digest-feature-link" href="/docs/en/mcp#raise-the-limit-for-a-specific-tool">MCP reference</a>98 <a className="digest-feature-link" href="/docs/docs/en/mcp#raise-the-limit-for-a-specific-tool">MCP reference</a>

99</div>99</div>

100 100 

101<div className="digest-feature">101<div className="digest-feature">


116 └── my-tool116 └── my-tool

117 ```117 ```

118 118 

119 <a className="digest-feature-link" href="/docs/en/plugins-reference#file-locations-reference">Plugins reference</a>119 <a className="digest-feature-link" href="/docs/docs/en/plugins-reference#file-locations-reference">Plugins reference</a>

120</div>120</div>

121 121 

122<div className="digest-wins">122<div className="digest-wins">


135 </div>135 </div>

136</div>136</div>

137 137 

138[Full changelog for v2.1.86–v2.1.91 →](/en/changelog#2-1-86)138[Full changelog for v2.1.86–v2.1.91 →](/docs/en/changelog#2-1-86)

Details

7> Ultraplan cloud planning, the Monitor tool with self-pacing /loop, /team-onboarding for packaging your setup, and /autofix-pr from your terminal.7> Ultraplan cloud planning, the Monitor tool with self-pacing /loop, /team-onboarding for packaging your setup, and /autofix-pr from your terminal.

8 8 

9<div className="digest-meta">9<div className="digest-meta">

10 <span>Releases <a href="/docs/en/changelog#2-1-92">v2.1.92 → v2.1.101</a></span>10 <span>Releases <a href="/docs/docs/en/changelog#2-1-92">v2.1.92 → v2.1.101</a></span>

11 <span>4 features · April 6–10</span>11 <span>4 features · April 6–10</span>

12</div>12</div>

13 13 


25 25 

26 <p className="digest-feature-try">Run the command, or just include the keyword in any prompt:</p>26 <p className="digest-feature-try">Run the command, or just include the keyword in any prompt:</p>

27 27 

28 ```text Claude Code theme={null}28 ```text title="Claude Code" wrap theme={null}

29 > /ultraplan migrate the auth service from sessions to JWTs29 /ultraplan migrate the auth service from sessions to JWTs

30 ```30 ```

31 31 

32 <a className="digest-feature-link" href="/docs/en/ultraplan">Ultraplan guide</a>32 <a className="digest-feature-link" href="/docs/docs/en/ultraplan">Ultraplan guide</a>

33</div>33</div>

34 34 

35<div className="digest-feature">35<div className="digest-feature">


46 46 

47 <p className="digest-feature-try">Ask Claude to watch something while you keep working:</p>47 <p className="digest-feature-try">Ask Claude to watch something while you keep working:</p>

48 48 

49 ```text Claude Code theme={null}49 ```text title="Claude Code" wrap theme={null}

50 > Tail server.log in the background and tell me the moment a 5xx shows up50 Tail server.log in the background and tell me the moment a 5xx shows up

51 ```51 ```

52 52 

53 <p className="digest-feature-try">This pairs with <code>/loop</code>, which now self-paces: omit the interval and Claude schedules the next tick based on the task, or reaches for the Monitor tool to skip polling altogether.</p>53 <p className="digest-feature-try">This pairs with <code>/loop</code>, which now self-paces: omit the interval and Claude schedules the next tick based on the task, or reaches for the Monitor tool to skip polling altogether.</p>

54 54 

55 ```text Claude Code theme={null}55 ```text title="Claude Code" wrap theme={null}

56 > /loop check CI on my PR56 /loop check CI on my PR

57 ```57 ```

58 58 

59 <a className="digest-feature-link" href="/docs/en/tools-reference#monitor-tool">Monitor tool reference</a>59 <a className="digest-feature-link" href="/docs/docs/en/tools-reference#monitor-tool">Monitor tool reference</a>

60</div>60</div>

61 61 

62<div className="digest-feature">62<div className="digest-feature">


73 73 

74 <p className="digest-feature-try">Run it from the PR's branch:</p>74 <p className="digest-feature-try">Run it from the PR's branch:</p>

75 75 

76 ```text Claude Code theme={null}76 ```text title="Claude Code" wrap theme={null}

77 > /autofix-pr77 /autofix-pr

78 ```78 ```

79 79 

80 <a className="digest-feature-link" href="/docs/en/claude-code-on-the-web#auto-fix-pull-requests">Auto-fix pull requests</a>80 <a className="digest-feature-link" href="/docs/docs/en/claude-code-on-the-web#auto-fix-pull-requests">Auto-fix pull requests</a>

81</div>81</div>

82 82 

83<div className="digest-feature">83<div className="digest-feature">


90 90 

91 <p className="digest-feature-try">Run it from a project you've spent real time in:</p>91 <p className="digest-feature-try">Run it from a project you've spent real time in:</p>

92 92 

93 ```text Claude Code theme={null}93 ```text title="Claude Code" wrap theme={null}

94 > /team-onboarding94 /team-onboarding

95 ```95 ```

96 96 

97 <a className="digest-feature-link" href="/docs/en/commands">Commands reference</a>97 <a className="digest-feature-link" href="/docs/docs/en/commands">Commands reference</a>

98</div>98</div>

99 99 

100<div className="digest-wins">100<div className="digest-wins">


102 102 

103 <div className="digest-wins-grid">103 <div className="digest-wins-grid">

104 <div>Focus view: press <code>Ctrl+O</code> in flicker-free mode to collapse the view to your last prompt, a one-line tool summary with diffstats, and Claude's final response</div>104 <div>Focus view: press <code>Ctrl+O</code> in flicker-free mode to collapse the view to your last prompt, a one-line tool summary with diffstats, and Claude's final response</div>

105 <div>Guided <a href="/docs/en/amazon-bedrock">Amazon Bedrock</a> and <a href="/docs/en/google-vertex-ai">Google Cloud's Agent Platform</a> setup wizards on the login screen: pick "3rd-party platform" for step-by-step auth, region, credential check, and model pinning</div>105 <div>Guided <a href="/docs/docs/en/amazon-bedrock">Amazon Bedrock</a> and <a href="/docs/docs/en/google-vertex-ai">Google Cloud's Agent Platform</a> setup wizards on the login screen: pick "3rd-party platform" for step-by-step auth, region, credential check, and model pinning</div>

106 <div><code>/agents</code> gets a tabbed layout: a Running tab shows live subagents with a <code>● N running</code> count, plus Run agent and View running instance actions in the Library tab</div>106 <div><code>/agents</code> gets a tabbed layout: a Running tab shows live subagents with a <code>● N running</code> count, plus Run agent and View running instance actions in the Library tab</div>

107 <div>Default effort level is now <code>high</code> for API-key, Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, Team, and Enterprise users (control with <code>/effort</code>)</div>107 <div>Default effort level is now <code>high</code> for API-key, Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, Team, and Enterprise users (control with <code>/effort</code>)</div>

108 <div><code>/cost</code> shows a per-model and cache-hit breakdown for subscription users</div>108 <div><code>/cost</code> shows a per-model and cache-hit breakdown for subscription users</div>


116 </div>116 </div>

117</div>117</div>

118 118 

119[Full changelog for v2.1.92–v2.1.101 →](/en/changelog#2-1-92)119[Full changelog for v2.1.92–v2.1.101 →](/docs/en/changelog#2-1-92)

Details

7> Run Claude Code on Claude Opus 4.8, orchestrate large tasks with dynamic workflows, catch security issues with the security-guidance plugin, and use fast mode on Opus 4.8 at a lower price.7> Run Claude Code on Claude Opus 4.8, orchestrate large tasks with dynamic workflows, catch security issues with the security-guidance plugin, and use fast mode on Opus 4.8 at a lower price.

8 8 

9<div className="digest-meta">9<div className="digest-meta">

10 <span>Releases <a href="/docs/en/changelog#2-1-150">v2.1.150 → v2.1.157</a></span>10 <span>Releases <a href="/docs/docs/en/changelog#2-1-150">v2.1.150 → v2.1.157</a></span>

11 <span>4 features · May 25–29</span>11 <span>4 features · May 25–29</span>

12</div>12</div>

13 13 


25 25 

26 <p className="digest-feature-try">Switch to Opus 4.8 by name, or pick it from the model picker:</p>26 <p className="digest-feature-try">Switch to Opus 4.8 by name, or pick it from the model picker:</p>

27 27 

28 ```text Claude Code theme={null}28 ```text title="Claude Code" wrap theme={null}

29 > /model claude-opus-4-829 /model claude-opus-4-8

30 ```30 ```

31 31 

32 <a className="digest-feature-link" href="/docs/en/model-config#available-models">Model configuration</a>32 <a className="digest-feature-link" href="/docs/docs/en/model-config#available-models">Model configuration</a>

33</div>33</div>

34 34 

35<div className="digest-feature">35<div className="digest-feature">


46 46 

47 <p className="digest-feature-try">Describe the task and ask for a workflow:</p>47 <p className="digest-feature-try">Describe the task and ask for a workflow:</p>

48 48 

49 ```text Claude Code theme={null}49 ```text title="Claude Code" wrap theme={null}

50 > create a workflow that migrates every internal fetch() call to the new HttpClient wrapper50 create a workflow that migrates every internal fetch() call to the new HttpClient wrapper

51 ```51 ```

52 52 

53 <a className="digest-feature-link" href="/docs/en/workflows">Dynamic workflows</a>53 <a className="digest-feature-link" href="/docs/docs/en/workflows">Dynamic workflows</a>

54</div>54</div>

55 55 

56<div className="digest-feature">56<div className="digest-feature">


67 67 

68 <p className="digest-feature-try">Install it from the official Anthropic marketplace:</p>68 <p className="digest-feature-try">Install it from the official Anthropic marketplace:</p>

69 69 

70 ```text Claude Code theme={null}70 ```text title="Claude Code" wrap theme={null}

71 > /plugin install security-guidance@claude-plugins-official71 /plugin install security-guidance@claude-plugins-official

72 ```72 ```

73 73 

74 <p className="digest-feature-try">Then activate it in the current session:</p>74 <p className="digest-feature-try">Then activate it in the current session:</p>

75 75 

76 ```text Claude Code theme={null}76 ```text title="Claude Code" wrap theme={null}

77 > /reload-plugins77 /reload-plugins

78 ```78 ```

79 79 

80 <a className="digest-feature-link" href="/docs/en/security-guidance">Security guidance plugin</a>80 <a className="digest-feature-link" href="/docs/docs/en/security-guidance">Security guidance plugin</a>

81</div>81</div>

82 82 

83<div className="digest-feature">83<div className="digest-feature">


90 90 

91 <p className="digest-feature-try">Toggle fast mode, now on Opus 4.8:</p>91 <p className="digest-feature-try">Toggle fast mode, now on Opus 4.8:</p>

92 92 

93 ```text Claude Code theme={null}93 ```text title="Claude Code" wrap theme={null}

94 > /fast94 /fast

95 ```95 ```

96 96 

97 <a className="digest-feature-link" href="/docs/en/fast-mode#understand-the-cost-tradeoff">Fast mode pricing</a>97 <a className="digest-feature-link" href="/docs/docs/en/fast-mode#understand-the-cost-tradeoff">Fast mode pricing</a>

98</div>98</div>

99 99 

100<div className="digest-wins">100<div className="digest-wins">


116 </div>116 </div>

117</div>117</div>

118 118 

119[Full changelog for v2.1.150–v2.1.157 →](/en/changelog#2-1-150)119[Full changelog for v2.1.150–v2.1.157 →](/docs/en/changelog#2-1-150)

Details

7> Publish a live, shareable page from your session with Artifacts, match tool parameters in deny and ask rules, and set any setting from the prompt with /config.7> Publish a live, shareable page from your session with Artifacts, match tool parameters in deny and ask rules, and set any setting from the prompt with /config.

8 8 

9<div className="digest-meta">9<div className="digest-meta">

10 <span>Releases <a href="/docs/en/changelog#2-1-178">v2.1.178 → v2.1.183</a></span>10 <span>Releases <a href="/docs/docs/en/changelog#2-1-178">v2.1.178 → v2.1.183</a></span>

11 <span>3 features · June 15–19</span>11 <span>3 features · June 15–19</span>

12</div>12</div>

13 13 


24 24 

25 <p className="digest-feature-try">Ask Claude for a page, then approve the publish prompt:</p>25 <p className="digest-feature-try">Ask Claude for a page, then approve the publish prompt:</p>

26 26 

27 ```text Claude Code theme={null}27 ```text title="Claude Code" wrap theme={null}

28 > Make an artifact that walks through this PR with the diff annotated inline.28 Make an artifact that walks through this PR with the diff annotated inline.

29 ```29 ```

30 30 

31 <a className="digest-feature-link" href="/docs/en/artifacts#create-an-artifact">Create an artifact</a>31 <a className="digest-feature-link" href="/docs/docs/en/artifacts#create-an-artifact">Create an artifact</a>

32</div>32</div>

33 33 

34<div className="digest-feature">34<div className="digest-feature">


49 }49 }

50 ```50 ```

51 51 

52 <a className="digest-feature-link" href="/docs/en/permissions#match-by-input-parameter">Match by input parameter</a>52 <a className="digest-feature-link" href="/docs/docs/en/permissions#match-by-input-parameter">Match by input parameter</a>

53</div>53</div>

54 54 

55<div className="digest-feature">55<div className="digest-feature">


62 62 

63 <p className="digest-feature-try">Set the <code>thinking</code> setting from the prompt:</p>63 <p className="digest-feature-try">Set the <code>thinking</code> setting from the prompt:</p>

64 64 

65 ```text Claude Code theme={null}65 ```text title="Claude Code" wrap theme={null}

66 > /config thinking=false66 /config thinking=false

67 ```67 ```

68 68 

69 <a className="digest-feature-link" href="/docs/en/commands#all-commands">Commands reference</a>69 <a className="digest-feature-link" href="/docs/docs/en/commands#all-commands">Commands reference</a>

70</div>70</div>

71 71 

72<div className="digest-wins">72<div className="digest-wins">


87 </div>87 </div>

88</div>88</div>

89 89 

90[Full changelog for v2.1.178–v2.1.183 →](/en/changelog#2-1-178)90[Full changelog for v2.1.178–v2.1.183 →](/docs/en/changelog#2-1-178)

Details

7> Pull live data into published artifacts through MCP connectors, and use Claude Code with a screen reader in the new screen reader mode.7> Pull live data into published artifacts through MCP connectors, and use Claude Code with a screen reader in the new screen reader mode.

8 8 

9<div className="digest-meta">9<div className="digest-meta">

10 <span>Releases <a href="/docs/en/changelog#2-1-207">v2.1.207 → v2.1.212</a></span>10 <span>Releases <a href="/docs/docs/en/changelog#2-1-207">v2.1.207 → v2.1.212</a></span>

11 <span>2 features · July 13–17</span>11 <span>2 features · July 13–17</span>

12</div>12</div>

13 13 


25 25 

26 <p className="digest-feature-try">Name the connector and the data you want in your prompt:</p>26 <p className="digest-feature-try">Name the connector and the data you want in your prompt:</p>

27 27 

28 ```text Claude Code theme={null}28 ```text title="Claude Code" wrap theme={null}

29 > Build a dashboard artifact of open pull requests that pulls the live list through my GitHub connector when the page loads.29 Build a dashboard artifact of open pull requests that pulls the live list through my GitHub connector when the page loads.

30 ```30 ```

31 31 

32 <a className="digest-feature-link" href="/docs/en/artifacts#pull-live-data-with-mcp-connectors">Pull live data with MCP connectors</a>32 <a className="digest-feature-link" href="/docs/docs/en/artifacts#pull-live-data-with-mcp-connectors">Pull live data with MCP connectors</a>

33</div>33</div>

34 34 

35<div className="digest-feature">35<div className="digest-feature">


46 claude --ax-screen-reader46 claude --ax-screen-reader

47 ```47 ```

48 48 

49 <a className="digest-feature-link" href="/docs/en/accessibility#turn-on-screen-reader-mode">Turn on screen reader mode</a>49 <a className="digest-feature-link" href="/docs/docs/en/accessibility#turn-on-screen-reader-mode">Turn on screen reader mode</a>

50</div>50</div>

51 51 

52<div className="digest-wins">52<div className="digest-wins">


54 54 

55 <div className="digest-wins-grid">55 <div className="digest-wins-grid">

56 <div><code>/fork</code> now copies your conversation into a new background session with its own row in <code>claude agents</code> while you keep working; the in-session forked subagent it used to launch is now <code>/subtask</code></div>56 <div><code>/fork</code> now copies your conversation into a new background session with its own row in <code>claude agents</code> while you keep working; the in-session forked subagent it used to launch is now <code>/subtask</code></div>

57 <div><a href="/docs/en/permission-modes#enable-auto-mode-on-bedrock-agent-platform-or-foundry">Auto mode</a> no longer needs the <code>CLAUDE\_CODE\_ENABLE\_AUTO\_MODE</code> opt-in on Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry; administrators can turn it off with <code>disableAutoMode</code></div>57 <div><a href="/docs/docs/en/permission-modes#enable-auto-mode-on-bedrock-agent-platform-or-foundry">Auto mode</a> no longer needs the <code>CLAUDE\_CODE\_ENABLE\_AUTO\_MODE</code> opt-in on Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry; administrators can turn it off with <code>disableAutoMode</code></div>

58 <div>MCP tool calls that run longer than two minutes now move to the background automatically so the session stays usable; tune or disable the threshold with <code>CLAUDE\_CODE\_MCP\_AUTO\_BACKGROUND\_MS</code></div>58 <div>MCP tool calls that run longer than two minutes now move to the background automatically so the session stays usable; tune or disable the threshold with <code>CLAUDE\_CODE\_MCP\_AUTO\_BACKGROUND\_MS</code></div>

59 <div>New <code>claude auto-mode reset</code> restores the default auto-mode configuration, and `--yes` skips the confirmation prompt</div>59 <div>New <code>claude auto-mode reset</code> restores the default auto-mode configuration, and `--yes` skips the confirmation prompt</div>

60 <div>New <a href="/docs/en/corporate-launcher">corporate launcher</a> support: <code>CLAUDE\_CODE\_PROCESS\_WRAPPER</code> or the <code>processWrapper</code> setting runs the processes Claude Code starts from its own binary, such as the background service and agent view sessions, through a required wrapper executable</div>60 <div>New <a href="/docs/docs/en/corporate-launcher">corporate launcher</a> support: <code>CLAUDE\_CODE\_PROCESS\_WRAPPER</code> or the <code>processWrapper</code> setting runs the processes Claude Code starts from its own binary, such as the background service and agent view sessions, through a required wrapper executable</div>

61 <div><code>vimInsertModeRemaps</code> setting maps two-key insert-mode sequences such as <code>jj</code> to Escape in vim mode</div>61 <div><code>vimInsertModeRemaps</code> setting maps two-key insert-mode sequences such as <code>jj</code> to Escape in vim mode</div>

62 <div>`--forward-subagent-text` and <code>CLAUDE\_CODE\_FORWARD\_SUBAGENT\_TEXT</code> include subagent text and thinking blocks in <a href="/docs/en/headless">stream-json output</a></div>62 <div>`--forward-subagent-text` and <code>CLAUDE\_CODE\_FORWARD\_SUBAGENT\_TEXT</code> include subagent text and thinking blocks in <a href="/docs/docs/en/headless">stream-json output</a></div>

63 <div>Session-wide caps stop runaway loops: WebSearch calls and subagent spawns each default to 200, tunable with <code>CLAUDE\_CODE\_MAX\_WEB\_SEARCHES\_PER\_SESSION</code> and <code>CLAUDE\_CODE\_MAX\_SUBAGENTS\_PER\_SESSION</code></div>63 <div>Session-wide caps stop runaway loops: WebSearch calls and subagent spawns each default to 200, tunable with <code>CLAUDE\_CODE\_MAX\_WEB\_SEARCHES\_PER\_SESSION</code> and <code>CLAUDE\_CODE\_MAX\_SUBAGENTS\_PER\_SESSION</code></div>

64 <div>"Always allow" permission rules save at the repository root, so approvals granted in a git worktree persist across sessions and worktrees</div>64 <div>"Always allow" permission rules save at the repository root, so approvals granted in a git worktree persist across sessions and worktrees</div>

65 <div>Amazon Bedrock, Google Cloud's Agent Platform, and Claude Platform on AWS now default to Claude Opus 4.8</div>65 <div>Amazon Bedrock, Google Cloud's Agent Platform, and Claude Platform on AWS now default to Claude Opus 4.8</div>


67 </div>67 </div>

68</div>68</div>

69 69 

70[Full changelog for v2.1.207–v2.1.212 →](/en/changelog#2-1-207)70[Full changelog for v2.1.207–v2.1.212 →](/docs/en/changelog#2-1-207)

workflows.md +32 −21

Details

41 <Step title="Run the workflow">41 <Step title="Run the workflow">

42 Run `/deep-research` with a question you want investigated. It fans out web searches across several angles, fetches and cross-checks the sources it finds, and synthesizes a cited report.42 Run `/deep-research` with a question you want investigated. It fans out web searches across several angles, fetches and cross-checks the sources it finds, and synthesizes a cited report.

43 43 

44 ```text theme={null}44 ```text wrap theme={null}

45 /deep-research What changed in the Node.js permission model between v20 and v22?45 /deep-research What changed in the Node.js permission model between v20 and v22?

46 ```46 ```

47 </Step>47 </Step>


53 <Step title="Watch progress">53 <Step title="Watch progress">

54 The run starts in the background. Run `/workflows`, use the arrow keys to select the run, and press Enter to open its progress view:54 The run starts in the background. Run `/workflows`, use the arrow keys to select the run, and press Enter to open its progress view:

55 55 

56 ```text theme={null}56 ```text wrap theme={null}

57 /workflows57 /workflows

58 ```58 ```

59 59 


87 87 

88Workflows run in the background, so the session stays responsive while agents work. Run `/workflows` at any time to list running and completed workflows, then select one to open its progress view.88Workflows run in the background, so the session stays responsive while agents work. Run `/workflows` at any time to list running and completed workflows, then select one to open its progress view.

89 89 

90```text theme={null}90```text wrap theme={null}

91/workflows91/workflows

92```92```

93 93 


118 118 

119To run a single task as a workflow without changing the session's effort level, include the keyword `ultracode` in your prompt. Asking in your own words, for example "use a workflow" or "run a workflow", also works: Claude treats a direct request as the same opt-in. Before v2.1.160 the literal trigger keyword was `workflow`; natural-language requests work in both versions.119To run a single task as a workflow without changing the session's effort level, include the keyword `ultracode` in your prompt. Asking in your own words, for example "use a workflow" or "run a workflow", also works: Claude treats a direct request as the same opt-in. Before v2.1.160 the literal trigger keyword was `workflow`; natural-language requests work in both versions.

120 120 

121```text theme={null}121```text wrap theme={null}

122ultracode: audit every API endpoint under src/routes/ for missing auth checks122ultracode: audit every API endpoint under src/routes/ for missing auth checks

123```123```

124 124 


147 147 

148Ultracode is a Claude Code setting that combines `xhigh` [reasoning effort](/docs/en/model-config#adjust-effort-level) with automatic workflow orchestration. With it on, Claude plans a workflow for each substantive task instead of waiting for you to ask.148Ultracode is a Claude Code setting that combines `xhigh` [reasoning effort](/docs/en/model-config#adjust-effort-level) with automatic workflow orchestration. With it on, Claude plans a workflow for each substantive task instead of waiting for you to ask.

149 149 

150```text theme={null}150```text wrap theme={null}

151/effort ultracode151/effort ultracode

152```152```

153 153 


220 220 

221The following prompt runs a saved workflow with a list of issue numbers:221The following prompt runs a saved workflow with a list of issue numbers:

222 222 

223```text theme={null}223```text wrap theme={null}

224> Run /triage-issues on issues 1024, 1025, and 1030224Run /triage-issues on issues 1024, 1025, and 1030

225```225```

226 226 

227Claude passes the list as structured data, so the script can call array and object methods on `args` directly without parsing it first. If `args` is omitted, the global is `undefined` inside the script.227Claude passes the list as structured data, so the script can call array and object methods on `args` directly without parsing it first. If `args` is omitted, the global is `undefined` inside the script.


234 234 

235Fan out one agent per file, then collect and verify the findings.235Fan out one agent per file, then collect and verify the findings.

236 236 

237```text theme={null}237```text wrap theme={null}

238> use a workflow to audit every route handler under src/routes/ for missing authentication checks, and adversarially verify each finding before reporting it238use a workflow to audit every route handler under src/routes/ for missing authentication checks, and adversarially verify each finding before reporting it

239```239```

240 240 

241### Keep fixing until a check passes241### Keep fixing until a check passes

242 242 

243Run a checker, fix what failed, and repeat until it passes or stops making progress.243Run a checker, fix what failed, and repeat until it passes or stops making progress.

244 244 

245```text theme={null}245```text wrap theme={null}

246> use a workflow to run npx tsc --noEmit and keep fixing the reported errors until the type check passes or two rounds in a row make no progress246use a workflow to run npx tsc --noEmit and keep fixing the reported errors until the type check passes or two rounds in a row make no progress

247```247```

248 248 

249### Migrate many files in parallel249### Migrate many files in parallel

250 250 

251Discover the files to migrate, transform each one in an isolated copy so edits don't conflict, and verify each result.251Discover the files to migrate, transform each one in an isolated copy so edits don't conflict, and verify each result.

252 252 

253```text theme={null}253```text wrap theme={null}

254> use a workflow to migrate every component under src/components/ from styled-components to Tailwind, working on each file in its own isolated copy254use a workflow to migrate every component under src/components/ from styled-components to Tailwind, working on each file in its own isolated copy

255```255```

256 256 

257### Review every changed file and write one summary257### Review every changed file and write one summary

258 258 

259Run a reviewer per file, then hand all the findings to one agent that ranks and deduplicates them.259Run a reviewer per file, then hand all the findings to one agent that ranks and deduplicates them.

260 260 

261```text theme={null}261```text wrap theme={null}

262> use a workflow to review every file changed in this PR for correctness issues, then merge the per-file findings into one ranked summary262use a workflow to review every file changed in this PR for correctness issues, then merge the per-file findings into one ranked summary

263```263```

264 264 

265### Research a topic across many sources265### Research a topic across many sources

266 266 

267Fan out readers across changelogs, issues, and docs, then synthesize. The bundled `/deep-research` workflow does this; you can also describe a narrower version.267Fan out readers across changelogs, issues, and docs, then synthesize. The bundled `/deep-research` workflow does this; you can also describe a narrower version.

268 268 

269```text theme={null}269```text wrap theme={null}

270> use a workflow to research how our three competitors handle rate limiting: read their public docs and recent changelog entries in parallel, then compare the approaches270use a workflow to research how our three competitors handle rate limiting: read their public docs and recent changelog entries in parallel, then compare the approaches

271```271```

272 272 

273### Find issues until the list stops growing273### Find issues until the list stops growing

274 274 

275Keep searching in rounds and stop when new rounds turn up nothing new.275Keep searching in rounds and stop when new rounds turn up nothing new.

276 276 

277```text theme={null}277```text wrap theme={null}

278> use a workflow to find flaky tests in this repo: run the suite repeatedly, record which tests fail intermittently, and stop once two rounds in a row find nothing new278use a workflow to find flaky tests in this repo: run the suite repeatedly, record which tests fail intermittently, and stop once two rounds in a row find nothing new

279```279```

280 280 

281### What the saved script looks like281### What the saved script looks like


326 326 

327### Resume after a pause327### Resume after a pause

328 328 

329If you stop a run, you can resume it: agents that already completed return their cached results, and the rest run live. An agent that was still running when you stopped isn't saved and starts over on resume, so a workflow that fans work out across many small agents preserves more progress than one long agent. Resume a paused run from `/workflows` by selecting it and pressing `p`, or ask Claude to relaunch the workflow with the same script.329If you stop a run, you can resume it. Agents that already completed usually return their cached results, and the rest run live.

330 

331Two rules decide which results survive:

332 

333* An agent that was still running when you stopped isn't saved, so it starts over on resume.

334* Replay follows the order agents started. Cached results stop at the first agent that didn't finish, and every agent that started after that one runs again, even if it completed.

335 

336The second rule is what makes stopping mid fan-out expensive. Say a script starts four agents, A, B, C, and D, in that order, and you stop the run while B is still going. On resume, A returns from cache. B runs again because it never finished. C and D run again too, because they started after B, even though both completed before you stopped.

337 

338A workflow that fans work out across many small agents therefore preserves more progress than one long agent.

339 

340Resume a paused run from `/workflows` by selecting it and pressing `p`, or ask Claude to relaunch the workflow with the same script.

330 341 

331Resume works within the same Claude Code session. If you exit Claude Code while a workflow is running, the next session starts the workflow fresh.342Resume works within the same Claude Code session. If you exit Claude Code while a workflow is running, the next session starts the workflow fresh.

332 343 


334 345 

335A workflow spawns many agents, so a single run can use meaningfully more tokens than working through the same task in conversation. Runs count toward your plan's usage and rate limits like any other session.346A workflow spawns many agents, so a single run can use meaningfully more tokens than working through the same task in conversation. Runs count toward your plan's usage and rate limits like any other session.

336 347 

337To gauge the spend before committing to a large task, run the workflow on a small slice first: one directory instead of the whole repo, or a narrow question instead of a broad one. The `/workflows` view shows each agent's token usage as the run progresses, and you can stop the run there at any time without losing completed work. The runtime's [agent caps](#behavior-and-limits) limit how many agents a single run can spawn, which bounds the cost of a runaway script. To keep runs to fewer agents, choose the `small` [size guideline](#set-a-size-guideline).348To gauge the spend before committing to a large task, run the workflow on a small slice first: one directory instead of the whole repo, or a narrow question instead of a broad one. The `/workflows` view shows each agent's token usage as the run progresses, and you can stop the run there at any time, usually without losing completed work. [Resume after a pause](#resume-after-a-pause) covers what a stopped run keeps. The runtime's [agent caps](#behavior-and-limits) limit how many agents a single run can spawn, which bounds the cost of a runaway script. To keep runs to fewer agents, choose the `small` [size guideline](#set-a-size-guideline).

338 349 

339Claude Code also flags a run that grows unusually large. When a workflow schedules more than 25 agents, or its projected token total passes 1.5 million, its progress line in the task panel below the input box shows a `Large workflow` warning. The warning points you to [`/workflows`](#watch-the-run), where you can stop the run. Requires Claude Code v2.1.203 or later.350Claude Code also flags a run that grows unusually large. When a workflow schedules more than 25 agents, or its projected token total passes 1.5 million, its progress line in the task panel below the input box shows a `Large workflow` warning. The warning points you to [`/workflows`](#watch-the-run), where you can stop the run. Requires Claude Code v2.1.203 or later.

340 351