SpyBara
Go Premium

Documentation 2026-10-25 23:58 UTC to 2026-10-26 22:57 UTC

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

admin-setup.md +1 −1

Details

93| [Sandboxing](https://code.claude.com/docs/en/sandboxing.md) | OS-level filesystem and network isolation with domain allowlists | `sandbox.enabled`, `sandbox.network.allowedDomains` |93| [Sandboxing](https://code.claude.com/docs/en/sandboxing.md) | OS-level filesystem and network isolation with domain allowlists | `sandbox.enabled`, `sandbox.network.allowedDomains` |

94| [Managed policy CLAUDE.md](https://code.claude.com/docs/en/memory.md#deploy-organization-wide-claude-md) | Organization-wide behavioral guidance for Claude rather than a client-enforced rule | File at the managed policy path |94| [Managed policy CLAUDE.md](https://code.claude.com/docs/en/memory.md#deploy-organization-wide-claude-md) | Organization-wide behavioral guidance for Claude rather than a client-enforced rule | File at the managed policy path |

95| [MCP server control](https://code.claude.com/docs/en/managed-mcp.md) | Restrict which MCP servers users can add or connect to, deploy a fixed set, or provide remote servers to every user alongside their own | `allowedMcpServers`, `deniedMcpServers`, `allowManagedMcpServersOnly`, `managedMcpServers`, or a deployed `managed-mcp.json` file |95| [MCP server control](https://code.claude.com/docs/en/managed-mcp.md) | Restrict which MCP servers users can add or connect to, deploy a fixed set, or provide remote servers to every user alongside their own | `allowedMcpServers`, `deniedMcpServers`, `allowManagedMcpServersOnly`, `managedMcpServers`, or a deployed `managed-mcp.json` file |

96| [Plugin marketplace control](https://code.claude.com/docs/en/plugins/org.md#restrict-what-users-can-install) | Restrict which marketplace sources users can add and install from, reject the CLI flags that sideload plugins, agents, and MCP servers for a single run, block [`command` plugin sources](https://code.claude.com/docs/en/plugins/marketplace-reference#command-plugin-source), and allowlist which marketplaces' plugins can be suggested | `strictKnownMarketplaces`, `blockedMarketplaces`, `disableSideloadFlags`, `disableCommandPluginSources`, `pluginSuggestionMarketplaces` |96| [Plugin marketplace control](https://code.claude.com/docs/en/plugins/org.md#restrict-what-users-can-install) | Restrict which marketplace sources users can add and install from, and reject the CLI flags that sideload plugins, agents, and MCP servers for a single run. Block [`command` plugin sources](https://code.claude.com/docs/en/plugins/marketplace-reference#command-plugin-source), and allowlist which marketplaces' plugins can be suggested in the terminal | `strictKnownMarketplaces`, `blockedMarketplaces`, `disableSideloadFlags`, `disableCommandPluginSources`, `pluginSuggestionMarketplaces` |

97| [Customization lockdown](https://code.claude.com/docs/en/settings-reference.md#strictpluginonlycustomization) | Block skills, agents, hooks, and MCP servers from user and project sources, so they can only come from plugins or managed settings. Locking skills also stops the [skills your developers enable on claude.ai](https://code.claude.com/docs/en/skills.md#where-synced-skills-load) from syncing | `strictPluginOnlyCustomization` |97| [Customization lockdown](https://code.claude.com/docs/en/settings-reference.md#strictpluginonlycustomization) | Block skills, agents, hooks, and MCP servers from user and project sources, so they can only come from plugins or managed settings. Locking skills also stops the [skills your developers enable on claude.ai](https://code.claude.com/docs/en/skills.md#where-synced-skills-load) from syncing | `strictPluginOnlyCustomization` |

98| [Disable claude.ai sync](https://code.claude.com/docs/en/settings-reference.md#syncclaudeaiskills) | Stop Claude Code from loading the [skills](https://code.claude.com/docs/en/skills.md#how-synced-skills-behave) and [plugins](https://code.claude.com/docs/en/plugins/loading.md#synced-plugins) your developers enable on claude.ai. If you turn off Skills for your organization on claude.ai, Claude Code stops syncing both, and on v2.1.273 or later it also removes the ones it already synced. To stop either one without turning Skills off, set its key to `false` in managed settings | `syncClaudeAiSkills`, `syncClaudeAiPlugins` |98| [Disable claude.ai sync](https://code.claude.com/docs/en/settings-reference.md#syncclaudeaiskills) | Stop Claude Code from loading the [skills](https://code.claude.com/docs/en/skills.md#how-synced-skills-behave) and [plugins](https://code.claude.com/docs/en/plugins/loading.md#synced-plugins) your developers enable on claude.ai. If you turn off Skills for your organization on claude.ai, Claude Code stops syncing both, and on v2.1.273 or later it also removes the ones it already synced. To stop either one without turning Skills off, set its key to `false` in managed settings | `syncClaudeAiSkills`, `syncClaudeAiPlugins` |

99| [Hook restrictions](https://code.claude.com/docs/en/settings-reference.md#allowmanagedhooksonly) | Restrict which hooks run and restrict HTTP hook URLs; see [what runs under `allowManagedHooksOnly`](https://code.claude.com/docs/en/settings-reference#what-runs-under-allowmanagedhooksonly) for the full effect list | `allowManagedHooksOnly`, `allowedHttpHookUrls` |99| [Hook restrictions](https://code.claude.com/docs/en/settings-reference.md#allowmanagedhooksonly) | Restrict which hooks run and restrict HTTP hook URLs; see [what runs under `allowManagedHooksOnly`](https://code.claude.com/docs/en/settings-reference#what-runs-under-allowmanagedhooksonly) for the full effect list | `allowManagedHooksOnly`, `allowedHttpHookUrls` |

Details

233| `"default"` | Tool calls that need approval and aren't covered by allow rules trigger your `canUseTool` callback; no callback means deny | Interactive applications with a custom approval callback |233| `"default"` | Tool calls that need approval and aren't covered by allow rules trigger your `canUseTool` callback; no callback means deny | Interactive applications with a custom approval callback |

234| `"acceptEdits"` | Auto-approves file edits and common filesystem commands (`mkdir`, `touch`, `mv`, `cp`, etc.); other Bash commands follow default rules | You trust Claude's edits and want faster iteration, such as during prototyping or when working in an isolated directory |234| `"acceptEdits"` | Auto-approves file edits and common filesystem commands (`mkdir`, `touch`, `mv`, `cp`, etc.); other Bash commands follow default rules | You trust Claude's edits and want faster iteration, such as during prototyping or when working in an isolated directory |

235| `"plan"` | Claude explores and plans without editing your source files; file edits are never auto-approved and prompt through your `canUseTool` callback | 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 |235| `"plan"` | Claude explores and plans without editing your source files; file edits are never auto-approved and prompt through your `canUseTool` callback | 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 |

236| `"dontAsk"` | Never prompts. Tools pre-approved by [permission rules](https://code.claude.com/docs/en/settings-reference.md#permission-settings) run, and so do calls that need no approval in `default` mode, such as file reads inside your working directories. Every call that would otherwise prompt is denied, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). `AskUserQuestion`, connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), MCP tools marked [`requiresUserInteraction`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool), and [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths) are denied even if you've allowed them | You want a fixed, explicit tool surface for a headless agent and prefer a hard deny over silent reliance on `canUseTool` being absent |236| `"dontAsk"` | Never prompts. Tools pre-approved by [permission rules](https://code.claude.com/docs/en/settings-reference.md#permission-settings) run, and so do calls that need no approval in `default` mode, such as file reads inside your working directories. Every call that would otherwise prompt is denied, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). A few calls, such as [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths), are denied even if you've allowed them. For the list, see [Don't ask mode](https://code.claude.com/docs/en/agent-sdk/permissions.md#don’t-ask-mode-dontask) | Headless agents with nobody to approve calls |

237| `"auto"` | Uses a model classifier to review actions such as shell commands and network requests, allowing or blocking each one it reviews. See [Auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) for availability and the decision order | Autonomous agents that still want safety guardrails on tool use |237| `"auto"` | Uses a model classifier to review actions such as shell commands and network requests, allowing or blocking each one it reviews. See [Auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) for availability and the decision order | Autonomous agents that still want safety guardrails on tool use |

238| `"bypassPermissions"` | Runs all allowed tools without asking, except tools matched by an explicit [`ask` rule](https://code.claude.com/docs/en/settings-reference#permission-settings), connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), and tools that require user interaction. The [cross-session messaging safeguards](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) still apply. See [How permissions are evaluated](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) for the precedence order. In the TypeScript SDK, also requires `allowDangerouslySkipPermissions: true` in `options`. Can't be used when running as root on Unix. Use only in isolated environments where the agent's actions can't affect systems you care about | CI, containers, or other isolated environments |238| `"bypassPermissions"` | Runs tool calls without asking for approval, including calls to tools you didn't list in `allowedTools`. A few calls still go to your `canUseTool` callback, listed under [Bypass permissions mode](https://code.claude.com/docs/en/agent-sdk/permissions.md#bypass-permissions-mode-bypasspermissions). In the TypeScript SDK, also requires `allowDangerouslySkipPermissions: true` in `options`. Can't be used when running as root on Unix. Use only in isolated environments where the agent's actions can't affect systems you care about | CI, containers, or other isolated environments |

239 239 

240For interactive applications, use `"default"` with a tool approval callback to surface approval prompts. For autonomous agents on a dev machine, `"acceptEdits"` auto-approves file edits and common filesystem commands (`mkdir`, `touch`, `mv`, `cp`, etc.) while still gating other `Bash` commands behind allow rules. Reserve `"bypassPermissions"` for CI, containers, or other isolated environments. See [Permissions](https://code.claude.com/docs/en/agent-sdk/permissions.md) for full details.240For interactive applications, use `"default"` with a tool approval callback to surface approval prompts. For autonomous agents on a dev machine, `"acceptEdits"` auto-approves file edits and common filesystem commands (`mkdir`, `touch`, `mv`, `cp`, etc.) while still gating other `Bash` commands behind allow rules. Reserve `"bypassPermissions"` for CI, containers, or other isolated environments. See [Permissions](https://code.claude.com/docs/en/agent-sdk/permissions.md) for full details.

241 241 

Details

16| Make a parameter optional | Declare it optional in the schema and apply the default in the handler. See [Make a parameter optional](#make-a-parameter-optional). |16| Make a parameter optional | Declare it optional in the schema and apply the default in the handler. See [Make a parameter optional](#make-a-parameter-optional). |

17| 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). |17| 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| Pre-approve a tool | Add to your allowed tools. See [Configure allowed tools](#configure-allowed-tools). |18| Pre-approve a tool | Add to your allowed tools. See [Configure allowed tools](#configure-allowed-tools). |

19| Require approval for calls to a tool, or block the tool | In the TypeScript SDK, add a `permission_policy` for the tool to the config object that `createSdkMcpServer()` returns. See [Require approval for specific tools](#require-approval-for-specific-tools). |

19| 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). |

20| Let Claude call tools in parallel | Set `readOnlyHint: true` on tools with no side effects. See [Add tool annotations](#add-tool-annotations). |21| Let Claude call tools in parallel | Set `readOnlyHint: true` on tools with no side effects. See [Add tool annotations](#add-tool-annotations). |

21| 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). |


327| Field | Default | Meaning |328| Field | Default | Meaning |

328| :- | :- | :- |329| :- | :- | :- |

329| `readOnlyHint` | `false` | Tool does not modify its environment. Controls whether the tool can be called in parallel with other read-only tools. |330| `readOnlyHint` | `false` | Tool does not modify its environment. Controls whether the tool can be called in parallel with other read-only tools. |

330| `destructiveHint` | `true` | Tool may perform destructive updates. Informational only. |331| `destructiveHint` | `true` | Tool may perform destructive updates. Set it to `true` explicitly on any tool you [mark `always_ask`](#require-approval-for-specific-tools). |

331| `idempotentHint` | `false` | Repeated calls with the same arguments have no additional effect. Informational only. |332| `idempotentHint` | `false` | Repeated calls with the same arguments have no additional effect. Informational only. |

332| `openWorldHint` | `true` | Tool reaches systems outside your process. Informational only. |333| `openWorldHint` | `true` | Tool reaches systems outside your process. Informational only. |

333 334 


383 384 

384To 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](https://code.claude.com/docs/en/agent-sdk/permissions.md) for the full evaluation order.385To 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](https://code.claude.com/docs/en/agent-sdk/permissions.md) for the full evaluation order.

385 386 

387### Require approval for specific tools

388 

389Set a tool's `permission_policy` to `always_ask`, and `allowedTools` stops approving that tool's calls, so they can reach your [`canUseTool`](https://code.claude.com/docs/en/agent-sdk/user-input) callback even though the tool is listed. Set `always_deny` instead, and [a call to the tool is denied](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated), but a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) in a plugin you load [can still approve it](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). The field is TypeScript-only and requires Agent SDK v0.3.301 or later.

390 

391Put the policy entry in a `tools` array on the config object `createSdkMcpServer()` returns, not in the `tools` option you pass into that function. This example spreads `weatherServer` from the [weather tool example](#weather-tool-example) and adds a `tools` array giving `get_temperature` the `always_ask` policy:

392 

393```typescript TypeScript theme={null}

394options: {

395 mcpServers: {

396 weather: {

397 ...weatherServer,

398 tools: [{ name: "get_temperature", permission_policy: "always_ask" as const }]

399 }

400 },

401 allowedTools: ["mcp__weather__get_temperature"],

402 permissionMode: "default",

403 canUseTool: async (toolName, input) => {

404 console.log(`Approval requested for ${toolName}`);

405 return { behavior: "allow", updatedInput: input };

406 }

407}

408```

409 

410To try the policy, replace the `options` in the [Call a custom tool](#call-a-custom-tool) script with this example's `options`, then run that script from your terminal. The script prints `Approval requested for mcp__weather__get_temperature`, followed by Claude's answer about the temperature. For a complete script, see the [TypeScript reference](https://code.claude.com/docs/en/agent-sdk/typescript.md#mcpsdkserverconfigwithinstance).

411 

412If you use `auto` or `plan` [permission mode](https://code.claude.com/docs/en/agent-sdk/permissions.md#permission-modes), set `destructiveHint: true` in the tool's [annotations](#add-tool-annotations) so calls to the tool still reach your callback. Otherwise the [auto mode classifier](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) can approve some `always_ask` calls, under [conditions listed in the TypeScript reference](https://code.claude.com/docs/en/agent-sdk/typescript.md#permission-modes-that-can-approve-an-always_ask-call), and a call it approves doesn't reach your callback. Set the hint explicitly, because an unset `destructiveHint` counts as `false` for `always_ask` calls rather than defaulting to `true`.

413 

386## Handle errors414## Handle errors

387 415 

388A handler error doesn't stop the agent loop. The SDK's in-process MCP server catches uncaught exceptions and returns them as error results, so how you report an error determines what Claude reads, not whether the query fails:416A handler error doesn't stop the agent loop. The SDK's in-process MCP server catches uncaught exceptions and returns them as error results, so how you report an error determines what Claude reads, not whether the query fails:

Details

10 10 

11## How permissions are evaluated11## How permissions are evaluated

12 12 

13> [!NOTE]

14>

15> If you load a plugin that contains a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md), see [where a mod's decisions fit among rules and hooks](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods).

16 

13When Claude requests a tool, the SDK checks permissions in this order:17When Claude requests a tool, the SDK checks permissions in this order:

14 18 

15**1. Hooks**19**1. Hooks**


20 24 

21**2. Deny rules**25**2. Deny rules**

22 26 

23Check `deny` rules (from `disallowed_tools` and [settings.json](https://code.claude.com/docs/en/settings-reference.md#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.27If a deny rule from `disallowed_tools` or [settings.json](https://code.claude.com/docs/en/settings-reference.md#permission-settings) matches, the call is denied and [`canUseTool`](https://code.claude.com/docs/en/agent-sdk/user-input) isn't called, even in [`bypassPermissions`](#bypass-permissions-mode-bypasspermissions) mode and even when a hook returned `allow`.

28 

29In the TypeScript SDK, if you set the `permission_policy` of a [custom tool](https://code.claude.com/docs/en/agent-sdk/custom-tools.md#require-approval-for-specific-tools) to [`always_deny`](https://code.claude.com/docs/en/agent-sdk/typescript#mcpservertoolpolicy), a call to that tool is denied at this step.

24 30 

25**3. Ask rules**31**3. Ask rules**

26 32 


30 36 

31[claude.ai connector](https://code.claude.com/docs/en/mcp.md#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.37[claude.ai connector](https://code.claude.com/docs/en/mcp.md#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.

32 38 

39In the TypeScript SDK, if you set a custom tool's `permission_policy` to [`always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools), no allow rule approves its calls, not even an `allowedTools` entry. In `dontAsk` mode Claude Code denies those calls, and in `auto`, `plan`, or `bypassPermissions` mode it [can approve them](https://code.claude.com/docs/en/agent-sdk/typescript.md#permission-modes-that-can-approve-an-always_ask-call) before your callback runs.

40 

33**4. Permission mode**41**4. Permission mode**

34 42 

35Apply the active [permission mode](#permission-modes):43Apply the active [permission mode](#permission-modes):

36 44 

37* In `bypassPermissions` mode, Claude Code approves everything that reaches this step except recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths), which fall through instead.45* In `bypassPermissions` mode, Claude Code approves everything that reaches this step except recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) and Bash commands flagged [`Dangerous rm operation not ruled out`](https://code.claude.com/docs/en/permission-modes#dangerous-rm-operation-not-ruled-out), which fall through instead.

38* In `acceptEdits` mode, Claude Code approves the file operations listed under [Accept edits mode](#accept-edits-mode-acceptedits).46* In `acceptEdits` mode, Claude Code approves the file operations listed under [Accept edits mode](#accept-edits-mode-acceptedits).

39* In `plan` mode, Claude Code sends file-edit and shell-write tools to your `canUseTool` callback regardless of allow rules, so write operations can't be auto-approved while planning.47* In `plan` mode, Claude Code sends file-edit tools to your `canUseTool` callback regardless of allow rules.

40* In other modes, the request falls through.48* In other modes, the request falls through.

41 49 

42**5. Allow rules**50**5. Allow rules**

43 51 

44Check `allow` rules (from `allowed_tools` and settings.json). If a rule matches, the tool is approved. A call the tool approves on its own is resolved at this step too, with no rule needed: for example a file read inside your working directories or a [read-only Bash command](https://code.claude.com/docs/en/permissions.md#read-only-commands).52Check `allow` rules (from `allowed_tools` and settings.json). If a rule matches, the tool is approved. A call the tool approves on its own is resolved at this step too, with no rule needed: for example a file read inside your working directories or a [read-only Bash command](https://code.claude.com/docs/en/permissions.md#read-only-commands).

45 53 

46Recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) aren't approved by an allow rule. Whether they then reach your callback depends on the permission mode: in an Agent SDK session in `auto` mode, for example, Claude Code denies them by default without calling it. The [Critical paths mode table](https://code.claude.com/docs/en/permission-modes.md#critical-path-removals-in-each-permission-mode) lists what each mode does with them.54Recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) aren't approved by an allow rule, and commands flagged `Dangerous rm operation not ruled out` aren't approved by a `Bash` or `Bash(*)` rule. Whether they then reach your callback depends on the permission mode: in an Agent SDK session in `auto` mode, for example, Claude Code denies them by default without calling it. The [Critical paths mode table](https://code.claude.com/docs/en/permission-modes.md#critical-path-removals-in-each-permission-mode) lists what each mode does with them.

47 55 

48An allow rule doesn't approve a read from a [network path](https://code.claude.com/docs/en/permissions.md#network-paths).56An allow rule doesn't approve a read from a [network path](https://code.claude.com/docs/en/permissions.md#network-paths).

49 57 


57 65 

58If you pass a `canUseTool` callback in a configuration where the TypeScript SDK expects the evaluation order to auto-approve calls before the callback is consulted, the 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:66If you pass a `canUseTool` callback in a configuration where the TypeScript SDK expects the evaluation order to auto-approve calls before the callback is consulted, the 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:

59 67 

60* `permissionMode: 'bypassPermissions'`, which auto-approves every call that reaches the permission mode step apart from the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves)68* `permissionMode: 'bypassPermissions'`: the warning text starts with `canUseTool will not be invoked: permissionMode 'bypassPermissions'`. Tool calls are approved before `canUseTool` is consulted, so your callback runs for only a few calls, such as the calls listed under [Bypass permissions mode](#bypass-permissions-mode-bypasspermissions). To check the approved calls too, put your callback's checks in a [`PreToolUse` hook](https://code.claude.com/docs/en/agent-sdk/hooks)

61* Each bare `allowedTools` entry such as `"Read"`, which auto-approves that whole tool before the callback is consulted, apart from the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) and [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths)69* An `allowedTools` entry that is only a tool name, such as `"Read"`: the warning lists each such entry after `canUseTool will not be invoked for:`. Calls to a listed tool are approved before `canUseTool` is consulted, apart from the [calls an allow rule never approves](#calls-an-allow-rule-never-approves). To have your callback run for a listed tool's calls that need approval, remove that tool's entry from `allowedTools`

62 70 

63Entries 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.71Entries 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.

64 72 

65Listen 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](https://code.claude.com/docs/en/agent-sdk/hooks) instead.73The warning doesn't block any call or change any option. If your callback already receives every call you want to check, leave your configuration as it is. To log the warning, listen with `process.on('warning', ...)` and match the `CLAUDE_SDK_CAN_USE_TOOL_SHADOWED` code.

66 74 

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

68 76 


90>98>

91> **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.99> **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.

92>100>

93> No allow rule auto-approves `AskUserQuestion`, MCP tools marked [`_meta["anthropic/requiresUserInteraction"]`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool), connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), or recognized `rm` and `rmdir` [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths). In `dontAsk` mode Claude Code denies these calls without invoking the callback. In other modes the first three reach the callback. The [Critical paths mode table](https://code.claude.com/docs/en/permission-modes.md#critical-path-removals-in-each-permission-mode) lists what each mode does with a critical-path removal. The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths).101> If calls to a tool in `allowed_tools` still reach your `canUseTool` callback, or are denied in `dontAsk` mode, check whether they're [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths) or among the following calls. No allow rule approves these calls. In `dontAsk` mode, which never prompts, Claude Code denies them without calling `canUseTool`, and in the other permission modes you handle them as each item says:

102>

103> * `AskUserQuestion`, MCP tools marked [`_meta["anthropic/requiresUserInteraction"]`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool), and connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools): answer them in the callback. [Handle clarifying questions](https://code.claude.com/docs/en/agent-sdk/user-input.md#handle-clarifying-questions) shows how to answer `AskUserQuestion`, and a connector call arrives with the reason `Your organization requires approval for this tool`

104>

105> * Custom tools your application marks [`always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools): decide the call in the callback. To stop these calls arriving, [change the policy mid-session](https://code.claude.com/docs/en/agent-sdk/typescript.md#mcpsdkserverconfigwithinstance). In `auto`, `plan`, and `bypassPermissions` mode the call can instead be approved before the callback, in the cases listed under [Permission modes that can approve an `always_ask` call](https://code.claude.com/docs/en/agent-sdk/typescript#permission-modes-that-can-approve-an-always_ask-call)

94>106>

95> Coverage depends on the entry's form: a bare name like `Read` or `mcp__github__get_issue` auto-approves every call to that tool apart from those exceptions and [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths), while a scoped rule like `Bash(npm test *)` auto-approves only matching calls, and other `Bash` calls that need approval still fall through to the callback. For checks that must run on every tool call, use a [`PreToolUse` hook](https://code.claude.com/docs/en/agent-sdk/hooks): hooks run before every other step, and a hook deny applies even in `bypassPermissions` mode.107> * Recognized `rm` and `rmdir` [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths): in `default`, `acceptEdits`, and `bypassPermissions` mode, allow or deny the removal in the callback, where [`decisionReason`](https://code.claude.com/docs/en/agent-sdk/typescript#canusetool) starts with `Dangerous rm`. For `auto` and `plan` mode, see [Critical-path removals in each permission mode](https://code.claude.com/docs/en/permission-modes.md#critical-path-removals-in-each-permission-mode). The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths)

108>

109> * **Bare name**: an entry like `Read` or `mcp__github__get_issue` auto-approves every call to that tool apart from the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) and [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths).

110>

111> * **Scoped rule**: an entry like `Bash(npm test *)` auto-approves only matching calls, and other `Bash` calls that need approval still fall through to the callback.

112>

113> For checks that must run on every tool call, use a [`PreToolUse` hook](https://code.claude.com/docs/en/agent-sdk/hooks): hooks run before every other step, and a hook deny applies even in `bypassPermissions` mode.

96 114 

97For a locked-down agent, pair `allowedTools` with `permissionMode: "dontAsk"`:115For a locked-down agent, pair `allowedTools` with `permissionMode: "dontAsk"`:

98 116 


103};121};

104```122```

105 123 

106Listed tools are approved, apart from the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) and [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths). Every other call that would prompt is denied instead, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods).124The listed `Read`, `Glob`, and `Grep` calls are approved, apart from the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) and [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths). Every other call that would prompt is denied instead, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods).

107 125 

108Calls that need no approval in `default` mode run whether or not you list them. They include [read-only Bash commands](https://code.claude.com/docs/en/permissions.md#read-only-commands), tools like `Agent` that don't ask before running, and file reads inside your working directories. To remove a tool from the request entirely, add its bare name to `disallowedTools`.126Calls that need no approval in `default` mode run whether or not you list them. These include [read-only Bash commands](https://code.claude.com/docs/en/permissions.md#read-only-commands), tools like `Agent` that don't ask before running, and file reads inside your working directories. To hide a built-in tool from Claude entirely rather than deny its calls, add its bare name to `disallowedTools`.

109 127 

110> [!WARNING]128> [!WARNING]

111>129>


128| `default` | Standard permission behavior | No mode-based auto-approvals; calls that need approval and match no allow rule trigger your `canUseTool` callback |146| `default` | Standard permission behavior | No mode-based auto-approvals; calls that need approval and match no allow rule trigger your `canUseTool` callback |

129| `dontAsk` | Deny instead of prompting | Any call that would otherwise prompt is denied without calling `canUseTool`, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). Calls approved by `allowed_tools` or `settings.json` allow rules run, and so do calls that need no approval in `default` mode. Some calls, such as [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths), are denied even when `allowed_tools` or an allow rule matches them. For the list, see [Don't ask mode](#don’t-ask-mode-dontask) |147| `dontAsk` | Deny instead of prompting | Any call that would otherwise prompt is denied without calling `canUseTool`, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). Calls approved by `allowed_tools` or `settings.json` allow rules run, and so do calls that need no approval in `default` mode. Some calls, such as [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths), are denied even when `allowed_tools` or an allow rule matches them. For the list, see [Don't ask mode](#don’t-ask-mode-dontask) |

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

131| `bypassPermissions` | Bypass permission checks | Tools run without permission prompts, except for the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves). Use with caution |149| `bypassPermissions` | Bypass permission checks | Tools run without permission prompts, except for the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) and, outside a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), custom tools your application [marks `always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools). Use with caution |

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

133| `auto` | Model-classified approvals | A model classifier reviews actions such as shell commands and network requests, allowing or blocking each one it reviews. See [Auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) for availability and the decision order |151| `auto` | Model-classified approvals | A model classifier reviews actions such as shell commands and network requests, allowing or blocking each one it reviews. See [Auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) for availability and the decision order |

134 152 


256* Works on a path outside that scope274* Works on a path outside that scope

257* Writes to a protected path275* Writes to a protected path

258* Removes a path that Claude Code recognizes as a [critical path](https://code.claude.com/docs/en/permission-modes.md#critical-paths) with `rm` or `rmdir`276* Removes a path that Claude Code recognizes as a [critical path](https://code.claude.com/docs/en/permission-modes.md#critical-paths) with `rm` or `rmdir`

277* Runs [`touch`](https://code.claude.com/docs/en/permission-modes#auto-approve-file-edits-with-acceptedits-mode) with, for example, an option, a glob, or a `timeout 5` or `LANG=C` prefix

259 278 

260**Use when:** you trust Claude's edits and want faster iteration, such as during prototyping or when working in an isolated directory.279**Use when:** you trust Claude's edits and want faster iteration, such as during prototyping or when working in an isolated directory.

261 280 

262#### Don't ask mode (`dontAsk`)281#### Don't ask mode (`dontAsk`)

263 282 

264Converts any permission prompt into a denial, without calling `canUseTool`, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). Tools pre-approved by `allowed_tools`, `settings.json` allow rules, or a hook run as normal. Calls that need no approval in `default` mode also run, such as file reads inside your working directories and calls to `Agent`.283Converts any permission prompt into a denial, without calling `canUseTool`, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). Tools pre-approved by `allowed_tools`, `settings.json` allow rules, or a hook run as normal. Calls that need no approval in `default` mode also run as normal, such as file reads inside your working directories and calls to `Agent`.

265 284 

266Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), tools that require user interaction, [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths), and recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) are denied even when an allow rule matches. A `PreToolUse` hook allow doesn't clear a recognized critical-path removal or a read from a network path either. The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths).285These calls are denied even when an allow rule matches:

286 

287* Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools)

288* Tools that require user interaction, such as `AskUserQuestion` and MCP tools whose server sets [`_meta["anthropic/requiresUserInteraction"]`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool)

289* Custom tools whose `permission_policy` your application sets to [`always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools)

290* [Reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths)

291* Recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths)

292 

293If your `PreToolUse` hook returns `allow` for a recognized critical-path removal, a read from a network path, or a call to a tool marked `always_ask`, the call is still denied. The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths).

267 294 

268**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.295**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.

269 296 

270#### Bypass permissions mode (`bypassPermissions`)297#### Bypass permissions mode (`bypassPermissions`)

271 298 

272Auto-approves tool uses without prompting, except the cases listed in the warning below. Hooks still execute and can block operations if needed. On Linux and macOS, Claude Code refuses to start in this mode as root or under `sudo` outside a [recognized sandbox](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode), and the query fails before the first turn.299Auto-approves tool uses without prompting, except the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves). Hooks still execute and can block operations if needed. On Linux and macOS, Claude Code refuses to start in this mode as root or under `sudo` outside a [recognized sandbox](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode), and the query fails before the first turn.

273 300 

274> [!WARNING]301> [!WARNING]

275>302>


278> `allowed_tools` does not constrain this mode. Every tool is approved, not just the ones you listed. These controls still apply:305> `allowed_tools` does not constrain this mode. Every tool is approved, not just the ones you listed. These controls still apply:

279>306>

280> * Deny rules, explicit `ask` rules, and hooks are evaluated before the mode check and can still block a tool.307> * Deny rules, explicit `ask` rules, and hooks are evaluated before the mode check and can still block a tool.

281> * Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), tools that require user interaction, and recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) still fall through to your `canUseTool` callback. The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths).308> * Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), tools that require user interaction, and recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) still fall through to your `canUseTool` callback. The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths). Outside a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), calls to custom tools your application [marks `always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools) fall through to the callback too.

282> * The [cross-session messaging safeguards](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) still apply.309> * The [cross-session messaging safeguards](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) still apply.

283 310 

284#### Plan mode (`plan`)311#### Plan mode (`plan`)

285 312 

286Claude explores the codebase and produces a plan without editing your source files. Read-only tools run as they do in the `default` permission mode.313Claude explores the codebase and produces a plan without editing your source files. File edits are never auto-approved in plan mode, even when an allow rule matches or a `PreToolUse` hook returns `allow`. They prompt through your `canUseTool` callback instead.

287 314 

288File edits are never auto-approved in plan mode, even when an allow rule matches or a `PreToolUse` hook returns `allow`. They prompt through your `canUseTool` callback instead. 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.315While auto mode is available to the session, commands Claude runs during planning don't reach your callback by default, because the classifier model that [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) uses [reviews them instead](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode). With that review on, the classifier can also approve read-only calls that would otherwise reach your callback, such as a `WebFetch` call with no allow rule.

289 316 

290In the TypeScript SDK, if you set `allowDangerouslySkipPermissions: true` alongside `permissionMode: 'plan'`, file edits and shell commands that modify files still reach your `canUseTool` callback. The option lets you switch to `bypassPermissions` later with `setPermissionMode()`.317> [!NOTE]

318>

319> In the TypeScript SDK, if you set `allowDangerouslySkipPermissions: true` alongside `permissionMode: 'plan'`, file edits still reach your `canUseTool` callback. To switch a session that starts in plan mode to `bypassPermissions` later with `setPermissionMode()`, you need `allowDangerouslySkipPermissions` set from the start.

291 320 

292Claude may use `AskUserQuestion` to clarify requirements before finalizing the plan. See [Handle approvals and user input](https://code.claude.com/docs/en/agent-sdk/user-input.md#handle-clarifying-questions) for handling these prompts.321Claude may use `AskUserQuestion` to clarify requirements before finalizing the plan. See [Handle approvals and user input](https://code.claude.com/docs/en/agent-sdk/user-input.md#handle-clarifying-questions) for handling these prompts.

293 322 

Details

70>70>

71> The path should point to the plugin's root directory: the parent of `skills/`, `agents/`, `hooks/`, `commands/`, or `.claude-plugin/`.71> The path should point to the plugin's root directory: the parent of `skills/`, `agents/`, `hooks/`, `commands/`, or `.claude-plugin/`.

72 72 

73### Add plugins to a running session

74 

75In the TypeScript SDK, call [`reloadPlugins()`](https://code.claude.com/docs/en/agent-sdk/typescript#load-more-plugin-folders-with-addplugins) on the `Query` object that `query()` returned, and list the plugin directory in that call's `addPlugins` option. Each `addPlugins` entry is a `{ type: "local", path }` object with an absolute `path`. Requires TypeScript Agent SDK v0.3.301 or later.

76 

77In this example, `q` is the `Query` object that `query()` returned. The example adds one plugin directory to the running session and, after `reloadPlugins()` returns, prints the path of every plugin in the session:

78 

79```typescript theme={null}

80const result = await q.reloadPlugins({

81 addPlugins: [{ type: "local", path: "/home/user/plugins/another-plugin" }]

82});

83 

84console.log(result.plugins.map((plugin) => plugin.path));

85```

86 

87If the plugin loaded, the printed list includes `/home/user/plugins/another-plugin`. If that path is missing from the list, or `reloadPlugins()` rejects, see [When `reloadPlugins()` doesn't load the `addPlugins` folders](https://code.claude.com/docs/en/agent-sdk/typescript#when-reloadplugins-doesnt-load-the-addplugins-folders) for the causes.

88 

73## Verifying plugin installation89## Verifying plugin installation

74 90 

75When plugins load successfully, they appear in the system initialization message. You can verify that your plugins are available:91When plugins load successfully, they appear in the system initialization message. You can verify that your plugins are available:

Details

200| :- | :- | :- | :- |200| :- | :- | :- | :- |

201| `title` | `string` | `undefined` | Human-readable title for the tool |201| `title` | `string` | `undefined` | Human-readable title for the tool |

202| `readOnlyHint` | `boolean` | `false` | If `true`, the tool does not modify its environment |202| `readOnlyHint` | `boolean` | `false` | If `true`, the tool does not modify its environment |

203| `destructiveHint` | `boolean` | `true` | If `true`, the tool may perform destructive updates (only meaningful when `readOnlyHint` is `false`) |203| `destructiveHint` | `boolean` | `true` | If `true`, the tool may perform destructive updates. Set `destructiveHint: true` explicitly on any tool you mark [`always_ask`](#mcpservertoolpolicy), or the auto mode classifier can approve that tool's calls in place of your `canUseTool` callback. Leaving `destructiveHint` unset isn't enough, because Claude Code treats an unset `destructiveHint` as `false` when it handles `always_ask` calls, although the MCP specification's default is `true` |

204| `idempotentHint` | `boolean` | `false` | If `true`, repeated calls with the same arguments have no additional effect (only meaningful when `readOnlyHint` is `false`) |204| `idempotentHint` | `boolean` | `false` | If `true`, repeated calls with the same arguments have no additional effect (only meaningful when `readOnlyHint` is `false`) |

205| `openWorldHint` | `boolean` | `true` | If `true`, the tool interacts with external entities (for example, web search). If `false`, the tool's domain is closed (for example, a memory tool) |205| `openWorldHint` | `boolean` | `true` | If `true`, the tool interacts with external entities (for example, web search). If `false`, the tool's domain is closed (for example, a memory tool) |

206 206 


630 ): Promise<SDKControlReadFileResponse | null>;630 ): Promise<SDKControlReadFileResponse | null>;

631 reloadPlugins(options?: {631 reloadPlugins(options?: {

632 holdOnCacheImpact?: boolean;632 holdOnCacheImpact?: boolean;

633 addPlugins?: SdkPluginConfig[];

633 }): Promise<SDKControlReloadPluginsResponse>;634 }): Promise<SDKControlReloadPluginsResponse>;

634 reloadSkills(): Promise<SDKControlReloadSkillsResponse>;635 reloadSkills(): Promise<SDKControlReloadSkillsResponse>;

635 reloadOutputStyles(): Promise<SDKControlReloadOutputStylesResponse>;636 reloadOutputStyles(): Promise<SDKControlReloadOutputStylesResponse>;


669| `mcpServerStatus()` | Returns the status of connected MCP servers as [`McpServerStatus`](#mcpserverstatus)`[]` |670| `mcpServerStatus()` | Returns the status of connected MCP servers as [`McpServerStatus`](#mcpserverstatus)`[]` |

670| `getContextUsage(opts?)` | Returns an [`SDKControlGetContextUsageResponse`](#sdkcontrolgetcontextusageresponse) breaking down the session's context window usage by category, skill, and tool. With the default `detail`, it includes the data `/context` shows in an interactive session, computed with token-counting API requests that don't appear in the message stream; see [how these requests are handled](#sdkcontrolgetcontextusageresponse). The [`detail` option](#sdkcontrolgetcontextusageresponse) requires Agent SDK v0.3.257 or later |671| `getContextUsage(opts?)` | Returns an [`SDKControlGetContextUsageResponse`](#sdkcontrolgetcontextusageresponse) breaking down the session's context window usage by category, skill, and tool. With the default `detail`, it includes the data `/context` shows in an interactive session, computed with token-counting API requests that don't appear in the message stream; see [how these requests are handled](#sdkcontrolgetcontextusageresponse). The [`detail` option](#sdkcontrolgetcontextusageresponse) requires Agent SDK v0.3.257 or later |

671| `readFile(path, options?)` | Reads a file from the session's filesystem. Claude Code resolves the path against `cwd`; [What `readFile()` can read](#what-readfile-can-read) lists the files it serves. Pass `{ maxBytes }` to change the read cap (default 1 MB, ceiling 10 MB) and `{ encoding: 'base64' }` for binary files such as images. Resolves with an [`SDKControlReadFileResponse`](#sdkcontrolreadfileresponse), or `null` on permission denial, a missing file, or a transport error. Requires TypeScript SDK v0.2.121 or later |672| `readFile(path, options?)` | Reads a file from the session's filesystem. Claude Code resolves the path against `cwd`; [What `readFile()` can read](#what-readfile-can-read) lists the files it serves. Pass `{ maxBytes }` to change the read cap (default 1 MB, ceiling 10 MB) and `{ encoding: 'base64' }` for binary files such as images. Resolves with an [`SDKControlReadFileResponse`](#sdkcontrolreadfileresponse), or `null` on permission denial, a missing file, or a transport error. Requires TypeScript SDK v0.2.121 or later |

672| `reloadPlugins(options?)` | Reloads plugins from disk, so plugins you install or edit mid-session reach the running session. Resolves with an [`SDKControlReloadPluginsResponse`](#sdkcontrolreloadpluginsresponse) listing the session's commands, subagents, plugins, and MCP server status. Requires Agent SDK v0.2.85 or later. The [`holdOnCacheImpact` option](#sdkcontrolreloadpluginsresponse) requires Agent SDK v0.3.268 or later |673| `reloadPlugins(options?)` | Reloads plugins from disk, so plugins you install or edit mid-session reach the running session. Resolves with an [`SDKControlReloadPluginsResponse`](#sdkcontrolreloadpluginsresponse) listing the session's commands, subagents, plugins, and MCP server status. Requires Agent SDK v0.2.85 or later. The [`holdOnCacheImpact` option](#sdkcontrolreloadpluginsresponse) requires Agent SDK v0.3.268 or later. The [`addPlugins` option](#load-more-plugin-folders-with-addplugins) requires Agent SDK v0.3.301 or later |

673| `reloadSkills()` | Reloads skills from disk, so skills you add or edit mid-session become available to the running session. Resolves with an [`SDKControlReloadSkillsResponse`](#sdkcontrolreloadskillsresponse) listing the skills available after the reload. Requires Agent SDK v0.3.163 or later |674| `reloadSkills()` | Reloads skills from disk, so skills you add or edit mid-session become available to the running session. Resolves with an [`SDKControlReloadSkillsResponse`](#sdkcontrolreloadskillsresponse) listing the skills available after the reload. Requires Agent SDK v0.3.163 or later |

674| `reloadOutputStyles()` | Re-reads [output styles](https://code.claude.com/docs/en/output-styles.md) from disk, so a style file you add or edit mid-session becomes available to the running session. Resolves with an [`SDKControlReloadOutputStylesResponse`](#sdkcontrolreloadoutputstylesresponse) listing the style names available after the reload. Requires Agent SDK v0.3.261 or later |675| `reloadOutputStyles()` | Re-reads [output styles](https://code.claude.com/docs/en/output-styles.md) from disk, so a style file you add or edit mid-session becomes available to the running session. Resolves with an [`SDKControlReloadOutputStylesResponse`](#sdkcontrolreloadoutputstylesresponse) listing the style names available after the reload. Requires Agent SDK v0.3.261 or later |

675| `seedReadState(path, mtime)` | Marks a file as already read so a later Edit doesn't fail with `File has not been read yet`. See [`seedReadState()`](#seedreadstate). Requires TypeScript SDK v0.2.83 or later |676| `seedReadState(path, mtime)` | Marks a file as already read so a later Edit doesn't fail with `File has not been read yet`. See [`seedReadState()`](#seedreadstate). Requires TypeScript SDK v0.2.83 or later |


1135 1136 

1136`cache_impact` is present only alongside `held: true`. `mcp_servers_added` and `mcp_servers_removed` name the plugin MCP servers the reload would register or drop, as scoped `plugin:<plugin>:<server>` names. The names are plugin-authored, so validate them before showing them. `lsp_tool_change` says whether applying would add or remove the LSP tool, or `null` when it would do neither. The `may-` forms mean the check couldn't fully see the pending plugin set.1137`cache_impact` is present only alongside `held: true`. `mcp_servers_added` and `mcp_servers_removed` name the plugin MCP servers the reload would register or drop, as scoped `plugin:<plugin>:<server>` names. The names are plugin-authored, so validate them before showing them. `lsp_tool_change` says whether applying would add or remove the LSP tool, or `null` when it would do neither. The `may-` forms mean the check couldn't fully see the pending plugin set.

1137 1138 

1139#### Load more plugin folders with `addPlugins`

1140 

1141To load plugin folders that weren't in the [`plugins`](#options) option at startup, pass them to `reloadPlugins()` as `addPlugins`, a list of [`SdkPluginConfig`](#sdkpluginconfig) entries whose `path` is absolute. Claude Code loads the new folders and reloads the session's existing plugins in one pass. Each added plugin's MCP servers connect too, unless you set [`skipMcpDiscovery`](#sdkpluginconfig) on that folder's entry. Requires Agent SDK v0.3.301 or later and Claude Code v2.1.301 or later.

1142 

1143This example adds one folder to a running query `q` and prints the install path of every plugin the session has loaded when the call returns:

1144 

1145```typescript theme={null}

1146const result = await q.reloadPlugins({

1147 addPlugins: [{ type: "local", path: "/opt/my-app/plugins/reports" }]

1148});

1149 

1150console.log(result.plugins.map((plugin) => plugin.path));

1151```

1152 

1153If the folder loaded, the printed list includes `/opt/my-app/plugins/reports`, and the plugin's commands and subagents appear in `result.commands` and `result.agents`.

1154 

1155An added folder stays part of the session. When you call `reloadPlugins()` again, Claude Code reloads it with the other plugins, and you don't pass it in `addPlugins` again.

1156 

1157##### When `reloadPlugins()` doesn't load the `addPlugins` folders

1158 

1159If `reloadPlugins()` rejects, none of the `addPlugins` folders are added, so pass them in `addPlugins` again when you retry. When the rejection has one of the following causes, the session keeps the plugins it already had:

1160 

1161* **A relative `path` or a malformed entry**: the error message says `add_plugins must be a list of { type: "local", path } entries with absolute paths`. Claude Code refuses the whole list over one bad entry, so pass every entry as `{ type: "local", path }` with an absolute `path`

1162* **An administrator has turned on [`disableSideloadFlags`](https://code.claude.com/docs/en/settings-reference#disablesideloadflags) in your managed settings**: the message says `reload_plugins add_plugins is disabled by managed settings (disableSideloadFlags)`. To load the folder, ask that administrator to remove the setting

1163* **The [sandbox](https://code.claude.com/docs/en/sandboxing.md) couldn't be rebuilt**: with [sandboxing](#sandboxsettings) on, Claude Code rebuilds the sandbox configuration so that sandboxed shell commands can't write to the folders you add. The message says `the sandbox could not be rebuilt to keep shell commands out of this folder`. Check that your [sandbox settings](#sandboxsettings) still form a valid configuration

1164 

1165If you pass `holdOnCacheImpact` and the call resolves with [`held: true`](#sdkcontrolreloadpluginsresponse), the `addPlugins` folders aren't added. To add them anyway, call `reloadPlugins()` again with the same `addPlugins` list and without `holdOnCacheImpact`.

1166 

1167When the call resolves without `held: true` and a folder is still missing from `result.plugins`, start by checking for these causes:

1168 

1169* **The folder doesn't exist or its plugin failed to load**: `result.error_count` is `1` or higher. The folder stays part of the session even so. After you fix the folder, call `reloadPlugins()` again to load it, this time without listing it in `addPlugins`

1170* **The Claude Code executable is older than v2.1.301**: an executable older than v2.1.301 ignores `addPlugins` and reloads only the plugins the session already had. Check `claude_code_version` on the [init message](#sdksystemmessage), and run an executable at v2.1.301 or later

1171 

1138### `SDKControlReloadSkillsResponse`1172### `SDKControlReloadSkillsResponse`

1139 1173 

1140Return type of [`reloadSkills()`](#query-object).1174Return type of [`reloadSkills()`](#query-object).


1430 1464 

1431#### `McpSdkServerConfigWithInstance`1465#### `McpSdkServerConfigWithInstance`

1432 1466 

1467The configuration for an in-process MCP server, one that [`createSdkMcpServer()`](#createsdkmcpserver) creates and that runs inside your application's process. It is the object `createSdkMcpServer()` returns, plus an optional `tools` list of [`McpServerToolPolicy`](#mcpservertoolpolicy) entries that you add yourself. To require approval for calls to one of the server's tools, or to deny them, add an entry that names the tool.

1468 

1433```typescript theme={null}1469```typescript theme={null}

1434type McpSdkServerConfigWithInstance = {1470type McpSdkServerConfigWithInstance = {

1435 type: "sdk";1471 type: "sdk";

1436 name: string;1472 name: string;

1437 timeout?: number;1473 timeout?: number;

1474 tools?: McpServerToolPolicy[];

1438 instance: McpServer;1475 instance: McpServer;

1439};1476};

1440```1477```

1441 1478 

1479To set a policy, spread the object `createSdkMcpServer()` returns into a new object in `mcpServers` and add the `tools` list to that new object. The `tools` option of `createSdkMcpServer()` itself is a different list, which holds the tool definitions and doesn't accept policy entries. The policy list requires Agent SDK v0.3.301 or later, and [`McpServerToolPolicy`](#mcpservertoolpolicy) describes what each `permission_policy` value does.

1480 

1481This example pre-approves every tool on the `records` server with an `allowedTools` wildcard, then marks `delete_record` as `always_ask` so that calls to it go to `canUseTool` anyway. With the `destructiveHint: true` annotation, the call still reaches the callback if the session runs in `auto` mode, where the auto mode [classifier](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) could otherwise approve it.

1482 

1483```typescript theme={null}

1484import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";

1485import { z } from "zod";

1486 

1487const deleteRecord = tool(

1488 "delete_record",

1489 "Delete a customer record by ID",

1490 { id: z.string() },

1491 async ({ id }) => ({ content: [{ type: "text", text: `Deleted record ${id}` }] }),

1492 { annotations: { destructiveHint: true } }

1493);

1494 

1495const records = createSdkMcpServer({ name: "records", tools: [deleteRecord] });

1496 

1497for await (const message of query({

1498 prompt: "Delete customer record 42",

1499 options: {

1500 mcpServers: {

1501 // Spread the returned config and add the policy list beside it

1502 records: {

1503 ...records,

1504 tools: [{ name: "delete_record", permission_policy: "always_ask" as const }]

1505 }

1506 },

1507 allowedTools: ["mcp__records__*"],

1508 canUseTool: async (toolName, input) => {

1509 console.log(`Approval requested for ${toolName}`);

1510 return { behavior: "allow", updatedInput: input };

1511 }

1512 }

1513})) {

1514 if (message.type === "result" && message.subtype === "success") {

1515 console.log(message.result);

1516 }

1517}

1518```

1519 

1520When Claude calls the tool, the script prints `Approval requested for mcp__records__delete_record` before the `delete_record` tool runs, although the `allowedTools` entry would otherwise have approved the call.

1521 

1522To change or lift a tool's policy while the session runs, pass the server's config with a new `tools` value to [`setMcpServers()`](#mcpsetserversresult). The `tools` value you pass takes effect from Claude's next call to that server's tools:

1523 

1524* **A list with entries**: the entries replace the current policies

1525* **An empty list**: every policy on the server is cleared

1526* **No `tools` key**: the current policies stay

1527 

1528Include in that call your other in-process servers and any server an earlier `setMcpServers()` call added, or the call disconnects them.

1529 

1530#### `McpServerToolPolicy`

1531 

1532One entry in an [`McpSdkServerConfigWithInstance`](#mcpsdkserverconfigwithinstance)'s `tools` list, naming one of the server's tools and setting the permission policy for calls to that tool. The list requires Agent SDK v0.3.301 or later and Claude Code v2.1.301 or later. An older Claude Code executable, such as an executable you point `pathToClaudeCodeExecutable` at, ignores the list. Then `always_ask` and `always_deny` aren't enforced, and each call goes through the [permission flow](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated).

1533 

1534```typescript theme={null}

1535type McpServerToolPolicy = {

1536 name: string;

1537 permission_policy?: "always_allow" | "always_ask" | "always_deny";

1538 org_max_permission?: "allow" | "ask" | "blocked";

1539};

1540```

1541 

1542| Field | Type | Description |

1543| :- | :- | :- |

1544| `name` | `string` | The tool's bare name as passed to [`tool()`](#tool), without the `mcp__<server>__` prefix |

1545| `permission_policy` | `'always_allow' \| 'always_ask' \| 'always_deny'` | The approval policy for the tool's calls, [`always_ask` or `always_deny`](#permission-policy-values). `always_allow` is ignored on an in-process server: to pre-approve a tool, list it in [`allowedTools`](#options) instead |

1546| `org_max_permission` | `'allow' \| 'ask' \| 'blocked'` | A per-tool ceiling that an organization admin sets. Ignored on an in-process server, so leave it unset |

1547 

1548##### `permission_policy` values

1549 

1550Choose `always_ask` to approve each call yourself, or `always_deny` to block the tool outright:

1551 

1552* **`always_ask`**: each call to the tool [needs approval](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated), even if an `allowedTools` entry or allow rule covers it. The call goes to your `canUseTool` callback or [`permissionPromptToolName`](#options) tool, unless it's settled first. A [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) in a plugin you load [can approve it first](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). Otherwise, in `dontAsk` mode it's denied, and in [`auto`, `plan`, and `bypassPermissions` mode](#permission-modes-that-can-approve-an-always_ask-call) it can be approved before it reaches your callback

1553* **`always_deny`**: a call to the tool [is denied](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) in every permission mode, including `bypassPermissions`, but a mod in a plugin you load [can still approve it](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods)

1554 

1555If you pass neither `canUseTool` nor `permissionPromptToolName`, or set [`permissionPrompts`](#options) to `'none'`, an `always_ask` call that isn't settled first is denied unless a [`PermissionRequest` hook](https://code.claude.com/docs/en/hooks#permissionrequest) allows it.

1556 

1557##### Permission modes that can approve an `always_ask` call

1558 

1559In `auto`, `plan`, and `bypassPermissions` mode, a call to a tool marked [`always_ask`](#permission-policy-values) can be approved before it reaches your `canUseTool` callback. Find your session's mode in this list to see when that approval happens and what to set so the call reaches your callback anyway:

1560 

1561* **`auto`**: the auto mode [classifier](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) reviews the call and can allow it. To make every call reach your callback in `auto` mode, set `destructiveHint: true` in the tool's [annotations](#toolannotations)

1562* **`plan`**: while [auto mode is available](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) to the session, calls to an `always_ask` tool annotated `readOnlyHint: true` go to the auto mode classifier, which can allow them. Calls to other `always_ask` tools reach your callback. To make a read-only tool's calls reach your callback too, add `destructiveHint: true` to that tool's annotations alongside `readOnlyHint: true`. Alternatively, set [`useAutoModeDuringPlan`](https://code.claude.com/docs/en/settings-reference#useautomodeduringplan) to `false`, which turns the classifier off during planning

1563* **`bypassPermissions`**: when the [`CLAUDE_CODE_REMOTE`](https://code.claude.com/docs/en/env-vars#variables) environment variable is `true`, as it is in a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), the call is approved without your callback, whatever the tool's annotations. Anywhere else the call reaches your callback. To make it reach your callback in a cloud session too, run the session in `default` or `acceptEdits` mode instead

1564 

1565Set `destructiveHint` to `true` explicitly in `auto` and `plan` mode. For `always_ask` calls, Claude Code reads an unset `destructiveHint` as `false`, although the default listed under [`ToolAnnotations`](#toolannotations) is `true`.

1566 

1442#### `McpClaudeAIProxyServerConfig`1567#### `McpClaudeAIProxyServerConfig`

1443 1568 

1444```typescript theme={null}1569```typescript theme={null}


1464| Field | Type | Description |1589| Field | Type | Description |

1465| :- | :- | :- |1590| :- | :- | :- |

1466| `type` | `'local'` | Must be `'local'` (only local plugins currently supported) |1591| `type` | `'local'` | Must be `'local'` (only local plugins currently supported) |

1467| `path` | `string` | Absolute or relative path to the plugin directory |1592| `path` | `string` | Path to the plugin directory. A relative path resolves against the [`cwd`](#options) option when the session starts. The path must be absolute when you load the plugin mid-session with [`addPlugins`](#load-more-plugin-folders-with-addplugins) |

1468| `skipMcpDiscovery` | `boolean` | When `true`, the SDK loads skills, hooks, agents, and commands from this plugin but does not read its `.mcp.json` or manifest `mcpServers`. Set this when your application owns the plugin's MCP connections. |1593| `skipMcpDiscovery` | `boolean` | When `true`, the SDK loads skills, hooks, agents, and commands from this plugin but does not read its `.mcp.json` or manifest `mcpServers`. Set this when your application owns the plugin's MCP connections. |

1469 1594 

1470**Example:**1595**Example:**


5076};5201};

5077```5202```

5078 5203 

5079`source` says where the server's definition came from, with the same values and trust rule as [`McpServerProvenance`](#mcpserverprovenance)'s `source`. The field requires Agent SDK v0.3.274 or later and is absent on earlier versions.5204Use `source` to decide how far to trust a server, and the `_meta` on each `tools` entry to find a UI resource the server attached to that tool:

5205 

5206* **`source`**: where the server's definition came from, with the same values as `source` on [`McpServerProvenance`](#mcpserverprovenance). Base trust decisions on `source` rather than on `name`, because only your own in-process server reports `sdk`, whatever name any other server is registered under. If you don't recognize a `source` value, treat that server as you treat any server whose `source` isn't `sdk`. Requires Agent SDK v0.3.274 or later

5207* **`_meta`**: the `ui` object and the `ui/resourceUri` string from the `_meta` the server declared for the tool. Claude Code withholds every other `_meta` key. `ui/resourceUri` is an older top-level spelling of `ui.resourceUri`. When the server attaches an [MCP Apps UI resource](https://code.claude.com/docs/en/mcp.md#reference-mcp-resources) to the tool, `ui.resourceUri` or `ui/resourceUri` holds the resource's `ui://` URI. Fetch that URI with [`readMcpResource()`](#query-object) and render the resource in your application. Requires Agent SDK v0.3.280 or later

5208 

5209Claude Code sends `_meta` only when the [`capabilities`](#sdksystemmessage) array of the `system` message with subtype `init` lists `mcp_tool_ui_meta_v1`. You don't turn `mcp_tool_ui_meta_v1` on yourself.

5210 

5211#### When a tool's `_meta.ui` holds only `visibility`

5212 

5213If your server declares `ui.resourceUri` for a tool but the `_meta.ui` your application receives holds only `visibility`, the `ui` object the server sent failed one of Claude Code's checks. Claude Code checks `ui` and `ui/resourceUri` separately, so one key can reach your application when the other fails. Compare the `_meta` in your server's `tools/list` response against the checks for each key:

5214 

5215* **`ui`**: reaches your application unchanged, including any members other than `resourceUri` and `visibility`, if all three checks pass:

5216 

5217 * `resourceUri` is absent, or is a string that starts with `ui://`

5218 * `visibility` is absent, or lists only `"model"` and `"app"`

5219 * The whole object is at most 4,096 characters when serialized as JSON

5220 

5221 If any of the checks fails, your application receives at most a `ui` whose only member is a `visibility` array with the `"model"` and `"app"` entries the server listed.

5222* **`ui/resourceUri`**: reaches your application if it is a string that starts with `ui://` and is at most 4,096 characters. Otherwise Claude Code drops it

5080 5223 

5081`_meta` on a `tools` entry carries the MCP Apps members of that tool's `_meta`, so your application can find the `ui://` resource to render with [`readMcpResource()`](#query-object). Claude Code passes through the `ui` object and the deprecated flat `ui/resourceUri` string, and withholds every other key. Inside `ui`, `resourceUri` is a `ui://` string and `visibility` an array of `"model"` and `"app"` when the server sets them, and any other member passes through unchanged. Claude Code drops either key when the value is malformed, and omits `_meta` from a tool that declares neither. The field is present only when the init message's [`capabilities`](#sdksystemmessage) include `mcp_tool_ui_meta_v1`, and requires TypeScript Agent SDK v0.3.280 or later.5224When Claude Code is left with no `ui` member and no `ui/resourceUri` string to send, the `tools` entry has no `_meta` at all.

5082 5225 

5083### `McpServerStatusConfig`5226### `McpServerStatusConfig`

5084 5227 


5313When you call `setMcpServers()`, Claude Code applies these rules:5456When you call `setMcpServers()`, Claude Code applies these rules:

5314 5457 

5315* **Servers the call doesn't name**: outside a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), Claude Code disconnects the servers an earlier `setMcpServers()` call added and the in-process SDK servers, and lists them in `removed`. Other servers keep running and aren't listed in `removed`, among them the stdio, HTTP, and SSE servers from the [`mcpServers`](#options) option, servers from settings files, and plugin-provided servers.5458* **Servers the call doesn't name**: outside a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), Claude Code disconnects the servers an earlier `setMcpServers()` call added and the in-process SDK servers, and lists them in `removed`. Other servers keep running and aren't listed in `removed`, among them the stdio, HTTP, and SSE servers from the [`mcpServers`](#options) option, servers from settings files, and plugin-provided servers.

5316* **Servers the call names**: Claude Code replaces a stdio, HTTP, or SSE server that an earlier `setMcpServers()` call added only when its config differs from the one you passed. An in-process SDK server already registered under that name stays as it is, so to swap one, leave it out of one call and add it in the next.5459* **Stdio, HTTP, and SSE servers that an earlier `setMcpServers()` call added**: outside a cloud session, a server you name again with an identical config keeps its connection and tools. It appears in neither `added` nor `removed`. If you pass a changed config, Claude Code reconnects the server using that config and lists it in `added`, not in `removed`.

5460* **Stdio, HTTP, and SSE servers the call names that no earlier call added**: outside a cloud session, Claude Code adds the server and lists it in `added`, or in `errors` if it refuses the server.

5461* **In-process SDK servers the call names**: a server already registered through `mcpServers` or an earlier call keeps its running instance and timeout. If you pass a [`tools` policy list](#mcpsdkserverconfigwithinstance) for it, even an empty one, you replace its policies; otherwise they stay. To run a new instance outside a cloud session, omit the server from one call and name it in the next.

5317* **Built-in servers the CLI started at startup**: if the call names one, Claude Code drops that entry and reports it in `errors`.5462* **Built-in servers the CLI started at startup**: if the call names one, Claude Code drops that entry and reports it in `errors`.

5318* **Stdio, HTTP, or SSE servers that share a name with one from an MCP installation scope such as `.mcp.json`**: under that name the session uses your server's tools rather than the [installation-scope server's](https://code.claude.com/docs/en/mcp.md#mcp-installation-scopes). Before Claude Code v2.1.305, Claude Code could disconnect your server and connect the installation-scope server when your app [reloaded plugins](#query-object).5463* **Stdio, HTTP, or SSE servers that share a name with one from an MCP installation scope such as `.mcp.json`**: under that name the session uses your server's tools rather than the [installation-scope server's](https://code.claude.com/docs/en/mcp.md#mcp-installation-scopes). Before Claude Code v2.1.305, Claude Code could disconnect your server and connect the installation-scope server when your app [reloaded plugins](#query-object).

5319 5464 


5800 5945 

5801The SDK's published typings declare `SDKConversationResetMessage` in Claude Code v2.1.203 and later. Before v2.1.203, `SDKMessage` referenced the type without declaring it, so narrowing on `type === "conversation_reset"` failed to typecheck when `skipLibCheck` was disabled.5946The SDK's published typings declare `SDKConversationResetMessage` in Claude Code v2.1.203 and later. Before v2.1.203, `SDKMessage` referenced the type without declaring it, so narrowing on `type === "conversation_reset"` failed to typecheck when `skipLibCheck` was disabled.

5802 5947 

5948### `BUILTIN_TOOL_NAMES` and `LEGACY_TOOL_NAME_ALIASES`

5949 

5950Use these two constants to check tool names that your application's users enter. Both spell each name the way you write it in permission rules, hook matchers, and the `tools` and `disallowedTools` options. Import them from `@anthropic-ai/claude-agent-sdk` or from `@anthropic-ai/claude-agent-sdk/core`. They require Agent SDK v0.3.301 or later and are alpha.

5951 

5952The SDK's type declarations give `BUILTIN_TOOL_NAMES` a readonly tuple type and `LEGACY_TOOL_NAME_ALIASES` a string-to-string record type:

5953 

5954```typescript theme={null}

5955const BUILTIN_TOOL_NAMES: readonly ["Agent", /* ...more names... */ "Write"];

5956const LEGACY_TOOL_NAME_ALIASES: Readonly<Record<string, string>>;

5957```

5958 

5959* **`BUILTIN_TOOL_NAMES`**: names of Claude Code's built-in tools in alphabetical order, such as `Agent`, `Bash`, and `Read`. MCP tool names aren't included. Because the type is a tuple of string literals, `(typeof BUILTIN_TOOL_NAMES)[number]` gives you a union type of the names

5960* **`LEGACY_TOOL_NAME_ALIASES`**: earlier tool names that permission rules, hook matchers, and the `tools` and `disallowedTools` options still accept. Each key is an earlier name and its value is the current one: for example, `Task` maps to `Agent`, and `KillShell` and `KillBash` map to `TaskStop`

5961 

5962You can confirm a name with either of two tests: `BUILTIN_TOOL_NAMES` includes it, or `Object.hasOwn(LEGACY_TOOL_NAME_ALIASES, name)` returns `true`. A name that fails both can still be valid, because `BUILTIN_TOOL_NAMES` leaves out MCP tools and some built-in tools. If you build a deny list from `BUILTIN_TOOL_NAMES`, Claude can still use the tools the constant leaves out. To deny every tool, set [`disallowedTools: ["*"]`](https://code.claude.com/docs/en/agent-sdk/permissions#allow-and-deny-rules) instead.

5963 

5964Finding a name in `BUILTIN_TOOL_NAMES` doesn't tell you the session has that tool: `TodoWrite` is listed even though it's [disabled by default](https://code.claude.com/docs/en/tools-reference.md). To see which tools a session has, read the `tools` array of its [`SDKSystemMessage`](#sdksystemmessage). That array includes MCP tools and lists the Agent tool as `Task`, so map each name through `LEGACY_TOOL_NAME_ALIASES` before comparing it with `BUILTIN_TOOL_NAMES`.

5965 

5803### `AbortError`5966### `AbortError`

5804 5967 

5805Custom error class for abort operations.5968Custom error class for abort operations.

agent-teams.md +1 −1

Details

188 188 

189### Assign and claim tasks189### Assign and claim tasks

190 190 

191The shared task list coordinates work across the team. The lead creates tasks and teammates work through them. Tasks have three states: pending, in progress, and completed. Tasks can also depend on other tasks: a pending task with unresolved dependencies cannot be claimed until those dependencies are completed.191The shared task list coordinates work across the team. The lead creates tasks and teammates work through them. Tasks have three states: pending, in progress, and completed. A task can also depend on other tasks and shows as blocked in the task list until they're completed. Teammates don't self-claim a blocked task, but you or the lead can still assign it.

192 192 

193Agents [without the Task tools](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability) coordinate through messages instead of the shared task list.193Agents [without the Task tools](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability) coordinate through messages instead of the shared task list.

194 194 

agent-view.md +18 −9

Details

206* A finished session: its result206* A finished session: its result

207* A working session: its full status sentence207* A working session: its full status sentence

208 208 

209Any pull requests linked to the session are listed next. For a session that's waiting on you, a line such as `waiting 3m` below them shows how long it has been waiting, and it's the only time shown in the panel. The age at the right edge of the row is a different number: it counts from when the session started.209Any pull requests linked to the session are listed next. One more line appears below them for a session that's waiting on you or running in safe mode:

210 

211* A line such as `waiting 3m`: how long the session has been waiting on you. The age at the right edge of the row is a different number: it counts from when the session started

212* `safe mode · customizations are off`: this session runs with [your customizations turned off](https://code.claude.com/docs/en/debug-your-config.md#test-against-a-clean-configuration) because you started it from your shell with `claude --bg --safe-mode`. You can leave it as it is. To continue the conversation with your customizations back on, run [`claude stop <id>`](#manage-sessions-from-the-shell) and then [`claude --resume`](https://code.claude.com/docs/en/sessions#resume-a-session), both in your shell

210 213 

211Most of the time the peek panel is enough and you don't need to open the full transcript.214Most of the time the peek panel is enough and you don't need to open the full transcript.

212 215 


468 471 

469#### What carries over when you background472#### What carries over when you background

470 473 

471Backgrounding starts a fresh process that resumes from the saved conversation, and in-flight background work moves to it. Running background shell commands, backgrounded subagents, dynamic workflows, scheduled tasks you created with [`/loop`](https://code.claude.com/docs/en/scheduled-tasks), and Claude's [automatic replies to artifact comments](https://code.claude.com/docs/en/artifacts.md#let-claude-reply-to-comments-on-its-own) all carry over and keep running there. A subagent moves together with everything it started, so it carries over only when all of that work can move too.474When you background the session, each kind of in-flight background work either carries over to the background session, continues only when Claude relaunches it there, or stops:

472 

473When a [dynamic workflow](https://code.claude.com/docs/en/workflows.md) still has subagents running, Claude Code asks before backgrounding with the `Background this session?` dialog, which says how many subagents would restart. Choose `Stay` to let them finish first. If you confirm, Claude Code replays the run in the background session: subagents that were still running start over from the beginning, so the tokens they used so far are spent again. See [Resume after a pause](https://code.claude.com/docs/en/workflows.md#resume-after-a-pause) for which completed subagents return their saved results and which run again.

474 475 

475Claude Code stops background work that can't carry over, such as a running [monitor](https://code.claude.com/docs/en/tools-reference.md#monitor-tool), and stops a backgrounded subagent that owns a monitor along with it. When any such work is running, Claude Code shows the `Background this session?` dialog so you can confirm before it stops the work.476* **Carries over**: running background shell commands, backgrounded subagents, scheduled tasks you created with [`/loop`](https://code.claude.com/docs/en/scheduled-tasks), and Claude's [automatic replies to artifact comments](https://code.claude.com/docs/en/artifacts.md#let-claude-reply-to-comments-on-its-own) keep running in the background session. A subagent moves together with everything it started, so it carries over only when all of that work can move too.

477* **Continues only when Claude relaunches it**: a running [dynamic workflow](https://code.claude.com/docs/en/workflows.md). If the workflow hasn't continued when you check on the background session, [ask Claude to relaunch it](#dynamic-workflows-when-you-background).

478* **Stops**: work that can't move to the background session, such as a running [monitor](https://code.claude.com/docs/en/tools-reference.md#monitor-tool). When any such work is running, Claude Code shows the `Background this session?` dialog so you can confirm before it stops the work. A backgrounded subagent that owns a monitor stops along with the monitor.

476 479 

477Once in the background, the session can start new subagents, monitors, and background commands, and those keep running across later detach and reattach.480Once in the background, the session can start new subagents, monitors, and background commands, and those keep running across later detach and reattach.

478 481 


488 491 

489Directories you added during the session with [`/add-dir`](https://code.claude.com/docs/en/permissions#additional-directories-grant-file-access-not-configuration) also carry through. Carrying `--allow-dangerously-skip-permissions` keeps `bypassPermissions` reachable in the backgrounded session, but it doesn't grant anything new: the mode still needs your [acceptance of the bypass disclaimer](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) on record.492Directories you added during the session with [`/add-dir`](https://code.claude.com/docs/en/permissions#additional-directories-grant-file-access-not-configuration) also carry through. Carrying `--allow-dangerously-skip-permissions` keeps `bypassPermissions` reachable in the backgrounded session, but it doesn't grant anything new: the mode still needs your [acceptance of the bypass disclaimer](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) on record.

490 493 

494##### Dynamic workflows when you background

495 

496If a [dynamic workflow](https://code.claude.com/docs/en/workflows.md) hasn't continued after you backgrounded its session, ask Claude to [relaunch the workflow](https://code.claude.com/docs/en/workflows.md#resume-after-you-leave-the-session). The run continues only when Claude relaunches it in the background session, and Claude Code can ask you to approve that relaunch first. The session's conversation shows a notice that the workflow `could not be resumed`.

497 

498When Claude relaunches the workflow, any of its subagents that were still running when you backgrounded the session start over and spend their tokens again. If you press `←` or run `/background` while any are still running, the `Background this session?` dialog says how many. To let them finish first, choose `Stay`.

499 

491### Dispatch an agent from your shell500### Dispatch an agent from your shell

492 501 

493Pass `--bg` or its long form `--background` to start a session that goes straight to the background:502Pass `--bg` or its long form `--background` to start a session that goes straight to the background:


844* **After an auto-update**: the supervisor restarts itself onto the new version and moves idle sessions over in the background. Sessions that are working, waiting on you, or attached aren't interrupted.853* **After an auto-update**: the supervisor restarts itself onto the new version and moves idle sessions over in the background. Sessions that are working, waiting on you, or attached aren't interrupted.

845* **The supervisor itself stops**, for example because its process was ended from outside Claude Code: on macOS and Linux, your sessions stop unless a new supervisor connects within about a minute. To start one, run `claude agents` in your shell. After that minute, see [Keep sessions running after the supervisor stops](#keep-sessions-running-after-the-supervisor-stops).854* **The supervisor itself stops**, for example because its process was ended from outside Claude Code: on macOS and Linux, your sessions stop unless a new supervisor connects within about a minute. To start one, run `claude agents` in your shell. After that minute, see [Keep sessions running after the supervisor stops](#keep-sessions-running-after-the-supervisor-stops).

846 855 

847When a session's process stops or restarts, the background shell commands, dynamic workflows, and background subagents Claude started in it carry over to its next process; running monitors and shell commands a subagent started stop with the process. Deleting the session stops everything it carried over. To stop all of it with the process instead, set [`CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF`](https://code.claude.com/docs/en/env-vars#variables) to `1`.856When a session's process stops or restarts, the background shell commands and background subagents Claude started in it carry over to its next process. A dynamic workflow [continues only when Claude relaunches it](#dynamic-workflows-when-you-background). Running monitors and shell commands a subagent started stop with the process. If you delete the session, everything it carried over stops. To stop all of it with the process instead, set [`CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF`](https://code.claude.com/docs/en/env-vars#variables) to `1`.

848 857 

849The supervisor and its sessions authenticate with the same stored credentials as your interactive sessions. For which settings and shell variables reach a session, including `PATH`, see [Settings and provider](#settings-and-provider). For gateway endpoints, see [LLM gateway](#llm-gateway).858The supervisor and its sessions authenticate with the same stored credentials as your interactive sessions. For which settings and shell variables reach a session, including `PATH`, see [Settings and provider](#settings-and-provider). For gateway endpoints, see [LLM gateway](#llm-gateway).

850 859 


897 906 

898### Backgrounding shows a `Background this session?` dialog907### Backgrounding shows a `Background this session?` dialog

899 908 

900If you press `←` to background the current session and Claude Code shows a `Background this session?` dialog, the session has in-flight background work that backgrounding would stop, restart, or leave running unattended, and Claude Code asks before it does any of those:909When you press `←` to background a session, a `Background this session?` dialog means the session has in-flight background work that would stop, be interrupted, or keep running unattended:

901 910 

902* **Work that can't move**: the session has work that can't move to the background session, such as a running [monitor](https://code.claude.com/docs/en/tools-reference.md#monitor-tool). The dialog names the background work Claude Code would stop and, separately, counts the tasks that carry over.911* **Work that can't move**: the session has work that can't move to the background session, such as a running [monitor](https://code.claude.com/docs/en/tools-reference.md#monitor-tool). The dialog names the background work Claude Code would stop and, separately, counts the tasks that carry over.

903* **A workflow with running subagents**: a [dynamic workflow](https://code.claude.com/docs/en/workflows.md) still has subagents running. The workflow itself carries over, but its running subagents restart from the beginning, and the dialog says how many.912* **A workflow with running subagents**: a [dynamic workflow](https://code.claude.com/docs/en/workflows.md) still has subagents running. Those subagents stop if you background anyway, and the dialog says how many. They start over from the beginning when Claude [relaunches the workflow in the background session](#dynamic-workflows-when-you-background).

904* **Automatic artifact replies**: Claude is [replying to comments on an artifact on its own](https://code.claude.com/docs/en/artifacts.md#let-claude-reply-to-comments-on-its-own). Those replies continue in the background session, and the dialog says so.913* **Automatic artifact replies**: Claude is [replying to comments on an artifact on its own](https://code.claude.com/docs/en/artifacts.md#let-claude-reply-to-comments-on-its-own). Those replies continue in the background session, and the dialog says so.

905 914 

906Run `/tasks` to see everything that's running, then confirm to background anyway or choose `Stay` to let the work finish first. See [What carries over when you background](#what-carries-over-when-you-background) for which kinds of work carry over and which Claude Code stops.915Run `/tasks` to see everything that's running, then confirm to background anyway or choose `Stay` to let the work finish first. See [What carries over when you background](#what-carries-over-when-you-background) for which kinds of work carry over and which Claude Code stops.


1118| v2.1.200 | An older Claude Code version that rewrites the session list in `roster.json` preserves fields written by a newer version, matching the existing `state.json` guarantee, so sessions started by the newer version keep accepting input after the supervisor restarts. When you open a session that has stopped responding, the supervisor restarts its process and the session continues the interrupted response from where it left off. Agent view applies a `--plugin-dir` flag placed after `agents` to its own subagent and skill autocomplete in the dispatch input as well as dispatched sessions. |1127| v2.1.200 | An older Claude Code version that rewrites the session list in `roster.json` preserves fields written by a newer version, matching the existing `state.json` guarantee, so sessions started by the newer version keep accepting input after the supervisor restarts. When you open a session that has stopped responding, the supervisor restarts its process and the session continues the interrupted response from where it left off. Agent view applies a `--plugin-dir` flag placed after `agents` to its own subagent and skill autocomplete in the dispatch input as well as dispatched sessions. |

1119| v2.1.199 | A background session whose process exits before it finishes starting on a low-memory host shows `possibly low memory — free some up and retry` in its row status instead of only the bare exit reason. Backgrounding a session with `←` or `/background` carries its `/color` over to the new row. |1128| v2.1.199 | A background session whose process exits before it finishes starting on a low-memory host shows `possibly low memory — free some up and retry` in its row status instead of only the bare exit reason. Backgrounding a session with `←` or `/background` carries its `/color` over to the new row. |

1120| v2.1.198 | Agent view sends a notification through `preferredNotifChannel` when a background session needs input, finishes, or fails, and fires the `Notification` hook with the `agent_needs_input` or `agent_completed` type. `←` and `/exit` inside `claude attach <id>` return to agent view instead of exiting to the shell; `Ctrl+Z` returns to the shell. A background session that isolated its work in a worktree commits, pushes its own isolated branch, never `main` or `master`, and opens a draft pull request when it finishes instead of asking first. `/login` runs in agent view and opens the sign-in dialog. The `Background work is running` exit dialog offers `Move to background and exit`. The exit handoff also covers background subagents, which resume from their transcript on the next wake instead of being reported as failed. `claude --bg` combined with `-p` or `--print` is rejected with an error. The background session host requests macOS Local Network permission on first LAN access instead of failing with `connect: no route to host`. |1129| v2.1.198 | Agent view sends a notification through `preferredNotifChannel` when a background session needs input, finishes, or fails, and fires the `Notification` hook with the `agent_needs_input` or `agent_completed` type. `←` and `/exit` inside `claude attach <id>` return to agent view instead of exiting to the shell; `Ctrl+Z` returns to the shell. A background session that isolated its work in a worktree commits, pushes its own isolated branch, never `main` or `master`, and opens a draft pull request when it finishes instead of asking first. `/login` runs in agent view and opens the sign-in dialog. The `Background work is running` exit dialog offers `Move to background and exit`. The exit handoff also covers background subagents, which resume from their transcript on the next wake instead of being reported as failed. `claude --bg` combined with `-p` or `--print` is rejected with an error. The background session host requests macOS Local Network permission on first LAN access instead of failing with `connect: no route to host`. |

1121| v2.1.196 | A single `←` press backgrounds a foreground session; earlier versions required two presses, with a footer hint and a confirm. `--dangerously-skip-permissions` passed to `claude agents` shows the bypass disclaimer instead of being silently dropped. Interactive sessions you never named carry a default name such as `my-app-3f` in session listings and `claude agents --json`. Background shell commands and dynamic workflows survive the session's process being stopped, restarted, or updated, including on Windows; set `CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF=1` to turn the handoff off. A transcript misread as empty on restart is renamed with an `.orphaned-` suffix instead of deleted. |1130| v2.1.196 | A single `←` press backgrounds a foreground session; earlier versions required two presses, with a footer hint and a confirm. `--dangerously-skip-permissions` passed to `claude agents` shows the bypass disclaimer instead of being silently dropped. Interactive sessions you never named carry a default name such as `my-app-3f` in session listings and `claude agents --json`. Background shell commands survive the session's process being stopped, restarted, or updated, including on Windows; set `CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF=1` to turn the handoff off. A transcript misread as empty on restart is renamed with an `.orphaned-` suffix instead of deleted. |

1122| v2.1.195 | In-flight background work carries over when you background a session on Windows too. The `Completed` group fills the remaining vertical space and the header compacts on short terminals. An older Claude Code version no longer drops newer sessions' `state.json` fields or hides those sessions from `claude agents`. Attaching to a stopped session switches immediately instead of showing a blank screen for up to five seconds. A supervisor that can't accept connections exits and releases its lock on its own. |1131| v2.1.195 | In-flight background work carries over when you background a session on Windows too. The `Completed` group fills the remaining vertical space and the header compacts on short terminals. An older Claude Code version no longer drops newer sessions' `state.json` fields or hides those sessions from `claude agents`. Attaching to a stopped session switches immediately instead of showing a blank screen for up to five seconds. A supervisor that can't accept connections exits and releases its lock on its own. |

1123| v2.1.191 | `claude --bg` with an `--agent` name that doesn't match any of your subagents fails the launch: the session exits immediately with an `--agent '<name>' not found` error instead of running with the default agent. |1132| v2.1.191 | `claude --bg` with an `--agent` name that doesn't match any of your subagents fails the launch: the session exits immediately with an `--agent '<name>' not found` error instead of running with the default agent. |

1124| v2.1.174 | Background sessions no longer inherit gateway endpoint variables such as `ANTHROPIC_BASE_URL` from the supervisor's launch shell; the supervisor supplies a fresh credential snapshot to pre-warmed workers, fixing spurious `Could not resolve authentication method` errors. |1133| v2.1.174 | Background sessions no longer inherit gateway endpoint variables such as `ANTHROPIC_BASE_URL` from the supervisor's launch shell; the supervisor supplies a fresh credential snapshot to pre-warmed workers, fixing spurious `Could not resolve authentication method` errors. |

Details

927 927 

928When you switch, delete any `serve_to_desktop` line in the same edit that renames the blocks. Where an instruction names the `cli` block, use your `code` block.928When you switch, delete any `serve_to_desktop` line in the same edit that renames the blocks. Where an instruction names the `cli` block, use your `code` block.

929 929 

930`serve_to_desktop: true` is a legacy way to offer a policy's `cli` settings to the Code tab. It has no effect when Claude Desktop connects through [`bootstrapUrl`](#claude-desktop-overlay). While your policies use `cli`, a boot warning that names this key means those settings aren't reaching the Code tab:

931 

932* **To cover the Code tab**: switch to `code`, once users' machines meet the conditions in [Apply `code` settings in the Code tab](#apply-code-settings-in-the-code-tab)

933* **To stay on `cli`**: set `serve_to_desktop: false` beside `cli` in a policy to silence the warning

934 

930#### What goes in `cli`935#### What goes in `cli`

931 936 

932Each `code` or `cli` value is a complete Claude Code `managed-settings.json` document, the same schema you would deploy via MDM or `/etc/claude-code/managed-settings.json`, expressed here as YAML. The CLI applies the delivered document at the managed tier, above user and project settings, in place of server-managed settings. It therefore ignores the settings [restricted to OS-level policy sources](https://code.claude.com/docs/en/server-managed-settings.md#current-limitations), such as `policyHelper` and `wslInheritsWindowsSettings`.937Each `code` or `cli` value is a complete Claude Code `managed-settings.json` document, the same schema you would deploy via MDM or `/etc/claude-code/managed-settings.json`, expressed here as YAML. The CLI applies the delivered document at the managed tier, above user and project settings, in place of server-managed settings. It therefore ignores the settings [restricted to OS-level policy sources](https://code.claude.com/docs/en/server-managed-settings.md#current-limitations), such as `policyHelper` and `wslInheritsWindowsSettings`.


974| - | - | - |979| - | - | - |

975| `availableModels` | Gateway + CLI | Model allowlist. Also checked at `/v1/messages`, so a patched client can't bypass it. |980| `availableModels` | Gateway + CLI | Model allowlist. Also checked at `/v1/messages`, so a patched client can't bypass it. |

976| [`deniedModels`](https://code.claude.com/docs/en/settings-reference#deniedmodels), [`availableModelsMatch`](https://code.claude.com/docs/en/settings-reference#availablemodelsmatch) | Gateway + CLI | [Block specific models or versions](https://code.claude.com/docs/en/model-config.md#block-specific-models-or-versions) that `availableModels` would otherwise permit. A blocked model is rejected with a `400` at `/v1/messages` and is left out of `/v1/models`. The gateway's own check requires Claude Code v2.1.299 or later on the gateway server. The CLI's check requires v2.1.283 or later on clients, and earlier clients ignore both keys. |981| [`deniedModels`](https://code.claude.com/docs/en/settings-reference#deniedmodels), [`availableModelsMatch`](https://code.claude.com/docs/en/settings-reference#availablemodelsmatch) | Gateway + CLI | [Block specific models or versions](https://code.claude.com/docs/en/model-config.md#block-specific-models-or-versions) that `availableModels` would otherwise permit. A blocked model is rejected with a `400` at `/v1/messages` and is left out of `/v1/models`. The gateway's own check requires Claude Code v2.1.299 or later on the gateway server. The CLI's check requires v2.1.283 or later on clients, and earlier clients ignore both keys. |

977| `permissions.allow` / `.deny` | CLI | Tool and command rules. See [Permissions](https://code.claude.com/docs/en/permissions.md). |982| `permissions.allow` / `.deny` | CLI | Tool and command rules. See [Permissions](https://code.claude.com/docs/en/permissions.md) and [what a Bash rule doesn't match](https://code.claude.com/docs/en/permissions.md#bash-rule-limits). |

978| `permissions.disableBypassPermissionsMode` | CLI | Set to `disable` to block [`bypassPermissions`](https://code.claude.com/docs/en/permission-modes#skip-all-checks-with-bypasspermissions-mode), the mode that skips permission prompts, and the `--dangerously-skip-permissions` flag |983| `permissions.disableBypassPermissionsMode` | CLI | Set to `disable` to block [`bypassPermissions`](https://code.claude.com/docs/en/permission-modes#skip-all-checks-with-bypasspermissions-mode), the mode that skips permission prompts, and the `--dangerously-skip-permissions` flag |

979| `allowManagedPermissionRulesOnly` | CLI | When `true`, managed settings become the only settings source of permission rules. The [`allowManagedPermissionRulesOnly`](https://code.claude.com/docs/en/settings-reference#allowmanagedpermissionrulesonly) entry lists every source Claude Code then ignores. |984| `allowManagedPermissionRulesOnly` | CLI | When `true`, managed settings become the only settings source of permission rules. The [`allowManagedPermissionRulesOnly`](https://code.claude.com/docs/en/settings-reference#allowmanagedpermissionrulesonly) entry lists every source Claude Code then ignores. |

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


1003 1008 

1004The `cli` key was named `settings` in earlier releases, and the gateway still accepts that spelling as an alias. For new deployments, use [`code`](#choose-cli-or-code).1009The `cli` key was named `settings` in earlier releases, and the gateway still accepts that spelling as an alias. For new deployments, use [`code`](#choose-cli-or-code).

1005 1010 

1011#### Test a policy before deployment

1012 

1013To test a policy change, start the gateway against a throwaway Postgres database. The gateway connects to Postgres and applies its schema migrations before it checks the contents of `cli`, `code`, and `desktop` blocks. When it can't reach the database, the start stops at `could not connect to Postgres` and reports nothing about their contents.

1014 

1006#### Context window in terminal sessions1015#### Context window in terminal sessions

1007 1016 

1008Terminal sessions signed in through `/login` use the 1M context window for Opus 4.7 and later, Sonnet 5 and later, and the Fable models. The model ID needs no `[1m]` suffix, and sessions compact at about 967K tokens. Before Claude Code v2.1.287 on the developer's machine, Claude Code treated the Opus and Fable models as having a 200K window unless the model ID ended in `[1m]`.1017Terminal sessions signed in through `/login` use the 1M context window for Opus 4.7 and later, Sonnet 5 and later, and the Fable models. The model ID needs no `[1m]` suffix, and sessions compact at about 967K tokens. Before Claude Code v2.1.287 on the developer's machine, Claude Code treated the Opus and Fable models as having a 200K window unless the model ID ended in `[1m]`.


1589 # The contractors policy inherits this key.1598 # The contractors policy inherits this key.

1590 enforceAvailableModels: true1599 enforceAvailableModels: true

1591 permissions:1600 permissions:

1592 allow: [Read, Grep, Bash, Edit]1601 allow: [Read, Grep, Edit]

1593 deny: ["WebFetch"]1602 deny: ["WebFetch"]

1594 env: { HTTP_PROXY: http://proxy.example.com:8080 }1603 env: { HTTP_PROXY: http://proxy.example.com:8080 }

1595 1604 

Details

393| A developer's `/login` shows the standard account picker instead of the **Cloud gateway** screen | `forceLoginMethod` or `forceLoginGatewayUrl` isn't set in managed settings on that machine | Deploy the [managed settings file](https://code.claude.com/docs/en/claude-apps-gateway#set-the-gateway-url) to the device; `/login` reads the gateway URL from there |393| A developer's `/login` shows the standard account picker instead of the **Cloud gateway** screen | `forceLoginMethod` or `forceLoginGatewayUrl` isn't set in managed settings on that machine | Deploy the [managed settings file](https://code.claude.com/docs/en/claude-apps-gateway#set-the-gateway-url) to the device; `/login` reads the gateway URL from there |

394| A developer's requests fail with `Not signed in to the Cloud gateway — run /login.` | The machine's managed settings set `forceLoginMethod: "gateway"` or `forceLoginGatewayUrl`, and the session has no gateway sign-in. A leftover claude.ai login doesn't satisfy the requirement. | Have the developer run `/login` and complete the gateway sign-in. See also [Administrator policy requires a Cloud gateway sign-in](https://code.claude.com/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in). |394| A developer's requests fail with `Not signed in to the Cloud gateway — run /login.` | The machine's managed settings set `forceLoginMethod: "gateway"` or `forceLoginGatewayUrl`, and the session has no gateway sign-in. A leftover claude.ai login doesn't satisfy the requirement. | Have the developer run `/login` and complete the gateway sign-in. See also [Administrator policy requires a Cloud gateway sign-in](https://code.claude.com/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in). |

395| Claude Desktop reports that its bootstrap configuration couldn't be fetched | `/user/bootstrap` returned 404: the policy matching the user doesn't carry a `desktop` key, or no policy matched. The gateway's audit log records each rejection as `desktop_bootstrap.denied` with the reason. | Add a `desktop` block to the policy that matches the user, or to the `match: {}` base layer; an empty `desktop: {}` suffices. See [Claude Desktop overlay](https://code.claude.com/docs/en/claude-apps-gateway-config.md#claude-desktop-overlay). |395| Claude Desktop reports that its bootstrap configuration couldn't be fetched | `/user/bootstrap` returned 404: the policy matching the user doesn't carry a `desktop` key, or no policy matched. The gateway's audit log records each rejection as `desktop_bootstrap.denied` with the reason. | Add a `desktop` block to the policy that matches the user, or to the `match: {}` base layer; an empty `desktop: {}` suffices. See [Claude Desktop overlay](https://code.claude.com/docs/en/claude-apps-gateway-config.md#claude-desktop-overlay). |

396| Audit log shows `auth.denied` with `reason: invalid_token` on `/v1/logs` or `/v1/metrics` | You set [`otelHeadersHelper`](https://code.claude.com/docs/en/settings-reference#otelheadershelper) in a machine's managed settings. In a Claude Desktop session on that machine, Claude Code sends the `Authorization` header from the helper to the gateway's telemetry relay in place of the session token. Where Claude Desktop bundles Claude Code before v2.1.307, you get the same denial if you set an `Authorization` header in `OTEL_EXPORTER_OTLP_HEADERS` or a per-signal form in those settings. | Remove the helper from those settings. Where Claude Desktop bundles Claude Code before v2.1.307, remove the variable. |

396| Startup shows `Gateway login is configured in managed settings, but this Claude Code build does not include Cloud gateway support.` | The installed Claude Code build predates gateway support | Have the developer update Claude Code to a release that includes Cloud gateway support |397| Startup shows `Gateway login is configured in managed settings, but this Claude Code build does not include Cloud gateway support.` | The installed Claude Code build predates gateway support | Have the developer update Claude Code to a release that includes Cloud gateway support |

397| Startup exits with `Administrator policy requires a Cloud gateway sign-in on this machine` | The developer's environment sets `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`, their settings configure an [`apiKeyHelper`](https://code.claude.com/docs/en/settings-reference#apikeyhelper), or an API key from an earlier Claude Console login is still saved | Have the developer clear each that applies: unset the variable, remove the `apiKeyHelper` entry, or run `claude auth logout` to remove the saved key. A session that selects a cloud provider with `CLAUDE_CODE_USE_*` then starts with no sign-in; for every other session, have them start `claude` and sign in with `/login`. See also [Administrator policy requires a Cloud gateway sign-in](https://code.claude.com/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in). |398| Startup exits with `Administrator policy requires a Cloud gateway sign-in on this machine` | The developer's environment sets `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`, their settings configure an [`apiKeyHelper`](https://code.claude.com/docs/en/settings-reference#apikeyhelper), or an API key from an earlier Claude Console login is still saved | Have the developer clear each that applies: unset the variable, remove the `apiKeyHelper` entry, or run `claude auth logout` to remove the saved key. A session that selects a cloud provider with `CLAUDE_CODE_USE_*` then starts with no sign-in; for every other session, have them start `claude` and sign in with `/login`. See also [Administrator policy requires a Cloud gateway sign-in](https://code.claude.com/docs/en/errors.md#administrator-policy-requires-a-cloud-gateway-sign-in). |

398| Startup or `/login` reports `Claude Code may not be enabled for your organization` after a 403 on the managed settings load | The gateway, or something in front of it, answered the `/managed/settings` request with 403. The gateway's own settings route never answers 403. The status comes from the [`access_control`](https://code.claude.com/docs/en/claude-apps-gateway-config#http-tuning) IP checks or from a proxy or WAF in front of the gateway. The audit log records an IP-check denial as `access.denied` with the reason. The developer stays signed in. | Check the audit log for `access.denied` at the time of the failure and fix the `access_control` lists or the front end, then have the developer start `claude` again |399| Startup or `/login` reports `Claude Code may not be enabled for your organization` after a 403 on the managed settings load | The gateway, or something in front of it, answered the `/managed/settings` request with 403. The gateway's own settings route never answers 403. The status comes from the [`access_control`](https://code.claude.com/docs/en/claude-apps-gateway-config#http-tuning) IP checks or from a proxy or WAF in front of the gateway. The audit log records an IP-check denial as `access.denied` with the reason. The developer stays signed in. | Check the audit log for `access.denied` at the time of the failure and fix the `access_control` lists or the front end, then have the developer start `claude` again |

Details

288 288 

289[Agent teams](https://code.claude.com/docs/en/agent-teams.md) are off by default but can be enabled by adding `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` to your [environment variables](https://code.claude.com/docs/en/cloud-environments.md#set-environment-variables).289[Agent teams](https://code.claude.com/docs/en/agent-teams.md) are off by default but can be enabled by adding `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` to your [environment variables](https://code.claude.com/docs/en/cloud-environments.md#set-environment-variables).

290 290 

291### Plugin suggestions in the conversation

292 

293A card in the conversation that lists one or more [plugins](https://code.claude.com/docs/en/plugins/overview.md), with an **Add** button, means Claude is suggesting plugins for your task. Claude can make these suggestions without you asking. You don't have to respond, and Claude carries on with the task either way.

294 

295#### Add or remove a suggested plugin

296 

297Select **Add** on a plugin to turn it on for your claude.ai account, where it stays on after the session ends. To undo, open the added plugin from the card, select **Manage** to reach the plugin's page on claude.ai, and remove the plugin from that page.

298 

299#### Turn off plugin suggestions

300 

301To stop Claude from suggesting plugins, deny the `SearchPlugins` and `SuggestPluginInstall` tools with [permission rules](https://code.claude.com/docs/en/permissions.md#manage-permissions). In a session with one repository outside a [project](https://code.claude.com/docs/en/claude-projects.md), commit the rules to that repository's `.claude/settings.json`, listing both tool names under `permissions.deny`:

302 

303```json theme={null}

304{

305 "permissions": {

306 "deny": ["SearchPlugins", "SuggestPluginInstall"]

307 }

308}

309```

310 

311Claude Code ignores permission rules in the repository's `.claude/settings.json`, including these deny rules, when the [managed settings](https://code.claude.com/docs/en/managed-settings.md) that apply to the session set [`allowManagedPermissionRulesOnly`](https://code.claude.com/docs/en/settings-reference#allowmanagedpermissionrulesonly). In that case, put the rules in those managed settings instead. For other setups, such as a session with several repositories or a cloud thread in a project, see which [settings reach a cloud session](https://code.claude.com/docs/en/settings.md#settings-in-cloud-sessions).

312 

291### Take back a queued message313### Take back a queued message

292 314 

293If you send a message while Claude is working, the message queues until Claude reads it. To take a queued message back, click the ✕ on it. The text returns to the message box so you can edit it or send something else.315If you send a message while Claude is working, the message queues until Claude reads it. To take a queued message back, click the ✕ on it. The text returns to the message box so you can edit it or send something else.

Details

103 103 

104Beyond the config you author, `~/.claude` holds data Claude Code writes during sessions. These files are plaintext. Anything that passes through a tool is written to a transcript on disk: file contents, command output, pasted text.104Beyond the config you author, `~/.claude` holds data Claude Code writes during sessions. These files are plaintext. Anything that passes through a tool is written to a transcript on disk: file contents, command output, pasted text.

105 105 

106The transcript can also hold what Claude Code sends the model with your messages:

107 

108* The system prompt

109* Tool definitions

110* Request parameters

111* The instruction files it loaded, such as CLAUDE.md

112 

106### Cleaned up automatically113### Cleaned up automatically

107 114 

108Claude Code deletes the files in the paths below once they're older than [`cleanupPeriodDays`](https://code.claude.com/docs/en/settings-reference#cleanupperioddays), as long as it can safely determine the retention period. The default is 30 days and the minimum is 1; setting `0` fails with a validation error. The same age cutoff applies to automatic removal of [orphaned worktrees](https://code.claude.com/docs/en/worktrees.md#clean-up-subagent-and-background-session-worktrees).115Claude Code deletes the files in the paths below once they're older than [`cleanupPeriodDays`](https://code.claude.com/docs/en/settings-reference#cleanupperioddays), as long as it can safely determine the retention period. The default is 30 days and the minimum is 1; setting `0` fails with a validation error. The same age cutoff applies to automatic removal of [orphaned worktrees](https://code.claude.com/docs/en/worktrees.md#clean-up-subagent-and-background-session-worktrees).

109 116 

110| Path under `~/.claude/` | Contents |117| Path under `~/.claude/` | Contents |

111| - | - |118| - | - |

112| `projects/<project>/<session>.jsonl` | Full conversation transcript: every message, tool call, and tool result |119| `projects/<project>/<session>.jsonl` | Conversation transcript: messages, tool calls, and tool results, plus the system prompt, tool definitions, and parameters of the requests Claude Code sent the model |

113| `projects/<project>/<session>.orphaned-<timestamp>-<suffix>.jsonl`, `projects/<project>/<session>.jsonl.superseded-<timestamp>` | A previous transcript for the session that Claude Code set aside instead of overwriting or deleting it. It doesn't appear in the session picker |120| `projects/<project>/<session>.orphaned-<timestamp>-<suffix>.jsonl`, `projects/<project>/<session>.jsonl.superseded-<timestamp>` | A previous transcript for the session that Claude Code set aside instead of overwriting or deleting it. It doesn't appear in the session picker |

114| `projects/<project>/<session>/subagents/` | [Subagent](https://code.claude.com/docs/en/sub-agents.md) conversation transcripts, removed with the parent session transcript when it ages out |121| `projects/<project>/<session>/subagents/` | [Subagent](https://code.claude.com/docs/en/sub-agents.md) transcripts in the same format as the session transcript, removed with the parent session transcript when it ages out |

115| `projects/<project>/<session>/tool-results/` | Large tool outputs spilled to separate files, and full-size copies of [images that MCP tools return](https://code.claude.com/docs/en/mcp.md#images-in-tool-results) |122| `projects/<project>/<session>/tool-results/` | Large tool outputs spilled to separate files, and full-size copies of [images that MCP tools return](https://code.claude.com/docs/en/mcp.md#images-in-tool-results) |

116| `projects/<project>/<session>/mcp-tasks/` | What a resumed session needs to follow its running [MCP tasks](https://code.claude.com/docs/en/mcp.md#mcp-tasks-that-run-on-the-server) again, and the results of finished tasks that Claude hasn't read yet |123| `projects/<project>/<session>/mcp-tasks/` | What a resumed session needs to follow its running [MCP tasks](https://code.claude.com/docs/en/mcp.md#mcp-tasks-that-run-on-the-server) again, and the results of finished tasks that Claude hasn't read yet |

117| `file-history/<session>/` | Pre-edit snapshots of files Claude changed, used for [checkpoint restore](https://code.claude.com/docs/en/checkpointing.md). Holds snapshots for the 100 most recent checkpoints; snapshot files that no retained checkpoint references are deleted, except each file's first snapshot |124| `file-history/<session>/` | Pre-edit snapshots of files Claude changed, used for [checkpoint restore](https://code.claude.com/docs/en/checkpointing.md). Holds snapshots for the 100 most recent checkpoints; snapshot files that no retained checkpoint references are deleted, except each file's first snapshot |

Details

6 6 

7> Install the Claude Security plugin to scan your codebase for vulnerabilities in a Claude Code session and turn findings into patches you review and apply.7> Install the Claude Security plugin to scan your codebase for vulnerabilities in a Claude Code session and turn findings into patches you review and apply.

8 8 

9The Claude Security plugin runs a multi-agent vulnerability scan of your codebase inside a Claude Code session. A team of Claude agents maps your architecture, builds a threat model, hunts for vulnerabilities, and independently reviews every finding before writing the report. Use the plugin to scan a whole repository or [only a set of changes](#scan-only-your-changes), such as a branch's diff, a pull request's diff, or a single commit, then turn the findings you choose into patches that you review and apply yourself.9The Claude Security plugin runs a multi-agent vulnerability scan of your codebase inside a Claude Code session. [By default](#choose-a-scan-effort), when you scan a whole repository, Claude agents map your architecture, build a threat model, hunt for vulnerabilities, and independently review every finding before writing the report.

10 

11Use the plugin to scan a whole repository or [only a set of changes](#scan-only-your-changes), such as a branch's diff, a pull request's diff, or a single commit, then turn the findings you choose into patches that you review and apply yourself.

10 12 

11The plugin runs locally in your session, uses [whichever models you have access to in Claude Code](#models-and-providers), and each scan counts toward your [usage](https://code.claude.com/docs/en/costs.md). If you want a managed service that monitors your repositories, or want to run scans on [Claude Mythos](https://platform.claude.com/docs/en/about-claude/models/introducing-claude-fable-5-and-claude-mythos-5), see the [Claude Security](https://claude.com/product/claude-security) product, available on the Enterprise plan.13The plugin runs locally in your session, uses [whichever models you have access to in Claude Code](#models-and-providers), and each scan counts toward your [usage](https://code.claude.com/docs/en/costs.md). If you want a managed service that monitors your repositories, or want to run scans on [Claude Mythos](https://platform.claude.com/docs/en/about-claude/models/introducing-claude-fable-5-and-claude-mythos-5), see the [Claude Security](https://claude.com/product/claude-security) product, available on the Enterprise plan.

12 14 


51 53 

52Once the plugin is active, you're ready to [scan and fix your codebase](#scan-and-fix-your-codebase).54Once the plugin is active, you're ready to [scan and fix your codebase](#scan-and-fix-your-codebase).

53 55 

56### Update the plugin

57 

58To update the plugin yourself, see [Update plugins now](https://code.claude.com/docs/en/plugins/install.md#update-plugins-now). Claude Code also [updates the plugin automatically](https://code.claude.com/docs/en/plugins/install.md#keep-plugins-updated) unless auto-update is turned off.

59 

54### Uninstall the plugin60### Uninstall the plugin

55 61 

56To remove the plugin, uninstall it from the `/plugin` menu, or run `claude plugin uninstall claude-security` in your terminal.62To remove the plugin, uninstall it from the `/plugin` menu, or run `claude plugin uninstall claude-security` in your terminal.


95 101 

96On a large repository, scan one area at a time instead of the whole tree. Pick one of the focused scopes the plugin offers, such as your API layer or your authentication code, and the run sizes itself to what you pick. The report's coverage section states what was and wasn't examined. Run another scan on a different area anytime.102On a large repository, scan one area at a time instead of the whole tree. Pick one of the focused scopes the plugin offers, such as your API layer or your authentication code, and the run sizes itself to what you pick. The report's coverage section states what was and wasn't examined. Run another scan on a different area anytime.

97 103 

104### Choose a scan effort

105 

106Scan effort sets how deep a scan goes. Your findings go through the same independent verification at `low`, `medium`, and `high`.

107 

108* **`low`**: a quick first look. It skips the architecture map and the threat model when you scan your codebase.

109* **`medium`**: the default.

110* **`high`**: what `medium` does, plus more hunting for vulnerabilities in the same code.

111 

112Name the scan effort in your request at the Claude Code prompt, such as `/claude-security scan my public API code at high` or `/claude-security scan my branch at high`.

113 

114If a scan of a large repository finds less than you expect, choose `high` scan effort, scan a second time, or do both. Each can report findings that one `medium` scan doesn't.

115 

98### Read the scan results116### Read the scan results

99 117 

100Every scan writes its results into a timestamped `CLAUDE-SECURITY-<timestamp>/` directory in your repository:118Every scan writes its results into a timestamped `CLAUDE-SECURITY-<timestamp>/` directory in your repository:


102* **`CLAUDE-SECURITY-RESULTS.md`**: the report, with each finding's ID, such as `F1`, plus its impact, exploit scenario, severity, confidence, and recommendation120* **`CLAUDE-SECURITY-RESULTS.md`**: the report, with each finding's ID, such as `F1`, plus its impact, exploit scenario, severity, confidence, and recommendation

103* **`CLAUDE-SECURITY-RESULTS.jsonl`**: the same findings in machine-readable form, one JSON object per line121* **`CLAUDE-SECURITY-RESULTS.jsonl`**: the same findings in machine-readable form, one JSON object per line

104* **`CLAUDE-SECURITY-RESULTS.sarif`**: the same findings as a [SARIF 2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html) log for GitHub code scanning and any other tool that reads the standard. The scan classifies findings under their [CWE](https://cwe.mitre.org/) weakness categories122* **`CLAUDE-SECURITY-RESULTS.sarif`**: the same findings as a [SARIF 2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html) log for GitHub code scanning and any other tool that reads the standard. The scan classifies findings under their [CWE](https://cwe.mitre.org/) weakness categories

105* **`CLAUDE-SECURITY-REVISION-<commit>.json`**: the revision stamp, recording which commit was scanned, at what effort, whether uncommitted changes were part of the scanned tree, and how thoroughly the run was verified, so a report is always tied to the code it describes. A scan outside version control stamps `UNVERSIONED` in place of the commit123* **`CLAUDE-SECURITY-REVISION-<commit>.json`**: the revision stamp, recording which commit was scanned, at what [scan effort](#choose-a-scan-effort), whether uncommitted changes were part of the scanned tree, and how thoroughly the run was verified, so a report is always tied to the code it describes. A scan outside version control stamps `UNVERSIONED` in place of the commit

106 124 

107That directory is the only change a scan makes to your checkout, and it carries its own `.gitignore`, so a stray `git add` never sweeps a report into a commit. To keep a report in history for an audit trail, delete that one `.gitignore` file and commit the directory like any other.125That directory is the only change a scan makes to your checkout, and it carries its own `.gitignore`, so a stray `git add` never sweeps a report into a commit. To keep a report in history for an audit trail, delete that one `.gitignore` file and commit the directory like any other.

108 126 

desktop.md +64 −0

Details

994* **Shell**: the shell set for your account on the remote machine has to run commands sent over SSH, as Bash, Zsh, and `sh` do994* **Shell**: the shell set for your account on the remote machine has to run commands sent over SSH, as Bash, Zsh, and `sh` do

995* **Network**: Claude Code runs on the remote machine and makes its network requests from there, so the machine needs the [network access that Claude Code requires](https://code.claude.com/docs/en/network-config.md#network-access-requirements). If the machine can't download Claude Code, Desktop downloads it on your computer and uploads it. Claude Code's other requests still go out from the remote machine. On a Linux remote machine, if those requests need a proxy, [set it for SSH sessions](#set-a-proxy-or-a-ca-certificate-for-ssh-sessions).995* **Network**: Claude Code runs on the remote machine and makes its network requests from there, so the machine needs the [network access that Claude Code requires](https://code.claude.com/docs/en/network-config.md#network-access-requirements). If the machine can't download Claude Code, Desktop downloads it on your computer and uploads it. Claude Code's other requests still go out from the remote machine. On a Linux remote machine, if those requests need a proxy, [set it for SSH sessions](#set-a-proxy-or-a-ca-certificate-for-ssh-sessions).

996 996 

997#### Check a remote machine's host key

998 

999A host key is the key that a remote machine presents to prove which machine it is, and a fingerprint is a short form of that key. When you trust a key, your computer saves it and connects to whatever presents it, without asking again. Check a key before you trust it, because something may be intercepting the connection.

1000 

1001First find which machine the key belongs to, from where you see the fingerprint:

1002 

1003* **Desktop asks `Connect to <host> for the first time?`, or you selected Review new key**: the machine that Desktop names, `<host>`

1004* **Desktop asks `Connect through <jump host> for the first time?`**: the jump host, which is the machine that your connection passes through, not the machine that you want to reach

1005* **`ssh` asks or warns in a terminal**: the machine that its message names, which may not be the one that you typed

1006 

1007Get that machine's own fingerprint from the machine, not over the connection that you're checking:

1008 

1009* **Someone else manages the machine**: ask them for its host key fingerprint

1010* **You manage it, and it runs Linux or macOS**: run `ssh-keygen -lf /etc/ssh/ssh_host_<type>_key.pub` on it, at its console or over a connection that you already trust. For `<type>`, use the key type that Desktop or `ssh` shows beside the fingerprint, in lowercase: `ed25519` for `ED25519` or `ssh-ed25519`.

1011 

1012Then compare the machine's own fingerprint with the one that you were shown:

1013 

1014* **They match**: trust the key. Select **Trust and connect** or **Trust new key** in Desktop, or answer `yes` in the terminal.

1015* **They differ, or you can't check**: don't connect. Select **Cancel** in Desktop, or answer `no` in the terminal. If someone else manages the machine, tell them which fingerprint you were shown.

1016 

1017If a troubleshooting step sent you here, go back to that step after either result.

1018 

997#### Set a proxy or a CA certificate for SSH sessions1019#### Set a proxy or a CA certificate for SSH sessions

998 1020 

999If a Linux remote machine reaches the internet through a proxy or needs a CA certificate, add the [proxy and CA variables](https://code.claude.com/docs/en/network-config.md) under `env` in `~/.claude/settings.json` there. Add them even if you already export them in `~/.profile`, `~/.bash_profile`, `~/.zprofile`, or `~/.zshrc` on that machine.1021If a Linux remote machine reaches the internet through a proxy or needs a CA certificate, add the [proxy and CA variables](https://code.claude.com/docs/en/network-config.md) under `env` in `~/.claude/settings.json` there. Add them even if you already export them in `~/.profile`, `~/.bash_profile`, `~/.zprofile`, or `~/.zshrc` on that machine.


2135 2157 

2136If MCP server toggles don't respond or servers fail to connect on Windows, check that the server is properly configured in your settings, restart the app, verify the server process is running in Task Manager, and review server logs for connection errors.2158If MCP server toggles don't respond or servers fail to connect on Windows, check that the server is properly configured in your settings, restart the app, verify the server process is running in Task Manager, and review server logs for connection errors.

2137 2159 

2160### SSH host key verification failed

2161 

2162Each of these messages means that Desktop refused a [host key](#check-a-remote-machines-host-key):

2163 

2164* `SSH host key verification failed` or `Host denied (verification failed)` under **View details** on a `Couldn't connect to <host>` card

2165* `Connection failed: Host key changed or not trusted` by the prompt box or after **Test connection**

2166* `<host>'s host key is not trusted` or `<host>'s host key has changed` on a disconnected session

2167 

2168Desktop usually refuses a key because it differs from the one saved on your computer, or because no key is saved for that machine. A machine that was rebuilt or reinstalled usually presents a new key, and so does something that intercepts the connection. Check the key before you connect again, starting from what Desktop shows with the message:

2169 

2170* **You're on Windows, and Desktop says `Connection failed: Host key changed or not trusted`**: first rule out a [missing OpenSSH client](#ssh-host-key-refused-on-windows-without-an-openssh-client)

2171* **Desktop tells you to set `UserKnownHostsFile`**: in `~/.ssh/config`, set it to `~/.ssh/known_hosts`, then [check the key from a terminal](#check-the-host-key-from-a-terminal)

2172* **You see a Review new key button**: select it, and [compare](#check-a-remote-machines-host-key) the fingerprint that Desktop shows with the machine's own. If they match, select **Trust new key** to replace the saved key. Otherwise select **Cancel**.

2173* **You see no Review new key button, Desktop shows `Couldn't show the new key`, or Desktop refuses the key again after Trust new key**: [check the key from a terminal](#check-the-host-key-from-a-terminal)

2174 

2175#### Check the host key from a terminal

2176 

2177Run `ssh <SSH host>` on your computer, with the **SSH host** value of your [SSH connection](#ssh-sessions) in Desktop. Add `-p <SSH port>` if the connection has an **SSH port** value. On Windows, use PowerShell, because Desktop doesn't connect with the `ssh` in Git Bash or WSL. If PowerShell finds no `ssh`, [install Microsoft's OpenSSH client](#ssh-host-key-refused-on-windows-without-an-openssh-client).

2178 

2179Note which machine `ssh` names in its message, which can be a jump host and not `<SSH host>`, then follow the case that fits:

2180 

2181* **`ssh` asks whether to continue connecting**: [compare](#check-a-remote-machines-host-key) the fingerprint that it shows with that machine's own. Answer `yes` only if they match.

2182* **`ssh` warns that the host key has changed**: [compare](#check-a-remote-machines-host-key) the warning's fingerprint with that machine's own. Only if they match, delete the line that `Offending <type> key in <file>:<line>` names and rerun `ssh`. If `ssh` warns again about another line, compare, delete and rerun as before.

2183* **`ssh` refuses a key that it doesn't know, without asking**: get that machine's `known_hosts` line from whoever manages it, not over the connection that you're checking. Add the line to your `known_hosts` file, with the name from `ssh`'s message as its host name, and rerun `ssh`.

2184* **`ssh` goes on to sign in without asking you about the host key**: don't type a password yet. [Check the keys that `ssh` already trusts](#check-the-keys-that-ssh-already-trusts).

2185 

2186Once `ssh` accepts a key that you checked or added, retry in Desktop. If Desktop refuses the key again, see [Get Desktop's logs for an SSH problem](#get-desktops-logs-for-an-ssh-problem).

2187 

2188##### Check the keys that `ssh` already trusts

2189 

2190Rerun the same `ssh` command with `-v -S none` added. In its output, a `Server host key:` line shows a fingerprint, and the next `Host '<name>' is known` line names the machine that it belongs to. [Compare](#check-a-remote-machines-host-key) each fingerprint that you find with that machine's own.

2191 

2192* **A jump host has no `Server host key:` line**: run `ssh -v -S none <jump host>` too, and compare that fingerprint in the same way.

2193* **A fingerprint doesn't match, or you can't check it**: don't connect again. Remove the saved key: under `Host '<name>' is known`, the line `Found key in <file>:<line>` names the file that holds it. Run `ssh-keygen -R "<name>" -f <file>`. If you keep host keys in more than one file, remove the key from each. If you can't change a file, tell whoever manages your computer.

2194* **Every fingerprint matches**: retry in Desktop. If Desktop refuses the key again, see [Get Desktop's logs for an SSH problem](#get-desktops-logs-for-an-ssh-problem).

2195 

2196### SSH host key refused on Windows without an OpenSSH client

2197 

2198On Windows without an OpenSSH client, Desktop refuses even a correct host key, with `Connection failed: Host key changed or not trusted`. It needs the client to look up saved keys. To see whether you have one, run `ssh` in PowerShell. If PowerShell doesn't recognize `ssh`, install [Microsoft's OpenSSH client](https://learn.microsoft.com/windows-server/administration/openssh/openssh_install_firstuse) and restart Desktop.

2199 

2200Then connect again. If Desktop asks whether to connect for the first time, [check the machine's host key](#check-a-remote-machines-host-key) before you trust it. If Desktop still refuses the key, follow the other cases under [SSH host key verification failed](#ssh-host-key-verification-failed).

2201 

2138### SSH connection fails after you log in2202### SSH connection fails after you log in

2139 2203 

2140Find the card's title, or the code that ends the error message, in this table, then do what the last column says. To see the message, select **View details** on the failure card.2204Find the card's title, or the code that ends the error message, in this table, then do what the last column says. To see the message, select **View details** on the failure card.

env-vars.md +2 −2

Details

236| `CLAUDE_CODE_DISABLE_BACKGROUND_TASKS` | Set to `1` to remove the `run_in_background` parameter from the Bash, PowerShell, and subagent tools and to turn off the Ctrl+B shortcut and background runs of [forked skills](https://code.claude.com/docs/en/skills.md#run-skills-in-a-subagent). Claude Code then also stops moving subagents, long MCP tool calls, and timed-out shell commands to the background automatically. [MCP tasks](https://code.claude.com/docs/en/mcp.md#make-claude-wait-for-the-result-of-an-mcp-task) and the [Monitor tool](https://code.claude.com/docs/en/tools-reference.md#monitor-tool) still run in the background |236| `CLAUDE_CODE_DISABLE_BACKGROUND_TASKS` | Set to `1` to remove the `run_in_background` parameter from the Bash, PowerShell, and subagent tools and to turn off the Ctrl+B shortcut and background runs of [forked skills](https://code.claude.com/docs/en/skills.md#run-skills-in-a-subagent). Claude Code then also stops moving subagents, long MCP tool calls, and timed-out shell commands to the background automatically. [MCP tasks](https://code.claude.com/docs/en/mcp.md#make-claude-wait-for-the-result-of-an-mcp-task) and the [Monitor tool](https://code.claude.com/docs/en/tools-reference.md#monitor-tool) still run in the background |

237| `CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_DEFAULT` | Set to `1` to stop Claude Code from treating an [Amazon Bedrock](https://code.claude.com/docs/en/amazon-bedrock.md) streaming response with a missing or empty `Content-Type` header as Amazon Bedrock's binary event stream. By default, Claude Code assumes a gateway dropped the header from an otherwise unmodified response, so it decodes the body and streaming keeps working. Set this only for a gateway that also re-emits the stream as server-sent events; Claude Code then reads the header-less body as server-sent events instead. Requires Claude Code v2.1.239 or later |237| `CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_DEFAULT` | Set to `1` to stop Claude Code from treating an [Amazon Bedrock](https://code.claude.com/docs/en/amazon-bedrock.md) streaming response with a missing or empty `Content-Type` header as Amazon Bedrock's binary event stream. By default, Claude Code assumes a gateway dropped the header from an otherwise unmodified response, so it decodes the body and streaming keeps working. Set this only for a gateway that also re-emits the stream as server-sent events; Claude Code then reads the header-less body as server-sent events instead. Requires Claude Code v2.1.239 or later |

238| `CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_GUARD` | Set to `1` to skip the check that an [Amazon Bedrock](https://code.claude.com/docs/en/amazon-bedrock.md) streaming response carries the `application/vnd.amazon.eventstream` content-type. Without this variable, when a response carries a different content-type, Claude Code fails the request with an error naming that type, which means a [gateway or proxy is transforming the response](https://code.claude.com/docs/en/amazon-bedrock.md#streaming-errors-behind-a-gateway-or-proxy). Configure the gateway to forward the `Content-Type` header and body unmodified rather than setting this variable. Requires Claude Code v2.1.208 or later |238| `CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_GUARD` | Set to `1` to skip the check that an [Amazon Bedrock](https://code.claude.com/docs/en/amazon-bedrock.md) streaming response carries the `application/vnd.amazon.eventstream` content-type. Without this variable, when a response carries a different content-type, Claude Code fails the request with an error naming that type, which means a [gateway or proxy is transforming the response](https://code.claude.com/docs/en/amazon-bedrock.md#streaming-errors-behind-a-gateway-or-proxy). Configure the gateway to forward the `Content-Type` header and body unmodified rather than setting this variable. Requires Claude Code v2.1.208 or later |

239| `CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF` | Set to `1` to stop a [background session's](https://code.claude.com/docs/en/agent-view.md) in-flight work when the [supervisor](https://code.claude.com/docs/en/agent-view.md#the-supervisor-process) stops, restarts, or updates that session's process, instead of handing it to the session's next process. That work is the session's running background shell commands and dynamic workflows, plus background subagents as of v2.1.198. Affects only that handoff: backgrounding a session with `←` or [`/background`](https://code.claude.com/docs/en/agent-view#from-inside-a-session) still carries in-flight background work over. Requires Claude Code v2.1.196 or later |239| `CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF` | Set to `1` to stop a [background session's](https://code.claude.com/docs/en/agent-view.md) in-flight work when the [supervisor](https://code.claude.com/docs/en/agent-view.md#the-supervisor-process) stops, restarts, or updates that session's process, instead of handing it to the session's next process. That work is the session's running background shell commands, plus background subagents as of v2.1.198. Affects only that handoff: backgrounding a session with `←` or [`/background`](https://code.claude.com/docs/en/agent-view#from-inside-a-session) still carries in-flight background work over. Requires Claude Code v2.1.196 or later |

240| `CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP` | Set to `1` to stop Claude Code from terminating [background shell commands](https://code.claude.com/docs/en/interactive-mode.md#background-bash-commands) under memory pressure. By default, on macOS and Linux, Claude Code terminates background shells when the operating system reports critical memory pressure and the session has been idle for 30 minutes with no turn or subagent running. Windows has no memory-pressure signal, so this variable has no effect there. Requires Claude Code v2.1.193 or later |240| `CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP` | Set to `1` to stop Claude Code from terminating [background shell commands](https://code.claude.com/docs/en/interactive-mode.md#background-bash-commands) under memory pressure. By default, on macOS and Linux, Claude Code terminates background shells when the operating system reports critical memory pressure and the session has been idle for 30 minutes with no turn or subagent running. Windows has no memory-pressure signal, so this variable has no effect there. Requires Claude Code v2.1.193 or later |

241| `CLAUDE_CODE_DISABLE_BUNDLED_SKILLS` | Set to `1` to disable the [skills](https://code.claude.com/docs/en/skills.md) and workflows included with Claude Code: bundled skills and workflows are removed entirely, while built-in commands like `/init` stay typable but are hidden from the model. `/doctor` stays typable like the built-in commands; hide it with `DISABLE_DOCTOR_COMMAND` instead. Skills from plugins, `.claude/skills/`, and `.claude/commands/` are unaffected. Equivalent to the [`disableBundledSkills`](https://code.claude.com/docs/en/settings-reference#disablebundledskills) setting |241| `CLAUDE_CODE_DISABLE_BUNDLED_SKILLS` | Set to `1` to disable the [skills](https://code.claude.com/docs/en/skills.md) and workflows included with Claude Code: bundled skills and workflows are removed entirely, while built-in commands like `/init` stay typable but are hidden from the model. `/doctor` stays typable like the built-in commands; hide it with `DISABLE_DOCTOR_COMMAND` instead. Skills from plugins, `.claude/skills/`, and `.claude/commands/` are unaffected. Equivalent to the [`disableBundledSkills`](https://code.claude.com/docs/en/settings-reference#disablebundledskills) setting |

242| `CLAUDE_CODE_DISABLE_CFC_PROMPT` | Set to `1` to keep the [Claude in Chrome](https://code.claude.com/docs/en/chrome.md) browser tools available while omitting the Chrome section of the system prompt and the `/claude-in-chrome` [bundled skill](https://code.claude.com/docs/en/skills.md#bundled-skills). For hosts that embed Claude Code and supply their own browser guidance. Requires Claude Code v2.1.257 or later |242| `CLAUDE_CODE_DISABLE_CFC_PROMPT` | Set to `1` to keep the [Claude in Chrome](https://code.claude.com/docs/en/chrome.md) browser tools available while omitting the Chrome section of the system prompt and the `/claude-in-chrome` [bundled skill](https://code.claude.com/docs/en/skills.md#bundled-skills). For hosts that embed Claude Code and supply their own browser guidance. Requires Claude Code v2.1.257 or later |

243| `CLAUDE_CODE_DISABLE_CLAUDE_MDS` | Set to `1` to prevent loading any CLAUDE.md memory files into context, including user, project, and auto memory files |243| `CLAUDE_CODE_DISABLE_CLAUDE_MDS` | Set to `1` to prevent loading any CLAUDE.md memory files into context, including user, project, and auto memory files |

244| `CLAUDE_CODE_DISABLE_CRON` | Set to `1` to disable [session-scoped scheduled tasks](https://code.claude.com/docs/en/scheduled-tasks.md). The `/loop` skill and cron tools become unavailable and any already-scheduled tasks stop firing, including tasks that are already running mid-session |244| `CLAUDE_CODE_DISABLE_CRON` | Set to `1` to disable [session-scoped scheduled tasks](https://code.claude.com/docs/en/scheduled-tasks.md). The `/loop` skill and cron tools become unavailable and any already-scheduled tasks stop firing, including tasks that are already running mid-session |

245| `CLAUDE_CODE_DISABLE_DANGEROUS_RM_TIMEOUT` | Set to `1` to turn off the time limit on [critical-path removal](https://code.claude.com/docs/en/permission-modes.md#critical-paths) prompts. In `auto` mode Claude Code then sends these removals to the classifier instead, and in `bypassPermissions` mode the prompt waits for your answer. Set it in the environment that launches Claude Code, since Claude Code ignores a copy delivered through a settings `env` block. Requires Claude Code v2.1.281 or later |245| `CLAUDE_CODE_DISABLE_DANGEROUS_RM_TIMEOUT` | Set to `1` to turn off the `auto` and `bypassPermissions` [time limit and denials](https://code.claude.com/docs/en/permission-modes.md#time-limits-and-denials-in-auto-and-bypasspermissions-modes) on critical-path removals. These removals then go to the classifier in `auto` mode, and get an untimed prompt in `bypassPermissions` mode wherever Claude Code can show one. Set it in the environment that launches Claude Code, since Claude Code ignores a copy delivered through a settings `env` block. Requires Claude Code v2.1.281 or later |

246| `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS` | Set to `1` to strip pre-release `anthropic-beta` request headers, the body fields that pair with them, and beta tool-schema fields such as `defer_loading` and `eager_input_streaming` from API requests. Use this when a proxy gateway rejects requests with an `Unexpected value(s)` error for the `anthropic-beta` header or an `Extra inputs are not permitted` error. [Disable pre-release capabilities](https://code.claude.com/docs/en/llm-gateway-protocol.md#disable-pre-release-capabilities) lists what the variable removes, including [MCP tool search](https://code.claude.com/docs/en/mcp.md#scale-with-mcp-tool-search), and what Claude Code keeps sending |246| `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS` | Set to `1` to strip pre-release `anthropic-beta` request headers, the body fields that pair with them, and beta tool-schema fields such as `defer_loading` and `eager_input_streaming` from API requests. Use this when a proxy gateway rejects requests with an `Unexpected value(s)` error for the `anthropic-beta` header or an `Extra inputs are not permitted` error. [Disable pre-release capabilities](https://code.claude.com/docs/en/llm-gateway-protocol.md#disable-pre-release-capabilities) lists what the variable removes, including [MCP tool search](https://code.claude.com/docs/en/mcp.md#scale-with-mcp-tool-search), and what Claude Code keeps sending |

247| `CLAUDE_CODE_DISABLE_EXPLORE_PLAN_AGENTS` | Set to `1` to disable the built-in [Explore and Plan subagents](https://code.claude.com/docs/en/sub-agents.md#built-in-subagents). Claude explores with its search tools or the general-purpose subagent instead, and [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) reads files directly rather than launching Explore and Plan agents. Custom subagents named `Explore` or `Plan` are unaffected. To remove every built-in subagent type in the Agent SDK or non-interactive mode, use `CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS` instead. Requires Claude Code v2.1.198 or later |247| `CLAUDE_CODE_DISABLE_EXPLORE_PLAN_AGENTS` | Set to `1` to disable the built-in [Explore and Plan subagents](https://code.claude.com/docs/en/sub-agents.md#built-in-subagents). Claude explores with its search tools or the general-purpose subagent instead, and [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) reads files directly rather than launching Explore and Plan agents. Custom subagents named `Explore` or `Plan` are unaffected. To remove every built-in subagent type in the Agent SDK or non-interactive mode, use `CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS` instead. Requires Claude Code v2.1.198 or later |

248| `CLAUDE_CODE_DISABLE_FAST_MODE` | Set to `1` to disable [fast mode](https://code.claude.com/docs/en/fast-mode.md) |248| `CLAUDE_CODE_DISABLE_FAST_MODE` | Set to `1` to disable [fast mode](https://code.claude.com/docs/en/fast-mode.md) |

errors.md +32 −0

Details

244| `MCP server "<name>" was not saved to` / `was not removed from` | [Command-line errors](#mcp-server-was-not-saved-or-removed) |244| `MCP server "<name>" was not saved to` / `was not removed from` | [Command-line errors](#mcp-server-was-not-saved-or-removed) |

245| `MCP server "<name>" may not have been saved` / `may not have been removed` | [Command-line errors](#mcp-server-may-not-have-been-saved-or-removed) |245| `MCP server "<name>" may not have been saved` / `may not have been removed` | [Command-line errors](#mcp-server-may-not-have-been-saved-or-removed) |

246| `Server rejected the Authorization header minted by the configured headersHelper` | [Command-line errors](#server-rejected-the-authorization-header-minted-by-the-configured-headershelper) |246| `Server rejected the Authorization header minted by the configured headersHelper` | [Command-line errors](#server-rejected-the-authorization-header-minted-by-the-configured-headershelper) |

247| `This server (Java MCP SDK 0.17.0 or older) rejected Claude Code's elicitation capability` | [Command-line errors](#mcp-server-rejected-the-elicitation-capability) |

247| `Error: MCP tool <name> (passed via --permission-prompt-tool) not found` | [Command-line errors](#mcp-permission-prompt-tool-not-found) |248| `Error: MCP tool <name> (passed via --permission-prompt-tool) not found` | [Command-line errors](#mcp-permission-prompt-tool-not-found) |

248| `OAuth callback port <port> is already in use — another process may be holding it` | [Command-line errors](#oauth-callback-port-is-already-in-use) |249| `OAuth callback port <port> is already in use — another process may be holding it` | [Command-line errors](#oauth-callback-port-is-already-in-use) |

249| `No available ports for OAuth redirect` | [Command-line errors](#no-available-ports-for-oauth-redirect) |250| `No available ports for OAuth redirect` | [Command-line errors](#no-available-ports-for-oauth-redirect) |


3473 3474 

3474Before v2.1.248, Claude Code ran OAuth discovery for a server whose helper supplied the `Authorization` header. That discovery could fail with `Incompatible auth server: does not support dynamic client registration` instead of reporting the rejected credential.3475Before v2.1.248, Claude Code ran OAuth discovery for a server whose helper supplied the `Authorization` header. That discovery could fail with `Incompatible auth server: does not support dynamic client registration` instead of reporting the rejected credential.

3475 3476 

3477### MCP server rejected the elicitation capability

3478 

3479An MCP server built on Java MCP SDK 0.11.0 through 0.17.0 refused the connection. Those SDK versions can't parse the `form` and `url` [elicitation modes](https://code.claude.com/docs/en/mcp.md#elicitation-modes-claude-code-declares) that Claude Code declares in its handshake. `claude mcp list` shows the server as failed with this message in place of the server's own error:

3480 

3481```text theme={null}

3482This server (Java MCP SDK 0.17.0 or older) rejected Claude Code's elicitation capability. Set "bareElicitationCapability": true for it, or upgrade to Java MCP SDK 0.17.1+ (Spring AI 1.0.7+ or 1.1.6+).

3483```

3484 

3485**What to do:**

3486 

3487* Upgrade the server to Java MCP SDK 0.17.1 or later, or to one of the Spring AI releases the message names

3488* Or add `"bareElicitationCapability": true` to that server's entry in your MCP configuration, then restart Claude Code. The field is accepted on stdio, `sse`, `http`, and `ws` entries and requires Claude Code v2.1.281 or later

3489 

3490This `.mcp.json` entry sets the field for one HTTP server:

3491 

3492```json theme={null}

3493{

3494 "mcpServers": {

3495 "inventory": {

3496 "type": "http",

3497 "url": "https://mcp.example.com/mcp",

3498 "bareElicitationCapability": true

3499 }

3500 }

3501}

3502```

3503 

3504After the restart, `/mcp` shows the server as connected. Claude Code declares form mode only to that server, so remove the field once you upgrade it.

3505 

3506A server can also fail with its own error text, such as one containing `Unrecognized field "form"`. The same fixes apply.

3507 

3476### MCP permission prompt tool not found3508### MCP permission prompt tool not found

3477 3509 

3478The tool you passed to [`--permission-prompt-tool`](https://code.claude.com/docs/en/cli-reference#cli-flags) wasn't among the connected MCP tools when the run first needed a permission decision, either because its server never connected or because no connected server exposes a tool by that name. Claude Code still sends your prompt: the [non-interactive](https://code.claude.com/docs/en/headless.md) run exits with this error, and exit code 1, on the first tool call, so it produces no answer even though the request was made. Before the first prompt, Claude Code waits up to the per-server connection timeout of 30 seconds set by [`MCP_TIMEOUT`](https://code.claude.com/docs/en/env-vars) for that server to connect. Before v2.1.206, startup didn't wait for the server to finish connecting, so a slow-starting but healthy server produced this error too.3510The tool you passed to [`--permission-prompt-tool`](https://code.claude.com/docs/en/cli-reference#cli-flags) wasn't among the connected MCP tools when the run first needed a permission decision, either because its server never connected or because no connected server exposes a tool by that name. Claude Code still sends your prompt: the [non-interactive](https://code.claude.com/docs/en/headless.md) run exits with this error, and exit code 1, on the first tool call, so it produces no answer even though the request was made. Before the first prompt, Claude Code waits up to the per-server connection timeout of 30 seconds set by [`MCP_TIMEOUT`](https://code.claude.com/docs/en/env-vars) for that server to connect. Before v2.1.206, startup didn't wait for the server to finish connecting, so a slow-starting but healthy server produced this error too.

hooks.md +1 −1

Details

1957 1957 

1958| Field | Description |1958| Field | Description |

1959| :- | :- |1959| :- | :- |

1960| `permissionDecision` | `"allow"` skips the permission prompt, except for [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) and [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths). `AskUserQuestion` and `ExitPlanMode` need [`updatedInput` paired with `"allow"`](#allow-with-updatedinput). For plan mode, see [Hook approvals in plan mode](https://code.claude.com/docs/en/permissions.md#hook-approvals-in-plan-mode). `"deny"` prevents the tool call. `"ask"` prompts the user to confirm. `"defer"` ends the turn so the tool can be resumed later, and requires [non-interactive mode](#defer-a-tool-call-for-later) with the `-p` flag. [Deny and ask rules](https://code.claude.com/docs/en/permissions.md#manage-permissions) are still evaluated regardless of what the hook returns |1960| `permissionDecision` | `"allow"` skips the permission prompt, except for [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) and [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths). It doesn't skip approval for calls to [tools an Agent SDK app marks `always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools) either, unless the [permission mode approves the call](https://code.claude.com/docs/en/agent-sdk/typescript.md#permission-modes-that-can-approve-an-always_ask-call). `AskUserQuestion` and `ExitPlanMode` need [`updatedInput` paired with `"allow"`](#allow-with-updatedinput). For plan mode, see [Hook approvals in plan mode](https://code.claude.com/docs/en/permissions.md#hook-approvals-in-plan-mode). `"deny"` prevents the tool call. `"ask"` prompts the user to confirm. `"defer"` ends the turn so the tool can be resumed later, and requires [non-interactive mode](#defer-a-tool-call-for-later) with the `-p` flag. [Deny and ask rules](https://code.claude.com/docs/en/permissions.md#manage-permissions) are still evaluated regardless of what the hook returns |

1961| `permissionDecisionReason` | For `"ask"`, shown to the user in the permission prompt. When Claude Code [denies the call](https://code.claude.com/docs/en/headless.md#turn-off-permission-prompts-in-unattended-runs) in a `-p` run where no one can answer that prompt, Claude reads the reason in the tool result instead. For `"deny"`, shown to Claude. For `"allow"` and `"defer"`, written to the [debug log](#debug-hooks) only |1961| `permissionDecisionReason` | For `"ask"`, shown to the user in the permission prompt. When Claude Code [denies the call](https://code.claude.com/docs/en/headless.md#turn-off-permission-prompts-in-unattended-runs) in a `-p` run where no one can answer that prompt, Claude reads the reason in the tool result instead. For `"deny"`, shown to Claude. For `"allow"` and `"defer"`, written to the [debug log](#debug-hooks) only |

1962| `updatedInput` | Modifies the tool's input parameters before execution. Replaces the entire input object, so include unchanged fields alongside modified ones. Claude Code evaluates permission rules and a Bash command's [auto-background eligibility](https://code.claude.com/docs/en/tools-reference.md#foreground-commands-that-move-to-the-background) against the input your hook returns, not the input Claude sent. Combine with `"allow"` to auto-approve, or `"ask"` to show the modified input to the user. For `"defer"`, ignored |1962| `updatedInput` | Modifies the tool's input parameters before execution. Replaces the entire input object, so include unchanged fields alongside modified ones. Claude Code evaluates permission rules and a Bash command's [auto-background eligibility](https://code.claude.com/docs/en/tools-reference.md#foreground-commands-that-move-to-the-background) against the input your hook returns, not the input Claude sent. Combine with `"allow"` to auto-approve, or `"ask"` to show the modified input to the user. For `"defer"`, ignored |

1963| `additionalContext` | String added to Claude's context alongside the tool result. Ignored when `permissionDecision` is `"defer"`. See [Add context for Claude](#add-context-for-claude) |1963| `additionalContext` | String added to Claude's context alongside the tool result. Ignored when `permissionDecision` is `"defer"`. See [Add context for Claude](#add-context-for-claude) |

hooks-guide.md +2 −0

Details

629 629 

630* Reads from [network paths](https://code.claude.com/docs/en/permissions.md#network-paths)630* Reads from [network paths](https://code.claude.com/docs/en/permissions.md#network-paths)

631* MCP tools marked [`requiresUserInteraction`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool)631* MCP tools marked [`requiresUserInteraction`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool)

632* Calls to [tools an Agent SDK app marks `always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools), unless the [permission mode approves the call](https://code.claude.com/docs/en/agent-sdk/typescript.md#permission-modes-that-can-approve-an-always_ask-call)

632* Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools) in sessions where that setting reaches Claude Code633* Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools) in sessions where that setting reaches Claude Code

633 634 

634For what `"allow"` does in plan mode, see [Hook approvals in plan mode](https://code.claude.com/docs/en/permissions.md#hook-approvals-in-plan-mode).635For what `"allow"` does in plan mode, see [Hook approvals in plan mode](https://code.claude.com/docs/en/permissions.md#hook-approvals-in-plan-mode).


964 965 

965 * Reads from [network paths](https://code.claude.com/docs/en/permissions.md#network-paths)966 * Reads from [network paths](https://code.claude.com/docs/en/permissions.md#network-paths)

966 * MCP tools marked [`requiresUserInteraction`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool)967 * MCP tools marked [`requiresUserInteraction`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool)

968 * Calls to [tools an Agent SDK app marks `always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools), unless the [permission mode approves the call](https://code.claude.com/docs/en/agent-sdk/typescript.md#permission-modes-that-can-approve-an-always_ask-call)

967 * Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools) in sessions where that setting reaches Claude Code969 * Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools) in sessions where that setting reaches Claude Code

968 970 

969 In [plan mode](https://code.claude.com/docs/en/permissions.md#hook-approvals-in-plan-mode), if your `PreToolUse` hook returns `"allow"` for a file edit, you get the same prompt, block, or approval the edit would get with no hook. To lift this limit on hook approvals, [approve the plan](https://code.claude.com/docs/en/permission-modes.md#review-and-approve-a-plan) or switch to another permission mode.971 In [plan mode](https://code.claude.com/docs/en/permissions.md#hook-approvals-in-plan-mode), if your `PreToolUse` hook returns `"allow"` for a file edit, you get the same prompt, block, or approval the edit would get with no hook. To lift this limit on hook approvals, [approve the plan](https://code.claude.com/docs/en/permission-modes.md#review-and-approve-a-plan) or switch to another permission mode.

Details

407| [`managedMcpServers`](https://code.claude.com/docs/en/settings-reference#managedmcpservers) | Remote MCP servers provided to every user alongside their own. It provides servers rather than locking anything down. See [Provide servers through managed settings](https://code.claude.com/docs/en/managed-mcp.md#provide-servers-through-managed-settings). Requires Claude Code v2.1.259 or later |407| [`managedMcpServers`](https://code.claude.com/docs/en/settings-reference#managedmcpservers) | Remote MCP servers provided to every user alongside their own. It provides servers rather than locking anything down. See [Provide servers through managed settings](https://code.claude.com/docs/en/managed-mcp.md#provide-servers-through-managed-settings). Requires Claude Code v2.1.259 or later |

408| [`managedSourcesBehavior`](https://code.claude.com/docs/en/settings-reference#managedsourcesbehavior) | Whether Claude Code applies only the highest-priority managed source or [composes every one of them](#compose-every-managed-source) |408| [`managedSourcesBehavior`](https://code.claude.com/docs/en/settings-reference#managedsourcesbehavior) | Whether Claude Code applies only the highest-priority managed source or [composes every one of them](#compose-every-managed-source) |

409| [`parentSettingsBehavior`](https://code.claude.com/docs/en/settings-reference#parentsettingsbehavior) | Whether host-supplied parent settings merge under the managed policy |409| [`parentSettingsBehavior`](https://code.claude.com/docs/en/settings-reference#parentsettingsbehavior) | Whether host-supplied parent settings merge under the managed policy |

410| [`pluginSuggestionMarketplaces`](https://code.claude.com/docs/en/settings-reference#pluginsuggestionmarketplaces) | Marketplaces whose plugins Claude Code may suggest to users |410| [`pluginSuggestionMarketplaces`](https://code.claude.com/docs/en/settings-reference#pluginsuggestionmarketplaces) | Marketplaces whose plugins Claude Code may suggest to users in the terminal |

411| [`pluginTrustMessage`](https://code.claude.com/docs/en/settings-reference#plugintrustmessage) | Custom message appended to the plugin trust warning shown before installation |411| [`pluginTrustMessage`](https://code.claude.com/docs/en/settings-reference#plugintrustmessage) | Custom message appended to the plugin trust warning shown before installation |

412| [`policyHelper`](https://code.claude.com/docs/en/settings-reference#policyhelper) | Executable that computes managed settings at startup; see [Compute managed settings with a policy helper](https://code.claude.com/docs/en/settings-reference.md#policyhelper) |412| [`policyHelper`](https://code.claude.com/docs/en/settings-reference#policyhelper) | Executable that computes managed settings at startup; see [Compute managed settings with a policy helper](https://code.claude.com/docs/en/settings-reference.md#policyhelper) |

413| [`sandbox.filesystem.allowManagedReadPathsOnly`](https://code.claude.com/docs/en/settings-reference#sandbox-filesystem-allowmanagedreadpathsonly) | When `true`, only `filesystem.allowRead` paths from managed settings are respected. `denyRead` still merges from all sources |413| [`sandbox.filesystem.allowManagedReadPathsOnly`](https://code.claude.com/docs/en/settings-reference#sandbox-filesystem-allowmanagedreadpathsonly) | When `true`, only `filesystem.allowRead` paths from managed settings are respected. `denyRead` still merges from all sources |

mcp.md +10 −1

Details

1624 1624 

1625If you're building an MCP server that uses elicitation, see the [MCP elicitation specification](https://modelcontextprotocol.io/docs/learn/client-concepts#elicitation) for protocol details and schema examples.1625If you're building an MCP server that uses elicitation, see the [MCP elicitation specification](https://modelcontextprotocol.io/docs/learn/client-concepts#elicitation) for protocol details and schema examples.

1626 1626 

1627On connections that use [protocol revision 2026-07-28](#mcp-client-runtimes), Claude Code declares `elicitation: {form: {}, url: {}}` in its client capabilities, so a server there can request either mode through the protocol's standard elicitation request.1627### Elicitation modes Claude Code declares

1628 

1629If you build an MCP server, the client capabilities Claude Code sends when it connects tell your server which elicitation modes it can request. Claude Code declares `elicitation: {form: {}, url: {}}` on the following connections, so a server on any of them can request both modes:

1630 

1631* Connections that use [protocol revision 2026-07-28](#mcp-client-runtimes)

1632* Connections on the earlier protocol revisions, 2025-11-25 and older, to the stdio, `sse`, `http`, and `ws` servers in a user's Claude Code MCP configuration. Requires Claude Code v2.1.287 or later

1633 

1634On its other connections on the earlier revisions, such as to [claude.ai connectors](#use-mcp-servers-from-claude-ai), Claude Code declares the bare `elicitation: {}`, which permits elicitation requests in form mode only.

1635 

1636A server built on Java MCP SDK 0.17.0 or earlier can refuse a declaration that has `form` and `url` in it. See [MCP server rejected the elicitation capability](https://code.claude.com/docs/en/errors.md#mcp-server-rejected-the-elicitation-capability).

1628 1637 

1629## Use MCP resources1638## Use MCP resources

1630 1639 

Details

36* Tools matched by an explicit [ask rule](https://code.claude.com/docs/en/permissions.md#manage-permissions)36* Tools matched by an explicit [ask rule](https://code.claude.com/docs/en/permissions.md#manage-permissions)

37* Connector tools your organization [set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), in sessions where that setting reaches Claude Code37* Connector tools your organization [set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), in sessions where that setting reaches Claude Code

38* Tools that require user interaction: the built-in `AskUserQuestion` tool and MCP tools marked [`requiresUserInteraction`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool)38* Tools that require user interaction: the built-in `AskUserQuestion` tool and MCP tools marked [`requiresUserInteraction`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool)

39* Recognized `rm` and `rmdir` [critical-path removals](#critical-paths), which no allow rule or `PreToolUse` hook `"allow"` approves39* Recognized `rm` and `rmdir` [critical-path removals](#critical-paths), which no allow rule or `PreToolUse` hook `"allow"` approves, and Bash commands flagged [`Dangerous rm operation not ruled out`](#dangerous-rm-operation-not-ruled-out)

40* The [cross-session messaging safeguards](#skip-all-checks-with-bypasspermissions-mode)40* The [cross-session messaging safeguards](#skip-all-checks-with-bypasspermissions-mode)

41* Reads outside the working directories while [`permissions.blockReadsOutsideWorkingDirectories`](https://code.claude.com/docs/en/settings-reference#permissions-blockreadsoutsideworkingdirectories) is on: recognized file-reading Bash commands prompt even in auto mode and `bypassPermissions` mode, and so does any [unsandboxed retry](https://code.claude.com/docs/en/sandboxing.md#the-unsandboxed-retry-escape-hatch) that needs approval to run outside the sandbox. Requires Claude Code v2.1.257 or later.41* Reads outside the working directories while [`permissions.blockReadsOutsideWorkingDirectories`](https://code.claude.com/docs/en/settings-reference#permissions-blockreadsoutsideworkingdirectories) is on: recognized file-reading Bash commands prompt even in auto mode and `bypassPermissions` mode, and so does any [unsandboxed retry](https://code.claude.com/docs/en/sandboxing.md#the-unsandboxed-retry-escape-hatch) that needs approval to run outside the sandbox. Requires Claude Code v2.1.257 or later.

42 42 


265 265 

266`acceptEdits` mode lets Claude create and edit files in your working directory without prompting. The status bar shows `⏵⏵ accept edits on` while this mode is active.266`acceptEdits` mode lets Claude create and edit files in your working directory without prompting. The status bar shows `⏵⏵ accept edits on` while this mode is active.

267 267 

268In addition to file edits, `acceptEdits` mode auto-approves common filesystem Bash commands: `mkdir`, `touch`, `rm`, `rmdir`, `mv`, `cp`, and `sed`. These commands are also auto-approved when prefixed with safe environment variables such as `LANG=C` or `NO_COLOR=1`, or process wrappers such as `timeout`, `nice`, or `nohup`. Like file edits, auto-approval applies only to paths inside your working directory or `additionalDirectories`.268In addition to file edits, `acceptEdits` mode auto-approves common filesystem Bash commands: `mkdir`, `touch`, `rm`, `rmdir`, `mv`, `cp`, and `sed`. Except for `touch`, these commands are also auto-approved when prefixed with safe environment variables such as `LANG=C` or `NO_COLOR=1`, or process wrappers such as `timeout`, `nice`, or `nohup`. Like file edits, auto-approval applies only to paths inside your working directory or `additionalDirectories`.

269 269 

270These still prompt:270These still prompt:

271 271 

272* Paths outside that scope272* Paths outside that scope

273* Writes to [protected paths](#protected-paths)273* Writes to [protected paths](#protected-paths)

274* Recognized `rm` and `rmdir` [critical-path removals](#critical-paths)274* Recognized `rm` and `rmdir` [critical-path removals](#critical-paths)

275* `touch` with anything beyond plain file paths, for example an option, a glob, or a prefix such as `timeout 5` or `LANG=C`

275* All other Bash commands except the [built-in read-only set](https://code.claude.com/docs/en/permissions.md#read-only-commands)276* All other Bash commands except the [built-in read-only set](https://code.claude.com/docs/en/permissions.md#read-only-commands)

276 277 

277Each path also goes through the [symlink check](https://code.claude.com/docs/en/permissions.md#symlinks), so a write that resolves outside that scope isn't auto-approved either.278Each path also goes through the [symlink check](https://code.claude.com/docs/en/permissions.md#symlinks), so a write that resolves outside that scope isn't auto-approved either.


369* **A direct connection to the Anthropic API**: in interactive terminal sessions and in `-p`, Agent SDK, [VS Code extension](https://code.claude.com/docs/en/vs-code.md), and [desktop app](https://code.claude.com/docs/en/desktop.md) sessions, whatever your plan or account type, as Anthropic rolls it out. In interactive terminal sessions, this requires Claude Code v2.1.271 or later on Pro, Max, and Team plans, and v2.1.278 or later on Enterprise plans and Claude API accounts. In `-p`, Agent SDK, VS Code extension, and desktop app sessions, this requires Claude Code v2.1.281 or later. From v2.1.282, a session that [doesn't fetch feature flags](https://code.claude.com/docs/en/env-vars.md#features-that-need-feature-flag-fetching), for example because you turned telemetry off, asks the server by default in any kind of session.370* **A direct connection to the Anthropic API**: in interactive terminal sessions and in `-p`, Agent SDK, [VS Code extension](https://code.claude.com/docs/en/vs-code.md), and [desktop app](https://code.claude.com/docs/en/desktop.md) sessions, whatever your plan or account type, as Anthropic rolls it out. In interactive terminal sessions, this requires Claude Code v2.1.271 or later on Pro, Max, and Team plans, and v2.1.278 or later on Enterprise plans and Claude API accounts. In `-p`, Agent SDK, VS Code extension, and desktop app sessions, this requires Claude Code v2.1.281 or later. From v2.1.282, a session that [doesn't fetch feature flags](https://code.claude.com/docs/en/env-vars.md#features-that-need-feature-flag-fetching), for example because you turned telemetry off, asks the server by default in any kind of session.

370* **A cloud provider, or an LLM gateway or proxy**: on [Claude Platform on AWS](https://code.claude.com/docs/en/claude-platform-on-aws.md), Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry, and whenever you point `ANTHROPIC_BASE_URL` at an [LLM gateway or proxy](https://code.claude.com/docs/en/llm-gateway), whatever your plan. Asking by default requires Claude Code v2.1.278 or later.371* **A cloud provider, or an LLM gateway or proxy**: on [Claude Platform on AWS](https://code.claude.com/docs/en/claude-platform-on-aws.md), Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry, and whenever you point `ANTHROPIC_BASE_URL` at an [LLM gateway or proxy](https://code.claude.com/docs/en/llm-gateway), whatever your plan. Asking by default requires Claude Code v2.1.278 or later.

371* **A signed-in [Claude apps gateway](https://code.claude.com/docs/en/claude-apps-gateway) session**: requires Claude Code v2.1.280 or later372* **A signed-in [Claude apps gateway](https://code.claude.com/docs/en/claude-apps-gateway) session**: requires Claude Code v2.1.280 or later

373* **A [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md) in an Anthropic-hosted environment**: whatever your plan, when you start it from the web, the mobile app, or the desktop app with **Cloud** selected. Sessions started by a [cloud scheduled task](https://code.claude.com/docs/en/routines.md) ask the server as Anthropic rolls it out.

372 374 

373Where the server reviews the actions, its verdicts decide them. Two other outcomes are possible:375Where the server reviews the actions, its verdicts decide them. Two other outcomes are possible:

374 376 


647 649 

648`bypassPermissions` mode disables permission prompts and safety checks so tool calls execute immediately, including writes to [protected paths](#protected-paths).650`bypassPermissions` mode disables permission prompts and safety checks so tool calls execute immediately, including writes to [protected paths](#protected-paths).

649 651 

650The [actions no mode auto-approves](#actions-no-mode-auto-approves) still prompt in this mode. Reading [another organization's public artifact](https://code.claude.com/docs/en/artifacts.md#read-an-artifact-shared-with-you) needs your approval, and this mode doesn't ask for it, so Claude can't read one. The [Remove-Item in PowerShell](#remove-item-in-powershell) denies also apply in this mode.652Even in `bypassPermissions` mode, each of the [actions no mode auto-approves](#actions-no-mode-auto-approves) gets a prompt or a denial instead of running on its own. Reading [another organization's public artifact](https://code.claude.com/docs/en/artifacts.md#read-an-artifact-shared-with-you) needs your approval, and this mode doesn't ask for it, so Claude can't read one. The [Remove-Item in PowerShell](#remove-item-in-powershell) denies also apply in this mode.

651 653 

652Two [cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md) safeguards still apply in this mode, and in interactive terminal plan-mode sessions where bypass permissions are available:654Two [cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md) safeguards still apply in this mode, and in interactive terminal plan-mode sessions where bypass permissions are available:

653 655 


769* `.devcontainer.json`771* `.devcontainer.json`

770* `.ripgreprc`, `pyrightconfig.json`772* `.ripgreprc`, `pyrightconfig.json`

771* `.mcp.json`, `.claude.json`773* `.mcp.json`, `.claude.json`

774* A file you passed to [`--settings`](https://code.claude.com/docs/en/cli-reference#cli-flags), `--mcp-config`, or `--agents` when you started the session

772* The file that your user, project, or local [settings file](https://code.claude.com/docs/en/settings.md#settings-files-and-who-they-affect) points to when the settings file is itself a symbolic link, for example into a dotfiles repository. In the modes that route protected-path writes to the classifier, a write to this file prompts you instead, even when an allow rule matches. If the file's own path is also that of a settings file, such as `.claude/settings.json` in another folder, the write goes to the classifier as other protected-path writes do775* The file that your user, project, or local [settings file](https://code.claude.com/docs/en/settings.md#settings-files-and-who-they-affect) points to when the settings file is itself a symbolic link, for example into a dotfiles repository. In the modes that route protected-path writes to the classifier, a write to this file prompts you instead, even when an allow rule matches. If the file's own path is also that of a settings file, such as `.claude/settings.json` in another folder, the write goes to the classifier as other protected-path writes do

773 776 

774## Critical paths777## Critical paths


844 847 

845For a glob or trailing slash under a variable, the prompt names the flagged `rm` and says how to rewrite it so the check passes.848For a glob or trailing slash under a variable, the prompt names the flagged `rm` and says how to rewrite it so the check passes.

846 849 

850### The `Dangerous rm operation not ruled out` prompt

851 

852The full reason reads:

853 

854```text theme={null}

855Dangerous rm operation not ruled out — the shell may read this command differently than it was parsed

856```

857 

858This reason means the shell may read the command differently than Claude Code did, so a removal could sit in an unchecked part, even with no `rm` present. In `auto` or `bypassPermissions` mode, a denial with this sentence comes from the same check:

859 

860```text theme={null}

861This command could not be checked for dangerous rm operations: the shell may read it differently than it was parsed.

862```

863 

864You get the prompt or denial a critical-path removal gets [in your permission mode](#critical-path-removals-in-each-permission-mode), `bypassPermissions` included. You can't approve the command with a `Bash` or `Bash(*)` allow rule, sandbox [auto-allow mode](https://code.claude.com/docs/en/sandboxing.md#auto-allow-mode), or a `PreToolUse` hook returning `"allow"`. Read the command, then approve the prompt or, after a denial, run it in your shell.

865 

847### The mounted drive prompt866### The mounted drive prompt

848 867 

849The mounted drive prompt appears on macOS, Linux, and WSL when a recursive `rm` targets a listed [mounted drive path](#paths-that-get-the-mounted-drive-prompt), such as `/mnt/c` or `/Volumes/USB/build`. Its reason reads `Dangerous rm operation on mounted drive path: <path>`. A `/*` target gets the prompt without the recursive flag, since Claude Code reads `rm /Volumes/USB/build/*` as a removal of `/Volumes/USB/build`.868The mounted drive prompt appears on macOS, Linux, and WSL when a recursive `rm` targets a listed [mounted drive path](#paths-that-get-the-mounted-drive-prompt), such as `/mnt/c` or `/Volumes/USB/build`. Its reason reads `Dangerous rm operation on mounted drive path: <path>`. A `/*` target gets the prompt without the recursive flag, since Claude Code reads `rm /Volumes/USB/build/*` as a removal of `/Volumes/USB/build`.


900| `plan` | Asks you to approve it. When [the classifier reviews commands during planning](#analyze-before-you-edit-with-plan-mode) and no bypass permissions are available, handles it as in `auto` mode |919| `plan` | Asks you to approve it. When [the classifier reviews commands during planning](#analyze-before-you-edit-with-plan-mode) and no bypass permissions are available, handles it as in `auto` mode |

901| `auto` | Asks you to approve it in the terminal, with a [time limit](#time-limits-and-denials-in-auto-and-bypasspermissions-modes). Elsewhere, denies it |920| `auto` | Asks you to approve it in the terminal, with a [time limit](#time-limits-and-denials-in-auto-and-bypasspermissions-modes). Elsewhere, denies it |

902| `dontAsk` | Denies it |921| `dontAsk` | Denies it |

903| `bypassPermissions` | Asks you to approve it, with a time limit in the terminal |922| `bypassPermissions` | In the terminal, asks you to approve it before a time limit runs out. Elsewhere, see [what happens in each place](#time-limits-and-denials-in-auto-and-bypasspermissions-modes) |

904 923 

905If an explicit [ask rule](https://code.claude.com/docs/en/permissions.md#manage-permissions) matches the command, Claude Code asks you instead, even in `auto` mode and without a time limit. In modes that ask, a [`PermissionRequest` hook](https://code.claude.com/docs/en/hooks#permissionrequest) can answer the prompt.924If an explicit [ask rule](https://code.claude.com/docs/en/permissions.md#manage-permissions) matches the command, Claude Code asks you instead, even in `auto` mode and without a time limit. In modes that ask, a [`PermissionRequest` hook](https://code.claude.com/docs/en/hooks#permissionrequest) can answer the prompt.

906 925 


912* Press any key while the prompt is open to stop the countdown and keep the prompt waiting for your answer.931* Press any key while the prompt is open to stop the countdown and keep the prompt waiting for your answer.

913* After three of these prompts run out unanswered in a session, Claude Code stops showing them and denies further critical-path removals immediately. Sending a new message starts the count over.932* After three of these prompts run out unanswered in a session, Claude Code stops showing them and denies further critical-path removals immediately. Sending a new message starts the count over.

914 933 

915In `auto` mode, wherever Claude Code can't show you a terminal prompt, it denies the command immediately, for example in [non-interactive runs](https://code.claude.com/docs/en/headless.md) with `-p`, in [Agent SDK](https://code.claude.com/docs/en/agent-sdk/permissions.md) sessions, and in the VS Code extension's chat panel and the Desktop app. The denial tells Claude to report what it wanted to delete and leave the removal to you.934The time limit applies in Claude Code v2.1.281 and later, and so does the `auto` mode denial outside the terminal.

935 

936Away from the terminal, you don't get that prompt:

916 937 

917The `auto` and `bypassPermissions` handling requires Claude Code v2.1.281 or later. To turn it off, set [`CLAUDE_CODE_DISABLE_DANGEROUS_RM_TIMEOUT=1`](https://code.claude.com/docs/en/env-vars#variables) in the environment that launches Claude Code. In `auto` mode, critical-path removals then go to the classifier instead, and in `bypassPermissions` mode the prompt has no time limit.938| Where | `auto` | `bypassPermissions` |

939| :- | :- | :- |

940| [VS Code extension](https://code.claude.com/docs/en/vs-code.md)'s chat panel | Denies it | Denies it unless a [`PermissionRequest` hook](https://code.claude.com/docs/en/hooks#permissionrequest) allows it |

941| [Desktop app](https://code.claude.com/docs/en/desktop.md) | Denies it | Denies it unless a `PermissionRequest` hook allows it |

942| [`-p` run](https://code.claude.com/docs/en/headless) or [Agent SDK session](https://code.claude.com/docs/en/agent-sdk/permissions.md) | Denies it | Your [`--permission-prompt-tool`](https://code.claude.com/docs/en/cli-reference#cli-flags) or [`canUseTool` callback](https://code.claude.com/docs/en/agent-sdk/user-input#handle-tool-approval-requests) decides. With neither, or under [`--permission-prompts none`](https://code.claude.com/docs/en/headless#turn-off-permission-prompts-in-unattended-runs), denies it unless a `PermissionRequest` hook allows it |

943 

944Wherever the removal is denied, you can read the whole command and run it in your shell.

945 

946To change what you get in each mode, set [`CLAUDE_CODE_DISABLE_DANGEROUS_RM_TIMEOUT`](https://code.claude.com/docs/en/env-vars#variables) to `1`:

947 

948* **`bypassPermissions`**: the terminal prompt has no time limit, and the VS Code chat panel asks you

949* **`auto`**: the [classifier](#eliminate-prompts-with-auto-mode) decides, in the terminal, the VS Code chat panel, `-p` runs and Agent SDK sessions

950 

951Set it in the environment that starts Claude Code, such as your shell or the SDK's `env` option, not in a Claude Code settings file. For the chat panel, add it to [`claudeCode.environmentVariables`](https://code.claude.com/docs/en/vs-code#extension-settings) in VS Code's own user `settings.json`, then start a new conversation:

952 

953```json theme={null}

954{

955 "claudeCode.environmentVariables": [

956 { "name": "CLAUDE_CODE_DISABLE_DANGEROUS_RM_TIMEOUT", "value": "1" }

957 ]

958}

959```

918 960 

919### Remove-Item in PowerShell961### Remove-Item in PowerShell

920 962 

Details

41 41 

42If a tutorial or an older set of instructions tells you to run `/plugin marketplace add anthropics/claude-code`, that adds the demo marketplace, named `claude-code-plugins`. It isn't the official marketplace.42If a tutorial or an older set of instructions tells you to run `/plugin marketplace add anthropics/claude-code`, that adds the demo marketplace, named `claude-code-plugins`. It isn't the official marketplace.

43 43 

44Most of the demo marketplace's plugins are also in the official marketplace under the same names. For example, `code-review`, `feature-dev`, `commit-commands`, and `security-guidance` are in both. Install those from `claude-plugins-official` so you don't have two copies installed.44Most of the demo marketplace's plugins are also in the official marketplace under the same names. For example, `code-review`, `feature-dev`, and `commit-commands` are in both. Install those from `claude-plugins-official` so you don't have two copies installed.

45 45 

46## Find plugins in the official marketplace46## Find plugins in the official marketplace

47 47 

Details

403 403 

404For version ranges, the `<plugin>--v<version>` git-tag convention they resolve against, and cross-marketplace trust, see [Plugin dependencies](https://code.claude.com/docs/en/plugins/dependencies.md).404For version ranges, the `<plugin>--v<version>` git-tag convention they resolve against, and cross-marketplace trust, see [Plugin dependencies](https://code.claude.com/docs/en/plugins/dependencies.md).

405 405 

406To have Claude Code suggest a plugin when a project matches it, add a `relevance` block to the entry with the signals that identify the project. Users see suggestions from your marketplace only when an admin lists it in `pluginSuggestionMarketplaces`. For the signals and the enablement step, see [Plugin relevance](https://code.claude.com/docs/en/plugins/relevance.md).406To have Claude Code suggest a plugin when a project matches it, add a `relevance` block to the entry with the signals that identify the project. Users see these suggestions only when an admin lists your marketplace in `pluginSuggestionMarketplaces`. For the signals and the enablement step, see [Plugin relevance](https://code.claude.com/docs/en/plugins/relevance.md).

407 407 

408## Work around what a marketplace can't do408## Work around what a marketplace can't do

409 409 

Details

95 95 

96None of these controls sandboxes a mod. A mod you allow runs as the user, with the user's access to files, processes, and the network.96None of these controls sandboxes a mod. A mod you allow runs as the user, with the user's access to files, processes, and the network.

97 97 

98### Know which hooks of a user's mod don't run

99 

100Where the [built-in guard](#know-what-happens-by-default) loads, a hook that a user's mod registers on one of these events never runs, and `/plugin` tells that user so in a note. In the [`session.append`](https://code.claude.com/docs/en/plugins/mods/reference#session) rows, `door` is the kind of stored row the hook is filtered to.

101 

102| Hook on | What the event is |

103| :- | :- |

104| [`classic.<Event>`](https://code.claude.com/docs/en/plugins/mods/events#hook-the-settings-hook-events), such as `classic.Stop` | A [settings hook event](https://code.claude.com/docs/en/hooks.md#hook-events) |

105| [`prompt.compose`](https://code.claude.com/docs/en/plugins/mods/reference#prompts-and-what-claude-reads) | The system prompt's list of sections |

106| `prompt.section` | One section of the system prompt |

107| `prompt.context` | The context sent with a conversation's first message |

108| `prompt.attachment` | A message Claude Code adds for Claude, such as a reminder |

109| `skill.prompt` | A skill's text as it's expanded for Claude |

110| `attribution.text` | Commit or pull request attribution text |

111| [`session.compact`](https://code.claude.com/docs/en/plugins/mods/reference#session) | A compaction of the conversation |

112| `settings.read` | A read of settings, such as a mod's `$.settings.read` call |

113| `session.append{door=attachment}` | The stored row for a message Claude Code adds for Claude |

114| `session.append{door=hook-context}` | The stored row for context from a settings hook |

115| `session.append{door=compaction}` | The stored rows for a compaction's summary and boundary |

116 

117The guard also passes over a user's hooks in some other cases, such as the descriptions of your organization's tools, on [`tool.describe`](https://code.claude.com/docs/en/plugins/mods/reference#tools), and the stored row for a skill's text. `/plugin` shows no note for those. If a hook on another event does nothing, see [Find out why a mod does nothing](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#find-out-why-a-mod-does-nothing).

118 

119The note appears in the plugin's details and in the **Errors** tab of `/plugin`. It requires Claude Code v2.1.299 or later. It names each hook from the table as the mod registered it, as in this example:

120 

121```text theme={null}

122Its hooks on classic.Stop, prompt.section do not run here: where an organization manages Claude Code, these events pass over the plugins you install

123Only a plugin that counts as your organization's own runs hooks on these events. An administrator sets that up in managed settings

124```

125 

126To let these hooks run, change managed settings in one of two ways:

127 

128* **Run the mod as your organization's**: [install the mod so that it counts as yours](#install-your-organizations-mods). Its hooks on these events then run, and the guard stays loaded for every other mod. The mod turns on for everyone who receives these settings, and it has to sit in a directory you place on each machine. If you list it in `prependPlugins`, keep `sec-default@builtin` in the list.

129* **Remove the guard**: leave `sec-default@builtin` out of `prependPlugins`. An empty list, `"prependPlugins": []`, is enough. You lose the whole guard, not only these events. A user's mod can then do what [the guard otherwise stops it from doing](#know-what-happens-by-default), and [the guard's options](#set-options-on-the-built-in-guard) don't apply.

130 

131If you deliver a list without the guard through [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md#fetch-and-caching-behavior), the guard stays loaded until the server confirms the settings for the session. To confirm either change on a machine that runs v2.1.299 or later, open `/plugin` in a session there and check that the note is gone.

132 

133A `session.append` hook with no `door` filter still runs and gets no note, but the stored rows in the table don't reach it.

134 

98## Decide whether to leave mods on135## Decide whether to leave mods on

99 136 

100A mod can do more than the other parts of a plugin because it runs inside Claude Code. It sees every prompt and tool call, can change them, and can allow or deny a tool call before a permission prompt appears.137A mod can do more than the other parts of a plugin because it runs inside Claude Code. It sees every prompt and tool call, can change them, and can allow or deny a tool call before a permission prompt appears.


142| `$.prompt.submit` | Submits a prompt, and can send it as the user's own words |179| `$.prompt.submit` | Submits a prompt, and can send it as the user's own words |

143| `$.session.send` | Sends a message that another session's, subagent's, or [teammate's](https://code.claude.com/docs/en/agent-teams.md) Claude reads |180| `$.session.send` | Sends a message that another session's, subagent's, or [teammate's](https://code.claude.com/docs/en/agent-teams.md) Claude reads |

144 181 

145In the `hooks:` line, [`tool.call`](https://code.claude.com/docs/en/plugins/mods/reference#tools) and [`prompt.submit`](https://code.claude.com/docs/en/plugins/mods/reference#prompts-and-what-claude-reads) mean the mod sees every tool call and every prompt, and can change them. [`session.append`](https://code.claude.com/docs/en/plugins/mods/reference#session) means the mod can rewrite each row of the conversation before it's stored. [`ui.render{component=AskUserQuestion}`](https://code.claude.com/docs/en/plugins/mods/interface#change-what-claude-code-already-draws) means the mod can redraw the dialog Claude uses to ask the user a question. `tool.check` means the mod can approve or deny a tool call before a permission prompt appears. [Know what happens by default](#know-what-happens-by-default) lists which of your rules and hooks take precedence over its answer.182In the `hooks:` line, [`tool.call`](https://code.claude.com/docs/en/plugins/mods/reference#tools) and [`prompt.submit`](https://code.claude.com/docs/en/plugins/mods/reference#prompts-and-what-claude-reads) mean the mod sees every tool call and every prompt, and can change them. [`session.append`](https://code.claude.com/docs/en/plugins/mods/reference#session) means the mod can rewrite each row of the conversation before it's stored, apart from [the rows the guard passes over](#hooks-the-guard-passes-over). [`ui.render{component=AskUserQuestion}`](https://code.claude.com/docs/en/plugins/mods/interface#change-what-claude-code-already-draws) means the mod can redraw the dialog Claude uses to ask the user a question. `tool.check` means the mod can approve or deny a tool call before a permission prompt appears. [Know what happens by default](#know-what-happens-by-default) lists which of your rules and hooks take precedence over its answer.

146 183 

147## Choose how much to allow184## Choose how much to allow

148 185 

Details

377 377 

378### Handle the settings hook events378### Handle the settings hook events

379 379 

380Settings hooks are the command, HTTP, prompt, and agent hooks you configure in settings files. Each [settings hook event](https://code.claude.com/docs/en/hooks.md#hook-events), such as `Stop`, `SessionEnd`, or `PostToolUse`, is also an event named `classic.` followed by the settings hook event's name, such as `classic.Stop`. `e` is the JSON a settings hook receives on stdin, including `transcript_path`.380Settings hooks are the command, HTTP, prompt, and agent hooks you configure in settings files. Each [settings hook event](https://code.claude.com/docs/en/hooks.md#hook-events), such as `Stop`, `SessionEnd`, or `PostToolUse`, is also an event named `classic.` followed by the settings hook event's name, such as `classic.Stop`. `e` is the JSON a settings hook receives on stdin, including `transcript_path`. Where the [built-in guard](https://code.claude.com/docs/en/plugins/mods/admin.md#know-what-happens-by-default) loads, [a hook on these events in a mod you install doesn't run](https://code.claude.com/docs/en/plugins/mods/admin.md#hooks-the-guard-passes-over).

381 381 

382This hook uses `Stop`, which fires when Claude finishes responding, to log where the session's transcript is saved:382This hook uses `Stop`, which fires when Claude finishes responding, to log where the session's transcript is saved:

383 383 


425* **It failed before calling `next`**: Claude Code skips it, and the next handler runs in its place425* **It failed before calling `next`**: Claude Code skips it, and the next handler runs in its place

426* **It failed after `next` resolved**: that result stands, and nothing runs a second time426* **It failed after `next` resolved**: that result stands, and nothing runs a second time

427 427 

428One line names the mod, the event, and the reason, such as `my-mod: tool.call hook skipped: threw Error: boom`. Where you read it depends on the session, as [Find out why a mod does nothing](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#find-out-why-a-mod-does-nothing) lists. A `ui.render` hook whose drawing doesn't validate is reported differently, as [Build a tree from elements](https://code.claude.com/docs/en/plugins/mods/interface.md#build-a-tree-from-elements) describes.428One line names the mod, the event, and the reason, such as `my-mod: tool.call hook skipped: threw Error: boom`. Where you read it depends on the session, as [Find out why a mod does nothing](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#find-out-why-a-mod-does-nothing) lists. A `ui.render` hook whose [tree doesn't validate](https://code.claude.com/docs/en/plugins/mods/interface.md#build-a-tree-from-elements) counts as one that returned the wrong shape.

429 429 

430To make a hook that blocks calls fail closed, add a `.catch` error handler that answers in its place. Here, `guard` is your hook function, and the handler tests [`next.called`](https://code.claude.com/docs/en/plugins/mods/reference#the-hook-function) to tell whether `guard` had already called `next` when it failed:430To make a hook that blocks calls fail closed, add a `.catch` error handler that answers in its place. Here, `guard` is your hook function, and the handler tests [`next.called`](https://code.claude.com/docs/en/plugins/mods/reference#the-hook-function) to tell whether `guard` had already called `next` when it failed:

431 431 

Details

421Note: Type a note and press Enter421Note: Type a note and press Enter

422```422```

423 423 

424Add `rows` to let the field hold several lines. Enter still submits, and a backslash before Enter starts a new line, as does Shift+Enter where [the terminal supports it](https://code.claude.com/docs/en/terminal-config.md#enter-multiline-prompts). The gallery shows [a field with `rows`](https://code.claude.com/docs/en/plugins/mods/gallery#input).

425 

424The [interface gallery](https://code.claude.com/docs/en/plugins/mods/gallery.md) has samples and screenshots of most elements. This table lists every element:426The [interface gallery](https://code.claude.com/docs/en/plugins/mods/gallery.md) has samples and screenshots of most elements. This table lists every element:

425 427 

426| Element | What it draws | Where |428| Element | What it draws | Where |


436 438 

437If your module is a `.tsx` or `.jsx` file, you can write the tree as JSX. Destructure the elements from `$.ui.resolve(e)` first.439If your module is a `.tsx` or `.jsx` file, you can write the tree as JSX. Destructure the elements from `$.ui.resolve(e)` first.

438 440 

439If a tree uses an element the app doesn't have, a prop an element doesn't take, or a child where none goes, Claude Code draws its own version of the site.441If your drawing doesn't show up, check its tree for a prop an element doesn't take or a child where none goes. A hook that returns such a tree [fails](https://code.claude.com/docs/en/plugins/mods/events.md#handle-a-hook-that-fails), and a [`hook skipped` line](https://code.claude.com/docs/en/plugins/mods/troubleshoot#a-pane-or-band-is-empty) names your mod and the rule the tree broke. For a `Text` in a pane with a prop named `bogusProp`, that line reads:

440 442 

441In a session started with `--plugin-dir`, a transcript line says so, such as `ui.render (Pane) refused: Text prop "bogusProp" is not allowed; the engine drew its own`. The [debug log](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#read-the-debug-log) records it as `ui.render (Pane): a hook returned a tree that does not validate` with the same reason. Nothing else appears in the session, so when a drawing doesn't show up, check that line or the log.443```text theme={null}

444my-mod: ui.render hook skipped: returned the wrong shape (a tree Pane refuses: Text prop "bogusProp" is not allowed)

445```

442 446 

443### `Link` in the Desktop app and VS Code447### `Link` in the Desktop app and VS Code

444 448 


542| Key | What it does |546| Key | What it does |

543| :- | :- |547| :- | :- |

544| Tab | Moves to the next control |548| Tab | Moves to the next control |

545| Up and Down | Move between controls while your drawing fits. When the pane or band has more rows than it can show, they scroll it. |549| Up and Down | Move between controls while your drawing fits. When the pane or band has more rows than it can show, they scroll it. In an `Input`, they [move between the field's rows](https://code.claude.com/docs/en/plugins/mods/gallery.md#input) first. |

546| Enter | Presses the focused `Button`, submits the focused `Input`, or picks in a `Select` |550| Enter | Presses the focused `Button`, submits the focused `Input`, or picks in a `Select` |

547| A button's hotkey | Presses that button. While an `Input` has the focus, every printable key goes to the field. |551| A button's hotkey | Presses that button. While an `Input` has the focus, every printable key goes to the field. |

548| Page Up, Page Down, Home, and End | Scroll your pane or band when it has more rows than it can show |552| Page Up, Page Down, Home, and End | Scroll your pane or band when it has more rows than it can show |

Details

275| [`Link`](https://code.claude.com/docs/en/plugins/mods/interface#link-in-the-desktop-app) | `href`, `label`. See [Limits](#limits). | ✓ | ✓ | ✓ |275| [`Link`](https://code.claude.com/docs/en/plugins/mods/interface#link-in-the-desktop-app) | `href`, `label`. See [Limits](#limits). | ✓ | ✓ | ✓ |

276| [`Code`](https://code.claude.com/docs/en/plugins/mods/gallery#show-code-and-changes) | `source`, `language`, `path`, `startLine`, `format`, `wrap` | ✓ | ✓ | ✓ |276| [`Code`](https://code.claude.com/docs/en/plugins/mods/gallery#show-code-and-changes) | `source`, `language`, `path`, `startLine`, `format`, `wrap` | ✓ | ✓ | ✓ |

277| `Markdown` | `text`, `key`, `dimColor`, `onLinkPress`, `pressableLinks` | ✓ | ✓ | ✓ |277| `Markdown` | `text`, `key`, `dimColor`, `onLinkPress`, `pressableLinks` | ✓ | ✓ | ✓ |

278| [`Input`](https://code.claude.com/docs/en/plugins/mods/interface#take-typed-input-and-draw-a-row-for-each-item) | `key`, `label`, `placeholder`, `value`, `submitLabel`, `onSubmit`, `onInput`, `autoFocus` | ✓ | ✓ | ✓ |278| [`Input`](https://code.claude.com/docs/en/plugins/mods/interface#take-typed-input-and-draw-a-row-for-each-item) | `key`, `label`, `placeholder`, `value`, `submitLabel`, [`rows`](https://code.claude.com/docs/en/plugins/mods/gallery#input), `onSubmit`, `onInput`, `autoFocus` | ✓ | ✓ | ✓ |

279| `Select` | `key`, `label`, `options`, `value`, `onSelect`, `autoFocus` | ✓ | ✓ | ✓ |279| `Select` | `key`, `label`, `options`, `value`, `onSelect`, `autoFocus` | ✓ | ✓ | ✓ |

280| `Svg` | a `source` of SVG markup up to 131,072 characters, `alt` text, `width`, `height`, and `isInteractive` | | ✓ | ✓ |280| `Svg` | a `source` of SVG markup up to 131,072 characters, `alt` text, `width`, `height`, and `isInteractive` | | ✓ | ✓ |

281| [`Client`](https://code.claude.com/docs/en/plugins/mods/interface#build-a-tree-from-elements) | `module`, `key`, `props`, `width`, `height`, `flexGrow` | ✓ | ✓ | |281| [`Client`](https://code.claude.com/docs/en/plugins/mods/interface#build-a-tree-from-elements) | `module`, `key`, `props`, `width`, `height`, `flexGrow` | ✓ | ✓ | |


333 333 

334If you set `gap`, `padding`, or `margin` to a step, the step applies across and down at once. For example, in the terminal and the VS Code extension, `padding: 'md'` is two cells at each side and one row above and below.334If you set `gap`, `padding`, or `margin` to a step, the step applies across and down at once. For example, in the terminal and the VS Code extension, `padding: 'md'` is two cells at each side and one row above and below.

335 335 

336Step names require Claude Code v2.1.299 or later. On an earlier release, Claude Code [draws its own version of the site](https://code.claude.com/docs/en/plugins/mods/interface.md#build-a-tree-from-elements) in place of a tree that uses a step name.336Step names require Claude Code v2.1.299 or later. On an earlier release, a tree that uses a step name doesn't draw.

337 337 

338### `Text` typography props338### `Text` typography props

339 339 


346| `mono` | `true` to ask for the app's monospaced typeface | Ignored: the terminal is always monospaced | Ignored, so text keeps the extension's own typeface |346| `mono` | `true` to ask for the app's monospaced typeface | Ignored: the terminal is always monospaced | Ignored, so text keeps the extension's own typeface |

347| `tabular` | `true` to ask for digits of equal width, so that a number that updates in place or a column of numbers stays aligned | Ignored: the terminal's digits are already one cell wide | Ignored |347| `tabular` | `true` to ask for digits of equal width, so that a number that updates in place or a column of numbers stays aligned | Ignored: the terminal's digits are already one cell wide | Ignored |

348 348 

349These four props require Claude Code v2.1.299 or later. On an earlier release, Claude Code [draws its own version of the site](https://code.claude.com/docs/en/plugins/mods/interface.md#build-a-tree-from-elements) in place of a tree that sets `size`, `weight`, `mono`, or `tabular`.349These four props require Claude Code v2.1.299 or later. On an earlier release, a tree that sets `size`, `weight`, `mono`, or `tabular` doesn't draw.

350 350 

351#### Replace `bold` with `weight`351#### Replace `bold` with `weight`

352 352 

353`bold` on a `Text` is deprecated in favor of `weight` and still works. To replace it on a `Text` with no `weight`, change `bold: true` to `weight: 'semibold'` for the same result on Claude Code v2.1.299 or later.353`bold` on a `Text` is deprecated in favor of `weight` and still works. To replace it on a `Text` with no `weight`, change `bold: true` to `weight: 'semibold'` for the same result on Claude Code v2.1.299 or later.

354 354 

355On a release earlier than v2.1.299, a tree that sets `weight` doesn't draw, and Claude Code [draws its own version of the site](https://code.claude.com/docs/en/plugins/mods/interface.md#build-a-tree-from-elements) instead. If you set both `bold` and `weight` on a `Text`, `bold` has no effect.355On a release earlier than v2.1.299, a tree that sets `weight` doesn't draw. If you set both `bold` and `weight` on a `Text`, `bold` has no effect.

356 356 

357## Limits357## Limits

358 358 

359Hooks and mods API calls run under time and size limits. Claude Code skips a hook that exceeds a time limit.359Hooks and mods API calls run under time and size limits. Claude Code skips a hook that exceeds a time limit. A tree over the nesting, element, `Raster` cell, or `Image` byte limit [isn't drawn](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#a-pane-or-band-is-empty).

360 360 

361| Limit | Value |361| Limit | Value |

362| :- | :- |362| :- | :- |


372| Redirects one `$.http.fetch` call follows | 5 |372| Redirects one `$.http.fetch` call follows | 5 |

373| A hook's `drop` reason or `config.set` `deny` reason | 4,096 characters. The end of a longer reason is cut, and the drop or deny still applies. The cut requires Claude Code v2.1.292 or later, and on earlier versions the hook [fails](https://code.claude.com/docs/en/plugins/mods/events.md#handle-a-hook-that-fails) instead. |373| A hook's `drop` reason or `config.set` `deny` reason | 4,096 characters. The end of a longer reason is cut, and the drop or deny still applies. The cut requires Claude Code v2.1.292 or later, and on earlier versions the hook [fails](https://code.claude.com/docs/en/plugins/mods/events.md#handle-a-hook-that-fails) instead. |

374| Text in one tree | The first 100,000 characters are drawn |374| Text in one tree | The first 100,000 characters are drawn |

375| A `Code`'s `language` or `path`, a `Select` option's `value`, or a `Client`'s `module` | 10,000 characters. If one is longer, Claude Code [draws its own version of the site](https://code.claude.com/docs/en/plugins/mods/interface.md#build-a-tree-from-elements). |375| A `Code`'s `language` or `path`, a `Select` option's `value`, or a `Client`'s `module` | 10,000 characters. If one is longer, the `ui.render` hook that returned it [fails](https://code.claude.com/docs/en/plugins/mods/events.md#handle-a-hook-that-fails). |

376| A `Link`'s `href` | 2,048 characters. A longer `href` keeps the whole tree from drawing. |376| A `Link`'s `href` | 2,048 characters. If it's longer, the `ui.render` hook that returned it [fails](https://code.claude.com/docs/en/plugins/mods/events.md#handle-a-hook-that-fails). |

377| Nesting depth of one tree | 32 levels below the root element |

378| Elements and text children in one tree | 20,000 |

379| `Raster` cells in one tree, each `Raster`'s `columns` times its `rows` | 262,144 |

380| PNG or RGBA bytes of all the `Image`s in one tree | 2 MiB |

377| `$.store` | 4 MiB of JSON in total |381| `$.store` | 4 MiB of JSON in total |

378| `$.session.messages()` | The newest 4,096 entries |382| `$.session.messages()` | The newest 4,096 entries |

379| `$.ui.invalidate('ui.render')` redraws | Throttled to 10 a second, or 30 in the terminal for the visible pane, the expanded band, and the hint line under the prompt. Calls that come sooner are coalesced. |383| `$.ui.invalidate('ui.render')` redraws | Throttled to 10 a second, or 30 in the terminal for the visible pane, the expanded band, and the hint line under the prompt. Calls that come sooner are coalesced. |

Details

312| Method | What it does |312| Method | What it does |

313| :- | :- |313| :- | :- |

314| `press({ key: 'more' })` | Presses the `Button` with that key |314| `press({ key: 'more' })` | Presses the `Button` with that key |

315| `input({ key: 'new-note', text: 'buy milk' })` | Types the text into the `Input` with that key and presses Enter. Add `kind: 'change'` to type without submitting. |315| `input({ key: 'new-note', text: 'buy milk' })` | Types the text into the `Input` with that key and presses Enter. Add `kind: 'change'` to type without submitting. For a field with `rows`, the text can hold `\n`. |

316| `select({ key: 'size', value: 'large' })` | Picks the option with that value in the `Select` with that key |316| `select({ key: 'size', value: 'large' })` | Picks the option with that value in the `Select` with that key |

317| `find({ key: 'more' })` or `find({ type: 'Text', text: 'Count: 2' })` | Returns the first matching element as `{ type, props, children }`, or `undefined`. `text` can be a string or a regular expression. |317| `find({ key: 'more' })` or `find({ type: 'Text', text: 'Count: 2' })` | Returns the first matching element as `{ type, props, children }`, or `undefined`. `text` can be a string or a regular expression. |

318| `unmount()` | Removes the drawing |318| `unmount()` | Removes the drawing |

319 319 

320Each method resolves after your handler has finished, so you can check the result on the next line. Set `props` to what Claude Code would pass for that site. The [render sites table](https://code.claude.com/docs/en/plugins/mods/reference.md#render-sites) lists each site's props, and [the types for your build](https://code.claude.com/docs/en/plugins/mods/create.md#get-the-types-for-your-build) have their types.320Each method resolves after your handler has finished, so you can check the result on the next line. Set `props` to what Claude Code would pass for that site. The [render sites table](https://code.claude.com/docs/en/plugins/mods/reference.md#render-sites) lists each site's props, and [the types for your build](https://code.claude.com/docs/en/plugins/mods/create.md#get-the-types-for-your-build) have their types.

321 321 

322A drawing test checks the tree your hook returns and whether it's valid for that app. It doesn't check how the app paints it, so look at a new layout in a real session as well.322To catch an [element tree](https://code.claude.com/docs/en/plugins/mods/interface.md#build-a-tree-from-elements) that isn't valid for the app you named in `surface`, check with `find` for an element your hook adds. The test doesn't check how the app paints a tree, so look at a new layout in a real session too.

323 323 

324### Test a drawing after `/clear`324### Test a drawing after `/clear`

325 325 

Details

226 226 

227To find that mod, [write a debug log](#read-the-debug-log) and search it for `answered ui.render without next()`. A line such as `other-mod (user) answered ui.render without next()` names a mod that returned its tree without calling `next(e)`. It doesn't name the [render site](https://code.claude.com/docs/en/plugins/mods/reference.md#render-sites), so a pane-only mod can appear too. A mod that calls `next(e)` and drops the result gets no line, so check the hooks before yours too.227To find that mod, [write a debug log](#read-the-debug-log) and search it for `answered ui.render without next()`. A line such as `other-mod (user) answered ui.render without next()` names a mod that returned its tree without calling `next(e)`. It doesn't name the [render site](https://code.claude.com/docs/en/plugins/mods/reference.md#render-sites), so a pane-only mod can appear too. A mod that calls `next(e)` and drops the result gets no line, so check the hooks before yours too.

228 228 

229After the change, you see nothing in the band if any of the mods returns a tree that doesn't validate. To read the reason, look for a `ui.render (AbovePrompt) refused:` line in the transcript of a `--plugin-dir` session, or search the debug log for `does not validate`. With several mods in the band, neither line names a mod, so check each mod's tree.229A mod's band is also missing when the tree its own hook returned doesn't validate, and the other mods' bands stay. To find which mod and why, [write a debug log](#read-the-debug-log) and search it for [`ui.render hook skipped`](#a-pane-or-band-is-empty).

230 230 

231### A pane or band is empty or shows Claude Code's usual content231### A pane or band is empty or shows Claude Code's usual content

232 232 

233The [tree](https://code.claude.com/docs/en/plugins/mods/interface.md#build-a-tree-from-elements) your hook returned didn't validate. With `--plugin-dir`, the transcript says `ui.render (Pane) refused:` with the reason, as in `first-mod: ui.render (Pane) refused: Box prop "flexDirection" must be one of row, column, row-reverse, column-reverse; the engine drew its own`. The debug log has `a hook returned a tree that does not validate` with the same reason.233The [tree](https://code.claude.com/docs/en/plugins/mods/interface.md#build-a-tree-from-elements) your hook returned didn't validate. A [`hook skipped`](#hook-skipped) line [in the transcript or the debug log](#find-out-why-a-mod-does-nothing) names your mod and the reason, as in this one for a `Box` in a pane:

234 234 

235Read the reason on that line. Common causes are a prop the element doesn't take and an element the app doesn't have.235```text theme={null}

236first-mod: ui.render hook skipped: returned the wrong shape (a tree Pane refuses: Box prop "flexDirection" must be one of row, column, row-reverse, column-reverse)

237```

238 

239Fix what the reason names. If the reason is cut short, [write a debug log](#read-the-debug-log) and search it for `a hook returned a tree that does not validate` to read the rest.

240 

241If the line instead says `refused:` right after the site's name, as in `ui.render (Pane) refused:`, see [A `ui.render` line says `refused`](#ui-render-refused).

242 

243### A `ui.render` line says `refused`

244 

245`ui.render (<site>) refused:`, or `ui.render (<site>): the chain settled on a tree that does not validate` in the [debug log](#read-the-debug-log), means the [tree](https://code.claude.com/docs/en/plugins/mods/interface.md#build-a-tree-from-elements) at that site exceeds a [size limit](https://code.claude.com/docs/en/plugins/mods/reference.md#limits). Either line names the [render site](https://code.claude.com/docs/en/plugins/mods/reference.md#render-sites) and then the reason, and the reason names the limit.

246 

247Change the mods that draw at that site so their [`ui.render`](https://code.claude.com/docs/en/plugins/mods/reference#interface) hooks return smaller trees, or ask their authors to. If the transcript line starts with `hooks`, more than one loaded mod has a `ui.render` hook for that site, so check each of those mods' trees. For several mods whose bands above the prompt nest into a tree more than 32 levels deep, the line reads:

248 

249```text theme={null}

250hooks: ui.render (AbovePrompt) refused: deeper than 32; nothing was drawn

251```

252 

253Before v2.1.307, a `refused:` line for any site reported any tree that didn't validate, and for `Pane` and `AbovePrompt` it ended `; the engine drew its own`. On those releases, fix what the reason names.

236 254 

237### `needs a key`, `is drawn twice`, or `key each once`255### `needs a key`, `is drawn twice`, or `key each once`

238 256 


383hooks module first-mod@inline loaded (worker, environment 2, tier user); events: session.start,tool.call,command.run,ui.render401hooks module first-mod@inline loaded (worker, environment 2, tier user); events: session.start,tool.call,command.run,ui.render

384```402```

385 403 

386A drawing that didn't validate counts as a refused result and gets a line too. To write your own lines in the log, call [`$.ui.log`](https://code.claude.com/docs/en/plugins/mods/api#show-something-without-starting-a-turn) with a second argument, as in `$.ui.log('message', { to: 'debug' })`. Without the second argument, `$.ui.log` adds a dim line to the transcript.404To write your own lines in the log, call [`$.ui.log`](https://code.claude.com/docs/en/plugins/mods/api#show-something-without-starting-a-turn) with a second argument, as in `$.ui.log('message', { to: 'debug' })`. Without the second argument, `$.ui.log` adds a dim line to the transcript.

387 405 

388While you edit a mod loaded with `--plugin-dir`, the transcript shows a line for each reload that names the mod and lists its hooks. If a save breaks the module, the line says `reload failed, the previous version stays loaded:` with the reason, and the last working version keeps running until Claude Code next reloads plugins, such as when you run `/reload-plugins`.406While you edit a mod loaded with `--plugin-dir`, the transcript shows a line for each reload that names the mod and lists its hooks. If a save breaks the module, the line says `reload failed, the previous version stays loaded:` with the reason, and the last working version keeps running until Claude Code next reloads plugins, such as when you run `/reload-plugins`.

389 407 

plugins/org.md +6 −2

Details

182| `blockedMarketplaces` | Blocklist of marketplace sources, checked before the allowlist | Doesn't block a marketplace already registered from a source it doesn't match |182| `blockedMarketplaces` | Blocklist of marketplace sources, checked before the allowlist | Doesn't block a marketplace already registered from a source it doesn't match |

183| `syncClaudeAiPlugins` | Set `false` to stop Claude Code downloading and loading the plugins [synced from claude.ai](https://code.claude.com/docs/en/plugins/loading.md#synced-plugins) for each user's account. Requires Claude Code v2.1.273 or later | Doesn't turn off one synced plugin. For that, set `"<name>@synced": false` in [`enabledPlugins`](https://code.claude.com/docs/en/settings-reference#enabledplugins) |183| `syncClaudeAiPlugins` | Set `false` to stop Claude Code downloading and loading the plugins [synced from claude.ai](https://code.claude.com/docs/en/plugins/loading.md#synced-plugins) for each user's account. Requires Claude Code v2.1.273 or later | Doesn't turn off one synced plugin. For that, set `"<name>@synced": false` in [`enabledPlugins`](https://code.claude.com/docs/en/settings-reference#enabledplugins) |

184| `enabledPlugins` | `true` force-enables, `false` blocks at every scope and hides the plugin | Doesn't install a plugin whose marketplace isn't registered or allowed |184| `enabledPlugins` | `true` force-enables, `false` blocks at every scope and hides the plugin | Doesn't install a plugin whose marketplace isn't registered or allowed |

185| `disableSideloadFlags` | Rejects `--plugin-dir`, `--plugin-url`, `--agents`, the Agent SDK `plugins` option, and non-SDK `--mcp-config` at startup, and rejects folders named in the [`CLAUDE_CODE_PLUGIN_DIRS`](https://code.claude.com/docs/en/env-vars#variables) variable the same way | Doesn't restrict `.mcp.json`, `claude mcp add`, or SDK-provided servers. Pair it with [`allowedMcpServers`](https://code.claude.com/docs/en/managed-mcp) |185| `disableSideloadFlags` | Rejects `--plugin-dir`, `--plugin-url`, `--agents`, the Agent SDK `plugins` option, and folders named in the [`CLAUDE_CODE_PLUGIN_DIRS`](https://code.claude.com/docs/en/env-vars#variables) variable at startup, and `--mcp-config` too unless every server in it is an in-process `type: "sdk"` entry. Refuses plugin folders an Agent SDK application adds mid-session with [`addPlugins`](https://code.claude.com/docs/en/agent-sdk/typescript#load-more-plugin-folders-with-addplugins) | Doesn't restrict `.mcp.json`, `claude mcp add`, or SDK-provided servers. Pair it with [`allowedMcpServers`](https://code.claude.com/docs/en/managed-mcp) |

186| `disableCommandPluginSources` | Blocks plugins with a `command` source from installing, updating, or loading. A `command` source is one whose plugin directory is produced by running a command on the machine. When unset, it takes the value of `allowManagedHooksOnly` | Doesn't affect other source types |186| `disableCommandPluginSources` | Blocks plugins with a `command` source from installing, updating, or loading. A `command` source is one whose plugin directory is produced by running a command on the machine. When unset, it takes the value of `allowManagedHooksOnly` | Doesn't affect other source types |

187| `allowManagedHooksOnly` | Restricts which hooks run. See [`allowManagedHooksOnly`](https://code.claude.com/docs/en/settings-reference#allowmanagedhooksonly) | Doesn't trust hooks from plugins users enable themselves |187| `allowManagedHooksOnly` | Restricts which hooks run. See [`allowManagedHooksOnly`](https://code.claude.com/docs/en/settings-reference#allowmanagedhooksonly) | Doesn't trust hooks from plugins users enable themselves |

188| `strictPluginOnlyCustomization` | Blocks skills, agents, hooks, and MCP servers that don't come from a plugin, managed settings, or Claude Code's built-ins. It also stops [skills-directory plugins](#keep-skills-directory-plugins-loading) loading. Set `true` to cover all four types, or an array of `skills`, `agents`, `hooks`, and `mcp` values such as `["skills", "hooks"]` to cover some | Doesn't restrict which plugins users install. Pair it with `strictKnownMarketplaces` |188| `strictPluginOnlyCustomization` | Blocks skills, agents, hooks, and MCP servers that don't come from a plugin, managed settings, or Claude Code's built-ins. It also stops [skills-directory plugins](#keep-skills-directory-plugins-loading) loading. Set `true` to cover all four types, or an array of `skills`, `agents`, `hooks`, and `mcp` values such as `["skills", "hooks"]` to cover some | Doesn't restrict which plugins users install. Pair it with `strictKnownMarketplaces` |

189| `pluginSuggestionMarketplaces` | Marketplaces whose plugins may appear as install suggestions. See [Recommend plugins](#recommend-plugins) | Doesn't affect the built-in tips |189| `pluginSuggestionMarketplaces` | Marketplaces whose plugins may appear as install suggestions in the terminal. See [Recommend plugins](#recommend-plugins) | Doesn't affect the built-in tips |

190| `pluginTrustMessage` | Appends your text to the trust warning that `/plugin` shows before a plugin installs | Doesn't change the warning's own text |190| `pluginTrustMessage` | Appends your text to the trust warning that `/plugin` shows before a plugin installs | Doesn't change the warning's own text |

191| `allowedChannelPlugins` | Replaces the default list of plugins allowed to push channel messages. Requires `channelsEnabled: true` | See [Restrict which channel plugins can run](https://code.claude.com/docs/en/channels.md#restrict-which-channel-plugins-can-run) |191| `allowedChannelPlugins` | Replaces the default list of plugins allowed to push channel messages. Requires `channelsEnabled: true` | See [Restrict which channel plugins can run](https://code.claude.com/docs/en/channels.md#restrict-which-channel-plugins-can-run) |

192| [`CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL=1`](https://code.claude.com/docs/en/env-vars) | Stops interactive terminal sessions from auto-registering the official marketplace | Doesn't remove a marketplace already registered. The allowlist and blocklist gate the same auto-registration without it. A machine that started once with it set doesn't resume auto-registration after you unset it |192| [`CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL=1`](https://code.claude.com/docs/en/env-vars) | Stops interactive terminal sessions from auto-registering the official marketplace | Doesn't remove a marketplace already registered. The allowlist and blocklist gate the same auto-registration without it. A machine that started once with it set doesn't resume auto-registration after you unset it |


361 361 

362Suggestions from a marketplace appear only when it's registered on the user's machine, you list its name in `pluginSuggestionMarketplaces` in managed settings, and you declare its source in the same policy. Declare the source either as the marketplace's `extraKnownMarketplaces` entry or as an allowlist entry. The official marketplace needs only the name. See [Enable suggestions in managed settings](https://code.claude.com/docs/en/plugins/relevance.md#enable-suggestions-in-managed-settings).362Suggestions from a marketplace appear only when it's registered on the user's machine, you list its name in `pluginSuggestionMarketplaces` in managed settings, and you declare its source in the same policy. Declare the source either as the marketplace's `extraKnownMarketplaces` entry or as an allowlist entry. The official marketplace needs only the name. See [Enable suggestions in managed settings](https://code.claude.com/docs/en/plugins/relevance.md#enable-suggestions-in-managed-settings).

363 363 

364> [!NOTE]

365>

366> In a cloud session's conversation, Claude can suggest plugins whether or not you set `pluginSuggestionMarketplaces`. To turn those suggestions off, see [Turn off plugin suggestions](https://code.claude.com/docs/en/claude-code-on-the-web.md#turn-off-plugin-suggestions).

367 

364## Audit and review368## Audit and review

365 369 

366OpenTelemetry events and the Analytics API tell you what your fleet installs and runs.370OpenTelemetry events and the Analytics API tell you what your fleet installs and runs.

Details

8 8 

9Claude Code can suggest installing a plugin from your organization's marketplace when a user's session matches signals you define for that plugin. Signals include the working directory, files Claude has read, and commands Claude has run. You define them by adding a `relevance` block to the plugin's entry in `marketplace.json`.9Claude Code can suggest installing a plugin from your organization's marketplace when a user's session matches signals you define for that plugin. Signals include the working directory, files Claude has read, and commands Claude has run. You define them by adding a `relevance` block to the plugin's entry in `marketplace.json`.

10 10 

11A marketplace operator writes the `relevance` entries. An administrator then allowlists the marketplace in managed settings. Users see no suggestions from a marketplace until it's allowlisted.11A marketplace operator writes the `relevance` entries. An administrator then allowlists the marketplace in managed settings. In the terminal, users see no suggestions from a marketplace until it's allowlisted.

12 12 

13> [!NOTE]13> [!NOTE]

14>14>

15> These cases are covered on other pages:15> These cases are covered on other pages:

16>16>

17> * **You want to install plugins**: see [Install and manage plugins](https://code.claude.com/docs/en/plugins/install.md)17> * **You want to install plugins**: see [Install and manage plugins](https://code.claude.com/docs/en/plugins/install.md)

18> * **You want to turn suggestions off**: see [Understand how plugin relevance works](#understand-how-plugin-relevance-works)18> * **You want to turn suggestions off**: see [Understand how plugin relevance works](#understand-how-plugin-relevance-works), or for the suggestions Claude makes in a cloud session's conversation, [Turn off plugin suggestions](https://code.claude.com/docs/en/claude-code-on-the-web.md#turn-off-plugin-suggestions)

19 19 

20Start with the sections for your role:20Start with the sections for your role:

21 21 


158 158 

159## Enable suggestions in managed settings159## Enable suggestions in managed settings

160 160 

161Users see no suggestions from a marketplace until an administrator allowlists it in [managed settings](https://code.claude.com/docs/en/plugins/org.md), even when its `marketplace.json` declares `relevance`.161In the terminal, users see no suggestions from a marketplace until an administrator allowlists it in [managed settings](https://code.claude.com/docs/en/plugins/org.md), even when its `marketplace.json` declares `relevance`.

162 162 

163To allowlist a marketplace, edit your managed settings as follows:163To allowlist a marketplace, edit your managed settings as follows:

164 164 

Details

170 170 

171**Subsequent launches with cached settings:**171**Subsequent launches with cached settings:**

172 172 

173* Cached settings apply immediately at startup, except for the cached `modelPricing` and `managedMcpServers` values and the environment variables that Claude Code withholds until the server confirms the payload173* Cached settings apply immediately at startup, except for the cached `modelPricing` and `managedMcpServers` values; the environment variables that Claude Code withholds until the server confirms the payload; the removal, repositioning, or disabling of the [built-in guard](https://code.claude.com/docs/en/plugins/mods/admin.md#know-what-happens-by-default) by a cached plugin list; and, on a machine where an endpoint-managed source lists or enables plugins of its own, the [organization standing](https://code.claude.com/docs/en/plugins/mods/admin.md#install-your-organizations-mods) of a plugin that only a cached list enables

174* A cached [`modelPricing`](https://code.claude.com/docs/en/settings-reference#modelpricing) doesn't apply until the session's fetch confirms the payload. Until then, the cost figures developers see in `/usage` and the status line are at list price174* A cached [`modelPricing`](https://code.claude.com/docs/en/settings-reference#modelpricing) doesn't apply until the session's fetch confirms the payload. Until then, the cost figures developers see in `/usage` and the status line are at list price

175* A cached [`managedMcpServers`](https://code.claude.com/docs/en/settings-reference#managedmcpservers) block doesn't apply until the session's fetch confirms the payload. Claude Code waits up to 30 seconds for that fetch before connecting MCP servers. If the fetch fails or times out, the session starts without the organization's servers, `/status` says so, and they connect once a later fetch confirms them. See [When provided servers connect](https://code.claude.com/docs/en/managed-mcp.md#when-provided-servers-connect) for the full behavior, including first launch. Requires Claude Code v2.1.259 or later175* A cached [`managedMcpServers`](https://code.claude.com/docs/en/settings-reference#managedmcpservers) block doesn't apply until the session's fetch confirms the payload. Claude Code waits up to 30 seconds for that fetch before connecting MCP servers. If the fetch fails or times out, the session starts without the organization's servers, `/status` says so, and they connect once a later fetch confirms them. See [When provided servers connect](https://code.claude.com/docs/en/managed-mcp.md#when-provided-servers-connect) for the full behavior, including first launch. Requires Claude Code v2.1.259 or later

176* A cached [`prependPlugins`](https://code.claude.com/docs/en/settings-reference#prependplugins), [`appendPlugins`](https://code.claude.com/docs/en/settings-reference#appendplugins), or [`enabledPlugins`](https://code.claude.com/docs/en/settings-reference#enabledplugins) value can't remove the built-in guard, change its position, or turn it off until the session's fetch confirms the payload

177* On a machine where an [endpoint-managed source](https://code.claude.com/docs/en/managed-settings.md#choose-a-delivery-mechanism) lists or enables plugins of its own, a plugin that only a cached list enables counts as [the user's](https://code.claude.com/docs/en/plugins/mods/admin.md#install-your-organizations-mods), not your organization's, until the fetch confirms the payload

176* Claude Code fetches fresh settings in the background178* Claude Code fetches fresh settings in the background

177* Cached settings persist through network failures. If the startup fetch fails, Claude Code warns in interactive sessions that the cached policy is in effect179* Cached settings persist through network failures. If the startup fetch fails, Claude Code warns in interactive sessions that the cached policy is in effect

178* Until a fetch succeeds, the values withheld at startup stay withheld180* Until a fetch succeeds, the values withheld at startup stay withheld

sessions.md +1 −1

Details

249 249 

250By default, Claude Code stores transcripts as JSONL at `~/.claude/projects/<project>/<session-id>.jsonl`, where `<project>` is your working directory path with non-alphanumeric characters replaced by `-`. For a working directory whose converted name exceeds 200 characters, Claude Code truncates the name to 200 characters and appends a hash of the full path, so the directory name stays within filesystem limits.250By default, Claude Code stores transcripts as JSONL at `~/.claude/projects/<project>/<session-id>.jsonl`, where `<project>` is your working directory path with non-alphanumeric characters replaced by `-`. For a working directory whose converted name exceeds 200 characters, Claude Code truncates the name to 200 characters and appends a hash of the full path, so the directory name stays within filesystem limits.

251 251 

252Each line is a JSON object for a message, tool use, or metadata entry. The entry format is internal to Claude Code and changes between versions, so scripts that parse these files directly can break on any release. To build on session data, use `/export` or the [script interfaces](#access-conversations-from-scripts) instead.252Each line is a JSON object: a message, a tool use or result, a record of a request Claude Code sent the model, or a metadata entry. The entry format is internal to Claude Code and changes between versions, so scripts that parse these files directly can break on any release. To build on session data, use `/export` or the [script interfaces](#access-conversations-from-scripts) instead.

253 253 

254The location, retention, and write behavior are configurable:254The location, retention, and write behavior are configurable:

255 255 

Details

2037* **Type**: array of strings, each a service name; a single trailing `*` matches a prefix, and `"*"` alone matches every service2037* **Type**: array of strings, each a service name; a single trailing `*` matches a prefix, and `"*"` alone matches every service

2038* **Default**: unset2038* **Default**: unset

2039 2039 

2040This allows every service under the `com.apple.coresimulator.` prefix:2040This allows every service under the `com.apple.CoreSimulator.` prefix:

2041 2041 

2042```json settings.json theme={null}2042```json settings.json theme={null}

2043{2043{

2044 "sandbox": {2044 "sandbox": {

2045 "network": {2045 "network": {

2046 "allowMachLookup": ["com.apple.coresimulator.*"]2046 "allowMachLookup": ["com.apple.CoreSimulator.*"]

2047 }2047 }

2048 }2048 }

2049}2049}


4729* **Type**: array of strings, directory paths relative to the repository root4729* **Type**: array of strings, directory paths relative to the repository root

4730* **Default**: unset, so each worktree checks out the whole tree4730* **Default**: unset, so each worktree checks out the whole tree

4731 4731 

4732This example checks out only `packages/my-app` and `shared/utils`, plus root-level files, in each worktree:4732Include `.claude` in the list so that each worktree also has the repository's `.claude/settings.json` and `.claude/rules/`. This example checks out only `.claude`, `packages/my-app`, and `shared/utils`, plus root-level files, in each worktree:

4733 4733 

4734```json settings.json theme={null}4734```json settings.json theme={null}

4735{4735{

4736 "worktree": {4736 "worktree": {

4737 "sparsePaths": ["packages/my-app", "shared/utils"]4737 "sparsePaths": [".claude", "packages/my-app", "shared/utils"]

4738 }4738 }

4739}4739}

4740```4740```


5525 5525 

5526Claude Code still accepts a `--mcp-config` whose servers are all in-process `type: "sdk"` entries, so the Agent SDK and VS Code extension keep working. Users can still add servers with `claude mcp add` or a `.mcp.json` file; for per-server control, set [`allowedMcpServers`](https://code.claude.com/docs/en/managed-mcp) as well. Requires Claude Code v2.1.193 or later.5526Claude Code still accepts a `--mcp-config` whose servers are all in-process `type: "sdk"` entries, so the Agent SDK and VS Code extension keep working. Users can still add servers with `claude mcp add` or a `.mcp.json` file; for per-server control, set [`allowedMcpServers`](https://code.claude.com/docs/en/managed-mcp) as well. Requires Claude Code v2.1.193 or later.

5527 5527 

5528The same check covers plugin folders named in the [`CLAUDE_CODE_PLUGIN_DIRS`](https://code.claude.com/docs/en/env-vars#variables) environment variable, which requires Claude Code v2.1.280 or later. When the variable names a folder, Claude Code exits with the same error, and the error says to unset the variable.5528`disableSideloadFlags` also rejects plugin folders from these sources:

5529 

5530* **The [`CLAUDE_CODE_PLUGIN_DIRS`](https://code.claude.com/docs/en/env-vars#variables) environment variable**: when the variable names a plugin folder, Claude Code exits at startup with an error that names the variable and says to unset it. Requires Claude Code v2.1.280 or later

5531* **The Agent SDK [`addPlugins`](https://code.claude.com/docs/en/agent-sdk/typescript#load-more-plugin-folders-with-addplugins) option**: when an application passes plugin folders to `reloadPlugins()` in `addPlugins`, that call fails with an error. The session keeps running with the plugins it already had. Requires Claude Code v2.1.301 or later

5529 5532 

5530In cloud sessions, Claude Code also ignores server-delivered mid-session MCP updates, the path behind cloud session configuration and SDK `setMcpServers()` calls that reach those sessions. In-process `type: "sdk"` entries and a Claude Tag session's Slack tools stay exempt there too. Before v2.1.268, both this drop and the startup drop also removed a Claude Tag session's Slack tools. Before v2.1.239, a server-delivered `--mcp-config` blocked a cloud session from starting.5533In cloud sessions, Claude Code also ignores server-delivered mid-session MCP updates, the path behind cloud session configuration and SDK `setMcpServers()` calls that reach those sessions. In-process `type: "sdk"` entries and a Claude Tag session's Slack tools stay exempt there too. Before v2.1.268, both this drop and the startup drop also removed a Claude Tag session's Slack tools. Before v2.1.239, a server-delivered `--mcp-config` blocked a cloud session from starting.

5531 5534 

vs-code.md +36 −17

Details

203What's in @src/components/ (include a trailing slash for folders)203What's in @src/components/ (include a trailing slash for folders)

204```204```

205 205 

206For large PDFs, you can ask Claude to read specific pages instead of the whole file. Ask for a single page, a range like pages 1-10, or an open-ended range like page 3 onward. Reading specific pages requires [poppler-utils](https://code.claude.com/docs/en/tools-reference.md#read-tool-behavior) on the machine where Claude Code runs.206### Read specific pages of a PDF

207 

208When you select text in the editor, Claude can see your highlighted code automatically. The prompt box footer shows how many lines are selected. Press `Option+K` (Mac) / `Alt+K` (Windows/Linux) to insert an @-mention with the file path and line numbers, for example `@app.ts#5-10`. Click the **X** on the selection indicator to remove it so Claude doesn't receive the selection. The indicator comes back when you select other text.

209 207 

210The extension withholds selected text from some files:208For large PDFs, you can ask Claude to read specific pages instead of the whole file. Ask for a single page, a range like pages 1-10, or an open-ended range like page 3 onward. Reading specific pages requires [poppler-utils](https://code.claude.com/docs/en/tools-reference.md#read-tool-behavior) on the machine where Claude Code runs.

211 

212* When the file is inside your workspace and matches your `files.exclude` or `search.exclude` settings, Claude receives at most the file's path and not the text you selected.

213* The same applies to a file git ignores, as long as VS Code's `search.useIgnoreFiles` setting and the extension's [`respectGitIgnore` setting](#extension-settings) are both on, which is the default.

214 209 

215This filter covers the chat panel only. When Claude Code runs in the integrated terminal, the CLI sends your selected text whatever the file. To keep a file's contents from Claude there, add a [`Read` deny rule](#the-built-in-ide-mcp-server).210### Include terminal output in prompts

216 211 

217Claude also sees which file you have open in the editor, even when nothing is selected, and the prompt box shows its name. To add only your selected text, turn off the [Attach Open File setting](vscode://settings/claudeCode.attachOpenFile). The setting requires Claude Code v2.1.271 or later.212Reference terminal output in your prompts using `@terminal:name` where `name` is the terminal's title. This lets Claude see command output, error messages, or logs without copy-pasting.

218 213 

219You can also attach images and files to your message:214### Attach images and files

220 215 

221* To attach an image, paste it from your clipboard into the prompt box.216* To attach an image, paste it from your clipboard into the prompt box.

222* To attach files, hold `Shift` while dragging them into the prompt box.217* To attach files, hold `Shift` while dragging them into the prompt box.

223* To remove an attachment from context, click the X on it.218* To remove an attachment from context, click the X on it.

224 219 

225### Include terminal output in prompts

226 

227Reference terminal output in your prompts using `@terminal:name` where `name` is the terminal's title. This lets Claude see command output, error messages, or logs without copy-pasting.

228 

229### Paste text220### Paste text

230 221 

231Text you paste stays visible in the prompt box, rather than collapsing to a placeholder as it does [in the terminal](https://code.claude.com/docs/en/terminal-config.md#paste-large-content). In sessions where Claude Code [marks pasted text](https://code.claude.com/docs/en/terminal-config.md#how-claude-treats-pasted-text), Claude still sees a large paste as text you pasted rather than typed.222Text you paste stays visible in the prompt box, rather than collapsing to a placeholder as it does [in the terminal](https://code.claude.com/docs/en/terminal-config.md#paste-large-content). In sessions where Claude Code [marks pasted text](https://code.claude.com/docs/en/terminal-config.md#how-claude-treats-pasted-text), Claude still sees a large paste as text you pasted rather than typed.


235* If a notice such as `Removed 3 invisible characters from the pasted text` appears when you paste, the text went in without those characters.226* If a notice such as `Removed 3 invisible characters from the pasted text` appears when you paste, the text went in without those characters.

236* If a notice about removed characters appears when you send, nothing was sent. The cleaned text is back in the prompt box. Send again to send the text as shown.227* If a notice about removed characters appears when you send, nothing was sent. The cleaned text is back in the prompt box. Send again to send the text as shown.

237 228 

229### Automatic context from your selection and open file

230 

231When you select text in the editor, Claude can see your highlighted code automatically. The prompt box footer shows how many lines are selected. Claude also sees which file you have open in the editor, even when nothing is selected, and the prompt box shows its name.

232 

233Press `Option+K` (Mac) / `Alt+K` (Windows/Linux) to insert an @-mention with the file path and line numbers, for example `@app.ts#5-10`.

234 

235#### Keep your selection and open file out of your messages

236 

237To stop selected text or your open file from going into your messages, turn off the matching setting in VS Code's settings:

238 

239* **Selected text**: turn off the [Attach Selection setting](vscode://settings/claudeCode.attachSelection). Requires Claude Code v2.1.300 or later. To drop one selection, click the **X** beside the line count. The count returns when you select different text.

240* **Open file**: turn off the [Attach Open File setting](vscode://settings/claudeCode.attachOpenFile). Requires Claude Code v2.1.271 or later. The file stays out unless your message includes text you selected in it.

241 

242To add text as an @-mention with Attach Selection off, select it and press `Option+K` on Mac or `Alt+K` on Windows and Linux.

243 

244Both settings also apply when you run `claude` in VS Code's integrated terminal.

245 

246#### Selected text from excluded or ignored files

247 

248In the chat panel, the extension withholds selected text from some files:

249 

250* When the file is inside your workspace and matches your `files.exclude` or `search.exclude` settings, Claude receives at most the file's path and not the text you selected.

251* The same applies to a file git ignores, as long as VS Code's `search.useIgnoreFiles` setting and the extension's [`respectGitIgnore` setting](#extension-settings) are both on, which is the default.

252 

253This filter covers the chat panel only. When Claude Code runs in the integrated terminal, Claude can receive text you select in these files. To keep a file's contents from Claude there, add a [`Read` deny rule](https://code.claude.com/docs/en/permissions#read-and-edit).

254 

238### LaTeX math in responses255### LaTeX math in responses

239 256 

240The chat panel shows LaTeX math in Claude's responses as typeset formulas. Math rendering requires Claude Code v2.1.301 or later. In [terminal mode](#switch-to-terminal-mode), math isn't typeset. The panel typesets both display math and inline math:257The chat panel shows LaTeX math in Claude's responses as typeset formulas. Math rendering requires Claude Code v2.1.301 or later. In [terminal mode](#switch-to-terminal-mode), math isn't typeset. The panel typesets both display math and inline math:


694| `preferredLocation` | `panel` | Where Claude opens: `sidebar` (right) or `panel` (new tab) |711| `preferredLocation` | `panel` | Where Claude opens: `sidebar` (right) or `panel` (new tab) |

695| `lockEditorGroups` | `true` | [Lock the editor groups Claude starts for its tabs](#choose-where-claude-lives), so files you open while a Claude tab is focused go to another group. When off, the extension never locks an editor group. Requires Claude Code v2.1.274 or later |712| `lockEditorGroups` | `true` | [Lock the editor groups Claude starts for its tabs](#choose-where-claude-lives), so files you open while a Claude tab is focused go to another group. When off, the extension never locks an editor group. Requires Claude Code v2.1.274 or later |

696| `autosave` | `true` | Auto-save files before Claude reads or writes them |713| `autosave` | `true` | Auto-save files before Claude reads or writes them |

697| `attachOpenFile` | `true` | Add the file that is open in the editor to your messages and show it in the prompt box. When off, only your selected text is added. Requires Claude Code v2.1.271 or later |714| `attachOpenFile` | `true` | Add the file that is open in the editor to your messages and show it in the prompt box. When off, the file is added only along with text you select. Requires Claude Code v2.1.271 or later |

715| `attachSelection` | `true` | Add the text you select in the editor to your messages and show it in the prompt box. When off, you can still [add a selection as an @-mention](#automatic-context-from-your-selection-and-open-file). Requires Claude Code v2.1.300 or later |

698| `useCtrlEnterToSend` | `false` | Use Ctrl/Cmd+Enter instead of Enter to send prompts |716| `useCtrlEnterToSend` | `false` | Use Ctrl/Cmd+Enter instead of Enter to send prompts |

699| `scrollToBottomOnSend` | `true` | Scroll the conversation to the bottom when you send a message. When off, the conversation stays where you left it. Requires Claude Code v2.1.275 or later |717| `scrollToBottomOnSend` | `true` | Scroll the conversation to the bottom when you send a message. When off, the conversation stays where you left it. Requires Claude Code v2.1.275 or later |

700| `showMessageTimestamps` | `true` | Show when each message was sent. A date line marks where the day changes. Requires Claude Code v2.1.284 or later. Before v2.1.290, the default was `false` |718| `showMessageTimestamps` | `true` | Show when each message was sent. A date line marks where the day changes. Requires Claude Code v2.1.284 or later. Before v2.1.290, the default was `false` |


705| `continueAfterReload` | `true` | After a window reload, Claude [continues the step that was interrupted](#continue-conversations-after-a-reload) in the restored session. Requires Claude Code v2.1.274 or later |723| `continueAfterReload` | `true` | After a window reload, Claude [continues the step that was interrupted](#continue-conversations-after-a-reload) in the restored session. Requires Claude Code v2.1.274 or later |

706| `hideOnboarding` | `false` | Hide the onboarding checklist (graduation cap icon) |724| `hideOnboarding` | `false` | Hide the onboarding checklist (graduation cap icon) |

707| `focusView` | `false` | Hide tool calls, tool results, and thinking behind expandable rows, leaving your prompts and Claude's responses. Claude's latest to-do list stays visible; this requires Claude Code v2.1.225 or later. You can also toggle Focus view from the command menu. Requires Claude Code v2.1.221 or later |725| `focusView` | `false` | Hide tool calls, tool results, and thinking behind expandable rows, leaving your prompts and Claude's responses. Claude's latest to-do list stays visible; this requires Claude Code v2.1.225 or later. You can also toggle Focus view from the command menu. Requires Claude Code v2.1.221 or later |

708| `respectGitIgnore` | `true` | Exclude .gitignore patterns from file searches and from [selection context](#reference-files-and-folders) |726| `respectGitIgnore` | `true` | Exclude .gitignore patterns from file searches and from [selection context](#selected-text-from-excluded-or-ignored-files) |

709| `usePythonEnvironment` | `true` | Activate the workspace's Python environment when running Claude. Requires the Python extension. |727| `usePythonEnvironment` | `true` | Activate the workspace's Python environment when running Claude. Requires the Python extension. |

710| `environmentVariables` | `[]` | Set environment variables for the Claude process. Use Claude Code settings instead for shared config. A [`CLAUDE_CONFIG_DIR`](https://code.claude.com/docs/en/env-vars) entry applies only when its value is an absolute path; the extension doesn't expand `~` and ignores a relative value. |728| `environmentVariables` | `[]` | Set environment variables for the Claude process. Use Claude Code settings instead for shared config. A [`CLAUDE_CONFIG_DIR`](https://code.claude.com/docs/en/env-vars) entry applies only when its value is an absolute path; the extension doesn't expand `~` and ignores a relative value. |

711| `disableLoginPrompt` | `false` | Skip authentication prompts (for third-party provider setups) |729| `disableLoginPrompt` | `false` | Skip authentication prompts (for third-party provider setups) |


835 853 

836**Selection and open-file context.** While connected, the CLI includes your current editor selection and the path of the active file as context on each prompt you send. The transcript shows a `⧉ Selected N lines from <file>` line when this happens. These cases change that context:854**Selection and open-file context.** While connected, the CLI includes your current editor selection and the path of the active file as context on each prompt you send. The transcript shows a `⧉ Selected N lines from <file>` line when this happens. These cases change that context:

837 855 

856* **[Attach Selection setting](#keep-your-selection-and-open-file-out-of-your-messages) off**: the CLI doesn't include your selection as context.

857* **Attach Open File setting off**: the CLI includes the active file's path only when it also includes a selection.

838* **Queued messages**: if you [queue a message while Claude works](https://code.claude.com/docs/en/interactive-mode.md#queue-messages-while-claude-works), it keeps the selection you had when you pressed `Enter`, whatever you select afterward.858* **Queued messages**: if you [queue a message while Claude works](https://code.claude.com/docs/en/interactive-mode.md#queue-messages-while-claude-works), it keeps the selection you had when you pressed `Enter`, whatever you select afterward.

839* **Sensitive files**: to exclude a sensitive file such as `.env`, add a [`Read` deny rule](https://code.claude.com/docs/en/permissions#read-and-edit) for its path. A matching deny rule prevents both the selected text and the open-file notice for that file from reaching Claude.859* **Sensitive files**: to exclude a sensitive file such as `.env`, add a [`Read` deny rule](https://code.claude.com/docs/en/permissions#read-and-edit) for its path. A matching deny rule prevents both the selected text and the open-file notice for that file from reaching Claude.

840* **Attach Open File turned off**: if you turn off the [Attach Open File setting](#extension-settings), the CLI receives the active file's path only while you have text selected in it.

841 860 

842**Transport and authentication.** The server binds to `127.0.0.1` on a random port in the range 10000–65535, and the port is not configurable. The transport and the auth token work as follows:861**Transport and authentication.** The server binds to `127.0.0.1` on a random port in the range 10000–65535, and the port is not configurable. The transport and the auth token work as follows:

843 862 

workflows.md +5 −4

Details

333 333 

334The workflow runtime executes the script in an isolated environment, separate from your conversation. Intermediate results stay in script variables instead of landing in Claude's context.334The workflow runtime executes the script in an isolated environment, separate from your conversation. Intermediate results stay in script variables instead of landing in Claude's context.

335 335 

336Every run writes its script to a file under your session's directory in `~/.claude/projects/`. Claude receives the path when the run starts, so you can ask for it. You can open that file to read the orchestration Claude wrote, diff it against a previous run's script, or edit it and ask Claude to relaunch from the edited version.336Unless Claude starts a run from a script file's path, Claude Code writes the run's script to a file under your session's directory in `~/.claude/projects/`. Claude receives the script's path when the run starts, so you can ask for it. You can open that file to read the orchestration Claude wrote, diff it against a previous run's script, or edit it and ask Claude to relaunch from the edited version.

337 337 

338Claude can start a workflow only from a script file the session is already allowed to read. To run a script kept outside your working directory, add its directory with [`/add-dir`](https://code.claude.com/docs/en/permissions#working-directories) or a [Read allow rule](https://code.claude.com/docs/en/permissions.md#read-and-edit) first.338Claude can start a workflow only from a script file the session is already allowed to read. To run a script kept outside your working directory, add its directory with [`/add-dir`](https://code.claude.com/docs/en/permissions#working-directories) or a [Read allow rule](https://code.claude.com/docs/en/permissions.md#read-and-edit) first.

339 339 


387 387 

388#### Resume after you leave the session388#### Resume after you leave the session

389 389 

390You can resume a run within the same Claude Code session. What happens to a running workflow when you leave the session depends on how you leave:390If you background your session or exit Claude Code while a workflow run is in progress, the run doesn't continue on its own. The run continues only when Claude relaunches it with a `Workflow` call, which [replays the run from its saved results](#which-agents-run-again).

391 391 

392* If you [background the session](https://code.claude.com/docs/en/agent-view.md#what-carries-over-when-you-background), Claude Code replays the run the same way in the background session and continues it.392* **You backgrounded the session or chose [`Move to background and exit`](https://code.claude.com/docs/en/agent-view#from-inside-a-session)**: if the run hasn't continued when you check the [background session](https://code.claude.com/docs/en/agent-view.md#what-carries-over-when-you-background), ask Claude there to relaunch the workflow. Depending on your [permission mode](#approve-the-plan-before-it-runs), Claude Code asks you to approve the relaunch first. If the session shows under `Needs input` in agent view, [attach to it](https://code.claude.com/docs/en/agent-view.md#attach-to-a-session) to answer the approval prompt.

393* If you exit Claude Code while a workflow is running and [agent view is on](https://code.claude.com/docs/en/agent-view.md#from-inside-a-session), the exit dialog offers `Move to background and exit`, which carries the run over the same way. If you choose `Exit and stop tasks` instead, or the option isn't offered, the run stops with the session. Claude Code keeps the run's saved results under that session's directory in `~/.claude/projects/`, so a session you resume with `claude --resume` can replay them when you ask Claude to relaunch the workflow. In a session you start fresh, Claude has no earlier run to relaunch and starts the workflow over as a new run.393* **The relaunch in the background session failed with `nothing to resume`**: ask Claude to start the workflow over as a new run. If Claude started the run from the path of a script file outside `~/.claude/projects/`, such as one in your working directory, Claude can't relaunch it in the background session.

394* **You chose `Exit and stop tasks`, or weren't offered `Move to background and exit`**: the run stopped with the session, and Claude Code keeps the run's saved results under that session's directory in `~/.claude/projects/`. Resume the session with `claude --resume` in your shell, then ask Claude to relaunch the workflow. In a fresh session, Claude has no earlier run to relaunch and starts the workflow over.

394 395 

395In a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), Claude Code also saves the run's results with the session's conversation history, which survives when the session's VM is reclaimed. When you [reopen such a session](https://code.claude.com/docs/en/claude-code-on-the-web.md#environment-expired) and ask Claude to relaunch the workflow, completed agents still return their saved results.396In a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), Claude Code also saves the run's results with the session's conversation history, which survives when the session's VM is reclaimed. When you [reopen such a session](https://code.claude.com/docs/en/claude-code-on-the-web.md#environment-expired) and ask Claude to relaunch the workflow, completed agents still return their saved results.

396 397