SpyBara
Go Premium

Documentation 2026-11-12 23:02 UTC to 2026-11-13 23:02 UTC

66 files changed +691 −328. View all changes and history on the product overview
2026
Sat 14 03:01 Fri 13 23:02 Thu 12 23:02 Wed 11 22:59 Tue 10 21:57 Mon 9 23:02 Sun 8 22:58 Sat 7 23:58 Fri 6 23:01 Thu 5 23:03 Wed 4 23:59 Tue 3 23:58 Mon 2 23:57 Sun 1 23:57
Details

496| **Persistence** | Per-project file | Saved as files | Session only | Session only |496| **Persistence** | Per-project file | Saved as files | Session only | Session only |

497| **Reusability** | Per-project | Across projects | Code duplication | Code duplication |497| **Reusability** | Per-project | Across projects | Code duplication | Code duplication |

498| **Management** | On filesystem | CLI + files | In code | In code |498| **Management** | On filesystem | CLI + files | In code | In code |

499| **Default tools** | Preserved | Preserved | Preserved | Lost (unless included) |499| **Tool guidance** | Preserved | Preserved | Preserved | Lost (unless included) |

500| **Built-in safety** | Maintained | Maintained | Maintained | Must be added |500| **Built-in safety** | Maintained | Maintained | Maintained | Must be added |

501| **Customization level** | Additions only | Additions; can omit coding instructions | Additions only | Complete control |501| **Customization level** | Additions only | Additions; can omit coding instructions | Additions only | Complete control |

502| **Version control** | With project | Yes | With code | With code |502| **Version control** | With project | Yes | With code | With code |

Details

340| `Read`, `Edit`, `Glob` | Analyze and modify code |340| `Read`, `Edit`, `Glob` | Analyze and modify code |

341| `Read`, `Edit`, `Bash`, `Glob`, `Grep` | Full automation |341| `Read`, `Edit`, `Bash`, `Glob`, `Grep` | Full automation |

342 342 

343To limit the agent's built-in tools to one of these sets, pass it as `tools`. If you list a set in `allowedTools` instead, you [pre-approve those tools](https://code.claude.com/docs/en/agent-sdk/custom-tools.md#configure-allowed-tools), and the agent can still call the others, subject to your permission mode.

344 

343**Permission modes** control how much human oversight you want. The SDK evaluates the active mode together with your allow and deny rules in a fixed order, described in [How permissions are evaluated](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated). For the full list of modes, their behavior, and when to use each, see [Permission mode in How the agent loop works](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#permission-mode).345**Permission modes** control how much human oversight you want. The SDK evaluates the active mode together with your allow and deny rules in a fixed order, described in [How permissions are evaluated](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated). For the full list of modes, their behavior, and when to use each, see [Permission mode in How the agent loop works](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#permission-mode).

344 346 

345## Next steps347## Next steps

Details

117 --network none \117 --network none \

118 --memory 2g \118 --memory 2g \

119 --cpus 2 \119 --cpus 2 \

120 --pids-limit 100 \120 --pids-limit 600 \

121 --user 1000:1000 \121 --user 1000:1000 \

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

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


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

136| `--network none` | Cuts the container off from external networks |136| `--network none` | Cuts the container off from external networks |

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

138| `--pids-limit 100` | Limits process count to prevent fork bombs |138| `--pids-limit 600` | Limits processes and threads to prevent fork bombs |

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

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

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

Details

104| `options` | [`Options`](#options) | Optional configuration object. Same as the `options` parameter to `query()` |104| `options` | [`Options`](#options) | Optional configuration object. Same as the `options` parameter to `query()` |

105| `initializeTimeoutMs` | `number` | Maximum time in milliseconds to wait for subprocess initialization. Defaults to `60000`. If initialization does not complete in time, the promise rejects with a timeout error |105| `initializeTimeoutMs` | `number` | Maximum time in milliseconds to wait for subprocess initialization. Defaults to `60000`. If initialization does not complete in time, the promise rejects with a timeout error |

106 106 

107Slow [SessionStart](https://code.claude.com/docs/en/hooks.md#sessionstart) and [Setup](https://code.claude.com/docs/en/hooks.md#setup) [command hooks](https://code.claude.com/docs/en/hooks.md#command-hook-fields) get extra time only when `initializeTimeoutMs` is unset:

108 

109* **If you leave it unset:** time these hooks spend running doesn't count toward the 60-second default, up to 10 minutes in total, so initialization can take 11 minutes at most.

110* **If you set a value, including `60000`:** that value is the limit, even while a hook is running.

111 

112The extra time requires TypeScript Agent SDK v0.3.304 or later.

113 

107#### Returns114#### Returns

108 115 

109Returns a `Promise<`[`WarmQuery`](#warmquery)`>` that resolves once the subprocess has spawned and completed its initialize handshake.116Returns a `Promise<`[`WarmQuery`](#warmquery)`>` that resolves once the subprocess has spawned and completed its initialize handshake.


128 135 

129### `prewarm()`136### `prewarm()`

130 137 

131*Alpha.* Starts a Claude Code process as a spare before you know which session it will serve, so you can bind it to a session later with [`claim()`](#spareprocess). Use it in an application that boots before the user picks a folder. Requires TypeScript Agent SDK v0.3.282 or later.138*Alpha.* Starts a Claude Code process as a spare before you know which session it will serve, so you can bind it to a session later with [`claim()`](#spareprocess). Requires TypeScript Agent SDK v0.3.282 or later.

132 139 

133`prewarm()` completes the same initialize handshake as [`startup()`](#startup), with the process waiting in `options.cwd` when you set it and otherwise in a private temporary directory under your Claude Code config directory. The session's working directory, its `SessionStart` hooks, its stdio MCP servers, and its CLAUDE.md and git context wait for the claim. A spare holds roughly 230 to 260 MB of memory while it waits. If your [`spawnClaudeCodeProcess`](#options) runs Claude Code on another machine or in a container, set `options.cwd` to a directory that exists there for the spare to wait in.140Use `prewarm()` when your application boots before the user picks a folder.

134 141 

135```typescript theme={null}142```typescript theme={null}

136function prewarm(params?: {143function prewarm(params?: {


139}): Promise<SpareProcess>;146}): Promise<SpareProcess>;

140```147```

141 148 

142`options` and `initializeTimeoutMs` mean the same as for `startup()`, except that `options.cwd` sets only the directory the spare waits in. The promise resolves with a [`SpareProcess`](#spareprocess) once the process has completed its initialize handshake. `prewarm()` throws if `options` sets `resume`, `continue`, or `forkSession`, because a spare has no session yet. Everything a claim can't set, such as `mcpServers`, `hooks`, `canUseTool`, `settingSources`, `systemPrompt`, and `plugins`, is fixed for the life of the spare, so keep one spare per distinct set of those options and prewarm again when they change.149#### Parameters

150 

151| Parameter | Type | Description |

152| :- | :- | :- |

153| `options` | [`Options`](#options) | Optional configuration object, the same type that `startup()` takes |

154| `initializeTimeoutMs` | `number` | Maximum time in milliseconds to wait for the spare's initialization. Defaults to `60000`. If initialization doesn't complete in time, the promise rejects with a timeout error |

155 

156`prewarm()` counts time spent in [Setup](https://code.claude.com/docs/en/hooks.md#setup) hooks toward `initializeTimeoutMs`, even when you leave it unset. To give slow Setup hooks more time, set a longer value.

157 

158#### Returns

159 

160Returns a `Promise<`[`SpareProcess`](#spareprocess)`>` that resolves once the spare is ready to claim.

161 

162The promise rejects if you ask for `resume`, `continue`, or `forkSession` in `options`, because a spare has no session yet.

163 

164#### How a spare works

165 

166* **Where a spare waits:** in a private temporary directory under your Claude Code config directory, or in `options.cwd` if you set it in `prewarm()`.

167* **If your [`spawnClaudeCodeProcess`](#options) runs Claude Code on another machine or in a container:** pass `prewarm()` an `options.cwd` that exists there, because the default temporary directory is created on your machine.

168* **Memory:** each spare uses roughly 230 to 260 MB while it waits.

169* **What doesn't happen until you call `claim()`:**

170 * Moving to the working directory you pass to `claim()`

171 * Running SessionStart hooks

172 * Starting stdio MCP servers

173 * Loading CLAUDE.md and git context

174* **What a claim can't change:** options such as `mcpServers`, `hooks`, `canUseTool`, `settingSources`, and `plugins` keep their values from `prewarm()`. [`SpareProcess`](#spareprocess) lists what a claim can set.

175* **If sessions need different values for these:** keep a separate spare for each set of values.

143 176 

144#### Example177#### Example

145 178 

agent-view.md +5 −3

Details

8 8 

9Agent view, opened with `claude agents`, is one screen for all your background sessions: what's running, what needs your input, and what's done. Dispatch new sessions, watch their state at a glance instead of scrolling through transcripts, and step in only when one needs you. Each background session is a full Claude Code conversation that keeps running without a terminal attached, so you can open it, reply, and leave whenever you want.9Agent view, opened with `claude agents`, is one screen for all your background sessions: what's running, what needs your input, and what's done. Dispatch new sessions, watch their state at a glance instead of scrolling through transcripts, and step in only when one needs you. Each background session is a full Claude Code conversation that keeps running without a terminal attached, so you can open it, reply, and leave whenever you want.

10 10 

11![Agent view in a terminal. A line at the top counts the sessions awaiting input, working, and completed. Four sessions are grouped under Needs input, Working, and Completed. Each row shows the session's name, its latest status or question, and a time. At the bottom are an input for describing a new task and a row of keyboard hints.](https://mintcdn.com/claude-code/HDAmBwgbrZVk0pOt/images/agent-view-light.png?fit=max\&auto=format\&n=HDAmBwgbrZVk0pOt\&q=85\&s=d6905012bee31f3e6b3920b09c05dd02)11![Agent view in a terminal. A line at the top counts the sessions awaiting input, working, and completed. Four sessions are grouped under Needs input, Working, and Completed. Each row shows the session's name, its latest status or question, and a time. At the bottom are an input for describing a new task and a row of keyboard hints.](https://mintcdn.com/claude-code/v_J840yKc6uuKDX_/images/agent-view-light.png?fit=max\&auto=format\&n=v_J840yKc6uuKDX_\&q=85\&s=bd95fda83ea66ca8b2e0e7b68f8cb29e)

12 12 

13Use agent view when you have several independent tasks Claude can work on without you watching every step. Dispatch a bug fix, a pull request review, and a flaky-test investigation as three rows, keep working in another window, and check back when a row shows it needs you or has a result.13Use agent view when you have several independent tasks Claude can work on without you watching every step. Dispatch a bug fix, a pull request review, and a flaky-test investigation as three rows, keep working in another window, and check back when a row shows it needs you or has a result.

14 14 


628 628 

629* Agent view removes it, including uncommitted changes, so commit what you want to keep first.629* Agent view removes it, including uncommitted changes, so commit what you want to keep first.

630* `claude rm` keeps it, along with the session row, when it has uncommitted changes.630* `claude rm` keeps it, along with the session row, when it has uncommitted changes.

631* Neither agent view nor `claude rm` removes a worktree that another running session is using or has locked, and deleting again doesn't change that. Claude Code keeps the worktree and the session, and names the kept directory and the reason; in agent view, the session's row shows `not deleted`. Close the other session, then delete again.631* Neither agent view nor `claude rm` removes a worktree that another running session is using or has locked, and deleting again doesn't change that. Claude Code keeps the worktree and the session, and names the kept directory and the reason; in agent view, the session's row shows `not removed`. Close the other session, then delete again.

632* When you delete a session whose worktree has commits that Claude Code can't confirm are saved elsewhere, Claude Code keeps the worktree and the session, and the message names the worktree's branch and how many commits are unpushed. The message also offers the two ways forward: push the commits, or delete again to discard them.632* When you delete a session whose worktree has commits that Claude Code can't confirm are saved elsewhere, Claude Code keeps the worktree and the session, and the message names the worktree's branch and how many commits are unpushed. The message also offers the two ways forward: push the commits, or delete again to discard them.

633 633 

634 Commits on a remote don't block the delete. Neither do commits on the local copy of your `origin` remote's default branch, as long as that branch is checked out in your main checkout, the repository directory itself rather than a worktree.634 Commits on a remote don't block the delete. Neither do commits on the local copy of your `origin` remote's default branch, as long as that branch is checked out in your main checkout, the repository directory itself rather than a worktree.


935Shutting down or restarting your machine stops running background sessions. A session that was waiting on your input stays under `Needs input` when you come back. For any other running session, what agent view shows depends on how long ago it last made progress:935Shutting down or restarting your machine stops running background sessions. A session that was waiting on your input stays under `Needs input` when you come back. For any other running session, what agent view shows depends on how long ago it last made progress:

936 936 

937* Within 48 hours, the session shows as failed. Attach or reply to it and it restarts from its saved conversation. To pick the interrupted work back up, send it a reply asking it to continue.937* Within 48 hours, the session shows as failed. Attach or reply to it and it restarts from its saved conversation. To pick the interrupted work back up, send it a reply asking it to continue.

938* Past 48 hours, such as after the machine was off for days, the session shows as stopped with `ended while the background service was off`. Press `Enter` on the row and the footer shows `Press enter again to resume this session (it ended while the background service was off), or ctrl+x to delete it.` Press `Enter` on the same row again to resume its saved conversation. A reply, or `claude attach <id>`, resumes it without that footer prompt.938* Past 48 hours, such as after the machine was off for days, the session shows as stopped with `ended while the background service was off`.

939 

940 Press `Enter` on the row and the footer shows `Press enter again to resume this session (it ended while the background service was off), or ctrl+x to remove it.` Press `Enter` on the same row again to resume its saved conversation. A reply, or `claude attach <id>`, resumes it without that footer prompt.

939 941 

940When [transcript cleanup](https://code.claude.com/docs/en/settings-reference.md#cleanupperioddays) has removed a stopped session's saved conversation, Claude Code refuses to open the row: the message says there is nothing to resume. `claude rm <id>` deletes the row, except in the [kept cases](#what-deleting-a-session-removes) described above, and `claude respawn <id>` runs its original prompt again. See [This session's saved conversation is no longer on disk](https://code.claude.com/docs/en/errors.md#this-sessions-saved-conversation-is-no-longer-on-disk).942When [transcript cleanup](https://code.claude.com/docs/en/settings-reference.md#cleanupperioddays) has removed a stopped session's saved conversation, Claude Code refuses to open the row: the message says there is nothing to resume. `claude rm <id>` deletes the row, except in the [kept cases](#what-deleting-a-session-removes) described above, and `claude respawn <id>` runs its original prompt again. See [This session's saved conversation is no longer on disk](https://code.claude.com/docs/en/errors.md#this-sessions-saved-conversation-is-no-longer-on-disk).

941 943 

Details

349 349 

350### When a model is disabled mid-session350### When a model is disabled mid-session

351 351 

352If your account loses access to the model your session is running on, for example because an administrator disables it in your Amazon Bedrock account, Claude Code switches the session to another model instead of failing each request, and shows `Switched to <fallback> because <model> is not available`. It tries the same models as the startup fallback: earlier versions of the same tier first and, for an Opus session with no Opus version available, the default Sonnet model.352When Amazon Bedrock rejects your session's model as unavailable to your account, Claude Code switches your session to another model, and you can keep working. You see a message that starts with `Switched to <fallback> because <model> is not available`. This happens, for example, when an administrator disables the model or the newest model isn't yet available to your account.

353 353 

354The switch applies only to a tier you haven't pinned, the same condition as the startup fallback. A session on a specific version you picked, or on an [application inference profile ARN](#map-each-model-version-to-an-inference-profile), keeps its model and, without a fallback model chain, the request fails instead. In [auto mode](https://code.claude.com/docs/en/permission-modes.md#enable-auto-mode-on-bedrock-agent-platform-or-foundry), Claude Code switches only to a model auto mode supports on Amazon Bedrock. If none of those models is available either, the request fails with [AWS authentication failed](https://code.claude.com/docs/en/errors.md#aws-authentication-failed) and a hint to enable the model.354If you configured a [fallback model chain](https://code.claude.com/docs/en/model-config.md#fallback-model-chains), Claude Code switches to your configured fallback instead. Without a chain, the request fails in cases such as these:

355 355 

356A [fallback model chain](https://code.claude.com/docs/en/model-config.md#fallback-model-chains) you configure replaces the tier switch: on these refusals Claude Code switches to your configured fallback instead. To have refused requests fail rather than switch, set [`CLAUDE_CODE_DISABLE_MODEL_ACCESS_FALLBACK=1`](https://code.claude.com/docs/en/env-vars). A fallback chain you configured still switches on these refusals; remove the chain as well if you want every refused request to fail.356* Your session is on a pinned model, a specific version you picked, or an [application inference profile ARN](#map-each-model-version-to-an-inference-profile)

357* None of the [models Claude Code tries](#startup-model-checks) is available. In [auto mode](https://code.claude.com/docs/en/permission-modes.md#enable-auto-mode-on-bedrock-agent-platform-or-foundry), Claude Code only switches to a model auto mode supports on Amazon Bedrock.

358 

359To keep working, run `/model` in the session and press `s` on a model your account can use, which leaves your default unchanged. A `403` shows as [AWS authentication failed](https://code.claude.com/docs/en/errors.md#aws-authentication-failed).

360 

361To have rejected requests fail instead of switching, set [`CLAUDE_CODE_DISABLE_MODEL_ACCESS_FALLBACK=1`](https://code.claude.com/docs/en/env-vars). If you configured a fallback model chain, remove it as well, because Claude Code still moves to that fallback.

357 362 

358## Cross-region inference profile prefixes363## Cross-region inference profile prefixes

359 364 

Details

222 222 

223Each is an array of prose descriptions, read as natural-language rules. For tool-pattern-based hard blocks that run before the classifier, use [`permissions.deny`](https://code.claude.com/docs/en/permissions).223Each is an array of prose descriptions, read as natural-language rules. For tool-pattern-based hard blocks that run before the classifier, use [`permissions.deny`](https://code.claude.com/docs/en/permissions).

224 224 

225> [!NOTE]

226>

227> In a [Code Mode](https://code.claude.com/docs/en/code-mode.md#permission-checks) session, the classifier applies `hard_deny` and `soft_deny` when it reviews Claude's code, and not to each tool call the code makes. `permissions.deny` rules apply to each call.

228 

225Inside the classifier, precedence works in four tiers:229Inside the classifier, precedence works in four tiers:

226 230 

227* `hard_deny` rules block unconditionally. User intent and `allow` exceptions don't apply.231* `hard_deny` rules block unconditionally. User intent and `allow` exceptions don't apply.


283 287 

284By default, narrow Bash and PowerShell allow rules such as `Bash(npm test)` stay in effect in auto mode. Claude Code resolves them before the classifier runs, unless the command carries [per-command allowed domains](https://code.claude.com/docs/en/sandboxing.md#per-command-allowed-domains-in-auto-mode). Claude Code suspends only the broad rules that grant arbitrary code execution, such as `Bash(*)` or wildcarded interpreters, together with every rule that names [`Monitor`](https://code.claude.com/docs/en/tools-reference#monitor-tool), because Monitor commands run through the shell. This means a narrow rule can still let a destructive argument through without the classifier seeing it, for example a script path or flag the rule's prefix didn't anticipate.288By default, narrow Bash and PowerShell allow rules such as `Bash(npm test)` stay in effect in auto mode. Claude Code resolves them before the classifier runs, unless the command carries [per-command allowed domains](https://code.claude.com/docs/en/sandboxing.md#per-command-allowed-domains-in-auto-mode). Claude Code suspends only the broad rules that grant arbitrary code execution, such as `Bash(*)` or wildcarded interpreters, together with every rule that names [`Monitor`](https://code.claude.com/docs/en/tools-reference#monitor-tool), because Monitor commands run through the shell. This means a narrow rule can still let a destructive argument through without the classifier seeing it, for example a script path or flag the rule's prefix didn't anticipate.

285 289 

286Set `autoMode.classifyAllShell` to `true` to suspend every Bash and PowerShell allow rule while auto mode is active, so the classifier evaluates every shell command regardless of your allow list, except [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths).290Set `autoMode.classifyAllShell` to `true` to suspend every Bash and PowerShell allow rule while auto mode is active, so the classifier evaluates every shell command regardless of your allow list, except [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths). In a [Code Mode](https://code.claude.com/docs/en/code-mode.md#permission-checks) session, the classifier reviews the code that runs the commands, even with this setting on.

287 291 

288```json theme={null}292```json theme={null}

289{293{

Details

74| PostgreSQL 11 or later | Backs the device sign-in flow and rate-limit counters. A managed PostgreSQL service works, including the smallest tier; see [which databases are supported](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#postgres). With [spend limits](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md), it also holds durable spend, audit, and identity tables that should be backed up. TLS via `?sslmode=require` is recommended. PostgreSQL 11, 12, and 13 require Claude Code v2.1.290 or later on the gateway server. The PostgreSQL project no longer maintains those versions, so use a newer one where you can. |74| PostgreSQL 11 or later | Backs the device sign-in flow and rate-limit counters. A managed PostgreSQL service works, including the smallest tier; see [which databases are supported](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#postgres). With [spend limits](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md), it also holds durable spend, audit, and identity tables that should be backed up. TLS via `?sslmode=require` is recommended. PostgreSQL 11, 12, and 13 require Claude Code v2.1.290 or later on the gateway server. The PostgreSQL project no longer maintains those versions, so use a newer one where you can. |

75| Model upstream | Amazon Bedrock credentials, Claude Platform on AWS credentials, Google Cloud credentials, a Microsoft Foundry resource, or an Anthropic API key. Multiple upstreams are supported with failover. |75| Model upstream | Amazon Bedrock credentials, Claude Platform on AWS credentials, Google Cloud credentials, a Microsoft Foundry resource, or an Anthropic API key. Multiple upstreams are supported with failover. |

76| HTTPS | The gateway must be reachable over `https://` from developer laptops and from any browser used for sign-in; the gateway serves the device-verification page on the same listener. Either provide a TLS cert via `listen.tls` or run behind a TLS-terminating ingress, and set `listen.public_url` to the external origin in both cases. At `/login`, Claude Code accepts a plain `http://` origin only when the gateway host is loopback: `localhost`, `127.0.0.1`, or `::1`. |76| HTTPS | The gateway must be reachable over `https://` from developer laptops and from any browser used for sign-in; the gateway serves the device-verification page on the same listener. Either provide a TLS cert via `listen.tls` or run behind a TLS-terminating ingress, and set `listen.public_url` to the external origin in both cases. At `/login`, Claude Code accepts a plain `http://` origin only when the gateway host is loopback: `localhost`, `127.0.0.1`, or `::1`. |

77| Private-network address | At `/login`, Claude Code requires the gateway's hostname or IP address to resolve only to private addresses: RFC 1918, link-local, CGNAT `100.64.0.0/10`, IPv6 ULA `fc00::/7`, or loopback. For a gateway you host, any public address outside a block you declare is rejected; see the [threat model](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#threat-model-summary) in the deployment guide. If developer machines route HTTPS through a corporate proxy, sign-in also requires the proxy host to resolve to private addresses; if it doesn't, add the gateway host to `NO_PROXY` so the CLI connects directly. If your internal network is numbered from public IPv4 space your organization owns, [declare those blocks](#allow-a-gateway-on-public-address-space-you-own) so `/login` accepts a gateway there. |77| Private-network address | Claude Code's `/login` requires the gateway's hostname or IP address to resolve only to private addresses: RFC 1918 and link-local ranges, CGNAT `100.64.0.0/10`, IPv6 ULA `fc00::/7` and loopback. See the [threat model](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#threat-model-summary). If your internal network is numbered from public IPv4 space your organization owns, [declare those blocks](#allow-a-gateway-on-public-address-space-you-own) so `/login` accepts a gateway there. |

78| Linux runtime | The gateway server runs only on the native Linux binary. macOS works for local development. Windows isn't supported as a server platform. |78| Linux runtime | The gateway server runs only on the native Linux binary. macOS works for local development. Windows isn't supported as a server platform. |

79 79 

80When `HTTPS_PROXY` or `HTTP_PROXY` applies to the gateway host, sign-in also needs either a proxy whose hostname resolves to private addresses or the gateway host in `NO_PROXY` on developer machines. If those machines also set `no_proxy`, add the gateway host there too, or model requests still go through the proxy.

81 

80### Steps82### Steps

81 83 

82**1. Register an OAuth client in your IdP**84**1. Register an OAuth client in your IdP**

Details

16 16 

17## File structure17## File structure

18 18 

19Five sections are [required](#required-sections). Every other section is [optional](#optional-sections), and an omitted section takes its defaults. Unknown keys fail boot, so a typo surfaces as a named error rather than a silently ignored setting.19Five sections are [required](#required-sections). Every other section is [optional](#optional-sections), and an omitted section takes its defaults.

20 20 

21**Required sections:**21**Required sections:**

22 22 


519 519 

520Requires a gateway running Claude Code v2.1.281 or later. [Cost attribution on AWS](https://code.claude.com/docs/en/claude-apps-gateway-on-aws.md#cost-attribution) covers the IAM role and where AWS billing shows the sessions.520Requires a gateway running Claude Code v2.1.281 or later. [Cost attribution on AWS](https://code.claude.com/docs/en/claude-apps-gateway-on-aws.md#cost-attribution) covers the IAM role and where AWS billing shows the sessions.

521 521 

522> [!NOTE]

523>

524> For per-developer attribution, set `assume_role` with `session_name` on every `bedrock` and [`mantle`](#amazon-bedrock-mantle-endpoint) upstream except those that use `aws_bearer_token`. Those [can't take `assume_role`](#bedrock-in-another-aws-account), so their requests stay under one principal.

525 

522```yaml theme={null}526```yaml theme={null}

523upstreams:527upstreams:

524 - provider: bedrock528 - provider: bedrock


535 539 

536The gateway also makes one call of its own on this role: the token count for a request the client abandoned, so that [spend limits](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md) stay accurate. That count and its [one-token fallback request](#amazon-bedrock) are signed by the shared `claude-apps-gateway` session, so AWS attributes the fallback to `claude-apps-gateway` rather than to the developer.540The gateway also makes one call of its own on this role: the token count for a request the client abandoned, so that [spend limits](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md) stay accurate. That count and its [one-token fallback request](#amazon-bedrock) are signed by the shared `claude-apps-gateway` session, so AWS attributes the fallback to `claude-apps-gateway` rather than to the developer.

537 541 

538For strict per-developer attribution, set `assume_role` with `session_name` on every Bedrock upstream you list. An upstream without it signs the requests it serves with its own credentials.

539 

540#### Amazon Bedrock Mantle endpoint542#### Amazon Bedrock Mantle endpoint

541 543 

542The `mantle` provider sends inference to Amazon Bedrock's [Mantle endpoint](https://code.claude.com/docs/en/amazon-bedrock.md#use-the-mantle-endpoint). It requires Claude Code v2.1.283 or later on the gateway server. Earlier gateway releases reject it at boot, so upgrade every replica before adding it.544The `mantle` provider sends inference to Amazon Bedrock's [Mantle endpoint](https://code.claude.com/docs/en/amazon-bedrock.md#use-the-mantle-endpoint). It requires Claude Code v2.1.283 or later on the gateway server. Earlier gateway releases reject it at boot, so upgrade every replica before adding it.


656 658 

657| Setup | How |659| Setup | How |

658| - | - |660| - | - |

659| RBAC | Grant the gateway's identity `Azure AI User` or `Cognitive Services User` on the Microsoft Foundry resource |661| RBAC | Grant the gateway's identity the `Foundry User` or `Cognitive Services User` role on the Microsoft Foundry resource |

660| Deployments | Microsoft Foundry uses admin-chosen deployment names, not canonical model IDs. Add a [`models:`](#models) block mapping each canonical ID to your deployment name. |662| Deployments | Microsoft Foundry uses admin-chosen deployment names, not canonical model IDs. Add a [`models:`](#models) block mapping each canonical ID to your deployment name. |

661| AKS (workload identity) | Federate a User-Assigned Managed Identity with the cluster's OIDC issuer and bind it to the gateway's service account. `use_azure_ad: true` picks it up via `WorkloadIdentityCredential`. |663| AKS (workload identity) | Federate a User-Assigned Managed Identity with the cluster's OIDC issuer and bind it to the gateway's service account. `use_azure_ad: true` picks it up via `WorkloadIdentityCredential`. |

662| ACI / App Service | Enable system-assigned or user-assigned managed identity on the resource. `use_azure_ad: true` picks it up. |664| ACI / App Service | Enable system-assigned or user-assigned managed identity on the resource. `use_azure_ad: true` picks it up. |


1001 1003 

1002Each key under `upstream_model` must match the `name` of a configured upstream, which defaults to the provider name. A key that matches no upstream fails boot, so omit the lines for providers you don't use.1004Each key under `upstream_model` must match the `name` of a configured upstream, which defaults to the provider name. A key that matches no upstream fails boot, so omit the lines for providers you don't use.

1003 1005 

1006To let developers use the `fable` alias with `auto_include_builtin_models: false`, add a `claude-fable-5` entry to `models`. That's the ID the [`fable` alias](https://code.claude.com/docs/en/model-config#fable-alias-resolution) resolves to for developers signed in to the gateway. Without it, their messages fail with an error that starts with `API Error: 400 model claude-fable-5 is not in the operator's model allowlist`.

1007 

1004### `managed`1008### `managed`

1005 1009 

1006The `managed` block defines role-based access policies keyed on IdP groups or email domain. Policies are evaluated in order; by default the first match is selected, then merged onto the `match: {}` catch-all base. A user who matches two role policies gets only the first, so the second policy's deny rules don't apply unless you [apply every matching policy](#apply-every-matching-policy). Policies are served per-user at `GET /managed/settings` with ETag/304 caching.1010The `managed` block defines role-based access policies keyed on IdP groups or email domain. Policies are evaluated in order; by default the first match is selected, then merged onto the `match: {}` catch-all base. A user who matches two role policies gets only the first, so the second policy's deny rules don't apply unless you [apply every matching policy](#apply-every-matching-policy). Policies are served per-user at `GET /managed/settings` with ETag/304 caching.


1025A `match: {}` catch-all, conventionally listed last, is treated as a base layer. Every other policy inherits any key it doesn't set from the catch-all, so per-role entries only need to list what differs from the org default. The merge rules depend on the key type:1029A `match: {}` catch-all, conventionally listed last, is treated as a base layer. Every other policy inherits any key it doesn't set from the catch-all, so per-role entries only need to list what differs from the org default. The merge rules depend on the key type:

1026 1030 

1027* **Allow-lists**: `availableModels` and `permissions.allow`. A specific policy's list fully replaces the base's.1031* **Allow-lists**: `availableModels` and `permissions.allow`. A specific policy's list fully replaces the base's.

1028* **Deny-lists and hook arrays**: `permissions.deny`, `permissions.ask`, `disabledMcpjsonServers`, `deniedMcpServers`, `blockedMarketplaces`, `deniedModels`, and every `hooks` event-type array. These take the union of base and policy, so an org-wide deny or audit hook can't be accidentally dropped by a per-role override.1032* **Deny-lists and hook arrays**: these take the union of base and policy:

1033 * `permissions.deny` and `permissions.ask`

1034 * `disabledMcpjsonServers` and `deniedMcpServers`

1035 * `blockedMarketplaces` and `deniedModels`

1036 * The `hooks` event-type arrays

1029* **Record-typed keys**: `env`, `modelOverrides`, and `skillOverrides`. These shallow-merge, so a per-role `env` block overrides keys it sets and inherits the rest from the base.1037* **Record-typed keys**: `env`, `modelOverrides`, and `skillOverrides`. These shallow-merge, so a per-role `env` block overrides keys it sets and inherits the rest from the base.

1030 1038 

1031`availableModels` is also enforced server-side at `/v1/messages`, so a denied model returns `400` regardless of what the client sends. An empty list denies every model. The check also covers the model a session starts on before the developer picks one, so [start sessions on a model the policy allows](#start-sessions-on-a-model-the-policy-allows).1039`availableModels` is also enforced server-side at `/v1/messages`, so a denied model returns `400` regardless of what the client sends. An empty list denies every model. The check also covers the model a session starts on before the developer picks one, so [start sessions on a model the policy allows](#start-sessions-on-a-model-the-policy-allows).


1277 1285 

1278To turn off 1M context instead, set [`CLAUDE_CODE_DISABLE_1M_CONTEXT: "1"`](https://code.claude.com/docs/en/model-config#extended-context) in the same `env` block. Claude Code then treats every model as having a 200K window. In interactive sessions, each developer approves this variable in the [approval dialog](#what-goes-in-cli) before it takes effect.1286To turn off 1M context instead, set [`CLAUDE_CODE_DISABLE_1M_CONTEXT: "1"`](https://code.claude.com/docs/en/model-config#extended-context) in the same `env` block. Claude Code then treats every model as having a 200K window. In interactive sessions, each developer approves this variable in the [approval dialog](#what-goes-in-cli) before it takes effect.

1279 1287 

1288> [!NOTE]

1289>

1290> Claude Code doesn't read an alias's `upstream_model` to size its context window. To give its model's window to an alias in `models` that Claude Code doesn't recognize, see [Correct the window for a gateway or custom model ID](https://code.claude.com/docs/en/model-config.md#correct-the-window-for-a-gateway-or-custom-model-id).

1291 

1280#### One-hour prompt cache1292#### One-hour prompt cache

1281 1293 

1282To request the one-hour [prompt cache TTL](https://code.claude.com/docs/en/prompt-caching.md#cache-lifetime) instead of the default five minutes, add these keys to a policy's existing [`code`, `cli`, or `settings` block](#choose-cli-or-code) and restart the gateway. The keys need Claude Code v2.1.242 or later on the gateway server and on clients.1294To request the one-hour [prompt cache TTL](https://code.claude.com/docs/en/prompt-caching.md#cache-lifetime) instead of the default five minutes, add these keys to a policy's existing [`code`, `cli`, or `settings` block](#choose-cli-or-code) and restart the gateway. The keys need Claude Code v2.1.242 or later on the gateway server and on clients.


1379 1391 

1380##### What the gateway rejects at boot1392##### What the gateway rejects at boot

1381 1393 

1382The gateway validates each `desktop` block at boot against the configuration schema Claude Desktop itself uses, so a mistake surfaces at gateway start as an error naming the key rather than reaching every connected desktop. The gateway fails at boot when a block contains:1394The gateway fails at boot when a `desktop` block contains:

1383 1395 

1384* An unknown key1396* A recognized key whose value Claude Desktop would reject or silently drop, such as an empty value.

1385* A recognized key whose value Claude Desktop would reject or silently drop, such as an empty value or a misspelled sub-key inside a nested entry. Before v2.1.260, the gateway silently dropped a misspelled field inside a nested object of a `managedMcpServers` or `orgPluginSettings` entry instead of failing at boot.

1386* A key the gateway computes itself: the inference connection, the model list, and the OTLP relay. Configure those through [`upstreams`](#upstreams), [`models`](#models), and the [`telemetry`](#telemetry) section's `forward_to`.1397* A key the gateway computes itself: the inference connection, the model list, and the OTLP relay. Configure those through [`upstreams`](#upstreams), [`models`](#models), and the [`telemetry`](#telemetry) section's `forward_to`.

1387* A legacy alias of a current key. In the boot error, the gateway names the canonical key to write.1398* A legacy alias of a current key. In the boot error, the gateway names the canonical key to write.

1399* From v2.1.300, any key whose name starts with `selfHosted`, such as the keys for a self-hosted session host. Remove these keys before you upgrade the gateway to v2.1.300 or later.

1388 1400 

1389If you use a deprecated value or entry shape, such as a `managedMcpServers` entry without `transport`, the gateway starts and logs a warning that names the replacement.1401If you use a deprecated value or entry shape, such as a `managedMcpServers` entry without `transport`, the gateway starts and logs a warning that names the replacement.

1390 1402 

1391Before v2.1.232, the gateway accepted a fixed list of 11 feature-gate keys, such as `chatTabEnabled` and `disableAutoUpdates`, and rejected every other key at boot. Before v2.1.227, the gateway also rejected `chatTabEnabled` and `chatAdvancedFileAnalysisEnabled` at boot.1403Before v2.1.232, the gateway accepted a fixed list of 11 feature-gate keys, such as `chatTabEnabled` and `disableAutoUpdates`, and rejected every other key at boot. Before v2.1.227, the gateway also rejected `chatTabEnabled` and `chatAdvancedFileAnalysisEnabled` at boot.

1392 1404 

1405##### Keys the gateway doesn't know

1406 

1407On a gateway running Claude Code v2.1.295 or later, most keys from a newer Claude Desktop release need no gateway upgrade. On v2.1.321 or later, neither do most new sub-keys inside a known key.

1408 

1409Some keys and values still fail at boot, such as these:

1410 

1411* A new choice in a known key's fixed list of values.

1412* A likely typo of a key you can set in a `desktop` block, such as `disable_auto_updates` for `disableAutoUpdates`. The error suggests a name.

1413 

1414In each case, if the name or value is real in a newer Claude Desktop release, [upgrade the gateway](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#upgrades) to the latest release. Otherwise correct or remove it. To find out before you deploy, [test the policy](#test-a-policy-before-deployment).

1415 

1393##### Keys that need a later gateway or Claude Desktop version1416##### Keys that need a later gateway or Claude Desktop version

1394 1417 

1395The gateway validates a `desktop` block against the schema bundled with its installed version, as it does the `cli` block. To deliver a setting introduced by a newer Claude Desktop release, upgrade the gateway first. For example, `userPluginMarketplacesEnabled` and `userPluginUploadsEnabled` need Claude Code v2.1.260 or later on the gateway server and Claude Desktop 1.37937.0 or later on members' machines.1418`userPluginMarketplacesEnabled` and `userPluginUploadsEnabled` need Claude Code v2.1.260 or later on the gateway server and Claude Desktop 1.37937.0 or later on members' machines.

1396 1419 

1397`blockReadsOutsideWorkingDirectories`, `disableBypassPermissionsMode`, `configRecheckIntervalMinutes`, and `sshClientPath` need Claude Code v2.1.281 or later on the gateway server. So do the `required` value of `microsoftAuthBroker` and the `continuousAccessEvaluation` field of a Microsoft 365 `managedMcpServers` entry. Claude Desktop releases that predate the `required` value read it as `disabled`, so set `required` only after every member's Claude Desktop supports it. Claude Desktop's [managed configuration reference](https://claude.com/docs/third-party/claude-desktop/configuration) lists the release that first reads each key.1420`blockReadsOutsideWorkingDirectories`, `disableBypassPermissionsMode`, `configRecheckIntervalMinutes`, and `sshClientPath` need Claude Code v2.1.281 or later on the gateway server. So do the `required` value of `microsoftAuthBroker` and the `continuousAccessEvaluation` field of a Microsoft 365 `managedMcpServers` entry. Claude Desktop releases that predate the `required` value read it as `disabled`, so set `required` only after every member's Claude Desktop supports it. Claude Desktop's [managed configuration reference](https://claude.com/docs/third-party/claude-desktop/configuration) lists the release that first reads each key.

1398 1421 

Details

189 189 

190```190```

191Sent to cloud session.191Sent to cloud session.

192Session ID: session_01DiUkqY2kzbUbDmW1w96rfi192Session ID: session_01HJKLMNOPQRSTUVWXYZ

193View: https://claude.ai/code/session_01DiUkqY2kzbUbDmW1w96rfi?from=cli&m=0193View: https://claude.ai/code/session_01HJKLMNOPQRSTUVWXYZ?from=cli&m=0

194```194```

195 195 

196Pass `--output-format json` for a machine-readable result: `{ok, session_id, url}` on success, or `{ok: false, session_id, error}` when the send fails, for example when the session is missing or archived. Configuration errors, such as an unsupported provider or a disabled organization policy, print to stderr without JSON. `--output-format stream-json` isn't supported with `--cloud <session-id>`.196Pass `--output-format json` for a machine-readable result: `{ok, session_id, url}` on success, or `{ok: false, session_id, error}` when the send fails, for example when the session is missing or archived. Configuration errors, such as an unsupported provider or a disabled organization policy, print to stderr without JSON. `--output-format stream-json` isn't supported with `--cloud <session-id>`.

Details

163Claude decides where each message you send in the conversation goes:163Claude decides where each message you send in the conversation goes:

164 164 

165* A quick question usually gets an answer in the conversation.165* A quick question usually gets an answer in the conversation.

166* New work goes to a new thread or to a thread already working in that area, and Claude tells you which. Each new thread shows up under your message as a card: a box with the thread's title and status, which you click to open the thread.166* New work goes to a new thread or to a thread already working in that area, and Claude tells you which. Each new thread shows up in the conversation, and you click it to open the thread.

167* Several unrelated tasks in one message become separate threads.167* Several unrelated tasks in one message become separate threads.

168 168 

169If Claude routes something differently than you wanted, say so. [Tune how Claude runs a project](#tune-how-claude-runs-a-project) lists things you can tell it, such as reusing an existing thread for follow-ups or answering in place instead of starting a thread.169If Claude routes something differently than you wanted, say so. [Tune how Claude runs a project](#tune-how-claude-runs-a-project) lists things you can tell it, such as reusing an existing thread for follow-ups or answering in place instead of starting a thread.

170 170 

171A thread's full results stay in the thread, and you open its card in the conversation to read them. Files a thread produced are also in the project's [**Library**](#see-what-needs-you-in-overview).171A thread's full results stay in the thread, so open the thread to read them. Files a thread produced are also in the project's [**Library**](#see-what-needs-you-in-overview).

172 172 

173Sometimes Claude proposes threads instead of starting them, in a **Suggested threads** list. Click the arrow on a suggestion to start that thread. When several are listed, a button under the list starts all of them.173Sometimes Claude proposes threads instead of starting them, in a **Suggested threads** list. Click the arrow on a suggestion to start that thread. When several are listed, a button under the list starts all of them.

174 174 


180* **Pull request**: opens one when you ask, and can open one on its own for a bug fix or another concrete change.180* **Pull request**: opens one when you ask, and can open one on its own for a bug fix or another concrete change.

181* **After it opens**: watches the pull request with [auto-fix](https://code.claude.com/docs/en/claude-code-on-the-web.md#auto-fix-pull-requests) turned on, whether or not auto-fix is on for your other cloud sessions. It pushes fixes when CI fails, addresses review comments, and replies in the thread when checks pass and the pull request is ready for you.181* **After it opens**: watches the pull request with [auto-fix](https://code.claude.com/docs/en/claude-code-on-the-web.md#auto-fix-pull-requests) turned on, whether or not auto-fix is on for your other cloud sessions. It pushes fixes when CI fails, addresses review comments, and replies in the thread when checks pass and the pull request is ready for you.

182 182 

183When a thread has pushed a branch or opened a pull request, its card in the conversation can show a button for the next step:

184 

185* **Resolve conflicts**, **Fix CI**, **Address comments**, and **Merge it** send that instruction to the thread as a message from you, so you can prompt the thread yourself instead of waiting for it to react to the pull request.

186* **Review PR** opens the pull request on GitHub.

187* **Create PR** appears when an idle thread has pushed a branch but hasn't opened a pull request. Clicking it creates the pull request from that branch directly rather than sending the thread an instruction to open one.

188 

189To change when threads open pull requests, for example only when you ask, or which branch they start from, say so in the task or in [project instructions](#write-project-instructions).183To change when threads open pull requests, for example only when you ask, or which branch they start from, say so in the task or in [project instructions](#write-project-instructions).

190 184 

191### See what needs you in Overview185### See what needs you in Overview


212 206 

213### Open a thread when you need control207### Open a thread when you need control

214 208 

215Click a thread's card in the conversation or its row in Overview to open its transcript in the Overview pane. From there you can:209Click a thread in the conversation or its row in Overview to open the thread in the Overview pane. From there you can:

216 210 

217* Read what Claude did, step by step.211* Read what Claude did, step by step.

218* Steer the task by writing in the thread's own message box. A message there goes straight to that thread, while a follow-up in the project conversation reaches it only when Claude matches the follow-up to that thread.212* Steer the task by writing in the thread's own message box. A message there goes straight to that thread, while a follow-up in the project conversation reaches it only when Claude matches the follow-up to that thread.


274 268 

275The thread runs in [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), so Claude runs commands and edits files in that folder without asking you each time. If auto mode is unavailable or turned off in that computer's Claude Code, the thread runs without it, and any permission prompt it raises waits for your answer in the thread, as [Unblock a thread waiting on approval](#unblock-a-thread-waiting-on-approval) describes.269The thread runs in [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), so Claude runs commands and edits files in that folder without asking you each time. If auto mode is unavailable or turned off in that computer's Claude Code, the thread runs without it, and any permission prompt it raises waits for your answer in the thread, as [Unblock a thread waiting on approval](#unblock-a-thread-waiting-on-approval) describes.

276 270 

271To run the thread in another mode, start `claude remote-control` with [`--settings`](https://code.claude.com/docs/en/remote-control#start-a-remote-control-session). Then [`permissions.defaultMode`](https://code.claude.com/docs/en/permission-modes#start-in-a-different-mode), in that file or in that computer's settings, can pick another mode.

272 

277While the thread runs, a laptop icon in its header shows whether your computer is connected. Click it to see which folder the thread is using or to turn the connection off. The thread pauses while that computer is asleep, and stops if the desktop app or `claude remote-control` quits.273While the thread runs, a laptop icon in its header shows whether your computer is connected. Click it to see which folder the thread is using or to turn the connection off. The thread pauses while that computer is asleep, and stops if the desktop app or `claude remote-control` quits.

278 274 

279* **To get the thread going again**: see [Lost contact with your folder](#lost-contact-with-your-folder)275* **To get the thread going again**: see [Lost contact with your folder](#lost-contact-with-your-folder)

code-mode.md +224 −0 created

Details

1> ## Documentation Index

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

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

4 

5# Run tool calls from code with Code Mode

6 

7> Try Code Mode, an experimental feature in which Claude writes JavaScript that makes several tool calls in one step.

8 

9Code Mode changes how Claude uses its [tools](https://code.claude.com/docs/en/tools-reference.md). Without Code Mode, Claude asks for tool calls such as Bash, Read, or Edit directly and reads each result before it decides what to do next. With Code Mode, Claude writes a piece of JavaScript that makes the tool calls, and Claude Code runs that code in your session.

10 

11> [!NOTE]

12>

13> Code Mode is experimental and off by default. It may change or be removed in any release. To share feedback, run `/feedback`.

14 

15## How Code Mode works

16 

17In a Code Mode session, you still describe your task in a prompt, and Claude writes JavaScript to carry it out. One piece of code can run commands in parallel, use one result in the next call, and return the part of the output that Claude needs to read.

18 

19For example, if you ask Claude to raise a retry limit, Claude might write this code to find the file, edit it, and run the tests. The last line returns the file's path and the test output to Claude:

20 

21```javascript theme={null}

22const files = await $`rg -l "function retryPolicy" src`.text();

23const target = files.trim().split("\n")[0];

24await edit(target, "maxAttempts: 3", "maxAttempts: 5");

25({ edited: target, tests: $`npm test -- retryPolicy`.nothrow() });

26```

27 

28In the conversation, you see the tool calls, such as the edit's diff, and not the code. To read the code, press `Ctrl+O` to open the [transcript viewer](https://code.claude.com/docs/en/interactive-mode.md#transcript-viewer). Each piece of code appears there as a collapsed **Code** row, with a hint for how to expand it.

29 

30### When to use Code Mode

31 

32Try Code Mode on tasks that take many related tool calls, such as:

33 

34* A change that repeats across many files

35* A search whose results need filtering before Claude reads them

36* Several independent commands that can run at the same time

37 

38### Code Mode limitations

39 

40Before you turn on Code Mode, check that you can accept these limits:

41 

42* **Resuming**: you can resume a Code Mode session only in the terminal, with Code Mode on

43* **Auto mode**: auto mode's classifier [reviews the code, not each tool call](#permission-checks)

44* **Long-running code**: unless [code can run in the background](#long-running-code), you wait for it to finish, and it stops after ten minutes

45* **Hooks**: you can see [tool calls refused](#tool-call-refused-by-a-hook) when a `PreToolUse` hook can't run or times out, and [code output blocked](#code-output-withheld-by-a-hook) by a `UserPromptSubmit` hook

46* **Unavailable features**: you can't use [Remote Control](https://code.claude.com/docs/en/remote-control.md), [Claude in Chrome](https://code.claude.com/docs/en/chrome.md), or [computer use](https://code.claude.com/docs/en/computer-use.md)

47* **Moving the session**: you can't move the session to the Desktop app or turn it into a [background session](https://code.claude.com/docs/en/agent-view.md), and `/fork` can't start a background copy

48 

49## Requirements

50 

51* **Version**: Claude Code v2.1.323 or later, on either [release channel](https://code.claude.com/docs/en/setup.md#configure-release-channel). An older version starts without Code Mode, with or without the reason `it isn't open to your account yet`

52* **Account**: a Claude subscription or Console account. You can't use Code Mode through a gateway, Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform, or Microsoft Foundry

53* **Organization**: your organization doesn't use the [HIPAA configuration](https://code.claude.com/docs/en/hipaa-setup.md) or [zero data retention](https://code.claude.com/docs/en/zero-data-retention.md)

54* **Model**: Claude Opus 5.5, Sonnet 5.5, Haiku 5.5, or Fable 5.2

55* **Surface**: an interactive `claude` session in a terminal. Code Mode doesn't work with `-p`, the Agent SDK, the VS Code panel, the Desktop app, or cloud sessions

56* **Installation**: the [native build](https://code.claude.com/docs/en/setup.md) of Claude Code

57* **Windows**: [Git for Windows](https://git-scm.com/downloads/win) is installed

58 

59You also can't start Code Mode with some settings on, such as an API key helper, agent teams, OpenTelemetry export, or `DISABLE_TELEMETRY`. For the fix for each, see [Code Mode doesn't start](#code-mode-doesnt-start).

60 

61## Try Code Mode

62 

63Turn on Code Mode, give Claude a task, and look at the code that Claude wrote.

64 

65**1. Check your version**

66 

67Run `claude --version`. If the version is older than v2.1.323, run `claude update`. If you're on the `stable` channel and the update doesn't reach v2.1.323, wait for `stable` to catch up or [switch to `latest`](https://code.claude.com/docs/en/setup#configure-release-channel).

68 

69**2. Start Claude Code with Code Mode on**

70 

71Set the [`CLAUDE_CODE_EXPERIMENTAL_CODE_MODE`](https://code.claude.com/docs/en/env-vars#variables) environment variable to `1`. To try Code Mode, set it in your shell. To turn on Code Mode for every new session, set it in your user settings.

72 

73> [tab] macOS, Linux, WSL

74>

75> ```bash theme={null}

76> CLAUDE_CODE_EXPERIMENTAL_CODE_MODE=1 claude

77> ```

78 

79> [tab] Windows PowerShell

80>

81> ```powershell theme={null}

82> $env:CLAUDE_CODE_EXPERIMENTAL_CODE_MODE = "1"

83> claude

84> ```

85 

86> [tab] settings.json

87>

88> Save this `env` block in `~/.claude/settings.json` and start `claude`:

89>

90> ```json theme={null}

91> {

92> "env": {

93> "CLAUDE_CODE_EXPERIMENTAL_CODE_MODE": "1"

94> }

95> }

96> ```

97>

98> Claude Code [ignores this variable in a project's settings files](https://code.claude.com/docs/en/settings-reference.md#variables-claude-code-ignores-in-env), so a repository you clone can't turn on Code Mode for you.

99 

100**3. Confirm that you want Code Mode**

101 

102Claude Code asks you to confirm before your first Code Mode session. Select **Yes, turn on Code Mode**. Claude Code restarts and shows this line near the top of the session:

103 

104```text theme={null}

105Code Mode (experimental) is on · this session can be resumed only with Code Mode on

106```

107 

108If you see a different line or none, see [Code Mode doesn't start](#code-mode-doesnt-start).

109 

110**4. Give Claude a task with many tool calls**

111 

112In a project you know, send a prompt such as this one:

113 

114```text theme={null}

115Read every Markdown file in this project and list the links that point to local files that don't exist.

116```

117 

118**5. Read the code Claude wrote**

119 

120Press `Ctrl+O` and expand a **Code** row to see the JavaScript behind the tool calls. Press `Ctrl+O` again to return to the conversation.

121 

122> [!WARNING]

123>

124> To resume a Code Mode session later, keep `CLAUDE_CODE_EXPERIMENTAL_CODE_MODE` set to `1` when you run `claude --continue` or `claude --resume`. With Code Mode off, Claude Code refuses to resume the session. Sessions that you started without Code Mode resume without Code Mode, even with the variable set.

125 

126### Turn off Code Mode

127 

128Remove `CLAUDE_CODE_EXPERIMENTAL_CODE_MODE` from your shell and from `~/.claude/settings.json`, then start a new session. You can also keep the variable and change its value to `0` in either place. With a `0` in one place, Code Mode stays off even if you set `1` in the other.

129 

130### Block Code Mode for your organization

131 

132Add `CLAUDE_CODE_EXPERIMENTAL_CODE_MODE` with the value `0` to your [managed settings](https://code.claude.com/docs/en/managed-settings.md) so that nobody in your organization can use Code Mode:

133 

134```json theme={null}

135{

136 "env": {

137 "CLAUDE_CODE_EXPERIMENTAL_CODE_MODE": "0"

138 }

139}

140```

141 

142Users who are in a Code Mode session stay in it until they exit or restart Claude Code. After that, your users start without Code Mode and can't resume their Code Mode sessions while the `0` is in place. You can't turn on Code Mode for your users from managed settings.

143 

144## Permissions and long-running code

145 

146Your permission mode decides how Claude's code is checked and whether you can talk to Claude while the code runs.

147 

148### Permission checks

149 

150Each tool call that Claude's code makes goes through your `deny` and `ask` [permission rules](https://code.claude.com/docs/en/permissions.md) and your [`PreToolUse` hooks](https://code.claude.com/docs/en/hooks#pretooluse). You don't need to change a rule or matcher for a tool such as `Bash`. Beyond rules and hooks, a classifier reviews the code in auto mode, and you answer prompts in the modes that ask:

151 

152* **[Auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode)**: the classifier reviews each piece of code before it runs, not each tool call. It doesn't see values computed at run time, such as a path taken from search output, so keep rules or hooks for calls you must control. You can still be [prompted when new code starts while earlier code runs](#permission-prompt-with-a-countdown)

153* **Other [permission modes](https://code.claude.com/docs/en/permission-modes.md)**: the code starts without a review, and you're prompted for each tool call that would prompt you in that mode

154 

155To check the code itself, write a `PreToolUse` hook that matches `REPL`, the tool that runs Claude's code, and read the JavaScript from `tool_input.code`.

156 

157> [!WARNING]

158>

159> Bash rules match command text, so Claude can run a denied command [in a form the rule doesn't match](https://code.claude.com/docs/en/permissions.md#bash-rule-limits), with or without Code Mode. For limits that don't depend on command text, see [sandboxing](https://code.claude.com/docs/en/sandboxing.md).

160 

161### Long-running code

162 

163While code runs a long build or test, Claude either waits for it or lets it continue in the background:

164 

165* **Waiting**: Claude answers after the code finishes, and the code stops after ten minutes, including time you spend at permission prompts

166* **Background**: you can keep talking to Claude, and the code can run for up to two hours

167 

168For background code, start your session in auto or `bypassPermissions` mode. If Claude still waits, check your current mode and how you started the session:

169 

170* **You switched to another mode**: press `Shift+Tab` until you're back in the mode you started in

171* **You started in another mode, or picked the session from the `claude --resume` list**: if [auto mode is available](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) to you, exit, then run `claude --continue --permission-mode auto` with Code Mode on

172* **You passed tool names to `--tools`**: start again in auto mode without that flag

173 

174## Troubleshooting

175 

176### Code Mode doesn't start

177 

178`Code Mode (experimental) isn't available` near the top of the session means that Claude Code started without Code Mode. The reason follows on the same line, and `/status` shows it too. Find the reason in this table, make the change, and start a new session. For a reason that isn't listed, check the [requirements](#requirements).

179 

180| Reason includes | What to do |

181| :- | :- |

182| `it isn't open to your account yet` | If your version is older than v2.1.323, [update](#try-code-mode). Otherwise, check your network connection and start again. If the reason stays, try again another day |

183| `it only works with the Anthropic API` | Remove the settings that route requests through a cloud provider, a gateway, or a custom `ANTHROPIC_BASE_URL` |

184| `it doesn't work with an API key helper` | Remove `apiKeyHelper`, `ANTHROPIC_AUTH_TOKEN`, and any `Authorization` or `X-Api-Key` header in `ANTHROPIC_CUSTOM_HEADERS`. Then sign in or set `ANTHROPIC_API_KEY` |

185| `it only works with Opus 5.5, Sonnet 5.5 and later models` | Start with a [supported model](#requirements), for example with `--model opus`. Haiku 5.5 and Fable 5.2 also work |

186| `it doesn't work in background jobs` | Start in the foreground, without `--remote-control` |

187| `it needs settings that Claude Code downloads from Anthropic` | Unset the variable that [turns off feature-flag fetching](https://code.claude.com/docs/en/env-vars.md#features-that-need-feature-flag-fetching), such as `DISABLE_TELEMETRY` |

188| `OpenTelemetry is on` | Unset `CLAUDE_CODE_ENABLE_TELEMETRY` and `ENABLE_BETA_TRACING_DETAILED` if you can work without [OpenTelemetry export](https://code.claude.com/docs/en/monitoring-usage.md) |

189| `it doesn't yet work with an installed mod` | Turn off the [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) that checks tool calls |

190| `it can't be used together with agent teams yet` | Unset `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` |

191| `this launch's tool options` | Start without `--restricted`, add `REPL` to `--tools`, and remove `REPL` from `--disallowedTools` and your `deny` rules |

192| `couldn't save your answer` | Make `~/.claude.json` writable |

193| `your organization's settings don't allow it` | Ask your administrator about the [managed setting](#block-code-mode-for-your-organization) |

194 

195If you see no line about Code Mode, run `claude --version`. If your version is older than v2.1.323, update. Then check that `CLAUDE_CODE_EXPERIMENTAL_CODE_MODE` is `1` in your shell or user settings, and remove any `0` from those and from any `--settings` file.

196 

197### Permission prompt with a countdown

198 

199When Claude starts more code in auto mode while earlier code is still running, the earlier code loses its classifier review. Claude Code then asks you about the earlier code's remaining calls that would need a review. With no IDE connected, the prompt shows a countdown:

200 

201```text theme={null}

202Claude Code will automatically block this request in 1:59, to avoid holding up an unattended session

203```

204 

205Answer before the countdown ends. Otherwise that call is refused, and later calls that would show a countdown are refused without a prompt. To see the prompts again, send Claude a message.

206 

207### Tool call refused by a hook

208 

209If Claude reports a refused tool call, ask it for the error text. These errors mean that a `PreToolUse` hook didn't give a decision, which refuses the call even when [`onFailure`](https://code.claude.com/docs/en/hooks#block-the-action-when-a-hook-fails) is unset:

210 

211* **`the hook failed`**: on a call from Claude's code, your hook couldn't start, was killed, exited with 126, 127, or a code above 128, or returned an HTTP error or invalid output. Fix the hook

212* **`the hook did not finish`**: your hook timed out on a call from Claude's code, or on any other tool call once Claude has run code in the session. Raise the hook's [`timeout`](https://code.claude.com/docs/en/hooks#common-fields)

213 

214To let calls go ahead when a `command` or `http` hook fails or times out, set `"onFailure": "continue"` on it. If a `command` hook exits with an ordinary code such as 1, the call goes ahead unless you set `"onFailure": "block"`.

215 

216### Code output withheld by a hook

217 

218If Claude reports a hook's block reason where you expected output from Claude's code, check your [`UserPromptSubmit`](https://code.claude.com/docs/en/hooks#userpromptsubmit) hooks. When [code can run in the background](#long-running-code), `command`, `http`, and `mcp_tool` hooks on that event also run on code output. To let the output through, change the hook so that it doesn't block when `source` in its input is `poll_event`.

219 

220## Related resources

221 

222* [Permission modes](https://code.claude.com/docs/en/permission-modes.md): compare auto mode with the modes that prompt you

223* [Hooks reference](https://code.claude.com/docs/en/hooks.md): write `PreToolUse` and `UserPromptSubmit` hooks

224* [Managed settings](https://code.claude.com/docs/en/managed-settings.md): apply one configuration across an organization

commands.md +3 −5

Details

35The table below lists all the commands included in Claude Code. Most are built-in commands whose behavior is coded into the CLI. Two kinds of entries are marked:35The table below lists all the commands included in Claude Code. Most are built-in commands whose behavior is coded into the CLI. Two kinds of entries are marked:

36 36 

37* **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills)**: a bundled skill. It works like skills you write yourself: a prompt handed to Claude.37* **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills)**: a bundled skill. It works like skills you write yourself: a prompt handed to Claude.

38 * `/verify` runs only when you invoke it.

39* **[Workflow](https://code.claude.com/docs/en/workflows.md#bundled-workflows)**: a bundled [dynamic workflow](https://code.claude.com/docs/en/workflows.md) that fans work out across many subagents and runs in the background.38* **[Workflow](https://code.claude.com/docs/en/workflows.md#bundled-workflows)**: a bundled [dynamic workflow](https://code.claude.com/docs/en/workflows.md) that fans work out across many subagents and runs in the background.

40 * `/deep-research` runs only when you invoke it.

41 39 

42To add your own commands, see [skills](https://code.claude.com/docs/en/skills.md).40To add your own commands, see [skills](https://code.claude.com/docs/en/skills.md).

43 41 


149| `/stats` | Alias for `/usage`. Opens on the Stats tab |147| `/stats` | Alias for `/usage`. Opens on the Stats tab |

150| `/status` | Open the Settings interface on the Status tab, showing version, model, account, and connectivity. A `Session kind` row reads `background job · attached` or `background job · unattended` in a [background session](https://code.claude.com/docs/en/agent-view.md), depending on whether a terminal is attached, and `interactive` in any other session. Before v2.1.221, `/status` didn't show this row. Works while Claude is responding |148| `/status` | Open the Settings interface on the Status tab, showing version, model, account, and connectivity. A `Session kind` row reads `background job · attached` or `background job · unattended` in a [background session](https://code.claude.com/docs/en/agent-view.md), depending on whether a terminal is attached, and `interactive` in any other session. Before v2.1.221, `/status` didn't show this row. Works while Claude is responding |

151| `/statusline` | Configure Claude Code's [status line](https://code.claude.com/docs/en/statusline.md). Describe what you want, or run without arguments to auto-configure from your shell prompt |149| `/statusline` | Configure Claude Code's [status line](https://code.claude.com/docs/en/statusline.md). Describe what you want, or run without arguments to auto-configure from your shell prompt |

152| `/stickers` | Order Claude Code stickers |150| `/stickers` | Check Claude Code sticker availability |

153| `/stop` | Stop the [background session](https://code.claude.com/docs/en/agent-view.md) you're attached to, or the one you send it to as a [peek reply](https://code.claude.com/docs/en/agent-view.md#peek-and-reply); the transcript and any worktree are kept. To detach without stopping, use `/exit` or press `←` |151| `/stop` | Stop the [background session](https://code.claude.com/docs/en/agent-view.md) you're attached to, or the one you send it to as a [peek reply](https://code.claude.com/docs/en/agent-view.md#peek-and-reply); the transcript and any worktree are kept. To detach without stopping, use `/exit` or press `←` |

154| `/subtask <task>` | Spawn a [forked subagent](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation): a background subagent that inherits the full conversation and works on the task while you keep working. Its result returns to this conversation when it finishes. To copy the conversation into a separate background session instead, use `/fork`. When [agent view is turned off](https://code.claude.com/docs/en/agent-view.md#turn-off-agent-view), `/subtask` isn't available and `/fork` spawns the forked subagent instead |152| `/subtask <task>` | Spawn a [forked subagent](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation): a background subagent that inherits the full conversation and works on the task while you keep working. Its result returns to this conversation when it finishes. To copy the conversation into a separate background session instead, use `/fork`. When [agent view is turned off](https://code.claude.com/docs/en/agent-view.md#turn-off-agent-view), `/subtask` isn't available and `/fork` spawns the forked subagent instead |

155| `/tasks` | View and manage background work in the current session, including subagents that have finished. Also available as `/bashes` |153| `/tasks` | View and manage background work in the current session, including subagents that have finished. Also available as `/bashes` |


161| `/ultraplan <prompt>` | Removed. Use [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) instead. Previously sent a planning task to a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md) for review in your browser |159| `/ultraplan <prompt>` | Removed. Use [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) instead. Previously sent a planning task to a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md) for review in your browser |

162| `/ultrareview [PR or branch]` | Run a deep, multi-agent code review in a cloud sandbox with [ultrareview](https://code.claude.com/docs/en/ultrareview.md). Pass a PR reference to review that pull request, or a base branch or commit to change the comparison base. The preferred invocation is `/code-review ultra`, and `/ultrareview` is an alias. Includes 3 free runs on Pro, Max, and Ultra, then requires [usage credits](https://support.claude.com/en/articles/12429409-extra-usage-for-paid-claude-plans) |160| `/ultrareview [PR or branch]` | Run a deep, multi-agent code review in a cloud sandbox with [ultrareview](https://code.claude.com/docs/en/ultrareview.md). Pass a PR reference to review that pull request, or a base branch or commit to change the comparison base. The preferred invocation is `/code-review ultra`, and `/ultrareview` is an alias. Includes 3 free runs on Pro, Max, and Ultra, then requires [usage credits](https://support.claude.com/en/articles/12429409-extra-usage-for-paid-claude-plans) |

163| `/update-config [request]` | **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills).** Describe a settings change, such as allowing a command, setting an environment variable, or adding a [hook](https://code.claude.com/docs/en/hooks.md), and Claude edits the matching [`settings.json`](https://code.claude.com/docs/en/settings) file. For options such as theme and model, use `/config` instead |161| `/update-config [request]` | **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills).** Describe a settings change, such as allowing a command, setting an environment variable, or adding a [hook](https://code.claude.com/docs/en/hooks.md), and Claude edits the matching [`settings.json`](https://code.claude.com/docs/en/settings) file. For options such as theme and model, use `/config` instead |

164| `/upgrade` | Open the upgrade page in your browser to switch to a higher plan tier. When the browser fails to open, the command shows a sign-in prompt without printing the URL |162| `/upgrade` | Open the upgrade page in your browser to switch to a higher plan tier. When no browser can open the page, for example over SSH, the command prints the page's URL above its sign-in prompt. Printing the URL requires Claude Code v2.1.323 or later |

165| `/usage` | Show session cost, plan usage limits, and activity stats. On a Pro, Max, Ultra, Team, or Enterprise plan, includes a [breakdown of what counts against your plan limits](https://code.claude.com/docs/en/costs.md#plan-usage-breakdown). Behind a Claude apps gateway that tracks spend, shows [your spend through the gateway](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md#usage-warnings-in-claude-code). `/cost` and `/stats` are aliases |163| `/usage` | Show session cost, plan usage limits, and activity stats. On a Pro, Max, Ultra, Team, or Enterprise plan, includes a [breakdown of what counts against your plan limits](https://code.claude.com/docs/en/costs.md#plan-usage-breakdown). Behind a Claude apps gateway that tracks spend, shows [your spend through the gateway](https://code.claude.com/docs/en/claude-apps-gateway-spend-limits.md#usage-warnings-in-claude-code). `/cost` and `/stats` are aliases |

166| `/usage-credits` | Configure usage credits, or request them from your admin, when you hit a limit. Opens your [usage-credits billing settings](https://code.claude.com/docs/en/costs.md#add-usage-credits-to-your-subscription) in the browser, except that Team and Enterprise members without billing access instead send a usage-credits request to their admin from the CLI, after confirming in a dialog that the request notifies their admins. When no browser can open the billing page, for example over SSH, the command prints the URL to visit instead; this requires Claude Code v2.1.205 or later, and earlier versions showed nothing in that case. Previously `/extra-usage` |164| `/usage-credits` | Configure usage credits, or request them from your admin, when you hit a limit. Opens your [usage-credits billing settings](https://code.claude.com/docs/en/costs.md#add-usage-credits-to-your-subscription) in the browser. Team and Enterprise members without billing access instead send a usage-credits request to their admin from the CLI. At a terminal where no browser can open the page, for example over SSH, the command prints the URL. Printing it requires Claude Code v2.1.205 or later. Previously `/extra-usage` |

167| `/verify` | **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills).** Confirm a code change does what it should by building your project's app, running it, and observing the result, rather than relying on tests or type checks. See [Run and verify your app](https://code.claude.com/docs/en/skills.md#run-and-verify-your-app) |165| `/verify` | **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills).** Confirm a code change does what it should by building your project's app, running it, and observing the result, rather than relying on tests or type checks. See [Run and verify your app](https://code.claude.com/docs/en/skills.md#run-and-verify-your-app) |

168| `/vim` | Removed in v2.1.92. To toggle between Vim and Normal editing modes, use `/config` → Editor mode |166| `/vim` | Removed in v2.1.92. To toggle between Vim and Normal editing modes, use `/config` → Editor mode |

169| `/voice [hold\|tap\|off]` | Toggle [voice dictation](https://code.claude.com/docs/en/voice-dictation.md), or enable it in a specific mode. Requires a Claude.ai account |167| `/voice [hold\|tap\|off]` | Toggle [voice dictation](https://code.claude.com/docs/en/voice-dictation.md), or enable it in a specific mode. Requires a Claude.ai account |

desktop.md +0 −4

Details

2261 2261 

2262The Desktop app loads MCP servers from `claude_desktop_config.json` into local Code tab sessions, alongside servers from `~/.claude.json` and `.mcp.json`. A server you define in `claude_desktop_config.json` is available in both the Desktop chat surface and local Code tab sessions.2262The Desktop app loads MCP servers from `claude_desktop_config.json` into local Code tab sessions, alongside servers from `~/.claude.json` and `.mcp.json`. A server you define in `claude_desktop_config.json` is available in both the Desktop chat surface and local Code tab sessions.

2263 2263 

2264If you define the same server name in `claude_desktop_config.json` and in `~/.claude.json` or `.mcp.json`, the Code tab in local sessions connects once and uses the `claude_desktop_config.json` definition.

2265 

2266The app also re-delivers stdio servers from `~/.claude.json` to the embedded CLI in local sessions. When the top level of `~/.claude.json` (user scope) and `.mcp.json` define the same stdio server name, the Code tab uses the `~/.claude.json` definition, departing from the CLI [scope hierarchy](https://code.claude.com/docs/en/mcp.md#scope-hierarchy-and-precedence).

2267 

2268> [!NOTE]2264> [!NOTE]

2269>2265>

2270> The standalone CLI does not read `claude_desktop_config.json`. On macOS and WSL, run `claude mcp add-from-claude-desktop` to copy those servers into `~/.claude.json`. See [Import MCP servers from Claude Desktop](https://code.claude.com/docs/en/mcp.md#import-mcp-servers-from-claude-desktop) for the import flow and scope options.2266> The standalone CLI does not read `claude_desktop_config.json`. On macOS and WSL, run `claude mcp add-from-claude-desktop` to copy those servers into `~/.claude.json`. See [Import MCP servers from Claude Desktop](https://code.claude.com/docs/en/mcp.md#import-mcp-servers-from-claude-desktop) for the import flow and scope options.

Details

71 71 

72Launch **Claude** from your application launcher, or run `claude-desktop` from a terminal, and sign in with your Anthropic account.72Launch **Claude** from your application launcher, or run `claude-desktop` from a terminal, and sign in with your Anthropic account.

73 73 

74The Linux app signs in the same way as on macOS and Windows: with a claude.ai subscription, or through your organization's SSO. For API-key authentication, use the [CLI](https://code.claude.com/docs/en/quickstart.md). To use Desktop with Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, or an LLM gateway instead, see [Claude Desktop on 3P](https://claude.com/docs/third-party/claude-desktop/overview). For proxy servers and custom certificate authorities in those deployments, see [network configuration](https://code.claude.com/docs/en/network-config.md).74The Linux app signs in the same way as on macOS and Windows: with a claude.ai subscription, or through your organization's SSO. To use Desktop with a Claude API key, Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, or an LLM gateway instead, see [Claude Desktop on 3P](https://claude.com/docs/third-party/claude-desktop/overview). For proxy servers and custom certificate authorities in those deployments, see [network configuration](https://code.claude.com/docs/en/network-config.md).

75 75 

76### Install from a downloaded file76### Install from a downloaded file

77 77 

Details

83 83 

84**8. Choose the permission mode and model**84**8. Choose the permission mode and model**

85 85 

86In the instructions box's toolbar, select a [permission mode](#permissions-for-scheduled-tasks) and model. If you leave them unchanged, runs use your Claude Code settings and the default model.86In the instructions box's toolbar, select a [permission mode](#permissions-for-scheduled-tasks) and model.

87 

88* **Permission mode**: if you leave it unchanged, runs use your Claude Code settings.

89* **Model**: if the model menu reads **Default · Set by admin** and you don't pick another model, runs use the model your organization set in [managed settings](https://code.claude.com/docs/en/managed-settings.md). A [catch-up run](#missed-runs) that starts as the app opens can use the [runtime default for your account](https://code.claude.com/docs/en/model-config.md#default-model-setting) instead.

87 90 

88**9. Create the task**91**9. Create the task**

89 92 

90Click **Create**. If you haven't trusted the folder yet, Desktop asks you to trust it at this point. The task's detail page opens.93Click **Create**. If you haven't trusted the folder yet, Desktop asks you to trust it at this point. The task's detail page opens.

91 94 

95To see which model **Default · Set by admin** stands for, click **Run now** on the detail page to run the task at once. Then [open the run's session](#find-a-runs-session), where the row under the prompt box shows the model's name.

96 

92On the detail page, click the pencil icon to open the [**Edit** form](#manage-scheduled-tasks). There you can change the **Description** that Desktop filled in from your instructions, select **Worktree**, or switch the schedule to **Manual** or **Custom**.97On the detail page, click the pencil icon to open the [**Edit** form](#manage-scheduled-tasks). There you can change the **Description** that Desktop filled in from your instructions, select **Worktree**, or switch the schedule to **Manual** or **Custom**.

93 98 

94You can also create a task by describing what you want in any session. For example, "set up a daily code review that runs every morning at 9am" creates a recurring task. A request like "remind me at 3pm tomorrow to check the deploy" creates a one-time task that disables itself after it fires.99You can also create a task by describing what you want in any session. For example, "set up a daily code review that runs every morning at 9am" creates a recurring task. A request like "remind me at 3pm tomorrow to check the deploy" creates a one-time task that disables itself after it fires.


177* **Review allowed permissions**: see and revoke saved tool approvals for this task from the **Always allowed** panel182* **Review allowed permissions**: see and revoke saved tool approvals for this task from the **Always allowed** panel

178* **Delete**: remove the task. The sessions the task created are [archived](https://code.claude.com/docs/en/desktop.md#organize-and-find-sessions), not deleted. The folder holding the task's `SKILL.md` file stays on disk at `~/.claude/scheduled-tasks/<task-name>/`, or at `scheduled-tasks/<task-name>/` under [`CLAUDE_CONFIG_DIR`](https://code.claude.com/docs/en/env-vars) if you set that variable. To remove that folder, delete it yourself.183* **Delete**: remove the task. The sessions the task created are [archived](https://code.claude.com/docs/en/desktop.md#organize-and-find-sessions), not deleted. The folder holding the task's `SKILL.md` file stays on disk at `~/.claude/scheduled-tasks/<task-name>/`, or at `scheduled-tasks/<task-name>/` under [`CLAUDE_CONFIG_DIR`](https://code.claude.com/docs/en/env-vars) if you set that variable. To remove that folder, delete it yourself.

179 184 

180You can also list, create, edit, and pause tasks by asking Claude in any Desktop session. For example, "pause my dependency-audit task" or "show me my scheduled tasks." To delete a task, use the **Delete** button on its detail page.185You can also manage tasks by asking Claude, letting a task update itself, or editing a task's prompt on disk:

181 

182To let a task change its own schedule or prompt with the `update_scheduled_task` MCP tool, click **Run now** and approve the call each time.

183 186 

184To edit a task's prompt on disk, open `~/.claude/scheduled-tasks/<task-name>/SKILL.md` (or under [`CLAUDE_CONFIG_DIR`](https://code.claude.com/docs/en/env-vars) if set). The file uses YAML frontmatter for `name` and `description`, with the prompt as the body. Changes take effect on the next run. Schedule, folder, model, and enabled state are not in this file: change them through the Edit form or ask Claude.187* **Ask Claude**: list, create, edit, and pause tasks by asking Claude in any Desktop session. For example, "pause my dependency-audit task" or "show me my scheduled tasks." To delete a task, use the **Delete** button on its detail page.

188* **Let a task update itself**: for a task to change its own schedule or prompt with the `update_scheduled_task` MCP tool, click **Run now** and approve the call each time

189* **Edit the prompt on disk**: open `~/.claude/scheduled-tasks/<task-name>/SKILL.md`, or `scheduled-tasks/<task-name>/SKILL.md` under [`CLAUDE_CONFIG_DIR`](https://code.claude.com/docs/en/env-vars) if you set that variable. The file uses YAML frontmatter for `name` and `description`, with the prompt as the body. Changes take effect on the next run. Schedule, folder, and enabled state are not in this file: change them through the Edit form or ask Claude.

185 190 

186## Related resources191## Related resources

187 192 

env-vars.md +8 −4

Details

211| `CLAUDE_CODE_AUTO_CONNECT_IDE` | Override automatic [IDE connection](https://code.claude.com/docs/en/vs-code.md). By default, Claude Code connects automatically when launched inside a supported IDE's integrated terminal. Set to `false` to prevent this. Set to `true` to force a connection attempt when auto-detection fails, such as when tmux obscures the parent terminal. Takes precedence over the [`autoConnectIde`](https://code.claude.com/docs/en/settings-reference#autoconnectide) global config setting |211| `CLAUDE_CODE_AUTO_CONNECT_IDE` | Override automatic [IDE connection](https://code.claude.com/docs/en/vs-code.md). By default, Claude Code connects automatically when launched inside a supported IDE's integrated terminal. Set to `false` to prevent this. Set to `true` to force a connection attempt when auto-detection fails, such as when tmux obscures the parent terminal. Takes precedence over the [`autoConnectIde`](https://code.claude.com/docs/en/settings-reference#autoconnectide) global config setting |

212| `CLAUDE_CODE_AUTO_MODE_MODEL` | Sets the model for the classifier requests Claude Code sends in [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode). Use a full model ID such as `claude-sonnet-4-6`. For the cases where Claude Code ignores it, see [Choose the classifier model](https://code.claude.com/docs/en/permission-modes.md#choose-the-classifier-model). Requires Claude Code v2.1.302 or later |212| `CLAUDE_CODE_AUTO_MODE_MODEL` | Sets the model for the classifier requests Claude Code sends in [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode). Use a full model ID such as `claude-sonnet-4-6`. For the cases where Claude Code ignores it, see [Choose the classifier model](https://code.claude.com/docs/en/permission-modes.md#choose-the-classifier-model). Requires Claude Code v2.1.302 or later |

213| `CLAUDE_CODE_AUTO_MODE_SERVER` | Controls whether Claude Code asks the server to [review auto mode actions](https://code.claude.com/docs/en/permission-modes.md#server-side-classifier-review). Set to `0` to use Claude Code's own classifier requests instead. On a direct connection to the Anthropic API, requires v2.1.281 or later. The linked section lists which sessions ask the server when the variable is unset, and from which version. Requires Claude Code v2.1.271 or later |213| `CLAUDE_CODE_AUTO_MODE_SERVER` | Controls whether Claude Code asks the server to [review auto mode actions](https://code.claude.com/docs/en/permission-modes.md#server-side-classifier-review). Set to `0` to use Claude Code's own classifier requests instead. On a direct connection to the Anthropic API, requires v2.1.281 or later. The linked section lists which sessions ask the server when the variable is unset, and from which version. Requires Claude Code v2.1.271 or later |

214| `CLAUDE_CODE_AUTOMOUNT_ROOTS` | Automount root folders for Claude Code to skip when it looks in the folders above your working directory for files such as `CLAUDE.md`, skills, and `.mcp.json`. Set it when those lookups wait on your automounter. Separate multiple paths with `:` on Unix or `;` on Windows, and give each as an absolute path with no symlink in it. Requires Claude Code v2.1.323 or later |

214| `CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS` | Time in milliseconds Claude Code waits for the AWS default credential provider chain to produce credentials before the request fails with [`AWS default-chain credential resolve timed out`](https://code.claude.com/docs/en/errors#aws-default-chain-credential-resolve-timed-out) (default: `60000`). Raise it when a step in your chain legitimately needs longer, such as a browser-based SSO sign-in with MFA through a wrapper like `aws-vault`. Applies on Amazon Bedrock, [Claude Platform on AWS](https://code.claude.com/docs/en/claude-platform-on-aws.md), and the [Mantle endpoint](https://code.claude.com/docs/en/amazon-bedrock.md#use-the-mantle-endpoint). See [credential caching and resolution timeout](https://code.claude.com/docs/en/amazon-bedrock.md#credential-caching-and-resolution-timeout). Requires Claude Code v2.1.207 or later |215| `CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS` | Time in milliseconds Claude Code waits for the AWS default credential provider chain to produce credentials before the request fails with [`AWS default-chain credential resolve timed out`](https://code.claude.com/docs/en/errors#aws-default-chain-credential-resolve-timed-out) (default: `60000`). Raise it when a step in your chain legitimately needs longer, such as a browser-based SSO sign-in with MFA through a wrapper like `aws-vault`. Applies on Amazon Bedrock, [Claude Platform on AWS](https://code.claude.com/docs/en/claude-platform-on-aws.md), and the [Mantle endpoint](https://code.claude.com/docs/en/amazon-bedrock.md#use-the-mantle-endpoint). See [credential caching and resolution timeout](https://code.claude.com/docs/en/amazon-bedrock.md#credential-caching-and-resolution-timeout). Requires Claude Code v2.1.207 or later |

215| `CLAUDE_CODE_BASH_EDIT_DIFF` | Set to `0` to turn off the [diff of the files that changed while a Bash command ran](https://code.claude.com/docs/en/hooks.md#bash), or `1` to record it in every permission mode. Takes precedence over the [`bashEditDiffEnabled`](https://code.claude.com/docs/en/settings-reference#basheditdiffenabled) setting. Requires Claude Code v2.1.269 or later |216| `CLAUDE_CODE_BASH_EDIT_DIFF` | Set to `0` to turn off the [diff of the files that changed while a Bash command ran](https://code.claude.com/docs/en/hooks.md#bash), or `1` to record it in every permission mode. Takes precedence over the [`bashEditDiffEnabled`](https://code.claude.com/docs/en/settings-reference#basheditdiffenabled) setting. Requires Claude Code v2.1.269 or later |

216| `CLAUDE_CODE_BG_TASKS_REPORT_RUNNING` | Set to `0` to make a non-interactive session report an idle status to its host at every turn end, even while background work is still running. By default, the session keeps reporting a running status past turn end while background work such as a background agent or a [workflow](https://code.claude.com/docs/en/workflows.md) run is still live. This keeps a host that watches the status, such as a remote session list, from announcing that Claude is waiting for your input mid-work. Background shell commands, such as a dev server, don't hold the running status. The running-status default and the `0` opt-out require Claude Code v2.1.269 or later; on earlier versions, set `1` to hold the running status |217| `CLAUDE_CODE_BG_TASKS_REPORT_RUNNING` | Set to `0` to make a non-interactive session report an idle status to its host at every turn end, even while background work is still running. By default, the session keeps reporting a running status past turn end while background work such as a background agent or a [workflow](https://code.claude.com/docs/en/workflows.md) run is still live. This keeps a host that watches the status, such as a remote session list, from announcing that Claude is waiting for your input mid-work. Background shell commands, such as a dev server, don't hold the running status. The running-status default and the `0` opt-out require Claude Code v2.1.269 or later; on earlier versions, set `1` to hold the running status |


298| `CLAUDE_CODE_EVEN_MORE_DANGEROUSLY_SKIP_PERMISSIONS` | Set to `1` to [run dangerous `rm` commands with no prompt](https://code.claude.com/docs/en/permission-modes#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode) in `bypassPermissions` mode, which removes a safety prompt for destructive deletes. The linked section lists where it has no effect. [Set it in the environment that launches Claude Code](#set-variables-in-your-shell), because Claude Code [ignores it in a settings `env` block](https://code.claude.com/docs/en/settings-reference#variables-claude-code-ignores-in-env). Requires Claude Code v2.1.311 or later |299| `CLAUDE_CODE_EVEN_MORE_DANGEROUSLY_SKIP_PERMISSIONS` | Set to `1` to [run dangerous `rm` commands with no prompt](https://code.claude.com/docs/en/permission-modes#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode) in `bypassPermissions` mode, which removes a safety prompt for destructive deletes. The linked section lists where it has no effect. [Set it in the environment that launches Claude Code](#set-variables-in-your-shell), because Claude Code [ignores it in a settings `env` block](https://code.claude.com/docs/en/settings-reference#variables-claude-code-ignores-in-env). Requires Claude Code v2.1.311 or later |

299| `CLAUDE_CODE_EXIT_AFTER_STOP_DELAY` | Time in milliseconds to wait after the query loop becomes idle before automatically exiting. Useful for automated workflows and scripts using SDK mode |300| `CLAUDE_CODE_EXIT_AFTER_STOP_DELAY` | Time in milliseconds to wait after the query loop becomes idle before automatically exiting. Useful for automated workflows and scripts using SDK mode |

300| `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` | Set to `1` to enable [agent teams](https://code.claude.com/docs/en/agent-teams.md). Agent teams are experimental and disabled by default |301| `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` | Set to `1` to enable [agent teams](https://code.claude.com/docs/en/agent-teams.md). Agent teams are experimental and disabled by default |

302| `CLAUDE_CODE_EXPERIMENTAL_CODE_MODE` | Set to `1` to start sessions in [Code Mode](https://code.claude.com/docs/en/code-mode.md), an experimental feature. Set to `0` to keep it off, or in managed settings to [block it for an organization](https://code.claude.com/docs/en/code-mode.md#block-code-mode-for-your-organization). The variable [doesn't count in every settings file](https://code.claude.com/docs/en/settings-reference.md#variables-claude-code-ignores-in-env). See the [version and account requirements](https://code.claude.com/docs/en/code-mode.md#requirements) |

301| `CLAUDE_CODE_EXTRA_BODY` | JSON object to merge into the top level of model request bodies except on some requests outside the conversation, such as `/model` checks. Useful for passing provider-specific parameters that Claude Code doesn't expose directly. A value exported in your shell also applies to the [background sessions](https://code.claude.com/docs/en/agent-view.md) you dispatch with `claude agents` or `--bg`. Before v2.1.206, background sessions ignored a shell-exported value and used whatever copy the background supervisor process inherited |303| `CLAUDE_CODE_EXTRA_BODY` | JSON object to merge into the top level of model request bodies except on some requests outside the conversation, such as `/model` checks. Useful for passing provider-specific parameters that Claude Code doesn't expose directly. A value exported in your shell also applies to the [background sessions](https://code.claude.com/docs/en/agent-view.md) you dispatch with `claude agents` or `--bg`. Before v2.1.206, background sessions ignored a shell-exported value and used whatever copy the background supervisor process inherited |

302| `CLAUDE_CODE_FILE_READ_MAX_OUTPUT_TOKENS` | Override the default token limit for [file reads](https://code.claude.com/docs/en/tools-reference.md#large-files), which is 25,000 tokens. Useful when you need to read larger files in full. A read that Claude makes with the `allow_large` parameter can go past this limit when the context window has room |304| `CLAUDE_CODE_FILE_READ_MAX_OUTPUT_TOKENS` | Override the default token limit for [file reads](https://code.claude.com/docs/en/tools-reference.md#large-files), which is 25,000 tokens. Useful when you need to read larger files in full. A read that Claude makes with the `allow_large` parameter can go past this limit when the context window has room |

303| `CLAUDE_CODE_FORCE_SESSION_PERSISTENCE` | Set to `1` to force transcript persistence, prompt history, and `claude agents` registration even when this `claude` was launched from inside another Claude Code session. Use when an inherited `CLAUDE_CODE_CHILD_SESSION` value, for example from a `screen` session or a background launcher first started by Claude Code's Bash tool, causes a genuine top-level session to be misclassified as nested. As of v2.1.178, Claude Code detects the tmux case automatically and ignores the inherited marker, so tmux no longer needs this variable. Also honored on v2.1.169 and earlier; has no effect on v2.1.170 and v2.1.171, where the nested-session detection it overrides was removed |305| `CLAUDE_CODE_FORCE_SESSION_PERSISTENCE` | Set to `1` to force transcript persistence, prompt history, and `claude agents` registration even when this `claude` was launched from inside another Claude Code session. Use when an inherited `CLAUDE_CODE_CHILD_SESSION` value, for example from a `screen` session or a background launcher first started by Claude Code's Bash tool, causes a genuine top-level session to be misclassified as nested. As of v2.1.178, Claude Code detects the tmux case automatically and ignores the inherited marker, so tmux no longer needs this variable. Also honored on v2.1.169 and earlier; has no effect on v2.1.170 and v2.1.171, where the nested-session detection it overrides was removed |


348| `CLAUDE_CODE_OTEL_FLUSH_TIMEOUT_MS` | Timeout in milliseconds for flushing pending OpenTelemetry spans (default: 5000). See [Monitoring](https://code.claude.com/docs/en/monitoring-usage.md) |350| `CLAUDE_CODE_OTEL_FLUSH_TIMEOUT_MS` | Timeout in milliseconds for flushing pending OpenTelemetry spans (default: 5000). See [Monitoring](https://code.claude.com/docs/en/monitoring-usage.md) |

349| `CLAUDE_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS` | Interval for refreshing dynamic OpenTelemetry headers in milliseconds (default: 1740000 / 29 minutes). See [Dynamic headers](https://code.claude.com/docs/en/monitoring-usage.md#dynamic-headers) |351| `CLAUDE_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS` | Interval for refreshing dynamic OpenTelemetry headers in milliseconds (default: 1740000 / 29 minutes). See [Dynamic headers](https://code.claude.com/docs/en/monitoring-usage.md#dynamic-headers) |

350| `CLAUDE_CODE_OTEL_SHUTDOWN_TIMEOUT_MS` | Timeout in milliseconds for the OpenTelemetry exporter to finish on shutdown (default: 2000). Increase if metrics are dropped at exit. See [Monitoring](https://code.claude.com/docs/en/monitoring-usage.md) |352| `CLAUDE_CODE_OTEL_SHUTDOWN_TIMEOUT_MS` | Timeout in milliseconds for the OpenTelemetry exporter to finish on shutdown (default: 2000). Increase if metrics are dropped at exit. See [Monitoring](https://code.claude.com/docs/en/monitoring-usage.md) |

351| `CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS` | Starting delay in milliseconds, in place of the default 500, of the exponential backoff between [automatic retries](https://code.claude.com/docs/en/errors.md#tune-retry-behavior) of a request that the API rejects with a `529` overloaded error. Raise it to spread the retries over a longer window when the API is at capacity. Give whole milliseconds from 500 to 32000 in plain digits; Claude Code treats any other value as unset. Has no effect when `CLAUDE_CODE_RETRY_WATCHDOG` is set to `1`, or when the rejected request was sent in [fast mode](https://code.claude.com/docs/en/fast-mode.md#handle-rate-limits). Requires Claude Code v2.1.292 or later |353| `CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS` | Starting delay in milliseconds of the backoff between retries of a request that the API rejects with a `529` overloaded error (default: 500). Raise it to spread the retries over a longer window when the API is at capacity. Give whole milliseconds from 500 to 32000 in plain digits; Claude Code treats any other value as unset. See [when it has no effect](https://code.claude.com/docs/en/errors.md#tune-retry-behavior). Requires Claude Code v2.1.292 or later |

352| `CLAUDE_CODE_OVERLOADED_RETRY_MAX_DELAY_MS` | Ceiling in milliseconds, in place of the default 32000, on the exponential backoff between [automatic retries](https://code.claude.com/docs/en/errors.md#tune-retry-behavior) of a request that the API rejects with a `529` overloaded error. Raise it so that later retries keep spreading apart when the API is at capacity. Give whole milliseconds from 32000 to 64000 in plain digits; Claude Code treats any other value as unset. Has no effect when `CLAUDE_CODE_RETRY_WATCHDOG` is set to `1`, or when the rejected request was sent in [fast mode](https://code.claude.com/docs/en/fast-mode.md#handle-rate-limits). Requires Claude Code v2.1.296 or later |354| `CLAUDE_CODE_OVERLOADED_RETRY_MAX_DELAY_MS` | Ceiling in milliseconds on the backoff between retries of a request that the API rejects with a `529` overloaded error (default: 32000). Raise it so that later retries keep spreading apart. Give whole milliseconds from 32000 to 300000 in plain digits; Claude Code treats any other value as unset. Values above 64000 require v2.1.323 or later. See [when it has no effect](https://code.claude.com/docs/en/errors.md#tune-retry-behavior). Requires Claude Code v2.1.296 or later |

353| `CLAUDE_CODE_PACKAGE_MANAGER_AUTO_UPDATE` | Set to `1` to let Claude Code run your package manager's upgrade command in the background when a new version is available. Applies to Homebrew and WinGet installations. Other package managers continue to show the upgrade command without running it. See [Auto updates](https://code.claude.com/docs/en/setup.md#auto-updates) |355| `CLAUDE_CODE_PACKAGE_MANAGER_AUTO_UPDATE` | Set to `1` to let Claude Code run your package manager's upgrade command in the background when a new version is available. Applies to Homebrew and WinGet installations. Other package managers continue to show the upgrade command without running it. See [Auto updates](https://code.claude.com/docs/en/setup.md#auto-updates) |

354| `CLAUDE_CODE_PERFORCE_MODE` | Set to `1` to enable Perforce-aware write protection. When set, Edit, Write, and NotebookEdit fail with a `p4 edit <file>` hint if the target file lacks the owner-write bit, which Perforce clears on synced files until `p4 edit` opens them. This prevents Claude Code from bypassing Perforce change tracking |356| `CLAUDE_CODE_PERFORCE_MODE` | Set to `1` to enable Perforce-aware write protection. When set, Edit, Write, and NotebookEdit fail with a `p4 edit <file>` hint if the target file lacks the owner-write bit, which Perforce clears on synced files until `p4 edit` opens them. This prevents Claude Code from bypassing Perforce change tracking |

355| `CLAUDE_CODE_PLUGIN_CACHE_DIR` | Override the plugins root directory. Despite the name, this sets the parent directory, not the cache itself: marketplaces and the plugin cache live in subdirectories under this path. Defaults to `~/.claude/plugins` |357| `CLAUDE_CODE_PLUGIN_CACHE_DIR` | Override the plugins root directory. Despite the name, this sets the parent directory, not the cache itself: marketplaces and the plugin cache live in subdirectories under this path. Defaults to `~/.claude/plugins` |

356| `CLAUDE_CODE_PLUGIN_DIRS` | Plugin directories to load for the session, each loaded the way a [`--plugin-dir`](https://code.claude.com/docs/en/plugins/cli-reference#flags-that-load-a-plugin-for-one-session) flag loads it. Separate multiple paths with `:` on Unix or `;` on Windows. Give each path as an absolute path or start it with `~`, because Claude Code skips relative paths. Requires Claude Code v2.1.280 or later. See [Load a plugin for one session](https://code.claude.com/docs/en/plugins/create.md#load-a-directory-or-archive-for-one-session) |358| `CLAUDE_CODE_PLUGIN_DIRS` | Plugin directories to load for the session, each loaded the way a [`--plugin-dir`](https://code.claude.com/docs/en/plugins/cli-reference#flags-that-load-a-plugin-for-one-session) flag loads it. Separate multiple paths with `:` on Unix or `;` on Windows. Give each path as an absolute path or start it with `~`, because Claude Code skips relative paths. Requires Claude Code v2.1.280 or later. See [Load a plugin for one session](https://code.claude.com/docs/en/plugins/create.md#load-a-directory-or-archive-for-one-session) |

357| `CLAUDE_CODE_PLUGIN_DIR_WATCH` | Controls whether Claude Code reloads a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) when the mod's files change. Reloading applies to a mod you load from a directory with `--plugin-dir`, and it's on by default in interactive sessions. Set to `1` to turn it on in non-interactive sessions as well, or `0` to turn it off in every session. Requires Claude Code v2.1.287 or later. See [mod settings and environment variables](https://code.claude.com/docs/en/plugins/mods/reference.md#settings-and-environment-variables) |359| `CLAUDE_CODE_PLUGIN_DIR_WATCH` | Controls whether a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) reloads when its files change. By default, mods in [skills directories](https://code.claude.com/docs/en/plugins/org.md#keep-skills-directory-plugins-loading) reload in any session that takes more than one prompt, [non-interactive](https://code.claude.com/docs/en/headless.md) included. Mods in `--plugin-dir` directories reload only in interactive terminal sessions. Set to `1` to reload them as skills-directory mods do, or `0` to turn reloading off everywhere. Requires Claude Code v2.1.287 or later |

358| `CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS` | Timeout in milliseconds for cloning or refreshing a plugin marketplace (default: 120000). Increase this value for large repositories or slow network connections. See [Git clone timed out](https://code.claude.com/docs/en/plugins/troubleshooting.md#git-clone-timed-out-after-120s) |360| `CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS` | Timeout in milliseconds for cloning or refreshing a plugin marketplace (default: 120000). Increase this value for large repositories or slow network connections. See [Git clone timed out](https://code.claude.com/docs/en/plugins/troubleshooting.md#git-clone-timed-out-after-120s) |

359| `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE` | Set to `1` to skip the re-clone attempt and keep using the existing marketplace checkout when a marketplace refresh can't reach or authenticate to the remote. Useful in offline or airgapped environments where re-cloning would fail the same way. See [Marketplace updates fail in offline environments](https://code.claude.com/docs/en/plugins/troubleshooting.md#marketplace-updates-keep-failing-offline) |361| `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE` | Set to `1` to skip the re-clone attempt and keep using the existing marketplace checkout when a marketplace refresh can't reach or authenticate to the remote. Useful in offline or airgapped environments where re-cloning would fail the same way. See [Marketplace updates fail in offline environments](https://code.claude.com/docs/en/plugins/troubleshooting.md#marketplace-updates-keep-failing-offline) |

360| `CLAUDE_CODE_PLUGIN_PREFER_HTTPS` | Set to `1` to clone GitHub `owner/repo` shorthand sources over HTTPS instead of SSH. Applies to plugin install and update, and to `/plugin marketplace add` and `update`. Useful in CI runners, containers, or any environment without a configured SSH key for `github.com` |362| `CLAUDE_CODE_PLUGIN_PREFER_HTTPS` | Set to `1` to clone GitHub `owner/repo` shorthand sources over HTTPS instead of SSH. Applies to plugin install and update, and to `/plugin marketplace add` and `update`. Useful in CI runners, containers, or any environment without a configured SSH key for `github.com` |


370| `CLAUDE_CODE_REMOTE` | Set automatically to `true` when Claude Code is running as a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md). Read this from a hook or setup script to detect whether you are in a cloud session |372| `CLAUDE_CODE_REMOTE` | Set automatically to `true` when Claude Code is running as a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md). Read this from a hook or setup script to detect whether you are in a cloud session |

371| `CLAUDE_CODE_REMOTE_SESSION_ID` | Set automatically in [cloud sessions](https://code.claude.com/docs/en/claude-code-on-the-web.md) to the current session's ID. Read this to construct a link back to the session transcript. See [Link output back to the session](https://code.claude.com/docs/en/cloud-environments.md#link-output-back-to-the-session) |373| `CLAUDE_CODE_REMOTE_SESSION_ID` | Set automatically in [cloud sessions](https://code.claude.com/docs/en/claude-code-on-the-web.md) to the current session's ID. Read this to construct a link back to the session transcript. See [Link output back to the session](https://code.claude.com/docs/en/cloud-environments.md#link-output-back-to-the-session) |

372| `CLAUDE_CODE_RESTRICTED` | Set to `1` to start the session in restricted mode, the same as passing [`--restricted`](https://code.claude.com/docs/en/cli-reference#cli-flags). Claude Code ignores this variable in a settings file's `env` block. Requires Claude Code v2.1.248 or later |374| `CLAUDE_CODE_RESTRICTED` | Set to `1` to start the session in restricted mode, the same as passing [`--restricted`](https://code.claude.com/docs/en/cli-reference#cli-flags). Claude Code ignores this variable in a settings file's `env` block. Requires Claude Code v2.1.248 or later |

375| `CLAUDE_CODE_RESUME_HINT_COMMAND` | In a wrapper script that starts Claude Code, set this to the name you type to run the wrapper, such as `mytool`. A local session then prints `mytool --resume <session-id>` at exit in place of `claude --resume <session-id>`. Claude Code ignores a name that doesn't match `^\w[\w-]*$`. It also ignores the variable in a settings file's `env` block. Requires Claude Code v2.1.323 or later |

373| `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` | Set to `1` to automatically resume if the previous session ended mid-turn. Used in SDK mode so the model continues without requiring the SDK to re-send the prompt. To turn this off, unset the variable or set it to `0`. For the VS Code chat panel, see [Continue conversations after a reload](https://code.claude.com/docs/en/vs-code.md#continue-conversations-after-a-reload) |376| `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` | Set to `1` to automatically resume if the previous session ended mid-turn. Used in SDK mode so the model continues without requiring the SDK to re-send the prompt. To turn this off, unset the variable or set it to `0`. For the VS Code chat panel, see [Continue conversations after a reload](https://code.claude.com/docs/en/vs-code.md#continue-conversations-after-a-reload) |

374| `CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS` | Maximum age in milliseconds of the last transcript message for a session that ended mid-turn to continue automatically on resume. When the last message is older than this bound, Claude Code skips the `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` automatic resume and its `CLAUDE_CODE_RESUME_PROMPT` continuation message, and the session starts idle so you continue explicitly. Unset or `0` sets no bound, except that some turns resume only within six hours of their last message, such as one that ended with an API error. A positive value bounds every turn, including those; a negative or non-numeric value applies a one-hour bound. Spawn scripts for long-running agents can set this so a restart against an old transcript doesn't re-run a stale prompt. Claude Code sets a one-hour bound itself when it restarts a crashed [agent view](https://code.claude.com/docs/en/agent-view.md) session that inherited its conversation from an interactive session. Requires Claude Code v2.1.211 or later |377| `CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS` | Maximum age in milliseconds of the last transcript message for a session that ended mid-turn to continue automatically on resume. When the last message is older than this bound, Claude Code skips the `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` automatic resume and its `CLAUDE_CODE_RESUME_PROMPT` continuation message, and the session starts idle so you continue explicitly. Unset or `0` sets no bound, except that some turns resume only within six hours of their last message, such as one that ended with an API error. A positive value bounds every turn, including those; a negative or non-numeric value applies a one-hour bound. Spawn scripts for long-running agents can set this so a restart against an old transcript doesn't re-run a stale prompt. Claude Code sets a one-hour bound itself when it restarts a crashed [agent view](https://code.claude.com/docs/en/agent-view.md) session that inherited its conversation from an interactive session. Requires Claude Code v2.1.211 or later |

375| `CLAUDE_CODE_RESUME_PROMPT` | Override the continuation message Claude Code sends to Claude when `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` continues an interrupted turn instead of resending its prompt, or when you resume a [deferred tool call](https://code.claude.com/docs/en/hooks.md#defer-a-tool-call-for-later) with `-p`. Defaults to `Continue from where you left off.`. An empty string uses the default |378| `CLAUDE_CODE_RESUME_PROMPT` | Override the continuation message Claude Code sends to Claude when `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` continues an interrupted turn instead of resending its prompt, or when you resume a [deferred tool call](https://code.claude.com/docs/en/hooks.md#defer-a-tool-call-for-later) with `-p`. Defaults to `Continue from where you left off.`. An empty string uses the default |


405| `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` | Set to `1` to strip credentials from the environments of the subprocesses Claude Code starts, such as Bash commands, hooks, and stdio MCP servers. The scrub recognizes a credential by its variable name or its value, and it leaves GitHub tokens and proxy settings in place. See [What the subprocess environment scrub removes](#what-the-subprocess-environment-scrub-removes). `claude-code-action` sets this automatically when `allowed_non_write_users` is configured |408| `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` | Set to `1` to strip credentials from the environments of the subprocesses Claude Code starts, such as Bash commands, hooks, and stdio MCP servers. The scrub recognizes a credential by its variable name or its value, and it leaves GitHub tokens and proxy settings in place. See [What the subprocess environment scrub removes](#what-the-subprocess-environment-scrub-removes). `claude-code-action` sets this automatically when `allowed_non_write_users` is configured |

406| `CLAUDE_CODE_SYNC_PLUGIN_INSTALL` | Set to `1` in non-interactive mode (the `-p` flag) to wait for plugin installation to complete before the first query. Without this, plugins install in the background and may not be available on the first turn. Combine with `CLAUDE_CODE_SYNC_PLUGIN_INSTALL_TIMEOUT_MS` to bound the wait |409| `CLAUDE_CODE_SYNC_PLUGIN_INSTALL` | Set to `1` in non-interactive mode (the `-p` flag) to wait for plugin installation to complete before the first query. Without this, plugins install in the background and may not be available on the first turn. Combine with `CLAUDE_CODE_SYNC_PLUGIN_INSTALL_TIMEOUT_MS` to bound the wait |

407| `CLAUDE_CODE_SYNC_PLUGIN_INSTALL_TIMEOUT_MS` | Timeout in milliseconds for synchronous plugin installation. When exceeded, Claude Code proceeds without plugins and logs an error. No default: without this variable, synchronous installation waits until complete |410| `CLAUDE_CODE_SYNC_PLUGIN_INSTALL_TIMEOUT_MS` | Timeout in milliseconds for synchronous plugin installation. When exceeded, Claude Code proceeds without plugins and logs an error. No default: without this variable, synchronous installation waits until complete |

408| `CLAUDE_CODE_SYNC_SKILLS` | Set to `1` in non-interactive mode with the `-p` flag to make Claude Code download the skills enabled for your claude.ai account in that run and wait for the list of them, up to `CLAUDE_CODE_SYNC_SKILLS_WAIT_TIMEOUT_MS`, before it runs the first query. Requires claude.ai authentication. Terminal sessions where you sign in with your claude.ai account [sync these skills](https://code.claude.com/docs/en/skills.md#where-synced-skills-load) without this variable, so set it only when a `-p` run needs your current skills on its first query |411| `CLAUDE_CODE_SYNC_SKILLS` | Set to `1` to make Claude Code download the skills enabled for your claude.ai account. In non-interactive mode with the `-p` flag, Claude Code also waits up to `CLAUDE_CODE_SYNC_SKILLS_WAIT_TIMEOUT_MS` for the list of skills before it runs the first query. Requires claude.ai authentication. Terminal sessions where you sign in with your claude.ai account [sync these skills](https://code.claude.com/docs/en/skills.md#where-synced-skills-load) without this variable. In an interactive session, the variable requires v2.1.323 or later |

409| `CLAUDE_CODE_SYNC_SKILLS_INSTALL_TIMEOUT_MS` | Timeout in milliseconds for the skills resync that runs mid-session when an app built on the [Agent SDK](https://code.claude.com/docs/en/agent-sdk/typescript.md#query-object) reloads skills (default: 30000). When exceeded, the reload continues with whichever skills have arrived, and the remaining downloads finish in the background |412| `CLAUDE_CODE_SYNC_SKILLS_INSTALL_TIMEOUT_MS` | Timeout in milliseconds for the skills resync that runs mid-session when an app built on the [Agent SDK](https://code.claude.com/docs/en/agent-sdk/typescript.md#query-object) reloads skills (default: 30000). When exceeded, the reload continues with whichever skills have arrived, and the remaining downloads finish in the background |

410| `CLAUDE_CODE_SYNC_SKILLS_WAIT_TIMEOUT_MS` | Timeout in milliseconds for the first query to wait for the initial skill list when `CLAUDE_CODE_SYNC_SKILLS` is set (default: 5000). When exceeded, the first query runs with whichever skills have arrived. The downloads finish in the background either way, and Claude waits for a skill's download when it invokes that skill |413| `CLAUDE_CODE_SYNC_SKILLS_WAIT_TIMEOUT_MS` | Timeout in milliseconds for the first query to wait for the initial skill list when `CLAUDE_CODE_SYNC_SKILLS` is set (default: 5000). When exceeded, the first query runs with whichever skills have arrived. The downloads finish in the background either way, and Claude waits for a skill's download when it invokes that skill |

411| `CLAUDE_CODE_SYNTAX_HIGHLIGHT` | Set to `false` to disable syntax highlighting in diff output. Useful when colors interfere with your terminal setup. To also disable highlighting in code blocks and file previews, use the [`syntaxHighlightingDisabled`](https://code.claude.com/docs/en/settings-reference#syntaxhighlightingdisabled) setting |414| `CLAUDE_CODE_SYNTAX_HIGHLIGHT` | Set to `false` to disable syntax highlighting in diff output. Useful when colors interfere with your terminal setup. To also disable highlighting in code blocks and file previews, use the [`syntaxHighlightingDisabled`](https://code.claude.com/docs/en/settings-reference#syntaxhighlightingdisabled) setting |


585* Turn on the [You should know mod](https://code.claude.com/docs/en/interactive-mode.md#you-should-know-suggestions)588* Turn on the [You should know mod](https://code.claude.com/docs/en/interactive-mode.md#you-should-know-suggestions)

586* Use [the advisor tool](https://code.claude.com/docs/en/advisor.md#requirements), except on Claude Platform on AWS with Claude Code v2.1.300 or later589* Use [the advisor tool](https://code.claude.com/docs/en/advisor.md#requirements), except on Claude Platform on AWS with Claude Code v2.1.300 or later

587* Use [MCP tasks](https://code.claude.com/docs/en/mcp.md#mcp-tasks-that-run-on-the-server)590* Use [MCP tasks](https://code.claude.com/docs/en/mcp.md#mcp-tasks-that-run-on-the-server)

591* Turn on [Code Mode](https://code.claude.com/docs/en/code-mode.md#requirements)

588* Read or reply to [comments on an artifact](https://code.claude.com/docs/en/artifacts.md#collect-comments-on-an-artifact)592* Read or reply to [comments on an artifact](https://code.claude.com/docs/en/artifacts.md#collect-comments-on-an-artifact)

589* Have Claude read [another organization's public artifact](https://code.claude.com/docs/en/artifacts.md#read-an-artifact-shared-with-you)593* Have Claude read [another organization's public artifact](https://code.claude.com/docs/en/artifacts.md#read-an-artifact-shared-with-you)

590* Get the [PowerShell tool](https://code.claude.com/docs/en/tools-reference.md#powershell-tool) by default for claude.ai and Console accounts on Windows with Git Bash installed; Claude Code routes shell commands through Git Bash unless you set `CLAUDE_CODE_USE_POWERSHELL_TOOL=1`. On Windows without Git Bash, the tool stays on594* Get the [PowerShell tool](https://code.claude.com/docs/en/tools-reference.md#powershell-tool) by default for claude.ai and Console accounts on Windows with Git Bash installed; Claude Code routes shell commands through Git Bash unless you set `CLAUDE_CODE_USE_POWERSHELL_TOOL=1`. On Windows without Git Bash, the tool stays on

errors.md +97 −12

Details

122| `A request to MCP server "<name>" was sent without your stored credentials` | [Authentication](#couldnt-read-the-stored-credentials-for-mcp-server) |122| `A request to MCP server "<name>" was sent without your stored credentials` | [Authentication](#couldnt-read-the-stored-credentials-for-mcp-server) |

123| `This server's URL is missing or not a valid URL, so sign-in can't start` | [Authentication](#mcp-server-url-is-missing-or-not-a-valid-url) |123| `This server's URL is missing or not a valid URL, so sign-in can't start` | [Authentication](#mcp-server-url-is-missing-or-not-a-valid-url) |

124| `Issuer mismatch in authorization response (RFC 9207)` | [Authentication](#issuer-mismatch-in-authorization-response) |124| `Issuer mismatch in authorization response (RFC 9207)` | [Authentication](#issuer-mismatch-in-authorization-response) |

125| `Stopped an OAuth request` | [Authentication](#stopped-an-oauth-request) |

125| `Refusing to send credentials to non-https token endpoint` / `<short-name> from the MCP SDK for <server-url>` | [Authentication](#refusing-to-send-credentials-to-non-https-token-endpoint) |126| `Refusing to send credentials to non-https token endpoint` / `<short-name> from the MCP SDK for <server-url>` | [Authentication](#refusing-to-send-credentials-to-non-https-token-endpoint) |

126| `Cloud gateway session expired — run /login to reconnect.` | [Authentication](#cloud-gateway-session-expired) |127| `Cloud gateway session expired — run /login to reconnect.` | [Authentication](#cloud-gateway-session-expired) |

127| `Cloud gateway <url> no longer accepts this session` | [Authentication](#cloud-gateway-session-expired) |128| `Cloud gateway <url> no longer accepts this session` | [Authentication](#cloud-gateway-session-expired) |


153| `403` with `GitHub GraphQL is not available from Claude Code sessions` in a cloud session | [GitHub proxy](https://code.claude.com/docs/en/cloud-environments.md#github-proxy) |154| `403` with `GitHub GraphQL is not available from Claude Code sessions` in a cloud session | [GitHub proxy](https://code.claude.com/docs/en/cloud-environments.md#github-proxy) |

154| `The cloud environments service returned an empty response` / `The cloud environments service returned a response in an unexpected format` | [Network](#the-cloud-environments-service-returned-an-empty-or-unexpected-response) |155| `The cloud environments service returned an empty response` / `The cloud environments service returned a response in an unexpected format` | [Network](#the-cloud-environments-service-returned-an-empty-or-unexpected-response) |

155| `Failed to fetch session from Sessions API: Failed to fetch session logs` | [Network](#failed-to-fetch-session-from-sessions-api) |156| `Failed to fetch session from Sessions API: Failed to fetch session logs` | [Network](#failed-to-fetch-session-from-sessions-api) |

157| `Couldn't load the history of cloud session` | [Network](#couldnt-load-the-history-of-cloud-session) |

156| `Couldn't reconnect to your Remote Control session` | [Network](#couldnt-reconnect-to-your-remote-control-session) |158| `Couldn't reconnect to your Remote Control session` | [Network](#couldnt-reconnect-to-your-remote-control-session) |

157| `N sessions ended while this machine was offline — the environment was cleaned up on the server and can't be resumed.` | [Network](#sessions-ended-while-this-machine-was-offline) |159| `N sessions ended while this machine was offline — the environment was cleaned up on the server and can't be resumed.` | [Network](#sessions-ended-while-this-machine-was-offline) |

158| `Couldn't share the transcript.` | [Network](#couldnt-share-the-transcript) |160| `Couldn't share the transcript.` | [Network](#couldnt-share-the-transcript) |


180| `PDF too large` / `PDF is password protected` / `pdftoppm is not installed` | [Request errors](#pdf-errors) |182| `PDF too large` / `PDF is password protected` / `pdftoppm is not installed` | [Request errors](#pdf-errors) |

181| `Extra inputs are not permitted` | [Request errors](#extra-inputs-are-not-permitted) |183| `Extra inputs are not permitted` | [Request errors](#extra-inputs-are-not-permitted) |

182| `API Error: 400 ... tools.N.custom.input_schema: JSON schema is invalid` / `Property keys should match pattern` | [Request errors](#tool-input-schema-is-invalid) |184| `API Error: 400 ... tools.N.custom.input_schema: JSON schema is invalid` / `Property keys should match pattern` | [Request errors](#tool-input-schema-is-invalid) |

185| `N tools left out` beside a server in `/mcp` / `Claude wasn't given N tools because the Anthropic API would reject their input schemas` | [Tools with invalid input schemas](https://code.claude.com/docs/en/mcp.md#tools-with-invalid-input-schemas) |

183| `Tool "mcp__<server>__<tool>" is not sent to Claude: its name has <N> characters and the API accepts at most 128` | [Request errors](#mcp-tool-name-over-128-characters) |186| `Tool "mcp__<server>__<tool>" is not sent to Claude: its name has <N> characters and the API accepts at most 128` | [Request errors](#mcp-tool-name-over-128-characters) |

184| `tools.N.custom.name: String should have at most 128 characters` | [Request errors](#mcp-tool-name-over-128-characters) |187| `tools.N.custom.name: String should have at most 128 characters` | [Request errors](#mcp-tool-name-over-128-characters) |

185| `tool_use.name: String should have at most 200 characters` | [Request errors](#tool-use-name-over-200-characters) |188| `tool_use.name: String should have at most 200 characters` | [Request errors](#tool-use-name-over-200-characters) |


251| `Ultrareview did not start` | [Command-line errors](#ultrareview-did-not-start) |254| `Ultrareview did not start` | [Command-line errors](#ultrareview-did-not-start) |

252| `Remote Control did not start: "<question>" got no answer` | [Command-line errors](#remote-control-did-not-start-got-no-answer) |255| `Remote Control did not start: "<question>" got no answer` | [Command-line errors](#remote-control-did-not-start-got-no-answer) |

253| `` `<flag>` before `remote-control` is not carried over to the sessions Remote Control starts `` | [Command-line errors](#not-carried-over-to-the-sessions-remote-control-starts) |256| `` `<flag>` before `remote-control` is not carried over to the sessions Remote Control starts `` | [Command-line errors](#not-carried-over-to-the-sessions-remote-control-starts) |

257| `Remote Control did not start, because sessions would skip part or all of the --settings file` | [Command-line errors](#remote-control-did-not-start-because-of-the-settings-file) |

258| `The settings file <file> has changed since Remote Control started, so this session did not start` | [Command-line errors](#settings-file-changed-since-remote-control-started) |

254| `--sandbox is not supported by claude remote-control` / `--no-sandbox is not supported by claude remote-control` | [Command-line errors](#sandbox-is-not-supported-by-claude-remote-control) |259| `--sandbox is not supported by claude remote-control` / `--no-sandbox is not supported by claude remote-control` | [Command-line errors](#sandbox-is-not-supported-by-claude-remote-control) |

255| `` `claude import` is not yet available in this build `` | [Command-line errors](#claude-import-is-not-yet-available-in-this-build) |260| `` `claude import` is not yet available in this build `` | [Command-line errors](#claude-import-is-not-yet-available-in-this-build) |

256| `Could not read Claude Code config` | [Command-line errors](#could-not-read-claude-code-config) |261| `Could not read Claude Code config` | [Command-line errors](#could-not-read-claude-code-config) |


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

269| `Shell command failed for pattern "..."`, from `/security-review` or any skill that injects dynamic context | [Command-line errors](#security-review-fails-without-origin-head) |274| `Shell command failed for pattern "..."`, from `/security-review` or any skill that injects dynamic context | [Command-line errors](#security-review-fails-without-origin-head) |

270| `Shell command permission check failed for pattern "..."`, from a skill that injects dynamic context | [Command-line errors](#security-review-fails-without-origin-head) |275| `Shell command permission check failed for pattern "..."`, from a skill that injects dynamic context | [Command-line errors](#security-review-fails-without-origin-head) |

276| ``Couldn't run `<command>` for <name>. A file named HEAD or .git in this folder or one above it may not be yours``, from a skill that injects dynamic context | [Permission checks on injected commands](https://code.claude.com/docs/en/skills.md#permission-checks-on-injected-commands) |

271| ``Skill <name> requires bash (`shell: bash` in frontmatter) but Git Bash was not found`` | [Command-line errors](#security-review-fails-without-origin-head) |277| ``Skill <name> requires bash (`shell: bash` in frontmatter) but Git Bash was not found`` | [Command-line errors](#security-review-fails-without-origin-head) |

272| `No shell command in <name> was run, because the <tool> tool does not accept one of them` | [Command-line errors](#no-shell-command-was-run) |278| `No shell command in <name> was run, because the <tool> tool does not accept one of them` | [Command-line errors](#no-shell-command-was-run) |

273| `Input must be provided either through stdin or as a prompt argument when using --print` | [Command-line errors](#input-must-be-provided-when-using-print) |279| `Input must be provided either through stdin or as a prompt argument when using --print` | [Command-line errors](#input-must-be-provided-when-using-print) |


425| `Workspace not trusted.` when starting or restarting a background session | [Background session errors](#workspace-not-trusted-when-dispatching-a-background-session) |431| `Workspace not trusted.` when starting or restarting a background session | [Background session errors](#workspace-not-trusted-when-dispatching-a-background-session) |

426| `Claude Code is being updated by npm on this machine (still not runnable after 2 min, ...)` | [Background session errors](#eacces-when-starting-a-background-session) |432| `Claude Code is being updated by npm on this machine (still not runnable after 2 min, ...)` | [Background session errors](#eacces-when-starting-a-background-session) |

427| `Claude Code process exited with code N` | [Wrapper and IDE errors](#claude-code-process-exited-with-code-n) |433| `Claude Code process exited with code N` | [Wrapper and IDE errors](#claude-code-process-exited-with-code-n) |

434| `Subprocess initialization did not complete within 60000ms` | [Wrapper and IDE errors](#subprocess-initialization-did-not-complete-within-60000ms) |

435| `Claude Code did not finish starting` | [Wrapper and IDE errors](#subprocess-initialization-did-not-complete-within-60000ms) |

428| `The connection to Claude Code ended before this message completed` | [Wrapper and IDE errors](#the-connection-to-claude-code-ended-before-this-message-completed) |436| `The connection to Claude Code ended before this message completed` | [Wrapper and IDE errors](#the-connection-to-claude-code-ended-before-this-message-completed) |

429| `Could not locate the Claude CLI on PATH` | [Wrapper and IDE errors](#could-not-locate-the-claude-cli-on-path) |437| `Could not locate the Claude CLI on PATH` | [Wrapper and IDE errors](#could-not-locate-the-claude-cli-on-path) |

430| `The Claude Code program for this computer, the <build> build, could not be found` | [Wrapper and IDE errors](#the-claude-code-program-for-this-computer-could-not-be-found) |438| `The Claude Code program for this computer, the <build> build, could not be found` | [Wrapper and IDE errors](#the-claude-code-program-for-this-computer-could-not-be-found) |


560| `CLAUDE_CODE_RETRY_WATCHDOG_MAX_USAGE_LIMIT_WAIT_MS` | no cap | With `CLAUDE_CODE_RETRY_WATCHDOG` set, the longest time in milliseconds one request waits for your plan's [usage limit](#youve-hit-your-session-limit), such as the session or weekly limit, to reset. When the reset is further away than this cap, the request fails at once, unless usage credits have room or the API couldn't check them. In those cases it's retried, and fails if the cap passes before it succeeds. Requires Claude Code v2.1.301 or later. |568| `CLAUDE_CODE_RETRY_WATCHDOG_MAX_USAGE_LIMIT_WAIT_MS` | no cap | With `CLAUDE_CODE_RETRY_WATCHDOG` set, the longest time in milliseconds one request waits for your plan's [usage limit](#youve-hit-your-session-limit), such as the session or weekly limit, to reset. When the reset is further away than this cap, the request fails at once, unless usage credits have room or the API couldn't check them. In those cases it's retried, and fails if the cap passes before it succeeds. Requires Claude Code v2.1.301 or later. |

561| [`CLAUDE_CODE_RETRY_WATCHDOG_USAGE_LIMIT_RECHECK_MS`](https://code.claude.com/docs/en/env-vars) | unset | Minimum interval in milliseconds between checks of whether a [usage limit](#youve-hit-your-session-limit) was already lifted, while a request waits for that limit to reset with `CLAUDE_CODE_RETRY_WATCHDOG` set. When a check finds the limit lifted, the request goes out at once. Give plain digits from `60000` to `10800000`. When unset or outside that range, no checks are made. For when Claude Code skips these checks, see the [environment variables reference](https://code.claude.com/docs/en/env-vars.md). Requires Claude Code v2.1.305 or later. |569| [`CLAUDE_CODE_RETRY_WATCHDOG_USAGE_LIMIT_RECHECK_MS`](https://code.claude.com/docs/en/env-vars) | unset | Minimum interval in milliseconds between checks of whether a [usage limit](#youve-hit-your-session-limit) was already lifted, while a request waits for that limit to reset with `CLAUDE_CODE_RETRY_WATCHDOG` set. When a check finds the limit lifted, the request goes out at once. Give plain digits from `60000` to `10800000`. When unset or outside that range, no checks are made. For when Claude Code skips these checks, see the [environment variables reference](https://code.claude.com/docs/en/env-vars.md). Requires Claude Code v2.1.305 or later. |

562| [`CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS`](https://code.claude.com/docs/en/env-vars) | 500 | Starting delay in milliseconds of the backoff between retries of a request that the API rejects with a `529` overloaded error. Raise it, up to 32000, to spread the retries over a longer window when the API is at capacity. Has no effect when `CLAUDE_CODE_RETRY_WATCHDOG` is set to `1`, or when the rejected request was sent in [fast mode](https://code.claude.com/docs/en/fast-mode.md#handle-rate-limits). Requires Claude Code v2.1.292 or later. |570| [`CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS`](https://code.claude.com/docs/en/env-vars) | 500 | Starting delay in milliseconds of the backoff between retries of a request that the API rejects with a `529` overloaded error. Raise it, up to 32000, to spread the retries over a longer window when the API is at capacity. Has no effect when `CLAUDE_CODE_RETRY_WATCHDOG` is set to `1`, or when the rejected request was sent in [fast mode](https://code.claude.com/docs/en/fast-mode.md#handle-rate-limits). Requires Claude Code v2.1.292 or later. |

563| [`CLAUDE_CODE_OVERLOADED_RETRY_MAX_DELAY_MS`](https://code.claude.com/docs/en/env-vars) | 32000 | Ceiling in milliseconds on the backoff between retries of a request that the API rejects with a `529` overloaded error. Raise it, up to 64000, so that later retries keep spreading apart when the API is at capacity. Has no effect when `CLAUDE_CODE_RETRY_WATCHDOG` is set to `1`, or when the rejected request was sent in [fast mode](https://code.claude.com/docs/en/fast-mode.md#handle-rate-limits). Requires Claude Code v2.1.296 or later. |571| [`CLAUDE_CODE_OVERLOADED_RETRY_MAX_DELAY_MS`](https://code.claude.com/docs/en/env-vars) | 32000 | Ceiling in milliseconds on the backoff between retries of a request that the API rejects with a `529` overloaded error. Raise it, up to 300000, so that later retries keep spreading apart when the API is at capacity. Values above 64000 require v2.1.323 or later. Has no effect in the same cases as `CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS`. Requires Claude Code v2.1.296 or later. |

564| [`API_TIMEOUT_MS`](https://code.claude.com/docs/en/env-vars) | 600000 | Time in milliseconds that each request attempt has to receive its response headers. It doesn't limit how long a streaming response runs after that. Raise it for slow networks or proxies. For how it caps the first-byte deadline, see [No response from API](#no-response-from-api). |572| [`API_TIMEOUT_MS`](https://code.claude.com/docs/en/env-vars) | 600000 | Time in milliseconds that each request attempt has to receive its response headers. It doesn't limit how long a streaming response runs after that. Raise it for slow networks or proxies. For how it caps the first-byte deadline, see [No response from API](#no-response-from-api). |

565| [`CLAUDE_CODE_NONSTREAMING_TIMEOUT_RETRIES`](https://code.claude.com/docs/en/env-vars) | unset | Limit on re-sends of a [non-streaming request](#streaming-response-ended-before-any-complete-data-was-received) that times out. At the limit, the request fails. A response from Claude that takes longer than the timeout to generate times out again on every re-send, so set a low number such as `0` to fail sooner. For each attempt's timeout, see [How long a non-streaming attempt waits](#how-long-a-non-streaming-attempt-waits). Requires Claude Code v2.1.285 or later. |573| [`CLAUDE_CODE_NONSTREAMING_TIMEOUT_RETRIES`](https://code.claude.com/docs/en/env-vars) | unset | Limit on re-sends of a [non-streaming request](#streaming-response-ended-before-any-complete-data-was-received) that times out. At the limit, the request fails. A response from Claude that takes longer than the timeout to generate times out again on every re-send, so set a low number such as `0` to fail sooner. For each attempt's timeout, see [How long a non-streaming attempt waits](#how-long-a-non-streaming-attempt-waits). Requires Claude Code v2.1.285 or later. |

566| [`CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS`](https://code.claude.com/docs/en/env-vars) | unset | Deadline in milliseconds for the first response byte of a streaming request. Requires Claude Code v2.1.242 or later. For how Claude Code picks the deadline when this is unset, see [No response from API](#no-response-from-api). |574| [`CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS`](https://code.claude.com/docs/en/env-vars) | unset | Deadline in milliseconds for the first response byte of a streaming request. Requires Claude Code v2.1.242 or later. For how Claude Code picks the deadline when this is unset, see [No response from API](#no-response-from-api). |


825Later calls in the same Claude response can be denied with this reason:833Later calls in the same Claude response can be denied with this reason:

826 834 

827```text theme={null}835```text theme={null}

828another call in this response was changed by a hook after auto mode reviewed it, or could not be confirmed unchanged836another call in this response was changed after auto mode reviewed it, or could not be confirmed unchanged

829```837```

830 838 

831Claude can then issue each denied call again so the server reviews it. If a permission prompt opens, answer it. You don't need to do anything else unless Claude says in its reply that auto mode couldn't check the call. Then stop the change or approve the call yourself, and ask Claude to try the call again:839Claude can then issue each denied call again so the server reviews it. If a permission prompt opens, answer it. You don't need to do anything else unless Claude says in its reply that auto mode couldn't check the call. Then stop the change or approve the call yourself, and ask Claude to try the call again:


978 986 

979### You've hit your monthly spend limit987### You've hit your monthly spend limit

980 988 

981Your plan's included usage can't cover this request, and the [usage credits](https://support.claude.com/en/articles/12429409-extra-usage-for-paid-claude-plans) that would otherwise pay for it have reached a spend limit. That happens when one of your plan's usage windows has run out, or when the request is one that only usage credits pay for, such as a request to a model that [bills to usage credits](https://code.claude.com/docs/en/model-config.md#fable-and-usage-credits). The message names whose limit blocked you. The text after the `·` says how to get that limit increased, and varies with your plan and whether you manage billing:989Your plan's included usage can't cover this request, and the [usage credits](https://support.claude.com/en/articles/12429409-extra-usage-for-paid-claude-plans) that would otherwise pay for it have reached a spend limit. Your plan can't cover a request when one of its usage windows has run out, or when only usage credits pay for the request. One example is a request to a model that [bills to usage credits](https://code.claude.com/docs/en/model-config.md#fable-and-usage-credits).

990 

991The words before the `·` name the limit that blocked you, such as your org's monthly spend limit, and the text after it says how to get that limit increased. In a cloud session or under [Remote Control](https://code.claude.com/docs/en/remote-control.md), that text gives no URL, and a message about your own `monthly spend limit` doesn't say how to raise it. Other sessions show forms like these:

982 992 

983```text theme={null}993```text theme={null}

984You've hit your monthly spend limit · raise it at https://claude.ai/settings/usage?from=cc_cli_limit_message994You've hit your monthly spend limit · raise it at https://claude.ai/settings/usage?from=cc_cli_limit_message


1822 1832 

1823Before v2.1.232, Claude Code used the v2 runtime only in a gradual rollout or when you set `MCP_SDK_GENERATION=v2`.1833Before v2.1.232, Claude Code used the v2 runtime only in a gradual rollout or when you set `MCP_SDK_GENERATION=v2`.

1824 1834 

1835### Stopped an OAuth request

1836 

1837This message means that Claude Code stopped an [OAuth request for an MCP server](https://code.claude.com/docs/en/mcp.md#authenticate-with-remote-mcp-servers) because an OAuth endpoint redirected it. In both forms of the message, the first address is the one that sent the redirect:

1838 

1839```text theme={null}

1840Stopped an OAuth request, which can hold secrets: https://auth.example.com redirected it to https://other.example.com. Ask the owner of https://auth.example.com to remove that redirect.

1841Stopped an OAuth request: https://auth.example.com redirected it more than 5 times. Ask the owner of https://auth.example.com to fix those redirects.

1842```

1843 

1844**What to do:**

1845 

1846* Ask whoever runs the first address, such as the MCP server's operator, to remove or fix the redirect. Then try again from `/mcp`.

1847 

1825### Refusing to send credentials to non-https token endpoint1848### Refusing to send credentials to non-https token endpoint

1826 1849 

1827On the [v2 runtime](https://code.claude.com/docs/en/mcp.md#mcp-client-runtimes), Claude Code sends an [MCP OAuth](https://code.claude.com/docs/en/mcp.md#authenticate-with-remote-mcp-servers) token request only to a token endpoint served over HTTPS or at `localhost`, `127.0.0.1`, or `::1`. This message means the server's token endpoint is neither, so Claude Code stopped before sending the request. That happens after the browser sign-in, so the browser step succeeds first, and again whenever Claude Code refreshes the server's token.1850On the [v2 runtime](https://code.claude.com/docs/en/mcp.md#mcp-client-runtimes), Claude Code sends an [MCP OAuth](https://code.claude.com/docs/en/mcp.md#authenticate-with-remote-mcp-servers) token request only to a token endpoint served over HTTPS or at `localhost`, `127.0.0.1`, or `::1`. This message means the server's token endpoint is neither, so Claude Code stopped before sending the request. That happens after the browser sign-in, so the browser step succeeds first, and again whenever Claude Code refreshes the server's token.


2207 2230 

2208### Host not allowed in a cloud session2231### Host not allowed in a cloud session

2209 2232 

2210An outbound HTTP request from a cloud session or cloud scheduled task was blocked by the environment's network policy.2233In a cloud session or cloud scheduled task, a `403` or a DNS error such as `ENOTFOUND` can mean that the requested host isn't on the [cloud environment's allowlist](https://code.claude.com/docs/en/cloud-environments.md#access-levels). To confirm, check the host against that list. A `403` with this header confirms the block, but not every blocked request's `403` has it:

2211 2234 

2212```text theme={null}2235```text theme={null}

2213HTTP 4032236HTTP 403


2290 2313 

2291Before v2.1.296, Claude Code didn't retry a failed read, and after one it could open the session with an empty conversation and report success instead of printing this message.2314Before v2.1.296, Claude Code didn't retry a failed read, and after one it could open the session with an empty conversation and report success instead of printing this message.

2292 2315 

2316### Couldn't load the history of cloud session

2317 

2318This message means Claude Code found the [cloud session you asked to pull into your terminal](https://code.claude.com/docs/en/claude-code-on-the-web.md#from-cloud-to-terminal), but the request for its conversation history came back as not found:

2319 

2320```text theme={null}

2321Couldn't load the history of cloud session session_01HJKLMNOPQRSTUVWXYZ. Check it at https://claude.ai/code/session_01HJKLMNOPQRSTUVWXYZ?from=cli

2322```

2323 

2324**What to do:**

2325 

2326* Open the link in the message to check the session in your browser. If it opens there and the same teleport fails this way again, [report the problem](#report-an-error).

2327 

2293### Couldn't reconnect to your Remote Control session2328### Couldn't reconnect to your Remote Control session

2294 2329 

2295```text theme={null}2330```text theme={null}


2565 2600 

2566Claude Code normally resizes large images automatically. These errors mean the image couldn't be decoded or resized to fit within the API limits.2601Claude Code normally resizes large images automatically. These errors mean the image couldn't be decoded or resized to fit within the API limits.

2567 2602 

2603The error you see can name a different pixel limit, such as `2576x2576px` where these examples say `2000x2000px`.

2604 

2568**What to do:**2605**What to do:**

2569 2606 

2570* If the message asks you to convert the image, convert it to PNG, JPEG, GIF, or WebP and attach it again. Claude Code can verify dimensions for these formats from the file header, without decoding the image.2607* If the message asks you to convert the image, convert it to PNG, JPEG, GIF, or WebP and attach it again. Claude Code can verify dimensions for these formats from the file header, without decoding the image.


2873* **A reason a hook wrote**: a PreModelSwitch hook supplied that reason when it [denied the switch or asked for confirmation](https://code.claude.com/docs/en/hooks.md#premodelswitch-decision-control). Address what it asks, or pick a model your hooks allow.2910* **A reason a hook wrote**: a PreModelSwitch hook supplied that reason when it [denied the switch or asked for confirmation](https://code.claude.com/docs/en/hooks.md#premodelswitch-decision-control). Address what it asks, or pick a model your hooks allow.

2874* **`PreModelSwitch hook <name> did not respond before its timeout`**: a hook that doesn't answer before its [timeout](https://code.claude.com/docs/en/hooks.md#timeouts) blocks the switch. Fix the hanging command or raise that hook's `timeout`, then switch again.2911* **`PreModelSwitch hook <name> did not respond before its timeout`**: a hook that doesn't answer before its [timeout](https://code.claude.com/docs/en/hooks.md#timeouts) blocks the switch. Fix the hanging command or raise that hook's `timeout`, then switch again.

2875* **`confirmation required, and this session cannot ask`**: a hook answered `ask` without a reason, and a control request has no way to show the confirmation prompt. A `/model` command in a [`-p` run](https://code.claude.com/docs/en/headless) reports the same condition with `(run /model interactively to confirm)` after the reason. Make the switch from an interactive session, or change the hook's decision for this model.2912* **`confirmation required, and this session cannot ask`**: a hook answered `ask` without a reason, and a control request has no way to show the confirmation prompt. A `/model` command in a [`-p` run](https://code.claude.com/docs/en/headless) reports the same condition with `(run /model interactively to confirm)` after the reason. Make the switch from an interactive session, or change the hook's decision for this model.

2876* **`so organization-managed PreModelSwitch hooks could not be checked`**: Claude Code couldn't tell which PreModelSwitch hooks your organization's [managed plugins](https://code.claude.com/docs/en/settings-reference.md#enabledplugins) deliver, for example because a managed plugin failed to load. One of those hooks might block the switch, so Claude Code refuses rather than apply the switch unchecked. The start of the reason names what failed. Claude Code re-checks on every switch attempt, so a failure that has since cleared stops blocking; if it keeps failing, run `claude --debug` and switch again to capture the details, then fix the plugin or ask your admin to fix it.2913* **`so organization-managed PreModelSwitch hooks could not be checked`**: Claude Code before v2.1.323 refuses when it can't tell which PreModelSwitch hooks your [managed plugins](https://code.claude.com/docs/en/settings-reference.md#enabledplugins) deliver. The text before this phrase names what failed. To stop the refusal, update Claude Code. To also get a failed plugin's hooks running, fix the plugin or ask your admin. For details, start `claude --debug` in your shell and switch models, then read the [debug log](https://code.claude.com/docs/en/hooks.md#debug-hooks).

2877* **`a PreModelSwitch hook failed before answering`** or **`PreModelSwitch hooks were cancelled (the control stream closed) before answering`**: the hook run ended without a verdict, and Claude Code doesn't treat that as approval. Run `claude --debug` to see what failed, then switch again.2914* **`a PreModelSwitch hook failed before answering`** or **`PreModelSwitch hooks were cancelled (the control stream closed) before answering`**: the hook run ended without a verdict, and Claude Code doesn't treat that as approval. Run `claude --debug` to see what failed, then switch again.

2878 2915 

2879Before v2.1.260, the managed-plugin refusal read `plugin hooks could not be loaded, so PreModelSwitch hooks could not be checked; see the debug log`. Claude Code retried the plugin load once and then refused later switches in the session, even when your organization managed no plugins. Restart the session to run the plugin load again on those versions.2916Before v2.1.260, the managed-plugin refusal read `plugin hooks could not be loaded, so PreModelSwitch hooks could not be checked; see the debug log`. Claude Code retried the plugin load once and then refused later switches in the session, even when your organization managed no plugins. Restart the session to run the plugin load again on those versions.


3522You started [Remote Control](https://code.claude.com/docs/en/remote-control.md) with a global `claude` flag before the `remote-control` verb, one that would restrict or configure the sessions Remote Control starts, such as `--settings`, `--setting-sources`, `--permission-mode`, `--disallowed-tools`, or `--mcp-config`. A flag placed before the verb never reaches those sessions. Claude Code refuses to start instead, naming the flag:3559You started [Remote Control](https://code.claude.com/docs/en/remote-control.md) with a global `claude` flag before the `remote-control` verb, one that would restrict or configure the sessions Remote Control starts, such as `--settings`, `--setting-sources`, `--permission-mode`, `--disallowed-tools`, or `--mcp-config`. A flag placed before the verb never reaches those sessions. Claude Code refuses to start instead, naming the flag:

3523 3560 

3524```text theme={null}3561```text theme={null}

3525Error: `--settings` before `remote-control` is not carried over to the sessions Remote Control starts, so Remote Control refuses to start rather than drop it — remove it, and give Remote Control's own options after the verb (see `claude remote-control --help`).3562Error: `--settings` before `remote-control` is not carried over to the sessions Remote Control starts, so Remote Control refuses to start rather than drop it — remove it, and give Remote Control's own options after the verb (see `claude remote-control --help`). Pass settings with `claude remote-control --settings <file>`.

3526```3563```

3527 3564 

3528Claude Code doesn't refuse global flags that are harmless to drop, such as `--verbose`, `--model`, or a wrapper-injected `--session-id` or `--plugin-dir`: it ignores them and Remote Control starts.3565Claude Code doesn't refuse global flags that are harmless to drop, such as `--verbose`, `--model`, or a wrapper-injected `--session-id` or `--plugin-dir`: it ignores them and Remote Control starts.


3536 3573 

3537Before v2.1.248, `claude remote-control` didn't accept its own flags when a global flag came first, and the command failed with an `unknown option` error.3574Before v2.1.248, `claude remote-control` didn't accept its own flags when a global flag came first, and the command failed with an `unknown option` error.

3538 3575 

3576### Remote Control did not start because of the `--settings` file

3577 

3578The file you passed to [`claude remote-control --settings`](https://code.claude.com/docs/en/remote-control#start-a-remote-control-session) has a problem:

3579 

3580```text theme={null}

3581Error: Remote Control did not start, because sessions would skip part or all of the --settings file ./rc-settings.json: Invalid or malformed JSON

3582```

3583 

3584**What to do:**

3585 

3586* Fix the problem the message names, then run your `claude remote-control` command again

3587 

3588### The settings file has changed since Remote Control started

3589 

3590This message in the terminal running `claude remote-control` means that sessions won't start from the file you passed to [`--settings`](https://code.claude.com/docs/en/remote-control#start-a-remote-control-session) as it is now:

3591 

3592```text theme={null}

3593Session failed: Error: The settings file /path/to/settings.json has changed since Remote Control started, so this session did not start. Restart `claude remote-control` to use it as it is now.

3594```

3595 

3596**What to do:**

3597 

3598* To use the file as it is now, stop `claude remote-control` and run the same command again. To bring back the sessions it was serving, see [Resume sessions after stopping the server](https://code.claude.com/docs/en/remote-control.md#resume-sessions-after-stopping-the-server).

3599* To keep the settings Remote Control started with, put the file's contents back as they were, then run the command again if `claude remote-control` has exited

3600 

3539### `--sandbox` or `--no-sandbox` is not supported by claude remote-control3601### `--sandbox` or `--no-sandbox` is not supported by claude remote-control

3540 3602 

3541This error means the command that starts your [Remote Control](https://code.claude.com/docs/en/remote-control.md) server passes `--sandbox` or `--no-sandbox` after `remote-control`, and `claude remote-control` accepts neither flag. The server exits with code 1 instead of starting:3603This error means the command that starts your [Remote Control](https://code.claude.com/docs/en/remote-control.md) server passes `--sandbox` or `--no-sandbox` after `remote-control`, and `claude remote-control` accepts neither flag. The server exits with code 1 instead of starting:


3806 3868 

3807Sibling strings fire before the command runs at all:3869Sibling strings fire before the command runs at all:

3808 3870 

3809* `Shell command permission check failed for pattern "..."`: the command's permission check didn't allow it. [Permission checks on injected commands](https://code.claude.com/docs/en/skills.md#permission-checks-on-injected-commands) covers which results abort in each permission mode and how to pre-approve a command with `allowed-tools`3871* `Shell command permission check failed for pattern "..."`: the command's permission check didn't allow it. See [Permission checks on injected commands](https://code.claude.com/docs/en/skills.md#permission-checks-on-injected-commands) for which results abort in each permission mode and when `allowed-tools` pre-approves a command

3810* ``Skill <name> requires bash (`shell: bash` in frontmatter) but Git Bash was not found``: the skill's frontmatter demands bash on a machine without it. Install Git for Windows or change the frontmatter to `shell: powershell`. See [How injected commands run](https://code.claude.com/docs/en/skills.md#how-injected-commands-run)3872* ``Skill <name> requires bash (`shell: bash` in frontmatter) but Git Bash was not found``: the skill's frontmatter demands bash on a machine without it. Install Git for Windows or change the frontmatter to `shell: powershell`. See [How injected commands run](https://code.claude.com/docs/en/skills.md#how-injected-commands-run)

3811 3873 

3812**What to do:**3874**What to do:**


4490commands path escapes plugin directory: ./commands/deploy.md — it resolves to /home/user/shared/deploy.md, outside the plugin directory4552commands path escapes plugin directory: ./commands/deploy.md — it resolves to /home/user/shared/deploy.md, outside the plugin directory

4491```4553```

4492 4554 

4493A message that gives the full path of one of a marketplace plugin's own files, such as `hooks/hooks.json`, means Claude Code skipped that file. That happens when Claude Code can't confirm the file is inside the plugin or, for a plugin in a [local marketplace](https://code.claude.com/docs/en/plugins/loading.md#in-place-and-copied-plugins), inside that marketplace. The message reports each of these files under the component name shown:4555A message that gives the full path of one of a marketplace plugin's own files, such as `hooks/hooks.json`, means Claude Code skipped that file. When Claude Code can't confirm the file is inside the plugin, or inside its marketplace for a plugin in a [local marketplace](https://code.claude.com/docs/en/plugins/loading.md#in-place-and-copied-plugins), it skips the file. The message reports these files under the component name shown:

4494 4556 

4495* `hooks/hooks.json`: `hooks`4557* `hooks/hooks.json`: `hooks`

4496* `monitors/monitors.json`: `monitors`4558* `monitors/monitors.json`: `monitors`

4497* `settings.json`: `settings`

4498* `SKILL.md` at the plugin root: `skills`4559* `SKILL.md` at the plugin root: `skills`

4499 4560 

4500For example, this message is for a `hooks/hooks.json` that resolves outside both the plugin and its local marketplace:4561For example, this message is for a `hooks/hooks.json` that resolves outside both the plugin and its local marketplace:


5481You opened a [background session](https://code.claude.com/docs/en/agent-view.md) that ended while the background service was off, and [transcript cleanup](https://code.claude.com/docs/en/settings-reference.md#cleanupperioddays) has since removed its saved conversation, for example after the machine was off for weeks. Opening such a row normally [resumes its saved conversation](https://code.claude.com/docs/en/agent-view.md#sessions-show-as-failed-after-shutdown). With nothing left to resume, Claude Code refuses rather than re-run the session's original prompt without asking:5542You opened a [background session](https://code.claude.com/docs/en/agent-view.md) that ended while the background service was off, and [transcript cleanup](https://code.claude.com/docs/en/settings-reference.md#cleanupperioddays) has since removed its saved conversation, for example after the machine was off for weeks. Opening such a row normally [resumes its saved conversation](https://code.claude.com/docs/en/agent-view.md#sessions-show-as-failed-after-shutdown). With nothing left to resume, Claude Code refuses rather than re-run the session's original prompt without asking:

5482 5543 

5483```text theme={null}5544```text theme={null}

5484This session's saved conversation is no longer on disk (it ended while the background service was off, and old transcripts are cleaned up), so there is nothing to resume. `claude rm 7c5dcf5d` deletes the row; `claude respawn 7c5dcf5d` runs its original prompt again instead.5545This session's saved conversation is no longer on disk (it ended while the background service was off, and old transcripts are cleaned up), so there is nothing to resume. `claude rm 7c5dcf5d` removes the row; `claude respawn 7c5dcf5d` runs its original prompt again instead.

5485```5546```

5486 5547 

5487`claude attach <id>` prints this text. In agent view, the footer is shorter and ends with `ctrl+x deletes the row`.5548`claude attach <id>` prints this text. In agent view, the footer is shorter and ends with `ctrl+x removes the row`.

5488 5549 

5489**What to do:**5550**What to do:**

5490 5551 


5503 push them and run 'claude rm 7c5dcf5d' again, or discard the worktree and its commits: claude rm 7c5dcf5d --discard-unpushed a1b2c3d000000000000000000000000000000000@0123456789abcdef0123456789abcdef5564 push them and run 'claude rm 7c5dcf5d' again, or discard the worktree and its commits: claude rm 7c5dcf5d --discard-unpushed a1b2c3d000000000000000000000000000000000@0123456789abcdef0123456789abcdef

5504```5565```

5505 5566 

5506When Claude Code can't summarize the commits, the detail line reads `The worktree has unpushed commits` instead. In [agent view](https://code.claude.com/docs/en/agent-view.md), the session's row shows `not deleted` with the same reason.5567When Claude Code can't summarize the commits, the detail line reads `The worktree has unpushed commits` instead. In [agent view](https://code.claude.com/docs/en/agent-view.md), the session's row shows `not removed` with the same reason.

5507 5568 

5508Commits on a remote don't block the delete. Neither do commits on the local copy of your `origin` remote's default branch, as long as that branch is checked out in your main checkout, the repository directory itself rather than a worktree.5569Commits on a remote don't block the delete. Neither do commits on the local copy of your `origin` remote's default branch, as long as that branch is checked out in your main checkout, the repository directory itself rather than a worktree.

5509 5570 


5780 5841 

5781These errors come from the program that launched Claude Code for you, such as an IDE extension or an [Agent SDK](https://code.claude.com/docs/en/agent-sdk/overview.md) application, rather than from Claude Code itself.5842These errors come from the program that launched Claude Code for you, such as an IDE extension or an [Agent SDK](https://code.claude.com/docs/en/agent-sdk/overview.md) application, rather than from Claude Code itself.

5782 5843 

5844### Subprocess initialization did not complete within 60000ms

5845 

5846This error means a Claude Code process that the [VS Code extension](https://code.claude.com/docs/en/vs-code.md) or an Agent SDK application launched didn't report in time that it was ready. The extension or application then stopped it. In a VS Code conversation the error starts with `Claude Code did not finish starting`, for example:

5847 

5848```text theme={null}

5849Claude Code did not finish starting: it did not answer in time. The output logs ("View output logs") show how far it got. Slow plugins, MCP servers, hooks, disks or network can each cause this.

5850```

5851 

5852In the extension's output logs, on its sign-in screen, and in an Agent SDK application, the error reads differently. It starts with `Subprocess initialization did not complete within` and the time limit, then gives what Claude Code reported, for example:

5853 

5854```text theme={null}

5855Subprocess initialization did not complete within 60000ms. Claude Code did not answer the initialize request and reported no SessionStart or Setup hook running. Slow plugins, MCP servers, hooks that Claude Code does not report, disks or network can each cause this.

5856```

5857 

5858**What to do:**

5859 

5860* To try again in VS Code, send a message. If the error appeared while you were signing in, select the sign-in method again instead.

5861* To see how far Claude Code got, click **View output logs** under a conversation's error, or run **Claude Code: Show Logs** from the Command Palette. Include the entries around the `Subprocess initialization` line when [reporting the problem](https://github.com/anthropics/claude-code/issues).

5862* To check your network, see [Network configuration](https://code.claude.com/docs/en/network-config.md). If the message tells you to check your sign-in or authentication, see [Login and authentication](https://code.claude.com/docs/en/troubleshoot-install.md#login-and-authentication).

5863* If the message says that [SessionStart](https://code.claude.com/docs/en/hooks.md#sessionstart) or [Setup](https://code.claude.com/docs/en/hooks.md#setup) hooks hadn't finished, [check how long yours run](https://code.claude.com/docs/en/hooks.md#debug-hooks). In VS Code, the first 10 minutes in which Claude Code reports these hooks running don't count toward the 60-second limit. Make a slow hook finish sooner, lower a non-async hook's [`timeout`](https://code.claude.com/docs/en/hooks#common-fields), or [remove the hook](https://code.claude.com/docs/en/hooks.md#disable-or-remove-hooks).

5864* If your Agent SDK application calls [`startup()`](https://code.claude.com/docs/en/agent-sdk/typescript#startup), set `initializeTimeoutMs` long enough for the whole start, or leave it unset so up to 10 minutes of reported hook time doesn't count.

5865 

5866Before VS Code extension v2.1.304 and TypeScript Agent SDK v0.3.304, all hook time counted toward the limit. With the default limit, the message contained `Subprocess initialization did not complete within 60000ms — check authentication and network connectivity`. If you see that wording, update the extension or the SDK.

5867 

5783### Claude Code process exited with code N5868### Claude Code process exited with code N

5784 5869 

5785The underlying `claude` process exited with a non-zero code. The exit code alone doesn't say what failed: the real error is in the process's own output, which the wrapper appends when it captured any and otherwise keeps in its logs.5870The underlying `claude` process exited with a non-zero code. The exit code alone doesn't say what failed: the real error is in the process's own output, which the wrapper appends when it captured any and otherwise keeps in its logs.

Details

117 <td>✗</td>117 <td>✗</td>

118 </tr>118 </tr>

119 119 

120 <tr>

121 <td>[Code Mode](https://code.claude.com/docs/en/code-mode.md)</td>

122 <td>✓ (experimental, [requirements apply](https://code.claude.com/docs/en/code-mode.md#requirements))</td>

123 <td>✓ (experimental, [requirements apply](https://code.claude.com/docs/en/code-mode.md#requirements))</td>

124 <td>✗</td>

125 <td>✗</td>

126 <td>✗</td>

127 <td>✗</td>

128 </tr>

129 

120 <tr>130 <tr>

121 <td>[Cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md)</td>131 <td>[Cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md)</td>

122 <td>✓ <sup>[5](#fn5)</sup></td>132 <td>✓ <sup>[5](#fn5)</sup></td>


231 241 

232> [tab] Amazon Bedrock242> [tab] Amazon Bedrock

233>243>

234> **Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription), plus [web search](https://code.claude.com/docs/en/tools-reference.md#websearch-tool-behavior), [fast mode](https://code.claude.com/docs/en/fast-mode.md), [Advisor](https://code.claude.com/docs/en/advisor.md), [Channels](https://code.claude.com/docs/en/channels.md), the [analytics dashboard](https://code.claude.com/docs/en/analytics.md), [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md), and the [`/design-sync` and `/import` commands](https://code.claude.com/docs/en/commands#all-commands).244> **Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription), plus [web search](https://code.claude.com/docs/en/tools-reference.md#websearch-tool-behavior), [fast mode](https://code.claude.com/docs/en/fast-mode.md), [Advisor](https://code.claude.com/docs/en/advisor.md), [Channels](https://code.claude.com/docs/en/channels.md), [Code Mode](https://code.claude.com/docs/en/code-mode.md), the [analytics dashboard](https://code.claude.com/docs/en/analytics.md), [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md), and the [`/design-sync` and `/import` commands](https://code.claude.com/docs/en/commands#all-commands).

235>245>

236> **Partial support:**246> **Partial support:**

237>247>


244 254 

245> [tab] Claude Platform on AWS255> [tab] Claude Platform on AWS

246>256>

247> **Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription), plus [fast mode](https://code.claude.com/docs/en/fast-mode.md), [Channels](https://code.claude.com/docs/en/channels.md), [GitHub Actions](https://code.claude.com/docs/en/github-actions.md), the [analytics dashboard](https://code.claude.com/docs/en/analytics.md), [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md), and the [`/design-sync` and `/import` commands](https://code.claude.com/docs/en/commands#all-commands).257> **Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription), plus [fast mode](https://code.claude.com/docs/en/fast-mode.md), [Channels](https://code.claude.com/docs/en/channels.md), [GitHub Actions](https://code.claude.com/docs/en/github-actions.md), [Code Mode](https://code.claude.com/docs/en/code-mode.md), the [analytics dashboard](https://code.claude.com/docs/en/analytics.md), [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md), and the [`/design-sync` and `/import` commands](https://code.claude.com/docs/en/commands#all-commands).

248>258>

249> **Available here, not on Amazon Bedrock:** [web search](https://code.claude.com/docs/en/tools-reference.md#websearch-tool-behavior), plus the [Advisor](https://code.claude.com/docs/en/advisor.md) in Claude Code v2.1.300 or later.259> **Available here, not on Amazon Bedrock:** [web search](https://code.claude.com/docs/en/tools-reference.md#websearch-tool-behavior), plus the [Advisor](https://code.claude.com/docs/en/advisor.md) in Claude Code v2.1.300 or later.

250>260>


256 266 

257> [tab] Google Cloud's Agent Platform267> [tab] Google Cloud's Agent Platform

258>268>

259> **Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription), plus [Advisor](https://code.claude.com/docs/en/advisor.md), [Channels](https://code.claude.com/docs/en/channels.md), the [analytics dashboard](https://code.claude.com/docs/en/analytics.md), [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md), and the [`/design-sync` and `/import` commands](https://code.claude.com/docs/en/commands#all-commands).269> **Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription), plus [Advisor](https://code.claude.com/docs/en/advisor.md), [Channels](https://code.claude.com/docs/en/channels.md), [Code Mode](https://code.claude.com/docs/en/code-mode.md), the [analytics dashboard](https://code.claude.com/docs/en/analytics.md), [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md), and the [`/design-sync` and `/import` commands](https://code.claude.com/docs/en/commands#all-commands).

260>270>

261> **Partial support:**271> **Partial support:**

262>272>


271 281 

272> [tab] Microsoft Foundry282> [tab] Microsoft Foundry

273>283>

274> **Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription), plus [fast mode](https://code.claude.com/docs/en/fast-mode.md), [Advisor](https://code.claude.com/docs/en/advisor.md), [Channels](https://code.claude.com/docs/en/channels.md), [GitLab CI/CD](https://code.claude.com/docs/en/gitlab-ci-cd.md), the [analytics dashboard](https://code.claude.com/docs/en/analytics.md), [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md), and the [`/design-sync` and `/import` commands](https://code.claude.com/docs/en/commands#all-commands).284> **Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription), plus [fast mode](https://code.claude.com/docs/en/fast-mode.md), [Advisor](https://code.claude.com/docs/en/advisor.md), [Channels](https://code.claude.com/docs/en/channels.md), [GitLab CI/CD](https://code.claude.com/docs/en/gitlab-ci-cd.md), [Code Mode](https://code.claude.com/docs/en/code-mode.md), the [analytics dashboard](https://code.claude.com/docs/en/analytics.md), [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md), and the [`/design-sync` and `/import` commands](https://code.claude.com/docs/en/commands#all-commands).

275>285>

276> **Partial support:**286> **Partial support:**

277>287>

Details

188>188>

189> **Put guardrails in hooks.** An instruction like "never edit `.env`" in CLAUDE.md or a skill is a request, not a guarantee. A `PreToolUse` hook that blocks the edit is enforcement. If a rule must hold every time, make it a hook rather than a prompt instruction.189> **Put guardrails in hooks.** An instruction like "never edit `.env`" in CLAUDE.md or a skill is a request, not a guarantee. A `PreToolUse` hook that blocks the edit is enforcement. If a rule must hold every time, make it a hook rather than a prompt instruction.

190>190>

191> **Hook output lands in context.** A `PostToolUse` hook that runs your linter feeds results back as text Claude reads; a `/fix-lint` skill tells Claude how to resolve them.191> **Pair a hook with a skill.** If a `PostToolUse` hook runs your linter, printing the errors to stdout isn't enough for Claude to see them. When there are errors, have the hook print them to stderr instead and [exit with code 2](https://code.claude.com/docs/en/hooks.md#exit-code-2-behavior-per-event). To give Claude your own rules for fixing the errors, write a skill such as `/fix-lint`.

192 192 

193### Understand how features layer193### Understand how features layer

194 194 

gateways.md +1 −1

Details

63* **Client telemetry**: Claude Code disables its Anthropic-bound client analytics when a session signs in to a Claude apps gateway. To keep pre-sign-in startup analytics off as well, deliver [`DISABLE_TELEMETRY`](https://code.claude.com/docs/en/managed-settings#turn-telemetry-off-for-your-organization) in the [client-side managed settings](https://code.claude.com/docs/en/claude-apps-gateway-config.md#client-side-managed-settings) on each device.63* **Client telemetry**: Claude Code disables its Anthropic-bound client analytics when a session signs in to a Claude apps gateway. To keep pre-sign-in startup analytics off as well, deliver [`DISABLE_TELEMETRY`](https://code.claude.com/docs/en/managed-settings#turn-telemetry-off-for-your-organization) in the [client-side managed settings](https://code.claude.com/docs/en/claude-apps-gateway-config.md#client-side-managed-settings) on each device.

64* **Client telemetry on other gateways**: whether Claude Code sends the optional client telemetry stream depends on your provider, and the [telemetry defaults table](https://code.claude.com/docs/en/data-usage.md#default-behaviors-by-api-provider) covers each case.64* **Client telemetry on other gateways**: whether Claude Code sends the optional client telemetry stream depends on your provider, and the [telemetry defaults table](https://code.claude.com/docs/en/data-usage.md#default-behaviors-by-api-provider) covers each case.

65* **Telemetry destinations**: where Claude Code sends a gateway session's telemetry depends on how the session signed in, and [What's enforced on developers](https://code.claude.com/docs/en/claude-apps-gateway#whats-enforced-on-developers) says where each kind of session's exports go.65* **Telemetry destinations**: where Claude Code sends a gateway session's telemetry depends on how the session signed in, and [What's enforced on developers](https://code.claude.com/docs/en/claude-apps-gateway#whats-enforced-on-developers) says where each kind of session's exports go.

66* **Corporate HTTP proxies**: an `HTTPS_PROXY` sits between Claude Code and every server it talks to, including the gateway. If your network requires one, [configure the proxy](https://code.claude.com/docs/en/network-config.md) in addition to the gateway. For a Claude apps gateway you host, [sign-in checks that the proxy host is also on a private network](https://code.claude.com/docs/en/claude-apps-gateway#prerequisites); if it isn't, add the gateway host to `NO_PROXY` so the CLI connects to it directly.66* **Corporate HTTP proxies**: Claude Code sends its requests, including those to the gateway, through the proxy in `HTTPS_PROXY`. If your network requires a proxy, [configure it](https://code.claude.com/docs/en/network-config.md). If the proxy applies to a Claude apps gateway you host, [sign-in](https://code.claude.com/docs/en/claude-apps-gateway#prerequisites) needs the proxy's hostname to resolve to private addresses, or the gateway host in `NO_PROXY`.

67 67 

68## Next steps68## Next steps

69 69 

Details

129| Administration | Read |129| Administration | Read |

130| Checks | Read and write |130| Checks | Read and write |

131| Contents | Read and write |131| Contents | Read and write |

132| Dependabot alerts | Read |

132| Discussions | Read and write |133| Discussions | Read and write |

133| Issues | Read and write |134| Issues | Read and write |

134| Members | Read |135| Members | Read |

Details

84> Create a Microsoft Entra application with a federated credential for your repository, following [Microsoft's guide to authenticating from GitHub Actions](https://learn.microsoft.com/en-us/azure/developer/github/connect-from-azure-openid-connect):84> Create a Microsoft Entra application with a federated credential for your repository, following [Microsoft's guide to authenticating from GitHub Actions](https://learn.microsoft.com/en-us/azure/developer/github/connect-from-azure-openid-connect):

85>85>

86> * Register a Microsoft Entra application and add a federated identity credential that trusts tokens GitHub issues to your repository. A user-assigned managed identity works in place of an application. Both have the client ID you note below86> * Register a Microsoft Entra application and add a federated identity credential that trusts tokens GitHub issues to your repository. A user-assigned managed identity works in place of an application. Both have the client ID you note below

87> * Assign the application the `Azure AI User` role on your Foundry resource. See [Azure RBAC configuration](https://code.claude.com/docs/en/microsoft-foundry.md#azure-rbac-configuration) for a narrower custom role87> * Assign the application the `Foundry User` role on your Foundry resource. See [Azure RBAC configuration](https://code.claude.com/docs/en/microsoft-foundry.md#azure-rbac-configuration) for the other built-in role and custom roles

88>88>

89> Note the application's client ID, your tenant ID, and your subscription ID. You add them as secrets in the next step.89> Note the application's client ID, your tenant ID, and your subscription ID. You add them as secrets in the next step.

90 90 

Details

228 228 

229### When a model is disabled mid-session229### When a model is disabled mid-session

230 230 

231If your project loses access to the model your session is running on, for example because an administrator disables it in [Model Garden](https://console.cloud.google.com/vertex-ai/model-garden), Claude Code switches the session to another model instead of failing each request, and shows `Switched to <fallback> because <model> is not available`. It tries the same models as the startup fallback: earlier versions of the same tier first and, for an Opus session with no Opus version available, the default Sonnet model.231When Agent Platform rejects your session's model as unavailable in your project or region, Claude Code switches your session to another model, and you can keep working. You see a message that starts with `Switched to <fallback> because <model> is not available`. This happens, for example, when an administrator disables the model in [Model Garden](https://console.cloud.google.com/vertex-ai/model-garden) or it isn't served in your region.

232 232 

233The switch applies only to a tier you haven't pinned, the same condition as the startup fallback. A session on a specific version you picked keeps its model and, without a fallback model chain, the request fails instead. In [auto mode](https://code.claude.com/docs/en/permission-modes.md#enable-auto-mode-on-bedrock-agent-platform-or-foundry), Claude Code switches only to a model auto mode supports on Agent Platform. If none of those models is available either, the request fails.233If you configured a [fallback model chain](https://code.claude.com/docs/en/model-config.md#fallback-model-chains), Claude Code switches to your configured fallback instead. Without a chain, the request fails in cases such as these:

234 234 

235A [fallback model chain](https://code.claude.com/docs/en/model-config.md#fallback-model-chains) you configure replaces the tier switch: on these refusals Claude Code switches to your configured fallback instead. To have refused requests fail rather than switch, set [`CLAUDE_CODE_DISABLE_MODEL_ACCESS_FALLBACK=1`](https://code.claude.com/docs/en/env-vars). A fallback chain you configured still switches on these refusals; remove the chain as well if you want every refused request to fail.235* Your session is on a pinned model or a specific version you picked

236* None of the [models Claude Code tries](#startup-model-checks) is available. In [auto mode](https://code.claude.com/docs/en/permission-modes.md#enable-auto-mode-on-bedrock-agent-platform-or-foundry), Claude Code only switches to a model auto mode supports on Agent Platform.

237 

238To keep working, run `/model` in the session and press `s` on a model available in your project and region, which leaves your default unchanged.

239 

240To have rejected requests fail instead of switching, set [`CLAUDE_CODE_DISABLE_MODEL_ACCESS_FALLBACK=1`](https://code.claude.com/docs/en/env-vars). If you configured a fallback model chain, remove it as well, because Claude Code still moves to that fallback.

236 241 

237## IAM configuration242## IAM configuration

238 243 

hooks.md +21 −6

Details

257Administrators can use [`allowManagedHooksOnly`](https://code.claude.com/docs/en/settings-reference#allowmanagedhooksonly) in [managed settings](https://code.claude.com/docs/en/managed-settings.md) to restrict which hooks run:257Administrators can use [`allowManagedHooksOnly`](https://code.claude.com/docs/en/settings-reference#allowmanagedhooksonly) in [managed settings](https://code.claude.com/docs/en/managed-settings.md) to restrict which hooks run:

258 258 

259* Your user, project, local, and plugin hooks are blocked. Hooks from plugins force-enabled in managed settings `enabledPlugins` are exempt259* Your user, project, local, and plugin hooks are blocked. Hooks from plugins force-enabled in managed settings `enabledPlugins` are exempt

260* Claude Code also narrows your [`statusLine`](https://code.claude.com/docs/en/statusline), [`fileSuggestion`](https://code.claude.com/docs/en/settings-reference#filesuggestion), and [`subagentStatusLine`](https://code.claude.com/docs/en/statusline#subagent-status-lines) settings to managed settings260* Claude Code also narrows your [`statusLine`](https://code.claude.com/docs/en/statusline) and [`fileSuggestion`](https://code.claude.com/docs/en/settings-reference#filesuggestion) settings to managed settings

261* Claude Code also disables plugins with a [`command` source](https://code.claude.com/docs/en/plugins/marketplace-reference#command-plugin-source), including plugins force-enabled in managed settings `enabledPlugins`, unless [`disableCommandPluginSources`](https://code.claude.com/docs/en/settings-reference#disablecommandpluginsources) is explicitly set to `false`. `command` sources require Claude Code v2.1.229 or later261* Claude Code also disables plugins with a [`command` source](https://code.claude.com/docs/en/plugins/marketplace-reference#command-plugin-source), including plugins force-enabled in managed settings `enabledPlugins`, unless [`disableCommandPluginSources`](https://code.claude.com/docs/en/settings-reference#disablecommandpluginsources) is explicitly set to `false`. `command` sources require Claude Code v2.1.229 or later

262* Claude Code also blocks marketplace [`headersHelper` commands](https://code.claude.com/docs/en/plugins/host-marketplace#authenticate-archive-downloads) unless [`disableCommandPluginSources`](https://code.claude.com/docs/en/settings-reference#disablecommandpluginsources) is explicitly set to `false`, except for a marketplace that managed settings themselves declare262* Claude Code also blocks marketplace [`headersHelper` commands](https://code.claude.com/docs/en/plugins/host-marketplace#authenticate-archive-downloads) unless [`disableCommandPluginSources`](https://code.claude.com/docs/en/settings-reference#disablecommandpluginsources) is explicitly set to `false`, except for a marketplace that managed settings themselves declare

263 263 


505| `url` | yes | URL to send the POST request to |505| `url` | yes | URL to send the POST request to |

506| `headers` | no | Additional HTTP headers as key-value pairs. Values support environment variable interpolation using `$VAR_NAME` or `${VAR_NAME}` syntax. Only variables listed in `allowedEnvVars` are resolved |506| `headers` | no | Additional HTTP headers as key-value pairs. Values support environment variable interpolation using `$VAR_NAME` or `${VAR_NAME}` syntax. Only variables listed in `allowedEnvVars` are resolved |

507| `allowedEnvVars` | no | List of environment variable names that may be interpolated into header values. References to unlisted variables are replaced with empty strings. Required for any env var interpolation to work |507| `allowedEnvVars` | no | List of environment variable names that may be interpolated into header values. References to unlisted variables are replaced with empty strings. Required for any env var interpolation to work |

508| `onFailure` | no | What happens to the action when the hook fails: `"continue"`, the default, or `"block"`. See [Block the action when a hook fails](#block-the-action-when-a-hook-fails). Requires Claude Code v2.1.295 or later |508| `onFailure` | no | Whether the action that triggered the hook goes ahead when the hook fails: `"continue"` or `"block"`. See [Block the action when a hook fails](#block-the-action-when-a-hook-fails) for `"block"` and for leaving the field unset. Requires Claude Code v2.1.295 or later |

509 509 

510Claude Code sends the hook's [JSON input](#hook-input-and-output) as the POST request body with `Content-Type: application/json`. The response body uses the same [JSON output format](#json-output) as command hooks.510Claude Code sends the hook's [JSON input](#hook-input-and-output) as the POST request body with `Content-Type: application/json`. The response body uses the same [JSON output format](#json-output) as command hooks.

511 511 


901 901 

902On `PreToolUse`, a timed-out `command`, `http`, or `mcp_tool` hook doesn't block the tool call, except for hooks [whose failure blocks the action](#block-the-action-when-a-hook-fails). The call continues through the normal [permission flow](https://code.claude.com/docs/en/permissions.md), so don't count on a stalled hook to act as a gate. To block the call when a `command` or `http` hook times out, set [`onFailure: "block"`](#block-the-action-when-a-hook-fails). An [Agent SDK callback hook](https://code.claude.com/docs/en/agent-sdk/hooks.md) that exceeds its timeout [blocks the tool call](#pretooluse).902On `PreToolUse`, a timed-out `command`, `http`, or `mcp_tool` hook doesn't block the tool call, except for hooks [whose failure blocks the action](#block-the-action-when-a-hook-fails). The call continues through the normal [permission flow](https://code.claude.com/docs/en/permissions.md), so don't count on a stalled hook to act as a gate. To block the call when a `command` or `http` hook times out, set [`onFailure: "block"`](#block-the-action-when-a-hook-fails). An [Agent SDK callback hook](https://code.claude.com/docs/en/agent-sdk/hooks.md) that exceeds its timeout [blocks the tool call](#pretooluse).

903 903 

904> [!NOTE]

905>

906> If you use Code Mode, timeouts on `PreToolUse` work differently. See [Tool call refused by a hook](https://code.claude.com/docs/en/code-mode.md#tool-call-refused-by-a-hook).

907 

904#### Hooks that start a background process908#### Hooks that start a background process

905 909 

906A hook can start a long-running program, such as a dev server, and leave it running while the session continues. In the hook's script or [shell form](#exec-form-and-shell-form) command:910A hook can start a long-running program, such as a dev server, and leave it running while the session continues. In the hook's script or [shell form](#exec-form-and-shell-form) command:


981* **`Stop`, `SubagentStop`, `TaskCompleted`, and `TeammateIdle` hooks**: exit code 2 on these events sends Claude back to keep working, and Claude can't repair a hook that won't run985* **`Stop`, `SubagentStop`, `TaskCompleted`, and `TeammateIdle` hooks**: exit code 2 on these events sends Claude back to keep working, and Claude can't repair a hook that won't run

982* **Background command hooks**: command hooks that set [`async` or `asyncRewake`](#run-hooks-in-the-background)986* **Background command hooks**: command hooks that set [`async` or `asyncRewake`](#run-hooks-in-the-background)

983 987 

988> [!NOTE]

989>

990> If you use Code Mode, failures on `PreToolUse` work differently. See [Tool call refused by a hook](https://code.claude.com/docs/en/code-mode.md#tool-call-refused-by-a-hook).

991 

984#### Failed hooks on Windows without Git Bash992#### Failed hooks on Windows without Git Bash

985 993 

986If the error for a blocked tool call includes this text, a `PreToolUse` or `PermissionRequest` command hook failed or timed out and blocked the call:994If the error for a blocked tool call includes this text, a `PreToolUse` or `PermissionRequest` command hook failed or timed out and blocked the call:


1512* A [session-scoped scheduled task](https://code.claude.com/docs/en/scheduled-tasks.md) firing, including a `/loop` iteration1520* A [session-scoped scheduled task](https://code.claude.com/docs/en/scheduled-tasks.md) firing, including a `/loop` iteration

1513* A [background subagent](https://code.claude.com/docs/en/sub-agents.md#run-subagents-in-foreground-or-background) reporting back to the session that started it1521* A [background subagent](https://code.claude.com/docs/en/sub-agents.md#run-subagents-in-foreground-or-background) reporting back to the session that started it

1514* A [message another session sends](https://code.claude.com/docs/en/cross-session-messaging.md) to your main conversation1522* A [message another session sends](https://code.claude.com/docs/en/cross-session-messaging.md) to your main conversation

1523* The output of Claude's code in a [Code Mode](https://code.claude.com/docs/en/code-mode.md#code-output-withheld-by-a-hook) session, for `command`, `http`, and `mcp_tool` hooks, when code can run in the background

1515 1524 

1516`UserPromptSubmit` hooks have a default timeout of 30 seconds for `command`, `http`, and `mcp_tool` types, shorter than the 600-second default for those types on most other events. Because this hook runs before every prompt and blocks model processing until it completes, a stuck hook stalls the session. If your hook needs more time, set the `timeout` field in the hook entry.1525`UserPromptSubmit` hooks have a default timeout of 30 seconds for `command`, `http`, and `mcp_tool` types, shorter than the 600-second default for those types on most other events. Because this hook runs before every prompt and blocks model processing until it completes, a stuck hook stalls the session. If your hook needs more time, set the `timeout` field in the hook entry.

1517 1526 


1560| Field | Description |1569| Field | Description |

1561| :- | :- |1570| :- | :- |

1562| `decision` | `"block"` stops the prompt before it reaches Claude. Omit to allow the prompt to proceed |1571| `decision` | `"block"` stops the prompt before it reaches Claude. Omit to allow the prompt to proceed |

1563| `reason` | Shown to the user when `decision` is `"block"`. Not added to context |1572| `reason` | Shown to the user when `decision` is `"block"`. Not added to context, except when the hook blocks [Code Mode output](https://code.claude.com/docs/en/code-mode.md#code-output-withheld-by-a-hook) |

1564| `additionalContext` | String added to Claude's context alongside the submitted prompt. See [Add context for Claude](#add-context-for-claude) |1573| `additionalContext` | String added to Claude's context alongside the submitted prompt. See [Add context for Claude](#add-context-for-claude) |

1565| `sessionTitle` | Sets the session title. Use to name sessions automatically based on the prompt content |1574| `sessionTitle` | Sets the session title. Use to name sessions automatically based on the prompt content |

1566| `suppressOriginalPrompt` | If `true` when the hook blocks the prompt, leaves the prompt text out of the block message. See [What a blocked prompt leaves behind](#what-a-blocked-prompt-leaves-behind) |1575| `suppressOriginalPrompt` | If `true` when the hook blocks the prompt, leaves the prompt text out of the block message. See [What a blocked prompt leaves behind](#what-a-blocked-prompt-leaves-behind) |

1567 1576 

1568A hook that blocks by exiting 2 routes the same way as `reason`: the block message shows the stderr text to the user, and it isn't added to context.1577If your hook blocks by exiting 2, its stderr text is treated the same way as `reason`.

1569 1578 

1570```json theme={null}1579```json theme={null}

1571{1580{


3000 3009 

3001Runs when a configuration file changes during a session. Use this to audit settings changes, enforce security policies, or block unauthorized modifications to configuration files.3010Runs when a configuration file changes during a session. Use this to audit settings changes, enforce security policies, or block unauthorized modifications to configuration files.

3002 3011 

3003Claude Code runs ConfigChange hooks when a settings file, a managed policy file, or a skill file changes. For managed policy, it runs them only when `managed-settings.json` or a file in `managed-settings.d/` changes. It applies [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md) and changes to macOS managed preferences or Windows registry policy without running them. On WSL with [`wslInheritsWindowsSettings`](https://code.claude.com/docs/en/settings-reference#wslinheritswindowssettings), it also applies a changed Windows-side managed settings file on its policy poll without running them.3012Claude Code runs ConfigChange hooks when a settings file, a managed policy file, or a skill file changes. For managed policy, it runs them only when `managed-settings.json` or a file in `managed-settings.d/` changes.

3004 3013 

3005The matcher filters on the configuration source:3014The matcher filters on the configuration source:

3006 3015 


3012| `policy_settings` | `managed-settings.json` or a file in `managed-settings.d/` changes |3021| `policy_settings` | `managed-settings.json` or a file in `managed-settings.d/` changes |

3013| `skills` | A skill file in `.claude/skills/` changes |3022| `skills` | A skill file in `.claude/skills/` changes |

3014 3023 

3015This example logs all configuration changes for security auditing:3024Changes such as these take effect without running the hooks:

3025 

3026* Rules and settings you save with **Yes, and don't ask again**, `/permissions`, or `/model`, in the session you saved them from. If another open session loads the same file, the hooks run there.

3027* Updates to [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md), macOS managed preferences, or Windows registry policy

3028* On WSL with [`wslInheritsWindowsSettings`](https://code.claude.com/docs/en/settings-reference#wslinheritswindowssettings), a changed Windows-side managed settings file, which Claude Code picks up on its policy poll

3029 

3030This example logs configuration changes for security auditing:

3016 3031 

3017```json theme={null}3032```json theme={null}

3018{3033{

hooks-guide.md +2 −2

Details

336 336 

337Track when settings or skills files change during a session. The `ConfigChange` event fires when an external process or editor modifies a configuration file, so you can log changes for compliance or block unauthorized modifications.337Track when settings or skills files change during a session. The `ConfigChange` event fires when an external process or editor modifies a configuration file, so you can log changes for compliance or block unauthorized modifications.

338 338 

339This example appends each change to an audit log. Add this to `~/.claude/settings.json`:339This example appends each event to an audit log. Add this to `~/.claude/settings.json`:

340 340 

341```json theme={null}341```json theme={null}

342{342{


925Your endpoint responds with a JSON body in the same [output format](https://code.claude.com/docs/en/hooks.md#json-output) as command hooks, and Claude Code also checks the response status:925Your endpoint responds with a JSON body in the same [output format](https://code.claude.com/docs/en/hooks.md#json-output) as command hooks, and Claude Code also checks the response status:

926 926 

927* **2xx status**: to block a tool call, return the appropriate `hookSpecificOutput` fields in the body.927* **2xx status**: to block a tool call, return the appropriate `hookSpecificOutput` fields in the body.

928* **Any other status, or the request fails**: Claude Code reports a [non-blocking error](https://code.claude.com/docs/en/hooks.md#exit-code-output) and lets the action continue. To make a failed endpoint block the action, set [`onFailure: "block"`](https://code.claude.com/docs/en/hooks#block-the-action-when-a-hook-fails) on the hook.928* **Any other status, or the request fails**: Claude Code reports a [non-blocking error](https://code.claude.com/docs/en/hooks.md#exit-code-output) and lets the action continue, unless the hook is one [whose failure blocks the action](https://code.claude.com/docs/en/hooks.md#block-the-action-when-a-hook-fails). To make a failed endpoint block the action, set [`onFailure: "block"`](https://code.claude.com/docs/en/hooks#block-the-action-when-a-hook-fails) on the hook.

929 929 

930Header values support environment variable interpolation using `$VAR_NAME` or `${VAR_NAME}` syntax. Only variables listed in the `allowedEnvVars` array are resolved; all other `$VAR` references remain empty.930Header values support environment variable interpolation using `$VAR_NAME` or `${VAR_NAME}` syntax. Only variables listed in the `allowedEnvVars` array are resolved; all other `$VAR` references remain empty.

931 931 

Details

81| :- | :- | :- |81| :- | :- | :- |

82| Quick escape | `\` + `Enter` | Works in all terminals |82| Quick escape | `\` + `Enter` | Works in all terminals |

83| Option key | `Option+Enter` | After enabling [Option as Meta](https://code.claude.com/docs/en/terminal-config.md#enable-option-key-shortcuts-on-macos) on macOS |83| Option key | `Option+Enter` | After enabling [Option as Meta](https://code.claude.com/docs/en/terminal-config.md#enable-option-key-shortcuts-on-macos) on macOS |

84| Shift+Enter | `Shift+Enter` | Native in iTerm2, WezTerm, Ghostty, Kitty, Warp, Apple Terminal, Windows Terminal. For other terminals, see [Enter multiline prompts](https://code.claude.com/docs/en/terminal-config.md#enter-multiline-prompts) |84| Shift+Enter | `Shift+Enter` | Native in iTerm2, WezTerm, Ghostty, Kitty, Warp, Windows Terminal. For other terminals, see [Enter multiline prompts](https://code.claude.com/docs/en/terminal-config.md#enter-multiline-prompts) |

85| Control sequence | `Ctrl+J` | Works in any terminal without configuration |85| Control sequence | `Ctrl+J` | Works in any terminal without configuration |

86| Paste mode | Paste directly | For code blocks, logs |86| Paste mode | Paste directly | For code blocks, logs |

87 87 


137 137 

138Enable vim-style editing via `/config` → Editor mode.138Enable vim-style editing via `/config` → Editor mode.

139 139 

140Claude Code keeps your vim mode and cursor position when you toggle the [transcript viewer](#transcript-viewer) with `Ctrl+O` or open and close a panel such as `/config`. If you leave the prompt in NORMAL mode, it's still in NORMAL mode when you return, with the cursor where you left it.

141 

142### Mode switching140### Mode switching

143 141 

144| Command | Action | From mode |142| Command | Action | From mode |


302 * Press `Ctrl+C` to cancel and restore your original input300 * Press `Ctrl+C` to cancel and restore your original input

303 * Press `Backspace` on empty search to cancel301 * Press `Backspace` on empty search to cancel

304 302 

305Accepting a match or canceling the search takes effect immediately, even while Claude Code is still loading the history.

306 

307To find an earlier prompt when all you remember is something long you pasted into it, such as an error log, press `Ctrl+R` and type a word from the paste. Requires Claude Code v2.1.314 or later.303To find an earlier prompt when all you remember is something long you pasted into it, such as an error log, press `Ctrl+R` and type a word from the paste. Requires Claude Code v2.1.314 or later.

308 304 

309## Background Bash commands305## Background Bash commands


600 596 

601### What Claude Code underlines597### What Claude Code underlines

602 598 

603Shortly after you pause typing, Claude Code underlines the words the dictionary doesn't know. It leaves the word you're still typing alone until you move past it, and it never changes your text. It also skips text that looks like code:599Shortly after you pause typing, Claude Code underlines the words the dictionary doesn't know. It leaves the word you're still typing alone until you move past it. It also skips text that looks like code:

604 600 

605* Commands such as `/help`, `@` mentions, URLs, file paths, and flags such as `--verbose`601* Commands such as `/help`, `@` mentions, URLs, file paths, and flags such as `--verbose`

606* Words with digits, underscores, or a capital letter after the first, and text in backticks602* Words with digits, underscores, or a capital letter after the first, and text in backticks

keybindings.md +7 −2

Details

581 581 

582Claude Code binds these default chords on the `ctrl+x` prefix, by context:582Claude Code binds these default chords on the `ctrl+x` prefix, by context:

583 583 

584* `Chat`: `ctrl+x ctrl+k`, `ctrl+x ctrl+e`, `ctrl+x enter`, `ctrl+x ctrl+a`, `ctrl+x ctrl+s`, and `ctrl+x tab`584* `Chat`: `ctrl+x ctrl+k`, `ctrl+x ctrl+e`, `ctrl+x enter`, `ctrl+x ctrl+a`, `ctrl+x ctrl+s`, `ctrl+x tab`, `ctrl+x ctrl+=`, `ctrl+x ctrl+-`, `ctrl+x ctrl+_`, `ctrl+x =`, and `ctrl+x -`

585* `Task`: `ctrl+x ctrl+b`585* `Task`: `ctrl+x ctrl+b`

586* `DiffPanel`: `ctrl+x b`586* `DiffPanel`: `ctrl+x b`

587* `Pane`: `ctrl+x left`, `ctrl+x right`, `ctrl+x up`, `ctrl+x down`, and `ctrl+x x`587* `Pane`: `ctrl+x left`, `ctrl+x right`, `ctrl+x up`, `ctrl+x down`, and `ctrl+x x`


631 "ctrl+x ctrl+a": null,631 "ctrl+x ctrl+a": null,

632 "ctrl+x ctrl+s": null,632 "ctrl+x ctrl+s": null,

633 "ctrl+x tab": null,633 "ctrl+x tab": null,

634 "ctrl+x ctrl+=": null,

635 "ctrl+x ctrl+-": null,

636 "ctrl+x ctrl+_": null,

637 "ctrl+x =": null,

638 "ctrl+x -": null,

634 "ctrl+x": "chat:newline"639 "ctrl+x": "chat:newline"

635 }640 }

636 }641 }


716Claude Code validates your keybindings and writes a warning to the debug log for:721Claude Code validates your keybindings and writes a warning to the debug log for:

717 722 

718* Parse errors (invalid JSON or structure)723* Parse errors (invalid JSON or structure)

719* Misspelled modifiers, such as `ctl+k`. Claude Code drops the part it doesn't recognize and applies the binding to the keystroke that remains, `k` in this example.724* Misspelled modifiers, such as `ctl+k`. Claude Code ignores the whole binding. Correct the modifier, to `ctrl+k` in this example.

720* A space next to `+` in a key string, such as `ctrl+ k`. Claude Code reads the string as a [chord](#chords) of `ctrl+` followed by `k`. No keypress matches `ctrl+` on its own, so the binding never fires. Remove the space.725* A space next to `+` in a key string, such as `ctrl+ k`. Claude Code reads the string as a [chord](#chords) of `ctrl+` followed by `k`. No keypress matches `ctrl+` on its own, so the binding never fires. Remove the space.

721* Invalid context names726* Invalid context names

722* Invalid action values, such as an action that isn't a string or `null`727* Invalid action values, such as an action that isn't a string or `null`

llm-gateway.md +4 −0

Details

43 43 

44To make a gateway reached through `ANTHROPIC_BASE_URL` the only destination a managed machine may use, set [`allowedProviders`](https://code.claude.com/docs/en/settings-reference#allowedproviders) to `["customEndpoint"]` in the same managed settings file and put the gateway's `ANTHROPIC_BASE_URL` in that file's `env` block. Claude Code then refuses a session pointed anywhere else, including at Anthropic directly or at a developer's own proxy, and accepts `ANTHROPIC_BASE_URL` only with the value you set there. For a gateway reached through a provider-specific endpoint variable such as `ANTHROPIC_BEDROCK_BASE_URL`, the `allowedProviders` entry says which variable to pin. Requires Claude Code v2.1.285 or later.44To make a gateway reached through `ANTHROPIC_BASE_URL` the only destination a managed machine may use, set [`allowedProviders`](https://code.claude.com/docs/en/settings-reference#allowedproviders) to `["customEndpoint"]` in the same managed settings file and put the gateway's `ANTHROPIC_BASE_URL` in that file's `env` block. Claude Code then refuses a session pointed anywhere else, including at Anthropic directly or at a developer's own proxy, and accepts `ANTHROPIC_BASE_URL` only with the value you set there. For a gateway reached through a provider-specific endpoint variable such as `ANTHROPIC_BEDROCK_BASE_URL`, the `allowedProviders` entry says which variable to pin. Requires Claude Code v2.1.285 or later.

45 45 

46> [!NOTE]

47>

48> With Desktop signed in to claude.ai, a Cowork session on the user's machine counts as [`"anthropic"`](https://code.claude.com/docs/en/settings-reference#allowedproviders). If you leave it out of this list in an MDM policy or managed settings file, that session is refused. With it in, sessions sent to Anthropic directly also pass this list.

49 

46## Subscriptions and gateways50## Subscriptions and gateways

47 51 

48While a [gateway credential variable](https://code.claude.com/docs/en/llm-gateway-connect.md#set-the-credential-variable) or `apiKeyHelper` is active, requests carry that credential in place of a developer's claude.ai subscription login, and the subscription's usage limits don't apply to them. Claude Code keeps a saved claude.ai login on the machine but doesn't send it with those requests. That traffic is billed per token to whoever owns the credential the gateway forwards, such as your organization's Anthropic Console account, or your Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry account when the gateway routes there.52While a [gateway credential variable](https://code.claude.com/docs/en/llm-gateway-connect.md#set-the-credential-variable) or `apiKeyHelper` is active, requests carry that credential in place of a developer's claude.ai subscription login, and the subscription's usage limits don't apply to them. Claude Code keeps a saved claude.ai login on the machine but doesn't send it with those requests. That traffic is billed per token to whoever owns the credential the gateway forwards, such as your organization's Anthropic Console account, or your Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry account when the gateway routes there.

Details

156 156 

157### Conflicts with an existing login157### Conflicts with an existing login

158 158 

159A gateway credential variable takes precedence over a saved claude.ai login or Console key. With `ANTHROPIC_AUTH_TOKEN`, the variable takes precedence immediately. With `ANTHROPIC_API_KEY`, you are prompted once in interactive mode to approve the key before it takes over.159Your requests use a gateway credential variable rather than a saved claude.ai login. With `ANTHROPIC_AUTH_TOKEN`, the variable takes precedence immediately. With `ANTHROPIC_API_KEY`, you are prompted once in interactive mode to approve the key before it takes over.

160 160 

161Run `/status` to confirm which credential source is active. If startup shows an auth-conflict warning naming two sources, see the first row of the [troubleshooting table](#troubleshoot-gateway-errors) for which one to drop. To clear a saved login so only the gateway credential remains, run `/logout`.161Run `/status` to confirm which credential source is active. If startup shows an auth-conflict warning naming two sources, see the first row of the [troubleshooting table](#troubleshoot-gateway-errors) for which one to drop. To clear a saved login so only the gateway credential remains, run `/logout`.

162 162 


506 506 

507| Error | Cause | Fix |507| Error | Cause | Fix |

508| :- | :- | :- |508| :- | :- | :- |

509| A startup warning naming two credential sources and ending in `auth may not work as expected`. Older versions show `Auth conflict: Both a token (SOURCE) and an API key (SOURCE) are set` instead. | A gateway credential and a saved login are both active; the variable is used for requests, but the stale login can cause unexpected auth behavior | Unset the variable to use the saved login, or run `/logout` to use the gateway credential |509| A startup warning naming two credential sources and ending in `auth may not work as expected`. Older versions show `Auth conflict: Both a token (SOURCE) and an API key (SOURCE) are set` instead. | A gateway credential and a saved login are both active | Unset the variable to use the saved login, or run `/logout` to use the gateway credential |

510| `401` errors naming an invalid or unrecognized token | The credential isn't one the gateway issued, or it's in a header the gateway doesn't read | Confirm the variable matches your credential kind in the [credential table](#set-the-credential-variable), and regenerate the key at the gateway if it was revoked |510| `401` errors naming an invalid or unrecognized token | The credential isn't one the gateway issued, or it's in a header the gateway doesn't read | Confirm the variable matches your credential kind in the [credential table](#set-the-credential-variable), and regenerate the key at the gateway if it was revoked |

511| `Your apiKeyHelper script is failing`, or `apiKeyHelper failed:` on stderr in non-interactive mode | The command in the [`apiKeyHelper`](https://code.claude.com/docs/en/settings-reference#apikeyhelper) setting didn't produce a usable key, so requests carry a placeholder key | Run the command directly to see why it fails, and re-authenticate with your credential provider if it reports an expired session; see [the error reference](https://code.claude.com/docs/en/errors.md#your-apikeyhelper-script-is-failing) |511| `Your apiKeyHelper script is failing`, or `apiKeyHelper failed:` on stderr in non-interactive mode | The command in the [`apiKeyHelper`](https://code.claude.com/docs/en/settings-reference#apikeyhelper) setting didn't produce a usable key, so requests carry a placeholder key | Run the command directly to see why it fails, and re-authenticate with your credential provider if it reports an expired session; see [the error reference](https://code.claude.com/docs/en/errors.md#your-apikeyhelper-script-is-failing) |

512| `Connection refused — a firewall or proxy may be blocking it (ConnectionRefused)` when nothing answers at the address, or `Can't reach the API server — check your internet or DNS (ENOTFOUND)` when the hostname doesn't resolve, often after a silent pause while Claude Code [retries with backoff](https://code.claude.com/docs/en/errors.md#automatic-retries). The code in parentheses varies; [Unable to connect to API](https://code.claude.com/docs/en/errors.md#unable-to-connect-to-api) covers the code spellings and the earlier wording | Nothing answered at the base URL: the address is wrong, or a VPN or firewall blocks the path to the gateway | Run the [curl test above](#verify-the-connection), which fails immediately with the same cause, and confirm the URL and network path with your gateway team |512| `Connection refused — a firewall or proxy may be blocking it (ConnectionRefused)` when nothing answers at the address, or `Can't reach the API server — check your internet or DNS (ENOTFOUND)` when the hostname doesn't resolve, often after a silent pause while Claude Code [retries with backoff](https://code.claude.com/docs/en/errors.md#automatic-retries). The code in parentheses varies; [Unable to connect to API](https://code.claude.com/docs/en/errors.md#unable-to-connect-to-api) covers the code spellings and the earlier wording | Nothing answered at the base URL: the address is wrong, or a VPN or firewall blocks the path to the gateway | Run the [curl test above](#verify-the-connection), which fails immediately with the same cause, and confirm the URL and network path with your gateway team |


520| `/fast` reports `Fast mode unavailable due to network connectivity issues` while inference requests work | The [fast mode](https://code.claude.com/docs/en/fast-mode.md) availability check goes directly to `api.anthropic.com` and doesn't follow `ANTHROPIC_BASE_URL`, so blocked direct egress fails the check | Allowlist `api.anthropic.com` if egress is blocked, or set a skip variable. See [use fast mode behind proxies and LLM gateways](https://code.claude.com/docs/en/fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) |520| `/fast` reports `Fast mode unavailable due to network connectivity issues` while inference requests work | The [fast mode](https://code.claude.com/docs/en/fast-mode.md) availability check goes directly to `api.anthropic.com` and doesn't follow `ANTHROPIC_BASE_URL`, so blocked direct egress fails the check | Allowlist `api.anthropic.com` if egress is blocked, or set a skip variable. See [use fast mode behind proxies and LLM gateways](https://code.claude.com/docs/en/fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) |

521| `/fast` reports `Fast mode is currently unavailable` in a session that authenticates with a gateway-issued key in `ANTHROPIC_API_KEY` | While `ANTHROPIC_BASE_URL` points at your gateway and the key isn't in the format of an Anthropic API key, Claude Code doesn't send the [fast mode](https://code.claude.com/docs/en/fast-mode.md) availability check. Without an earlier successful check cached, it treats fast mode as unavailable | Set `CLAUDE_CODE_SKIP_FAST_MODE_NETWORK_ERRORS=1`; see [use fast mode behind proxies and LLM gateways](https://code.claude.com/docs/en/fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) |521| `/fast` reports `Fast mode is currently unavailable` in a session that authenticates with a gateway-issued key in `ANTHROPIC_API_KEY` | While `ANTHROPIC_BASE_URL` points at your gateway and the key isn't in the format of an Anthropic API key, Claude Code doesn't send the [fast mode](https://code.claude.com/docs/en/fast-mode.md) availability check. Without an earlier successful check cached, it treats fast mode as unavailable | Set `CLAUDE_CODE_SKIP_FAST_MODE_NETWORK_ERRORS=1`; see [use fast mode behind proxies and LLM gateways](https://code.claude.com/docs/en/fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) |

522| `/fast` reports `Fast mode has been disabled by your organization` in a session authenticated with `ANTHROPIC_AUTH_TOKEN`, even though the organization has fast mode enabled | The availability check requires a claude.ai login or an API key; with only a bearer token, Claude Code treats fast mode as disabled without sending the check | Set `CLAUDE_CODE_SKIP_FAST_MODE_ORG_CHECK=1`; see [use fast mode behind proxies and LLM gateways](https://code.claude.com/docs/en/fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) |522| `/fast` reports `Fast mode has been disabled by your organization` in a session authenticated with `ANTHROPIC_AUTH_TOKEN`, even though the organization has fast mode enabled | The availability check requires a claude.ai login or an API key; with only a bearer token, Claude Code treats fast mode as disabled without sending the check | Set `CLAUDE_CODE_SKIP_FAST_MODE_ORG_CHECK=1`; see [use fast mode behind proxies and LLM gateways](https://code.claude.com/docs/en/fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) |

523| `/feedback` saves a local file in a session that uses `ANTHROPIC_BASE_URL` | Behind a gateway, `ANTHROPIC_AUTH_TOKEN` and a key that isn't in the format of an Anthropic API key aren't Anthropic credentials. Without one, Claude Code writes the report to a local archive under `~/.claude/feedback-bundles/` instead of sending it | Send the file to your Anthropic account representative or attach it to a support request. See [telemetry services](https://code.claude.com/docs/en/data-usage.md#telemetry-services) |

523| Claude Code asks you to log in even though the [curl test](#verify-the-connection) succeeds | The CLI has no credential of its own: a reachable base URL isn't one, and in an interactive session an `env` block in a project's `.claude/settings.json` or `.claude/settings.local.json` applies only after the first-run wizard and [trust prompt](https://code.claude.com/docs/en/permissions.md#what-runs-before-you-trust-a-folder) | Set `ANTHROPIC_AUTH_TOKEN` somewhere Claude Code reads before first-run setup: a shell export, the `env` block in `~/.claude/settings.json`, or managed settings |524| Claude Code asks you to log in even though the [curl test](#verify-the-connection) succeeds | The CLI has no credential of its own: a reachable base URL isn't one, and in an interactive session an `env` block in a project's `.claude/settings.json` or `.claude/settings.local.json` applies only after the first-run wizard and [trust prompt](https://code.claude.com/docs/en/permissions.md#what-runs-before-you-trust-a-folder) | Set `ANTHROPIC_AUTH_TOKEN` somewhere Claude Code reads before first-run setup: a shell export, the `env` block in `~/.claude/settings.json`, or managed settings |

524| `ANTHROPIC_API_KEY` is set but ignored, with no prompt | The key needs a one-time approval in interactive sessions, and a previously declined key is ignored without asking again | Enable it under `/config` with the `Use custom API key` option |525| `ANTHROPIC_API_KEY` is set but ignored, with no prompt | The key needs a one-time approval in interactive sessions, and a previously declined key is ignored without asking again | Enable it under `/config` with the `Use custom API key` option |

525| `This machine's managed settings require a first-party login`, or [`Administrator policy requires a Cloud gateway sign-in`](https://code.claude.com/docs/en/errors#administrator-policy-requires-a-cloud-gateway-sign-in) when managed settings set `forceLoginMethod` to `"gateway"` or also set `forceLoginGatewayUrl` | Managed settings include `forceLoginMethod` or `forceLoginOrgUUID`, which cannot coexist with `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` | Your administrator must remove `forceLoginMethod`, `forceLoginOrgUUID`, and `forceLoginGatewayUrl` from managed settings to use gateway credentials, or remove the gateway credential and use the sign-in the managed settings require. The two cannot be combined |526| `This machine's managed settings require a first-party login`, or [`Administrator policy requires a Cloud gateway sign-in`](https://code.claude.com/docs/en/errors#administrator-policy-requires-a-cloud-gateway-sign-in) when managed settings set `forceLoginMethod` to `"gateway"` or also set `forceLoginGatewayUrl` | Managed settings include `forceLoginMethod` or `forceLoginOrgUUID`, which cannot coexist with `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` | Your administrator must remove `forceLoginMethod`, `forceLoginOrgUUID`, and `forceLoginGatewayUrl` from managed settings to use gateway credentials, or remove the gateway credential and use the sign-in the managed settings require. The two cannot be combined |

Details

142claude -p "Reply with one word: connected"142claude -p "Reply with one word: connected"

143```143```

144 144 

145**Checkpoint**: the prompt returns a response, and the request appears in the gateway's log as a `POST` to the `/v1/messages` path with status `200`. Claude Code appends a query string such as `?beta=true`, so match on the path, not the full URL. Two failure messages point in different directions:145**Checkpoint**: the prompt returns a response, and the request appears in the gateway's log as a `POST` to the `/v1/messages` path with status `200`. Claude Code appends a query string such as `?beta=true`, so match on the path, not the full URL. Check the failure message:

146 146 

147* `Not logged in`: check the gateway log to tell the two causes apart. If it's empty, no credential reached the session and no request left the machine; re-run the exports in the shell you're testing from. If it shows a rejected request with `x-api-key` in the `401` body, the gateway expects keys in that header instead; switch to `ANTHROPIC_API_KEY`147* `Not logged in`: check the gateway log. If it's empty, no credential reached the session and no request left the machine; re-run the exports in the shell you're testing from. If it shows a `401` from the gateway naming `x-api-key`, the gateway expects keys in that header instead; switch to `ANTHROPIC_API_KEY`. If it shows a `401` from `api.anthropic.com` or your provider's endpoint, fix the provider credential the gateway holds

148* `Failed to authenticate. API Error: 401` means a credential was sent and rejected, and the gateway log says where: a `401` naming `api.anthropic.com` or your provider's endpoint means the gateway reached the upstream but its provider credential was rejected, so the developer key worked and the provider credential the gateway holds is wrong or a placeholder148* `Failed to authenticate. API Error: 401` means a credential was sent and rejected, and the gateway log says where: a `401` naming `api.anthropic.com` or your provider's endpoint means the gateway reached the upstream but its provider credential was rejected, so the developer key worked and the provider credential the gateway holds is wrong or a placeholder

149 149 

150A wrong or unreachable base URL produces a different symptom: Claude Code [retries the connection with backoff](https://code.claude.com/docs/en/errors.md#automatic-retries) and can sit with no output for several minutes before reporting an error. If the command appears to hang, check the gateway log instead of waiting; no arriving request means `ANTHROPIC_BASE_URL` doesn't point at the gateway.150A wrong or unreachable base URL produces a different symptom: Claude Code [retries the connection with backoff](https://code.claude.com/docs/en/errors.md#automatic-retries) and can sit with no output for several minutes before reporting an error. If the command appears to hang, check the gateway log instead of waiting; no arriving request means `ANTHROPIC_BASE_URL` doesn't point at the gateway.


247 247 

248You should see `data:` lines arrive incrementally. The whole response arriving at once after a pause means the gateway is buffering, which stalls Claude Code; a `404` means the model name isn't routed. Repeat per model name.248You should see `data:` lines arrive incrementally. The whole response arriving at once after a pause means the gateway is buffering, which stalls Claude Code; a `404` means the model name isn't routed. Repeat per model name.

249 249 

250Then start `claude` and send a message. Each symptom at this step has one cause:250Then start `claude`, send a message, and match what you see:

251 251 

252* A login prompt means a credential gap. Run `/status` and open the **Status** tab: when the `Setting sources` line doesn't include managed settings, the distribution didn't reach the machine; when it does, the developer credential wasn't delivered, so set `ANTHROPIC_AUTH_TOKEN` or the `apiKeyHelper`252* A login screen, or `Not logged in` with nothing new in the gateway log, means a credential gap. Run `/status` and open the **Status** tab: when the `Setting sources` line doesn't include managed settings, the distribution didn't reach the machine; when it does, the developer credential wasn't delivered, so set `ANTHROPIC_AUTH_TOKEN` or the `apiKeyHelper`

253* `Failed to authenticate` errors mean the gateway is rejecting requests; its log says which credential failed. A rejection the gateway logs itself names the developer key, while a `401` from `api.anthropic.com` or your provider's endpoint means the provider credential the gateway holds was rejected253* `Please run /login · API Error: 401`, `Not logged in`, or `Invalid API key` with a `401` in the gateway log: check who wrote the `401`. Fix the developer key or its header if the gateway wrote it, or the provider credential it holds if it came from `api.anthropic.com` or your provider's endpoint

254* A one-time approval prompt for the key is expected on first use when the gateway expects keys in the `x-api-key` header, set as `ANTHROPIC_API_KEY`254* A one-time approval prompt for the key is expected on first use when the gateway expects keys in the `x-api-key` header, set as `ANTHROPIC_API_KEY`

255 255 

256If your organization uses [fast mode](https://code.claude.com/docs/en/fast-mode.md), run `/fast` here too: the availability check calls `api.anthropic.com` directly rather than following the gateway base URL, so a gateway-routed session can report fast mode as unavailable or disabled even though inference works. [Use fast mode behind proxies and LLM gateways](https://code.claude.com/docs/en/fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) maps each message to the variable that restores it, distributed with [the rest of the configuration](#distribute-the-configuration).256If your organization uses [fast mode](https://code.claude.com/docs/en/fast-mode.md), run `/fast` here too: the availability check calls `api.anthropic.com` directly rather than following the gateway base URL, so a gateway-routed session can report fast mode as unavailable or disabled even though inference works. [Use fast mode behind proxies and LLM gateways](https://code.claude.com/docs/en/fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) maps each message to the variable that restores it, distributed with [the rest of the configuration](#distribute-the-configuration).

mcp.md +0 −2

Details

835 835 

836A server your organization provides through the [`managedMcpServers`](https://code.claude.com/docs/en/managed-mcp#provide-servers-through-managed-settings) managed setting ranks above all of these, so when one of them duplicates it, Claude Code connects the organization's definition. Requires Claude Code v2.1.259 or later.836A server your organization provides through the [`managedMcpServers`](https://code.claude.com/docs/en/managed-mcp#provide-servers-through-managed-settings) managed setting ranks above all of these, so when one of them duplicates it, Claude Code connects the organization's definition. Requires Claude Code v2.1.259 or later.

837 837 

838If you open a local session in the [Desktop app's Code tab](https://code.claude.com/docs/en/desktop.md#mcp-servers-from-the-claude-desktop-chat-app) with the same stdio server name at the top level of `~/.claude.json` (user scope) and in `.mcp.json`, the Code tab uses the `~/.claude.json` definition.

839 

840### Environment variable expansion in `.mcp.json`838### Environment variable expansion in `.mcp.json`

841 839 

842Claude Code supports environment variable expansion in `.mcp.json` files, allowing teams to share configurations while maintaining flexibility for machine-specific paths and sensitive values like API keys.840Claude Code supports environment variable expansion in `.mcp.json` files, allowing teams to share configurations while maintaining flexibility for machine-specific paths and sensitive values like API keys.

Details

147 147 

148## Azure RBAC configuration148## Azure RBAC configuration

149 149 

150The `Azure AI User` and `Cognitive Services User` default roles include all required permissions for invoking Claude models.150If you authenticate with Microsoft Entra ID or a bearer token it issued, assign your identity the `Foundry User` or `Cognitive Services User` role on your Foundry resource. You might still see `Foundry User` under its previous name, `Azure AI User`.

151 151 

152For more restrictive permissions, create a custom role with the following:152If these roles don't meet your needs, see [Microsoft Foundry RBAC documentation](https://learn.microsoft.com/en-us/azure/foundry/concepts/rbac-foundry) for custom roles.

153 

154```json theme={null}

155{

156 "permissions": [

157 {

158 "dataActions": [

159 "Microsoft.CognitiveServices/accounts/providers/*"

160 ]

161 }

162 ]

163}

164```

165 

166For details, see [Microsoft Foundry RBAC documentation](https://learn.microsoft.com/en-us/azure/ai-foundry/concepts/rbac-azure-ai-foundry).

167 153 

168## 1M token context window154## 1M token context window

169 155 

model-config.md +5 −3

Details

157 157 

158When the active model at startup comes from project or managed settings rather than your own selection, the startup header shows which settings file set it. Run `/model` to override; the project or managed setting reapplies on the next launch. On platforms that embed Claude Code and set [`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`](https://code.claude.com/docs/en/env-vars), the host's model configuration takes precedence over managed model settings, while a managed `availableModels` allowlist stays in force unless the host supplies its own; [Exceptions to managed settings precedence](https://code.claude.com/docs/en/settings.md#exceptions-to-managed-settings-precedence) says which keys and variables the host overrides.158When the active model at startup comes from project or managed settings rather than your own selection, the startup header shows which settings file set it. Run `/model` to override; the project or managed setting reapplies on the next launch. On platforms that embed Claude Code and set [`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`](https://code.claude.com/docs/en/env-vars), the host's model configuration takes precedence over managed model settings, while a managed `availableModels` allowlist stays in force unless the host supplies its own; [Exceptions to managed settings precedence](https://code.claude.com/docs/en/settings.md#exceptions-to-managed-settings-precedence) says which keys and variables the host overrides.

159 159 

160If you or your organization configure [PreModelSwitch hooks](https://code.claude.com/docs/en/hooks.md#premodelswitch), they run before a requested switch applies and can block it or ask you to confirm.160If you or your organization configure [PreModelSwitch hooks](https://code.claude.com/docs/en/hooks.md#premodelswitch), they run before a requested switch applies and can block it or ask you to confirm. To find out why a hook blocked a switch and what to do, see [Model switch was blocked by a PreModelSwitch hook](https://code.claude.com/docs/en/errors.md#model-switch-was-blocked-by-a-premodelswitch-hook).

161 161 

162When Claude Code can't tell which PreModelSwitch hooks your organization's [managed plugins](https://code.claude.com/docs/en/settings-reference.md#enabledplugins) deliver, for example because a managed plugin failed to load, it refuses the switch rather than apply it unchecked, and it checks again on each new attempt. See [Model switch was blocked by a PreModelSwitch hook](https://code.claude.com/docs/en/errors.md#model-switch-was-blocked-by-a-premodelswitch-hook) for the message and recovery.162If a [managed plugin](https://code.claude.com/docs/en/settings-reference.md#enabledplugins) or its hooks fail to load, you can still switch models. The plugin's PreModelSwitch hooks don't run, so a switch that one of them would have blocked can go ahead. Other PreModelSwitch hooks that loaded still run and can block it. If Claude Code before v2.1.323 refuses the switch with `so organization-managed PreModelSwitch hooks could not be checked`, update Claude Code.

163 

164To see what failed, run `/plugin` in your session and open the [**Errors** tab](https://code.claude.com/docs/en/plugins/troubleshooting.md#failed-to-load-hooks-from-and-hooks-that-dont-fire). If nothing is listed there, start a new session with `claude --debug` from your shell and switch to a different model, then read the [debug log](https://code.claude.com/docs/en/hooks.md#debug-hooks). After you fix the plugin, or a [plugin update](https://code.claude.com/docs/en/plugins/install.md#keep-plugins-updated) brings your admin's fix to your machine, run `/reload-plugins` in your session to get its hooks running.

163 165 

164When you switch models through the [Agent SDK](https://code.claude.com/docs/en/agent-sdk/overview.md) `setModel()` method, through an app such as the [Desktop app](https://code.claude.com/docs/en/desktop.md), or from a device connected through [Remote Control](https://code.claude.com/docs/en/remote-control.md), Claude Code checks the value at the switch:166When you switch models through the [Agent SDK](https://code.claude.com/docs/en/agent-sdk/overview.md) `setModel()` method, through an app such as the [Desktop app](https://code.claude.com/docs/en/desktop.md), or from a device connected through [Remote Control](https://code.claude.com/docs/en/remote-control.md), Claude Code checks the value at the switch:

165 167 


903 905 

904### Correct the window for a gateway or custom model ID906### Correct the window for a gateway or custom model ID

905 907 

906Either of these startup warnings means Claude Code doesn't recognize your session's model ID, so it can't tell the model's context window and assumes 200K tokens:908Either of these warnings means Claude Code doesn't recognize your session's model ID, so it can't tell the model's context window and assumes 200K tokens:

907 909 

908```text theme={null}910```text theme={null}

909⚠ Model "my-gateway-opus" isn't recognized · context assumed to be 200k tokens · ...911⚠ Model "my-gateway-opus" isn't recognized · context assumed to be 200k tokens · ...

Details

110| `CLAUDE_CODE_ENABLE_TELEMETRY` | Enables telemetry collection (required) | `1` |110| `CLAUDE_CODE_ENABLE_TELEMETRY` | Enables telemetry collection (required) | `1` |

111| `OTEL_METRICS_EXPORTER` | Metrics exporter types, comma-separated. Use `none` to disable | `console`, `otlp`, `prometheus`, `none` |111| `OTEL_METRICS_EXPORTER` | Metrics exporter types, comma-separated. Use `none` to disable | `console`, `otlp`, `prometheus`, `none` |

112| `OTEL_LOGS_EXPORTER` | Logs/events exporter types, comma-separated. Use `none` to disable | `console`, `otlp`, `none` |112| `OTEL_LOGS_EXPORTER` | Logs/events exporter types, comma-separated. Use `none` to disable | `console`, `otlp`, `none` |

113| `OTEL_EXPORTER_OTLP_PROTOCOL` | Protocol for OTLP exporter, applies to all signals. Claude Code has no default protocol, so set this or the signal-specific protocol variable for each `otlp` exporter you enable | `grpc`, `http/json`, `http/protobuf` |113| `OTEL_EXPORTER_OTLP_PROTOCOL` | Protocol for OTLP exporter, applies to all signals. Defaults to `http/protobuf` for a valid `http://` or `https://` endpoint. For a gRPC endpoint such as `http://localhost:4317`, set this to `grpc`. The default requires Claude Code v2.1.323 or later | `grpc`, `http/json`, `http/protobuf` |

114| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector endpoint for all signals | `http://localhost:4317` |114| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector endpoint for all signals | `http://localhost:4317` |

115| `OTEL_EXPORTER_OTLP_METRICS_PROTOCOL` | Protocol for metrics, overrides general setting | `grpc`, `http/json`, `http/protobuf` |115| `OTEL_EXPORTER_OTLP_METRICS_PROTOCOL` | Protocol for metrics, overrides general setting | `grpc`, `http/json`, `http/protobuf` |

116| `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` | OTLP metrics endpoint, overrides general setting | `http://localhost:4318/v1/metrics` |116| `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` | OTLP metrics endpoint, overrides general setting | `http://localhost:4318/v1/metrics` |


431> * **No spaces allowed**: values can't contain spaces. For example, `user.organizationName=My Company` is invalid431> * **No spaces allowed**: values can't contain spaces. For example, `user.organizationName=My Company` is invalid

432> * **Format**: must be comma-separated key=value pairs: `key1=value1,key2=value2`432> * **Format**: must be comma-separated key=value pairs: `key1=value1,key2=value2`

433> * **Allowed characters**: only US-ASCII characters excluding control characters, whitespace, double quotes, commas, semicolons, and backslashes433> * **Allowed characters**: only US-ASCII characters excluding control characters, whitespace, double quotes, commas, semicolons, and backslashes

434> * **Special characters**: characters outside the allowed range must be percent-encoded434> * **Special characters**: characters outside the allowed range must be percent-encoded, and an `=` inside a value must be written as `%3D`

435>435>

436> For a value that would need a space, use underscores or camelCase instead. The following examples set `org.name` with each form:436> For a value that would need a space, use underscores or camelCase instead. The following examples set `org.name` with each form:

437>437>


475 475 

476* **You set it on the computer that runs Desktop**: Desktop doesn't pass a value you set there to the SSH session476* **You set it on the computer that runs Desktop**: Desktop doesn't pass a value you set there to the SSH session

477* **You exported it in `/etc/profile` or another file that only login shells read**: the name arrives when you run `claude` from a login shell, but not in a Desktop SSH session. Desktop doesn't start Claude Code through a login shell. Set the variable under `env` in the [managed settings file](https://code.claude.com/docs/en/desktop.md#managed-settings) on the remote machine instead.477* **You exported it in `/etc/profile` or another file that only login shells read**: the name arrives when you run `claude` from a login shell, but not in a Desktop SSH session. Desktop doesn't start Claude Code through a login shell. Set the variable under `env` in the [managed settings file](https://code.claude.com/docs/en/desktop.md#managed-settings) on the remote machine instead.

478* **A value has a space inside it**: Claude Code then copies none of the keys onto events or datapoints and reports no error. [Take the space out of the value](#multi-team-organization-support).478* **A value has a space inside it**: Claude Code then copies none of the keys onto events or datapoints. To see which value has the space, run `/status` in a session on the remote machine. [Take the space out of the value](#multi-team-organization-support).

479* **Something else already sets the variable**: in a session that the desktop app starts, a variable already set in the launch environment [takes precedence over settings files](https://code.claude.com/docs/en/settings-reference.md#how-env-values-interact-with-your-shell). The [debug log](https://code.claude.com/docs/en/debug-your-config.md) names each ignored variable. When a third-party Desktop deployment [names an OTLP endpoint](#how-managed-settings-lock-the-otlp-destination) in the environment it provides, that environment carries Desktop's own `OTEL_RESOURCE_ATTRIBUTES`.479* **Something else already sets the variable**: in a session that the desktop app starts, a variable already set in the launch environment [takes precedence over settings files](https://code.claude.com/docs/en/settings-reference.md#how-env-values-interact-with-your-shell). The [debug log](https://code.claude.com/docs/en/debug-your-config.md) names each ignored variable. When a third-party Desktop deployment [names an OTLP endpoint](#how-managed-settings-lock-the-otlp-destination) in the environment it provides, that environment carries Desktop's own `OTEL_RESOURCE_ATTRIBUTES`.

480 480 

481### Example configurations481### Example configurations

Details

593> * When Claude reads an [artifact someone else made](https://code.claude.com/docs/en/artifacts.md#read-an-artifact-shared-with-you), the approval cases listed in that section apply593> * When Claude reads an [artifact someone else made](https://code.claude.com/docs/en/artifacts.md#read-an-artifact-shared-with-you), the approval cases listed in that section apply

594> * A read from a [network path](https://code.claude.com/docs/en/permissions.md#network-paths) prompts you594> * A read from a [network path](https://code.claude.com/docs/en/permissions.md#network-paths) prompts you

595> 3. Everything else goes to the classifier, apart from [critical-path removals](#critical-paths) under their default handling. The connector tools and `requiresUserInteraction` MCP tools that prompt you directly in step 1 never reach the classifier either, so neither an org-required approval nor a consent step is auto-approved595> 3. Everything else goes to the classifier, apart from [critical-path removals](#critical-paths) under their default handling. The connector tools and `requiresUserInteraction` MCP tools that prompt you directly in step 1 never reach the classifier either, so neither an org-required approval nor a consent step is auto-approved

596> * With [Code Mode](https://code.claude.com/docs/en/code-mode.md#permission-checks) on, Claude's code goes to the classifier once before it runs, and the tool calls inside it don't. You can still block a call with a `deny` rule or require a prompt with an `ask` rule, but Claude can run Bash commands in [forms the rules don't match](https://code.claude.com/docs/en/permissions.md#bash-rule-limits)

596> 4. If the classifier blocks, Claude receives the reason. In most sessions the reason names the rule the classifier matched, such as `[Data Exfiltration]`, rather than giving a written explanation; see [Review denials](https://code.claude.com/docs/en/auto-mode-config.md#review-denials)597> 4. If the classifier blocks, Claude receives the reason. In most sessions the reason names the rule the classifier matched, such as `[Data Exfiltration]`, rather than giving a written explanation; see [Review denials](https://code.claude.com/docs/en/auto-mode-config.md#review-denials)

597>598>

598> A [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you install that handles `tool.check` can also approve an action. For the cases where its approval doesn't get past your rules and hooks, see [Extend permissions with hooks](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods).599> A [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you install that handles `tool.check` can also approve an action. For the cases where its approval doesn't get past your rules and hooks, see [Extend permissions with hooks](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods).

permissions.md +1 −1

Details

784* Outside a repository, Claude Code keys the trust on the directory you started it from, and the trust covers any subdirectory of that directory apart from a git repository nested inside it, such as a clone. Each covered subdirectory then counts as a folder whose parent you trusted.784* Outside a repository, Claude Code keys the trust on the directory you started it from, and the trust covers any subdirectory of that directory apart from a git repository nested inside it, such as a clone. Each covered subdirectory then counts as a folder whose parent you trusted.

785* When you start in your home directory, Claude Code holds the trust for the current session only and doesn't write it to disk; see the [additional safeguards](https://code.claude.com/docs/en/security.md#additional-safeguards) note.785* When you start in your home directory, Claude Code holds the trust for the current session only and doesn't write it to disk; see the [additional safeguards](https://code.claude.com/docs/en/security.md#additional-safeguards) note.

786 786 

787Claude Code shows the trust dialog in interactive sessions only. A `claude -p` run or an SDK session never shows it, and trusting a parent folder doesn't count for these rules, so [What runs before you trust a folder](#what-runs-before-you-trust-a-folder) says which repository content Claude Code still uses in each of those two situations.787The VS Code extension asks for the same trust, in a dialog titled `Trust this folder in Claude Code?`, before it starts a session. Claude Code shows the trust dialog in interactive terminal sessions, but not in `claude -p` or SDK sessions. Trusting a parent folder doesn't count for these rules. [What runs before you trust a folder](#what-runs-before-you-trust-a-folder) says which repository content Claude Code still uses in each case.

788 788 

789Before it starts or restarts a [background session](https://code.claude.com/docs/en/agent-view.md), Claude Code also checks workspace trust for the directory the session runs in. If you run `claude --bg` from a terminal in a directory you haven't trusted, the trust dialog appears first and the session starts once you accept it. Where no dialog can appear, such as in a script, the command exits with a [`Workspace not trusted`](https://code.claude.com/docs/en/errors#workspace-not-trusted-when-dispatching-a-background-session) error instead.789Before it starts or restarts a [background session](https://code.claude.com/docs/en/agent-view.md), Claude Code also checks workspace trust for the directory the session runs in. If you run `claude --bg` from a terminal in a directory you haven't trusted, the trust dialog appears first and the session starts once you accept it. Where no dialog can appear, such as in a script, the command exits with a [`Workspace not trusted`](https://code.claude.com/docs/en/errors#workspace-not-trusted-when-dispatching-a-background-session) error instead.

790 790 

Details

4 4 

5# Add components to a plugin5# Add components to a plugin

6 6 

7> Add skills, hooks, MCP servers, and every other component type to a Claude Code plugin, with an example that validates for each.7> Add skills, hooks, MCP servers, and other component types to a Claude Code plugin, with an example that validates for each.

8 8 

9A Claude Code plugin is built from components, such as skills, agents, hooks, and MCP servers. Each component has a default folder in the plugin, an optional manifest key in `.claude-plugin/plugin.json` that replaces or adds to that folder, and a name the user sees. For each key's full field table, see the [manifest reference](https://code.claude.com/docs/en/plugins/manifest-reference.md#fields).9A Claude Code plugin is built from components, such as skills, agents, hooks, and MCP servers. Each component has a default folder in the plugin, an optional manifest key in `.claude-plugin/plugin.json` that replaces or adds to that folder, and a name the user sees. For each key's full field table, see the [manifest reference](https://code.claude.com/docs/en/plugins/manifest-reference.md#fields).

10 10 


22 22 

23## Explore the plugin directory23## Explore the plugin directory

24 24 

25The explorer shows an example plugin, `my-plugin`, that has one of every kind of component in its default location:25The explorer shows an example plugin, `my-plugin`, that has these components in their default locations:

26 26 

27* A review skill and an `about` command27* A review skill and an `about` command

28* A security-review subagent28* A security-review subagent


31* An output style and a color theme31* An output style and a color theme

32* A route-audit workflow32* A route-audit workflow

33* A `hello-plugin` executable33* A `hello-plugin` executable

34* Default settings

35* A local MCP server and a Go language server34* A local MCP server and a Go language server

36 35 

37Each file is the smallest valid example of its format, there to show the shape rather than to be useful: a real skill or agent carries full instructions and often supporting files, and a real hook or monitor does real work. The sections after the explorer use the same files as their examples and link to fuller ones. Select a file or folder to read what it's for, see what goes in it, and find the section that covers it.36Each file is the smallest valid example of its format, there to show the shape rather than to be useful: a real skill or agent carries full instructions and often supporting files, and a real hook or monitor does real work. The sections after the explorer use the same files as their examples and link to fuller ones. Select a file or folder to read what it's for, see what goes in it, and find the section that covers it.

38 37 

39What goes in a plugin38What goes in a plugin

40 39 

41This example plugin, `my-plugin`, has one of every kind of component, each in its default location. Select a file or folder to read what it’s for and see what goes in it.40This example plugin, `my-plugin`, has the components listed here, each in its default location. Select a file or folder to read what it’s for and see what goes in it.

42 41 

43Plugin directory42Plugin directory

44 43 


178npx prettier --write .177npx prettier --write .

179```178```

180 179 

181A `settings.json` at the plugin root holds [settings](https://code.claude.com/docs/en/settings-reference.md) that apply while the plugin is enabled, so a plugin can change how the session behaves and not only add components. Only two keys take effect from a plugin, [`agent`](https://code.claude.com/docs/en/settings-reference#agent) and [`subagentStatusLine`](https://code.claude.com/docs/en/settings-reference#subagentstatusline); every other key is dropped. See [Default settings](#default-settings).

182 

183This one sets `agent`, which runs the session's main thread as the plugin's own `security-reviewer` agent, so that agent's system prompt, tool restrictions, and model apply to the whole session:

184 

185```json theme={null}

186{

187 "agent": "security-reviewer"

188}

189```

190 

191An [MCP server](https://code.claude.com/docs/en/mcp.md) gives Claude tools from an external system. Declare it in `.mcp.json` at the plugin root. This one starts a local server from a script inside the plugin, and appears in `/mcp` as `plugin:my-plugin:db`:180An [MCP server](https://code.claude.com/docs/en/mcp.md) gives Claude tools from an external system. Declare it in `.mcp.json` at the plugin root. This one starts a local server from a script inside the plugin, and appears in `/mcp` as `plugin:my-plugin:db`:

192 181 

193```json theme={null}182```json theme={null}


484 473 

485claude.ai and Cowork don't install a plugin that has a top-level `bin/` directory, including one you [distribute through claude.ai organization settings](https://claude.com/docs/plugins/org-sync#keep-executables-out-of-the-top-level-bin-directory).474claude.ai and Cowork don't install a plugin that has a top-level `bin/` directory, including one you [distribute through claude.ai organization settings](https://claude.com/docs/plugins/org-sync#keep-executables-out-of-the-top-level-bin-directory).

486 475 

487### Default settings

488 

489To set defaults that apply while the plugin is enabled, add a `settings.json` at the plugin root, or put the same object inline in the `settings` manifest key. Two keys take effect, `agent` and `subagentStatusLine`, and every other key is dropped.

490 

491Set `agent` to run one of the plugin's own agents as the main thread:

492 

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

494{

495 "agent": "security-reviewer"

496}

497```

498 

499Load the plugin and start a session. Claude then answers in the main conversation with the `security-reviewer` agent's system prompt and model.

500 

501For everything the key controls, see the [`agent` setting](https://code.claude.com/docs/en/settings-reference#agent).

502 

503When the same key is set in more than one place, these rules decide which value applies:

504 

505* **File over manifest**: when both exist and `settings.json` sets at least one supported key, `settings.json` applies and the manifest's `settings` is ignored

506* **User settings over plugin defaults**: across settings sources, plugin defaults are the lowest layer, so a user's own `agent` in `~/.claude/settings.json` overrides yours

507* **Two plugins set the same key**: the value from the plugin loaded last applies, and `claude --debug` logs `overrides setting`

508 

509For the `subagentStatusLine` shape, see [subagent status lines](https://code.claude.com/docs/en/statusline.md#subagent-status-lines).

510 

511### Themes and output styles476### Themes and output styles

512 477 

513A plugin can include color themes and output styles. Both appear in the same pickers as the user's own. For either one, setting the manifest key replaces the folder scan.478A plugin can include color themes and output styles. Both appear in the same pickers as the user's own. For either one, setting the manifest key replaces the folder scan.

Details

72* **`version`**: optional. Setting it keeps users on that version until you change it; [Release a new version](https://code.claude.com/docs/en/plugins/host-marketplace.md#release-a-new-version) says when to set or omit it.72* **`version`**: optional. Setting it keeps users on that version until you change it; [Release a new version](https://code.claude.com/docs/en/plugins/host-marketplace.md#release-a-new-version) says when to set or omit it.

73* **`author`**: who to credit. `name` is required inside it; `email` and `url` are optional.73* **`author`**: who to credit. `name` is required inside it; `email` and `url` are optional.

74 74 

75Every other field is on the [manifest reference](https://code.claude.com/docs/en/plugins/manifest-reference.md#fields).75Other fields are on the [manifest reference](https://code.claude.com/docs/en/plugins/manifest-reference.md#fields).

76 76 

77Only `plugin.json` goes inside `.claude-plugin/`. The skill you add next goes directly under `my-first-plugin/`, next to that folder.77Only `plugin.json` goes inside `.claude-plugin/`. The skill you add next goes directly under `my-first-plugin/`, next to that folder.

78 78 

Details

4 4 

5# Plugin manifest reference5# Plugin manifest reference

6 6 

7> Complete reference for plugin.json: every field with its type and default, accepted path forms, and the userConfig and environment variable schemas.7> Complete reference for plugin.json: fields with types and defaults, accepted path forms, and the userConfig and environment variable schemas.

8 8 

9A plugin manifest is the `plugin.json` file in a plugin's `.claude-plugin/` directory. It carries the plugin's metadata and the [`userConfig`](#user-configuration) values that Claude Code prompts the user for. It also declares any component that you define inline or keep outside its [default location](#standard-layout).9A plugin manifest is the `plugin.json` file in a plugin's `.claude-plugin/` directory. It carries the plugin's metadata and the [`userConfig`](#user-configuration) values that Claude Code prompts the user for. It also declares any component that you define inline or keep outside its [default location](#standard-layout).

10 10 


117 117 

118## Fields118## Fields

119 119 

120The table lists the top-level keys in `plugin.json`. `name` is the only required key. Where a field name is a link, the linked section has its full rules.120The table lists top-level keys in `plugin.json`. `name` is the only required key. Where a field name is a link, the linked section has its full rules.

121 121 

122For component keys such as `commands` and `hooks`, [Component path forms](#component-path-forms) shows each accepted shape with an example, and every path follows the [path rules](#path-rules) for the `./` prefix, extensions, and containment.122For component keys such as `commands` and `hooks`, [Component path forms](#component-path-forms) shows each accepted shape with an example, and every path follows the [path rules](#path-rules) for the `./` prefix, extensions, and containment.

123 123 


141| [`termsOfServiceUrl`](#directory-listing-fields) | String | Terms of service link for the plugin's listing in Anthropic's directory. Claude Code doesn't read it |141| [`termsOfServiceUrl`](#directory-listing-fields) | String | Terms of service link for the plugin's listing in Anthropic's directory. Claude Code doesn't read it |

142| [`defaultEnabled`](#defaultenabled) | Boolean | Whether the plugin starts enabled when the user hasn't set it. Defaults to `true` |142| [`defaultEnabled`](#defaultenabled) | Boolean | Whether the plugin starts enabled when the user hasn't set it. Defaults to `true` |

143| [`dependencies`](#dependencies) | Array of strings or objects | Plugins that must be enabled for this one to work |143| [`dependencies`](#dependencies) | Array of strings or objects | Plugins that must be enabled for this one to work |

144| [`settings`](#settings) | Object | Settings Claude Code applies while the plugin is enabled. Only `agent` and `subagentStatusLine` take effect |

145| [`userConfig`](#user-configuration) | Object | Values Claude Code prompts the user for when the plugin is enabled |144| [`userConfig`](#user-configuration) | Object | Values Claude Code prompts the user for when the plugin is enabled |

146| `types` | Path | A `.d.ts` file that declares the `$.state` values and `$` nouns of a [mod](https://code.claude.com/docs/en/plugins/mods/reference.md#files) |145| `types` | Path | A `.d.ts` file that declares the `$.state` values and `$` nouns of a [mod](https://code.claude.com/docs/en/plugins/mods/reference.md#files) |

147| [`channels`](#channels) | Array of objects | Message channels the plugin provides, each bound to one of its MCP servers |146| [`channels`](#channels) | Array of objects | Message channels the plugin provides, each bound to one of its MCP servers |


211 210 

212Plugins that must be enabled for this one to work. Each entry is `"name"`, `"name@marketplace"`, or `{ "name": "...", "marketplace": "...", "version": "..." }`. Bare names resolve against this plugin's own marketplace. See [dependency constraints](https://code.claude.com/docs/en/plugins/dependencies.md).211Plugins that must be enabled for this one to work. Each entry is `"name"`, `"name@marketplace"`, or `{ "name": "...", "marketplace": "...", "version": "..." }`. Bare names resolve against this plugin's own marketplace. See [dependency constraints](https://code.claude.com/docs/en/plugins/dependencies.md).

213 212 

214### `settings`

215 

216Settings Claude Code applies while the plugin is enabled. Only `agent` and `subagentStatusLine` take effect; other keys are dropped at load. A `settings.json` at the plugin root takes precedence over this key. See [Default settings](https://code.claude.com/docs/en/plugins/components.md#default-settings).

217 

218## Component path forms213## Component path forms

219 214 

220Every component key accepts a path relative to the plugin root. `hooks`, `mcpServers`, `lspServers`, and `experimental.monitors` also accept inline configuration, `commands` also accepts an object map, and `mcpServers` also accepts MCP bundle paths and URLs. The examples that follow show each accepted shape once. For what each component does at runtime, see [Plugin components](https://code.claude.com/docs/en/plugins/components.md).215Every component key accepts a path relative to the plugin root. `hooks`, `mcpServers`, `lspServers`, and `experimental.monitors` also accept inline configuration, `commands` also accepts an object map, and `mcpServers` also accepts MCP bundle paths and URLs. The examples that follow show each accepted shape once. For what each component does at runtime, see [Plugin components](https://code.claude.com/docs/en/plugins/components.md).


626| Themes | `themes/` | Theme JSON files |621| Themes | `themes/` | Theme JSON files |

627| Monitors | `monitors/monitors.json` | The monitors array |622| Monitors | `monitors/monitors.json` | The monitors array |

628| Executables | `bin/` | Files here are on the Bash tool's `PATH` while the plugin is enabled, so Claude runs them as bare commands. claude.ai and Cowork don't install a plugin that has this directory, including one you [distribute through claude.ai organization settings](https://claude.com/docs/plugins/org-sync#keep-executables-out-of-the-top-level-bin-directory) |623| Executables | `bin/` | Files here are on the Bash tool's `PATH` while the plugin is enabled, so Claude runs them as bare commands. claude.ai and Cowork don't install a plugin that has this directory, including one you [distribute through claude.ai organization settings](https://claude.com/docs/plugins/org-sync#keep-executables-out-of-the-top-level-bin-directory) |

629| Settings | `settings.json` | `agent` and `subagentStatusLine` defaults applied while the plugin is enabled |

630 624 

631A plugin that uses every default location, plus a `scripts/` folder that its hooks call, is laid out like this:625A plugin that uses default locations, plus a `scripts/` folder that its hooks call, is laid out like this:

632 626 

633```text theme={null}627```text theme={null}

634deploy-tools/628deploy-tools/


655│ └── deploy-tool649│ └── deploy-tool

656├── scripts/650├── scripts/

657│ └── format.sh651│ └── format.sh

658├── settings.json

659├── .mcp.json652├── .mcp.json

660└── .lsp.json653└── .lsp.json

661```654```

Details

61 * The session runs on [`/login` credentials](https://code.claude.com/docs/en/authentication#authentication-precedence) for a Team or Enterprise plan61 * The session runs on [`/login` credentials](https://code.claude.com/docs/en/authentication#authentication-precedence) for a Team or Enterprise plan

62 62 

63 A user with an API key, or on Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry, gets the guard only on a machine with managed settings or `managed-mcp.json`. A session that runs on a long-lived [`CLAUDE_CODE_OAUTH_TOKEN`](https://code.claude.com/docs/en/authentication#generate-a-long-lived-token) doesn't count as that login either, even when a Team or Enterprise login is stored on the machine.63 A user with an API key, or on Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry, gets the guard only on a machine with managed settings or `managed-mcp.json`. A session that runs on a long-lived [`CLAUDE_CODE_OAUTH_TOKEN`](https://code.claude.com/docs/en/authentication#generate-a-long-lived-token) doesn't count as that login either, even when a Team or Enterprise login is stored on the machine.

64* **The guard protects what you manage.** A user's mod can't change what your managed hooks receive or decide, the system prompt, your managed `CLAUDE.md` and other managed instructions, what any mod reads as settings, or the tools and descriptions of your managed MCP servers.64* **The guard protects what you manage.** A user's mod can't change what your managed hooks receive or decide, the system prompt, or your managed `CLAUDE.md` and other managed instructions. It also can't change what any mod reads as settings, or the tools and descriptions of your managed MCP servers once they connect.

65* **Outside what you manage, a user's mod acts as that user.** The mod keeps that user's permissions: it can still read and write files, start processes, and make network requests. It can also rewrite tool calls and prompts, deny a tool call, and draw in the interface.65* **On v2.1.323 or later, a user's mod can keep a managed MCP server from connecting.** In that user's session, `/mcp` lists the server as held by that mod. To prevent it, [stop user-installed mods from loading](#stop-user-installed-mods-from-loading).

66* **Outside what you manage, a user's mod acts as that user.** The mod keeps that user's permissions: it can still read and write files, start processes, and make network requests. It can also rewrite tool calls and prompts, deny a tool call, add or remove tools, and draw in the interface.

66* **Permission rules and `PreToolUse` hooks take precedence over a user's mod.** With the guard loaded, by default a user's mod can't approve a call that a `deny` rule refuses or an `ask` rule prompts for, whichever settings file holds the rule. The mod can't approve a call that any `PreToolUse` hook blocked, either.67* **Permission rules and `PreToolUse` hooks take precedence over a user's mod.** With the guard loaded, by default a user's mod can't approve a call that a `deny` rule refuses or an `ask` rule prompts for, whichever settings file holds the rule. The mod can't approve a call that any `PreToolUse` hook blocked, either.

67 68 

68 Permission rules and `PreToolUse` hooks apply to Claude's tool calls, not to a mod's [`$.fs` and `$.process` calls](https://code.claude.com/docs/en/plugins/mods/api#reach-files-processes-and-the-network). With `Read(.env)` denied, a mod can still read that file with `$.fs.read` or start a program that does. To limit a mod's own `$.fs` and `$.process` calls, [keep the mod from loading](#stop-user-installed-mods-from-loading) or handle them in a [policy mod](#enforce-a-policy-with-a-mod-of-your-own).69 Permission rules and `PreToolUse` hooks apply to Claude's tool calls, not to a mod's [`$.fs` and `$.process` calls](https://code.claude.com/docs/en/plugins/mods/api#reach-files-processes-and-the-network). With `Read(.env)` denied, a mod can still read that file with `$.fs.read` or start a program that does. To limit a mod's own `$.fs` and `$.process` calls, [keep the mod from loading](#stop-user-installed-mods-from-loading) or handle them in a [policy mod](#enforce-a-policy-with-a-mod-of-your-own).


159The `hooks:` and `calls:` lines in the output describe the mod's code:160The `hooks:` and `calls:` lines in the output describe the mod's code:

160 161 

161```text theme={null}162```text theme={null}

162 ❯ ./register.js hooks: session.start, tool.call, ui.render{component=Pane}163 ❯ ./register.js hooks: session.start, tool.call, ui.render{component=Pane} (default matcher key: plugin)

163 ❯ ./register.js calls: $.fs.read, $.http.fetch, $.store.set, $.ui.open164 ❯ ./register.js calls: $.fs.read, $.http.fetch, $.store.set, $.ui.open

164```165```

165 166 

166The `hooks:` line lists the events the mod receives. The `calls:` line lists the mods API methods its code calls. The [mods API](https://code.claude.com/docs/en/plugins/mods/api.md), written `$` in a mod's code, is how a mod reaches files, processes, and the network. Claude Code refuses to load a mod that uses the mods API in a way this command can't read.167* **`hooks:`**: the events the mod receives. A `default matcher key: plugin` note means the hook before it [skips other mods' controls and drawings](https://code.claude.com/docs/en/plugins/mods/events.md#hook-other-mods-drawings-and-controls).

168* **`calls:`**: the mods API methods its code calls

167 169 

168Look at the `calls:` line for these:170The [mods API](https://code.claude.com/docs/en/plugins/mods/api.md), written `$` in a mod's code, is how a mod reaches files, processes, and the network. Claude Code refuses to load a mod that uses the mods API in a way this command can't read.

171 

172Don't approve a mod that fails this command, because some failures don't stop it from loading. Run the command on Claude Code v2.1.323 or later, where a long list continues on more lines with the same label, and read every `hooks:` and `calls:` line. In the `calls:` lines, look for these:

169 173 

170| Call | What it means |174| Call | What it means |

171| :- | :- |175| :- | :- |


174| `$.http.fetch` | Makes network requests |178| `$.http.fetch` | Makes network requests |

175| `$.env.get`, `$.settings.read` | Reads environment variables and settings, which can hold API keys. An `env reads:` line in the output names each variable. |179| `$.env.get`, `$.settings.read` | Reads environment variables and settings, which can hold API keys. An `env reads:` line in the output names each variable. |

176| `$.env.set` | Sets an environment variable for Claude Code and for every command and MCP server it starts afterward, which can change what those programs run. An `env writes:` line names each variable. |180| `$.env.set` | Sets an environment variable for Claude Code and for every command and MCP server it starts afterward, which can change what those programs run. An `env writes:` line names each variable. |

177| `$.mcp.call` | Calls a tool on a connected MCP server, under the session's permission rules |181| `$.mcp.call` | Calls a tool on a connected MCP server, with no permission prompt. Claude Code refuses the call under a deny rule or a managed ask rule. It also refuses a call to a tool marked [`requiresUserInteraction`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool), or to one your organization [set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools) where that setting reaches Claude Code. |

178| `$.model.complete` | Uses the user's plan or API key for model calls |182| `$.model.complete` | Uses the user's plan or API key for model calls |

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

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 |184| `$.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 |


316 320 

317Claude Code fires an event each time it's about to act, such as run a tool, and passes it to each mod in turn. A mod that counts as yours [runs before users' mods](https://code.claude.com/docs/en/plugins/mods/events.md#the-order-mods-run-in) even when you list it nowhere. To set its place, list its id in one of two settings. The id is the plugin's name, `@`, and the marketplace's name, such as `acme-guard@acme-tools`.321Claude Code fires an event each time it's about to act, such as run a tool, and passes it to each mod in turn. A mod that counts as yours [runs before users' mods](https://code.claude.com/docs/en/plugins/mods/events.md#the-order-mods-run-in) even when you list it nowhere. To set its place, list its id in one of two settings. The id is the plugin's name, `@`, and the marketplace's name, such as `acme-guard@acme-tools`.

318 322 

319* **`prependPlugins`**: your mod sees every event before any user's mod and every result after. It can change the event, refuse it, or skip the users' mods.323* **`prependPlugins`**: your mod sees an event before any user's mod, and the event's result after them. It can change the event, refuse it, or skip the users' mods. On v2.1.323 or later, check that your hooks still [reach other mods' controls and drawings](https://code.claude.com/docs/en/plugins/mods/events.md#hook-other-mods-drawings-and-controls).

320* **`appendPlugins`**: your mod runs after every user's mod, so it sees only the events those mods pass on, in the form they pass them324* **`appendPlugins`**: your mod runs after every user's mod, so it sees only the events those mods pass on, in the form they pass them

321 325 

322This example declares the `acme-tools` marketplace at `/opt/acme/claude-plugins`, enables `acme-guard` from it, and runs that mod first, with the built-in guard after it:326This example declares the `acme-tools` marketplace at `/opt/acme/claude-plugins`, enables `acme-guard` from it, and runs that mod first, with the built-in guard after it:


359 363 

360Each time another mod is about to load, your mod receives the list that `claude plugin validate` prints, in an event named [`plugin.register`](https://code.claude.com/docs/en/plugins/mods/reference#other-mods). A mod in `prependPlugins` can read that list and refuse the mod. It can also [handle any mods API call by name](https://code.claude.com/docs/en/plugins/mods/api.md#reach-files-processes-and-the-network) to record or refuse that call for every other mod. The name is the method without the `$.`, so a hook on `fs.write` sees every `$.fs.write` call.364Each time another mod is about to load, your mod receives the list that `claude plugin validate` prints, in an event named [`plugin.register`](https://code.claude.com/docs/en/plugins/mods/reference#other-mods). A mod in `prependPlugins` can read that list and refuse the mod. It can also [handle any mods API call by name](https://code.claude.com/docs/en/plugins/mods/api.md#reach-files-processes-and-the-network) to record or refuse that call for every other mod. The name is the method without the `$.`, so a hook on `fs.write` sees every `$.fs.write` call.

361 365 

366> [!NOTE]

367>

368> On v2.1.323 or later, a `ui.focus` hook needs a wider matcher to receive other mods' `$.ui.focus` calls. See [Hook other mods' drawings and controls](https://code.claude.com/docs/en/plugins/mods/events.md#hook-other-mods-drawings-and-controls).

369 

362This policy mod refuses any user's mod whose own code calls `$.process.run` or `$.process.spawn`. It also keeps an audit log, writing each tool call and each file a mod writes to the debug log. Because it runs first, the log records what was requested, before any user's mod changes it. Save it as `acme-guard/hooks/register.js`:370This policy mod refuses any user's mod whose own code calls `$.process.run` or `$.process.spawn`. It also keeps an audit log, writing each tool call and each file a mod writes to the debug log. Because it runs first, the log records what was requested, before any user's mod changes it. Save it as `acme-guard/hooks/register.js`:

363 371 

364```javascript acme-guard/hooks/register.js theme={null}372```javascript acme-guard/hooks/register.js theme={null}


403* **`e.tier`**: where the mod would run, one of `prepend`, `user`, `append`, or `builtin`. Every mod a person installs is `user`.411* **`e.tier`**: where the mod would run, one of `prepend`, `user`, `append`, or `builtin`. Every mod a person installs is `user`.

404* **`e.uses.calls`**: the mods API methods the mod calls, each written `namespace.method` such as `process.run`, without the `$.` that `claude plugin validate` prints412* **`e.uses.calls`**: the mods API methods the mod calls, each written `namespace.method` such as `process.run`, without the `$.` that `claude plugin validate` prints

405 413 

406When a user installs a mod that calls `$.process.run`, the mod doesn't load, and their debug log has a line that ends with `refused by acme-guard:` and your reason. The refusal also reaches the transcript in a [session that hot-reloads a plugin directory](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#find-out-why-a-mod-does-nothing). To block a call without refusing the whole mod, return `{ deny: 'your reason' }` from a hook on that call's name.414When a user installs a mod that calls `$.process.run`, the mod doesn't load, and their debug log has a line that ends with `refused by acme-guard:` and your reason. The refusal also reaches the transcript in a [session that hot-reloads a plugin directory](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#find-out-why-a-mod-does-nothing).

415 

416To block a call without refusing the whole mod, return `{ deny: 'your reason' }` from a hook on that call's name, after you [check who made the call](https://code.claude.com/docs/en/plugins/mods/reference.md#mods-api-calls).

407 417 

408To send the audit lines somewhere other than the debug log, call `$.http.fetch` from the same hooks.418To send the audit lines somewhere other than the debug log, call `$.http.fetch` from the same hooks.

409 419 

Details

21 21 

22Describe the mod you want in an interactive Claude Code session, and Claude writes it. Claude works from a built-in [skill](https://code.claude.com/docs/en/skills.md) named `plugin-authoring`, which tells it where to write the mod, which events and methods your version has, and how the mod gets loaded. Claude can load the skill when you ask for a mod, or you can load it yourself by running `/plugin-authoring` at the Claude Code prompt.22Describe the mod you want in an interactive Claude Code session, and Claude writes it. Claude works from a built-in [skill](https://code.claude.com/docs/en/skills.md) named `plugin-authoring`, which tells it where to write the mod, which events and methods your version has, and how the mod gets loaded. Claude can load the skill when you ask for a mod, or you can load it yourself by running `/plugin-authoring` at the Claude Code prompt.

23 23 

24In the `auto` and `bypassPermissions` [permission modes](https://code.claude.com/docs/en/permission-modes.md), the mod can run when the turn ends. Otherwise, it runs once you approve it, except in [sessions where a mod Claude writes can't load](#sessions-that-skip-the-approval).24In `auto` and `bypassPermissions` [permission modes](https://code.claude.com/docs/en/permission-modes.md), Claude Code [can load the mod without asking you](#sessions-that-skip-the-approval). To be asked first, start a new session in `default` or `acceptEdits` mode, or [switch](https://code.claude.com/docs/en/permission-modes.md#switch-permission-modes) to either mode before you ask for the session's first mod. In [some sessions](#sessions-that-cant-load), the mod can't load.

25 25 

26**1. Describe the mod**26**1. Describe the mod**

27 27 


33 33 

34**2. Approve the mod**34**2. Approve the mod**

35 35 

36When Claude saves the first file, Claude Code asks whether to enable hot reloading for the session. Hot reloading runs the mods Claude writes in this session and picks up each later change. If no question appears, skip this step.36When Claude saves the first file, Claude Code asks whether to enable hot reloading for the session. Hot reloading runs the mods Claude writes in this session and picks up each later change. You don't see this question in a session that [loads new mods without asking](#sessions-that-skip-the-approval) or [can't load them](#sessions-that-cant-load).

37 37 

38Choose one of these answers:38Choose one of these answers:

39 39 


57* **In a session you start**: in your shell, run `claude --plugin-dir ~/mods/git-branch`57* **In a session you start**: in your shell, run `claude --plugin-dir ~/mods/git-branch`

58* **For other people**: [add it to a marketplace](#share-your-mod) so they can install it58* **For other people**: [add it to a marketplace](#share-your-mod) so they can install it

59 59 

60### Sessions that load a mod without asking

61 

62Claude Code can enable hot reloading without asking in `auto` and `bypassPermissions` modes, and the mods load when the turn ends.

63 

64When you resume a session, interactively or with `claude -p`, the mods already in its mods folder [can load](#sessions-that-cant-load) without asking. To keep a mod from loading when you resume, delete its directory.

65 

60### Sessions where a mod Claude writes can't load66### Sessions where a mod Claude writes can't load

61 67 

62A mod Claude writes loads in a trusted workspace where mods are allowed to run, after you approve it in the modes that ask. In these sessions it doesn't load:68A mod Claude writes doesn't load in these cases, and Claude Code doesn't ask to load it:

63 69 

64* **Nobody is there to approve**: the session can't show you a prompt, as in a `claude -p` run outside `auto` and `bypassPermissions` modes, or [`dontAsk` mode](https://code.claude.com/docs/en/permission-modes)70* **Nobody is there to approve**: the session is in [`dontAsk` mode](https://code.claude.com/docs/en/permission-modes), or it's the `claude -p` run that writes the mod, in `default` or `acceptEdits` mode, which can't show you the hot reloading question.

65* **The workspace isn't trusted**: you haven't accepted the trust prompt for the directory71* **An interactive session where the workspace isn't trusted**: you haven't accepted the trust prompt for the directory

66* **Mods are disabled**: you started with `--safe-mode` or `--bare`, you set `disableAllHooks`, or your organization's [managed settings block it](https://code.claude.com/docs/en/plugins/mods/admin.md#choose-how-much-to-allow)72* **Mods are disabled**: you started with `--safe-mode` or `--bare`, you set `disableAllHooks`, or your organization's [managed settings block it](https://code.claude.com/docs/en/plugins/mods/admin.md#choose-how-much-to-allow)

67 73 

68## Write a mod yourself74## Write a mod yourself


292 298 

293Check the `hooks:` line for the events your module hooks, each with its filter in braces, and `calls:` for every mods API method it calls. If your module reads or sets environment variables, look for `env reads:` and `env writes:` lines too, and `state reads:` and `state writes:` if it uses [`$.state`](https://code.claude.com/docs/en/plugins/mods/interface#keep-state). You also see one line for each hook that can refuse an action, such as `gating hook without .catch: tool.call`, which says whether that hook has a [`.catch` handler](https://code.claude.com/docs/en/plugins/mods/events#handle-a-hook-that-fails).299Check the `hooks:` line for the events your module hooks, each with its filter in braces, and `calls:` for every mods API method it calls. If your module reads or sets environment variables, look for `env reads:` and `env writes:` lines too, and `state reads:` and `state writes:` if it uses [`$.state`](https://code.claude.com/docs/en/plugins/mods/interface#keep-state). You also see one line for each hook that can refuse an action, such as `gating hook without .catch: tool.call`, which says whether that hook has a [`.catch` handler](https://code.claude.com/docs/en/plugins/mods/events#handle-a-hook-that-fails).

294 300 

295If an event you meant to handle is missing from the first line, Claude Code won't call that hook either. The usual cause is a misspelled event name, which the command reports as an error such as `"tool.calls" is not an event`.301If an event you meant to handle is missing from the `hooks:` lines, Claude Code won't call that hook either. The usual cause is a misspelled event name, which the command reports as an error such as `"tool.calls" is not an event`.

296 302 

297Follow these rules so that static analysis can find every hook and call:303Follow these rules so that static analysis can find every hook and call:

298 304 

Details

91 91 

92Register each event once per matcher. If you call `on` twice for `session.start` with no matcher, the module fails to load with `on("session.start") is registered twice without a matcher`. Put everything your mod does at session start in one hook.92Register each event once per matcher. If you call `on` twice for `session.start` with no matcher, the module fails to load with `on("session.start") is registered twice without a matcher`. Put everything your mod does at session start in one hook.

93 93 

94#### Hook other mods' drawings and controls

95 

96To hook another mod's controls, panes, or row above the prompt, pass a matcher with `plugin`. Use the mod's name without its marketplace, as in `{ plugin: 'other-mod' }`, or `{ plugin: '*' }` for every mod. Without `plugin`, a hook on `ui.press`, `ui.input`, `ui.select`, or `ui.focus` doesn't run for other mods' controls, and a `ui.render` hook skips their panes and their rows above the prompt.

97 

98A hook on a wildcard with no matcher, such as `on('*', hook)` or `on('ui.*', hook)`, still runs for every mod. A wildcard with a matcher needs `plugin` too.

99 

100> [!NOTE]

101>

102> `{ plugin: '*' }` requires Claude Code v2.1.323 or later. Before v2.1.323, a hook with no `plugin` ran for every mod, and a hook with `{ plugin: '*' }` didn't run. To match every mod on both versions, use `{ plugin: /./ }` on `ui.press`, `ui.input`, and `ui.select`. For `ui.focus` and `ui.render`, use `on('ui.*', hook)` and check the event's name in `next.event`, as in `if (next.event !== 'ui.focus') return next(e)`.

103 

94## Hook what Claude is doing104## Hook what Claude is doing

95 105 

96Handle these events to see or change a tool call, a prompt, a turn, or a settings read as it happens. For every event and what a hook can return, see the [events reference](https://code.claude.com/docs/en/plugins/mods/reference.md#events).106Handle these events to see or change a tool call, a prompt, a turn, or a settings read as it happens. For every event and what a hook can return, see the [events reference](https://code.claude.com/docs/en/plugins/mods/reference.md#events).

Details

177 177 

178## Pick where to draw178## Pick where to draw

179 179 

180A `ui.render` hook runs for every render site unless you narrow it to the one you want to draw in. To choose the render site, pass a filter, called a [matcher](https://code.claude.com/docs/en/plugins/mods/events.md#filter-which-events-a-hook-handles), as the second argument to `on`. `{ component: 'Pane' }` runs the hook only for panes. In the hook, `e.component` names the site, `e.surface` says which app is drawing, and `e.props` holds the site's own data. For a pane, `e.requestId` is the `id` you opened it with.180To choose the render site a `ui.render` hook draws in, pass a filter, called a [matcher](https://code.claude.com/docs/en/plugins/mods/events.md#filter-which-events-a-hook-handles), as the second argument to `on`. `{ component: 'Pane' }` runs the hook only for panes. In the hook, `e.component` names the site, `e.surface` says which app is drawing, and `e.props` holds the site's own data. For a pane, `e.requestId` is the `id` you opened it with.

181 181 

182The pane and the band are empty until a mod fills them. Select a tab to see what each one is and how to draw in it:182The pane and the band are empty until a mod fills them. Select a tab to see what each one is and how to draw in it:

183 183 


191 191 

192> [tab] Band above the prompt192> [tab] Band above the prompt

193>193>

194> The band is a strip directly above the prompt input. It's always there, and every mod shares it.194> The band is a strip directly above the prompt input. Each mod that draws there gets its own row, and the rows stack from the top in the [order mods run in](https://code.claude.com/docs/en/plugins/mods/events.md#the-order-mods-run-in).

195>195>

196> Your hook returns a tree to show something in the band, or `next(e)` to show nothing. A tree replaces what the mods [after yours](https://code.claude.com/docs/en/plugins/mods/events.md#the-order-mods-run-in) draw there. To keep theirs, put the result of `await next(e)` among the children of a [`Box`](#build-a-tree-from-elements) in your tree.196> To draw your mod's row, filter on `{ component: 'AbovePrompt' }` and return a [tree](#build-a-tree-from-elements). To draw nothing, return `next(e)`.

197>197>

198> To draw in the band, filter on `{ component: 'AbovePrompt' }`.198> Before v2.1.323, all mods shared one drawing in the band, and your tree replaced what the mods after yours drew. To support those releases too, put the result of `await next(e)` among the children of a [`Box` that stays valid](https://code.claude.com/docs/en/plugins/mods/troubleshoot#another-mods-band-shows-and-yours-doesnt). On v2.1.323 or later, that child doesn't draw other mods' rows.

199 199 

200A mod can also [place a row of its own in the transcript](#place-a-row-in-the-transcript).200A mod can also [place a row of its own in the transcript](#place-a-row-in-the-transcript).

201 201 


281 281 

282While Claude works, the spinner animates as before, and `under the spinner` appears below it.282While Claude works, the spinner animates as before, and `under the spinner` appears below it.

283 283 

284The permission prompt isn't a render site, so a mod can't change what it shows. The question dialog, `AskUserQuestion`, is one, so a mod can change that. A tree for the dialog has to hold the reference exactly once, with your elements above it. Otherwise, Claude Code draws its own dialog.284The permission prompt isn't a render site, so a mod can't change what it shows. The question dialog, `AskUserQuestion`, is one, so a mod can change that dialog when Claude asks a question. A tree for the dialog has to hold the reference exactly once, with your elements above it. Otherwise, Claude Code draws its own dialog.

285 285 

286### Open a pane at the right time286### Open a pane at the right time

287 287 

288A pane appears only when your mod opens it. How and when you open it decides whether it takes keyboard focus, how much room it asks for, and whether it shows at all in a narrow terminal.288A pane appears only when your mod opens it. How and when you open it decides whether it takes keyboard focus, how much room it asks for, and whether it shows at all in a narrow terminal.

289 289 

290To open a pane, call [`$.ui.open`](https://code.claude.com/docs/en/plugins/mods/reference#mods-api-methods) with an `id` you choose. The `id` is the pane's name: your `ui.render` hook checks for it, and you pass it again to close the pane.290To open a pane, call [`$.ui.open`](https://code.claude.com/docs/en/plugins/mods/reference#mods-api-methods) with an `id` you choose. The `id` is the pane's name: your `ui.render` hook checks for it, and you pass it again to close the pane. If another mod has a pane open with that `id`, the call rejects.

291 291 

292```javascript theme={null}292```javascript theme={null}

293await $.ui.open({ id: 'hello-tabs', title: 'Hello tabs', focus: true })293await $.ui.open({ id: 'hello-tabs', title: 'Hello tabs', focus: true })


399 399 

400> [!NOTE]400> [!NOTE]

401>401>

402> `$.theme.set` and `$.theme.clear` replace `$.ui.backdrop`, which Claude Code v2.1.319 removed. Change `$.ui.backdrop({ id: 'your-backdrop' })` to `$.theme.set({ backdrop: { id: 'your-backdrop' } })`, and `$.ui.backdrop(undefined)` to `$.theme.clear()`, which removes any mod's backdrop.402> `$.theme.set` and `$.theme.clear` replace `$.ui.backdrop`, which Claude Code v2.1.319 removed. Change `$.ui.backdrop({ id: 'your-backdrop' })` to a `$.theme.set` call like the one in this section's example, and `$.ui.backdrop(undefined)` to `$.theme.clear()`, which removes any mod's backdrop.

403 403 

404To put a backdrop behind the conversation in the Desktop app or the mobile app, call [`$.theme.set`](https://code.claude.com/docs/en/plugins/mods/reference#mods-api-methods) with a `backdrop`, then draw the backdrop at the [`Backdrop`](https://code.claude.com/docs/en/plugins/mods/reference#render-sites) render site. To take the backdrop off, call `$.theme.clear()`. The terminal draws no backdrop. `$.theme.set` and `$.theme.clear` require Claude Code v2.1.319 or later.404To put a backdrop behind the conversation in the Desktop app or the mobile app, call [`$.theme.set`](https://code.claude.com/docs/en/plugins/mods/reference#mods-api-methods) with a `backdrop`, then draw the backdrop at the [`Backdrop`](https://code.claude.com/docs/en/plugins/mods/reference#render-sites) render site. To take the backdrop off, call `$.theme.clear()`. The terminal draws no backdrop. `$.theme.set` and `$.theme.clear` require Claude Code v2.1.319 or later.

405 405 

406This mod sets a backdrop when the session starts, draws the backdrop, and adds a `/plain` command that takes the backdrop off:406This example requires Claude Code v2.1.323 or later, so [check your version](https://code.claude.com/docs/en/plugins/mods/overview.md#turn-mods-on-or-off) first. The mod sets a backdrop when the session starts, draws the backdrop, and adds a `/plain` command that takes the backdrop off:

407 407 

408```javascript theme={null}408```javascript theme={null}

409export function register(on) {409export function register(on) {

410 // Neither a reload of this mod nor --resume keeps the backdrop, so set it here410 // Neither a reload of this mod nor --resume keeps the backdrop, so set it here

411 on('session.start', async ($, e, next) => {411 on('session.start', async ($, e, next) => {

412 await $.theme.set({ backdrop: { id: 'night-sky', colorScheme: 'dark' } })412 await $.theme.set({ backdrop: { scene: 'night-sky' }, overrideColorScheme: 'dark' })

413 await $.command.register({ name: 'plain', description: 'Take the backdrop off' })413 await $.command.register({ name: 'plain', description: 'Take the backdrop off' })

414 return next(e)414 return next(e)

415 })415 })

416 416 

417 on('ui.render', { component: 'Backdrop' }, async ($, e, next) => {417 on('ui.render', { component: 'Backdrop' }, async ($, e, next) => {

418 // This hook runs for every mod's backdrop, and another mod can use the same id418 // This hook runs for every mod's backdrop, and another mod can use the same scene

419 if (e.props.plugin !== $.plugin.name || e.props.id !== 'night-sky') return next(e)419 if (e.props.plugin !== $.plugin.name || e.props.scene !== 'night-sky') return next(e)

420 const { Box, Text } = $.ui.resolve(e)420 const { Box, Text } = $.ui.resolve(e)

421 return Box({ backgroundColor: 'blue', children: [Text({ children: ['Night sky'] })] })421 return Box({ backgroundColor: 'blue', children: [Text({ children: ['Night sky'] })] })

422 })422 })


428}428}

429```429```

430 430 

431> [!NOTE]

432>

433> Before v2.1.323, write `id` in place of `scene` in the `$.theme.set` call and in `e.props`, and move `overrideColorScheme` into `backdrop` as `colorScheme`.

434 

431To try the example, put this code in a [mod](https://code.claude.com/docs/en/plugins/mods/create.md) and start a session in the Desktop app or the mobile app. To take the backdrop off, run `/plain` at the Claude Code prompt. The transcript shows `the theme is cleared` after the mod's name, as in `night-sky: the theme is cleared` for a mod named `night-sky`.435To try the example, put this code in a [mod](https://code.claude.com/docs/en/plugins/mods/create.md) and start a session in the Desktop app or the mobile app. To take the backdrop off, run `/plain` at the Claude Code prompt. The transcript shows `the theme is cleared` after the mod's name, as in `night-sky: the theme is cleared` for a mod named `night-sky`.

432 436 

433Check what `backdrop` takes, what the call's result tells you, and what other mods can change:437Check what `backdrop` takes, what the call's result tells you, and what other mods can change:

434 438 

435* **The `backdrop` fields**: `id`, a [name](https://code.claude.com/docs/en/plugins/mods/reference.md#limits) you choose, is required, and the other fields are optional. `colorScheme` is `'light'` or `'dark'` and says whether your drawing is light or dark. For `glass`, see [the types for your build](https://code.claude.com/docs/en/plugins/mods/create.md#get-the-types-for-your-build).439* **The `backdrop` fields**: `scene` is a [name](https://code.claude.com/docs/en/plugins/mods/reference.md#limits) you choose for a backdrop your hook draws. For the other fields and `overrideColorScheme`, see [the types for your build](https://code.claude.com/docs/en/plugins/mods/create.md#get-the-types-for-your-build).

436* **Whether the backdrop is drawn**: `$.theme.set` resolves with `isDrawn: true` when a Desktop or mobile app connected to the session says it draws backdrops. Otherwise `isDrawn` is `false` and `reason` says why.440* **Whether the backdrop is drawn**: `$.theme.set` resolves with `isDrawn: true` when a Desktop or mobile app connected to the session says it draws backdrops. Otherwise `isDrawn` is `false` and `reason` says why.

437* **One backdrop for each session**: a `$.theme.set` call replaces the session's backdrop and `$.theme.clear()` removes that backdrop, whichever mod set it. Call `$.theme.clear()` only when the user asks for it.441* **One backdrop for each session**: a `$.theme.set` call replaces the session's backdrop and `$.theme.clear()` removes that backdrop, whichever mod set it. Call `$.theme.clear()` only when the user asks for it.

438 442 


510>514>

511> Set `rows` to 2 or more for [a field that holds several lines](https://code.claude.com/docs/en/plugins/mods/gallery.md#input).515> Set `rows` to 2 or more for [a field that holds several lines](https://code.claude.com/docs/en/plugins/mods/gallery.md#input).

512 516 

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

514 518 

515| Element | What it draws | Where |519| Element | What it draws | Where |

516| :- | :- | :- |520| :- | :- | :- |


606Tests and other mods identify a control by its key:610Tests and other mods identify a control by its key:

607 611 

608* **Tests**: a [test](https://code.claude.com/docs/en/plugins/mods/test.md#test-a-drawing) presses or types into a control by its key.612* **Tests**: a [test](https://code.claude.com/docs/en/plugins/mods/test.md#test-a-drawing) presses or types into a control by its key.

609* **Other mods**: Claude Code fires [`ui.press`, `ui.input`, or `ui.select`](https://code.claude.com/docs/en/plugins/mods/reference#interface) with the control's key in `e.element` before it runs the control's callback. Another mod's hook for that event sees what the user typed into your `Input` and can change that text or keep your callback from running. The mods API gives that mod no method to press your buttons.613* **Other mods**: Claude Code fires [`ui.press`, `ui.input`, or `ui.select`](https://code.claude.com/docs/en/plugins/mods/reference#interface) with the control's key in `e.element` before it runs the control's callback. Another mod's hook can also [run for that event](https://code.claude.com/docs/en/plugins/mods/events.md#hook-other-mods-drawings-and-controls). That hook sees what the user typed into your `Input` and can change that text or keep your callback from running. The mods API gives that mod no method to press your buttons.

610 614 

611If a message says `needs a key` or `is drawn twice`, [find the cause by that message](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#needs-a-key).615If a message says `needs a key` or `is drawn twice`, [find the cause by that message](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#needs-a-key).

612 616 

Details

208 208 

209### Mods API calls209### Mods API calls

210 210 

211Every [mods API method](#mods-api-methods) is also an event, named for its namespace and method, such as `fs.read`, `model.complete`, or `ui.open`. A hook on one intercepts calls from the mods that run after it, and can return `next(e)`, `{ deny: reason }`, or `{ value }`.211Every [mods API method](#mods-api-methods) is also an event, named for its namespace and method, such as `fs.read`, `model.complete`, or `ui.open`. A hook on one can return `next(e)`, `{ deny: reason }`, or `{ value }`.

212 

213Some of these events also fire for Claude Code's own actions, so check whether `next.origin.plugin` is `engine` before you refuse one.

212 214 

213## Mods API methods215## Mods API methods

214 216 


249| :- | :- | :- | :- |251| :- | :- | :- | :- |

250| [`Pane`](https://code.claude.com/docs/en/plugins/mods/interface#pick-where-to-draw) | `title`, `isFocused`, `bodyColumns`, `placement`, `scroll`, `view` | The pane's `id` | Terminal, Desktop, VS Code |252| [`Pane`](https://code.claude.com/docs/en/plugins/mods/interface#pick-where-to-draw) | `title`, `isFocused`, `bodyColumns`, `placement`, `scroll`, `view` | The pane's `id` | Terminal, Desktop, VS Code |

251| [`AbovePrompt`](https://code.claude.com/docs/en/plugins/mods/interface#pick-where-to-draw) | `hasSurvey`, `isWorking`, `maxRows`, `bodyColumns`, `scroll`, `view` | One instance | Terminal, Desktop |253| [`AbovePrompt`](https://code.claude.com/docs/en/plugins/mods/interface#pick-where-to-draw) | `hasSurvey`, `isWorking`, `maxRows`, `bodyColumns`, `scroll`, `view` | One instance | Terminal, Desktop |

254| `AbovePromptList`, the stack of `AbovePrompt` rows | `rows`, a list with one `{ plugin, tree }` for each mod's row, plus the `AbovePrompt` props | One instance | Terminal, Desktop. Requires Claude Code v2.1.323 or later. |

252| [`Placed`](https://code.claude.com/docs/en/plugins/mods/interface#place-a-row-in-the-transcript) | `id`, `plugin`, `onScreen` | The `requestId` that `$.ui.place` returned | Terminal |255| [`Placed`](https://code.claude.com/docs/en/plugins/mods/interface#place-a-row-in-the-transcript) | `id`, `plugin`, `onScreen` | The `requestId` that `$.ui.place` returned | Terminal |

253| [`Backdrop`](https://code.claude.com/docs/en/plugins/mods/interface#put-a-backdrop-behind-the-conversation) | `id`, `plugin`, `glass`, `colorScheme` | `backdrop` | `desktop` and `mobile` surfaces. Your hook runs when the Desktop or mobile app asks to draw a backdrop. |256| [`Backdrop`](https://code.claude.com/docs/en/plugins/mods/interface#put-a-backdrop-behind-the-conversation) | `scene`, `plugin`, `glass`, `overrideColorScheme`. Before v2.1.323, `scene` was `id` and `overrideColorScheme` was `colorScheme`. | `backdrop` | `desktop` and `mobile` surfaces. Your hook runs when the Desktop or mobile app asks to draw a backdrop. |

254| `UserMessage` | `text`, `origin`, `isExpanded`, and `task` or `from` by origin | The drawn row's id | Terminal, Desktop, VS Code |257| `UserMessage` | `text`, `origin`, `isExpanded`, and `task` or `from` by origin | The drawn row's id | Terminal, Desktop, VS Code |

255| `AssistantMessage` | The reply's text | The drawn row's id | Terminal, Desktop, VS Code |258| `AssistantMessage` | The reply's text | The drawn row's id | Terminal, Desktop, VS Code |

256| `ToolUse`, `ToolResult`, `ToolGroup` | The tool's name, input, and result | The tool call id | Terminal, Desktop, VS Code |259| `ToolUse`, `ToolResult`, `ToolGroup` | The tool's name, input, and result | The tool call id | Terminal, Desktop, VS Code |


297* **`action`**: names one of Claude Code's own [keybinding actions](https://code.claude.com/docs/en/keybindings.md), and the user's binding for it presses the button when that binding is a chord or a modified key300* **`action`**: names one of Claude Code's own [keybinding actions](https://code.claude.com/docs/en/keybindings.md), and the user's binding for it presses the button when that binding is a chord or a modified key

298* **Digit hotkeys on the band**: a digit `hotkey` on a button in the band also fires when the user types that digit alone into an empty prompt and pauses301* **Digit hotkeys on the band**: a digit `hotkey` on a button in the band also fires when the user types that digit alone into an empty prompt and pauses

299* **A collapsed band**: while the band is [collapsed](https://code.claude.com/docs/en/plugins/mods/interface.md#when-the-user-collapses-the-band), neither an `action` binding nor a hotkey presses a button in it302* **A collapsed band**: while the band is [collapsed](https://code.claude.com/docs/en/plugins/mods/interface.md#when-the-user-collapses-the-band), neither an `action` binding nor a hotkey presses a button in it

300* **Two buttons on one hotkey**: when two buttons in one drawing name the same `hotkey`, the later one gets it303* **Two buttons on one hotkey**: when two of your buttons in one drawing name the same `hotkey`, the later one gets it. For another mod's button on the same key, see [Hotkeys do nothing](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#hotkeys-do-nothing).

301* **`variant`**: `primary` or `secondary`, and any other value throws. In the terminal, a `primary` button draws in the accent color unless it's `plain`.304* **`variant`**: `primary` or `secondary`, and any other value throws. In the terminal, a `primary` button draws in the accent color unless it's `plain`.

302* **`role`**: `dismiss` marks a close button, and any other value throws. Do the closing in your `onPress`. In a band that holds text and a row of buttons, the Desktop app can draw the row's first `dismiss` button as its own close control. The terminal draws the button as it would without `role`.305* **`role`**: `dismiss` marks a close button, and any other value throws. Do the closing in your `onPress`. In a band that holds text and a row of buttons, the Desktop app can draw the row's first `dismiss` button as its own close control. The terminal draws the button as it would without `role`.

303 306 


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

402| Elements and text children in one tree | 20,000 |405| Elements and text children in one tree | 20,000 |

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

407| The rows above the prompt, stacked | Elements, `Raster` cells, and `Image` bytes add up across the rows, against the limits for one tree |

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

405| `$.store` | 4 MiB of JSON in total |409| `$.store` | 4 MiB of JSON in total |

406| `$.session.messages()` | The newest 4,096 entries |410| `$.session.messages()` | The newest 4,096 entries |


412| Nesting depth of a changed event passed to `next`, outside [async generator hooks](#events) such as one on `turn.step` | 28,000 levels. Past that, `next` rejects with a message ending `nesting deeper than 28000 levels is not supported`. Requires Claude Code v2.1.299 or later. |416| Nesting depth of a changed event passed to `next`, outside [async generator hooks](#events) such as one on `turn.step` | 28,000 levels. Past that, `next` rejects with a message ending `nesting deeper than 28000 levels is not supported`. Requires Claude Code v2.1.299 or later. |

413| Nesting depth of a hook's return value, outside `ui.render`, `ui.resolve`, and async generator hooks | 28,000 levels. Past that, the hook's result is refused, and [the notice that reports it](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#find-out-why-a-mod-does-nothing) includes `nesting deeper than 28000 levels is not supported`. Requires Claude Code v2.1.299 or later. |417| Nesting depth of a hook's return value, outside `ui.render`, `ui.resolve`, and async generator hooks | 28,000 levels. Past that, the hook's result is refused, and [the notice that reports it](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#find-out-why-a-mod-does-nothing) includes `nesting deeper than 28000 levels is not supported`. Requires Claude Code v2.1.299 or later. |

414| Scopes, such as functions, blocks, and loops, nested inside one another in one file of a hooks module | 2,000 |418| Scopes, such as functions, blocks, and loops, nested inside one another in one file of a hooks module | 2,000 |

415| Command, tool, subagent type, and pane names, and the `id` of a placed row or a backdrop | Letters, digits, `_`, and `-`, up to 64 characters |419| Command, tool, subagent type, and pane names, the `id` of a placed row, and the `scene` of a backdrop | Letters, digits, `_`, and `-`, up to 64 characters |

416| One `claude plugin test` test | 5 seconds unless the test sets `timeoutMs` |420| One `claude plugin test` test | 5 seconds unless the test sets `timeoutMs` |

417 421 

418## Settings and environment variables422## Settings and environment variables


422| Name | Where | What it does |426| Name | Where | What it does |

423| :- | :- | :- |427| :- | :- | :- |

424| `CLAUDE_CODE_PLUGIN_DIRS` | Environment, or `env` in `~/.claude/settings.json` | Plugin directories to load as `--plugin-dir` does, for apps you can't pass a flag to. Absolute paths separated by `:`, or `;` on Windows. |428| `CLAUDE_CODE_PLUGIN_DIRS` | Environment, or `env` in `~/.claude/settings.json` | Plugin directories to load as `--plugin-dir` does, for apps you can't pass a flag to. Absolute paths separated by `:`, or `;` on Windows. |

425| `CLAUDE_CODE_PLUGIN_DIR_WATCH` | Environment | `1` makes a long-running non-interactive session reload `--plugin-dir` mods on save |429| `CLAUDE_CODE_PLUGIN_DIR_WATCH` | Environment | Whether mods reload on save. See the [environment variables reference](https://code.claude.com/docs/en/env-vars.md) for the defaults and values |

426| `prependPlugins`, `appendPlugins` | Managed settings. User settings only on a machine with no managed settings or [`managed-mcp.json`](https://code.claude.com/docs/en/managed-mcp#deploy-managed-mcp-json) file, in a session whose credential isn't a Team or Enterprise `/login`. | Lists of plugin ids, such as `acme-guard@acme-tools`. Mods in `prependPlugins` run before every mod a user installs, and mods in `appendPlugins` run after, in the listed order. See [The order mods run in](https://code.claude.com/docs/en/plugins/mods/events.md#the-order-mods-run-in). |430| `prependPlugins`, `appendPlugins` | Managed settings. User settings only on a machine with no managed settings or [`managed-mcp.json`](https://code.claude.com/docs/en/managed-mcp#deploy-managed-mcp-json) file, in a session whose credential isn't a Team or Enterprise `/login`. | Lists of plugin ids, such as `acme-guard@acme-tools`. Mods in `prependPlugins` run before every mod a user installs, and mods in `appendPlugins` run after, in the listed order. See [The order mods run in](https://code.claude.com/docs/en/plugins/mods/events.md#the-order-mods-run-in). |

427| `allowManagedModsOnly` | Managed settings, as an [option on the built-in guard](https://code.claude.com/docs/en/plugins/mods/admin.md#set-options-on-the-built-in-guard) | Only mods that [count as your organization's](https://code.claude.com/docs/en/plugins/mods/admin.md#install-your-organizations-mods), and mods built into Claude Code, run their hooks. Users' settings hooks keep running. |431| `allowManagedModsOnly` | Managed settings, as an [option on the built-in guard](https://code.claude.com/docs/en/plugins/mods/admin.md#set-options-on-the-built-in-guard) | Only mods that [count as your organization's](https://code.claude.com/docs/en/plugins/mods/admin.md#install-your-organizations-mods), and mods built into Claude Code, run their hooks. Users' settings hooks keep running. |

428| `allowModsToOverrideDenyRules` | Managed settings, as an [option on the built-in guard](https://code.claude.com/docs/en/plugins/mods/admin.md#set-options-on-the-built-in-guard) | Lets a mod a user installed approve a tool call past most of [the outcomes that stay in place by default](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods), including a `deny` rule |432| `allowModsToOverrideDenyRules` | Managed settings, as an [option on the built-in guard](https://code.claude.com/docs/en/plugins/mods/admin.md#set-options-on-the-built-in-guard) | Lets a mod a user installed approve a tool call past most of [the outcomes that stay in place by default](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods), including a `deny` rule |

Details

139 on('ui.render', () => ({ type: 'Text', props: {}, children: ['drawn by Claude Code'] }))139 on('ui.render', () => ({ type: 'Text', props: {}, children: ['drawn by Claude Code'] }))

140 ```140 ```

141 141 

142 With the stub registered, the mount succeeds, and `ui.find({ type: 'Text' })` returns that element whenever your hook returned `next(e)`.142 With the stub registered, the mount succeeds, and `ui.find({ type: 'Text' })` returns that element whenever your hook returned `next(e)`. On v2.1.323 or later, for the band, pass your mod's name as the second argument to `on`, as in `{ plugin: 'my-mod' }`. Without it, the stub doesn't answer your `next(e)`.

143 143 

144* **A stub for `turn.step` is an async generator**, and the test reads the stream to its end to get the result:144* **A stub for `turn.step` is an async generator**, and the test reads the stream to its end to get the result:

145 145 


192| `$.session.id`, `$.agent.list` | `() => ({ value: 'abc123' })`, `() => ({ value: [] })` |192| `$.session.id`, `$.agent.list` | `() => ({ value: 'abc123' })`, `() => ({ value: [] })` |

193| `session.send` | `() => ({ isDelivered: true })`. `e.to` arrives as a string even when your mod passed `{ sessionId }`. |193| `session.send` | `() => ({ isDelivered: true })`. `e.to` arrives as a string even when your mod passed `{ sessionId }`. |

194| `session.receive` | `($, e) => ({ text: e.text })`. Fire it with `$.session.receive({ origin: { kind: 'peer-send-message' }, text })`. |194| `session.receive` | `($, e) => ({ text: e.text })`. Fire it with `$.session.receive({ origin: { kind: 'peer-send-message' }, text })`. |

195| `ui.render` | `() => ({ type: 'Text', props: {}, children: ['...'] })` |195| `ui.render` | `() => ({ type: 'Text', props: {}, children: ['...'] })`. For the band, see the matcher in [Follow the test kit's rules](#follow-the-test-kit’s-rules). |

196 196 

197### Check a result with `expect`197### Check a result with `expect`

198 198 

199The kit has these assertions, and the one you pick goes after the value you're checking, as in `expect(answer.text).toBe('ok')`:199`expect` has its own set of assertions, such as `toEqual` and `toHaveLength`, which go after the value you're checking, as in `expect(answer.text).toBe('ok')`. For the full list, search `claude-code/index.d.ts` in [the types for your build](https://code.claude.com/docs/en/plugins/mods/create.md#get-the-types-for-your-build) for `type Matchers`. Put `.not` before the assertion to check the opposite. To check what a promise settles with, put `.resolves` or `.rejects` right after `expect(...)` and `await` the line, as in `await expect(promise).rejects.toThrow()`.

200 

201* **Equality**: `toBe` for the same value or object, `toEqual` for structure, `toStrictEqual` for structure plus `undefined` fields and the prototype, and `toMatchObject` for the fields you name

202* **Text**: `toMatch`, which takes a regular expression or a substring, `toStartWith`, and `toEndWith`

203* **Numbers**: `toBeGreaterThan`, `toBeGreaterThanOrEqual`, `toBeLessThan`, `toBeLessThanOrEqual`

204* **Contents**: `toContain` for a substring or a member, `toContainEqual` for a member compared by structure, `toHaveLength`, and `toHaveProperty`

205* **Presence and type**: `toBeDefined`, `toBeUndefined`, `toBeNull`, `toBeTruthy`, `toBeFalsy`, `toBeNaN`, `toBeInstanceOf`

206* **Throwing**: `toThrow`, for a function `expect` calls, or for a promise you check with `.rejects`

207 

208Put `.not` in front of an assertion to check the opposite, and `.resolves` or `.rejects` to check what a promise settles with.

209 200 

210When an `expect` fails inside a stub or hook that you passed to `on` as a plain function rather than an async generator, the test fails. The engine skips that hook, and the failure output names it, such as `in the test's store.set hook`.201When an `expect` fails inside a stub or hook that you passed to `on` as a plain function rather than an async generator, the test fails. The engine skips that hook, and the failure output names it, such as `in the test's store.set hook`.

211 202 

Details

223 223 

224### Another mod's band shows and yours doesn't224### Another mod's band shows and yours doesn't

225 225 

226There is one band above the prompt, and every mod shares it. A mod that runs [before yours](https://code.claude.com/docs/en/plugins/mods/events.md#the-order-mods-run-in) replaces your band when it returns a tree without the result of `next(e)` in it. To show both bands, change that mod's hook, or ask its author to:226Each mod that draws above the prompt gets its own row, so when yours is missing while another's shows, check for these causes:

227 227 

228* **Keep the bands after it**: put the result of `await next(e)` among the children of a `Box` in its tree, as in the Band above the prompt tab of [Pick where to draw](https://code.claude.com/docs/en/plugins/mods/interface.md#pick-where-to-draw)228* **Your tree doesn't validate**: [write a debug log](#read-the-debug-log), search it for [`ui.render hook skipped`](#a-pane-or-band-is-empty) or [`does not validate`](#ui-render-refused), and fix what the line names.

229* **Keep the tree valid**: don't give that `Box`, or any `Box` around it, a `width`, `height`, `minWidth`, `minHeight`, `position`, `top`, `left`, `right`, `bottom`, `display`, or `overflow` prop229* **The rows together exceed a limit**: [write a debug log](#read-the-debug-log) and search it for `past the limits of the band`. The rows [share one tree's limits](https://code.claude.com/docs/en/plugins/mods/reference.md#limits), so draw a smaller tree, or ask the other mods' authors to.

230* **Another mod hides or draws over your row**: if the log has none of these lines, [turn off](https://code.claude.com/docs/en/plugins/mods/overview.md#turn-mods-on-or-off) the other mods one at a time. If your row comes back, ask that mod's author to change it.

230 231 

231To 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.232Before v2.1.323, all mods shared one drawing in the band. A mod that ran [before yours](https://code.claude.com/docs/en/plugins/mods/events.md#the-order-mods-run-in) replaced your drawing when it returned a tree without the result of `next(e)` in it. Update Claude Code, or ask that mod's author to make these changes:

232 233 

233A 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).234* **Keep later mods' drawings**: put the result of `await next(e)` among the children of a `Box` in its tree

235* **Keep the tree valid**: don't give that `Box`, or any `Box` around it, a `width`, `height`, `minWidth`, `minHeight`, `position`, `top`, `left`, `right`, `bottom`, `display`, or `overflow` prop

234 236 

235### A pane or band is empty or shows Claude Code's usual content237### A pane or band is empty or shows Claude Code's usual content

236 238 


246 248 

247### A `ui.render` line says `refused`249### A `ui.render` line says `refused`

248 250 

249`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.251`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.

250 252 

251Change 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:253Change 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 rows above the prompt that don't fit the band's limits together, the line reads:

252 254 

253```text theme={null}255```text theme={null}

254hooks: ui.render (AbovePrompt) refused: deeper than 32; nothing was drawn256hooks: ui.render (AbovePrompt) refused: a row past the limits of the band; nothing was drawn

255```257```

256 258 

259Despite that ending, the rows that fit still draw.

260 

257Before 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.261Before 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.

258 262 

259### `needs a key`, `is drawn twice`, or `key each once`263### `needs a key`, `is drawn twice`, or `key each once`


307 311 

308### Hotkeys do nothing312### Hotkeys do nothing

309 313 

310Your pane or band doesn't have keyboard focus, your button is in a collapsed band, or the drawing is in the VS Code extension, where buttons have no hotkeys. Do the one that matches:314Your pane or band doesn't have keyboard focus, your button is in a collapsed band, another mod uses the same key, or the drawing is in the VS Code extension.

311 315 

312* **No keyboard focus**: press Ctrl+X then Tab or, in [fullscreen rendering](https://code.claude.com/docs/en/fullscreen.md), click the pane or band. To have the pane take focus when it opens, open it with `focus: true` from a command.316* **No keyboard focus**: press Ctrl+X then Tab or, in [fullscreen rendering](https://code.claude.com/docs/en/fullscreen.md), click the pane or band. To have the pane take focus when it opens, open it with `focus: true` from a command.

313* **The button is in a collapsed band**: the band shows one dim row that starts with `▸ plugin panel hidden`. Press the keys the row names, Ctrl+X then Ctrl+A by default, to [expand it](#plugin-panel-hidden).317* **The button is in a collapsed band**: the band shows one dim row that starts with `▸ plugin panel hidden`. Press the keys the row names, Ctrl+X then Ctrl+A by default, to [expand it](#plugin-panel-hidden).

314* **In the VS Code extension**: click the button, or press Enter on it once it has focus318* **Another mod's row in the band uses the same hotkey**: in the terminal, the key presses neither button. To check, [turn off](https://code.claude.com/docs/en/plugins/mods/overview.md#turn-mods-on-or-off) the other mods that draw rows, one at a time, until the key works. Change your button's `hotkey`, or ask that mod's author to change theirs.

319* **In the VS Code extension, where buttons have no hotkeys**: click the button, or press Enter on it once it has focus

315 320 

316### A drawing works in the terminal and not in the Desktop app or VS Code321### A drawing works in the terminal and not in the Desktop app or VS Code

317 322 

Details

36 36 

37![Diagram in two columns joined by five straight arrows. Left, the directory of a plugin named my-plugin, holding a manifest at .claude-plugin/plugin.json, skills/review/SKILL.md, agents/reviewer.md, hooks/hooks.json, .mcp.json, and other components. Right, what each file gives you in your session: the manifest sets the plugin name, my-plugin; the skill runs as /my-plugin:review; the agent file is a subagent Claude can delegate to; the hooks file holds hooks that run on lifecycle events; and .mcp.json adds an MCP server that gives Claude tools.](https://mintcdn.com/claude-code/2Q_GtOEovg5qaBem/images/plugin-directory.svg?fit=max\&auto=format\&n=2Q_GtOEovg5qaBem\&q=85\&s=f623b64e82713b830e48174f0a922888)37![Diagram in two columns joined by five straight arrows. Left, the directory of a plugin named my-plugin, holding a manifest at .claude-plugin/plugin.json, skills/review/SKILL.md, agents/reviewer.md, hooks/hooks.json, .mcp.json, and other components. Right, what each file gives you in your session: the manifest sets the plugin name, my-plugin; the skill runs as /my-plugin:review; the agent file is a subagent Claude can delegate to; the hooks file holds hooks that run on lifecycle events; and .mcp.json adds an MCP server that gives Claude tools.](https://mintcdn.com/claude-code/2Q_GtOEovg5qaBem/images/plugin-directory.svg?fit=max\&auto=format\&n=2Q_GtOEovg5qaBem\&q=85\&s=f623b64e82713b830e48174f0a922888)

38 38 

39For every component type a plugin can hold, with an example of each, see [Plugin components](https://code.claude.com/docs/en/plugins/components.md). To see where each piece is located in a plugin's directory, use the [plugin explorer](https://code.claude.com/docs/en/plugins/components.md#explore-the-plugin-directory) on that page.39For component types a plugin can hold, with an example of each, see [Plugin components](https://code.claude.com/docs/en/plugins/components.md). To see where each piece is located in a plugin's directory, use the [plugin explorer](https://code.claude.com/docs/en/plugins/components.md#explore-the-plugin-directory) on that page.

40 40 

41### Decide whether you need a plugin41### Decide whether you need a plugin

42 42 

Details

59 59 

60**5. Fill in the metadata users see**60**5. Fill in the metadata users see**

61 61 

62Set `description`, `author`, `homepage`, and `repository` in `plugin.json`, and add a `README.md` at the plugin root. `homepage` must parse as a URL. The [manifest reference](https://code.claude.com/docs/en/plugins/manifest-reference.md#fields) lists every field.62Set `description`, `author`, `homepage`, and `repository` in `plugin.json`, and add a `README.md` at the plugin root. `homepage` must parse as a URL. For what each field accepts, see the [manifest reference](https://code.claude.com/docs/en/plugins/manifest-reference.md#fields).

63 63 

64**6. Run your eval suite**64**6. Run your eval suite**

65 65 

Details

67> | `--capacity <N>` | Maximum number of concurrent sessions. Default is 32. Cannot be used with `--spawn=session`. |67> | `--capacity <N>` | Maximum number of concurrent sessions. Default is 32. Cannot be used with `--spawn=session`. |

68> | `--[no-]create-session-in-dir` | Pre-create one session in the current directory when the server starts, so you have somewhere to type immediately. In `worktree` mode this session stays in the current directory while on-demand sessions get isolated worktrees. On by default. If you pass `--no-create-session-in-dir` to start with none, Claude Code archives the server's sessions when you stop it, so there's nothing to [resume](#resume-sessions-after-stopping-the-server). |68> | `--[no-]create-session-in-dir` | Pre-create one session in the current directory when the server starts, so you have somewhere to type immediately. In `worktree` mode this session stays in the current directory while on-demand sessions get isolated worktrees. On by default. If you pass `--no-create-session-in-dir` to start with none, Claude Code archives the server's sessions when you stop it, so there's nothing to [resume](#resume-sessions-after-stopping-the-server). |

69> | `--permission-mode <mode>` | Set the starting [permission mode](https://code.claude.com/docs/en/permission-modes.md) for the server's sessions, such as `acceptEdits`. Accepts `manual` as an alias for `default`; an unrecognized mode stops the server at startup and lists the valid modes. |69> | `--permission-mode <mode>` | Set the starting [permission mode](https://code.claude.com/docs/en/permission-modes.md) for the server's sessions, such as `acceptEdits`. Accepts `manual` as an alias for `default`; an unrecognized mode stops the server at startup and lists the valid modes. |

70> | `--settings <file>` | Apply a JSON settings file to the server's sessions, at the same [precedence](https://code.claude.com/docs/en/settings.md#settings-precedence) as `claude --settings`. Give a file path, not a JSON string. Requires Claude Code v2.1.321 or later. |

70> | `--chrome` / `--no-chrome` | Turn [Chrome integration](https://code.claude.com/docs/en/chrome.md) on or off in the sessions the server creates, so Claude can use Chrome on your machine while you work from another device. Without either flag, the session the server pre-creates and any session you start yourself from claude.ai/code or the Claude app begin with Chrome off, even if you [enabled Chrome by default](https://code.claude.com/docs/en/chrome.md#enable-chrome-by-default). A session the server starts for one of your [project](https://code.claude.com/docs/en/claude-projects.md) threads follows that setting instead, except in `bypassPermissions` mode. Requires Claude Code v2.1.273 or later. |71> | `--chrome` / `--no-chrome` | Turn [Chrome integration](https://code.claude.com/docs/en/chrome.md) on or off in the sessions the server creates, so Claude can use Chrome on your machine while you work from another device. Without either flag, the session the server pre-creates and any session you start yourself from claude.ai/code or the Claude app begin with Chrome off, even if you [enabled Chrome by default](https://code.claude.com/docs/en/chrome.md#enable-chrome-by-default). A session the server starts for one of your [project](https://code.claude.com/docs/en/claude-projects.md) threads follows that setting instead, except in `bypassPermissions` mode. Requires Claude Code v2.1.273 or later. |

71> | `-d`, `--debug[=<filter>]` | Turn on debug logging for the server, optionally filtered by category. Pass a filter only in the `=` form, such as `--debug=api,hooks`. Requires Claude Code v2.1.282 or later. |72> | `-d`, `--debug[=<filter>]` | Turn on debug logging for the server, optionally filtered by category. Pass a filter only in the `=` form, such as `--debug=api,hooks`. Requires Claude Code v2.1.282 or later. |

72> | `--debug-file <path>` | Write debug logs to the given file. |73> | `--debug-file <path>` | Write debug logs to the given file. |

73> | `--verbose` | Show detailed connection and session logs. |74> | `--verbose` | Show detailed connection and session logs. |

74> | `--sandbox`, `--no-sandbox` | Removed in v2.1.300. If you pass either flag, the server [exits with an error](https://code.claude.com/docs/en/errors.md#sandbox-is-not-supported-by-claude-remote-control) instead of starting. |75> | `--sandbox`, `--no-sandbox` | Removed in v2.1.300. If you pass either flag, the server [exits with an error](https://code.claude.com/docs/en/errors.md#sandbox-is-not-supported-by-claude-remote-control) instead of starting. |

75>76>

76> If you pass a global `claude` flag before `remote-control`, or a wrapper script adds one, Claude Code doesn't carry the flag over to the sessions the server creates. Claude Code lets the flag through only when dropping it is known not to change what those sessions can do, such as `--verbose` or `--model`. For any other flag, such as `--settings`, Claude Code [refuses to start](https://code.claude.com/docs/en/errors.md#not-carried-over-to-the-sessions-remote-control-starts) and names the flag to remove.77> If you pass a global `claude` flag before `remote-control`, or a wrapper script adds one, Claude Code doesn't carry the flag over to the sessions the server creates. The server still starts with some flags, such as `--verbose` or `--model`. With any other flag, the server [doesn't start](https://code.claude.com/docs/en/errors.md#not-carried-over-to-the-sessions-remote-control-starts). To pass a settings file, put `--settings` after `remote-control`.

77>78>

78> To sandbox the sessions the server starts, turn on [sandboxing](https://code.claude.com/docs/en/sandboxing.md) in a settings file.79> To sandbox the sessions the server starts, turn on [sandboxing](https://code.claude.com/docs/en/sandboxing.md) in a settings file.

79>80>


375* **Forwarded dialogs expire**: Claude Code keeps permission prompts and `AskUserQuestion` questions open until you answer them. When Claude Code forwards another kind of dialog to the remote session, such as the model-choice prompt shown after a safety refusal, it waits five minutes by default, then closes the dialog and continues with the dialog's no-action default. Set [`dialogExpiry`](https://code.claude.com/docs/en/settings-reference#dialogexpiry) to adjust or disable the deadline. Requires Claude Code v2.1.224 or later.376* **Forwarded dialogs expire**: Claude Code keeps permission prompts and `AskUserQuestion` questions open until you answer them. When Claude Code forwards another kind of dialog to the remote session, such as the model-choice prompt shown after a safety refusal, it waits five minutes by default, then closes the dialog and continues with the dialog's no-action default. Set [`dialogExpiry`](https://code.claude.com/docs/en/settings-reference#dialogexpiry) to adjust or disable the deadline. Requires Claude Code v2.1.224 or later.

376* **The Fable usage-credits consent prompt isn't forwarded**: Claude Code shows the mid-session [Fable usage-credits consent prompt](https://code.claude.com/docs/en/model-config.md#fable-and-usage-credits) only where the session runs, not on your device. When the session runs in a terminal and nobody there answers before Claude Code closes the prompt, the turn ends without sending the request; see [The prompt to confirm went unanswered](https://code.claude.com/docs/en/errors.md#the-prompt-to-confirm-went-unanswered).377* **The Fable usage-credits consent prompt isn't forwarded**: Claude Code shows the mid-session [Fable usage-credits consent prompt](https://code.claude.com/docs/en/model-config.md#fable-and-usage-credits) only where the session runs, not on your device. When the session runs in a terminal and nobody there answers before Claude Code closes the prompt, the turn ends without sending the request; see [The prompt to confirm went unanswered](https://code.claude.com/docs/en/errors.md#the-prompt-to-confirm-went-unanswered).

377* **Some commands are local-only**: commands that only run in the terminal interface, such as `/plugin` or `/resume`, work only from the local CLI, whether or not you pass an argument. `/claude-api` is also unavailable when you type it from mobile or web. Claude can still [load that skill on its own](https://code.claude.com/docs/en/skills.md#work-on-claude-api-projects) there. The following work from mobile and web:378* **Some commands are local-only**: commands that only run in the terminal interface, such as `/plugin` or `/resume`, work only from the local CLI, whether or not you pass an argument. `/claude-api` is also unavailable when you type it from mobile or web. Claude can still [load that skill on its own](https://code.claude.com/docs/en/skills.md#work-on-claude-api-projects) there. The following work from mobile and web:

378 * Text-output commands: `/compact`, `/clear`, `/context`, `/usage`, `/exit`, `/usage-credits`, `/recap`, and `/reload-plugins`. `/usage-credits` prints the billing URL instead of opening a browser. `/reload-plugins` works only when the session runs in an interactive terminal; a session without one declines it.379 * Text-output commands: `/compact`, `/clear`, `/context`, `/usage`, `/exit`, `/usage-credits`, `/recap`, and `/reload-plugins`. `/usage-credits` replies in text, such as where to manage usage credits. `/reload-plugins` works only when the session runs in an interactive terminal; a session without one declines it.

379 * `/model`, `/effort`, `/fast`, `/color`, and `/rename`: pass the value as an argument, for example `/model sonnet` or `/effort high`. From mobile and web, `/model` and `/effort` take the argument in place of the terminal picker or slider.380 * `/model`, `/effort`, `/fast`, `/color`, and `/rename`: pass the value as an argument, for example `/model sonnet` or `/effort high`. From mobile and web, `/model` and `/effort` take the argument in place of the terminal picker or slider.

380 * `/mcp`: from the mobile app, returns a text summary of server status instead of opening the picker. On the web, `/mcp` on its own opens a directory of [claude.ai connectors](https://code.claude.com/docs/en/mcp.md#use-mcp-servers-from-claude-ai) instead of returning the summary. The `reconnect`, `enable`, and `disable` [subcommands](https://code.claude.com/docs/en/commands.md#all-commands) work from both when the session runs in an interactive terminal. `/mcp reconnect` with no server name retries every server that has failed or needs authentication. To authorize a claude.ai connector without the picker, see [Authorize a connector again from your shell](#authorize-a-connector-again-from-your-shell).381 * `/mcp`: from the mobile app, returns a text summary of server status instead of opening the picker. On the web, `/mcp` on its own opens a directory of [claude.ai connectors](https://code.claude.com/docs/en/mcp.md#use-mcp-servers-from-claude-ai) instead of returning the summary. The `reconnect`, `enable`, and `disable` [subcommands](https://code.claude.com/docs/en/commands.md#all-commands) work from both when the session runs in an interactive terminal. `/mcp reconnect` with no server name retries every server that has failed or needs authentication. To authorize a claude.ai connector without the picker, see [Authorize a connector again from your shell](#authorize-a-connector-again-from-your-shell).

381 * `/config`: from the mobile app, pass `key=value` to set a setting, or run it with no argument to list the keys you can set. On the web, `/config` opens **Settings > Code** or **Settings > Claude Code** instead.382 * `/config`: from the mobile app, pass `key=value` to set a setting, or run it with no argument to list the keys you can set. On the web, `/config` opens **Settings > Code** or **Settings > Claude Code** instead.

routines.md +1 −1

Details

431 431 

432Each scheduled task uses a [cloud environment](https://code.claude.com/docs/en/cloud-environments.md) that controls network access, environment variables, and setup scripts. The task inherits the environment's network policy on every run.432Each scheduled task uses a [cloud environment](https://code.claude.com/docs/en/cloud-environments.md) that controls network access, environment variables, and setup scripts. The task inherits the environment's network policy on every run.

433 433 

434The **Default** environment uses **Limited** access with **Allow package managers** checked, so its runs reach the [default allowlist](https://code.claude.com/docs/en/cloud-environments.md#default-allowed-domains). A request to a blocked host fails with `403` and `x-deny-reason: host_not_allowed`. MCP connector traffic is routed through Anthropic's servers, so the connectors you add to the task work without adding their hosts to **Allowed domains**. Remove any connectors you don't need under [Connectors](#connectors).434The **Default** environment uses **Limited** access with **Allow package managers** checked, so its runs reach the [default allowlist](https://code.claude.com/docs/en/cloud-environments.md#default-allowed-domains). A request to a blocked host fails with [an error such as a `403` or `ENOTFOUND`](https://code.claude.com/docs/en/errors#host-not-allowed-in-a-cloud-session). MCP connector traffic is routed through Anthropic's servers, so the connectors you add to the task work without adding their hosts to **Allowed domains**. Remove any connectors you don't need under [Connectors](#connectors).

435 435 

436To allow additional domains on one of your own environments, follow these steps. An [organization-shared environment](https://code.claude.com/docs/en/cloud-environments.md#organization-shared-environments) opens read-only here, so an Owner changes its network access from the **Cloud environments** page in [admin settings](https://claude.ai/admin-settings) instead.436To allow additional domains on one of your own environments, follow these steps. An [organization-shared environment](https://code.claude.com/docs/en/cloud-environments.md#organization-shared-environments) opens read-only here, so an Owner changes its network access from the **Cloud environments** page in [admin settings](https://claude.ai/admin-settings) instead.

437 437 

sandboxing.md +5 −3

Details

276 276 

277These paths are enforced at the OS level, so all commands running inside the sandbox, including their child processes, respect them. This is the recommended approach when a tool needs write access to a specific location, rather than excluding the tool from the sandbox entirely with `excludedCommands`.277These paths are enforced at the OS level, so all commands running inside the sandbox, including their child processes, respect them. This is the recommended approach when a tool needs write access to a specific location, rather than excluding the tool from the sandbox entirely with `excludedCommands`.

278 278 

279On Linux and WSL2, an entry for a path that doesn't exist yet has no effect, so create the path first.

280 

279When you define the same filesystem array in multiple [settings scopes](https://code.claude.com/docs/en/settings.md#settings-precedence), Claude Code merges them, combining the paths rather than replacing one scope's array with another's. Claude Code leaves an entry out of the merge when a lock under [Keep developers from widening the policy](#keep-developers-from-widening-the-policy) covers it.281When you define the same filesystem array in multiple [settings scopes](https://code.claude.com/docs/en/settings.md#settings-precedence), Claude Code merges them, combining the paths rather than replacing one scope's array with another's. Claude Code leaves an entry out of the merge when a lock under [Keep developers from widening the policy](#keep-developers-from-widening-the-policy) covers it.

280 282 

281If you exclude a source with [`--setting-sources`](https://code.claude.com/docs/en/cli-reference) on the CLI or [`settingSources`](https://code.claude.com/docs/en/agent-sdk/claude-code-features#control-filesystem-settings-with-settingsources) in the Agent SDK, Claude Code ignores its `sandbox.filesystem` entries, its `Edit` permission rules, and its `Read` deny rules when building the sandbox configuration. Requires Claude Code v2.1.246 or later.283If you exclude a source with [`--setting-sources`](https://code.claude.com/docs/en/cli-reference) on the CLI or [`settingSources`](https://code.claude.com/docs/en/agent-sdk/claude-code-features#control-filesystem-settings-with-settingsources) in the Agent SDK, Claude Code ignores its `sandbox.filesystem` entries, its `Edit` permission rules, and its `Read` deny rules when building the sandbox configuration. Requires Claude Code v2.1.246 or later.


376 378 

377Because turning filesystem isolation off widens what sandboxed commands can do, Claude Code honors `filesystem.disabled` from these settings sources only:379Because turning filesystem isolation off widens what sandboxed commands can do, Claude Code honors `filesystem.disabled` from these settings sources only:

378 380 

379* User settings, managed settings, and the `--settings` CLI flag can set it. Project settings in `.claude/settings.json` and `.claude/settings.local.json` can't, so a checked-out project can't switch filesystem isolation off.381* User settings, managed settings, and the `--settings` CLI flag can set it. Project settings in `.claude/settings.json` and `.claude/settings.local.json` can't set it.

380* When managed settings configure `sandbox.filesystem` at all, or list any `sandbox.credentials.files` entry with `"mode": "deny"`, only managed settings can set the key. This keeps developers from turning filesystem isolation off in such a deployment; to turn it off for everyone, set `"disabled": true` in managed settings.382* When managed settings configure `sandbox.filesystem` at all, or list any `sandbox.credentials.files` entry with `"mode": "deny"`, only managed settings can set the key. To turn filesystem isolation off for everyone, set `"disabled": true` in managed settings.

381* When [`CLAUDE_CODE_SUBPROCESS_ENV_SCRUB`](https://code.claude.com/docs/en/env-vars) is set, Claude Code ignores `filesystem.disabled` from every source, including managed settings, and keeps filesystem isolation on.383* When [`CLAUDE_CODE_SUBPROCESS_ENV_SCRUB`](https://code.claude.com/docs/en/env-vars) is set, Claude Code ignores `filesystem.disabled` from every source, including managed settings.

382 384 

383A [valid](https://code.claude.com/docs/en/settings-reference.md#invalid-credential-entries-in-managed-settings) `mask` entry doesn't lock the key, even when Claude Code [falls back to `deny`](#mask-credential-files) for it at startup. List a path that can't be masked, such as a credential directory, as an explicit `deny` entry in managed settings, which locks the key.385A [valid](https://code.claude.com/docs/en/settings-reference.md#invalid-credential-entries-in-managed-settings) `mask` entry doesn't lock the key, even when Claude Code [falls back to `deny`](#mask-credential-files) for it at startup. List a path that can't be masked, such as a credential directory, as an explicit `deny` entry in managed settings, which locks the key.

384 386 

Details

117 117 

118* **Listener**: the listener is a forward proxy on `127.0.0.1`. The runner starts the listener before registering with the control plane, and exits at startup if the listener can't start.118* **Listener**: the listener is a forward proxy on `127.0.0.1`. The runner starts the listener before registering with the control plane, and exits at startup if the listener can't start.

119* **Proxy variables**: the runner rewrites whichever of `HTTPS_PROXY` and `HTTP_PROXY` you set so that it points at the listener. That rewritten value reaches the runner itself, its lifecycle hooks, and every session it runs.119* **Proxy variables**: the runner rewrites whichever of `HTTPS_PROXY` and `HTTP_PROXY` you set so that it points at the listener. That rewritten value reaches the runner itself, its lifecycle hooks, and every session it runs.

120* **Token rotation**: a rotated token takes effect without a restart. For each connection the listener opens to your proxy, the runner runs your command or reads your file again and adds the result as the header.120* **Token rotation**: when you rotate the token, new connections carry the new one without a runner restart. For each connection the listener opens to your proxy, the runner runs your command or reads your file again and adds the result as the header. A connection that's already open stays usable with the old token until your proxy closes it or the runner exits.

121* **Session environment**: a session reaches your proxy only through the listener. In each session's environment the runner removes `ALL_PROXY`, removes any spelling of `HTTPS_PROXY` or `HTTP_PROXY` that you didn't set, and pins `NO_PROXY` to the runner's own value.121* **Session environment**: a session reaches your proxy only through the listener. In each session's environment the runner removes `ALL_PROXY`, removes any spelling of `HTTPS_PROXY` or `HTTP_PROXY` that you didn't set, and pins `NO_PROXY` to the runner's own value.

122* **Logs**: the runner never logs the header value.122* **Logs**: the runner never logs the header value.

123 123 


840 840 

841### Some sessions don't count as idle841### Some sessions don't count as idle

842 842 

843A session holding a background task that keeps running doesn't count as idle, so `--release-idle-session-min` won't release that session's slot. A session that's waiting on an approval requested from inside a running tool call also doesn't count as idle. Set `--kill-session-after-min` alongside it as a hard backstop.843While a session doesn't count as idle, it keeps its slot past the `--release-idle-session-min` limit, so also set `--kill-session-after-min`.

844 

845A session counts as idle after its turn ends or while its turn waits on its user, but not in cases such as these:

846 

847* Its turn has ended and it isn't waiting on its user, but a background task keeps running

848* Its turn waits on an approval that a non-MCP tool requests while that tool runs

849* Its turn waits on an MCP server's [`elicitation/create` request](https://code.claude.com/docs/en/mcp#respond-to-mcp-elicitation-requests)

844 850 

845`--kill-session-after-min` is a backstop for runaway sessions. On a runner on v2.1.260 or later, a session that reaches the limit isn't terminated outright. The runner gives it a grace window, 15 minutes by default, which you can change with [`SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS`](https://code.claude.com/docs/en/self-hosted-environments-reference#environment-variable-only-settings):851`--kill-session-after-min` is a backstop for runaway sessions. On a runner on v2.1.260 or later, a session that reaches the limit isn't terminated outright. The runner gives it a grace window, 15 minutes by default, which you can change with [`SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS`](https://code.claude.com/docs/en/self-hosted-environments-reference#environment-variable-only-settings):

846 852 

847* If the session is waiting on its user, the runner releases it. If its turn has ended and it holds only background tasks, the runner waits up to 60 seconds for those tasks to finish and then releases it. The session resumes when its user sends their next message.853* If the session is waiting on its user, the runner releases it. If its turn has ended and it holds only background tasks, the runner waits up to 60 seconds for those tasks to finish and then releases it. The session resumes when its user sends their next message.

848* If a turn is still running, the runner waits for the turn to finish, or for the session to next wait on its user, and then releases it.854* If a turn is still running, the runner waits for the turn to finish, or for the session to next wait on its user, and then releases it.

849* If the session is still on the runner when the grace window ends, the runner terminates it, and any running turn's work is lost. A turn waiting on an approval requested from inside a running tool call is one way a session outlasts the window.855* If the session is still on the runner when the grace window ends, the runner terminates it, and any running turn's work is lost. For example, a session can stay on the runner until then if its turn waits on an approval that a non-MCP tool requests while that tool runs. A session can also stay there while its turn waits on an MCP server's `elicitation/create` request.

850 856 

851A released session resumes from a fresh clone, so work it hadn't pushed is gone either way; see [Resumed sessions lose unpushed work](#resumed-sessions-lose-unpushed-work). Before v2.1.260, the runner terminated every session at the limit, after waiting at most the grace window for a running turn to finish.857A released session resumes from a fresh clone, so work it hadn't pushed is gone either way; see [Resumed sessions lose unpushed work](#resumed-sessions-lose-unpushed-work). Before v2.1.260, the runner terminated every session at the limit, after waiting at most the grace window for a running turn to finish.

852 858 

Details

252 252 

253Every other key in the cached `env` block applies at startup. Once the server confirms the payload, and you approve it if it needs [security approval](#security-approval-dialogs), the withheld variables apply for the rest of the session.253Every other key in the cached `env` block applies at startup. Once the server confirms the payload, and you approve it if it needs [security approval](#security-approval-dialogs), the withheld variables apply for the rest of the session.

254 254 

255If your organization needs a proxy to reach `api.anthropic.com`, the withholding only affects the server-delivered `env` block itself: a proxy set in an [endpoint-managed](https://code.claude.com/docs/en/managed-settings.md#delivery-mechanisms) `env` block through MDM or `managed-settings.json`, in the shell environment, or in [user settings](https://code.claude.com/docs/en/settings.md#where-settings-live) reaches the settings fetch. The endpoint-managed source requires Claude Code v2.1.223 or later: the cached server-managed proxy value is withheld until the fetch confirms it, so the endpoint-managed value fills in per key and reaches the fetch itself. Before v2.1.223, use the shell environment or user settings so the proxy applies alongside a cached server payload. The first launch has no cache, so an endpoint-managed source, the shell environment, or user settings is still required for the initial fetch.255If the fetch needs a proxy, set `HTTPS_PROXY` in one of:

256 

257* An [endpoint-managed](https://code.claude.com/docs/en/managed-settings.md#delivery-mechanisms) `env` block through MDM or `managed-settings.json`. This source requires Claude Code v2.1.223 or later. Before v2.1.223, use the shell environment or user settings so the proxy [applies alongside a cached server payload](#per-key-exceptions-across-managed-sources).

258* The shell environment

259* [User settings](https://code.claude.com/docs/en/settings.md#where-settings-live)

260 

261Set `HTTPS_PROXY` even if `ALL_PROXY` already names the proxy.

256 262 

257Claude Code applies most settings updates to running sessions without a restart. Some updates apply only at the next launch, including OpenTelemetry exporter configuration, the `model` key, and the removal of a variable from the `env` block.263Claude Code applies most settings updates to running sessions without a restart. Some updates apply only at the next launch, including OpenTelemetry exporter configuration, the `model` key, and the removal of a variable from the `env` block.

258 264 

settings.md +1 −1

Details

177 177 

178Claude Code watches your settings files and reloads them when they change, so it applies most edits to the running session without a restart, including edits to `permissions`, `hooks`, and credential helpers such as `apiKeyHelper`. Claude Code also loads a settings file you create mid-session if its folder existed when the session started. For the project's `.claude/` folder, it loads the file even when you create the folder in the same session.178Claude Code watches your settings files and reloads them when they change, so it applies most edits to the running session without a restart, including edits to `permissions`, `hooks`, and credential helpers such as `apiKeyHelper`. Claude Code also loads a settings file you create mid-session if its folder existed when the session started. For the project's `.claude/` folder, it loads the file even when you create the folder in the same session.

179 179 

180The reload covers user, project, local, and managed settings, and Claude Code runs the [`ConfigChange` hook](https://code.claude.com/docs/en/hooks#configchange) for each settings-file change it detects, not for managed settings that arrive from MDM or the claude.ai console. Managed settings that arrive through MDM or from the claude.ai console reach a running session on a schedule rather than on save; the [delivery table](https://code.claude.com/docs/en/managed-settings.md#choose-a-delivery-mechanism) gives it per source.180The reload covers user, project, local, and managed settings. Claude Code runs the [`ConfigChange` hook](https://code.claude.com/docs/en/hooks#configchange) for direct edits to settings files, not for managed settings that arrive from MDM or the claude.ai console. Managed settings that arrive through MDM or from the claude.ai console reach a running session on a schedule rather than on save; the [delivery table](https://code.claude.com/docs/en/managed-settings.md#choose-a-delivery-mechanism) gives it per source.

181 181 

182Claude Code reads some keys only once, at session start, so an edit to one of them doesn't reach the running session. Admin-side keys that also wait for a restart, such as `requiredMinimumVersion`, are listed under [where and when a policy applies](https://code.claude.com/docs/en/managed-settings.md#where-and-when-a-policy-applies). The ones you're most likely to edit mid-session:182Claude Code reads some keys only once, at session start, so an edit to one of them doesn't reach the running session. Admin-side keys that also wait for a restart, such as `requiredMinimumVersion`, are listed under [where and when a policy applies](https://code.claude.com/docs/en/managed-settings.md#where-and-when-a-policy-applies). The ones you're most likely to edit mid-session:

183 183 

Details

235| [`strictPluginOnlyCustomization.mcp`](#strictpluginonlycustomization-mcp) | Block [MCP servers](https://code.claude.com/docs/en/mcp.md) from user and project sources | Plugins and skills | Managed |235| [`strictPluginOnlyCustomization.mcp`](#strictpluginonlycustomization-mcp) | Block [MCP servers](https://code.claude.com/docs/en/mcp.md) from user and project sources | Plugins and skills | Managed |

236| [`strictPluginOnlyCustomization.skills`](#strictpluginonlycustomization-skills) | Block [skills](https://code.claude.com/docs/en/skills.md) from user and project sources | Plugins and skills | Managed |236| [`strictPluginOnlyCustomization.skills`](#strictpluginonlycustomization-skills) | Block [skills](https://code.claude.com/docs/en/skills.md) from user and project sources | Plugins and skills | Managed |

237| [`subagentPromptCacheTtl`](#subagentpromptcachettl) | Choose the [prompt cache lifetime](https://code.claude.com/docs/en/prompt-caching.md#cache-lifetime) for subagents and other requests outside the main conversation | Model and responses | Any file |237| [`subagentPromptCacheTtl`](#subagentpromptcachettl) | Choose the [prompt cache lifetime](https://code.claude.com/docs/en/prompt-caching.md#cache-lifetime) for subagents and other requests outside the main conversation | Model and responses | Any file |

238| [`subagentStatusLine`](#subagentstatusline) | Rewrite rows in the [subagent](https://code.claude.com/docs/en/sub-agents.md) task display with your own command | Interface and terminal | Any file |

239| [`switchModelsOnFlag`](#switchmodelsonflag) | Switch models automatically or pause when a [safety classifier](https://code.claude.com/docs/en/model-config.md#ask-before-switching) flags a request | Model and responses | Any file |238| [`switchModelsOnFlag`](#switchmodelsonflag) | Switch models automatically or pause when a [safety classifier](https://code.claude.com/docs/en/model-config.md#ask-before-switching) flags a request | Model and responses | Any file |

240| [`syncClaudeAiPlugins`](#syncclaudeaiplugins) | Stop loading the [plugins enabled on your claude.ai account](https://code.claude.com/docs/en/plugins/loading.md#synced-plugins) and stop downloading new ones | Plugins and skills | User, local, or managed |239| [`syncClaudeAiPlugins`](#syncclaudeaiplugins) | Stop loading the [plugins enabled on your claude.ai account](https://code.claude.com/docs/en/plugins/loading.md#synced-plugins) and stop downloading new ones | Plugins and skills | User, local, or managed |

241| [`syncClaudeAiSkills`](#syncclaudeaiskills) | Stop loading the [skills enabled on your claude.ai account](https://code.claude.com/docs/en/skills.md#how-synced-skills-behave) and stop downloading new ones | Plugins and skills | User, local, or managed |240| [`syncClaudeAiSkills`](#syncclaudeaiskills) | Stop loading the [skills enabled on your claude.ai account](https://code.claude.com/docs/en/skills.md#how-synced-skills-behave) and stop downloading new ones | Plugins and skills | User, local, or managed |


885}884}

886```885```

887 886 

888See [Route all shell commands through the classifier](https://code.claude.com/docs/en/auto-mode-config.md#route-all-shell-commands-through-the-classifier).887This key works differently in a Code Mode session. See [Route all shell commands through the classifier](https://code.claude.com/docs/en/auto-mode-config.md#route-all-shell-commands-through-the-classifier).

889 888 

890### `disableAutoMode`889### `disableAutoMode`

891 890 


1533}1532}

1534```1533```

1535 1534 

1535On Linux and WSL2, an entry for a path that doesn't exist yet has no effect, so create the path first.

1536 

1536Claude Code merges `allowWrite` entries and the paths from your `Edit(...)` allow permission rules across the settings scopes the session loads, leaving out the ones from repository settings while [`permissions.blockReadsOutsideWorkingDirectories`](#sandboxed-commands-under-the-block) is on. [Repository locks](https://code.claude.com/docs/en/sandboxing.md#repository-settings-under-an-admin-required-sandbox) can leave out a repository's entries too. An `allowWrite` entry can't lift a [protected path](https://code.claude.com/docs/en/sandboxing.md#protected-paths).1537Claude Code merges `allowWrite` entries and the paths from your `Edit(...)` allow permission rules across the settings scopes the session loads, leaving out the ones from repository settings while [`permissions.blockReadsOutsideWorkingDirectories`](#sandboxed-commands-under-the-block) is on. [Repository locks](https://code.claude.com/docs/en/sandboxing.md#repository-settings-under-an-admin-required-sandbox) can leave out a repository's entries too. An `allowWrite` entry can't lift a [protected path](https://code.claude.com/docs/en/sandboxing.md#protected-paths).

1537 1538 

1538### `sandbox.filesystem.denyWrite`1539### `sandbox.filesystem.denyWrite`


2453 2454 

2454#### How `env` values interact with your shell2455#### How `env` values interact with your shell

2455 2456 

2456* A value here overwrites the same variable exported in your shell, and when more than one settings file sets a variable, the [highest-precedence](https://code.claude.com/docs/en/settings.md#settings-precedence) one applies. [Variables Claude Code ignores in `env`](#variables-claude-code-ignores-in-env) lists the exceptions for project and local settings.2457* A value here overwrites the same variable exported in your shell, and when more than one settings file sets a variable, the [highest-precedence](https://code.claude.com/docs/en/settings.md#settings-precedence) one applies. [Variables Claude Code ignores in `env`](#variables-claude-code-ignores-in-env) lists the exceptions.

2457* When the Claude Desktop app or a [self-hosted environment](https://code.claude.com/docs/en/self-hosted-environments) runner starts the session, the launch environment it builds takes precedence instead: Claude Code ignores an `env` value from any settings file for a variable the launch environment already sets. The [debug log](https://code.claude.com/docs/en/debug-your-config.md) names each ignored variable.2458* When the Claude Desktop app or a [self-hosted environment](https://code.claude.com/docs/en/self-hosted-environments) runner starts the session, the launch environment it builds takes precedence instead: Claude Code ignores an `env` value from any settings file for a variable the launch environment already sets. The [debug log](https://code.claude.com/docs/en/debug-your-config.md) names each ignored variable.

2458* To cancel a shell export, set the variable to `""`. Claude Code treats an empty value as unset for provider selection, and subprocesses inherit the empty value.2459* To cancel a shell export, set the variable to `""`. Claude Code treats an empty value as unset for provider selection, and subprocesses inherit the empty value.

2459* `NO_COLOR` and `FORCE_COLOR` set here reach only subprocesses. To change Claude Code's own interface colors, set them in your shell before launching `claude`.2460* `NO_COLOR` and `FORCE_COLOR` set here reach only subprocesses. To change Claude Code's own interface colors, set them in your shell before launching `claude`.


2494 * [`CLAUDE_CODE_DISABLE_FILE_MENTIONS`](https://code.claude.com/docs/en/env-vars#variables), which stops Claude Code from expanding `@` mentions of files and directories.2495 * [`CLAUDE_CODE_DISABLE_FILE_MENTIONS`](https://code.claude.com/docs/en/env-vars#variables), which stops Claude Code from expanding `@` mentions of files and directories.

2495 2496 

2496 Before v2.1.251, project and local settings could also set the variables in this list that choose where Claude Code writes its files or that export session content, except `HOME` and `XDG_CONFIG_HOME`. Before v2.1.290, they could also set the dialog timer variables and `CLAUDE_CODE_DISABLE_ATTACHMENTS`.2497 Before v2.1.251, project and local settings could also set the variables in this list that choose where Claude Code writes its files or that export session content, except `HOME` and `XDG_CONFIG_HOME`. Before v2.1.290, they could also set the dialog timer variables and `CLAUDE_CODE_DISABLE_ATTACHMENTS`.

2498* You can turn on [Code Mode](https://code.claude.com/docs/en/code-mode.md) with [`CLAUDE_CODE_EXPERIMENTAL_CODE_MODE`](https://code.claude.com/docs/en/env-vars#variables) from your shell, user settings, or a `--settings` file, and not from managed, project, or local settings. With a `0` in any of the first three or in managed settings, Code Mode stays off whatever you set elsewhere. When managed settings contain a `1`, set your own `1` in user settings, because a `1` in your shell is ignored

2497* Identity variables that Claude Code's hosting environments own, such as `CLAUDE_CODE_REMOTE` and `CLAUDE_CODE_ACCOUNT_UUID`, are ignored from every file.2499* Identity variables that Claude Code's hosting environments own, such as `CLAUDE_CODE_REMOTE` and `CLAUDE_CODE_ACCOUNT_UUID`, are ignored from every file.

2498* [`CLAUDE_CODE_MESSAGING_SOCKET` and `CLAUDE_CODE_MESSAGING_TOKEN`](https://code.claude.com/docs/en/env-vars#variables), which Claude Code exports itself, are ignored from every file. Ignoring the socket variable requires Claude Code v2.1.224 or later, and ignoring the token requires v2.1.228 or later.2500* [`CLAUDE_CODE_MESSAGING_SOCKET` and `CLAUDE_CODE_MESSAGING_TOKEN`](https://code.claude.com/docs/en/env-vars#variables), which Claude Code exports itself, are ignored from every file. Ignoring the socket variable requires Claude Code v2.1.224 or later, and ignoring the token requires v2.1.228 or later.

2499* [`CLAUDE_CODE_PROJECT_DIR_NAME`](https://code.claude.com/docs/en/sessions#name-the-project-directory-yourself), which Claude Code reads from the launch environment only, is ignored from every file; requires v2.1.234 or later.2501* [`CLAUDE_CODE_PROJECT_DIR_NAME`](https://code.claude.com/docs/en/sessions#name-the-project-directory-yourself), which Claude Code reads from the launch environment only, is ignored from every file; requires v2.1.234 or later.


3173 3175 

3174The example needs [`jq`](https://jqlang.org/) installed and runs in a shell. For PowerShell and Git Bash equivalents, see [Windows configuration](https://code.claude.com/docs/en/statusline.md#windows-configuration); for the full setup, see [Manually configure a status line](https://code.claude.com/docs/en/statusline.md#manually-configure-a-status-line).3176The example needs [`jq`](https://jqlang.org/) installed and runs in a shell. For PowerShell and Git Bash equivalents, see [Windows configuration](https://code.claude.com/docs/en/statusline.md#windows-configuration); for the full setup, see [Manually configure a status line](https://code.claude.com/docs/en/statusline.md#manually-configure-a-status-line).

3175 3177 

3176### `subagentStatusLine`

3177 

3178When Claude runs [subagents](https://code.claude.com/docs/en/sub-agents.md), Claude Code lists them in a task display below the prompt, one row per subagent showing `name · description · token count`. This key lets you run your own command to rewrite those rows, for example to show each subagent's context usage as a percentage. On each refresh, Claude Code sends the visible rows as one JSON object on stdin, with a `tasks` array carrying each subagent's `id`, `name`, `status`, `model`, `tokenCount`, and more, and replaces the row for each `id` you write back as a `{"id", "content"}` line. Rows you don't write back keep the default rendering.

3179 

3180* **Scope**: [`Any file`](#scopes). When [`allowManagedHooksOnly`](#allowmanagedhooksonly) is on, or [`disableAllHooks`](#disableallhooks) is set outside managed settings, only the managed settings value runs.

3181* **Type**: object with `type` set to `"command"` and a `command` string

3182* **Default**: unset, so Claude Code renders the default rows

3183 

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

3185{

3186 "subagentStatusLine": {

3187 "type": "command",

3188 "command": "jq -c '.tasks[] | {id, content: \"\\(.name): \\(.tokenCount) tokens\"}'"

3189 }

3190}

3191```

3192 

3193See [Subagent status lines](https://code.claude.com/docs/en/statusline.md#subagent-status-lines).

3194 

3195### `syntaxHighlightingDisabled`3178### `syntaxHighlightingDisabled`

3196 3179 

3197Claude Code colors code by language in the diffs, code blocks, and file previews it shows in the terminal, with its built-in highlighter. Set this key to `true` to show them as plain text instead, for example if the colors clash with your terminal theme or slow a screen reader.3180Claude Code colors code by language in the diffs, code blocks, and file previews it shows in the terminal, with its built-in highlighter. Set this key to `true` to show them as plain text instead, for example if the colors clash with your terminal theme or slow a screen reader.


3648* **Everything else is blocked**: user, project, and local hooks, hooks and mods from other installed plugins, and hooks declared in agent frontmatter. [Mods built into Claude Code](https://code.claude.com/docs/en/plugins/mods/overview.md#mods-built-into-claude-code) keep running. To block only users' mods, set [`allowManagedModsOnly`](https://code.claude.com/docs/en/plugins/mods/admin#set-options-on-the-built-in-guard) instead.3631* **Everything else is blocked**: user, project, and local hooks, hooks and mods from other installed plugins, and hooks declared in agent frontmatter. [Mods built into Claude Code](https://code.claude.com/docs/en/plugins/mods/overview.md#mods-built-into-claude-code) keep running. To block only users' mods, set [`allowManagedModsOnly`](https://code.claude.com/docs/en/plugins/mods/admin#set-options-on-the-built-in-guard) instead.

3649* **Command-sourced plugins are disabled**: Claude Code also disables plugins with a [`command` source](https://code.claude.com/docs/en/plugins/marketplace-reference#command-plugin-source), including plugins force-enabled in managed `enabledPlugins`, unless you set [`disableCommandPluginSources`](#disablecommandpluginsources) to `false` explicitly3632* **Command-sourced plugins are disabled**: Claude Code also disables plugins with a [`command` source](https://code.claude.com/docs/en/plugins/marketplace-reference#command-plugin-source), including plugins force-enabled in managed `enabledPlugins`, unless you set [`disableCommandPluginSources`](#disablecommandpluginsources) to `false` explicitly

3650* **Marketplace `headersHelper` commands are blocked**: Claude Code also blocks marketplace [`headersHelper` commands](https://code.claude.com/docs/en/plugins/host-marketplace#authenticate-archive-downloads) unless [`disableCommandPluginSources`](#disablecommandpluginsources) is explicitly set to `false`, except for a marketplace that managed settings themselves declare. Requires Claude Code v2.1.238 or later3633* **Marketplace `headersHelper` commands are blocked**: Claude Code also blocks marketplace [`headersHelper` commands](https://code.claude.com/docs/en/plugins/host-marketplace#authenticate-archive-downloads) unless [`disableCommandPluginSources`](#disablecommandpluginsources) is explicitly set to `false`, except for a marketplace that managed settings themselves declare. Requires Claude Code v2.1.238 or later

3651* **Status line and file suggestion narrow to managed settings**: Claude Code reads [`statusLine`](https://code.claude.com/docs/en/statusline), [`fileSuggestion`](#filesuggestion), and [`subagentStatusLine`](https://code.claude.com/docs/en/statusline#subagent-status-lines) from managed settings only, following the [status line and file suggestion gates](#status-line-and-file-suggestion-gates)3634* **Status line and file suggestion narrow to managed settings**: Claude Code reads [`statusLine`](https://code.claude.com/docs/en/statusline) and [`fileSuggestion`](#filesuggestion) from managed settings only, following the [status line and file suggestion gates](#status-line-and-file-suggestion-gates)

3652 3635 

3653The [`/goal`](https://code.claude.com/docs/en/goal) command can't run while this key is set, because it depends on hooks.3636The [`/goal`](https://code.claude.com/docs/en/goal) command can't run while this key is set, because it depends on hooks.

3654 3637 


3687 3670 

3688#### Status line and file suggestion gates3671#### Status line and file suggestion gates

3689 3672 

3690Claude Code makes two decisions for `statusLine`, `fileSuggestion`, and `subagentStatusLine`, in this order:3673Claude Code makes two decisions for `statusLine` and `fileSuggestion`, in this order:

3691 3674 

3692* **Off entirely**: when managed settings set `disableAllHooks`, or when the folder isn't trusted under the same [workspace trust rule as hooks in settings files](https://code.claude.com/docs/en/permissions.md#what-runs-before-you-trust-a-folder)3675* **Off entirely**: when managed settings set `disableAllHooks`, or when the folder isn't trusted under the same [workspace trust rule as hooks in settings files](https://code.claude.com/docs/en/permissions.md#what-runs-before-you-trust-a-folder)

3693* **Narrowed to managed settings**: when [`allowManagedHooksOnly`](#allowmanagedhooksonly) is set, when `disableAllHooks` is `true` outside managed settings after [settings precedence](https://code.claude.com/docs/en/hooks.md#disable-or-remove-hooks) applies, or when you start Claude Code with `--safe-mode`3676* **Narrowed to managed settings**: when [`allowManagedHooksOnly`](#allowmanagedhooksonly) is set, when `disableAllHooks` is `true` outside managed settings after [settings precedence](https://code.claude.com/docs/en/hooks.md#disable-or-remove-hooks) applies, or when you start Claude Code with `--safe-mode`


4659 4642 

4660* **Scope**: [`Any file`](#scopes)4643* **Scope**: [`Any file`](#scopes)

4661* **Type**: string, the name of a built-in or custom agent4644* **Type**: string, the name of a built-in or custom agent

4662* **Default**: unset, so the main thread runs as Claude Code's default agent4645* **Default**: unset

4663* **Per-session overrides**: `--agent` takes precedence over this key for one session4646* **Per-session overrides**: `--agent` takes precedence over this key for one session

4664 4647 

4665```json settings.json theme={null}4648```json settings.json theme={null}


4668}4651}

4669```4652```

4670 4653 

4671A plugin's own `settings.json` can also supply this key; see [Ship default settings with your plugin](https://code.claude.com/docs/en/plugins/components.md#default-settings).

4672 

4673### `crossSessionInbound`4654### `crossSessionInbound`

4674 4655 

4675Choose what this session does with [messages arriving from your other Claude Code sessions](https://code.claude.com/docs/en/cross-session-messaging.md#control-inbound-messages). When no value applies, Claude Code decides per message from the two sessions' permission-mode classes.4656Choose what this session does with [messages arriving from your other Claude Code sessions](https://code.claude.com/docs/en/cross-session-messaging.md#control-inbound-messages). When no value applies, Claude Code decides per message from the two sessions' permission-mode classes.


4889 4870 

4890### `agentPushNotifEnabled`4871### `agentPushNotifEnabled`

4891 4872 

4892Allow Claude to send a push notification to your phone when it decides one is worth sending, for example when a long task finishes. In a local session, Claude can send one while [Remote Control](https://code.claude.com/docs/en/remote-control.md) is connected. Appears in `/config` as **Push when Claude decides**. When you change it there, Claude Code also saves the value to your account.4873Allow Claude to send a push notification to your phone when it decides one is worth sending, for example when a long task finishes. In a local session, Claude can send one while [Remote Control](https://code.claude.com/docs/en/remote-control.md) is connected. Appears in `/config` as **Push when Claude decides**.

4893 4874 

4894* **Scope**: [`Any file`](#scopes). Claude Code also reads a value left in `~/.claude.json` by older versions.4875* **Scope**: [`Any file`](#scopes). Claude Code also reads a value left in `~/.claude.json` by older versions.

4895* **Type**: Boolean4876* **Type**: Boolean


4903}4884}

4904```4885```

4905 4886 

4906If you run sessions under a [`claude remote-control`](https://code.claude.com/docs/en/remote-control#start-a-remote-control-session) server, they follow the value saved to your account rather than this key. To change that value, run `/config` in a Claude Code session in your terminal and turn **Push when Claude decides** on or off. If the toggle already shows the value you want, change it and change it back so that Claude Code saves that value to your account.4887You don't receive notifications with this key alone. To set them up, follow the steps in [Mobile push notifications](https://code.claude.com/docs/en/remote-control.md#mobile-push-notifications).

4907 4888 

4908See [Mobile push notifications](https://code.claude.com/docs/en/remote-control.md#mobile-push-notifications).4889If you run sessions under a [`claude remote-control`](https://code.claude.com/docs/en/remote-control#start-a-remote-control-session) server, they follow the value saved to your account rather than this key. To change that value, run `/config` in a Claude Code session in your terminal and turn **Push when Claude decides** on or off. If the toggle already shows the value you want, change it and change it back so that Claude Code saves that value to your account.

4909 4890 

4910### `awaySummaryEnabled`4891### `awaySummaryEnabled`

4911 4892 


5062}5043}

5063```5044```

5064 5045 

5065See [Mobile push notifications](https://code.claude.com/docs/en/remote-control.md#mobile-push-notifications).5046You don't receive notifications with this key alone. To set them up, follow the steps in [Mobile push notifications](https://code.claude.com/docs/en/remote-control.md#mobile-push-notifications).

5066 5047 

5067### `preferredNotifChannel`5048### `preferredNotifChannel`

5068 5049 


5207 5188 

5208* **Scope**: [`Managed`](#scopes). A list that the machine's own admin sources set, MDM policies and managed settings files, keeps applying when server-managed settings also deliver one: a session may then use only the providers on both lists, so a server-managed list can narrow what the machine allows but never widen it. Which machine source's `allowedProviders` counts follows [how Claude Code combines managed sources](https://code.claude.com/docs/en/managed-settings.md#how-claude-code-combines-managed-sources). A list delivered through server-managed settings alone reaches only the sessions that [fetch server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md#platform-availability).5189* **Scope**: [`Managed`](#scopes). A list that the machine's own admin sources set, MDM policies and managed settings files, keeps applying when server-managed settings also deliver one: a session may then use only the providers on both lists, so a server-managed list can narrow what the machine allows but never widen it. Which machine source's `allowedProviders` counts follows [how Claude Code combines managed sources](https://code.claude.com/docs/en/managed-settings.md#how-claude-code-combines-managed-sources). A list delivered through server-managed settings alone reaches only the sessions that [fetch server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md#platform-availability).

5209* **Type**: array of strings, each one of:5190* **Type**: array of strings, each one of:

5210 * `"anthropic"`: the Anthropic API on Anthropic's own host, through a claude.ai or Console sign-in or an API key. Pair it with [`forceLoginMethod`](#forceloginmethod) or [`forceLoginOrgUUID`](#forceloginorguuid) to also restrict the sign-in5191 * `"anthropic"`: the Anthropic API on Anthropic's own host, through a claude.ai or Console sign-in or an API key. Pair it with [`forceLoginMethod`](#forceloginmethod) or [`forceLoginOrgUUID`](#forceloginorguuid) to also restrict the sign-in. Desktop's Cowork [on the user's machine](https://code.claude.com/docs/en/managed-settings.md#where-and-when-a-policy-applies) counts as `"anthropic"` when signed in to claude.ai, so without it in the machine's list, Cowork [is refused at start](https://code.claude.com/docs/en/errors.md#managed-settings-dont-allow-this-api-provider). To let Cowork start, add it, which also opens this list to direct Anthropic sessions.

5211 * `"bedrock"`: [Amazon Bedrock](https://code.claude.com/docs/en/amazon-bedrock.md)5192 * `"bedrock"`: [Amazon Bedrock](https://code.claude.com/docs/en/amazon-bedrock.md)

5212 * `"vertex"`: [Google Cloud's Agent Platform](https://code.claude.com/docs/en/google-vertex-ai.md), formerly Vertex AI5193 * `"vertex"`: [Google Cloud's Agent Platform](https://code.claude.com/docs/en/google-vertex-ai.md), formerly Vertex AI

5213 * `"foundry"`: [Microsoft Foundry](https://code.claude.com/docs/en/microsoft-foundry.md)5194 * `"foundry"`: [Microsoft Foundry](https://code.claude.com/docs/en/microsoft-foundry.md)

setup.md +2 −2

Details

445>445>

446> If `npm --version` prints a version starting with `12` in your shell, follow [Fix an npm 12 install](https://code.claude.com/docs/en/troubleshoot-install.md#fix-an-npm-12-install) instead. Don't install with `sudo`. Claude Code runs npm without `sudo` when it updates itself, so an install that needs `sudo` can't update automatically.446> If `npm --version` prints a version starting with `12` in your shell, follow [Fix an npm 12 install](https://code.claude.com/docs/en/troubleshoot-install.md#fix-an-npm-12-install) instead. Don't install with `sudo`. Claude Code runs npm without `sudo` when it updates itself, so an install that needs `sudo` can't update automatically.

447 447 

448You can also install Claude Code as a global npm package. The npm package requires [Node.js 22 or later](https://nodejs.org/en/download). On an older Node.js version, npm prints an `EBADENGINE` warning during install rather than failing; the install completes and `claude` still runs, since the package downloads a native binary that doesn't use your Node.js at runtime.448You can also install Claude Code as a global npm package. The npm package requires [Node.js 22 or later](https://nodejs.org/en/download). On an older Node.js version, npm by default prints an `EBADENGINE` warning and completes the install rather than failing. The installed `claude` still runs, since the package downloads a native binary that doesn't use your Node.js at runtime.

449 449 

450```bash theme={null}450```bash theme={null}

451npm install -g @anthropic-ai/claude-code451npm install -g @anthropic-ai/claude-code@latest

452```452```

453 453 

454The npm package installs the same native binary as the standalone installer. npm pulls the binary in through a per-platform optional dependency such as `@anthropic-ai/claude-code-darwin-arm64`, and a postinstall step links it into place. The installed `claude` binary does not itself invoke Node.454The npm package installs the same native binary as the standalone installer. npm pulls the binary in through a per-platform optional dependency such as `@anthropic-ai/claude-code-darwin-arm64`, and a postinstall step links it into place. The installed `claude` binary does not itself invoke Node.

skills.md +9 −3

Details

22 22 

23Claude Code includes a set of bundled skills, such as `/doctor`, `/code-review`, `/batch`, `/debug`, `/loop`, and `/claude-api`. Bundled skills are prompt-based: they give Claude detailed instructions and let it orchestrate the work using its tools. Most built-in commands instead execute fixed logic directly.23Claude Code includes a set of bundled skills, such as `/doctor`, `/code-review`, `/batch`, `/debug`, `/loop`, and `/claude-api`. Bundled skills are prompt-based: they give Claude detailed instructions and let it orchestrate the work using its tools. Most built-in commands instead execute fixed logic directly.

24 24 

25You invoke a bundled skill by typing `/` followed by the skill name. Claude invokes some bundled skills automatically when relevant; others, including [`/verify`](#run-and-verify-your-app), run only when you invoke them.25You invoke a bundled skill by typing `/` followed by the skill name. Claude invokes some bundled skills automatically when relevant.

26 26 

27Most bundled skills are available in every session. A few depend on a specific feature: `/workflow-authoring`, for example, is available only when [dynamic workflows](https://code.claude.com/docs/en/workflows.md) are enabled.27Most bundled skills are available in every session. A few depend on a specific feature: `/workflow-authoring`, for example, is available only when [dynamic workflows](https://code.claude.com/docs/en/workflows.md) are enabled.

28 28 


320 320 

321If you create a top-level skills directory that didn't exist when the session started, run [`/reload-skills`](https://code.claude.com/docs/en/commands#all-commands) to pick up the skills you put there. Claude Code isn't watching that directory yet, so run `/reload-skills` again after each later change there.321If you create a top-level skills directory that didn't exist when the session started, run [`/reload-skills`](https://code.claude.com/docs/en/commands#all-commands) to pick up the skills you put there. Claude Code isn't watching that directory yet, so run `/reload-skills` again after each later change there.

322 322 

323Live change detection covers `SKILL.md` text only. For a skill folder that is also a [plugin](https://code.claude.com/docs/en/plugins/loading.md#plugins-shared-through-a-repository), changes to `hooks/`, `.mcp.json`, `agents/`, and `output-styles/` need `/reload-plugins` to take effect.323> [!NOTE]

324>

325> Live change detection covers `SKILL.md` text. For a skill folder that is also a [plugin](https://code.claude.com/docs/en/plugins/loading.md#plugins-shared-through-a-repository), changes to `.mcp.json`, `agents/`, and `output-styles/` need `/reload-plugins` to take effect. Changes to `hooks/` need it too, except a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md)'s module file when it [reloads on its own](https://code.claude.com/docs/en/env-vars.md).

324 326 

325### Remove a skill327### Remove a skill

326 328 


787 789 

788Injected commands never prompt for permission while the skill renders. Claude Code checks each one against your [permission rules](https://code.claude.com/docs/en/permissions.md) first. A command a deny rule matches aborts the invocation with `Shell command permission check failed for pattern "..."`.790Injected commands never prompt for permission while the skill renders. Claude Code checks each one against your [permission rules](https://code.claude.com/docs/en/permissions.md) first. A command a deny rule matches aborts the invocation with `Shell command permission check failed for pattern "..."`.

789 791 

790Outside [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), when a command's permission check returns anything other than allow, Claude Code aborts the invocation with the same error. This includes a rule that would normally ask you. To keep an unmatched command from aborting here, pre-approve it with [`allowed-tools`](#pre-approve-tools-for-a-skill). If your organization restricts permission rules to managed settings, see [When only managed permission rules apply](#when-only-managed-permission-rules-apply). Deny and ask rules still override `allowed-tools`. See [Manage permissions](https://code.claude.com/docs/en/permissions.md#manage-permissions).792Outside [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), when a command's permission check returns anything other than allow, Claude Code aborts the invocation. To keep an unmatched command from aborting, pre-approve it with [`allowed-tools`](#pre-approve-tools-for-a-skill), within these limits:

793 

794* **Deny and ask rules**: a command that one of them matches still aborts. To find the rule, see [Manage permissions](https://code.claude.com/docs/en/permissions.md#manage-permissions).

795* **Managed-only rules**: if `/status` in the session lists the skill under `allowed-tools ignored this session`, see [When only managed permission rules apply](#when-only-managed-permission-rules-apply).

796* **Unverified Git folders**: where a `HEAD` or `.git` file may not be yours, Claude Code ignores `allowed-tools` for a Bash command that contains `git` or that Claude Code can't parse. If you trust the folder, for example your own bare repository's worktree, allow the command with [`/permissions`](https://code.claude.com/docs/en/permissions#manage-permissions) in the session.

791 797 

792In auto mode, a command that would otherwise need your approval doesn't abort the invocation. The skill loads with an instruction telling Claude to run the command first, and Claude's own call then goes through [auto mode's usual checks](https://code.claude.com/docs/en/permission-modes.md#how-the-classifier-evaluates-actions). The invocation still aborts in a [forked skill](#run-skills-in-a-subagent) that sets `agent`, and in a session where Claude doesn't have the [shell tool that runs injected commands](#how-injected-commands-run).798In auto mode, a command that would otherwise need your approval doesn't abort the invocation. The skill loads with an instruction telling Claude to run the command first, and Claude's own call then goes through [auto mode's usual checks](https://code.claude.com/docs/en/permission-modes.md#how-the-classifier-evaluates-actions). The invocation still aborts in a [forked skill](#run-skills-in-a-subagent) that sets `agent`, and in a session where Claude doesn't have the [shell tool that runs injected commands](#how-injected-commands-run).

793 799 

statusline.md +0 −40

Details

1085echo "$dirname [$model]"1085echo "$dirname [$model]"

1086```1086```

1087 1087 

1088## Subagent status lines

1089 

1090The `subagentStatusLine` setting renders a custom row body for each [subagent](https://code.claude.com/docs/en/sub-agents.md) shown in the agent panel below the prompt. Use it to replace the default `name · description · token count` row with your own formatting.

1091 

1092```json theme={null}

1093{

1094 "subagentStatusLine": {

1095 "type": "command",

1096 "command": "~/.claude/subagent-statusline.sh"

1097 }

1098}

1099```

1100 

1101The command runs once per refresh tick and receives all visible subagent rows as a single JSON object on stdin. The input includes the [base hook fields](https://code.claude.com/docs/en/hooks.md#common-input-fields), a `columns` field with the usable row width, and a `tasks` array with one entry per row, described in [Task fields](#task-fields).

1102 

1103Write one JSON line to stdout per row you want to override, in the form `{"id": "<task id>", "content": "<row body>"}`. The `content` string is rendered as-is, including ANSI colors and OSC 8 hyperlinks. Omit a task's `id` to keep the default rendering for that row; emit an empty `content` string to hide it.

1104 

1105The same trust, `disableAllHooks`, and [`allowManagedHooksOnly`](https://code.claude.com/docs/en/settings-reference#allowmanagedhooksonly) gates that apply to `statusLine` apply here. Plugins can ship a default `subagentStatusLine` in their [`settings.json`](https://code.claude.com/docs/en/plugins/manifest-reference#standard-layout), but unlike hooks, plugin values don't run under `allowManagedHooksOnly` even when the plugin is force-enabled in managed settings `enabledPlugins`.

1106 

1107### Task fields

1108 

1109Each entry in the `tasks` array describes one subagent row with the fields below. Fields marked optional are omitted when they have no value, so guard for their absence in your script.

1110 

1111| Field | Type | Description |

1112| :- | :- | :- |

1113| `id` | string | Identifier of the task. Echo it as `id` in the line you write back for this row |

1114| `name` | string, optional | Name the subagent is [addressed by](https://code.claude.com/docs/en/sub-agents.md#subagent-names), when it has one |

1115| `type` | string | Kind of task: `local_agent` |

1116| `agentType` | string | Subagent type the task runs as, such as the built-in [`Explore`](https://code.claude.com/docs/en/sub-agents#built-in-subagents) or a custom `code-reviewer`. Holds the same value that hooks receive as [`agent_type`](https://code.claude.com/docs/en/hooks#subagentstart). Requires Claude Code v2.1.293 or later |

1117| `status` | string | State of the task, such as `running`, `completed`, `failed`, or `killed` |

1118| `description` | string | Short description of the task, such as the one Claude gave when it spawned the subagent |

1119| `label` | string | Short progress summary of the task when Claude Code has one, otherwise the same text as `description` |

1120| `startTime` | number | When the task started, in milliseconds since the Unix epoch |

1121| `model` | string, optional | ID of the resolved model the task runs on. Omitted until the model is resolved |

1122| `effort` | string or number, optional | Reasoning effort set for the subagent in its [definition frontmatter](https://code.claude.com/docs/en/sub-agents.md#supported-frontmatter-fields) or on the individual invocation: `low`, `medium`, `high`, `xhigh`, `max`, or a numeric token budget. This is the configured value, and the effort Claude Code applies can differ when the model doesn't support that level. Omitted when no effort is set |

1123| `contextWindowSize` | number, optional | Context window of `model` in tokens, computed the same way as the main status line's [`context_window.context_window_size`](#context-window-fields), so you can render a per-row percentage from `tokenCount`. Omitted when `model` is |

1124| `tokenCount` | number | Running token count of the subagent, the figure the default row shows |

1125| `tokenSamples` | array of numbers | Up to the last 16 `tokenCount` readings, one per refresh tick, oldest first and ending with the current one |

1126| `cwd` | string | Working directory of the subagent: its own directory when it runs in one, such as an isolated worktree, otherwise the session's working directory |

1127 

1128## Tips1088## Tips

1129 1089 

1130* **Test with mock input**: `echo '{"model":{"display_name":"Opus"},"workspace":{"current_dir":"/home/user/project"},"context_window":{"used_percentage":25},"session_id":"test-session-abc"}' | ./statusline.sh`1090* **Test with mock input**: `echo '{"model":{"display_name":"Opus"},"workspace":{"current_dir":"/home/user/project"},"context_window":{"used_percentage":25},"session_id":"test-session-abc"}' | ./statusline.sh`

Details

26 26 

27| Terminal | Shift+Enter for newline |27| Terminal | Shift+Enter for newline |

28| :- | :- |28| :- | :- |

29| Ghostty, Kitty, iTerm2, WezTerm, Warp, Apple Terminal, Windows Terminal | Works without setup |29| Ghostty, Kitty, iTerm2, WezTerm, Warp, Windows Terminal | Works without setup |

30| Other terminals that support the kitty keyboard protocol, such as foot and Alacritty 0.16 or later | Works without setup. Requires Claude Code v2.1.269 or later |30| Other terminals that support the kitty keyboard protocol, such as foot and Alacritty 0.16 or later | Works without setup. Requires Claude Code v2.1.269 or later |

31| VS Code, Cursor, Devin Desktop, Alacritty before 0.16, Zed | Run `/terminal-setup` once |31| VS Code, Cursor, Devin Desktop, Alacritty before 0.16, Zed | Run `/terminal-setup` once |

32| gnome-terminal, JetBrains IDEs such as PyCharm and Android Studio | Not available; use Ctrl+J or `\` then Enter |32| gnome-terminal, JetBrains IDEs such as PyCharm and Android Studio | Not available; use Ctrl+J or `\` then Enter |

Details

173 173 

174To limit which of these deployment options a managed machine may use, set [`allowedProviders`](https://code.claude.com/docs/en/settings-reference#allowedproviders) in managed settings. For example, `["bedrock"]` allows Amazon Bedrock and nothing else; a Bedrock fleet that also enables the Mantle endpoint lists `"mantle"` too. The entry says which endpoint variables also need a managed `env` pin. Requires Claude Code v2.1.285 or later.174To limit which of these deployment options a managed machine may use, set [`allowedProviders`](https://code.claude.com/docs/en/settings-reference#allowedproviders) in managed settings. For example, `["bedrock"]` allows Amazon Bedrock and nothing else; a Bedrock fleet that also enables the Mantle endpoint lists `"mantle"` too. The entry says which endpoint variables also need a managed `env` pin. Requires Claude Code v2.1.285 or later.

175 175 

176> [!NOTE]

177>

178> With Desktop signed in to claude.ai, a Cowork session on the user's machine counts as [`"anthropic"`](https://code.claude.com/docs/en/settings-reference#allowedproviders). If you leave it out of this list in an MDM policy or managed settings file, that session is refused. With it in, sessions sent to Anthropic directly also pass this list.

179 

176### Use MCP for integrations180### Use MCP for integrations

177 181 

178MCP is a great way to give Claude Code more information, such as connecting to ticket management systems or error logs. Have one central team configure MCP servers and check a `.mcp.json` configuration into the codebase so that all users benefit. [Learn more](https://code.claude.com/docs/en/mcp.md).182MCP is a great way to give Claude Code more information, such as connecting to ticket management systems or error logs. Have one central team configure MCP servers and check a `.mcp.json` configuration into the codebase so that all users benefit. [Learn more](https://code.claude.com/docs/en/mcp.md).

Details

127 127 

128Claude uses `AskUserQuestion` to ask you multiple-choice questions when it needs a decision or a clarification. Answer by picking an option, or type your own text through the `Other` row or the notes field.128Claude uses `AskUserQuestion` to ask you multiple-choice questions when it needs a decision or a clarification. Answer by picking an option, or type your own text through the `Other` row or the notes field.

129 129 

130When you answer by typing your own text, Claude Code relays the answer with neutral wording so Claude follows what you wrote, including a request to wait or explain first.

131 

132### Question auto-continue timeout130### Question auto-continue timeout

133 131 

134Questions stay open until you answer them. If you want a question you leave unanswered to eventually close and let Claude continue without you, set the [`askUserQuestionTimeout`](https://code.claude.com/docs/en/settings-reference#askuserquestiontimeout) setting to `60s`, `5m`, or `10m`, either in your user `settings.json` or from the **Question auto-continue timeout** row in `/config`.132Questions stay open until you answer them. If you want a question you leave unanswered to eventually close and let Claude continue without you, set the [`askUserQuestionTimeout`](https://code.claude.com/docs/en/settings-reference#askuserquestiontimeout) setting to `60s`, `5m`, or `10m`, either in your user `settings.json` or from the **Question auto-continue timeout** row in `/config`.


525 523 

526## Read tool behavior524## Read tool behavior

527 525 

528The Read tool takes a file path and returns the contents with line numbers. Claude is instructed to always pass absolute paths.526The Read tool takes a file path and returns the contents with line numbers.

529 527 

530Reading an empty file returns a notice that the file exists but its contents are empty, and an `offset` past the last line returns a notice giving the file's line count.528Reading an empty file returns a notice that the file exists but its contents are empty, and an `offset` past the last line returns a notice giving the file's line count.

531 529 

Details

995 995 

996These issues apply if you installed Claude Code with `npm install -g` inside WSL. If you used the [native installer](https://code.claude.com/docs/en/setup.md), skip this section. On npm 12, install as [Fix an npm 12 install](#fix-an-npm-12-install) describes.996These issues apply if you installed Claude Code with `npm install -g` inside WSL. If you used the [native installer](https://code.claude.com/docs/en/setup.md), skip this section. On npm 12, install as [Fix an npm 12 install](#fix-an-npm-12-install) describes.

997 997 

998**OS or platform detection issues.** If npm reports a platform mismatch during install, WSL is likely picking up the Windows `npm`. Run `npm config set os linux` first, then install with `npm install -g @anthropic-ai/claude-code --force`. Do not use `sudo`.998**OS or platform detection issues.** If npm reports a platform mismatch during install, run `npm config set os linux` first, then install with `npm install -g @anthropic-ai/claude-code@latest --force`. Do not use `sudo`.

999 999 

1000**`exec: node: not found` when running `claude`.** Your WSL environment is likely using the Windows installation of Node.js. Confirm with `which npm` and `which node`: paths starting with `/mnt/c/` are Windows binaries, while Linux paths start with `/usr/`. To fix this, install Node via your Linux distribution's package manager or via [`nvm`](https://github.com/nvm-sh/nvm).1000**`exec: node: not found` when running `claude`.** Your WSL environment is likely using the Windows installation of Node.js. Confirm with `which npm` and `which node`: paths starting with `/mnt/c/` are Windows binaries, while Linux paths start with `/usr/`. To fix this, install Node via your Linux distribution's package manager or via [`nvm`](https://github.com/nvm-sh/nvm).

1001 1001 


1082 3. Reinstall:1082 3. Reinstall:

1083 1083 

1084 ```bash theme={null}1084 ```bash theme={null}

1085 npm install -g @anthropic-ai/claude-code1085 npm install -g @anthropic-ai/claude-code@latest

1086 ```1086 ```

1087 1087 

1088 If this or step 1 fails with `EACCES`, switch to the native installer instead of rerunning it with `sudo`. Claude Code runs npm without `sudo` when it updates itself, so automatic updates would fail the same way.1088 If this or step 1 fails with `EACCES`, switch to the native installer instead of rerunning it with `sudo`. Claude Code runs npm without `sudo` when it updates itself, so automatic updates would fail the same way.


1093 1093 

1094### npm `ENOTEMPTY` error during update or reinstall1094### npm `ENOTEMPTY` error during update or reinstall

1095 1095 

1096When you run `npm install -g @anthropic-ai/claude-code` over an existing installation, npm can fail while moving the old package directory aside:1096When you run `npm install -g @anthropic-ai/claude-code@latest` over an existing installation, npm can fail while moving the old package directory aside:

1097 1097 

1098```text theme={null}1098```text theme={null}

1099npm error code ENOTEMPTY1099npm error code ENOTEMPTY


1127Then reinstall. On npm 12, follow [Fix an npm 12 install](#fix-an-npm-12-install). Otherwise, run:1127Then reinstall. On npm 12, follow [Fix an npm 12 install](#fix-an-npm-12-install). Otherwise, run:

1128 1128 

1129```bash theme={null}1129```bash theme={null}

1130npm install -g @anthropic-ai/claude-code1130npm install -g @anthropic-ai/claude-code@latest

1131```1131```

1132 1132 

1133Confirm with `claude --version`, which prints a version number such as `2.1.211 (Claude Code)`.1133Confirm with `claude --version`, which prints a version number such as `2.1.211 (Claude Code)`.

vs-code.md +10 −0

Details

202 Thinking blocks you already have stay empty. In responses after the reload, click a block or press `Ctrl+O` to expand them all.202 Thinking blocks you already have stay empty. In responses after the reload, click a block or press `Ctrl+O` to expand them all.

203* **Multi-line input**: press `Shift+Enter` to add a new line without sending. This also works in the "Other" free-text input of question dialogs.203* **Multi-line input**: press `Shift+Enter` to add a new line without sending. This also works in the "Other" free-text input of question dialogs.

204 204 

205### Use or turn off suggested prompts

206 

207After Claude replies, the panel can show a suggested next prompt as gray italic text in the empty prompt box. Each suggestion uses a [short background request](https://code.claude.com/docs/en/interactive-mode.md#prompt-suggestions) that counts toward your plan's usage limits or API costs.

208 

209* **Use the suggestion**: press `Tab` to turn it into editable text, then send it. Pressing `Enter` before you accept it doesn't send the suggestion.

210* **Write your own prompt**: start typing, which hides the suggestion.

211 

212To turn suggestions off, set [`promptSuggestionEnabled`](https://code.claude.com/docs/en/settings-reference#promptsuggestionenabled) to `false` in `~/.claude/settings.json`. You stop seeing them in new conversations, or in open ones after you run **Developer: Reload Window** from the Command Palette. If you set [`CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION`](https://code.claude.com/docs/en/env-vars) to `true`, change it to `false` where you set it, or you keep seeing suggestions.

213 

205### Reference files and folders214### Reference files and folders

206 215 

207Use @-mentions to give Claude context about specific files or folders. When you type `@` followed by a file or folder name, Claude reads that content and can answer questions about it or make changes to it. Claude Code supports fuzzy matching, so you can type partial names to find what you need:216Use @-mentions to give Claude context about specific files or folders. When you type `@` followed by a file or folder name, Claude reads that content and can answer questions about it or make changes to it. Claude Code supports fuzzy matching, so you can type partial names to find what you need:


936| `SSL certificate verification failed` or `Self-signed certificate detected` | [SSL certificate errors](https://code.claude.com/docs/en/errors.md#ssl-certificate-errors) |945| `SSL certificate verification failed` or `Self-signed certificate detected` | [SSL certificate errors](https://code.claude.com/docs/en/errors.md#ssl-certificate-errors) |

937| `Dictation error: WebSocket error:` followed by a certificate error such as `unable to get local issuer certificate`, or `Remote server is not connected` on the Web tab | [Dictation or the Web tab fails behind a TLS-inspecting proxy](#dictation-or-the-web-tab-fails-behind-a-tls-inspecting-proxy) |946| `Dictation error: WebSocket error:` followed by a certificate error such as `unable to get local issuer certificate`, or `Remote server is not connected` on the Web tab | [Dictation or the Web tab fails behind a TLS-inspecting proxy](#dictation-or-the-web-tab-fails-behind-a-tls-inspecting-proxy) |

938| `Claude Code process exited with code 1`, or another code | [Claude Code process exited with code N](https://code.claude.com/docs/en/errors.md#claude-code-process-exited-with-code-n) |947| `Claude Code process exited with code 1`, or another code | [Claude Code process exited with code N](https://code.claude.com/docs/en/errors.md#claude-code-process-exited-with-code-n) |

948| `Claude Code did not finish starting` or `Subprocess initialization did not complete within 60000ms` | [Subprocess initialization did not complete within 60000ms](https://code.claude.com/docs/en/errors.md#subprocess-initialization-did-not-complete-within-60000ms) |

939| `Could not locate the Claude CLI on PATH` | [Could not locate the Claude CLI on PATH](https://code.claude.com/docs/en/errors.md#could-not-locate-the-claude-cli-on-path) |949| `Could not locate the Claude CLI on PATH` | [Could not locate the Claude CLI on PATH](https://code.claude.com/docs/en/errors.md#could-not-locate-the-claude-cli-on-path) |

940| `The connection to Claude Code ended before this message completed` | [The connection to Claude Code ended before this message completed](https://code.claude.com/docs/en/errors.md#the-connection-to-claude-code-ended-before-this-message-completed) |950| `The connection to Claude Code ended before this message completed` | [The connection to Claude Code ended before this message completed](https://code.claude.com/docs/en/errors.md#the-connection-to-claude-code-ended-before-this-message-completed) |

941| `The Claude Code program for this computer, the <build> build, could not be found` | [The Claude Code program for this computer could not be found](https://code.claude.com/docs/en/errors.md#the-claude-code-program-for-this-computer-could-not-be-found) |951| `The Claude Code program for this computer, the <build> build, could not be found` | [The Claude Code program for this computer could not be found](https://code.claude.com/docs/en/errors.md#the-claude-code-program-for-this-computer-could-not-be-found) |

workflows.md +0 −2

Details

75| :- | :- |75| :- | :- |

76| `/deep-research <question>` | Fans out web searches on a question across several angles, fetches and cross-checks the sources it finds, votes on each claim, and returns a cited report with claims that didn't survive cross-checking filtered out. Requires the [WebSearch tool](https://code.claude.com/docs/en/tools-reference.md#websearch-tool-behavior) to be available |76| `/deep-research <question>` | Fans out web searches on a question across several angles, fetches and cross-checks the sources it finds, votes on each claim, and returns a cited report with claims that didn't survive cross-checking filtered out. Requires the [WebSearch tool](https://code.claude.com/docs/en/tools-reference.md#websearch-tool-behavior) to be available |

77 77 

78`/deep-research` runs only when you invoke it.

79 

80[Workflows you save](#save-the-workflow-for-reuse) yourself become commands the same way and appear in `/` autocomplete alongside the bundled ones.78[Workflows you save](#save-the-workflow-for-reuse) yourself become commands the same way and appear in `/` autocomplete alongside the bundled ones.

81 79 

82### Watch the run80### Watch the run