llms.txt@02-Claude-Code-CLI · git:20261024.48b8a60 · 2026-10-24 · sha256 1002b06d7b57a0bc

llms.txt@02-Claude-Code-CLI git:20261024.48b8a60F

Immutable. This exact content never changes and is served at /api/v1/blob/1002b06d7b57a0bc.

# Claude Code CLI

> Every page below, concatenated. Each section gives the page title, its upstream source and its path in this repository.

---

## Use Claude Code with a screen reader - Claude Code Docs

Source: https://code.claude.com/docs/en/accessibility
Path: 02-Claude-Code-CLI/accessibility.md

## On this page

- [Turn on screen reader mode](#turn-on-screen-reader-mode)
  - [Project settings can’t turn on screen reader mode](#project-settings-can%E2%80%99t-turn-on-screen-reader-mode)
- [Turn off screen reader mode](#turn-off-screen-reader-mode)
- [Accessibility settings](#accessibility-settings)
- [What your screen reader hears](#what-your-screen-reader-hears)
  - [Read earlier output without losing your place](#read-earlier-output-without-losing-your-place)
  - [Jump between turns](#jump-between-turns)
- [Answer menus and prompts](#answer-menus-and-prompts)
- [Hear when Claude Code needs you](#hear-when-claude-code-needs-you)
- [Known limitations](#known-limitations)
- [Report an issue](#report-an-issue)

Interface

# Use Claude Code with a screen reader

Copy pageCopy page

Set up Claude Code for screen readers such as VoiceOver and NVDA, plus settings for screen magnifiers, reduced motion, and colorblind-friendly themes.

Copy pageCopy page

Claude Code has a screen reader mode that replaces its visual terminal interface with plain, linear text. Instead of boxes, progress animations, and in-place redraws, Claude Code prints labeled lines that a screen reader such as VoiceOver or NVDA reads in order. You can hold a full conversation, approve tool permissions, and review output end to end. Screen reader mode is opt-in. If you use a screen magnifier, reduced motion, or a colorblind-friendly theme instead of a screen reader, set `CLAUDE_CODE_ACCESSIBILITY`, `prefersReducedMotion`, or `theme` from the [Accessibility settings](#accessibility-settings) table. Screen reader mode adapts the terminal interface only, so you don’t need it in the VS Code extension’s chat panel. On Claude Code v2.1.236 or later, the extension [announces conversation activity to your screen reader](../03-IDE-Integrations/vs-code.md#use-a-screen-reader) there without any setting.


[​](#turn-on-screen-reader-mode)

Turn on screen reader mode

Pick the method that matches how often you use a screen reader:

- For one session: run `claude --ax-screen-reader`.
- For sessions started from one shell: set the `CLAUDE_AX_SCREEN_READER` environment variable to `1`. In Bash or Zsh, run `export CLAUDE_AX_SCREEN_READER=1`. In PowerShell, run `$env:CLAUDE_AX_SCREEN_READER = "1"`. Add that line to your shell profile to keep it for future shells.
- For every session on the machine: add `"axScreenReader": true` to your user [settings file](settings.md). The setting applies in any terminal, including the VS Code integrated terminal.

If you combine methods, Claude Code applies the [`--ax-screen-reader`](cli-reference.md#cli-flags) flag over the [`CLAUDE_AX_SCREEN_READER`](env-vars.md#variables) environment variable, and the variable over the [`axScreenReader`](settings-reference.md#axscreenreader) setting. If you use Claude Code over SSH, set the environment variable or setting on the remote machine where Claude Code runs. The first line Claude Code prints confirms the mode: `[Screen Reader Mode: on via flag]`, `[Screen Reader Mode: on via env]`, or `[Screen Reader Mode: on via settings]`.


[​](#project-settings-can’t-turn-on-screen-reader-mode)

Project settings can’t turn on screen reader mode

The startup line `Screen reader mode is off: project settings can't turn it on` means the project asked for screen reader mode and nothing else turns it on. Claude Code ignores both the `axScreenReader` key and a `CLAUDE_AX_SCREEN_READER` value under `env` in the project’s `.claude/settings.json` and `.claude/settings.local.json`, whatever their value.

- **To turn the mode on**: start Claude Code with `--ax-screen-reader`, set `CLAUDE_AX_SCREEN_READER` to `1` in your shell, or add `"axScreenReader": true` to your user [settings file](settings.md) and restart Claude Code. You don’t need to change the project’s files. Once you turn the mode on, the [confirmation line](#turn-on-screen-reader-mode) appears at startup instead.
- **If you don’t use a screen reader**: you don’t need to do anything. To stop the line from appearing, add `"axScreenReader": false` to your user settings file, or remove the `axScreenReader` key and the `CLAUDE_AX_SCREEN_READER` variable from the project’s settings files.


[​](#turn-off-screen-reader-mode)

Turn off screen reader mode

Reverse whichever method turned the mode on: start without the flag, unset the environment variable, or set `axScreenReader` to `false` in your user settings file. If you set `CLAUDE_AX_SCREEN_READER` to `0`, Claude Code keeps the mode off even when the setting is `true`.


[​](#accessibility-settings)

Accessibility settings

The table lists each accessibility option, whether you set it as a flag, an environment variable, or a setting, and what it changes.

| Option                                                                       | Type                 | What it changes                                                                                                                                                                                                                                          |
|:-----------------------------------------------------------------------------|:---------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`--ax-screen-reader`](cli-reference.md#cli-flags)                     | Flag                 | Screen reader mode for one session.                                                                                                                                                                                                                      |
| [`CLAUDE_AX_SCREEN_READER`](env-vars.md#variables)                     | Environment variable | Screen reader mode for sessions started from the shell where you set it.                                                                                                                                                                                 |
| [`axScreenReader`](settings-reference.md#axscreenreader)               | Setting              | Screen reader mode for every session when `true`.                                                                                                                                                                                                        |
| [`CLAUDE_AX_STARTUP_QUIET_MS`](env-vars.md#variables)                  | Environment variable | How long Claude Code waits after the confirmation line before it draws the first prompt in screen reader mode. Requires Claude Code v2.1.217 or later.                                                                                                   |
| [`CLAUDE_AX_PREPARK_MS`](env-vars.md#variables)                        | Environment variable | When you set it, how many milliseconds Claude Code holds the terminal cursor at the start of the current line before writing a new or changed line in screen reader mode. Requires Claude Code v2.1.233 or later.                                        |
| [`CLAUDE_CODE_ACCESSIBILITY`](env-vars.md#variables)                   | Environment variable | A terminal cursor that stays visible for screen magnifiers such as macOS Zoom when you set it to `1`. The cursor follows the input caret and, on Claude Code v2.1.218 or later, the highlighted row in menus and panels such as `/config` and `/plugin`. |
| [`prefersReducedMotion`](settings-reference.md#prefersreducedmotion)   | Setting              | Reduced or no spinners, shimmer, and other animations when `true`.                                                                                                                                                                                       |
| [`theme`](settings-reference.md#theme)                                 | Setting              | The interface colors, including the colorblind-friendly `dark-daltonized` and `light-daltonized` themes. You can also pick one with [`/theme`](commands.md#all-commands).                                                                          |
| [`preferredNotifChannel`](settings-reference.md#preferrednotifchannel) | Setting              | With the value `"terminal_bell"`, a terminal bell outside screen reader mode when Claude is waiting on you.                                                                                                                                              |


[​](#what-your-screen-reader-hears)

What your screen reader hears

In screen reader mode, Claude Code writes flat text:

- No box-drawing characters for the interface chrome
- No color-only cues
- No redraws of content that hasn’t changed. Progress spinners render as static text
- Tables in Claude’s replies read as `Header: value` sentences instead of a box-character grid
- Diffs read as plain text, line by line with `+` and `-` marking added and removed lines, so you can hear the proposed change in a file edit approval prompt before you answer it

Claude Code leaves everything it prints in your terminal’s scrollback, so you can re-read earlier turns with your screen reader’s review commands or your terminal’s search. Claude Code ignores the [`tui` setting](settings-reference.md#tui) in screen reader mode. Apart from the attached background sessions listed under [Known limitations](#known-limitations), it prints scrolling text instead of [fullscreen rendering](fullscreen.md). After Claude Code prints the [confirmation line](#turn-on-screen-reader-mode) at startup, it waits 3 seconds before it draws the prompt, so your screen reader can finish the line. Press any key to end the wait. To change the length of the wait, set [`CLAUDE_AX_STARTUP_QUIET_MS`](env-vars.md#variables). Each message in the transcript starts with a label your screen reader announces, naming what it is: your messages, Claude’s replies and thinking, tool activity, errors and warnings, and prompts. The labels are also searchable, so you can jump between sections of the transcript by searching your terminal’s scrollback:

| Label                  | Meaning                                                                                        |
|:-----------------------|:-----------------------------------------------------------------------------------------------|
| `you:`                 | Your messages                                                                                  |
| `claude:`              | Claude’s replies                                                                               |
| `thinking:`            | Claude’s thinking                                                                              |
| `tool:`                | Tool activity, such as a file edit or a command run                                            |
| `tool error:`          | A tool that failed                                                                             |
| `error:`               | An error in the conversation, such as a failed API request                                     |
| `warning:`             | A warning from Claude Code, such as a switch to a fallback model                               |
| `Permission Required:` | A permission prompt waiting for your answer                                                    |
| `Cost:`                | The session cost summary when Claude Code exits, if your account [shows costs](../17-Billing-Plans/costs.md) |

Claude Code keeps the terminal cursor on the input caret, so your screen reader’s read-current-line command reads the prompt you’re editing. As you type at the end of the input line, or press `Backspace` there, Claude Code writes only the characters that change. Your screen reader echoes only those characters. When you delete a word or a line with one of the [text editing shortcuts](interactive-mode.md#text-editing), Claude Code announces the deleted text:

- Deleting words with `Ctrl+W` or `Alt+D`, or with `Option+Delete` on macOS or `Ctrl+Backspace` on Windows
- Deleting to the start of the line with `Ctrl+U` or `Cmd+Backspace`
- Deleting to the end of the line with `Ctrl+K`

When you cycle [permission modes](permission-modes.md) with `Shift+Tab`, Claude Code announces the permission mode you land on, such as `[plan mode on]` or `[accept edits on]`. Claude Code prints the announcement once and doesn’t repeat it on later redraws.


[​](#read-earlier-output-without-losing-your-place)

Read earlier output without losing your place

If your screen reader jumps back to the prompt while you’re reading earlier output, it’s following the terminal cursor. Claude Code moves the terminal cursor back to the prompt each time it writes new text. To keep your place while you read, stop your screen reader from following the terminal cursor. In NVDA, press `NVDA+6` to stop the review cursor from following the terminal cursor. Press `NVDA+6` again to turn following back on.


[​](#jump-between-turns)

Jump between turns

Claude Code emits OSC 133 shell-integration markers at turn boundaries, so your terminal’s jump-to-previous-prompt key moves between turns without reading through the whole transcript:

- iTerm2: Cmd+Shift+Up
- VS Code terminal: Ctrl+Up on Windows, Cmd+Up on macOS
- Windows Terminal: no key by default; bind the `scrollToMark` action in its settings
- Kitty and Ghostty: check the terminal’s documentation for its jump-to-prompt key

macOS Terminal doesn’t act on the markers, and Claude Code doesn’t emit them in WezTerm. In those terminals, search the scrollback for the `you:` label instead.


[​](#answer-menus-and-prompts)

Answer menus and prompts

In screen reader mode, menus you’d normally navigate with the arrow keys, including permission prompts, become numbered lists. Claude Code announces each option as a numbered line, then a `Select with numbers` prompt that names the valid range. Type the number of the option you want and press Enter.

- Press Escape to cancel a menu whose prompt ends with `or Escape to cancel`.
- If you type a number that isn’t on the list, Claude Code announces the valid range and lets you try again.

The [`/effort`](model-config.md#adjust-effort-level) selector, which is a slider outside screen reader mode, becomes the same kind of numbered list. Yes-or-no prompts ask for a typed answer instead of a two-option menu. Answer `y` or `n` and press Enter. `yes` and `no` also work.


[​](#hear-when-claude-code-needs-you)

Hear when Claude Code needs you

In screen reader mode, Claude Code rings the terminal bell when it needs your attention, so you don’t have to keep checking the transcript. The bell rings when:

- Claude finishes a reply
- A prompt or dialog needs your answer, such as a permission prompt
- A tool that ran longer than 5 seconds finishes

The bell is your terminal’s standard alert. To silence it, change the bell setting in your terminal application. Outside screen reader mode, set [`preferredNotifChannel`](settings-reference.md#preferrednotifchannel) to `"terminal_bell"` to get a [similar bell](terminal-config.md#get-a-terminal-bell-or-notification) when Claude is waiting on you.


[​](#known-limitations)

Known limitations

Some behaviors aren’t adapted for screen reader mode:

- Screen reader mode doesn’t turn on automatically when a screen reader is running.
- Claude Code doesn’t announce a permission mode change you make with a command, such as entering [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode) with `/plan`.
- Attaching to a [background session](../09-Agents-Patterns/agent-view.md) with `claude attach` or from agent view enters the terminal’s alternate screen, which has no native scrollback. This is the [same behavior as other attached sessions](fullscreen.md). To get back out, press Left Arrow on an empty prompt, or Ctrl+Z if a dialog has focus.
- Claude Code announces costs in the summary it prints at exit, not per turn.
- Screen reader mode doesn’t change [non-interactive mode](headless.md) with the `-p` flag. Non-interactive mode already writes plain text and remains an alternative for scripting.


[​](#report-an-issue)

Report an issue

If something doesn’t work with your screen reader, magnifier, or terminal, open an issue on the [Claude Code issue tracker](https://github.com/anthropics/claude-code/issues) and mention your assistive technology in the title. Include your operating system, terminal application, and assistive technology name and version in the report.

---

## Escalate hard decisions with the advisor tool - Claude Code Docs

Source: https://code.claude.com/docs/en/advisor
Path: 02-Claude-Code-CLI/advisor.md

## On this page

- [When to use the advisor](#when-to-use-the-advisor)
- [Enable the advisor](#enable-the-advisor)
  - [Use the /advisor command](#use-the-%2Fadvisor-command)
  - [Set advisorModel in settings](#set-advisormodel-in-settings)
  - [Use the --advisor flag](#use-the-advisor-flag)
- [Choose an advisor model](#choose-an-advisor-model)
  - [Fable advisor and usage credits](#fable-advisor-and-usage-credits)
  - [Common model pairings](#common-model-pairings)
- [When Claude consults the advisor](#when-claude-consults-the-advisor)
- [What you see during a session](#what-you-see-during-a-session)
- [Cost](#cost)
- [Impact on prompt caching](#impact-on-prompt-caching)
- [Requirements](#requirements)
- [Turn the advisor off](#turn-the-advisor-off)
- [Compare with related features](#compare-with-related-features)
- [See also](#see-also)

Model and responses

# Escalate hard decisions with the advisor tool

Copy pageCopy page

Pair your main model with a stronger advisor model that Claude consults at key moments during a task.

Copy pageCopy page

The advisor tool is experimental and requires the Anthropic API. It is not available on Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, or Microsoft Foundry. Behavior, pricing, and availability may change.

The advisor tool lets Claude consult a second, typically stronger model at key moments during a task, such as before committing to an approach, when stuck on a recurring error, or before declaring a task complete. The advisor receives the full conversation, including every tool call and result, and returns guidance that Claude applies before continuing. The advisor runs server-side on Anthropic’s infrastructure as a [server tool](../04-API-Reference/Agents-Tools/agents-and-tools-tool-use-advisor-tool.md), available to both subscription and API-billed accounts. You choose which model acts as the advisor, and Claude decides when to call it. This page covers how to enable the advisor, which model pairings are accepted, what Claude shows during a consultation, and how advisor usage is billed.


[​](#when-to-use-the-advisor)

When to use the advisor

The advisor fits long, multi-step tasks where most turns are routine but plan quality determines the outcome. Examples include large refactors, debugging sessions where an error keeps recurring, and tasks you want independently checked before Claude declares them done. It adds less value on short tasks where there is little to plan, or on work where every turn needs the strongest model. For those, [switch the main model](model-config.md#setting-your-model) instead, or see [how the advisor compares with opusplan and subagents](#compare-with-related-features) for other ways to get a second opinion.


[​](#enable-the-advisor)

Enable the advisor

You can set the advisor model in three ways:

- **`/advisor` command**: set or change the advisor mid-session and save it as your default
- **`advisorModel` setting**: configure a persistent default in your [settings file](settings.md)
- **`--advisor` flag**: set the advisor for a single session at launch

Each of these enables the advisor for sessions whose main model [supports it](#choose-an-advisor-model). After the session starts, Claude Code shows an `Advisor Tool (experimental) is on and may use more tokens · /advisor` notification. To stop using the advisor, see [Turn the advisor off](#turn-the-advisor-off). On some plans, Fable as the advisor also needs your one-time [consent to bill Fable usage to usage credits](model-config.md#fable-and-usage-credits). For what happens before you have given that consent, see [Fable advisor and usage credits](#fable-advisor-and-usage-credits).


[​](#use-the-/advisor-command)

Use the `/advisor` command

Run `/advisor` without arguments to open a picker listing the available advisor models, or pass the model directly:

```python
/advisor opus
```

The command confirms with `Advisor set to` followed by the advisor model name. Your selection is saved to `advisorModel` in your user settings and persists across sessions, except in the cases the [`advisorModel` entry](settings-reference.md#advisormodel) lists as applying to the current session only. The command also works where there is no terminal picker: in [non-interactive mode](headless.md) with `-p`, in the Agent SDK, in the desktop app, and over [Remote Control](remote-control.md). This requires Claude Code v2.1.260 or later. On those surfaces:

- Run `/advisor` with no argument to print the current advisor model and the aliases it accepts.
- Run `/advisor` with a model, such as `/advisor opus`, to set it.
- Run `/advisor off` to turn it off.

Claude Code doesn’t invoke a saved advisor that your organization’s [`availableModels`](model-config.md#restrict-model-selection) allowlist excludes. To use the advisor, pick an allowed model with `/advisor`. Claude Code still saves an advisor that your current main model doesn’t support. That advisor activates after you switch to a [compatible main model](#choose-an-advisor-model) with [`/model`](model-config.md#setting-your-model). If the API already refused the saved advisor in the current conversation, it stays off until `/clear` or `/compact`, even after you switch models. On some plans, Fable as the advisor also needs your one-time [consent to bill Fable usage to usage credits](model-config.md#fable-and-usage-credits). For what `/advisor fable` does before you have given that consent, see [Fable advisor and usage credits](#fable-advisor-and-usage-credits).


[​](#set-advisormodel-in-settings)

Set `advisorModel` in settings

To configure the advisor as a default without opening a session, set it in your settings file:

```python
{
  "advisorModel": "opus"
}
```


[​](#use-the-advisor-flag)

Use the `--advisor` flag

To set the advisor for a single session without changing your saved setting, launch with the flag:

```python
claude --advisor opus
```

Claude Code uses the flag instead of the `advisorModel` setting for that session. It doesn’t list `--advisor` in `claude --help`. Claude Code exits with an error at launch if:

- The session’s main model doesn’t support the advisor
- The requested model, such as Haiku 4.5, can’t act as an advisor
- Your organization’s [`availableModels`](model-config.md#restrict-model-selection) allowlist excludes the requested model
- You requested Fable and your account still requires the [usage-credits consent](#fable-advisor-and-usage-credits)

If you start a [background session](../09-Agents-Patterns/agent-view.md) with `--advisor` and one of these applies, Claude Code starts the session without the advisor instead of exiting. If the model you pass can act as an advisor but [ranks below your main model](#choose-an-advisor-model), the session starts whether or not it’s a background session. Your main model then runs without the advisor.


[​](#choose-an-advisor-model)

Choose an advisor model

Claude Code ranks models by capability for the advisor role, and an advisor must rank at or above your session’s main model. Rows run from the lowest-ranked main model to the highest:

| Main model            | Accepted advisors                                      |
|-----------------------|--------------------------------------------------------|
| Haiku 4.5             | Fable, Opus, Sonnet, Haiku 5.5                         |
| Sonnet 4.6            | Fable, Opus, Sonnet, Haiku 5.5                         |
| Opus 4.6              | Fable, Opus, Sonnet 5 or later, Haiku 5.5              |
| Sonnet 5 or Haiku 5.5 | Fable, Opus 4.7 or later, Sonnet 5 or later, Haiku 5.5 |
| Opus 4.7 or Opus 4.8  | Fable, Opus 4.7 or later, Sonnet 5.5                   |
| Sonnet 5.5            | Fable, Opus 5 or later, Sonnet 5.5                     |
| Opus 5 or Opus 5.5    | Fable, Opus 5 or later                                 |
| Fable 5               | Fable 5.1 or Fable 5                                   |
| Fable 5.1             | Fable 5.1                                              |

Fable 5.1 requires Claude Code v2.1.257 or later. Fable models require [Fable access](model-config.md#work-with-fable). Sonnet 5.5 as the advisor for an Opus 4.7 or Opus 4.8 main model requires Claude Code v2.1.287 or later. Haiku 5.5 as the main model or as the advisor requires Claude Code v2.1.293 or later. Set the advisor as `fable`, `opus`, or `sonnet`. These aliases resolve to Claude Code’s [built-in default version](model-config.md#model-aliases) for each model family, which advances with new Claude Code releases. You can also pass a full model ID such as `claude-opus-5-5` or `claude-haiku-5-5`. Haiku 4.5 can call the advisor but can’t act as one. Subagents inherit the configured advisor and apply the same pairing check against their own model. Claude Code validates the pairing before sending a request, and the API validates it again:

- For an advisor that ranks below the main model, Claude Code doesn’t attach it to the main model’s requests. The `/advisor` command output and a notification show this; see [Advisor is less capable than the current main model](errors.md#advisor-is-less-capable-than-the-current-main-model). Subagents whose own model satisfies the pairing may still use the advisor.
- If the API refuses the pairing of an advisor that Claude Code attached, Claude Code resends that request without the advisor. The conversation continues without one, so you see no error and get no advisor calls. If you then pick a different advisor with `/advisor`, it takes effect after `/clear` or `/compact` and in new sessions.
- If the main model or the advisor is a model Claude Code does not recognize, the advisor is not attached.


[​](#fable-advisor-and-usage-credits)

Fable advisor and usage credits

On some plans, Fable usage bills to usage credits, and Fable as the advisor bills the same way. If your account requires the [one-time consent to bill Fable usage to usage credits](model-config.md#fable-and-usage-credits), Claude Code asks for it when you select a Fable model with `/model` and doesn’t apply Fable as the advisor until you have accepted that consent. Before you have accepted it, Claude Code doesn’t save Fable as the advisor when you type `/advisor fable` or pick Fable in the `/advisor` picker. It points you to `/model fable` instead. With `claude --advisor fable`, Claude Code exits at launch with a message that points to `/model fable`. In a [background session](#use-the-advisor-flag), it starts the session without the advisor instead of exiting. With Fable already saved as your `advisorModel`, Claude Code sends requests without the advisor. In an interactive session whose main model supports the advisor, it also shows a notification that points to `/model fable`. To accept the consent, run `/model fable` and choose to continue on Fable. Claude Code records the consent and [saves Fable as your selected model](model-config.md#default-model-setting). Then select Fable as the advisor.


[​](#common-model-pairings)

Common model pairings

Any accepted pairing works. These combinations balance cost against capability in different ways:

| Pairing                      | When to use                                                                                                                                |
|------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| Sonnet main + Opus advisor   | Sonnet handles routine work and escalates planning, ambiguous failures, and completion checks to Opus                                      |
| Sonnet main + Fable advisor  | Fable guidance at decision points without running Fable throughout. Requires Fable access                                                  |
| Haiku main + Opus advisor    | Lowest-cost main model with strong planning. Expect higher cost than Haiku alone but lower than switching the main model to Sonnet or Opus |
| Opus main + Opus advisor     | A second Opus reviews the first. Useful for high-stakes tasks where an independent check matters more than cost                            |
| Fable main + Fable advisor   | Highest-capability pairing when Fable is available. Claude Code doesn’t apply an Opus or Sonnet advisor to a Fable main model              |
| Sonnet main + Sonnet advisor | A lower-cost second opinion for catching routine oversights                                                                                |


[​](#when-claude-consults-the-advisor)

When Claude consults the advisor

Claude decides when to call the advisor. It tends to consult before committing to an approach, when an error keeps recurring, and before declaring a task done, but the timing is model-driven rather than rule-based. You can ask for a consultation in your prompt the same way you would request any tool, for example `consult the advisor before you continue`. There is no setting to cap or force advisor calls; if you want Claude to consult more or less often during a task, say so in your instructions.


[​](#what-you-see-during-a-session)

What you see during a session

When Claude calls the advisor, the transcript shows an `Advising` line with the advisor model name while the call is in progress. When the result returns, the line reports whether the advisor gave guidance:

- **Reviewed**: the line confirms that the advisor has reviewed the conversation. When the advisor returned readable guidance, press `Ctrl+O` to read it.
- **Declined**: the line reads `Advisor declined to advise on this request`. If the advisor gave a reason, press `Ctrl+O` to read it.
- **Unavailable**: the advisor call failed, and the line reads `Advisor unavailable (<error_code>)`, where `<error_code>` is the code the call returned.

Claude generally follows the advisor’s guidance, but adapts when its own evidence contradicts a specific claim: if a recommended step fails when tried, or the file contents contradict the advice, Claude surfaces the conflict rather than following the guidance unconditionally. The advisor always receives the full conversation, and Claude controls the timing. For more control or a different configuration, see [how the advisor compares with subagents and opusplan](#compare-with-related-features).


[​](#cost)

Cost

When Claude calls the advisor, the advisor model reads the conversation, so each call consumes tokens at the advisor model’s rates in addition to your main model’s usage. How those advisor tokens are billed depends on how you pay:

- **API billing**: you pay the advisor model’s input and output rates for advisor tokens
- **Subscription plans**: advisor usage counts toward your plan’s usage limits, except that a Fable advisor bills to [usage credits](model-config.md#fable-and-usage-credits) on plans where Fable usage does

If your account requires the usage-credits consent, a Fable advisor bills nothing before you give it, because Claude Code [doesn’t apply the selection](#fable-advisor-and-usage-credits) until then. Claude calls the advisor at decision points rather than on every turn, so pairing a faster main model with a stronger advisor typically costs less than running the stronger model throughout. Advisor usage counts toward the session totals shown by [`/usage`](../17-Billing-Plans/costs.md#track-your-costs). For how advisor tokens are reported in API responses, see [Usage and billing](../04-API-Reference/Agents-Tools/agents-and-tools-tool-use-advisor-tool.md#usage-and-billing) in the Claude API documentation.


[​](#impact-on-prompt-caching)

Impact on prompt caching

Enabling or disabling the advisor mid-session does not invalidate your main model’s [prompt cache](prompt-caching.md). Unlike [switching models](prompt-caching.md#switching-models), toggling `/advisor` keeps the cached prefix intact, and the advisor’s returned guidance is cached as part of the transcript on later turns. The advisor model’s own read of the conversation is not cached. Each advisor call processes the full transcript anew, with no reuse between calls.


[​](#requirements)

Requirements

The advisor tool requires all of the following:

- **Anthropic API only**: the advisor is a server-executed tool. It is not available on Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, or Microsoft Foundry. Through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) configured with `ANTHROPIC_BASE_URL`, availability depends on whether the gateway forwards the request intact to the Anthropic API. If the gateway or its upstream doesn’t recognize the advisor tool, see [Automatic retry and error forwarding](../13-Enterprise-Admin/llm-gateway-protocol.md#automatic-retry-and-error-forwarding) for how Claude Code responds.
- **Supported main model**: Fable, Opus 4.6 or later, Sonnet 4.6 or later, Haiku 4.5, or Haiku 5.5. See [Choose an advisor model](#choose-an-advisor-model) for which advisors each accepts.
- **Feature-flag fetching**: Claude Code turns the advisor on through a feature flag it fetches from Anthropic. In a session where a variable that turns flag fetching off is set, such as `DISABLE_TELEMETRY`, the advisor stays off. See [Features that need feature-flag fetching](env-vars.md#features-that-need-feature-flag-fetching).


[​](#turn-the-advisor-off)

Turn the advisor off

To stop using the advisor, run `/advisor off` or choose **No advisor** in the `/advisor` picker:

```python
/advisor off
```

To disable the advisor tool entirely, set `CLAUDE_CODE_DISABLE_ADVISOR_TOOL=1`. The `/advisor` command becomes unavailable and any configured `advisorModel` is ignored. The `--advisor` flag is accepted but has no effect. See [Environment variables](env-vars.md).


[​](#compare-with-related-features)

Compare with related features

The advisor is one of several ways to combine model strengths. Pick based on when you want a second model involved.

| Approach                                                         | When the stronger model runs                                                                                                                | How it starts                                |
|------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------|
| Advisor tool                                                     | At decision points mid-task                                                                                                                 | Claude calls it when it needs guidance       |
| [`opusplan`](model-config.md#opusplan-model-setting)       | During plan mode when [allowed by `availableModels`](model-config.md#restrict-model-selection), then switches to Sonnet for execution | You enter plan mode                          |
| [Subagents](../09-Agents-Patterns/sub-agents.md#choose-a-model) with `model` set | For the entire delegated subtask                                                                                                            | Claude delegates, or you invoke the subagent |
| [`/model`](model-config.md#setting-your-model)             | From the next request onward                                                                                                                | You switch models                            |


[​](#see-also)

See also

- [Model configuration](model-config.md): switch models, set effort levels, and use `opusplan`
- [Manage costs effectively](../17-Billing-Plans/costs.md): track token usage across models
- [Advisor tool in the Claude API](../04-API-Reference/Agents-Tools/agents-and-tools-tool-use-advisor-tool.md): understand the underlying server tool, or use it directly from the Messages API
- [The advisor strategy](https://claude.com/blog/the-advisor-strategy): why pairing a fast main model with a stronger advisor works

---

## Claude Code on Amazon Bedrock - Claude Code Docs

Source: https://code.claude.com/docs/en/amazon-bedrock
Path: 02-Claude-Code-CLI/amazon-bedrock.md

## On this page

- [Prerequisites](#prerequisites)
- [Sign in with Bedrock](#sign-in-with-bedrock)
- [Set up manually](#set-up-manually)
  - [1. Submit use case details](#1-submit-use-case-details)
  - [2. Configure AWS credentials](#2-configure-aws-credentials)
  - [Use aws configure](#use-aws-configure)
  - [Export an access key](#export-an-access-key)
  - [Use an SSO profile](#use-an-sso-profile)
  - [Use AWS Management Console credentials](#use-aws-management-console-credentials)
  - [Use an Amazon Bedrock API key](#use-an-amazon-bedrock-api-key)
  - [Credential caching and resolution timeout](#credential-caching-and-resolution-timeout)
  - [Advanced credential configuration](#advanced-credential-configuration)
  - [3. Configure Claude Code](#3-configure-claude-code)
  - [4. Pin model versions](#4-pin-model-versions)
  - [Map each model version to an inference profile](#map-each-model-version-to-an-inference-profile)
- [Startup model checks](#startup-model-checks)
  - [When your organization enforces a model allowlist](#when-your-organization-enforces-a-model-allowlist)
  - [When a model is disabled mid-session](#when-a-model-is-disabled-mid-session)
- [Cross-region inference profile prefixes](#cross-region-inference-profile-prefixes)
- [IAM configuration](#iam-configuration)
- [1M token context window](#1m-token-context-window)
- [Service tiers](#service-tiers)
- [AWS Guardrails](#aws-guardrails)
- [Use the Mantle endpoint](#use-the-mantle-endpoint)
  - [Enable Mantle](#enable-mantle)
  - [Select a Mantle model](#select-a-mantle-model)
  - [Run Mantle alongside the Invoke API](#run-mantle-alongside-the-invoke-api)
  - [Route Mantle through a gateway](#route-mantle-through-a-gateway)
  - [Mantle environment variables](#mantle-environment-variables)
- [Troubleshooting](#troubleshooting)
  - [Authentication loop with SSO and corporate proxies](#authentication-loop-with-sso-and-corporate-proxies)
  - [Certificate errors behind a TLS-inspecting proxy](#certificate-errors-behind-a-tls-inspecting-proxy)
  - [Region issues](#region-issues)
  - [Streaming errors behind a gateway or proxy](#streaming-errors-behind-a-gateway-or-proxy)
  - [Zero token counts in /context](#zero-token-counts-in-%2Fcontext)
  - [Mantle endpoint errors](#mantle-endpoint-errors)
- [Additional resources](#additional-resources)

Deployment

# Claude Code on Amazon Bedrock

Copy pageCopy page

Learn about configuring Claude Code through Amazon Bedrock, including setup, IAM configuration, and troubleshooting.

Copy pageCopy page


[​](#prerequisites)

Prerequisites

Before configuring Claude Code with Amazon Bedrock, ensure you have:

- An AWS account with Amazon Bedrock access enabled
- Access to desired Claude models (for example, Claude Sonnet 4.6) in Amazon Bedrock
- AWS CLI installed and configured (optional - only needed if you don’t have another mechanism for getting credentials)
- Appropriate IAM permissions

To sign in with your own Amazon Bedrock credentials, follow [Sign in with Amazon Bedrock](#sign-in-with-bedrock) below. To deploy Claude Code across a team, use the [manual setup](#set-up-manually) steps and [pin your model versions](#4-pin-model-versions) before rolling out.


[​](#sign-in-with-bedrock)

Sign in with Bedrock

If you have AWS credentials and want to start using Claude Code through Amazon Bedrock, the login wizard walks you through it. You complete the AWS-side prerequisites once per account; the wizard handles the Claude Code side.

1

Enable Anthropic models in your AWS account

In the [Amazon Bedrock console](https://console.aws.amazon.com/bedrock/), open the Model catalog, select an Anthropic model, and submit the use case form. Access is granted immediately after submission. See [Submit use case details](#1-submit-use-case-details) for AWS Organizations and [IAM configuration](#iam-configuration) for the permissions your role needs.

2

Start Claude Code and choose Amazon Bedrock

Run `claude`. At the login prompt, select **3rd-party platform**, then **Amazon Bedrock**. If you’re already signed in and see the chat prompt instead, run `/setup-bedrock` to open the wizard. Until `CLAUDE_CODE_USE_BEDROCK=1` is set, Claude Code [hides the command from the command menu](commands.md#how-the-command-menu-matches-what-you-type); type it in full.

3

Follow the wizard prompts

Choose how you authenticate to AWS: an AWS profile detected from your `~/.aws` directory, an Amazon Bedrock API key, an access key and secret, or credentials already in your environment. The wizard asks for your region, verifies which Claude models your account can invoke, and lets you pin them. It saves the result to the `env` block of your [user settings file](settings.md), so you don’t need to export environment variables yourself.

After you’ve signed in, run `/setup-bedrock` any time to reopen the wizard and change your credentials, region, or model pins. The model pin step starts from your currently pinned models. The wizard writes to `~/.claude/settings.json`, or to `$CLAUDE_CONFIG_DIR/settings.json` when [`CLAUDE_CONFIG_DIR`](env-vars.md#variables) is set.


[​](#set-up-manually)

Set up manually

To configure Amazon Bedrock through environment variables instead of the wizard, for example in CI or a scripted enterprise rollout, follow the steps below.


[​](#1-submit-use-case-details)

1. Submit use case details

Before you invoke an Anthropic model for the first time, submit use case details. You do this once per AWS account.

1.  Ensure you have the right IAM permissions described below
2.  Go to the [Amazon Bedrock console](https://console.aws.amazon.com/bedrock/)
3.  Select an Anthropic model from the **Model catalog**
4.  Complete the use case form. Access is granted immediately after submission.

If you use AWS Organizations, you can submit the form once from the management account using the [`PutUseCaseForModelAccess` API](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_PutUseCaseForModelAccess.html). This call requires the `bedrock:PutUseCaseForModelAccess` IAM permission. Approval extends to child accounts automatically.


[​](#2-configure-aws-credentials)

2. Configure AWS credentials

Claude Code uses the default AWS SDK credential chain. If the machine already supplies credentials to that chain, such as an Amazon EC2 instance profile or Amazon ECS task credentials, skip to [step 3](#3-configure-claude-code). AWS [warns against using an IAM user’s access keys](https://docs.aws.amazon.com/cli/latest/userguide/cli-authentication-user.html) when you develop purpose-built software or work with real data. Set up your credentials with one of these methods:

- [`aws configure`](#use-aws-configure): save an IAM user’s access key to a profile in your `~/.aws` directory
- [Access key environment variables](#export-an-access-key): set an access key, or temporary credentials with a session token, in the current shell only
- [SSO profile](#use-an-sso-profile): sign in through IAM Identity Center in your browser and get temporary credentials. Use this method if you access your AWS account through IAM Identity Center.
- [AWS Management Console credentials](#use-aws-management-console-credentials): sign in through your browser with your AWS Management Console credentials and get temporary credentials. AWS [recommends this method](https://docs.aws.amazon.com/signin/latest/userguide/command-line-sign-in.html) if you access your AWS account as the root user, as an IAM user, or through federation with IAM.
- [Amazon Bedrock API key](#use-an-amazon-bedrock-api-key): authenticate with a bearer token that works only for Amazon Bedrock, instead of AWS credentials


[​](#use-aws-configure)

Use `aws configure`

Run `aws configure` and enter your access key ID, secret access key, and default region when prompted:

```python
aws configure
```

The AWS CLI saves the key to the `default` profile in `~/.aws/credentials`, where the credential chain reads it.


[​](#export-an-access-key)

Export an access key

Export your access key as environment variables. `AWS_SESSION_TOKEN` is required only with temporary credentials, so leave that line out if your access key belongs to an IAM user:

```python
export AWS_ACCESS_KEY_ID=your-access-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-access-key
export AWS_SESSION_TOKEN=your-session-token
```


[​](#use-an-sso-profile)

Use an SSO profile

Create a profile with `aws configure sso` if you don’t have one. Then sign in to IAM Identity Center and set `AWS_PROFILE` so the credential chain uses that profile. Replace `your-profile-name` with the name of your AWS profile before running these commands.

```python
aws sso login --profile=your-profile-name

export AWS_PROFILE=your-profile-name
```

Claude Code requests role credentials from the IAM Identity Center region named by the profile’s `sso_region`, which doesn’t need to match the region you run Amazon Bedrock in.


[​](#use-aws-management-console-credentials)

Use AWS Management Console credentials

The `aws login` command requires AWS CLI 2.32.0 or later. For the IAM policy your identity needs, see the [AWS instructions for `aws login`](https://docs.aws.amazon.com/signin/latest/userguide/command-line-sign-in.html). Run the command to sign in through your browser with your AWS Management Console credentials:

```python
aws login
```

The session is valid for up to 12 hours, after which you run `aws login` again.


[​](#use-an-amazon-bedrock-api-key)

Use an Amazon Bedrock API key

An Amazon Bedrock API key is a bearer token that authenticates your requests in place of AWS credentials. AWS issues [two types of key](https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys.html):

- **Short-term keys**: last up to 12 hours. AWS prefers them over long-term keys for production environments.
- **Long-term keys**: last until an expiration date you set. AWS recommends them only for exploration.

Export the key as `AWS_BEARER_TOKEN_BEDROCK`:

```python
export AWS_BEARER_TOKEN_BEDROCK=your-bedrock-api-key
```

When `AWS_BEARER_TOKEN_BEDROCK` is set, Claude Code authenticates with the key and doesn’t resolve the credential chain, even if other AWS credentials are present. [Learn more about Amazon Bedrock API keys](https://aws.amazon.com/blogs/machine-learning/accelerate-ai-development-with-amazon-bedrock-api-keys/).


[​](#credential-caching-and-resolution-timeout)

Credential caching and resolution timeout

Claude Code resolves the AWS default credential provider chain once and keeps the resolved credentials in memory. It reuses them until five minutes before they expire, or for one hour when they carry no expiration, so an SSO-backed profile requests credentials from IAM Identity Center about once per credential lifetime. A credential error from the API clears the cache, and the retry resolves fresh credentials. The cache covers every credential method listed at the start of this step except an Amazon Bedrock API key, which doesn’t use the provider chain. To resolve the chain on every request instead, set [`CLAUDE_CODE_SKIP_AWS_CRED_CACHE=1`](env-vars.md). The resolve that fills the cache times out after 60 seconds. If a step in the chain stalls, for example a `credential_process` helper that waits for input it can’t receive, the request fails with [`AWS default-chain credential resolve timed out`](errors.md#aws-default-chain-credential-resolve-timed-out). If your chain runs an interactive sign-in that legitimately needs longer, such as browser-based SSO with MFA through a wrapper like `aws-vault`, raise the limit in milliseconds with [`CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS`](env-vars.md). With `CLAUDE_CODE_SKIP_AWS_CRED_CACHE=1` set, each API request resolves the chain without this limit. Except when you authenticate with an Amazon Bedrock API key, the [setup wizard](#sign-in-with-bedrock) applies the same limit to each AWS call it makes while verifying your credentials, and to the credential lookup before each model check. During credential verification, a check that exceeds it fails with [`Timed out after 60s waiting for AWS`](errors.md#bedrock-setup-verification-timed-out-waiting-for-aws).


[​](#advanced-credential-configuration)

Advanced credential configuration

Claude Code supports automatic credential refresh for AWS SSO and corporate identity providers. Add these settings to your Claude Code settings file (see [Settings](settings.md) for file locations). These two settings have different trigger conditions:

- **`awsAuthRefresh`**: runs only when Claude Code detects that your AWS credentials are expired, either locally based on their timestamp or when the API returns a credential error, then retries the request with refreshed credentials.
- **`awsCredentialExport`**: runs at session start and on each credential reload, even when the credentials in your AWS default credential provider chain are still valid. Use this when your Amazon Bedrock account requires cross-account credentials that differ from the ones the default provider chain would resolve.

Before running the `awsAuthRefresh` command, Claude Code makes an STS `GetCallerIdentity` call to confirm that your credentials are actually expired, and skips the command when they still work. Claude Code sends this check through your [proxy configuration](../13-Enterprise-Admin/network-config.md#proxy-configuration), honoring `HTTPS_PROXY` and `NO_PROXY`. Before v2.1.239, Claude Code sent this check directly and hung at startup on networks that only allow egress through a proxy.

##### Example configuration

```python
{
  "awsAuthRefresh": "aws sso login --profile myprofile",
  "env": {
    "AWS_PROFILE": "myprofile"
  }
}
```

##### Configuration settings explained

**`awsAuthRefresh`**: Use this for commands that modify the `.aws` directory, such as updating credentials, SSO cache, or config files. The command’s output is displayed to the user, but interactive input isn’t supported. This works well for browser-based SSO flows where the CLI displays a URL or code and you complete authentication in the browser. **`awsCredentialExport`**: Only use this if you can’t modify `.aws` and must directly return credentials. Output is captured silently and not shown to the user. The command must output JSON in this format:

```python
{
  "Credentials": {
    "AccessKeyId": "value",
    "SecretAccessKey": "value",
    "SessionToken": "value",
    "Expiration": "2026-01-01T00:00:00Z"
  }
}
```

The flat output from `aws configure export-credentials --format process` is also accepted, with the same keys at the top level instead of nested under `Credentials`. `Expiration` is optional. When the command returns a valid ISO 8601 `Expiration`, Claude Code caches the credentials until five minutes before that time. Without it, credentials are cached for one hour. When you configure `awsCredentialExport` without `awsAuthRefresh`, Claude Code uses the exported credentials directly and doesn’t re-resolve the AWS default credential provider chain at startup.


[​](#3-configure-claude-code)

3. Configure Claude Code

Set the following environment variables to enable Amazon Bedrock:

```python
# Enable Bedrock integration
export CLAUDE_CODE_USE_BEDROCK=1
export AWS_REGION=us-east-1  # optional if your AWS profile already sets a region

# Optional: Override the AWS region for the small/fast model (Bedrock and Mantle).
# On Bedrock, has no effect without ANTHROPIC_DEFAULT_HAIKU_MODEL
# or the deprecated ANTHROPIC_SMALL_FAST_MODEL set.
export ANTHROPIC_SMALL_FAST_MODEL_AWS_REGION=us-west-2

# Optional: Override the Bedrock endpoint URL for custom endpoints or gateways
# export ANTHROPIC_BEDROCK_BASE_URL=https://bedrock-runtime.us-east-1.amazonaws.com
```

When enabling Amazon Bedrock for Claude Code, keep the following in mind:

- You only need to set `AWS_REGION` to override your AWS profile’s region or when your profile has no region. Claude Code resolves the region in this order:
  - `AWS_REGION`
  - `AWS_DEFAULT_REGION`
  - the `region` set on your active AWS profile, read from the AWS shared credentials file first and then the shared config file, matching AWS SDK precedence
  - `us-east-1`

  If a value from any of these sources isn’t shaped like a region name, Claude Code treats it as unset and continues down the order. For example, Claude Code treats a value containing a slash, dot, or space as unset. The active profile is `AWS_PROFILE` if set, otherwise `default`. Set `AWS_SHARED_CREDENTIALS_FILE` or `AWS_CONFIG_FILE` to point at non-default file paths. Run `/status` to see the resolved region. When the region came from your AWS config files or the default fallback, Claude Code also notes the source in the `/status` output.
- When using Amazon Bedrock, the `/logout` command is unavailable since authentication is handled through AWS credentials.
- The WebSearch tool is not available on Amazon Bedrock. See [WebSearch tool behavior](tools-reference.md#websearch-tool-behavior).
- You can use settings files for environment variables like `AWS_PROFILE` that you don’t want to leak to other processes. See [Settings](settings.md) for more information.


[​](#4-pin-model-versions)

4. Pin model versions

Pin specific model versions when deploying to multiple users. Without pinning, model aliases such as `sonnet` and `opus` resolve to Claude Code’s built-in default for Amazon Bedrock, which can lag the newest release and may not yet be available in your account. Claude Code [falls back](#startup-model-checks) to an earlier or lower-tier model at startup when the default is unavailable, but pinning lets you control when your users move to a new model.

Set these environment variables to specific Amazon Bedrock model IDs. Without `ANTHROPIC_DEFAULT_OPUS_MODEL`, the `opus` alias on Amazon Bedrock resolves to Opus 5.5, and without `ANTHROPIC_DEFAULT_SONNET_MODEL`, the `sonnet` alias resolves to Sonnet 4.5. This example pins each alias to a specific version:

```python
export ANTHROPIC_DEFAULT_OPUS_MODEL='us.anthropic.claude-opus-4-8'
export ANTHROPIC_DEFAULT_SONNET_MODEL='us.anthropic.claude-sonnet-4-6'
export ANTHROPIC_DEFAULT_HAIKU_MODEL='us.anthropic.claude-haiku-4-5-20251001-v1:0'
```

These IDs use the `us.` cross-region inference profile prefix. If you use a different region prefix or application inference profiles, adjust accordingly. In AWS GovCloud regions, use the `us-gov.` prefix. To keep the built-in default models and change only their preferred prefix, set [`ANTHROPIC_BEDROCK_REGION_PREFIX`](#cross-region-inference-profile-prefixes) instead of pinning. The difference shows in what the `opus` alias resolves to:

| You set                                                       | The `opus` alias resolves to                                                    |
|:--------------------------------------------------------------|:--------------------------------------------------------------------------------|
| `ANTHROPIC_DEFAULT_OPUS_MODEL='us.anthropic.claude-opus-4-8'` | `us.anthropic.claude-opus-4-8`, the exact ID you pinned                         |
| `ANTHROPIC_BEDROCK_REGION_PREFIX=eu`                          | `eu.anthropic.claude-opus-5-5`, the built-in default with your preferred prefix |

For current and legacy model IDs, see [Models overview](../20-Models/about-claude-models-overview.md). For the full list of pinning environment variables, see [Model configuration](model-config.md#pin-models-for-third-party-deployments). Claude Code uses these default models when no pinning variables are set:

| Model type       | Default model                                                                             |
|:-----------------|:------------------------------------------------------------------------------------------|
| Primary model    | Opus 5.5, for example `us.anthropic.claude-opus-5-5` in a `us-*` region                   |
| Small/fast model | Sonnet 4.5, for example `us.anthropic.claude-sonnet-4-5-20250929-v1:0` in a `us-*` region |

Background tasks such as session title generation use the small/fast model, normally a Haiku-class model. On Amazon Bedrock, Claude Code uses the default Sonnet model for background tasks because Haiku may not be enabled in every account or region. Two selections change which model carries them:

- When you select a primary model with `--model`, `ANTHROPIC_MODEL`, or the `model` setting, background tasks use that model. When Claude Code starts the session on the model you set with [`ANTHROPIC_DEFAULT_MODEL`](model-config.md#set-a-default-model-for-new-sessions), background tasks use that model too. Setting `ANTHROPIC_DEFAULT_OPUS_MODEL` without `ANTHROPIC_DEFAULT_SONNET_MODEL` also counts as a selection, because the built-in Sonnet model may not be enabled in an account that steers its own Opus.
- To use Haiku for background tasks, set `ANTHROPIC_DEFAULT_HAIKU_MODEL` to a model ID that is available in your account.

Opus models have a higher per-token price than Sonnet models, so if you don’t pin a primary model, you’re billed at the Opus rate. To use Sonnet 4.5 as the primary model, set `ANTHROPIC_MODEL` to its full model ID. A deployment that steers the default with `ANTHROPIC_DEFAULT_SONNET_MODEL` and doesn’t set `ANTHROPIC_DEFAULT_OPUS_MODEL` keeps its steered Sonnet model as the default.

Before v2.1.280, the primary model on Amazon Bedrock defaulted to Opus 5 and the `opus` alias resolved to Opus 5 from v2.1.219. On v2.1.207 through v2.1.218, the primary model on Amazon Bedrock defaulted to Opus 4.8 and the `opus` alias resolved to Opus 4.8. To customize models further, use one of these methods:

```python
# Using inference profile ID
export ANTHROPIC_MODEL='us.anthropic.claude-sonnet-4-6'
export ANTHROPIC_DEFAULT_HAIKU_MODEL='us.anthropic.claude-haiku-4-5-20251001-v1:0'

# Using application inference profile ARN
export ANTHROPIC_MODEL='arn:aws:bedrock:us-east-2:your-account-id:application-inference-profile/your-model-id'

# Optional: Disable prompt caching if needed
# export DISABLE_PROMPT_CACHING=1

# Optional: Request 1-hour prompt cache TTL instead of the 5-minute default
# export ENABLE_PROMPT_CACHING_1H=1
```

The 1-hour cache TTL is billed at a higher rate than the 5-minute default. See [cache lifetime](prompt-caching.md#cache-lifetime). To set different TTLs for your main conversation and for the requests Claude Code makes outside it, [choose the TTL yourself](prompt-caching.md#choose-the-ttl-yourself).

Prompt caching may not be available in all Amazon Bedrock regions. If cache token counts stay at zero, check [supported models, regions, and limits](https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html#prompt-caching-models) in the Amazon Bedrock documentation.


[​](#map-each-model-version-to-an-inference-profile)

Map each model version to an inference profile

The `ANTHROPIC_DEFAULT_*_MODEL` environment variables configure one inference profile per model family. If your organization needs to expose several versions of the same family in the `/model` picker, each routed to its own application inference profile ARN, use the `modelOverrides` setting in your [settings file](settings.md#where-settings-live) instead. This example maps four Opus versions to distinct ARNs so users can switch between them without bypassing your organization’s inference profiles:

```python
{
  "modelOverrides": {
    "claude-opus-4-7": "arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/opus-47-prod",
    "claude-opus-4-6": "arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/opus-46-prod",
    "claude-opus-4-5-20251101": "arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/opus-45-prod",
    "claude-opus-4-1-20250805": "arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/opus-41-prod"
  }
}
```

When a user selects one of these versions in `/model`, Claude Code calls Amazon Bedrock with the mapped ARN. The same mapping applies when you pass the Anthropic model ID directly through `--model` or `ANTHROPIC_MODEL`. Versions without an override fall back to the built-in Amazon Bedrock model ID or any matching inference profile discovered at startup. Before v2.1.200, `--model` and `ANTHROPIC_MODEL` values reached Amazon Bedrock as-is without going through the override map. See [Override model IDs per version](model-config.md#override-model-ids-per-version) for details on how overrides interact with `availableModels` and other model settings.


[​](#startup-model-checks)

Startup model checks

When Claude Code starts with Amazon Bedrock configured, it verifies that the models it intends to use are accessible in your account. If you have pinned a model version that is older than the current Claude Code default, and your account can invoke the newer version, Claude Code prompts you to update the pin. Accepting writes the new model ID to your [user settings file](settings.md) and restarts Claude Code. Declining is remembered until the next default version change. Pins that point to an [application inference profile ARN](#map-each-model-version-to-an-inference-profile) are skipped, since those are managed by your administrator. If you have not pinned a model and the current default is unavailable in your account, Claude Code falls back for the current session and shows a notice. It tries earlier versions of the default model first and, when the default is an Opus model and no Opus version is available, falls back to the default Sonnet model. The fallback is not persisted. Enable the newer model in your Amazon Bedrock account or [pin a version](#4-pin-model-versions) to make the choice permanent. When you start the session on a specific Sonnet or Opus version, for example with `--model`, `ANTHROPIC_MODEL`, or the [`model` setting](settings-reference.md#model), that version acts as the session’s pinned default for the matching `sonnet` or `opus` alias. Claude Code skips the availability check for the built-in default your model replaces and starts on the model you configured, with no fallback notice. Model aliases such as `opus` don’t act as pins, and neither does a model ID Claude Code doesn’t recognize, such as an application inference profile ARN. When these checks find a model your account can’t invoke, Claude Code remembers the refusal on this machine for up to a day, and launches during that time skip the remembered model without asking Amazon Bedrock again. Claude Code checks a remembered refusal of a current default model again at launch once ten minutes have passed since the last check, so a default your administrator re-enables comes back. To turn the memory off, set [`CLAUDE_CODE_SKIP_MODEL_ACCESS_MEMORY=1`](env-vars.md).


[​](#when-your-organization-enforces-a-model-allowlist)

When your organization enforces a model allowlist

If you set [`enforceAvailableModels`](model-config.md#enforce-the-allowlist-for-the-default-model) in managed settings, the startup model checks use only models your `availableModels` list permits. This applies on the Amazon Bedrock Invoke API and requires Claude Code v2.1.287 or later. A list without `enforceAvailableModels` doesn’t restrict these checks. The checks compare each entry with the inference profile ID they would send, including its [region prefix](#cross-region-inference-profile-prefixes), so write the list in those IDs. This example permits Opus 4.8 and Sonnet 4.5 for a deployment whose models resolve to `us.` profiles:

```python
{
  "availableModels": ["us.anthropic.claude-opus-4-8", "us.anthropic.claude-sonnet-4-5-20250929-v1:0"],
  "enforceAvailableModels": true
}
```

For aliases, version prefixes, and `modelOverrides` entries, see [Pin models for third-party deployments](model-config.md#pin-models-for-third-party-deployments).


[​](#when-a-model-is-disabled-mid-session)

When a model is disabled mid-session

If 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. The 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](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](errors.md#aws-authentication-failed) and a hint to enable the model. A [fallback model chain](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`](env-vars.md). A fallback chain you configured still switches on these refusals; remove the chain as well if you want every refused request to fail.


[​](#cross-region-inference-profile-prefixes)

Cross-region inference profile prefixes

On the Amazon Bedrock [Invoke API](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModelWithResponseStream.html), Claude Code resolves its built-in default models to [cross-region inference profile](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html) IDs; to route model versions through your own inference profiles instead, see [Map each model version to an inference profile](#map-each-model-version-to-an-inference-profile). This table shows the prefix Claude Code prefers for each resolved AWS region:

| AWS region                | Prefix    |
|:--------------------------|:----------|
| `us-gov-*` (AWS GovCloud) | `us-gov.` |
| `us-*`                    | `us.`     |
| `eu-*`                    | `eu.`     |
| `ap-*`                    | `apac.`   |
| All other regions         | `global.` |

Set `ANTHROPIC_BEDROCK_REGION_PREFIX` to choose the prefix Claude Code tries first; when Claude Code can check profile availability and finds no matching profile for a model, it falls back as described in the resolution order below. Valid values are `us`, `eu`, `apac`, `jp`, `au`, and `global`. For example, set it to `global` when your account has `global.` profiles enabled but Claude Code would derive a geography-specific one from your AWS region. Requires Claude Code v2.1.224 or later. This example routes the default models through `global.` profiles:

```python
export ANTHROPIC_BEDROCK_REGION_PREFIX=global
# In a us-* region, the primary model now resolves to
# global.anthropic.claude-opus-5-5 instead of us.anthropic.claude-opus-5-5
```

The preferred prefix is a preference, not a guarantee, whether it comes from your region or from the variable. How Claude Code applies it depends on whether it can check profile availability in your account:

- When Claude Code can [list the inference profiles](#iam-configuration) in your account, it resolves each model in this order:
  1.  The profile with your preferred prefix.
  2.  Any matching profile, for a model that has no profile with that prefix.
  3.  The built-in model ID with your preferred prefix, for a model that has no matching profile at all. Claude Code applies this ID without checking availability at this step; the [startup model checks](#startup-model-checks) still cover the session’s default models.
- When profile discovery is unavailable, Claude Code applies the prefix without checking availability. If your account doesn’t have inference profiles with that prefix enabled, requests fail with a 400 error.

Claude Code doesn’t rewrite Amazon Bedrock inference profile IDs or ARNs you configure yourself, or [`modelOverrides`](#map-each-model-version-to-an-inference-profile) values; Anthropic-format model IDs resolve through [the same mapping as the `/model` picker](#map-each-model-version-to-an-inference-profile). Claude Code also ignores the variable in two cases:

- In AWS GovCloud regions, Claude Code always uses `us-gov.`, the only prefix that routes within the GovCloud partition.
- When you set a value that isn’t one of the valid values, Claude Code falls back to the region-derived preferred prefix.


[​](#iam-configuration)

IAM configuration

Create an IAM policy with the required permissions for Claude Code:

```python
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowModelAndInferenceProfileAccess",
      "Effect": "Allow",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream",
        "bedrock:ListInferenceProfiles",
        "bedrock:GetInferenceProfile"
      ],
      "Resource": [
        "arn:aws:bedrock:*:*:inference-profile/*",
        "arn:aws:bedrock:*:*:application-inference-profile/*",
        "arn:aws:bedrock:*:*:foundation-model/*"
      ]
    },
    {
      "Sid": "AllowMarketplaceSubscription",
      "Effect": "Allow",
      "Action": [
        "aws-marketplace:ViewSubscriptions",
        "aws-marketplace:Subscribe"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:CalledViaLast": "bedrock.amazonaws.com"
        }
      }
    }
  ]
}
```

For more restrictive permissions, you can limit the Resource to specific inference profile ARNs. `bedrock:GetInferenceProfile` lets Claude Code resolve an [application inference profile ARN](#map-each-model-version-to-an-inference-profile) to its backing foundation model, which is used to select the correct request shape for that model. If the token is missing this permission, Claude Code recovers automatically by retrying once with the alternate shape, so requests still succeed but each new model adds an extra round-trip. Granting the permission avoids the retry. This applies most often to `AWS_BEARER_TOKEN_BEDROCK` deployments, where the token’s policy is typically narrower than a full IAM role. For details, see [Amazon Bedrock IAM documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/security-iam.html).

Create a dedicated AWS account for Claude Code to simplify cost tracking and access control.


[​](#1m-token-context-window)

1M token context window

Fable models, Sonnet 5 and later, and Opus 4.7 and later run with the [1M token context window](../04-API-Reference/Guides/build-with-claude-context-windows.md#context-window-sizes-by-model) by default on Amazon Bedrock, on both the Invoke API and the [Mantle endpoint](#use-the-mantle-endpoint), with no `[1m]` suffix needed. An application inference profile ARN gets the 1M window when a [`modelOverrides`](#map-each-model-version-to-an-inference-profile) entry maps its model to it. To keep a 200K window instead, set [`CLAUDE_CODE_DISABLE_1M_CONTEXT=1`](model-config.md#turn-off-1m-context). Opus 4.6 and Sonnet 4.6 on the Invoke API reach the 1M window when you select their `[1m]` variant. The [setup wizard](#sign-in-with-bedrock) offers a 1M context option when it pins models. To enable it for a manually pinned model instead, append `[1m]` to the model ID. See [Pin models for third-party deployments](model-config.md#pin-models-for-third-party-deployments) for details, including how to use the 1M window without changing the pin. Before v2.1.287, the Fable models and Opus 4.7 and later ran with a 200K window by default on the Invoke API and reached the 1M window there through a `[1m]` suffix.


[​](#service-tiers)

Service tiers

[Amazon Bedrock service tiers](https://docs.aws.amazon.com/bedrock/latest/userguide/service-tiers-inference.html) let you trade off cost against latency. Set `ANTHROPIC_BEDROCK_SERVICE_TIER` to `default`, `flex`, or `priority`:

```python
export ANTHROPIC_BEDROCK_SERVICE_TIER=priority
```

Claude Code sends this as the `X-Amzn-Bedrock-Service-Tier` header on each request. Tier availability varies by model and region. Reserved capacity uses a [provisioned throughput](https://docs.aws.amazon.com/bedrock/latest/userguide/prov-throughput.html) ARN as the model ID instead of this setting.


[​](#aws-guardrails)

AWS Guardrails

[Amazon Bedrock Guardrails](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) let you implement content filtering for Claude Code. Create a Guardrail in the [Amazon Bedrock console](https://console.aws.amazon.com/bedrock/), publish a version, then add the Guardrail headers to your [settings file](settings.md). Enable Cross-Region inference on your Guardrail if you’re using cross-region inference profiles. Example configuration:

```python
{
  "env": {
    "ANTHROPIC_CUSTOM_HEADERS": "X-Amzn-Bedrock-GuardrailIdentifier: your-guardrail-id\nX-Amzn-Bedrock-GuardrailVersion: 1"
  }
}
```

If your organization delivers the guardrail headers through a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) policy instead, they count as [settings that need approval](../13-Enterprise-Admin/server-managed-settings.md#environment-variables-and-the-approval-dialog). When the guardrail blocks a response partway through, the text streamed so far stays and the reply ends with the message configured on the guardrail for blocked responses.


[​](#use-the-mantle-endpoint)

Use the Mantle endpoint

Mantle is an Amazon Bedrock endpoint that serves Claude models through the native Anthropic API shape rather than the Amazon Bedrock Invoke API. It uses the same [AWS credentials](#2-configure-aws-credentials) and [`awsAuthRefresh` configuration](#advanced-credential-configuration). Mantle has its own IAM actions under the `bedrock-mantle:` prefix, so the `bedrock:` actions in [IAM configuration](#iam-configuration) don’t cover it. Grant your IAM identity `bedrock-mantle:CreateInference` for inference and `bedrock-mantle:CountTokens` for token counting. See [Making inference requests](https://docs.aws.amazon.com/bedrock/latest/userguide/inference.html) and [Counting tokens](https://docs.aws.amazon.com/bedrock/latest/userguide/count-tokens.html) in the AWS documentation, and the [service authorization reference](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonbedrockpoweredbyawsmantle.html) for every Mantle action.


[​](#enable-mantle)

Enable Mantle

With AWS credentials already configured, set `CLAUDE_CODE_USE_MANTLE` to route requests to the Mantle endpoint:

```python
export CLAUDE_CODE_USE_MANTLE=1
export AWS_REGION=us-east-1
```

Claude Code constructs the endpoint URL from the AWS region, resolved with the same precedence as [Amazon Bedrock above](#3-configure-claude-code). To override the URL for a custom endpoint or gateway, set `ANTHROPIC_BEDROCK_MANTLE_BASE_URL`. Run `/status` inside Claude Code to confirm. The provider line shows `Amazon Bedrock (Mantle)` when Mantle is active.


[​](#select-a-mantle-model)

Select a Mantle model

Mantle uses model IDs prefixed with `anthropic.` and without a version suffix, for example `anthropic.claude-sonnet-5` or `anthropic.claude-haiku-4-5`. The models available to your account depend on what your organization has been granted; additional model IDs are listed in your onboarding materials from AWS. Contact your AWS account team to request access to allowlisted models. Set the model with the `--model` flag or with `/model` inside Claude Code:

```python
claude --model anthropic.claude-haiku-4-5
```


[​](#run-mantle-alongside-the-invoke-api)

Run Mantle alongside the Invoke API

The models available to you on Mantle may not include every model you use today. Setting both `CLAUDE_CODE_USE_BEDROCK` and `CLAUDE_CODE_USE_MANTLE` lets Claude Code call both endpoints from the same session. Model IDs that match the Mantle format are routed to Mantle, and all other model IDs go to the Amazon Bedrock Invoke API.

```python
export CLAUDE_CODE_USE_BEDROCK=1
export CLAUDE_CODE_USE_MANTLE=1
```

To surface a Mantle model in the `/model` picker, list its ID in `availableModels` in your [settings file](settings.md). This setting also restricts the picker to the listed entries. Listing `anthropic.claude-haiku-4-5` removes the bare `haiku` alias from the picker, so also list version prefixes or full IDs for the versions you want to keep selectable. The Mantle ID and the `haiku` alias resolve to the same model family, so the merge keeps only the more specific entry. See [Merge behavior](model-config.md#merge-behavior):

```python
{
  "availableModels": ["opus", "sonnet", "claude-haiku-4-5", "anthropic.claude-haiku-4-5"]
}
```

Entries with the `anthropic.` prefix are added as custom picker options, and the ones that match the Mantle format are routed to Mantle. Replace `anthropic.claude-haiku-4-5` with the model ID your account has been granted. See [Restrict model selection](model-config.md#restrict-model-selection) for how `availableModels` interacts with other model settings. When both providers are active, `/status` shows `Amazon Bedrock + Amazon Bedrock (Mantle)`.


[​](#route-mantle-through-a-gateway)

Route Mantle through a gateway

If your organization routes model traffic through a centralized [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) that injects AWS credentials server-side, disable client-side authentication so Claude Code sends requests without SigV4 signatures or `x-api-key` headers:

```python
export CLAUDE_CODE_USE_MANTLE=1
export CLAUDE_CODE_SKIP_MANTLE_AUTH=1
export ANTHROPIC_BEDROCK_MANTLE_BASE_URL=https://your-gateway.example.com
```


[​](#mantle-environment-variables)

Mantle environment variables

These variables are specific to the Mantle endpoint. See [Environment variables](env-vars.md) for the full list.

| Variable                                | Purpose                                                                    |
|:----------------------------------------|:---------------------------------------------------------------------------|
| `CLAUDE_CODE_USE_MANTLE`                | Enable the Mantle endpoint. Set to `1` or `true`.                          |
| `ANTHROPIC_BEDROCK_MANTLE_BASE_URL`     | Override the default Mantle endpoint URL                                   |
| `CLAUDE_CODE_SKIP_MANTLE_AUTH`          | Skip client-side authentication for proxy setups                           |
| `ANTHROPIC_SMALL_FAST_MODEL_AWS_REGION` | Override AWS region for the Haiku-class model (shared with Amazon Bedrock) |


[​](#troubleshooting)

Troubleshooting


[​](#authentication-loop-with-sso-and-corporate-proxies)

Authentication loop with SSO and corporate proxies

If browser sign-in tabs keep opening when you use AWS SSO, remove the `awsAuthRefresh` setting from your [settings file](settings.md). The loop can occur when corporate VPNs or TLS inspection proxies interrupt the SSO browser flow. Claude Code treats the interrupted connection as an authentication failure. When a later request finds the credentials still expired, Claude Code re-runs `awsAuthRefresh`, which opens another tab. If your network environment interferes with automatic browser-based SSO flows, use `aws sso login` manually before starting Claude Code instead of relying on `awsAuthRefresh`.


[​](#certificate-errors-behind-a-tls-inspecting-proxy)

Certificate errors behind a TLS-inspecting proxy

Claude Code applies your [CA certificate store](../13-Enterprise-Admin/network-config.md#ca-certificate-store) configuration to its requests to AWS, including:

- Model discovery
- Token counting
- The STS and SSO role-credential calls that resolve your AWS credentials
- The [setup wizard](#sign-in-with-bedrock)’s credential verification and model checks

For these requests, a corporate root certificate in your OS trust store or `NODE_EXTRA_CA_CERTS` bundle needs no Amazon Bedrock-specific setup. Before v2.1.260, Claude Code applied your CA configuration to these requests only when they went through a configured proxy, and on a direct connection they trusted only the runtime’s default certificate store. Before v2.1.261, the credential lookup behind the setup wizard’s model checks with the **Use credentials already in my environment** option still trusted only the runtime’s default certificate store. Behind a TLS-inspecting proxy whose root certificate is only in the OS store, the affected requests failed with `unable to get local issuer certificate`, or the wizard showed models as `unreachable`, while inference requests succeeded. Update to v2.1.261 or later.


[​](#region-issues)

Region issues

If you encounter region issues:

- Check model availability: `aws bedrock list-inference-profiles --region your-region`
- Switch to a supported region: `export AWS_REGION=us-east-1`
- Consider using inference profiles for cross-region access

If you receive an error “on-demand throughput isn’t supported”:

- Specify the model as an [inference profile](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html) ID

Claude Code uses the Amazon Bedrock [Invoke API](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModelWithResponseStream.html) and does not support the Converse API.


[​](#streaming-errors-behind-a-gateway-or-proxy)

Streaming errors behind a gateway or proxy

Amazon Bedrock streams `InvokeModelWithResponseStream` responses in a binary event-stream format with the header `Content-Type: application/vnd.amazon.eventstream`. A gateway or proxy between Claude Code and Amazon Bedrock must forward the response body and its headers, including `Content-Type`, as Amazon Bedrock sent them. If the gateway rewrites `Content-Type` to another value, Claude Code rejects the response with an error that begins `Bedrock streaming response has content-type`, naming the value it received. The common rewrite is `text/event-stream`, from an integration that re-emits the stream as server-sent events. For the `CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_GUARD` variable that the error message names, see [Bedrock streaming response has an unexpected content-type](errors.md#bedrock-streaming-response-has-an-unexpected-content-type). If the gateway drops or blanks the header instead, Claude Code assumes the body is Amazon Bedrock’s event stream and decodes it, so a body the gateway passed through unmodified keeps streaming. If a gateway that drops the header also re-emits the stream as server-sent events, Claude Code can’t decode the body and falls back to a slower non-streaming path on every turn: each response appears only once it is complete instead of streaming in. In that case, set [`CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_DEFAULT=1`](env-vars.md) so Claude Code reads the body as server-sent events instead. To fix the error or the fallback, configure the gateway to forward the `InvokeModelWithResponseStream` response body and its `Content-Type` header unmodified. A gateway that converts the stream to server-sent events is no longer serving the Amazon Bedrock API. If it also accepts Anthropic Messages API requests, connect to it as an [LLM gateway](../13-Enterprise-Admin/llm-gateway-connect.md) with `ANTHROPIC_BASE_URL` instead of `CLAUDE_CODE_USE_BEDROCK`.


[​](#zero-token-counts-in-/context)

Zero token counts in /context

The `/context` command counts tokens for each tool group by sending the tool schemas to the Amazon Bedrock count-tokens API. On Claude Code versions before v2.1.196, Amazon Bedrock rejected that request because the schemas carried fields its count-tokens API doesn’t accept, so every tool group showed 0 tokens. Other rows in the breakdown, such as messages and memory files, aren’t affected. Update to v2.1.196 or later.


[​](#mantle-endpoint-errors)

Mantle endpoint errors

If `/status` does not show `Amazon Bedrock (Mantle)` after you set `CLAUDE_CODE_USE_MANTLE`, the variable is not reaching the process. Confirm it is exported in the shell where you launched `claude`, or set it in the `env` block of your [settings file](settings.md). What a `403` from the Mantle endpoint means depends on whether the error names an IAM action:

- If the error names a `bedrock-mantle:` action, grant your IAM identity that action.
- If the error names no action and your credentials are valid, your AWS account has not been granted access to the model you requested. Contact your AWS account team to request access.

A `400` that names the model ID means that model is not served on Mantle. Mantle has its own model lineup separate from the standard Amazon Bedrock catalog, so inference profile IDs such as `us.anthropic.claude-sonnet-4-6` will not work. Use a Mantle-format ID, or enable [both endpoints](#run-mantle-alongside-the-invoke-api) so Claude Code routes each request to the endpoint where the model is available.


[​](#additional-resources)

Additional resources

- [Amazon Bedrock documentation](https://docs.aws.amazon.com/bedrock/)
- [Amazon Bedrock pricing](https://aws.amazon.com/bedrock/pricing/)
- [Amazon Bedrock inference profiles](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html)
- [Amazon Bedrock token burndown and quotas](https://docs.aws.amazon.com/bedrock/latest/userguide/quotas-token-burndown.html)
- [Claude Code on Amazon Bedrock: Quick Setup Guide](https://builder.aws.com/content/2tXkZKrZzlrlu0KfH8gST5Dkppq/claude-code-on-amazon-bedrock-quick-setup-guide)
- [Claude Code Monitoring Implementation (Amazon Bedrock)](https://github.com/aws-solutions-library-samples/guidance-for-claude-code-with-amazon-bedrock/blob/main/assets/docs/MONITORING.md)

---

## Share session output as artifacts - Claude Code Docs

Source: https://code.claude.com/docs/en/artifacts
Path: 02-Claude-Code-CLI/artifacts.md

## On this page

- [When to use an artifact](#when-to-use-an-artifact)
  - [What an artifact is not](#what-an-artifact-is-not)
- [Create an artifact](#create-an-artifact)
  - [When Claude Code asks before publishing](#when-claude-code-asks-before-publishing)
- [Update an artifact](#update-an-artifact)
- [Find an artifact again](#find-an-artifact-again)
- [Share an artifact](#share-an-artifact)
  - [Link to a specific view](#link-to-a-specific-view)
  - [Let someone edit with you](#let-someone-edit-with-you)
- [Read an artifact shared with you](#read-an-artifact-shared-with-you)
- [Collect comments on an artifact](#collect-comments-on-an-artifact)
  - [Let Claude reply to comments on its own](#let-claude-reply-to-comments-on-its-own)
- [Pull live data with MCP connectors](#pull-live-data-with-mcp-connectors)
  - [How connector calls work for viewers](#how-connector-calls-work-for-viewers)
  - [The page shows no live data for a viewer](#the-page-shows-no-live-data-for-a-viewer)
- [Offer a file download](#offer-a-file-download)
- [What you can build](#what-you-can-build)
  - [Walk through a change](#walk-through-a-change)
  - [Compare alternatives](#compare-alternatives)
  - [Tune with interactive controls](#tune-with-interactive-controls)
  - [Bring the result back to your session](#bring-the-result-back-to-your-session)
  - [Track work in progress](#track-work-in-progress)
- [Improve the visual design](#improve-the-visual-design)
- [Start from a Slides, Design, or Docs template](#start-from-a-slides-design-or-docs-template)
  - [Make a slide deck](#make-a-slide-deck)
  - [Draft a design canvas](#draft-a-design-canvas)
  - [Write a document with Claude Docs](#write-a-document-with-claude-docs)
- [Page constraints](#page-constraints)
- [Availability](#availability)
- [Disable artifacts](#disable-artifacts)
- [Manage artifacts for your organization](#manage-artifacts-for-your-organization)
  - [Enable or disable artifacts](#enable-or-disable-artifacts)
  - [Control connector calls from artifacts](#control-connector-calls-from-artifacts)
  - [Control public sharing](#control-public-sharing)
  - [Set a retention policy](#set-a-retention-policy)
  - [Review the audit log](#review-the-audit-log)
  - [Allowlist the viewer domain](#allowlist-the-viewer-domain)
  - [List and delete artifacts with the Compliance API](#list-and-delete-artifacts-with-the-compliance-api)
- [Related resources](#related-resources)

Artifacts

# Share session output as artifacts

Copy pageCopy page

Artifacts turn Claude Code’s work into live, interactive pages on claude.ai that you can keep private, share with your organization, or publish to a public link.

Copy pageCopy page

Artifacts are available on Pro, Max, Team, and Enterprise plans and require a session signed in with [`/login`](../01-Getting-Started/setup.md#authenticate). See [Availability](#availability) for the full set of requirements.

An [artifact](https://claude.com/features/artifacts) is a live, interactive web page that Claude Code publishes from your session to a private URL on claude.ai. You open it in a browser, and it updates in place as the session continues. Share it from the page header when you want someone else to see it too.


[​](#when-to-use-an-artifact)

When to use an artifact

Use an artifact when terminal text is the wrong medium for what Claude produced: output that is easier to look at and interact with than to read line by line. Claude builds the page from anything your session can reach, including your codebase and data it pulls through your [connected tools](../06-MCP-Tools/General/mcp.md), so the page can show things that would take paragraphs to describe. For example, ask Claude to:

- Walk a reviewer through a pull request with annotated diffs
- Render a dashboard from data the session already pulled
- Lay out several design or implementation options side by side
- Keep an investigation timeline that fills in while a long task runs
- Send a teammate a link instead of pasting output into Slack
- Publish a status board that [pulls fresh data through MCP connectors](#pull-live-data-with-mcp-connectors) each time someone opens it

See [What you can build](#what-you-can-build) for prompts that match these, and [Pull live data with MCP connectors](#pull-live-data-with-mcp-connectors) for the connector-backed board’s prompt.


[​](#what-an-artifact-is-not)

What an artifact is not

An artifact is a capture of work: one self-contained page with no backend, so it can’t serve multiple routes. For a hosted internal tool with a backend, deploy it on your own infrastructure instead. See [Page constraints](#page-constraints) for the full set of limits.


[​](#create-an-artifact)

Create an artifact

Claude may publish an artifact on its own when the output suits a page, or you can ask for one directly. To ask, name the feature or describe the visual output you want in plain language. A good candidate is anything easier to see than to read as text, such as an annotated diff, a chart, or a set of options to compare. The prompts below are two examples; see [What you can build](#what-you-can-build) for more patterns.

```python
Make an artifact that walks through this PR with the diff annotated inline.
```

```python
Build a dashboard artifact of last week's deploy failures by service and keep it updated as you investigate.
```

Unless you name a location, Claude writes the page to an HTML or Markdown file in a temporary directory outside your project, then publishes it. The artifact stays private to you until you [share it](#share-an-artifact). After the first publish, Claude prints the URL, and your browser opens to the new page.

- **Reopen the page**: press `Ctrl+]` at any time to reopen the session’s most recent artifact
- **See this session’s artifacts**: a `⧉` pill below the prompt shows the artifact’s name, or a count when the session has several. In [fullscreen rendering](fullscreen.md), click it to open the [`/artifacts`](#find-an-artifact-again) list
- **Keep the browser from opening**: set `CLAUDE_CODE_ARTIFACT_AUTO_OPEN=0` in your environment
- **Remote Control**: if you sent the prompt through [Remote Control](remote-control.md) from claude.ai, Claude Desktop, or the Claude mobile app, no tab opens on the machine running the session. The browser opens there the next time Claude publishes the artifact from a prompt you type at the terminal

Claude picks the artifact’s title and a browser-tab icon that matches what the page is, such as a chart or a calendar. The title appears in your [gallery of artifacts](#share-an-artifact) on claude.ai and in shared links. Ask Claude for a specific title or tab icon if you want one. If Claude responds that it can’t publish, or writes a local HTML file without a link, artifacts aren’t enabled for your session. Check the [Availability](#availability) requirements. If the terminal shows `Artifacts need a claude.ai login`, see [that error’s entry](errors.md#artifacts-need-a-claude-ai-login) for how to sign in.


[​](#when-claude-code-asks-before-publishing)

When Claude Code asks before publishing

A new artifact that Claude publishes in response to a prompt you type goes through without a permission prompt or classifier review. In these cases Claude Code asks you first, or in [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) has the classifier review the publish:

| When                                                                                                                                                                                       | What Claude Code does                                                                                                                              |
|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------|
| The session is in [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode)                                                                                            | Asks before the first publish of each artifact                                                                                                     |
| The publish declares runtime capabilities for the page, such as [connector calls](#pull-live-data-with-mcp-connectors) or [file downloads](#offer-a-file-download)                         | Asks before that publish                                                                                                                           |
| You shared the artifact publicly                                                                                                                                                           | Asks once per conversation before changing it                                                                                                      |
| Claude publishes in a turn that a [session-scoped scheduled task](scheduled-tasks.md) firing in your session started, rather than a prompt you typed                                 | Asks before the first publish of each artifact                                                                                                     |
| Claude can’t read the file without your approval                                                                                                                                           | Asks before publishing it. An allow rule for the `Artifact` tool doesn’t skip this prompt                                                          |
| In [Manual](permission-modes.md) or `acceptEdits` mode, Claude makes a small change to an artifact’s file it can’t edit without your approval, such as a project file in Manual mode | Asks before publishing the change. You’re asked even if an allow rule covers the `Artifact` tool, because the edit to the file needs your approval |

To let Claude read a file outside your [working directories](permissions.md#working-directories) without your approval, add its folder as a working directory with [`--add-dir`](cli-reference.md#cli-flags) at launch or `/add-dir` during the session. Claude already reads files in those directories, and in the temporary directory it writes pages to, without asking. If a publish prompt includes a sentence such as `Also makes 1 edit to that file on disk.`, Claude is changing the artifact’s file and publishing it in one step. When you approve the prompt, Claude Code publishes the page, then writes the change to your file.


[​](#update-an-artifact)

Update an artifact

Ask Claude to revise the page, or let a long-running task republish as it makes progress. Claude edits the underlying file and publishes again to the same URL.

```python
Add a per-region breakdown below the summary chart and republish.
```

Anyone with the page open sees the update in place. Each publish becomes a version, and from the **Share** control in the page header you can choose which version viewers see. To update an artifact from a different session, give Claude its URL, or attach it with [`/artifacts`](#find-an-artifact-again). Without either, a new session creates a new artifact instead of updating one.

```python
Update https://claude.ai/code/artifact/5fbea6f3-... with today's numbers.
```


[​](#find-an-artifact-again)

Find an artifact again

Run `/artifacts` in Claude Code to list the artifacts you own and the ones shared with you. The current session’s artifacts come first, under **This session**. Select an artifact, then press one of these keys:

- **`Enter`**: opens it in your browser when it’s already attached to the current session, and attaches it when it isn’t. Before v2.1.216, `Enter` opened it in your browser
- **`o`**: opens it in your browser
- **`c`**: copies its link
- **`d`**: outside a [cloud session](claude-code-on-the-web.md), permanently deletes an artifact you own after you confirm. Its link stops working for everyone, including you

Claude Code reads the list from your claude.ai account, so `/artifacts` works in a new session and after `/clear`, when an artifact’s link has scrolled out of the terminal.


[​](#share-an-artifact)

Share an artifact

A new artifact is visible only to you. To share it, open the artifact in your browser and use the **Share** control in the page header. The header also links to your gallery at [claude.ai/code/artifacts](https://claude.ai/code/artifacts), which lists every artifact you have created. Viewers in your organization can see who published the page: on an artifact shared within your organization, your name is in the title menu, and on a public artifact it’s in the page header for signed-in viewers in your organization. A viewer who opens a public link without signing in, or from outside your organization, sees the label `Content is user-generated and unverified.` instead of your name. Who you can share with depends on your plan:

- **Within your organization**: on Team and Enterprise plans, grant access to specific people in your organization, or to everyone in it. Viewers sign in to claude.ai as members of your organization to see the page.
- **Publicly**: share a link that anyone on the internet can open, with no claude.ai sign-in required. On Team and Enterprise plans, public sharing is off until an Owner [enables it for the organization](#control-public-sharing).


[​](#link-to-a-specific-view)

Link to a specific view

If a page has several views, such as tabs or sections, you can link to one of them directly. Ask Claude for the links:

```python
Give me a link to each tab of the deploy failures dashboard.
```

Each link is the artifact’s link with an anchor on the end, such as `#overview`.


[​](#let-someone-edit-with-you)

Let someone edit with you

People you share with are viewers by default: they see each version you publish but can’t change the page. On Team and Enterprise plans, you can also make someone an editor. In the share dialog, add a person and switch their role from **viewer** to **editor**. An editor publishes new versions the same way you [update the artifact from another session](#update-an-artifact): they give Claude the artifact’s URL, or attach it from [`/artifacts`](#find-an-artifact-again), and Claude pulls the current content and republishes with their changes. Everyone with the page open sees each update live. If an editor publishes while Claude holds an older copy of the page, Claude Code refuses a publish built on that copy. Claude then merges its changes onto the newer version and publishes again.


[​](#read-an-artifact-shared-with-you)

Read an artifact shared with you

When someone shares an artifact with you, you can have Claude read it: give Claude its URL, or attach it from [`/artifacts`](#find-an-artifact-again). Claude reads a page someone else wrote the way it reads a web page with [WebFetch](tools-reference.md#webfetch-tool-behavior): it gets a summary of what it asked about rather than the raw page, and the summary reports instructions written into the page instead of relaying them. Claude Code also saves the page’s full source to a local file, which Claude can open when it needs the exact content, such as to republish the artifact as an [editor](#let-someone-edit-with-you). Claude Code asks for your approval before Claude reads the artifact in these cases, in addition to any prompt your permission mode or rules call for:

- **Cloud session without network access**: for a [cloud environment](cloud-environments.md#access-levels), that’s the **None** level. In [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode), the classifier can approve instead; in a [Cowork](../15-Claude-AI-Features/product-cowork.md) session, the approval is yours alone.
- **Another organization’s public artifact**: Claude Code asks you first, even in auto mode. Where Claude Code can’t ask you, such as in `bypassPermissions` mode, Claude can’t read the artifact. Claude can read these artifacts only while [feature-flag fetching](env-vars.md#features-that-need-feature-flag-fetching) is on.
- **Unconfirmed owner or network setting**: when Claude Code can’t confirm who made the artifact, or can’t confirm a cloud session’s network setting, it asks, and your approval covers that one request.
- **Plan mode**: in [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode), Claude Code asks before the Artifact tool reads an artifact someone else in your organization made.

When Claude reads the artifact with WebFetch, WebFetch’s own [prompting rules](tools-reference.md#webfetch-tool-behavior) still apply.


[​](#collect-comments-on-an-artifact)

Collect comments on an artifact

When you share an artifact within your organization, the people you share it with can leave comments on the page, and you can have Claude read those comments and reply to them. You need Claude Code v2.1.221 or later. Claude reads the comments in two cases:

- **You ask Claude to read them**: give Claude the artifact’s URL and ask for the comments. Claude lists each thread and marks the comments someone who can edit the artifact sent to it.
- **Someone who can edit the artifact sends a comment to Claude**: in a thread on the page, they send a comment with **Send to Claude**, or mention `@claude` in one. Either way, they activate the thread.

Claude can reply to or resolve only an activated thread. Other threads stay open until a person resolves them on the page. Viewers see each reply attributed to Claude, via you. If you share an artifact publicly, people whose only access is the public link don’t see its comments and can’t add any. Existing comment threads stay on the artifact, and you and its editors can still read and reply to them. To ask for the comments yourself, give Claude the URL:

```python
Read the comments on https://claude.ai/code/artifact/5fbea6f3-... and make the changes the commenters ask for.
```

If Claude tells you it can’t read comments, confirm your version, your session, and your feature-flag setting:

- You’re running Claude Code v2.1.221 or later.
- You’re not in your first session since you installed Claude Code or upgraded from a version before v2.1.221. In that [first session after an install or upgrade](env-vars.md#first-session-after-an-install-or-upgrade), Claude might not be able to read comments yet; start a new session and ask again.
- You haven’t turned feature-flag fetching off.


[​](#let-claude-reply-to-comments-on-its-own)

Let Claude reply to comments on its own

After your session publishes an artifact, Claude Code watches that artifact for comments. When someone who can edit the artifact sends a comment to Claude, it reaches your session right away, and Claude can read the thread and reply without you asking. You need Claude Code v2.1.228 or later. If you turned [feature-flag fetching](env-vars.md#features-that-need-feature-flag-fetching) off, Claude Code doesn’t watch for comments. Your [permission mode](permission-modes.md) decides what Claude does when a sent comment arrives:

- **Claude replies on its own**: if you’re in a permission mode that lets Claude post the reply without asking you, Claude reads the thread and replies. You see `Auto-replied to comment thread on Artifact: <name>`.
- **Claude waits for you**: outside plan mode, when posting the reply would need your approval, you see `Comments are waiting on Artifact: <name>`. Claude then asks you for approval to read the thread, and again to post the reply.
- **Claude pauses in plan mode**: you see `Comments are waiting on Artifact: <name>`, and Claude doesn’t reply until you leave plan mode and ask it to read and reply.

Claude also stops replying on its own to an artifact after it handles 60 sent comments or thread activations on that artifact within an hour. You see `Comments are waiting on Artifact: <name>` once, and Claude picks up again as that hour’s comments age out. Run `/tasks` to see the artifacts your session is watching. `/tasks` groups the watches Claude Code started on its own under the **System tasks** row. Press `Enter` on that row to list them. A watch you asked Claude to start appears under **Monitors**. You can stop Claude from replying on its own in any of these ways:

- **Press Ctrl+C once at an idle prompt**: Claude pauses replying on every artifact your session is watching. Replies start again after you send your next message.
- **Stop the task in `/tasks`**: Claude stops replying on that artifact until you ask it to resume replies there. Publishing the artifact again doesn’t start replies again, and the stop still applies when you resume the session later.
- **Press `Ctrl+X Ctrl+K` twice within 3 seconds**: the chord that [stops every running background subagent](interactive-mode.md#general-controls) also stops Claude from replying on every artifact for the rest of the session. Asking Claude to resume replies doesn’t undo this stop.

A watch that Claude Code started on its own can end after the artifact goes several hours without activity. To start the watch again, publish the artifact again or ask Claude to watch it. If the service that delivers comments becomes unavailable or stops answering, Claude Code keeps trying to reconnect for a while, then stops watching each artifact your session was watching.


[​](#pull-live-data-with-mcp-connectors)

Pull live data with MCP connectors

An artifact can call [MCP connectors](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) each time someone views it, so the page shows current data rather than a snapshot from the session that built it. Connector calls from artifacts are available on Pro, Max, Team, and Enterprise plans and require Claude Code v2.1.209 or later. On earlier versions, Claude publishes the page with whatever data the session gathered while building it. To create a connector-backed page, name the connector and the data you want in your prompt:

```python
Build a dashboard artifact of our open pull requests that pulls the live list through my GitHub connector when the page loads.
```

Claude declares which connectors the page may call as part of publishing, and the page can’t call connectors outside that declaration. Only connectors from your claude.ai account qualify: Claude names them in the declaration, and when someone views the page, each call [runs through the viewing account’s own connection](#how-connector-calls-work-for-viewers) to that connector. Local MCP servers you configure in Claude Code, such as servers from `.mcp.json`, can supply data while Claude builds the page, but the published page can’t call them. The page fetches data when it loads and can refresh on an interval or when a viewer uses a refresh control on the page. Responses are cached in the viewer’s browser, so a reopened page renders from the cached responses immediately, then updates with fresh results.


[​](#how-connector-calls-work-for-viewers)

How connector calls work for viewers

When a published page calls a connector, the call uses the account of the person viewing the page, not the account of the person who published it:

- **Each viewer uses their own connectors**: calls go through the viewing account’s connected tools, so two people opening the same dashboard can see different data depending on what their accounts can access. The page never sees anyone’s credentials; claude.ai makes the calls on the page’s behalf.
- **Viewers approve access first**: claude.ai asks each viewer for permission before the page’s first connector call. A viewer who declines, or who hasn’t connected a connector the page uses, still sees the page without its live sections.
- **Actions use the viewer’s account too**: a page can offer controls that invoke connector tools with side effects, such as posting a message or updating an issue. The action goes through the account of whoever selects the control.

When you plan to share a connector-backed page, ask Claude to include a fallback message in each live section that names the connector it needs. A viewer who’s missing the connection then sees what to connect instead of an empty section. You can [share a connector-backed page](#share-an-artifact) within your organization or publicly, as your plan and organization settings allow. Connector calls don’t run for a viewer who opens the public link without signing in to claude.ai, or from outside your organization. That viewer sees the page without its live sections.


[​](#the-page-shows-no-live-data-for-a-viewer)

The page shows no live data for a viewer

When a connector-backed page renders but its live sections stay empty for a viewer in your organization, work through these causes:

- **The viewer hasn’t connected the connector**: connectors are per-account, so each viewer needs their own connection to every connector the page calls. They can add one under **Settings \> Connectors** on claude.ai, then reload the page.
- **The viewer declined the permission ask**: a denial lasts for the rest of that page load. Reloading the page brings the permission ask back.
- **Connector calls are turned off for the organization**: an Owner controls the [**Enable artifact connectors** toggle](#control-connector-calls-from-artifacts) in admin settings.
- **The page calls tool names the connector doesn’t expose**: the affected sections stay empty for everyone, including you. This can happen when a page names the individual tools behind a gateway-style connector that exposes only a few tools of its own. Ask Claude to fix the tool names the page calls and publish it again. When Claude publishes the page and that connector’s tools are available in your session, Claude Code checks the tool names the page declares against them, warns Claude about names that don’t match, and refuses the publish when none do. Before v2.1.265, it published the page without checking them.


[​](#offer-a-file-download)

Offer a file download

An artifact can offer viewers a file the page generates, such as a CSV export of a table or a PNG of a chart. The viewer saves it through a download control on the page, such as a button. File downloads are a runtime capability that claude.ai enables per account, so Claude checks whether your account has it before it builds the control. Viewers can’t save a file from an ordinary download link or a script on the page, because the artifact viewer on claude.ai blocks any download the page starts itself, including links to `data:` or `blob:` URLs. If a page has download buttons built that way, ask Claude to rebuild them with the downloads capability. To offer a file, ask for the control and the file format in your prompt:

```python
Add a button that downloads this table as a CSV file.
```

Claude declares the downloads capability as part of publishing, the same way it [declares connectors](#pull-live-data-with-mcp-connectors).


[​](#what-you-can-build)

What you can build

An artifact is a single HTML page, so anything you can express in HTML, CSS, and inline JavaScript is in scope. The patterns below come up most often.


[​](#walk-through-a-change)

Walk through a change

Ask for a page that renders a diff or a design change with annotations beside the relevant lines, so reviewers can read your reasoning next to the code instead of reconstructing it from a description.

```python
Make an artifact that walks through this PR. Render the diff with margin annotations and color-code findings by severity.
```


[​](#compare-alternatives)

Compare alternatives

Ask for several variants on one page so you can evaluate them against each other. This works for layouts, copy, API shapes, or implementation plans.

```python
Make an artifact with four distinctly different layouts for the settings panel. Vary density and grouping, and lay them out as a grid with a one-line tradeoff under each.
```


[​](#tune-with-interactive-controls)

Tune with interactive controls

Ask for sliders, toggles, or input fields bound to whatever you are adjusting, so you can explore values directly instead of describing them.

```python
Build an artifact with sliders for the easing curve, duration, and delay so I can try values on this transition. Show the animation live as I move them.
```


[​](#bring-the-result-back-to-your-session)

Bring the result back to your session

An artifact can act as a lightweight editor for a decision you then send back to Claude. Ask for an export control that produces text you can paste into the terminal, so the result of interacting with the page flows back into the session instead of staying on the page.

```python
Make a triage board artifact with each open issue as a draggable card across Now, Next, Later, and Cut columns. Add a "Copy as prompt" button that gives me the final ordering to paste back here.
```


[​](#track-work-in-progress)

Track work in progress

Ask Claude to keep an artifact current while a long task runs, so anyone with the link can follow along without reading the terminal.

```python
Turn this migration plan into a checklist artifact. Check items off as you complete them and add a note for anything you skip.
```


[​](#improve-the-visual-design)

Improve the visual design

Claude applies a built-in design skill when it builds an artifact, so pages get a deliberate palette, typography, and layout without extra prompting. That skill also looks for an existing design system in your project before choosing its own. Design tokens are the named color, typography, and spacing values your design system reuses. To keep artifacts consistent with your product’s branding, record them where Claude can find them, such as the project’s [CLAUDE.md](memory.md) or a theme file in your repository:

```python
## Design system

- Colors: primary #1a4d8f, accent #f59e0b, surface #f8fafc
- Typography: Inter for body, JetBrains Mono for code
- Spacing: 8px scale, 6px border radius
```

Claude treats your design system as higher precedence than its own choices, and your prompt as higher precedence than both. The heading and format above are an example; any clear list of colors, fonts, and spacing works. For typography, Claude can load a typeface from Google Fonts, the one external font source an artifact page can load from. Claude inlines any other typeface as a `@font-face` data URI and gives every typeface a fallback stack, so the page still renders if a font doesn’t load. To use a specific typeface, name it in your prompt or your design system.


[​](#start-from-a-slides-design-or-docs-template)

Start from a Slides, Design, or Docs template

Instead of building a page from scratch, Claude can start an artifact from one of the templates on your claude.ai account: [Claude Slides](../15-Claude-AI-Features/what-are-artifacts-and-how-do-i-use-them-claude-help-center.md#h_11d5a9a5fa) for a presentation, [Claude Design](../15-Claude-AI-Features/get-started-with-claude-design.md) for a visual design, or [Claude Docs](https://support.claude.com/en/articles/16923645-get-started-with-claude-docs) for a document other people will read and edit. Each opens in its own editor on claude.ai, where you and your teammates change it directly or ask Claude to, and export it to formats such as PowerPoint, PDF, or Word. To start from a template, describe what you want, such as “turn the migration notes into a deck for Thursday’s review” or “write this plan up as a doc for the team”. Claude picks the matching template, fills it from your request and from what the session already has, and gives you the link. For a deck or a design you can also run `/slides` or `/design` with a brief.

Templates are in beta. They’re on by default on Pro, Max, and Team plans. On Enterprise plans, an Owner [turns each template on](../17-Billing-Plans/artifacts-admin-guide-for-team-and-enterprise-plans.md) under **Organization settings \> Artifacts**. If your organization has the Slides template turned off, `/slides` doesn’t appear; if it has the Design template turned off, `/design` doesn’t draft designs. Both commands require Claude Code v2.1.265 or later and a session where [artifacts are available](#availability).


[​](#make-a-slide-deck)

Make a slide deck

Run `/slides` with a brief that says what the deck covers and who it’s for:

```python
/slides a quarterly review of the platform team's reliability work, for the engineering all-hands
```

Claude creates a Claude Slides artifact and gives you the link. Open it in a desktop browser to edit or present the deck. If you run `/slides` without a brief, Claude asks what the deck should be about before creating anything.


[​](#draft-a-design-canvas)

Draft a design canvas

To mock up a UI, a screen flow, a landing page, or a poster rather than build a page, run `/design` with a brief. Claude drafts the design as artboards on one canvas and publishes the canvas as a Claude Design artifact. The brief names what you want drawn:

```python
/design a settings screen for a mobile banking app
```

Open the published artifact in a desktop browser to review the artboards. Select an element on an artboard and change it, and your edits save automatically. You can export each artboard as PNG or PDF.


[​](#write-a-document-with-claude-docs)

Write a document with Claude Docs

Claude Docs reaches Claude Code as a claude.ai [connector](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) rather than a command. When it’s connected, `/mcp` lists it as `claude.ai Claude Docs`. A request for a document meant for other people then goes to Claude Docs instead of an artifact page: a spec, a proposal, or a write-up of the plan you worked through in the session. Claude gives you the doc’s link when it’s drafted. A document that belongs in the codebase, such as a README, stays a file. To get a file for something Claude would otherwise put in Claude Docs, name the format, such as `.docx` or a Markdown file in the repository. To turn the connector off, add `claude.ai Claude Docs` to `deniedMcpServers` or use the `/mcp` toggle, both described in [Disable claude.ai connectors](../06-MCP-Tools/General/mcp.md#disable-claude-ai-connectors).


[​](#page-constraints)

Page constraints

Each artifact is one self-contained page. Claude Code wraps the file you publish in an HTML document shell and serves it under a strict Content Security Policy (CSP), which shapes what the page can do.

| Constraint        | Effect                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
|:------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| External requests | The page can load typefaces from Google Fonts, and scripts from [five public CDN hosts](#allowlist-the-viewer-domain): cdnjs, unpkg, the Tailwind and jQuery CDNs, and selected paths on jsDelivr such as `/npm/`. The CSP blocks every external image and all other external scripts, stylesheets, and fonts, and lets `fetch`, XHR, and WebSocket calls reach only the page’s own origin and the Google Fonts hosts. Claude therefore loads any library the page needs from one of those CDNs, inlines all other CSS and JavaScript, and embeds images as data URIs. [Connector calls](#pull-live-data-with-mcp-connectors) go through claude.ai, which makes the network call itself. |
| No backend        | An artifact is a static page. It can’t authenticate viewers itself.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| Downloads         | The page can’t start a download itself. To let viewers save a file the page generates, Claude declares the downloads capability. See [Offer a file download](#offer-a-file-download).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Single page       | Relative links do not resolve, because nothing is deployed alongside the page. For multi-section content, Claude uses in-page anchors rather than separate files.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Source file types | The published file must be `.html`, `.htm`, or `.md`, and must decode as UTF-8, or as little-endian UTF-16 by its byte-order mark. Markdown files render as styled document pages with syntax-highlighted code. A file that doesn’t decode, or that contains the replacement character `U+FFFD`, is [refused with the line and column to fix](errors.md#the-source-file-is-not-valid-utf-8-text).                                                                                                                                                                                                                                                                                  |
| Source location   | A file at a path that names a network host is refused without being read. See [Not published: that file is on a network share](errors.md#not-published-that-file-is-on-a-network-share) for which paths are refused and the mapped-drive exception on Windows.                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Rendered size     | The rendered page must be 16 MiB or smaller. Large embedded images are the usual cause when a publish fails for size.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |

Generating an artifact uses output tokens like any other response, and a styled page is more token-intensive than the same content as terminal text. Inline CSS, JavaScript for interactive controls, and especially images embedded as data URIs are the main contributors. To reduce an artifact’s token cost:

- Prefer SVG, or HTML and CSS, for diagrams over embedded raster images
- Omit interactivity you do not need
- Have the page summarize large datasets rather than inline them in full


[​](#availability)

Availability

Artifacts require every condition below. When one is not met, Claude writes a local HTML file or says it cannot publish instead.

| Requirement         | Available when                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
|:--------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Plan                | Pro, Max, Team, or Enterprise. On Pro and Max plans, artifacts are private to you until you share them, and no admin management applies. On Team and Enterprise plans, artifacts are on by default, and an Owner can [turn them off for the organization](#manage-artifacts-for-your-organization) in claude.ai admin settings.                                                                                                                                                                                                                                                                                                                                                                              |
| Authentication      | The session is backed by a claude.ai account: sign in with `/login` in the CLI or desktop app. Claude Tag sessions are signed in through the agent’s identity, so no step is needed there. Sessions using an API key, [gateway token](../13-Enterprise-Admin/llm-gateway.md), or cloud-provider credential cannot publish.                                                                                                                                                                                                                                                                                                                                                                                                    |
| Model provider      | Anthropic API. Not available on [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), or [Microsoft Foundry](microsoft-foundry.md).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| Organization policy | Customer-managed encryption keys (CMEK), HIPAA, and [Zero Data Retention](zero-data-retention.md) are not enabled for the organization.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| Surface             | Claude Code CLI, or the Claude desktop app version 1.13576.0 or later. [Claude Tag](https://claude.com/docs/claude-tag/overview) sessions can also publish artifacts when both Claude Tag and artifacts are enabled for the organization. Sessions served by [`claude remote-control`](remote-control.md) can publish artifacts when you started the session yourself. Requires Claude Code v2.1.281 or later. Off by default in the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md), the GitHub Action, and MCP-server contexts, when you run Claude Code with [`-p`](headless.md) from your own terminal or scripts, and when [`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`](env-vars.md) is set. |

Whether artifacts are allowed for your organization comes from your organization’s policy, which Claude Code loads from `api.anthropic.com`. When Claude Code can’t load the policy, artifacts are unavailable. When you ask for one, Claude says why. If a proxy, VPN, or web filter is involved, ask your IT admin to let `api.anthropic.com` through. Claude Code keeps retrying in the background, and artifacts become available once the policy loads and allows them.


[​](#disable-artifacts)

Disable artifacts

To turn artifacts off for your own sessions regardless of your organization’s setting, use any of:

| Where                                     | What to do                                                                                                                                 |
|:------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------|
| [`/config`](commands.md)            | Turn the **Artifacts** row off, which writes [`"enableArtifact": false`](settings-reference.md#enableartifact) to your user settings |
| [Settings file](settings.md)        | Set `"enableArtifact": false`. The deprecated `"disableArtifact": true` also turns artifacts off                                           |
| [Environment variable](env-vars.md) | Set `CLAUDE_CODE_DISABLE_ARTIFACT=1`                                                                                                       |
| [Permission rule](permissions.md)   | Add `Artifact` to `permissions.deny`                                                                                                       |

Once you turn artifacts off in a [`--settings`](cli-reference.md#cli-flags) file or with `CLAUDE_CODE_DISABLE_ARTIFACT`, or your administrator turns them off in [managed settings](../13-Enterprise-Admin/server-managed-settings.md), no settings file turns them back on. You can also set `"enableArtifact": false` in a project’s `.claude/settings.json` or `.claude/settings.local.json` to turn artifacts off for sessions in that project. An `"enableArtifact": true` in either file doesn’t turn them back on. Honoring the key in project and local settings requires Claude Code v2.1.242 or later. If you add a `WebFetch` deny or ask rule with no `domain:` part, it doesn’t turn artifacts off or block artifact reads. A [`WebFetch(domain:claude.ai)` rule in `deny` or `ask` does apply to artifact reads](permissions.md#allow-or-deny-every-fetch).


[​](#manage-artifacts-for-your-organization)

Manage artifacts for your organization

Owners on Team and Enterprise plans control artifacts from [claude.ai admin settings](https://claude.ai/admin-settings/artifacts). Artifact content is stored on Anthropic-operated infrastructure and is visible only to authenticated members of the publishing organization and the people they share it with, unless the artifact is [shared publicly](#control-public-sharing).


[​](#enable-or-disable-artifacts)

Enable or disable artifacts

To enable or disable artifacts for the whole organization, go to [**Organization settings \> Artifacts**](https://claude.ai/admin-settings/artifacts) and use the **Artifacts** toggle. On Enterprise plans with role-based access control, you can additionally scope artifacts to specific roles: go to [**Organization settings \> Roles**](https://claude.ai/admin-settings/roles), edit a role, and set the **Artifacts** permission.


[​](#control-connector-calls-from-artifacts)

Control connector calls from artifacts

[Connector calls from artifacts](#pull-live-data-with-mcp-connectors) have their own toggle, separate from the **Artifacts** toggle that turns artifacts on or off. Go to [**Organization settings \> Capabilities**](https://claude.ai/admin-settings/capabilities) and use the **Enable artifact connectors** toggle. The same toggle governs connector calls from artifacts created in claude.ai conversations.


[​](#control-public-sharing)

Control public sharing

Public sharing is off by default on Team and Enterprise plans. To let members publish artifacts to public links that anyone can view without signing in, go to [**Organization settings \> Artifacts**](https://claude.ai/admin-settings/artifacts) and turn on **External sharing** under the **Artifacts** toggle. Turning it back off blocks access through existing public links without changing each artifact’s audience; access resumes if you re-enable it.


[​](#set-a-retention-policy)

Set a retention policy

To set how long artifacts are kept before automatic deletion, go to [**Organization settings \> Data and privacy**](https://claude.ai/admin-settings/data-privacy-controls). You can set separate retention periods for artifacts that are still private to their author and artifacts that have been shared.


[​](#review-the-audit-log)

Review the audit log

Publishing, sharing, and deleting an artifact each appear in your organization’s audit log under the `claude_artifact_*` event types, the same family used for artifacts created in claude.ai conversations.


[​](#allowlist-the-viewer-domain)

Allowlist the viewer domain

The viewer on claude.ai loads each artifact from a sandboxed `*.claudeusercontent.com` origin. If your organization restricts outbound network access, add that domain to your allowlist alongside `claude.ai`. See [Network access requirements](../13-Enterprise-Admin/network-config.md#network-access-requirements) for the full list. An artifact that loads a typeface from [Google Fonts](#improve-the-visual-design) also requests `fonts.googleapis.com` and `fonts.gstatic.com`. Both hosts are optional. If you block them, artifacts render in fallback typefaces. Block with a fast rejection rather than a silent drop so the font request fails immediately instead of delaying the page’s first render. Artifacts can also load JavaScript libraries, such as React or a charting package, from `cdnjs.cloudflare.com`, `cdn.jsdelivr.net`, `cdn.tailwindcss.com`, `code.jquery.com`, and `unpkg.com`, and from no other external host. If you block those hosts, the parts of an artifact that depend on a library don’t work, and unlike a blocked font, a blocked library has no fallback. Block with a fast rejection here too, so a blocked library request fails at once rather than hanging until it times out.


[​](#list-and-delete-artifacts-with-the-compliance-api)

List and delete artifacts with the Compliance API

The [Compliance API](https://docs.claude.com/en/api/compliance) provides endpoints to list an organization’s artifacts, retrieve a specific version’s content, and delete an artifact:

| Method   | Endpoint                                                                 |
|:---------|:-------------------------------------------------------------------------|
| `GET`    | `/v1/compliance/apps/code/artifacts`                                     |
| `GET`    | `/v1/compliance/apps/code/artifacts/{artifact_id}/versions/{version_id}` |
| `DELETE` | `/v1/compliance/apps/code/artifacts/{artifact_id}`                       |

For the request and response schemas, see the [Compliance API reference](../04-API-Reference/Admin/compliance-apps-code-artifacts.md).


[​](#related-resources)

Related resources

- Browse [prompting patterns and workflows](prompt-library.md) that pair with artifacts
- Turn an artifact prompt you reuse into a [skill](../08-Plugins-Skills/skills.md) so you can invoke it as a command
- [Connect MCP servers](../06-MCP-Tools/General/mcp.md) so Claude can pull data into an artifact while it builds the page

---

## Authentication - Claude Code Docs

Source: https://code.claude.com/docs/en/authentication
Path: 02-Claude-Code-CLI/authentication.md

## On this page

- [Log in to Claude Code](#log-in-to-claude-code)
  - [Login prompt still appears after an earlier sign-in](#login-prompt-still-appears-after-an-earlier-sign-in)
  - [Log in with multiple accounts](#log-in-with-multiple-accounts)
- [Set up team authentication](#set-up-team-authentication)
  - [Claude for Teams or Enterprise](#claude-for-teams-or-enterprise)
  - [Claude Console authentication](#claude-console-authentication)
  - [Sign in without an API key](#sign-in-without-an-api-key)
  - [Cloud provider authentication](#cloud-provider-authentication)
  - [Restrict login to your organization](#restrict-login-to-your-organization)
  - [Restrict which API providers a machine may use](#restrict-which-api-providers-a-machine-may-use)
- [Credential management](#credential-management)
  - [Renew an expiring login](#renew-an-expiring-login)
  - [Authentication precedence](#authentication-precedence)
  - [Anthropic profiles and federation credentials](#anthropic-profiles-and-federation-credentials)
  - [Generate a long-lived token](#generate-a-long-lived-token)

Setup and access

# Authentication

Copy pageCopy page

Log in to Claude Code and configure authentication for individuals, teams, and organizations.

Copy pageCopy page

Claude Code supports multiple authentication methods depending on your setup. Individual users can log in with a claude.ai account, while teams can use Claude for Teams or Enterprise, the Claude Console, or a cloud provider like Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry.


[​](#log-in-to-claude-code)

Log in to Claude Code

After [installing Claude Code](../01-Getting-Started/setup.md#install-claude-code), run `claude` in your terminal. Claude Code opens a browser window for you to log in on first launch, except in cases such as these, where it can skip the login prompt:

- **API key**: you’ve set the `ANTHROPIC_API_KEY` environment variable and you approve the key when Claude Code asks whether to use it
- **Earlier sign-in**: you ran [`claude auth login`](cli-reference.md#cli-commands) in your shell before your first session, or you rebuilt a dev container that keeps your credentials in a [volume](devcontainer.md#persist-authentication-and-settings-across-rebuilds). If you see the login prompt anyway, [check what can cause it](#login-prompt-still-appears-after-an-earlier-sign-in).

If the browser doesn’t open automatically, press `c` to copy the login URL to your clipboard, then paste it into your browser. If your browser shows a login code instead of redirecting back after you sign in, paste it into the terminal at the `Paste code here if prompted` prompt. This happens when the browser can’t reach Claude Code’s local callback server, which is common in WSL2, SSH sessions, and containers. When login completes, the terminal shows `Login successful` and prompts you to press `Enter` to continue. You can authenticate with any of these account types:

- **Claude Pro or Max subscription**: log in with your claude.ai account. Subscribe at [claude.com/pricing](../17-Billing-Plans/pricing.md).
- **Claude for Teams or Enterprise**: log in with the claude.ai account your team admin invited you to.
- **Claude Console**: log in with your Console credentials. Your admin must have [invited you](#claude-console-authentication) first. You can sign in with or without [creating an API key](#sign-in-without-an-api-key).
- **Cloud providers**: if your organization uses [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), or [Microsoft Foundry](microsoft-foundry.md), set the required environment variables before running `claude`, or select **3rd-party platform** at the login prompt, which launches an interactive setup wizard for Bedrock and Vertex AI. No browser login is needed.
- **Cloud gateway**: if your organization runs a self-hosted [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md), sign in with corporate SSO through `/login`. The gateway-issued token is the session’s only credential.

Admins can direct which login method developers use and require claude.ai logins to belong to a specific organization; see [Restrict login to your organization](#restrict-login-to-your-organization). To log out and re-authenticate, type `/logout` at the Claude Code prompt. Logging out also resets your first-launch setup state, so the next time you run `claude` it walks you through login and setup again. If you’re having trouble logging in, see [authentication troubleshooting](troubleshoot-install.md#login-and-authentication).


[​](#login-prompt-still-appears-after-an-earlier-sign-in)

Login prompt still appears after an earlier sign-in

If you signed in earlier and first-launch setup shows the login prompt instead of [skipping it](#log-in-to-claude-code), check for causes such as these:

- **Expired sign-in**: your earlier sign-in expired and Claude Code can’t refresh it. Log in again at the prompt.
- **Login restricted to an organization**: an administrator set [`forceLoginOrgUUID`](settings-reference.md#forceloginorguuid) in managed settings to [require logins from specific organizations](#restrict-login-to-your-organization). The prompt appears whether or not your account belongs to one of them. Log in with an account in a required organization. If you don’t have one, ask your administrator to add you.
- **Required login method**: your sign-in isn’t the kind that [`forceLoginMethod`](settings-reference.md#forceloginmethod) in a settings file requires. With `"claudeai"`, an API key from an earlier Claude Console login doesn’t count as an existing sign-in. With `"console"`, a claude.ai account doesn’t. Log in with the kind of account that setting names.
- **Older version**: before v2.1.290, the prompt appeared during setup whether or not you were signed in. [Update Claude Code](../01-Getting-Started/setup.md#update-claude-code) to skip it.


[​](#log-in-with-multiple-accounts)

Log in with multiple accounts

To stay signed in to multiple accounts at once, such as work and personal accounts, give each account its own configuration directory. When you start `claude`, set the [`CLAUDE_CONFIG_DIR`](env-vars.md#variables) environment variable to the directory for the account you want to use. Each directory has its own settings, session history, and claude.ai login or API key. For example, in Bash or Zsh, add this alias to `~/.bashrc` or `~/.zshrc` so that `claude-work` uses your work account while `claude` keeps your personal one:

```python
alias claude-work='CLAUDE_CONFIG_DIR=~/.claude-work claude'
```

After you open a new terminal and run `claude-work` for the first time, Claude Code walks you through login and setup for the new directory. Separate directories don’t keep two Claude Console sign-ins [without an API key](#sign-in-without-an-api-key) apart, because Claude Code stores that kind of sign-in outside the configuration directory.


[​](#set-up-team-authentication)

Set up team authentication

For teams and organizations, you can configure Claude Code access in one of these ways:

- [Claude for Teams or Enterprise](#claude-for-teams-or-enterprise), recommended for most teams
- [Claude Console](#claude-console-authentication)
- [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md), a self-hosted gateway that signs developers in with your IdP and routes inference to the cloud provider you configure
- [Amazon Bedrock](amazon-bedrock.md)
- [Google Cloud’s Agent Platform](google-vertex-ai.md)
- [Microsoft Foundry](microsoft-foundry.md)


[​](#claude-for-teams-or-enterprise)

Claude for Teams or Enterprise

[Claude for Teams](../17-Billing-Plans/pricing.md#team-&-enterprise) and [Claude for Enterprise](https://anthropic.com/contact-sales?utm_source=claude_code&utm_medium=docs&utm_content=authentication_enterprise) provide the best experience for organizations using Claude Code. Team members get access to both Claude Code and Claude on the web with centralized billing and team management.

- **Claude for Teams**: self-service plan with collaboration features, admin tools, SSO, billing management, and [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) for organization-wide Claude Code configuration. Best for smaller teams.
- **Claude for Enterprise**: adds domain capture, role-based permissions, and the compliance API. Best for larger organizations with security and compliance requirements.

1

Subscribe

Subscribe to [Claude for Teams](../17-Billing-Plans/pricing.md#team-&-enterprise) or contact sales for [Claude for Enterprise](https://anthropic.com/contact-sales?utm_source=claude_code&utm_medium=docs&utm_content=authentication_enterprise_step).

2

Invite team members

Invite team members from the admin dashboard.

3

Install and log in

Team members install Claude Code and log in with their claude.ai accounts.


[​](#claude-console-authentication)

Claude Console authentication

For organizations that prefer API-based billing, you can set up access through the Claude Console.

1

Create or use a Console account

Use your existing Claude Console account or create a new one.

2

Add users

You can add users through either method:

- Bulk invite users from the Console’s Members page at [platform.claude.com/settings/members](../04-API-Reference/Other/playground.md): click **Invite**
- [Set up SSO](../21-Account-Support/setting-up-single-sign-on-sso.md)

3

Assign roles

When inviting users, assign one of:

- **Claude Code** role: users can only create Claude Code API keys
- **Developer** role: users can create any kind of API key

4

Users complete setup

Each invited user needs to:

- Accept the Console invite
- [Check system requirements](../01-Getting-Started/setup.md#system-requirements)
- [Install Claude Code](../01-Getting-Started/setup.md#install-claude-code)
- Log in with Console account credentials


[​](#sign-in-without-an-api-key)

Sign in without an API key

You can sign in to your Console account without creating an API key, even when your organization doesn’t let developers create them. Choose the Anthropic Console account at the `/login` prompt and Claude Code asks how you want to sign in. Requires Claude Code v2.1.242 or later. Both routes sign you in to Console in the browser and differ in what Claude Code stores afterwards:

- **Sign in with your Console account**, labeled `(recommended)`: Claude Code keeps the OAuth token from that sign-in and stores it as an [Anthropic profile](#anthropic-profiles-and-federation-credentials). It creates no API key
- **Create an API key**, labeled `(legacy)`: Claude Code creates a Console API key for you and stores it with your other credentials

In practice, the profile stores an OAuth login while an API key is a static credential. Claude Code refreshes the profile’s login automatically, and when refresh fails, requests fail with an [expired profile login error](errors.md#anthropic-profile-login-expired) until you sign in again. You don’t get the choice on every machine. Claude Code creates an API key without asking in these cases:

- You run against a cloud provider, such as [Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry](third-party-integrations.md) or [Claude Platform on AWS](claude-platform-on-aws.md)
- Any settings file sets [`forceLoginOrgUUID`](#restrict-login-to-your-organization), or sets `forceLoginMethod` to `"claudeai"` or `"console"`
- A managed settings source on your machine, such as the managed settings file, an MDM profile, or the cached server-managed settings, exists but Claude Code [can’t read it](../13-Enterprise-Admin/managed-settings.md#invalid-entries-in-managed-settings) and no other managed source supplies a policy

Unset `ANTHROPIC_API_KEY` before you sign in without a key. After you sign in without a key, you have a profile instead of a stored API key:

- **Which profile it writes**: Claude Code writes the profile named by `ANTHROPIC_PROFILE`, or your active profile, or `default`. If that profile is a federation profile, Claude Code refuses the sign-in instead of overwriting it
- **What it signs you out of**: Claude Code signs you out of any claude.ai login stored on the machine
- **How to undo it**: run `/logout`, which removes and revokes the credential this sign-in wrote

Everything else about profiles applies to this sign-in, including where it ranks against your other credentials, the `Profile` row you get in `/status`, and the features that need a claude.ai login. See [Anthropic profiles and federation credentials](#anthropic-profiles-and-federation-credentials).


[​](#cloud-provider-authentication)

Cloud provider authentication

For teams using Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry:

1

Follow provider setup

Follow the [Amazon Bedrock docs](amazon-bedrock.md), [Google Cloud’s Agent Platform docs](google-vertex-ai.md), or [Microsoft Foundry docs](microsoft-foundry.md).

2

Distribute configuration

Distribute the environment variables and instructions for generating cloud credentials to your users. Read more about how to [manage configuration here](settings.md).

3

Install Claude Code

Users can [install Claude Code](../01-Getting-Started/setup.md#install-claude-code).


[​](#restrict-login-to-your-organization)

Restrict login to your organization

To require that developers’ claude.ai logins belong to a specific Anthropic organization, set [`forceLoginMethod`](settings-reference.md#forceloginmethod) and [`forceLoginOrgUUID`](settings-reference.md#forceloginorguuid) in [managed settings](../13-Enterprise-Admin/managed-settings.md). Set `forceLoginOrgUUID` to your organization ID, shown in [claude.ai admin settings](https://claude.ai/admin-settings/organization) for Claude for Teams or Enterprise organizations. Claude Code reports an error for a claude.ai login to any other organization and exits at startup if the claude.ai credential in use belongs to an organization that isn’t listed. For Claude Console logins, Claude Code uses `forceLoginOrgUUID` to pre-select the organization on the Console sign-in page when you set it to a single Console organization ID, shown at [platform.claude.com/settings/organization](../04-API-Reference/Other/playground.md). It doesn’t check which organization the resulting Console credential belongs to, at login or at startup. A developer who logged in with a Console account before you deployed the keys stays logged in, and that saved key is blocked on a machine that also requires the [gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sign-in or in a session that selects a cloud provider. If you set `forceLoginOrgUUID` in any settings file, Claude Code stops offering the [keyless Console sign-in](#sign-in-without-an-api-key) in the sessions that file applies to and creates an API key instead. To direct developers to claude.ai sign-in instead, set `forceLoginMethod` to `"claudeai"`. On Claude Code v2.1.212 or later, every login path listed here applies `forceLoginMethod`. On the terminal’s interactive login screen, reached by `/login` or first-run onboarding, Claude Code pre-selects a `claudeai` or `console` method without enforcing it, so even with `forceLoginMethod` set to `"claudeai"`, a developer can still complete a Console login there. The paths differ on `forceLoginOrgUUID`:

- **Terminal, [VS Code extension](../03-IDE-Integrations/vs-code.md), and Agent SDK logins**: verify `forceLoginOrgUUID` for claude.ai account logins
- **`claude setup-token` and `/install-github-app`**: enforce only `forceLoginMethod`, so they can mint a token in a different organization
- **[Gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sign-in**: selected by `forceLoginMethod: "gateway"` rather than restricted by it, and doesn’t authenticate against an Anthropic organization, so `forceLoginOrgUUID` doesn’t apply; use your gateway identity provider to restrict access

Deploy the keys through your device management tooling. [Server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) reach only accounts that are already authenticated into your organization, so they can’t redirect a developer’s first login. If your organization distributes server-managed settings as well, set the keys in both places: managed-settings sources [don’t merge](../13-Enterprise-Admin/server-managed-settings.md#settings-precedence), and cached server-managed settings replace the device-managed file apart from a few [per-key exceptions](../13-Enterprise-Admin/server-managed-settings.md#per-key-exceptions-across-managed-sources). `forceLoginOrgUUID` and the `"claudeai"` and `"console"` values of `forceLoginMethod` aren’t among those exceptions, so keep them in both places. In a [gateway](../13-Enterprise-Admin/claude-apps-gateway.md) deployment, also keep `forceLoginMethod` and `forceLoginOrgUUID` out of the [settings the gateway serves](../13-Enterprise-Admin/claude-apps-gateway-config.md#managed). The keys also decide whether a session that doesn’t use a login credential can start. See [`forceLoginOrgUUID`](settings-reference.md#forceloginorguuid) in the settings reference for the full behavior.

- **`ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper`**: blocked at startup. Under `forceLoginOrgUUID`, organization membership can’t be verified for an environment credential, and under `forceLoginMethod` the credential would stand in for the required sign-in. When the managed settings also require the [gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sign-in, Claude Code blocks an API key saved by an earlier Claude Console login the same way. See [Administrator policy requires a Cloud gateway sign-in](errors.md#administrator-policy-requires-a-cloud-gateway-sign-in)
- **Cloud provider sessions such as Amazon Bedrock**: blocked only while an `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` credential, or an API key saved by an earlier Claude Console login, is still present on the machine. Remove it and the session starts. These sessions authenticate against your cloud provider, whose access policies govern them
- **[Anthropic profile or federation credentials](#anthropic-profiles-and-federation-credentials)**: not blocked unless an `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` credential, or an API key saved by an earlier Claude Console login, is also present on the machine. The keys don’t check which organization the profile belongs to


[​](#restrict-which-api-providers-a-machine-may-use)

Restrict which API providers a machine may use

[`allowedProviders`](settings-reference.md#allowedproviders) in [managed settings](../13-Enterprise-Admin/managed-settings.md) lists which services a managed machine may reach Claude through, such as the Anthropic API, Amazon Bedrock, or an LLM gateway. It complements `forceLoginMethod` and `forceLoginOrgUUID`, which govern which account a session uses when it talks to Anthropic. Requires Claude Code v2.1.285 or later.

managed-settings.json

```python
{
  "forceLoginMethod": "claudeai",
  "forceLoginOrgUUID": ["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"],
  "allowedProviders": ["anthropic", "bedrock"]
}
```

With this file, a developer signed in to your claude.ai organization or configured for Amazon Bedrock starts normally. A session set up for any other provider is refused at startup, and a running session that switches to one is refused on its next request. [Managed settings don’t allow this API provider](errors.md#managed-settings-dont-allow-this-api-provider) shows each message.

- **Allow an LLM gateway or proxy**: list `"customEndpoint"` and set the gateway’s URL in the managed `env` block of the same source. The [settings reference](settings-reference.md#allowedproviders) lists every value and says which endpoint variables need a managed `env` pin.
- **Deploy on managed machines**: put the list in the managed source that carries the rest of your policy. The entry’s [Scope note](settings-reference.md#allowedproviders) says how a server-managed list combines with it.
- **Server-managed settings only**: a list you set only in [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) reaches only sessions that fetch your organization’s settings, so treat it as a convenience for machines you can’t reach with device management, not as enforcement. [Platform availability](../13-Enterprise-Admin/server-managed-settings.md#platform-availability) lists which sessions fetch them.


[​](#credential-management)

Credential management

Claude Code securely manages your authentication credentials:

- **Storage location**:
  - On macOS, credentials are stored in the encrypted macOS Keychain. When the Keychain rejects the write, such as when it’s locked in an SSH session, Claude Code stores your login in `~/.claude/.credentials.json` with file mode `0600` instead, the same storage it uses on Linux. A Console login that creates an API key fails until the Keychain is writable. To move your login back into the Keychain, follow [the recovery steps](troubleshoot-install.md#not-logged-in-or-token-expired).
  - On Linux, credentials are stored in `~/.claude/.credentials.json` with file mode `0600`.
  - On Windows, credentials are stored in `%USERPROFILE%\.claude\.credentials.json` and inherit the access controls of your user profile directory, which restricts the file to your user account by default.
  - If you’ve set the `CLAUDE_CONFIG_DIR` environment variable, Claude Code keeps the `.credentials.json` file under that directory instead, including the file the macOS fallback writes, and keys the macOS Keychain entry to that directory too, so a session with a different `CLAUDE_CONFIG_DIR` reads a different entry.
  - Claude Code manages `.credentials.json` through `/login` and `/logout`. To route requests through a custom API endpoint, set the [`ANTHROPIC_BASE_URL`](env-vars.md) environment variable instead.
- **Supported authentication types**: claude.ai credentials, Claude API credentials, Microsoft Foundry Auth, Bedrock Auth, Vertex Auth, Anthropic profile and [Workload Identity Federation](../04-API-Reference/Other/manage-claude-workload-identity-federation.md) credentials, and [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) session tokens.
- **Custom credential scripts**: configure the [`apiKeyHelper`](settings-reference.md#apikeyhelper) setting to run a shell script that returns an API key.
- **Refresh intervals**: see [`apiKeyHelper`](settings-reference.md#apikeyhelper) for the cases in which Claude Code re-runs the helper.
- **Slow helper notice**: if `apiKeyHelper` takes longer than 10 seconds to return a key, Claude Code displays a warning notice in the prompt bar showing the elapsed time. If you see this notice regularly, check whether your credential script can be optimized.
- **Helper failures**: when the script exits with an error, times out, or prints nothing, requests fail with [`Your apiKeyHelper script is failing`](errors.md#your-apikeyhelper-script-is-failing) within three attempts.

`apiKeyHelper`, `ANTHROPIC_API_KEY`, and `ANTHROPIC_AUTH_TOKEN` apply to the CLI and the surfaces that wrap it, including the VS Code extension, the Agent SDK, and GitHub Actions. Claude Desktop and cloud sessions do not call `apiKeyHelper` or read these environment variables: they use OAuth, except desktop sessions running a [third-party inference configuration](../13-Enterprise-Admin/llm-gateway-connect.md#desktop-app), which authenticate with that configuration’s credential.


[​](#renew-an-expiring-login)

Renew an expiring login

When the login you created with `/login` is within three days of expiring, Claude Code shows a warning at startup: `Your login expires in 3 days · run /login to renew`. Run `/login` to renew. The warning is informational and never blocks a request: authentication keeps working until the login actually expires. Once the stored login expires and can’t be refreshed, each model request fails with [`Login expired · Please run /login`](errors.md#login-expired) until you sign in again. You can check for this state before a request fails: [`/status`](commands.md) shows a `Login` row reading `Expired — log in again`, plus the organization and email it has saved for the expired login. The row appears only when the saved claude.ai login is the active credential. The row requires Claude Code v2.1.210 or later. The warning appears only when a claude.ai login is the active credential, and not when a cloud provider, `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` supplies the credential. Renewing early matters most for sessions that run unattended. A [background session in agent view](../09-Agents-Patterns/agent-view.md) or a [Remote Control](remote-control.md) session that outlives the login stops making progress once the credential expires and can’t recover until you sign in again.


[​](#authentication-precedence)

Authentication precedence

When multiple credentials are present, Claude Code chooses one in this order:

1.  Cloud provider credentials, when `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, or `CLAUDE_CODE_USE_FOUNDRY` is set. See [third-party integrations](third-party-integrations.md) for setup.
2.  `ANTHROPIC_AUTH_TOKEN` environment variable. Sent as the `Authorization: Bearer` header. Use this when routing through an [LLM gateway or proxy](../13-Enterprise-Admin/llm-gateway.md) that authenticates with bearer tokens rather than Anthropic API keys.
3.  `ANTHROPIC_API_KEY` environment variable. Sent as the `X-Api-Key` header. Use this for direct Anthropic API access with a key from the [Claude Console](../04-API-Reference/Other/playground.md). In interactive mode, you are prompted once to approve or decline the key, and your choice is remembered. To change it later, use the “Use custom API key” toggle in `/config`. The toggle only appears while `ANTHROPIC_API_KEY` is set in your environment. In non-interactive mode (`-p`), the key is always used when present.
4.  [`apiKeyHelper`](settings-reference.md#apikeyhelper) script output. Use this for dynamic or rotating credentials, such as short-lived tokens fetched from a vault.
5.  `CLAUDE_CODE_OAUTH_TOKEN` environment variable. A long-lived OAuth token generated by [`claude setup-token`](#generate-a-long-lived-token). Use this for CI pipelines and scripts where browser login isn’t available. If you run `/login` while the variable is set, Claude Code switches the current session to the new login, but reads the variable again in every new session until you remove it from your shell profile or the `env` block of a [settings file](settings.md).
6.  Anthropic profile and federation credentials, the credentials that the `ant` CLI and Workload Identity Federation use. A profile that `ant auth login` wrote ranks here only when you name it in `ANTHROPIC_PROFILE`; otherwise it ranks below `/login`. See [Anthropic profiles and federation credentials](#anthropic-profiles-and-federation-credentials).
7.  Subscription OAuth credentials from `/login`. This is the default for Claude Pro, Max, Team, and Enterprise users.

A signed-in [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) session sits outside this list: it is a provider selection like Amazon Bedrock or Google Cloud’s Agent Platform, and it outranks them. When a gateway session exists, the CLI authenticates with the gateway token even if `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, or `CLAUDE_CODE_USE_FOUNDRY` is set, and credential sources above such as the bearer token, API key, `apiKeyHelper`, and profiles are not used. If your machine’s [managed settings](../13-Enterprise-Admin/managed-settings.md) set [`forceLoginMethod`](settings-reference.md#forceloginmethod) to `"gateway"` or set [`forceLoginGatewayUrl`](settings-reference.md#forcelogingatewayurl), and you don’t select a cloud provider through a variable such as `CLAUDE_CODE_USE_BEDROCK` or `CLAUDE_CODE_USE_VERTEX`, your session uses only the gateway sign-in. Claude Code skips the other credential sources and asks you to sign in with `/login`. See [Administrator policy requires a Cloud gateway sign-in](errors.md#administrator-policy-requires-a-cloud-gateway-sign-in) for what you see with each leftover credential. Requires Claude Code v2.1.261 or later, or v2.1.265 or later on a machine that sets only `forceLoginGatewayUrl`. If you have an active Claude subscription but also have `ANTHROPIC_API_KEY` set in your environment, Claude Code uses the API key once you approve it. This can cause authentication failures if the key belongs to a disabled or expired organization. Run `unset ANTHROPIC_API_KEY` to fall back to your subscription, and check `/status` to confirm which method is active. When a login and an API key are both configured, `/status` marks the credential that isn’t in use. [Cloud sessions](claude-code-on-the-web.md) always use your subscription credentials. If you set `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN` in the cloud environment, it doesn’t override your subscription credentials.


[​](#anthropic-profiles-and-federation-credentials)

Anthropic profiles and federation credentials

A profile is a named credential configuration file in your [Anthropic configuration directory](../04-API-Reference/Other/manage-claude-wif-reference.md#configuration-directory), by default `~/.config/anthropic` on macOS and Linux or `%APPDATA%\Anthropic` on Windows. A profile’s auth mode is `oidc_federation` when you set it up for [Workload Identity Federation (WIF)](../04-API-Reference/Other/manage-claude-workload-identity-federation.md) or `user_oauth` when [`ant auth login`](../04-API-Reference/Other/cli-sdks-libraries-cli-authentication.md) wrote it or you [signed in to a Console account without an API key](#sign-in-without-an-api-key). Claude Code doesn’t read profiles or federation variables in [bare mode](headless.md#start-faster-with-bare-mode), in Claude Desktop, or in cloud sessions. In those sessions, `/status` shows no `Profile` row. Claude Code checks three sources in this order and stops at the first one that is set. The table shows what sets each source and where it ranks against your `/login` credential.

| Source               | Set by                                                                                                                                                                   | Rank against `/login`                                                                                                 |
|:---------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------|
| Named profile        | `ANTHROPIC_PROFILE`                                                                                                                                                      | Above, whichever auth mode the profile has                                                                            |
| Federation variables | `ANTHROPIC_FEDERATION_RULE_ID` and `ANTHROPIC_ORGANIZATION_ID`, both set                                                                                                 | Above                                                                                                                 |
| Active profile       | The [`active_config` file](../04-API-Reference/Other/manage-claude-wif-reference.md#active-profile) in your configuration directory, or a profile named `default` | Above when its auth mode is `oidc_federation`; below a working `/login` credential when its auth mode is `user_oauth` |

For the federation variables, Claude Code also reads the other variables in the [WIF reference](../04-API-Reference/Other/manage-claude-wif-reference.md#environment-variables), such as `ANTHROPIC_IDENTITY_TOKEN_FILE`, when it exchanges your identity token. For the profile file format, see the [WIF reference](../04-API-Reference/Other/manage-claude-wif-reference.md#profile-configuration-file). To confirm which source Claude Code chose, run `/status`. A `Profile` row names the source in place of the `Login method` row. When the profile is the credential in use, `Organization` and `Email` rows show its account. When a `user_oauth` profile’s login has expired and Claude Code can’t renew it, requests fail with an [expired profile login error](errors.md#anthropic-profile-login-expired). Features that need your claude.ai login, such as [claude.ai connectors](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) and [`/schedule`](web-scheduled-tasks.md), aren’t available while one of these sources is selected. To stop Claude Code from selecting a source:

- **Named profile or federation variables**: unset `ANTHROPIC_PROFILE`, or unset either federation variable
- **Active profile**: run `/logout` for a `user_oauth` profile whose current credential you wrote by [signing in to a Console account without an API key](#sign-in-without-an-api-key), run `ant auth logout` for one whose current credential `ant auth login` wrote, or delete the profile’s file from `configs/` in your configuration directory for either auth mode


[​](#generate-a-long-lived-token)

Generate a long-lived token

For CI pipelines, scripts, or other environments where interactive browser login isn’t available, generate a one-year OAuth token with `claude setup-token`:

```python
claude setup-token
```

The command opens the same browser authorization flow as `/login`, and the token prints to the terminal after you approve access in the browser. It does not save the token anywhere; copy it and set it as the `CLAUDE_CODE_OAUTH_TOKEN` environment variable wherever you want to authenticate:

- macOS, Linux, WSL

- Windows PowerShell

- Windows CMD

```python
export CLAUDE_CODE_OAUTH_TOKEN=your-token
```

```python
$env:CLAUDE_CODE_OAUTH_TOKEN = "your-token"
```

```python
set CLAUDE_CODE_OAUTH_TOKEN=your-token
```

This token authenticates with your Claude subscription and requires a Pro, Max, Team, or Enterprise plan. It can only make model requests, so it can’t establish [Remote Control](remote-control.md) sessions or fetch [claude.ai connectors](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai). MCP servers you configure locally still work. [Bare mode](headless.md#start-faster-with-bare-mode) does not read `CLAUDE_CODE_OAUTH_TOKEN`. If your script passes `--bare`, authenticate with `ANTHROPIC_API_KEY` or an `apiKeyHelper` instead.

---

## Configure auto mode - Claude Code Docs

Source: https://code.claude.com/docs/en/auto-mode-config
Path: 02-Claude-Code-CLI/auto-mode-config.md

## On this page

- [Common boundaries](#common-boundaries)
  - [Add a human checkpoint](#add-a-human-checkpoint)
- [Where the classifier reads configuration](#where-the-classifier-reads-configuration)
- [Define trusted infrastructure](#define-trusted-infrastructure)
- [Generate environment entries with /auto-mode-setup](#generate-environment-entries)
  - [What /auto-mode-setup reads](#what-auto-mode-setup-reads)
  - [Review and save the draft](#review-and-save-the-draft)
  - [Turn off /auto-mode-setup](#turn-off-auto-mode-setup)
  - [/auto-mode-setup returns “Unknown command”](#auto-mode-setup-returns-unknown-command)
- [Override the block and allow rules](#override-the-block-and-allow-rules)
- [Edit rules from /permissions](#edit-rules-from-permissions)
- [Route all shell commands through the classifier](#route-all-shell-commands-through-the-classifier)
- [Inspect the defaults and your effective config](#inspect-the-defaults-and-your-effective-config)
- [Review denials](#review-denials)
  - [Fix a denial with an allow rule, an environment entry, or a retry](#fix-a-denial-with-an-allow-rule-an-environment-entry-or-a-retry)
  - [Fix repeated denials](#fix-repeated-denials)
- [See also](#see-also)

Setup and access

# Configure auto mode

Copy pageCopy page

Tell the auto mode classifier which repos, buckets, and domains your organization trusts. Set environment context, override the default block and allow rules, and inspect your effective config with the auto-mode CLI subcommands.

Copy pageCopy page

[Auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) lets Claude Code run without routine permission prompts by routing tool calls through a classifier that blocks anything irreversible, destructive, or aimed outside your environment. Deny and explicit ask rules are evaluated before the classifier and still block or prompt. Use the `autoMode` settings block to tell that classifier which repos, buckets, and domains your organization trusts, so it stops blocking routine internal operations.

This page is the configuration reference. Turning auto mode on and off is covered on the Permission modes page:

- **Switch to auto mode mid-session, or back out of it**: see [Switch permission modes](permission-modes.md#switch-permission-modes)
- **Start a session in auto mode**: see [Start in a different permission mode](permission-modes.md#start-in-a-different-mode)

Auto mode is available to all users on every provider, including the Anthropic API, [Claude Platform on AWS](claude-platform-on-aws.md), Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and signed-in [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sessions. If Claude Code reports auto mode as unavailable for your account, check the [full requirements](permission-modes.md#eliminate-prompts-with-auto-mode), which also cover the supported models and the organization-level control on Team and Enterprise plans. By default, the classifier trusts only the working directory and the current repo’s configured remotes. Actions like pushing to your company’s source-control org or writing to a team cloud bucket are blocked until you add them to `autoMode.environment`. This page covers how to:

- [Add a human checkpoint](#add-a-human-checkpoint) for pushes and pull requests with `permissions.ask`
- [Define trusted infrastructure](#define-trusted-infrastructure) with `autoMode.environment`
- [Generate environment entries](#generate-environment-entries) with `/auto-mode-setup`
- [Review denials](#review-denials) so you know what to add next


[​](#common-boundaries)

Common boundaries

Auto mode allows pushes to any branch of the repository you’re working in, including the default branch, and pull request creation by default. A non-default branch whose name marks it as a deploy or publication target, such as `production`, `release`, or `gh-pages`, isn’t covered by that default: the classifier judges a push there on its own terms, including as a production deploy. The push’s content is also still checked, so a force push, a secret entering the commit, or a change that would send secrets outside the repository when CI or a deploy pipeline runs it stays blocked. If you want a human checkpoint before Claude’s push and pull request commands, add permission rules: the [recipes below](#add-a-human-checkpoint) keep auto mode on for everything else.


[​](#add-a-human-checkpoint)

Add a human checkpoint

The most direct mechanism is [`permissions.ask`](permissions.md#permission-rule-syntax). Content-scoped ask rules like the ones below are evaluated before the classifier and always force a permission prompt, even in auto mode, because an explicit ask rule is your stated intent to be prompted for that action. Add the rules in your [settings](settings.md#where-settings-live):

```python
{
  "permissions": {
    "ask": [
      "Bash(git push *)",
      "Bash(gh pr create *)"
    ]
  }
}
```

These rules match commands that begin with `git push` or `gh pr create`. A push Claude writes another way, such as `git -C <dir> push` or `git -c <key>=<value> push`, [doesn’t match the rule](permissions.md#bash-rule-limits), so it isn’t checkpointed. For a checkpoint that inspects the full command text, add a [PreToolUse hook](../07-Hooks/hooks.md#pretooluse). Pick the mechanism that matches how firm the boundary needs to be:

| Boundary                          | Mechanism                                                  | Behavior in auto mode                                                                                                                                                                                                |
|:----------------------------------|:-----------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Prompt before the action          | `permissions.ask`                                          | Always prompts for a command that matches a content-scoped rule like the recipe above. The classifier cannot auto-approve a matching action.                                                                         |
| Never run the action              | `permissions.deny`                                         | Blocks before the classifier is consulted. Neither the classifier nor user intent can override it.                                                                                                                   |
| One-off boundary for this session | State it in conversation, like “don’t push until I review” | The classifier blocks matching actions, but the boundary can be lost if [context compaction](../17-Billing-Plans/costs.md#reduce-token-usage) removes the message that stated it. Use an ask or deny rule for a durable guarantee. |


[​](#where-the-classifier-reads-configuration)

Where the classifier reads configuration

The classifier reads the same [CLAUDE.md](memory.md) content Claude itself loads, so an instruction like “never force push” in your project’s CLAUDE.md steers both Claude and the classifier at the same time. Start there for project conventions and behavioral rules. For rules that apply across projects, such as trusted infrastructure or organization-wide deny rules, use the `autoMode` settings block. The classifier reads `autoMode` from the following scopes:

| Scope                          | File                                                 | Use for                                              |
|:-------------------------------|:-----------------------------------------------------|:-----------------------------------------------------|
| One developer                  | `~/.claude/settings.json`                            | Personal trusted infrastructure                      |
| Organization-wide              | [Managed settings](../13-Enterprise-Admin/server-managed-settings.md) | Trusted infrastructure distributed to all developers |
| `--settings` flag or Agent SDK | Inline JSON                                          | Per-invocation overrides for automation              |

The classifier doesn’t read `autoMode` from project settings in `.claude/settings.json` or `.claude/settings.local.json`. Both files live in the repo directory, so a checked-in repo or a build step could otherwise inject its own allow rules. Move any `autoMode` block in `.claude/settings.local.json` to `~/.claude/settings.json`. Entries from each scope are combined. A developer can extend `environment`, `allow`, `soft_deny`, and `hard_deny` with personal entries but can’t remove entries that managed settings provide. Because allow rules act as exceptions to soft block rules inside the classifier, a developer-added `allow` entry can override an organization `soft_deny` entry: the combination is additive, not a hard policy boundary.

The classifier is a second gate that runs after the [permissions system](permissions.md). For actions that must never run regardless of user intent or classifier configuration, use `permissions.deny` in managed settings, which blocks the action before the classifier is consulted and can’t be overridden.


[​](#define-trusted-infrastructure)

Define trusted infrastructure

For most organizations, `autoMode.environment` is the only field you need to set. It tells the classifier which repos, buckets, and domains are trusted: the classifier uses it to decide what “external” means, so any destination not listed is a potential exfiltration target. `claude auto-mode defaults` prints three kinds of environment entry.

- **Context slots**: describe your organization, stack, and security posture so the classifier reads the other rules in your context. Each defaults to `None configured` or to the conservative assumption named next to it:
  - **Organization**
  - **Primary use of Claude Code**: defaults to software development
  - **Cloud provider(s)**
  - **Repository visibility**: a repository is assumed private unless its remote host and name indicate otherwise, or the classifier reads a visibility check earlier in the conversation showing it is public. In the classifier requests sent by Claude Code itself, the classifier reads your messages and the commands Claude runs, not their output. The evidence has to be something the classifier can read, such as your own message naming the repository as public; the output of a `gh repo view` on its own doesn’t reach it.
  - **Internal sharing / snippet hosting**: public paste and gist services are treated as outside the trust boundary until you name one
  - **Org-specific CLIs**
  - **Secrets management**
  - **CI/CD deploy targets**
  - **Network posture**
  - **Host containment**: defaults to an ordinary developer machine or CI runner with open internet. If Claude Code runs in a container, VM, or pod with an egress allow-list or neighbors it must not touch, name the allowed hosts, whether the cloud metadata endpoint should be reachable, and which cloud project, cluster, or registry the task uses and under what identity. Until this entry names that identity, the classifier [blocks](permission-modes.md#what-the-classifier-blocks-by-default) requests for the host’s own credentials. Requires Claude Code v2.1.257 or later
  - **Protected deployment namespaces / environments**: falls back to the Sensitive remote targets heuristic until you name them
  - **Data retention / declassification**
- **Trust slots**: name what the classifier treats as inside your boundary. The slots are Trusted repo, Source control, Trusted internal domains, Trusted cloud buckets, Key internal services, and Internal package registry. The repo and source-control entries default to the working repository and its configured remotes. Every other trust slot defaults to `None configured`, so nothing else is trusted until you add it. A repository’s visibility scopes only confidential material: a private repository is an acceptable destination for confidential material, but making a repository private never clears secrets or personal or entrusted data into it, and the classifier treats content ported, repointed, or first read from outside the working repository as not that repository’s own work.
- **Sensitivity slots**: name what the protective rules treat as high-risk. The slots are Sensitive data locations & audiences, Sensitive remote targets, and Protected IaC scopes. Each defaults to a broad heuristic, such as treating any host or namespace whose name carries `prod` or `production` as a sensitive remote target, so the protective rules are active before you configure anything. Naming concrete targets in a sensitivity slot makes those rules apply to the named targets instead of the heuristic.

To add your own entries alongside the defaults, include the literal string `"$defaults"` in the array. The default entries are spliced in at that position, so your custom entries can go before or after them. The following example keeps the default entries and adds an organization’s repos, buckets, domains, and services.

```python
{
  "autoMode": {
    "environment": [
      "$defaults",
      "Source control: github.example.com/acme-corp and all repos under it",
      "Trusted cloud buckets: s3://acme-build-artifacts, gs://acme-ml-datasets",
      "Trusted internal domains: *.corp.example.com, api.internal.example.com",
      "Key internal services: Jenkins at ci.example.com, Artifactory at artifacts.example.com"
    ]
  }
}
```

After you save your settings, run `claude auto-mode config` to [confirm the effective rules](#inspect-the-defaults-and-your-effective-config) include your entries. Entries are prose, not regex or tool patterns. The classifier reads them as natural-language rules. Write them the way you would describe your infrastructure to a new engineer. A thorough environment section covers:

- **Organization**: your company name and what Claude Code is primarily used for, like software development, infrastructure automation, or data engineering
- **Source control**: every GitHub, GitLab, or Bitbucket org your developers push to
- **Cloud providers and trusted buckets**: bucket names or prefixes that Claude should be able to read from and write to
- **Trusted internal domains**: hostnames for APIs, dashboards, and services inside your network, like `*.internal.example.com`
- **Key internal services**: CI, artifact registries, internal package indexes, incident tooling
- **Internal package registry**: the private npm, PyPI, or other registry that installs should route through, so installs that bypass it for a public registry get blocked
- **Sensitive data locations & audiences**: the buckets, databases, or paths that hold personal data, confidential business data, credentials, regulated data, or similarly sensitive material, and the audiences that data in each location may be shared with, so the classifier protects those locations instead of guessing from content.
- **Sensitive remote targets**: the namespaces, hosts, or containers that count as production, so remote shells and port-forwards into them need your explicit approval
- **Protected IaC scopes**: the infrastructure resources whose apply or destroy should always require you to name the change
- **Additional context**: regulated-industry constraints, multi-tenant infrastructure, or compliance requirements that affect what the classifier should treat as risky

A useful starting template: fill in the bracketed fields and remove any lines that don’t apply.

```python
{
  "autoMode": {
    "environment": [
      "$defaults",
      "Organization: {COMPANY_NAME}. Primary use: {PRIMARY_USE_CASE, e.g. software development, infrastructure automation}",
      "Source control: {SOURCE_CONTROL, e.g. GitHub org github.example.com/acme-corp}",
      "Cloud provider(s): {CLOUD_PROVIDERS, e.g. AWS, GCP, Azure}",
      "Trusted cloud buckets: {TRUSTED_BUCKETS, e.g. s3://acme-builds, gs://acme-datasets}",
      "Trusted internal domains: {TRUSTED_DOMAINS, e.g. *.internal.example.com, api.example.com}",
      "Key internal services: {SERVICES, e.g. Jenkins at ci.example.com, Artifactory at artifacts.example.com}",
      "Additional context: {EXTRA, e.g. regulated industry, multi-tenant infrastructure, compliance requirements}"
    ]
  }
}
```

You don’t need to fill everything in at once. A reasonable rollout: start with the defaults and add your source control org and key internal services, which resolves the most common false positives like pushing to your own repos. Add trusted domains and cloud buckets next. Fill the rest as blocks come up.


[​](#generate-environment-entries)

Generate environment entries with `/auto-mode-setup`

Run `/auto-mode-setup` to have Claude Code draft `autoMode.environment` entries, and sometimes [rule entries](#override-the-block-and-allow-rules) too, from your project and your recent sessions in it. If you accept the draft, Claude Code writes it to `~/.claude/settings.json`.

`/auto-mode-setup` is available on Pro, Max, Team, and Enterprise plans and with a Claude Console API key. On a Pro, Max, or Team plan, you need v2.1.228 or later, or v2.1.233 or later on native Windows. On an Enterprise plan or with a Claude Console API key, you need v2.1.283 or later. If the command is missing from your session, see [`/auto-mode-setup` returns “Unknown command”](#auto-mode-setup-returns-unknown-command).


[​](#what-auto-mode-setup-reads)

What `/auto-mode-setup` reads

If `~/.claude/settings.json` already holds `autoMode` entries, Claude Code starts by asking whether to add to your environment list or replace it, and keeps the rules you wrote either way. Claude Code then asks how you use this project and offers two optional scans before it scans anything. In the scan, Claude Code always reads these sources:

- This project’s `CLAUDE.md`, `README.md`, config files, and git remotes
- Your `autoMode` and `permissions.allow` settings
- The hosts, buckets, and command names from the commands Claude ran in your recent sessions in this project, never your messages

The two optional scans add one source each:

- The first word of each command in your shell history
- The remote hosts and names of the repositories under your home directory


[​](#review-and-save-the-draft)

Review and save the draft

Claude Code scans in the background, then shows you the draft. You accept or discard it as a whole, so edit `~/.claude/settings.json` afterwards to adjust single entries. When you accept, Claude Code writes the draft and reconciles it with the settings you already have:

- Claude Code writes the `environment` list without `"$defaults"`, because the draft spells out the built-in entries it left unchanged
- Claude Code includes `"$defaults"` in each of the `allow`, `soft_deny`, and `hard_deny` lists the draft adds entries to, unless you already wrote an `allow` list without it, so the [built-in rules](#override-the-block-and-allow-rules) you haven’t replaced stay in effect
- After saving, Claude Code offers to remove `permissions.allow` rules in `~/.claude/settings.json` that auto mode ignores, such as `Bash(*)`, or that auto-approve destructive commands

Then run `claude auto-mode config` to [see the effective result](#inspect-the-defaults-and-your-effective-config).


[​](#turn-off-auto-mode-setup)

Turn off `/auto-mode-setup`

Once auto mode has blocked several actions and you still have no `autoMode.environment` entries, Claude Code shows a dialog titled “Teach auto mode about your environment?” at the end of a turn and offers to run `/auto-mode-setup` for you. To stop the offer but keep the command, select **Don’t show again** in that dialog. To turn off both the command and the offer, add this [`skillOverrides`](../08-Plugins-Skills/skills.md#override-skill-visibility-from-settings) entry to `~/.claude/settings.json`:

```python
{
  "skillOverrides": {
    "auto-mode-setup": "off"
  }
}
```

`/auto-mode-setup` is a built-in command rather than a [bundled skill](../08-Plugins-Skills/skills.md#bundled-skills), so this `skillOverrides` entry still applies to it, but [`disableBundledSkills`](settings-reference.md#disablebundledskills) doesn’t turn it off.


[​](#auto-mode-setup-returns-unknown-command)

`/auto-mode-setup` returns “Unknown command”

If typing `/auto-mode-setup` at the Claude Code prompt prints `Unknown command: /auto-mode-setup`, check for these causes:

- **First session after an install or upgrade**: start a new session. If the command is still missing there, see the [setups where later sessions also start without it](env-vars.md#first-session-after-an-install-or-upgrade).
- **Outdated version**: run `claude --version` in your shell. If the version is below [the minimum for your plan](#generate-environment-entries), [update Claude Code](../01-Getting-Started/setup.md#update-claude-code).
- **Telemetry off, third-party provider, or Claude apps gateway**: before v2.1.304, the command isn’t available in [sessions where feature-flag fetching is off](env-vars.md#features-that-need-feature-flag-fetching). If your session is one of them, [update Claude Code](../01-Getting-Started/setup.md#update-claude-code) to v2.1.304 or later.

In a [cloud session](claude-code-on-the-web.md), the command prints `/auto-mode-setup isn't available in this environment.` instead. Run it in an interactive session in your terminal.


[​](#override-the-block-and-allow-rules)

Override the block and allow rules

Three additional fields let you replace the classifier’s built-in rule lists:

- `autoMode.hard_deny`: unconditional security boundaries
- `autoMode.soft_deny`: destructive actions that user intent can clear
- `autoMode.allow`: exceptions to soft block rules

Each 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`](permissions.md). Inside the classifier, precedence works in four tiers:

- `hard_deny` rules block unconditionally. User intent and `allow` exceptions don’t apply.
- `soft_deny` rules block next. User intent and `allow` exceptions can override these.
- `allow` rules then override matching `soft_deny` rules as exceptions.
- Explicit user intent overrides the remaining soft blocks: if the user’s message directly and specifically describes the exact action Claude is about to take, the classifier allows it even when a `soft_deny` rule matches.

General requests don’t count as explicit intent. Asking Claude to “clean up the repo” doesn’t authorize force-pushing, but asking Claude to “force-push this branch” does. To loosen, add to `allow` when the classifier repeatedly flags a routine pattern the default exceptions don’t cover. To tighten, add to `soft_deny` for destructive risks specific to your environment that the defaults miss, or to `hard_deny` for security boundaries that must never be crossed. To keep the built-in rules while adding your own, include the literal string `"$defaults"` in the array. The default rules are spliced in at that position, so your custom rules can go before or after them, and you continue to inherit updates as the built-in list changes across releases. The following example keeps the defaults in all four lists and adds organization-specific rules to each.

```python
{
  "autoMode": {
    "environment": [
      "$defaults",
      "Source control: github.example.com/acme-corp and all repos under it"
    ],
    "allow": [
      "$defaults",
      "Deploying to the staging namespace is allowed: staging is isolated from production and resets nightly",
      "Writing to s3://acme-scratch/ is allowed: ephemeral bucket with a 7-day lifecycle policy"
    ],
    "soft_deny": [
      "$defaults",
      "Never run database migrations outside the migrations CLI, even against dev databases",
      "Never modify files under infra/terraform/prod/: production infrastructure changes go through the review workflow"
    ],
    "hard_deny": [
      "$defaults",
      "Never send repository contents to third-party code-review APIs"
    ]
  }
}
```

Setting any of `environment`, `allow`, `soft_deny`, or `hard_deny` without `"$defaults"` replaces the entire default list for that section. If you set an array without `"$defaults"`, you discard the built-in rules for that section:

- `soft_deny`: every built-in soft block rule, including force push, `curl | bash`, production deploys, and auto-mode bypass
- `hard_deny`: the built-in data exfiltration rule

Each section is evaluated independently, so setting `environment` alone leaves the default `allow`, `soft_deny`, and `hard_deny` lists intact. Only omit `"$defaults"` when you intend to take full ownership of the list. To do that safely, run `claude auto-mode defaults` to print the built-in rules, copy them into your settings file, then review each rule against your own pipeline and risk tolerance.


[​](#edit-rules-from-permissions)

Edit rules from `/permissions`

To view and edit classifier rules and `environment` entries without opening a settings file, run [`/permissions`](permissions.md#manage-permissions) and select the **Auto mode** tab. The tab requires Claude Code v2.1.246 or later, and it appears only when [auto mode is available](permission-modes.md#eliminate-prompts-with-auto-mode) to your session. Claude Code shows entries from [managed settings](../13-Enterprise-Admin/server-managed-settings.md) or the `--settings` flag as read-only, and saves every change you make on the tab to `~/.claude/settings.json`.


[​](#route-all-shell-commands-through-the-classifier)

Route all shell commands through the classifier

By 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](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`](tools-reference.md#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. Set `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](permission-modes.md#critical-paths).

```python
{
  "autoMode": {
    "classifyAllShell": true
  }
}
```

This trades latency for coverage: a command that an allow rule would have approved instantly now waits for a classifier decision, and each shell command counts as a classifier call. The setting applies only while auto mode is active, and your allow rules behave normally in other permission modes.


[​](#inspect-the-defaults-and-your-effective-config)

Inspect the defaults and your effective config

The `claude auto-mode` subcommands help you inspect, validate, and reset your configuration. Print the built-in `environment`, `allow`, `soft_deny`, and `hard_deny` rules as JSON:

```python
claude auto-mode defaults
```

To read one rule’s full wording without piping through `jq`, pass `--label` with the start of the rule’s label, such as `claude auto-mode defaults --label 'Git Destructive'`. Matching is a case-insensitive prefix on each rule’s label, and sections with no match print as empty lists. Print what the classifier actually uses as JSON, with your settings applied where set and defaults otherwise:

```python
claude auto-mode config
```

Both `defaults` and `config` print the four rule lists as a single JSON object, with each rule as a prose string. This is a truncated example:

```python
{
  "allow": [
    ...
    "Test Artifacts: Hardcoded test API keys, placeholder credentials in examples, or hardcoding test cases. Placeholder means authored as a placeholder — a file or value copied from a real secret or sensitive path is never a test artifact (see Sensitive-Source Provenance).",
    ...
  ],
  "soft_deny": [
    "Git Destructive [named+specifics — **must name:** the destructive operation and its target]: Force pushing (`git push --force`), deleting remote branches, tags, or releases, or rewriting remote history. Also `git commit --amend` when the commit being rewritten is not the agent's own unpushed work: either no prior `git commit` is visible (HEAD pre-dates the session), or a `git push` of the current branch is visible after the most recent commit (it has been pushed). Clears when the user asked to amend/reword/fixup, or when it is a message-only reword (`--amend -m …`, nothing newly staged) of a commit the agent visibly created this session.",
    ...
  ],
  "hard_deny": [...],
  "environment": [
    ...
    "**Trusted repo**: The git repository the agent started in (its working directory) and its configured remote(s). When the repo's public/private visibility is given — by the Repository visibility entry or the user's own message — use it to scope what is OK to commit or push there: confidential material is fine in a private repo; in a public one, only that repo's own work is — and content ported, repointed, or first read from outside this session's repo is not its own work, whoever directed the port. Visibility scopes confidential material only: secrets and sensitive data (personal & entrusted) are never cleared into any repo by its visibility (see Definitions).",
    ...
  ]
}
```

Get AI feedback on your custom `allow`, `soft_deny`, `hard_deny`, and `environment` entries:

```python
claude auto-mode critique
```

If you’ve written custom rules, `claude auto-mode critique` reviews them and flags entries that are ambiguous, redundant, or likely to cause false positives. To discard your customizations and return to the built-in defaults, run the reset subcommand, which removes the `autoMode` section from your user settings file:

```python
claude auto-mode reset
```

The command summarizes what it will remove and asks `Reset auto mode configuration to defaults?` before writing; pass `--yes` to skip the confirmation. Reset changes only `~/.claude/settings.json`: `autoMode` rules from [managed settings](../13-Enterprise-Admin/server-managed-settings.md) or the `--settings` flag still apply.


[​](#review-denials)

Review denials

To review and retry actions the auto mode classifier denied, open `/permissions` and select the **Recently denied** tab, where Claude Code records each denial. Press `r` on a denied action to mark it for retry: when you exit the dialog, Claude Code sends a message telling the model it may retry that tool call and resumes the conversation. When the classifier produces [no verdict on the action](errors.md#auto-mode-cannot-determine-the-safety-of-an-action), because a safety check separate from auto mode refused the classifier’s own request or its response didn’t parse, Claude Code denies the action without recording it under **Recently denied**. The linked error entry covers what Claude is told and how to run the action if you need it.


[​](#fix-a-denial-with-an-allow-rule-an-environment-entry-or-a-retry)

Fix a denial with an allow rule, an environment entry, or a retry

To read the command or URL behind a notice such as `bash denied by auto mode · [Data Exfiltration] · /permissions`, use the **Recently denied** tab, a hook, or the conversation:

- **Recently denied tab**: in the `/permissions` dialog, highlight a denied Bash or PowerShell action to read its command below the list. In [screen reader mode](accessibility.md), all the commands appear before the list instead.
- **Hook**: to capture the exact input of denials programmatically, add a [`PermissionDenied` hook](../07-Hooks/hooks.md#permissiondenied), which receives it as `tool_input`.
- **Conversation**: find the tool call. If the call appears shortened or folded into a summary line such as `Ran 3 shell commands`, press `Ctrl+O` to open the [transcript viewer](interactive-mode.md#transcript-viewer), which expands it.

The text beneath the call tells you whether there is anything to fix. A dim `Not run · auto mode's check had no usable answer` row, or text that reports a problem with the classifier itself, such as `Auto mode could not evaluate this action`, means Claude Code blocked the call without a verdict from the classifier. For a `Not run` row, press `Ctrl+O` to read the full message, then see [Auto mode cannot determine the safety of an action](errors.md#auto-mode-cannot-determine-the-safety-of-an-action) or [The server returned no safety verdict](errors.md#the-server-returned-no-safety-verdict) for what to do. Otherwise, a line reading `Denied by auto mode classifier` with a reason such as `[Production Deploy]` or `Blocked by classifier` means the classifier judged the call unsafe, so pick the fix from what the call was trying to reach or do:

- A destination Claude needs throughout the task, such as a package registry, an internal domain, or a repository host: add it to `autoMode.environment`.
- A command you want to run without review from now on: add an `allow` rule.
- A one-off action you did intend: state that intent in your next message and let Claude retry.

You can add the environment entry or `allow` rule from the `/permissions` dialog’s [**Auto mode** tab](#edit-rules-from-permissions). The text in square brackets, such as `[Data Exfiltration]`, is the name of the rule the classifier matched. To read that rule’s full wording, see [Inspect the defaults and your effective config](#inspect-the-defaults-and-your-effective-config).


[​](#fix-repeated-denials)

Fix repeated denials

Repeated denials for the same destination usually mean the classifier is missing context. Add that destination to `autoMode.environment`, or [run `/auto-mode-setup`](#generate-environment-entries) to have Claude Code draft the entries, then run `claude auto-mode config` to confirm the change took effect.


[​](#see-also)

See also

- [Permission modes](permission-modes.md#eliminate-prompts-with-auto-mode): what auto mode is, what it blocks by default, and which sessions start in it
- [Managed settings](../13-Enterprise-Admin/server-managed-settings.md): deploy `autoMode` configuration across your organization
- [Permissions](permissions.md): allow, ask, and deny rules that apply before the classifier runs
- [All settings](settings-reference.md#automode): every settings key, including `autoMode`

---

## Automated Security Reviews in Claude Code | Claude Help Center

Source: https://support.claude.com/en/articles/11932705-automated-security-reviews-in-claude-code
Path: 02-Claude-Code-CLI/automated-security-reviews-in-claude-code.md

# Automated Security Reviews in Claude Code

March 16, 2026


Claude Code now includes automated security review features to help you identify and fix vulnerabilities in your code. This guide explains how to use the /security-review command and GitHub Actions to improve your code security.

**Note:** While automated security reviews help identify many common vulnerabilities, they should complement, not replace, your existing security practices and manual code reviews.

## Overview

Automated security reviews in Claude Code help developers catch vulnerabilities before they reach production. These features check for common security issues including SQL injection risks, cross-site scripting (XSS) vulnerabilities, authentication flaws, insecure data handling, and dependency vulnerabilities.

You can use security reviews in two ways: through the /security-review command for on-demand checks in your terminal, or through GitHub Actions for automatic review of pull requests.

## Availability

These features are available for all Claude Code users, including:

- Users on individual paid plans (Pro or Max).

- Individual users or enterprises with pay-as-you-go API Console accounts.

## Using the /security-review command

The /security-review command lets you run security analysis directly from your terminal before committing code.

### Running a Security Review

To check your code for vulnerabilities:

1.  Open Claude Code in your project directory.

2.  Run /security-review in the terminal.

3.  Claude will analyze your codebase and identify potential security concerns.

4.  Review the detailed explanations provided for each issue found.

### Implementing Fixes

After Claude identifies vulnerabilities, you can ask it to implement fixes directly. This keeps security reviews integrated into your development workflow, allowing you to address issues when they're easiest to resolve.

### Customizing the Command

You can customize the /security-review command for your specific needs. See the [security review documentation](https://github.com/anthropics/claude-code-security-review/tree/main?tab=readme-ov-file#security-review-slash-command) for configuration options.

## Setting up GitHub Actions for automated PR reviews

After installing and configuring the GitHub action, it will automatically review every pull request for security vulnerabilities when it's opened.

### Installation

To set up automated security reviews for your repository:

1.  Navigate to your repository's GitHub Actions settings

2.  Follow the [step-by-step installation guide](https://github.com/anthropics/claude-code-security-review) in our documentation

3.  Configure the action according to your team's security requirements

### How It Works

Once configured, the GitHub action:

- Triggers automatically when new pull requests are opened.

- Reviews code changes for security vulnerabilities.

- Applies customizable filtering rules to reduce false positives.

- Posts inline comments on the PR with identified concerns and recommended fixes.

This creates a consistent security review process across your entire team, ensuring code is checked for vulnerabilities before merging.

### Customization Options

You can customize the GitHub action to match your team's security policies, including setting specific rules for your codebase and adjusting sensitivity levels for different vulnerability types.

## What security issues can be detected?

Both the /security-review command and GitHub action check for common vulnerability patterns:

- **SQL injection risks**: Identifies potential database query vulnerabilities.

- **Cross-site scripting (XSS)**: Detects client-side script injection vulnerabilities.

- **Authentication and authorization flaws**: Finds issues with access control.

- **Insecure data handling**: Identifies problems with data validation and sanitization.

- **Dependency vulnerabilities**: Checks for known issues in third-party packages.

## Getting Started

To start using automated security reviews:

- **For the /security-review command**: Update Claude Code to the latest version (run), then run `/security-review` in your project directory.

  - Claude Code automatically keeps itself up to date to ensure you have the latest features and security fixes, but you can also run `claude update` to update manually.

- **For the GitHub actions**: Visit our [documentation](https://github.com/anthropics/claude-code-security-review) for installation and configuration instructions.

## Best Practices

For optimal results, we recommend running /security-review before committing significant changes and configuring the GitHub action for all repositories containing production code. Consider adjusting the filtering rules based on your team's specific security requirements and codebase characteristics.

---

## Best practices for Claude Code - Claude Code Docs

Source: https://code.claude.com/docs/en/best-practices
Path: 02-Claude-Code-CLI/best-practices.md

## On this page

- [Give Claude a way to verify its work](#give-claude-a-way-to-verify-its-work)
- [Explore first, then plan, then code](#explore-first-then-plan-then-code)
- [Provide specific context in your prompts](#provide-specific-context-in-your-prompts)
  - [Provide rich content](#provide-rich-content)
- [Configure your environment](#configure-your-environment)
  - [Write an effective CLAUDE.md](#write-an-effective-claude-md)
  - [Configure permissions](#configure-permissions)
  - [Use CLI tools](#use-cli-tools)
  - [Connect MCP servers](#connect-mcp-servers)
  - [Set up hooks](#set-up-hooks)
  - [Create skills](#create-skills)
  - [Create custom subagents](#create-custom-subagents)
  - [Install plugins](#install-plugins)
- [Communicate effectively](#communicate-effectively)
  - [Ask codebase questions](#ask-codebase-questions)
  - [Let Claude interview you](#let-claude-interview-you)
- [Manage your session](#manage-your-session)
  - [Course-correct early and often](#course-correct-early-and-often)
  - [Manage context aggressively](#manage-context-aggressively)
  - [Use subagents for investigation](#use-subagents-for-investigation)
  - [Rewind with checkpoints](#rewind-with-checkpoints)
  - [Resume conversations](#resume-conversations)
- [Automate and scale](#automate-and-scale)
  - [Run non-interactive mode](#run-non-interactive-mode)
  - [Run multiple Claude sessions](#run-multiple-claude-sessions)
  - [Fan out across files](#fan-out-across-files)
  - [Run autonomously with auto mode](#run-autonomously-with-auto-mode)
  - [Add an adversarial review step](#add-an-adversarial-review-step)
- [Avoid common failure patterns](#avoid-common-failure-patterns)
- [Develop your intuition](#develop-your-intuition)
- [Related resources](#related-resources)

Use Claude Code

# Best practices for Claude Code

Copy pageCopy page

Tips and patterns for getting the most out of Claude Code, from configuring your environment to scaling across parallel sessions.

Copy pageCopy page

Claude Code is an agentic coding environment. Unlike a chatbot that answers questions and waits, Claude Code can read your files, run commands, make changes, and autonomously work through problems while you watch, redirect, or step away entirely. This changes how you work. Instead of writing code yourself and asking Claude to review it, you describe what you want and Claude figures out how to build it. Claude explores, plans, and implements. But this autonomy still comes with a learning curve. Claude works within certain constraints you need to understand. This guide covers patterns that have proven effective across Anthropic’s internal teams and for engineers using Claude Code across various codebases, languages, and environments. For how the agentic loop works, see [How Claude Code works](how-claude-code-works.md).

------------------------------------------------------------------------

Most best practices are based on one constraint: Claude’s context window fills up fast, and performance degrades as it fills. Claude’s context window holds your entire conversation, including every message, every file Claude reads, and every command output. However, this can fill up fast. A single debugging session or codebase exploration might generate and consume tens of thousands of tokens. This matters since LLM performance degrades as context fills. When the context window is getting full, Claude may start “forgetting” earlier instructions or making more mistakes. The context window is the most important resource to manage. To see how a session fills up in practice, [watch an interactive walkthrough](context-window.md) of what loads at startup and what each file read costs. Track context usage continuously with a [custom status line](statusline.md), and see [Reduce token usage](../17-Billing-Plans/costs.md#reduce-token-usage) for strategies on reducing token usage.

------------------------------------------------------------------------


[​](#give-claude-a-way-to-verify-its-work)

Give Claude a way to verify its work

Give Claude a check it can run: tests, a build, a screenshot to compare. It’s the difference between a session you watch and one you walk away from.

Claude stops when the work looks done. Without a check it can run, “looks done” is the only signal available, and you become the verification loop: every mistake waits for you to notice it. Give Claude something that produces a pass or fail, and the loop closes on its own. Claude does the work, runs the check, reads the result, and iterates until the check passes. The check is anything that returns a signal Claude can read in the conversation: a test suite, a build exit code, a linter, a script that diffs output against a fixture, or a [browser screenshot](../03-IDE-Integrations/chrome.md) compared against a design. Run [`/verify`](../08-Plugins-Skills/skills.md#run-and-verify-your-app) yourself after Claude’s check passes to confirm the change against the running app.

| Strategy                              | Before                                                  | After                                                                                                                                                                                                   |
|---------------------------------------|---------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Provide verification criteria**     | *”implement a function that validates email addresses"* | *"write a validateEmail function. example test cases: [user@example.com](mailto:user@example.com) is true, invalid is false, [user@.com](mailto:user@.com) is false. run the tests after implementing”* |
| **Verify UI changes visually**        | *”make the dashboard look better"*                      | *"\[paste screenshot\] implement this design. take a screenshot of the result and compare it to the original. list differences and fix them”*                                                           |
| **Address root causes, not symptoms** | *”the build is failing"*                                | *"the build fails with this error: \[paste error\]. fix it and verify the build succeeds. address the root cause, don’t suppress the error”*                                                            |

Once the check exists, decide how hard it gates the stop:

- **In one prompt**: ask Claude to run the check and iterate in the same message, as in the table above.
- **Across a session**: set the check as a [`/goal` condition](goal.md). A separate evaluator re-checks it after every turn and Claude keeps working until the goal resolves. If Claude stalls, Claude Code eventually stops the run with the goal still set — see [how /goal evaluation works](goal.md#how-evaluation-works).
- **As a deterministic gate**: a [Stop hook](../07-Hooks/hooks.md#stop) runs your check as a script and blocks the turn from ending until it passes. [Stop input](../07-Hooks/hooks.md#stop-input) covers the cap on consecutive blocks.
- **By a second opinion**: a [verification subagent](../09-Agents-Patterns/sub-agents.md) or a [dynamic workflow](workflows.md) that checks its own findings has a fresh model try to refute the result, so the agent doing the work isn’t the one grading it.

Each step trades setup for attention. The prompt version works on any task today. The `/goal` and Stop hook versions are what let an unattended run finish correctly without you. Have Claude show evidence rather than asserting success: the test output, the command it ran and what it returned, or a screenshot of the result. Reviewing evidence is faster than re-running the verification yourself, and it works for sessions you weren’t watching.

------------------------------------------------------------------------


[​](#explore-first-then-plan-then-code)

Explore first, then plan, then code

Separate research and planning from implementation to avoid solving the wrong problem.

Letting Claude jump straight to coding can produce code that solves the wrong problem. Use [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode) to separate exploration from execution. The recommended workflow has four phases:

1

Explore

Enter plan mode by pressing `Shift+Tab` until the status bar shows `⏸ plan mode on`, or start the session with `claude --permission-mode plan`. Claude reads files and answers questions without making changes.

claude (plan mode)

```python
read /src/auth and understand how we handle sessions and login.
also look at how we manage environment variables for secrets.
```

2

Plan

Ask Claude to create a detailed implementation plan.

claude (plan mode)

```python
I want to add Google OAuth. What files need to change?
What's the session flow? Create a plan.
```

Press `Ctrl+G` to open the plan in your text editor for direct editing before Claude proceeds.

3

Implement

Switch out of plan mode by approving the plan or pressing `Shift+Tab`, then let Claude code, verifying against its plan.

claude

```python
implement the OAuth flow from your plan. write tests for the
callback handler, run the test suite and fix any failures.
```

4

Commit

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

claude

```python
commit with a descriptive message and open a PR
```

Plan mode is useful, but also adds overhead.For tasks where the scope is clear and the fix is small (like fixing a typo, adding a log line, or renaming a variable) ask Claude to do it directly.Planning is most useful when you’re uncertain about the approach, when the change modifies multiple files, or when you’re unfamiliar with the code being modified. If you could describe the diff in one sentence, skip the plan.

------------------------------------------------------------------------


[​](#provide-specific-context-in-your-prompts)

Provide specific context in your prompts

The more precise your instructions, the fewer corrections you’ll need.

Claude can infer intent, but it can’t read your mind. Reference specific files, mention constraints, and point to example patterns.

| Strategy                                                                                         | Before                                               | After                                                                                                                                                                                                                                                                                                                                                            |
|--------------------------------------------------------------------------------------------------|------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Scope the task.** Specify which file, what scenario, and testing preferences.                  | *”add tests for foo.py"*                             | *"write a test for foo.py covering the edge case where the user is logged out. avoid mocks.”*                                                                                                                                                                                                                                                                    |
| **Point to sources.** Direct Claude to the source that can answer a question.                    | *”why does ExecutionFactory have such a weird api?"* | *"look through ExecutionFactory’s git history and summarize how its api came to be”*                                                                                                                                                                                                                                                                             |
| **Reference existing patterns.** Point Claude to patterns in your codebase.                      | *”add a calendar widget"*                            | *"look at how existing widgets are implemented on the home page to understand the patterns. HotDogWidget.php is a good example. follow the pattern to implement a new calendar widget that lets the user select a month and paginate forwards/backwards to pick a year. build from scratch without libraries other than the ones already used in the codebase.”* |
| **Describe the symptom.** Provide the symptom, the likely location, and what “fixed” looks like. | *”fix the login bug"*                                | *"users report that login fails after session timeout. check the auth flow in src/auth/, especially token refresh. write a failing test that reproduces the issue, then fix it”*                                                                                                                                                                                 |

Vague prompts can be useful when you’re exploring and can afford to course-correct. A prompt like `"what would you improve in this file?"` can surface things you wouldn’t have thought to ask about.


[​](#provide-rich-content)

Provide rich content

Use `@` to reference files, paste screenshots/images, or pipe data directly.

You can provide rich data to Claude in several ways:

- **Reference files with `@`** instead of describing where code lives. Claude reads the file before responding.
- **Paste images directly**. Copy/paste or drag and drop images into the prompt.
- **Give URLs** for documentation and API references. Use `/permissions` to allowlist frequently used domains.
- **Pipe in data** by running `cat error.log | claude -p "explain this error"` to send file contents directly.
- **Let Claude fetch what it needs**. Tell Claude to pull context itself using Bash commands, MCP tools, or by reading files.

------------------------------------------------------------------------


[​](#configure-your-environment)

Configure your environment

A few setup steps make Claude Code significantly more effective across all your sessions. For a full overview of extension features and when to use each one, see [Extend Claude Code](features-overview.md).


[​](#write-an-effective-claude-md)

Write an effective CLAUDE.md

Run `/init` to generate a starter CLAUDE.md file based on your current project structure, then refine over time.

CLAUDE.md is a special file that Claude reads at the start of every conversation. Include Bash commands, code style, and workflow rules. This gives Claude persistent context it can’t infer from code alone. There’s no required format for CLAUDE.md files, but keep it short and human-readable. For example:

CLAUDE.md

```python
# Code style
- Use ES modules (import/export) syntax, not CommonJS (require)
- Destructure imports when possible (eg. import { foo } from 'bar')

# Workflow
- Be sure to typecheck when you're done making a series of code changes
- Prefer running single tests, and not the whole test suite, for performance
```

Run `/context` to confirm Claude loaded the file. CLAUDE.md is loaded every session, so only include things that apply broadly. For domain knowledge or workflows that are only relevant sometimes, use [skills](../08-Plugins-Skills/skills.md) instead. Claude loads them on demand without bloating every conversation. Keep it concise. For each line, ask: *“Would removing this cause Claude to make mistakes?”* If not, cut it. Bloated CLAUDE.md files cause Claude to ignore your actual instructions!

| ✅ Include                                           | ❌ Exclude                                         |
|------------------------------------------------------|----------------------------------------------------|
| Bash commands Claude can’t guess                     | Anything Claude can figure out by reading code     |
| Code style rules that differ from defaults           | Standard language conventions Claude already knows |
| Testing instructions and preferred test runners      | Detailed API documentation (link to docs instead)  |
| Repository etiquette (branch naming, PR conventions) | Information that changes frequently                |
| Architectural decisions specific to your project     | Long explanations or tutorials                     |
| Developer environment quirks (required env vars)     | File-by-file descriptions of the codebase          |
| Common gotchas or behaviors that aren’t self-evident | Self-evident practices like “write clean code”     |

If Claude keeps doing something you don’t want despite having a rule against it, the file is probably too long and the rule is getting lost. If Claude asks you questions that are answered in CLAUDE.md, the phrasing might be ambiguous. Treat CLAUDE.md like code: review it when things go wrong, prune it regularly, and test changes by observing whether Claude’s behavior actually shifts. For a checked-in CLAUDE.md, run [`/doctor`](commands.md#all-commands) and Claude proposes cuts for content it can derive from the codebase. If Claude keeps skipping one instruction, add emphasis such as “IMPORTANT” to that line alone. If you emphasize many lines, none of them stands out. Check CLAUDE.md into git so your team can contribute. The file compounds in value over time. CLAUDE.md files can import additional files using `@path/to/import` syntax. For import rules and where CLAUDE.md files can live, see [CLAUDE.md files](memory.md#claude-md-files).


[​](#configure-permissions)

Configure permissions

To get fewer prompts without giving up control, pre-approve the tools you trust with `/permissions` and let sandboxed commands run without asking with `/sandbox`. Switch to Manual mode when you want to approve edits and commands yourself.

With Claude Code v2.1.283 or later, auto mode is the [built-in starting permission mode](permission-modes.md#eliminate-prompts-with-auto-mode) for interactive terminal and VS Code sessions: a separate classifier model reviews most actions instead of you and blocks only what looks risky, such as scope escalation, unknown infrastructure, or hostile-content-driven actions. On earlier versions, auto mode is the built-in starting permission mode only on Pro, Max, and Team plans. In Manual mode, Claude Code asks before actions that might modify your system: file writes, Bash commands, MCP tools. That’s safe but tedious. After the tenth approval you’re clicking through rather than reviewing. Two tools cut those interruptions in Manual mode and apply in auto mode as well:

- **Permission allowlists**: permit specific tools you know are safe, like `npm run lint` or `git commit`
- **Sandboxing**: enable OS-level isolation that restricts filesystem and network access, allowing Claude to work more freely within defined boundaries

Read more about [permission modes](permission-modes.md), [permission rules](permissions.md), and [sandboxing](sandboxing.md).


[​](#use-cli-tools)

Use CLI tools

Tell Claude Code to use CLI tools like `gh`, `aws`, `gcloud`, and `sentry-cli` when interacting with external services.

CLI tools are the most context-efficient way to interact with external services. If you use GitHub, install the `gh` CLI. Claude knows how to use it for creating issues, opening pull requests, and reading comments. Without `gh`, Claude can still use the GitHub API, but unauthenticated requests often hit rate limits. Claude is also effective at learning CLI tools it doesn’t already know. Try prompts like `Use 'foo-cli-tool --help' to learn about foo tool, then use it to solve A, B, C.`


[​](#connect-mcp-servers)

Connect MCP servers

Run `claude mcp add` with a server name and URL or command to connect external tools like Notion, Figma, or your database. For example: `claude mcp add --transport http notion https://mcp.notion.com/mcp`.

With [MCP servers](../06-MCP-Tools/General/mcp.md), you can ask Claude to implement features from issue trackers, query databases, analyze monitoring data, integrate designs from Figma, and automate workflows.


[​](#set-up-hooks)

Set up hooks

Use hooks for actions that must happen every time with zero exceptions.

[Hooks](../07-Hooks/hooks-guide.md) run scripts automatically at specific points in Claude’s workflow. Unlike CLAUDE.md instructions which are advisory, hooks are deterministic and guarantee the action happens. Claude can write hooks for you. Try prompts like *“Write a hook that runs eslint after every file edit”* or *“Write a hook that blocks writes to the migrations folder.”* Edit `.claude/settings.json` directly to configure hooks by hand, and run `/hooks` to browse what’s configured.


[​](#create-skills)

Create skills

Create `SKILL.md` files in `.claude/skills/` to give Claude domain knowledge and reusable workflows.

[Skills](../08-Plugins-Skills/skills.md) extend Claude’s knowledge with information specific to your project, team, or domain. Claude applies them automatically when relevant, or you can invoke them directly with `/skill-name`. Create a skill by adding a directory with a `SKILL.md` to `.claude/skills/`:

.claude/skills/api-conventions/SKILL.md

```python
---
name: api-conventions
description: REST API design conventions for our services
---
# API Conventions
- Use kebab-case for URL paths
- Use camelCase for JSON properties
- Always include pagination for list endpoints
- Version APIs in the URL path (/v1/, /v2/)
```

Skills can also define repeatable workflows you invoke directly:

.claude/skills/fix-issue/SKILL.md

```python
---
name: fix-issue
description: Fix a GitHub issue
disable-model-invocation: true
---
Analyze and fix the GitHub issue: $ARGUMENTS.

1. Use `gh issue view` to get the issue details
2. Understand the problem described in the issue
3. Search the codebase for relevant files
4. Implement the necessary changes to fix the issue
5. Write and run tests to verify the fix
6. Ensure code passes linting and type checking
7. Create a descriptive commit message
8. Push and create a PR
```

Run `/fix-issue 1234` to invoke it. Use `disable-model-invocation: true` for workflows with side effects that you want to trigger manually.


[​](#create-custom-subagents)

Create custom subagents

Define specialized assistants in `.claude/agents/` that Claude can delegate to for isolated tasks.

[Subagents](../09-Agents-Patterns/sub-agents.md) run in their own context with their own set of allowed tools. They’re useful for tasks that read many files or need specialized focus without cluttering your main conversation.

.claude/agents/security-reviewer.md

```python
---
name: security-reviewer
description: Reviews code for security vulnerabilities
tools: Read, Grep, Glob, Bash
model: opus
---
You are a senior security engineer. Review code for:
- Injection vulnerabilities (SQL, XSS, command injection)
- Authentication and authorization flaws
- Secrets or credentials in code
- Insecure data handling

Provide specific line references and suggested fixes.
```

Tell Claude to use subagents explicitly: *“Use a subagent to review this code for security issues.”*


[​](#install-plugins)

Install plugins

Run `/plugin` to browse the marketplace. Plugins add skills, tools, and integrations without configuration.

[Plugins](../08-Plugins-Skills/plugins.md) bundle skills, hooks, subagents, and MCP servers into a single installable unit from the community and Anthropic. If you work with a typed language, install a [code intelligence plugin](../08-Plugins-Skills/plugins-code-intelligence.md) to give Claude precise symbol navigation and automatic error detection after edits. For guidance on choosing between skills, subagents, hooks, and MCP, see [Extend Claude Code](features-overview.md#match-features-to-your-goal).

------------------------------------------------------------------------


[​](#communicate-effectively)

Communicate effectively

Ask Claude the questions you’d ask another engineer, and for larger features have Claude interview you and write a spec before you start implementing.


[​](#ask-codebase-questions)

Ask codebase questions

Ask Claude questions you’d ask a senior engineer.

When onboarding to a new codebase, use Claude Code for learning and exploration. You can ask Claude the same sorts of questions you would ask another engineer:

- How does logging work?
- How do I make a new API endpoint?
- What does `async move { ... }` do on line 134 of `foo.rs`?
- What edge cases does `CustomerOnboardingFlowImpl` handle?
- Why does this code call `foo()` instead of `bar()` on line 333?

Using Claude Code this way is an effective onboarding workflow, improving ramp-up time and reducing load on other engineers. No special prompting required: ask questions directly.


[​](#let-claude-interview-you)

Let Claude interview you

For larger features, have Claude interview you first. Start with a minimal prompt and ask Claude to interview you using the `AskUserQuestion` tool.

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

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

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

Keep interviewing until we've covered everything, then write a complete spec to SPEC.md.
```

Once the spec is complete, start a fresh session to execute it. The new session has clean context focused entirely on implementation, and you have a written spec to reference. The most useful specs are self-contained: they name the files and interfaces involved, state what is out of scope, and end with an end-to-end verification step that proves the feature works. Time spent making the spec precise pays off more than time spent watching the implementation.

------------------------------------------------------------------------


[​](#manage-your-session)

Manage your session

Conversations are persistent and reversible. Use this to your advantage!


[​](#course-correct-early-and-often)

Course-correct early and often

Correct Claude as soon as you notice it going off track.

The best results come from tight feedback loops. Though Claude occasionally solves problems perfectly on the first attempt, correcting it quickly generally produces better solutions faster.

- **`Esc`**: stop Claude mid-action with the `Esc` key. Context is preserved, so you can redirect.
- **`Esc + Esc` or `/rewind`**: press `Esc` twice or run `/rewind` to open the rewind menu and restore previous conversation and code state, or summarize from a selected message.
- **`"Undo that"`**: have Claude revert its changes.
- **`/clear`**: reset context between unrelated tasks. Long sessions with irrelevant context can reduce performance.

If you’ve corrected Claude more than twice on the same issue in one session, the context is cluttered with failed approaches. Run `/clear` and start fresh with a more specific prompt that incorporates what you learned. A clean session with a better prompt almost always outperforms a long session with accumulated corrections.


[​](#manage-context-aggressively)

Manage context aggressively

Run `/clear` between unrelated tasks to reset context.

Claude Code automatically compacts conversation history when you approach context limits, which preserves important code and decisions while freeing space. During long sessions, Claude’s context window can fill with irrelevant conversation, file contents, and commands. This can reduce performance and sometimes distract Claude.

- Use `/clear` frequently between tasks to reset the context window entirely
- When auto compaction triggers, Claude summarizes what matters most, including code patterns, file states, and key decisions
- For more control, run `/compact <instructions>`, like `/compact Focus on the API changes`
- To compact only part of the conversation, use `Esc + Esc` or `/rewind`, select a message checkpoint, and choose **Summarize from here** or **Summarize up to here**. The first condenses messages from that point forward while keeping earlier context intact; the second condenses earlier messages while keeping recent ones in full. See [the rewind menu’s summarize options](checkpointing.md#rewind-and-summarize).
- Customize compaction behavior in CLAUDE.md with instructions like `"When compacting, always preserve the full list of modified files and any test commands"` to ensure critical context survives summarization
- For questions that don’t need to stay in context, use [`/btw`](interactive-mode.md#side-questions-with-%2Fbtw). The answer never enters conversation history, so you can check a detail without growing context.


[​](#use-subagents-for-investigation)

Use subagents for investigation

Delegate research with `"use subagents to investigate X"`. They explore in a separate context, keeping your main conversation clean for implementation.

Since context is your fundamental constraint, use subagents to keep research out of it. When Claude researches a codebase it reads lots of files, all of which consume your context. Subagents run in separate context windows and report back summaries:

```python
Use subagents to investigate how our authentication system handles token
refresh, and whether we have any existing OAuth utilities I should reuse.
```

You can also use subagents for verification after Claude implements something. See [Add an adversarial review step](#add-an-adversarial-review-step).


[​](#rewind-with-checkpoints)

Rewind with checkpoints

Every prompt you send that starts a turn creates a checkpoint. You can restore conversation, code, or both to any previous checkpoint.

Claude automatically snapshots files before each change so a checkpoint can restore them. Double-tap `Escape` or run `/rewind` to open the rewind menu. You can restore conversation only, restore code only, restore both, or summarize from a selected message. See [Checkpointing](checkpointing.md) for details. Instead of carefully planning every move, you can tell Claude to try something risky. If it doesn’t work, rewind and try a different approach. Checkpoints are saved with the conversation, so you can close your terminal, resume the session later, and still rewind.

Checkpoints only track changes made through Claude’s file editing tools. Changes made through Bash commands or external processes are not captured. This isn’t a replacement for git.


[​](#resume-conversations)

Resume conversations

Name sessions with `/rename` and treat them like branches: each workstream gets its own persistent context.

Claude Code saves conversations locally, so when a task spans multiple sittings you don’t have to re-explain the context. Run [`claude --continue`](sessions.md#resume-a-session) to pick up where you left off, or `claude --resume` to choose from a list. Give sessions descriptive names like `oauth-migration` so you can find them later. See [Manage sessions](sessions.md) for the full set of resume, branch, and naming controls.

------------------------------------------------------------------------


[​](#automate-and-scale)

Automate and scale

Once you’re effective with one Claude, multiply your output with parallel sessions, non-interactive mode, and fan-out patterns.


[​](#run-non-interactive-mode)

Run non-interactive mode

Use `claude -p "prompt"` in CI, pre-commit hooks, or scripts. Add `--output-format stream-json --verbose` for streaming JSON output.

With `claude -p "your prompt"`, you can run Claude non-interactively, without an interactive prompt. The run still creates a resumable session unless you pass `--no-session-persistence`. [Non-interactive mode](headless.md) is how you integrate Claude into CI pipelines, pre-commit hooks, or any automated workflow. The output formats let you parse results programmatically: plain text, JSON, or streaming JSON.

```python
# One-off queries
claude -p "Explain what this project does"

# Structured output for scripts
claude -p "List all API endpoints" --output-format json

# Streaming for real-time processing
claude -p "Analyze this log file" --output-format stream-json --verbose
```

The first command prints plain text. The `json` format returns a single JSON object with a `result` field. The `stream-json` format prints one JSON object per line, starting with an init event.


[​](#run-multiple-claude-sessions)

Run multiple Claude sessions

Run multiple Claude sessions in parallel to speed up development, run isolated experiments, or start complex workflows.

Pick the parallel approach that fits how much coordination you want to do yourself, and add messaging when the sessions need to pass findings between them:

- [Worktrees](worktrees.md): run separate CLI sessions in isolated git checkouts so edits don’t collide
- [Cross-session messaging](cross-session-messaging.md): let the sessions you run yourself pass findings to each other
- [Desktop app](../16-Mobile-Desktop/desktop.md#work-in-parallel-with-sessions): manage multiple local sessions visually, optionally each in its own worktree
- [Use Claude Code in the cloud](claude-code-on-the-web.md): run sessions on Anthropic-managed infrastructure by default
- [Agent view](../09-Agents-Patterns/agent-view.md): research preview. Run `claude agents` to dispatch sessions that keep running in the background and watch them from one screen
- [Agent teams](../09-Agents-Patterns/agent-teams.md): experimental and disabled by default. Automated coordination of multiple sessions with shared tasks, messaging, and a team lead

Beyond parallelizing work, multiple sessions enable quality-focused workflows. A fresh context improves code review since Claude won’t be biased toward code it just wrote. For example, use a Writer/Reviewer pattern:

| Session A (Writer)                                                      | Session B (Reviewer)                                                                                                                                                     |
|-------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `Implement a rate limiter for our API endpoints`                        |                                                                                                                                                                          |
|                                                                         | `Review the rate limiter implementation in @src/middleware/rateLimiter.ts. Look for edge cases, race conditions, and consistency with our existing middleware patterns.` |
| `Here's the review feedback: [Session B output]. Address these issues.` |                                                                                                                                                                          |

You can do something similar with tests: have one Claude write tests, then another write code to pass them.


[​](#fan-out-across-files)

Fan out across files

Loop through tasks calling `claude -p` for each. Use `--allowedTools` to pre-approve tools for batch operations.

For large migrations or analyses, you can distribute work across many parallel Claude invocations. Run [`/batch <instruction>`](commands.md#all-commands) to have Claude split the change across 5 to 30 subagents. Each subagent works in its own worktree. To drive the fan-out from your own script instead, loop over `claude -p`:

1

Generate a task list

Have Claude write the list of files that need migrating to a file, so the loop in the next step can read it, with a prompt like `list all 2,000 Python files that need migrating and save the list to files.txt`

2

Write a script to loop through the list

```python
for file in $(cat files.txt); do
  claude -p "Migrate $file from Python 2 to Python 3. Return OK or FAIL." \
    --allowedTools "Edit,Bash(git commit *)" \
    --permission-mode dontAsk
done
```

3

Test on a few files, then run on all of them

Refine your prompt based on what goes wrong with the first 2-3 files, then run on the full set. The `--allowedTools` flag pre-approves the tools the migration needs. [`--permission-mode dontAsk`](permission-modes.md#allow-only-pre-approved-tools-with-dontask-mode) denies anything else that would need approval, which matters when you’re running unattended, though a [mod](../08-Plugins-Skills/plugins-mods-overview.md) you installed can still approve some of those calls.

You can also integrate Claude into existing data/processing pipelines:

```python
claude -p "<your prompt>" --output-format json | your_command
```


[​](#run-autonomously-with-auto-mode)

Run autonomously with auto mode

For uninterrupted execution with background safety checks, use [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode). A classifier model reviews commands before they run, blocking scope escalation, unknown infrastructure, and hostile-content-driven actions while letting routine work proceed without prompts.

```python
claude --permission-mode auto -p "fix all lint errors"
```

When the classifier repeatedly blocks actions in a non-interactive run with the `-p` flag, Claude Code doesn’t stop the run. See [when auto mode falls back](permission-modes.md#when-auto-mode-falls-back) for what happens instead and for the thresholds.


[​](#add-an-adversarial-review-step)

Add an adversarial review step

Before treating a task as done, have a subagent review the diff in a fresh context and report gaps.

The longer Claude works unattended, the more an independent check matters before you count the work as done. A reviewer running in a fresh [subagent](../09-Agents-Patterns/sub-agents.md) context sees only the diff and the criteria you give it, not the reasoning that produced the change, so it evaluates the result on its own terms. For a correctness check, run the bundled [`/code-review` skill](commands.md), which reviews the current diff for bugs in a fresh subagent and returns findings to the session. To check the diff against your plan instead, write the review prompt yourself. Name the work to check, the plan to check it against, and what counts as a finding:

```python
Use a subagent to review the rate limiter diff against PLAN.md. Check that
every requirement is implemented, the listed edge cases have tests, and
nothing outside the task's scope changed. Report gaps, not style preferences.
```

Because the reviewer runs as a subagent, the implementing session receives the gaps directly and can fix them and re-review without you copying findings between windows.

A reviewer prompted to find gaps will usually report some, even when the work is sound, because that is what it was asked to do. Chasing every finding leads to over-engineering: extra abstraction layers, defensive code, and tests for cases that can’t happen. Tell the reviewer to flag only gaps that affect correctness or the stated requirements, and treat the rest as optional.

------------------------------------------------------------------------


[​](#avoid-common-failure-patterns)

Avoid common failure patterns

These are common mistakes. Recognizing them early saves time:

- **The kitchen sink session.** You start with one task, then ask Claude something unrelated, then go back to the first task. Context is full of irrelevant information.

  > **Fix**: `/clear` between unrelated tasks.

- **Correcting over and over.** Claude does something wrong, you correct it, it’s still wrong, you correct again. Context is polluted with failed approaches.

  > **Fix**: After two failed corrections, `/clear` and write a better initial prompt incorporating what you learned.

- **The over-specified CLAUDE.md.** If your CLAUDE.md is too long, Claude ignores half of it because important rules get lost in the noise.

  > **Fix**: Ruthlessly prune. If Claude already does something correctly without the instruction, delete it or convert it to a hook.

- **The trust-then-verify gap.** Claude produces a plausible-looking implementation that doesn’t handle edge cases.

  > **Fix**: Always provide verification (tests, scripts, screenshots). If you can’t verify it, don’t ship it.

- **The infinite exploration.** You ask Claude to “investigate” something without scoping it. Claude reads hundreds of files, filling the context.

  > **Fix**: Scope investigations narrowly or use subagents so the exploration doesn’t consume your main context.

------------------------------------------------------------------------


[​](#develop-your-intuition)

Develop your intuition

The patterns in this guide aren’t set in stone. They’re starting points that work well in general, but might not be optimal for every situation. Sometimes you *should* let context accumulate because you’re deep in one complex problem and the history is valuable. Sometimes you should skip planning and let Claude figure it out because the task is exploratory. Sometimes a vague prompt is exactly right because you want to see how Claude interprets the problem before constraining it. Pay attention to what works. When Claude produces great output, notice what you did: the prompt structure, the context you provided, the mode you were in. When Claude struggles, ask why. Was the context too noisy? The prompt too vague? The task too big for one pass? Over time, you’ll develop intuition that no guide can capture. You’ll know when to be specific and when to be open-ended, when to plan and when to explore, when to clear context and when to let it accumulate.


[​](#related-resources)

Related resources

- [How Claude Code works](how-claude-code-works.md): the agentic loop, tools, and context management
- [Extend Claude Code](features-overview.md): skills, hooks, MCP, subagents, and plugins
- [Common workflows](common-workflows.md): step-by-step recipes for debugging, testing, PRs, and more
- [CLAUDE.md](memory.md): store project conventions and persistent context

---

## Claude Code on the web | Claude by Anthropic

Source: https://www.claude.com/blog/claude-code-on-the-web
Path: 02-Claude-Code-CLI/blog-claude-code-on-the-web.md

# Claude Code on the web

- 

  Category[Announcements](https://www.claude.com/resources/product-announcements)
- 

  ProductClaude Code
- 

  DateOctober 20, 2025
- 

  Reading time4 min
- 


***Update:** Cloud sessions (previously known as Claude Code on the web) are now generally available for Pro, Max, and Team users, and for Enterprise users with premium seats or Chat + Claude Code seats. Read the [docs](claude-code-on-the-web.md) for the latest information. September 23, 2026.*

Today, we're introducing Claude Code on the web, a new way to delegate coding tasks directly from your browser.

Now in beta as a research preview, you can assign multiple coding tasks to Claude that run on Anthropic-managed cloud infrastructure, perfect for tackling bug backlogs, routine fixes, or parallel development work.

## Run coding tasks in parallel

Claude Code on the web lets you kick off coding sessions without opening your terminal. Connect your GitHub repositories, describe what you need, and Claude handles the implementation.

Each session runs in its own isolated environment with real-time progress tracking, and you can actively steer Claude to adjust course as it’s working through tasks.

With Claude Code running in the cloud, you can now **run multiple tasks in parallel** across different repositories from a single interface and **ship faster** with automatic PR creation and clear change summaries.

## Flexible for every workflow

The web interface complements your existing Claude Code workflow. Running tasks in the cloud is especially effective for:

- Answering questions about how projects work and how repositories are mapped
- Bugfixes and routine, well-defined tasks
- Backend changes, where Claude Code can use test-driven development to verify changes

You can also use Claude Code on mobile. As part of this research preview, we’re making Claude Code available on our iOS app so developers can explore coding with Claude on the go. It’s an early preview, and we hope to quickly refine the mobile experience based on your feedback.  

## Security-first cloud execution

Every Claude Code task runs in an isolated sandbox environment with network and filesystem restrictions. Git interactions are handled through a secure proxy service that ensures Claude can only access authorized repositories—helping keep your code and credentials protected throughout the entire workflow.

You can also add custom network configuration to choose what domains Claude Code can connect to from its sandbox. For example, you can allow Claude to download npm packages over the internet so that it can run tests and validate changes.

Read our [engineering blog](https://www.anthropic.com/engineering/claude-code-sandboxing) and [documentation](https://docs.claude.com/en/docs/claude-code/sandboxing) for a deep dive on Claude Code’s sandboxing approach.

## Getting started

Claude Code on the web is available now in research preview for Pro and Max users. Visit [claude.com/code](http://claude.com/code) to connect your first repository and start delegating tasks.

Cloud-based sessions share rate limits with all other Claude Code usage. [Explore our documentation](https://docs.claude.com/en/docs/claude-code/claude-code-on-the-web) to learn more.

## Related articles

Explore more product news and best practices for teams building with Claude.


ArticleOct 22, 2026

### The full Claude Platform, available on Google Cloud

Use Claude Models on Google Cloud (Anthropic managed) to access Claude Platform features with Google Cloud authentication, billing, and commitment retirement.

Claude Platform


ArticleOct 21, 2026

### HCLTech joins the Claude Partner Network as a Global Premier partner

HCLTech will bring Claude into the solutions it provides for banks, hospitals, telecom companies, and manufacturers.


ArticleOct 21, 2026

### Introducing Claude Duet

A research preview is available by waitlist today, starting with US Pro and Max subscribers.


ArticleOct 21, 2026

### Claude Security now scans continuously and tracks fixes

Claude Security now keeps up with your repositories as code changes, tracks findings until they’re fixed, learns from the context your team adds, and connects to your tools through an API and MCP. Available in public beta for Claude Enterprise customers.

Claude Security

---

## Claude Code changelog - Claude Code Docs

Source: https://code.claude.com/docs/en/changelog
Path: 02-Claude-Code-CLI/changelog.md

## On this page

- [2.1.309](#2-1-309)
- [2.1.308](#2-1-308)
- [2.1.307](#2-1-307)
- [2.1.306](#2-1-306)
- [2.1.305](#2-1-305)
- [2.1.304](#2-1-304)
- [2.1.303](#2-1-303)
- [2.1.302](#2-1-302)
- [2.1.301](#2-1-301)
- [2.1.300](#2-1-300)
- [2.1.299](#2-1-299)
- [2.1.296](#2-1-296)
- [2.1.295](#2-1-295)
- [2.1.294](#2-1-294)
- [2.1.293](#2-1-293)
- [2.1.292](#2-1-292)
- [2.1.291](#2-1-291)
- [2.1.290](#2-1-290)
- [2.1.289](#2-1-289)
- [2.1.288](#2-1-288)
- [2.1.287](#2-1-287)
- [2.1.286](#2-1-286)
- [2.1.285](#2-1-285)
- [2.1.284](#2-1-284)
- [2.1.283](#2-1-283)
- [2.1.282](#2-1-282)
- [2.1.281](#2-1-281)
- [2.1.280](#2-1-280)
- [2.1.278](#2-1-278)
- [2.1.277](#2-1-277)
- [2.1.276](#2-1-276)
- [2.1.275](#2-1-275)
- [2.1.274](#2-1-274)
- [2.1.273](#2-1-273)
- [2.1.272](#2-1-272)
- [2.1.271](#2-1-271)
- [2.1.270](#2-1-270)
- [2.1.269](#2-1-269)
- [2.1.268](#2-1-268)
- [2.1.267](#2-1-267)
- [2.1.266](#2-1-266)
- [2.1.265](#2-1-265)
- [2.1.263](#2-1-263)
- [2.1.261](#2-1-261)
- [2.1.260](#2-1-260)
- [2.1.259](#2-1-259)
- [2.1.258](#2-1-258)
- [2.1.257](#2-1-257)
- [2.1.252](#2-1-252)
- [2.1.251](#2-1-251)
- [2.1.250](#2-1-250)
- [2.1.248](#2-1-248)
- [2.1.247](#2-1-247)
- [2.1.246](#2-1-246)
- [2.1.245](#2-1-245)
- [2.1.243](#2-1-243)
- [2.1.241](#2-1-241)
- [2.1.240](#2-1-240)
- [2.1.239](#2-1-239)
- [2.1.238](#2-1-238)
- [2.1.237](#2-1-237)
- [2.1.236](#2-1-236)
- [2.1.235](#2-1-235)
- [2.1.234](#2-1-234)
- [2.1.233](#2-1-233)
- [2.1.232](#2-1-232)
- [2.1.231](#2-1-231)
- [2.1.229](#2-1-229)
- [2.1.228](#2-1-228)
- [2.1.227](#2-1-227)
- [2.1.226](#2-1-226)
- [2.1.225](#2-1-225)
- [2.1.224](#2-1-224)
- [2.1.223](#2-1-223)
- [2.1.222](#2-1-222)
- [2.1.221](#2-1-221)
- [2.1.220](#2-1-220)
- [2.1.219](#2-1-219)
- [2.1.218](#2-1-218)
- [2.1.217](#2-1-217)
- [2.1.216](#2-1-216)
- [2.1.215](#2-1-215)
- [2.1.214](#2-1-214)
- [2.1.212](#2-1-212)
- [2.1.211](#2-1-211)
- [2.1.210](#2-1-210)
- [2.1.209](#2-1-209)
- [2.1.208](#2-1-208)
- [2.1.207](#2-1-207)
- [2.1.206](#2-1-206)
- [2.1.205](#2-1-205)
- [2.1.204](#2-1-204)
- [2.1.203](#2-1-203)
- [2.1.202](#2-1-202)
- [2.1.201](#2-1-201)
- [2.1.200](#2-1-200)
- [2.1.199](#2-1-199)
- [2.1.198](#2-1-198)
- [2.1.197](#2-1-197)
- [2.1.196](#2-1-196)
- [2.1.195](#2-1-195)
- [2.1.193](#2-1-193)
- [2.1.191](#2-1-191)
- [2.1.190](#2-1-190)
- [2.1.187](#2-1-187)
- [2.1.186](#2-1-186)
- [2.1.185](#2-1-185)
- [2.1.183](#2-1-183)
- [2.1.181](#2-1-181)
- [2.1.179](#2-1-179)
- [2.1.178](#2-1-178)
- [2.1.176](#2-1-176)
- [2.1.175](#2-1-175)
- [2.1.174](#2-1-174)
- [2.1.173](#2-1-173)
- [2.1.172](#2-1-172)
- [2.1.170](#2-1-170)
- [2.1.169](#2-1-169)
- [2.1.168](#2-1-168)
- [2.1.167](#2-1-167)
- [2.1.166](#2-1-166)
- [2.1.165](#2-1-165)
- [2.1.163](#2-1-163)
- [2.1.162](#2-1-162)
- [2.1.161](#2-1-161)
- [2.1.160](#2-1-160)
- [2.1.159](#2-1-159)
- [2.1.158](#2-1-158)
- [2.1.157](#2-1-157)
- [2.1.156](#2-1-156)
- [2.1.154](#2-1-154)
- [2.1.153](#2-1-153)
- [2.1.152](#2-1-152)
- [2.1.150](#2-1-150)
- [2.1.149](#2-1-149)
- [2.1.148](#2-1-148)
- [2.1.147](#2-1-147)
- [2.1.145](#2-1-145)
- [2.1.144](#2-1-144)
- [2.1.143](#2-1-143)
- [2.1.142](#2-1-142)
- [2.1.141](#2-1-141)
- [2.1.140](#2-1-140)
- [2.1.139](#2-1-139)
- [2.1.138](#2-1-138)
- [2.1.137](#2-1-137)
- [2.1.136](#2-1-136)
- [2.1.133](#2-1-133)
- [2.1.132](#2-1-132)
- [2.1.131](#2-1-131)
- [2.1.129](#2-1-129)
- [2.1.128](#2-1-128)
- [2.1.126](#2-1-126)
- [2.1.123](#2-1-123)
- [2.1.122](#2-1-122)
- [2.1.121](#2-1-121)
- [2.1.120](#2-1-120)
- [2.1.119](#2-1-119)
- [2.1.118](#2-1-118)
- [2.1.117](#2-1-117)
- [2.1.116](#2-1-116)
- [2.1.114](#2-1-114)
- [2.1.113](#2-1-113)
- [2.1.112](#2-1-112)
- [2.1.111](#2-1-111)
- [2.1.110](#2-1-110)
- [2.1.109](#2-1-109)
- [2.1.108](#2-1-108)
- [2.1.107](#2-1-107)
- [2.1.105](#2-1-105)
- [2.1.101](#2-1-101)
- [2.1.98](#2-1-98)
- [2.1.97](#2-1-97)
- [2.1.96](#2-1-96)
- [2.1.94](#2-1-94)
- [2.1.92](#2-1-92)
- [2.1.91](#2-1-91)
- [2.1.90](#2-1-90)
- [2.1.89](#2-1-89)
- [2.1.87](#2-1-87)
- [2.1.86](#2-1-86)
- [2.1.85](#2-1-85)
- [2.1.84](#2-1-84)
- [2.1.83](#2-1-83)
- [2.1.81](#2-1-81)
- [2.1.80](#2-1-80)
- [2.1.79](#2-1-79)
- [2.1.78](#2-1-78)
- [2.1.77](#2-1-77)
- [2.1.76](#2-1-76)
- [2.1.75](#2-1-75)
- [2.1.74](#2-1-74)
- [2.1.73](#2-1-73)
- [2.1.72](#2-1-72)
- [2.1.71](#2-1-71)
- [2.1.70](#2-1-70)
- [2.1.69](#2-1-69)
- [2.1.68](#2-1-68)
- [2.1.66](#2-1-66)
- [2.1.63](#2-1-63)
- [2.1.62](#2-1-62)
- [2.1.61](#2-1-61)
- [2.1.59](#2-1-59)
- [2.1.58](#2-1-58)
- [2.1.56](#2-1-56)
- [2.1.55](#2-1-55)
- [2.1.53](#2-1-53)
- [2.1.52](#2-1-52)
- [2.1.51](#2-1-51)
- [2.1.50](#2-1-50)
- [2.1.49](#2-1-49)
- [2.1.47](#2-1-47)
- [2.1.46](#2-1-46)
- [2.1.45](#2-1-45)
- [2.1.44](#2-1-44)
- [2.1.43](#2-1-43)
- [2.1.42](#2-1-42)
- [2.1.41](#2-1-41)
- [2.1.39](#2-1-39)
- [2.1.38](#2-1-38)
- [2.1.37](#2-1-37)
- [2.1.36](#2-1-36)
- [2.1.34](#2-1-34)
- [2.1.33](#2-1-33)
- [2.1.32](#2-1-32)
- [2.1.31](#2-1-31)
- [2.1.30](#2-1-30)
- [2.1.29](#2-1-29)
- [2.1.27](#2-1-27)
- [2.1.25](#2-1-25)
- [2.1.23](#2-1-23)
- [2.1.22](#2-1-22)
- [2.1.21](#2-1-21)
- [2.1.20](#2-1-20)
- [2.1.19](#2-1-19)
- [2.1.18](#2-1-18)
- [2.1.17](#2-1-17)
- [2.1.16](#2-1-16)
- [2.1.15](#2-1-15)
- [2.1.14](#2-1-14)
- [2.1.12](#2-1-12)
- [2.1.11](#2-1-11)
- [2.1.10](#2-1-10)
- [2.1.9](#2-1-9)
- [2.1.7](#2-1-7)
- [2.1.6](#2-1-6)
- [2.1.5](#2-1-5)
- [2.1.4](#2-1-4)
- [2.1.3](#2-1-3)
- [2.1.2](#2-1-2)
- [2.1.0](#2-1-0)
- [2.0.76](#2-0-76)
- [2.0.75](#2-0-75)
- [2.0.74](#2-0-74)
- [2.0.73](#2-0-73)
- [2.0.72](#2-0-72)
- [2.0.71](#2-0-71)
- [2.0.70](#2-0-70)
- [2.0.69](#2-0-69)
- [2.0.68](#2-0-68)
- [2.0.67](#2-0-67)
- [2.0.65](#2-0-65)
- [2.0.64](#2-0-64)
- [2.0.62](#2-0-62)
- [2.0.61](#2-0-61)
- [2.0.60](#2-0-60)
- [2.0.59](#2-0-59)
- [2.0.58](#2-0-58)
- [2.0.57](#2-0-57)
- [2.0.56](#2-0-56)
- [2.0.55](#2-0-55)
- [2.0.54](#2-0-54)
- [2.0.52](#2-0-52)
- [2.0.51](#2-0-51)
- [2.0.50](#2-0-50)
- [2.0.49](#2-0-49)
- [2.0.47](#2-0-47)
- [2.0.46](#2-0-46)
- [2.0.45](#2-0-45)
- [2.0.43](#2-0-43)
- [2.0.42](#2-0-42)
- [2.0.41](#2-0-41)
- [2.0.37](#2-0-37)
- [2.0.36](#2-0-36)
- [2.0.35](#2-0-35)
- [2.0.34](#2-0-34)
- [2.0.33](#2-0-33)
- [2.0.32](#2-0-32)
- [2.0.31](#2-0-31)
- [2.0.30](#2-0-30)
- [2.0.28](#2-0-28)
- [2.0.27](#2-0-27)
- [2.0.25](#2-0-25)
- [2.0.24](#2-0-24)
- [2.0.22](#2-0-22)
- [2.0.21](#2-0-21)
- [2.0.20](#2-0-20)
- [2.0.19](#2-0-19)
- [2.0.17](#2-0-17)
- [2.0.15](#2-0-15)
- [2.0.14](#2-0-14)
- [2.0.13](#2-0-13)
- [2.0.12](#2-0-12)
- [2.0.11](#2-0-11)
- [2.0.10](#2-0-10)
- [2.0.9](#2-0-9)
- [2.0.8](#2-0-8)
- [2.0.5](#2-0-5)
- [2.0.1](#2-0-1)
- [2.0.0](#2-0-0)
- [1.0.126](#1-0-126)
- [1.0.124](#1-0-124)
- [1.0.123](#1-0-123)
- [1.0.120](#1-0-120)
- [1.0.119](#1-0-119)
- [1.0.117](#1-0-117)
- [1.0.115](#1-0-115)
- [1.0.113](#1-0-113)
- [1.0.112](#1-0-112)
- [1.0.111](#1-0-111)
- [1.0.110](#1-0-110)
- [1.0.109](#1-0-109)
- [1.0.106](#1-0-106)
- [1.0.97](#1-0-97)
- [1.0.94](#1-0-94)
- [1.0.93](#1-0-93)
- [1.0.90](#1-0-90)
- [1.0.88](#1-0-88)
- [1.0.86](#1-0-86)
- [1.0.85](#1-0-85)
- [1.0.84](#1-0-84)
- [1.0.83](#1-0-83)
- [1.0.82](#1-0-82)
- [1.0.81](#1-0-81)
- [1.0.80](#1-0-80)
- [1.0.77](#1-0-77)
- [1.0.73](#1-0-73)
- [1.0.72](#1-0-72)
- [1.0.71](#1-0-71)
- [1.0.70](#1-0-70)
- [1.0.69](#1-0-69)
- [1.0.68](#1-0-68)
- [1.0.65](#1-0-65)
- [1.0.64](#1-0-64)
- [1.0.63](#1-0-63)
- [1.0.62](#1-0-62)
- [1.0.61](#1-0-61)
- [1.0.60](#1-0-60)
- [1.0.59](#1-0-59)
- [1.0.58](#1-0-58)
- [1.0.57](#1-0-57)
- [1.0.56](#1-0-56)
- [1.0.55](#1-0-55)
- [1.0.54](#1-0-54)
- [1.0.53](#1-0-53)
- [1.0.52](#1-0-52)
- [1.0.51](#1-0-51)
- [1.0.48](#1-0-48)
- [1.0.45](#1-0-45)
- [1.0.44](#1-0-44)
- [1.0.43](#1-0-43)
- [1.0.42](#1-0-42)
- [1.0.41](#1-0-41)
- [1.0.40](#1-0-40)
- [1.0.39](#1-0-39)
- [1.0.38](#1-0-38)
- [1.0.37](#1-0-37)
- [1.0.36](#1-0-36)
- [1.0.35](#1-0-35)
- [1.0.34](#1-0-34)
- [1.0.33](#1-0-33)
- [1.0.32](#1-0-32)
- [1.0.31](#1-0-31)
- [1.0.30](#1-0-30)
- [1.0.29](#1-0-29)
- [1.0.28](#1-0-28)
- [1.0.27](#1-0-27)
- [1.0.25](#1-0-25)
- [1.0.24](#1-0-24)
- [1.0.23](#1-0-23)
- [1.0.22](#1-0-22)
- [1.0.21](#1-0-21)
- [1.0.18](#1-0-18)
- [1.0.17](#1-0-17)
- [1.0.11](#1-0-11)
- [1.0.10](#1-0-10)
- [1.0.8](#1-0-8)
- [1.0.7](#1-0-7)
- [1.0.6](#1-0-6)
- [1.0.4](#1-0-4)
- [1.0.1](#1-0-1)
- [1.0.0](#1-0-0)
- [0.2.125](#0-2-125)
- [0.2.117](#0-2-117)
- [0.2.108](#0-2-108)
- [0.2.107](#0-2-107)
- [0.2.106](#0-2-106)
- [0.2.105](#0-2-105)
- [0.2.102](#0-2-102)
- [0.2.100](#0-2-100)
- [0.2.98](#0-2-98)
- [0.2.96](#0-2-96)
- [0.2.93](#0-2-93)
- [0.2.82](#0-2-82)
- [0.2.75](#0-2-75)
- [0.2.74](#0-2-74)
- [0.2.72](#0-2-72)
- [0.2.70](#0-2-70)
- [0.2.69](#0-2-69)
- [0.2.67](#0-2-67)
- [0.2.66](#0-2-66)
- [0.2.63](#0-2-63)
- [0.2.61](#0-2-61)
- [0.2.59](#0-2-59)
- [0.2.54](#0-2-54)
- [0.2.53](#0-2-53)
- [0.2.50](#0-2-50)
- [0.2.49](#0-2-49)
- [0.2.47](#0-2-47)
- [0.2.44](#0-2-44)
- [0.2.41](#0-2-41)
- [0.2.37](#0-2-37)
- [0.2.36](#0-2-36)
- [0.2.34](#0-2-34)
- [0.2.32](#0-2-32)
- [0.2.31](#0-2-31)
- [0.2.30](#0-2-30)
- [0.2.26](#0-2-26)
- [0.2.21](#0-2-21)

Getting started

# Claude Code changelog

Copy pageCopy page

Release notes for Claude Code, including new features, improvements, and bug fixes by version.

Copy pageCopy page

This page is generated from the [CHANGELOG.md on GitHub](https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md). Longer releases are grouped by type of change, with long lists of improvements and bug fixes collapsed. Run `claude --version` to check your installed version.

[​](#2-1-309)

2.1.309

October 22, 2026

**Added**

- \[VSCode\] Added a log warning that says what to do when dictation or the extension’s own requests fail certificate verification, such as behind a TLS-inspecting proxy

**Changed**

- Updated the bundled dataviz skill to accept APCA as a text-contrast measure (keeping WCAG 2 ratios where AA conformance is required), add an `apca(text, background)` function to its palette validator scripts, and say whether a label inside a colored chart fill should be white or near-black
- Updated the /claude-api skill: service account keys and Workload Identity Federation tokens can now manage OpenTelemetry destinations
- Changed `sed -i` to get the standard Bash prompt and run as written, not a simulated file-edit preview; like other Bash edits, it is no longer restored by `/rewind`
- Changed `claude ultrareview` to require workspace trust: it asks on a terminal, else refuses; scripts pass `--trust-workspace`, which takes no value (put a PR number or base branch before it), or set `CLAUDE_CODE_DISABLE_ULTRAREVIEW_TRUST_CHECK=1`
- Changed the dangerous `rm` and `rmdir` prompt in bypass permissions mode in the Desktop app and VS Code to deny the command at once with a rewrite hint, so unattended sessions keep going
- Changed commands the settings exclude from the sandbox to ask before writing to its write-list paths while the sandbox is enabled but cannot run; the unsandboxed fallback is refused there
- Changed worktree creation and reuse so git no longer fetches objects on demand, in ordinary clones and in partial clones with a Bash sandbox configured; such a partial clone fetches them first
- Changed the `/claude-api` skill to build Managed Agents subagent teams on `multiagent_20261001` with dynamic workflows on by default, instead of `coordinator`

Show 8 improvements

- Improved the speed of many git commands Claude Code runs for itself on Windows; on every platform, errors from those commands now show in English even when git is set to another language
- Improved the error when a hooks module is nested too deep to load: it now names the file instead of showing a bare stack-overflow message
- Improved disk-full handling: a Bash command cut off by a full disk now says so and names the folder to free up, and starting on a full temp volume prints a clear message, not a raw ENOSPC error
- Improved the /claude-api skill to offer API tracing alongside SDK tracing when asked to add OpenTelemetry
- Improved the /claude-api skill to check the live docs before saying a feature is unsupported
- Self-hosted runner: Improved sessions that move to a new runner: Claude now sees the tool call that was interrupted, marked as outcome unknown
- \[VSCode\] Improved Edit and Write speed in the chat panel: the wait for new problems after each edit is now 0.75 seconds in most cases, down from 1 to 1.5 seconds
- \[Cloud sessions\] Improved a cloud session’s Changes pane, which now says when it lists only pushed commits or only Claude’s edits

Show 62 bug fixes

- Fixed sandboxed Bash commands on macOS and Linux running the shell’s startup files outside the sandbox before each command
- Fixed macOS sandbox `denyWrite` glob patterns not applying at a path’s real location when the pattern’s folder is reached through a symlink
- Fixed sandboxed commands and auto-accepted edits being able to modify the MCP config file passed with `--mcp-config`
- Fixed a disabled MCP server being reconnected by a later permission prompt in print and SDK sessions
- Fixed the Bash permission check trusting a variable set by a command whose redirect can fail to open
- Fixed Bash permission checks not prompting for some compound commands that change directory before running git when the `cd` is wrapped or prefixed, as they do for a plain `cd`
- Fixed an `Edit(path)` deny rule not blocking a Bash redirect to that path in some commands that also held a subshell
- Fixed worktree-isolated sessions accepting some locale-prefixed commands the isolation guard should refuse
- Fixed worktree-isolated sessions on zsh accepting some arithmetic commands that the isolation guard should refuse
- Fixed worktrees and branch checkouts that Claude Code creates so they ignore git replace refs, as its other git operations already do
- Fixed profile store write protection not applying when the config directory is reached through a symlink
- Fixed sessions compacting repeatedly after reading files under a very large nested CLAUDE.md; a nested CLAUDE.md over the size limit now loads only its start
- Fixed ctrl+enter (send now) only queuing a message when pressed before the response had started, and restarting a prompt’s hooks while leaving the message queued when pressed while those hooks were running
- Fixed key-bound slash commands running in the shell from `!` mode
- Fixed ctrl+o not showing messages from other agents and sessions that are still waiting to be delivered; they now appear in full under the transcript, marked as waiting
- Fixed long tool output previews being cut through an emoji, leaving session transcripts that `jq` could not parse
- Fixed Read reporting “File does not exist” for PDF page ranges in Linux sandboxes that share the parent’s `/proc`
- Fixed messages from a Claude Desktop-hosted session sometimes being lost when its connection refreshed
- Fixed features missing from Claude Code sessions in the Claude desktop app when the terminal on the same computer was signed in to a different account or organization
- Fixed the `claude remote-control` status line showing `HEAD` as the branch for a folder that is not in a git repository
- Fixed split-pane agent teammates not inheriting the tool deny and `--tools` rules given on the leader’s command line
- Fixed sessions renamed with `/rename` appearing to other sessions under a generated name after a VS Code window reload or a non-interactive `--resume`
- Fixed the `/rewind` list showing “No code changes” for a turn that changed checkpointed files through `/code-review --fix`, a subagent or a shell command
- Fixed `/privacy-settings` showing an out-of-date “Help improve our AI models” value; it now also says when the setting can’t be fetched
- Fixed feedback saying “try again later” when your organization does not accept feedback; it now shows the server’s reason and where to report a bug
- Fixed oversized /feedback reports failing instead of being resent without the transcript
- Fixed a skill in an `--add-dir` folder being unreachable when another skill already held its name; it is now offered as `<folder>:<name>`
- Fixed `/verify` and `/code-review` not finding a nested package’s own skill when its files were changed from the shell
- Fixed the /claude-api skill saying that `ant beta:worker poll --on-work` passes trace context to the command
- Fixed the /claude-api skill’s C# tracing setup missing spans from the cloud platform clients
- Fixed the /claude-api skill saying that API spans for requests to Claude Platform on AWS can’t join the caller’s trace
- Fixed hooks that run in PowerShell not blocking when the hook’s program exits with code 2, and on Windows `PreToolUse` and `PermissionRequest` hooks with `"shell": "powershell"` failing open when Git for Windows isn’t installed
- Fixed a mod’s `turn.step` hook that names a model by alias, such as `haiku`, failing every request with a model error: the alias now resolves to its model
- Fixed plugins and skills synced from claude.ai being removed, sometimes mid-session, after a disk read error
- Fixed artifact publishes and updates being refused for some ordinary pages, such as pages with certain minified scripts or artifacts Claude could not read first
- Fixed Claude asking for permission on each artifact update for the rest of a turn after the conversation was compacted in that turn
- Fixed fine-grained tool streaming staying off on Amazon Bedrock when `ANTHROPIC_BEDROCK_BASE_URL` is set to the default `bedrock-runtime.<region>.amazonaws.com` endpoint
- Fixed the “Waiting for API response” hint flickering behind gateways that send only keepalive pings: routes off Anthropic’s backend now wait 45 seconds
- Fixed Claude notifying unrelated GitHub users by writing role names and placeholders as mentions in PRs, issues and comments
- Linux: Fixed sandbox write denies lifting when a background command outlived the session
- Windows: Fixed PowerShell permission checks auto-approving some `Set-Location` or `cd` commands that target the current directory and carry extra arguments; these now prompt for approval
- macOS: Fixed the “Install Command Line Developer Tools” dialog opening each time Claude Code starts on a Mac without Xcode or the Command Line Tools
- Self-hosted runner: Fixed `--startup-timeout-min` stopping a session whose first prompt, such as `/code-review`, was still working in a subagent; a frozen process is still stopped
- \[VSCode\] Fixed the Claude panel staying blank after the editor cached an incomplete copy of its files; it now recovers by itself, or says what went wrong and how to fix it
- \[VSCode\] Fixed Session history filling up with empty “Untitled” sessions each time you start a new session without sending a message
- \[VSCode\] Fixed long slash-command messages such as `/goal` filling the chat panel; they now fold behind Show more like other prompts (anthropics/claude-code#97469)
- \[VSCode\] Fixed long messages not folding behind Show more after the chat panel is made narrower
- \[VSCode\] Fixed Ctrl+J in the chat input always inserting a newline: it is now left to VS Code and the OS when “ctrl+j” is set to null in the Chat context of ~/.claude/keybindings.json
- \[VSCode\] Fixed a mod’s “From the … plugin” label above the prompt being drawn over the slash command and @-mention menus (anthropics/claude-code#102981)
- \[VSCode\] Fixed an empty list item, paragraph or code block, and list items renumbered from 1, when pasting copied LaTeX math
- \[VSCode\] Fixed the feedback error showing only an HTTP status when your organization does not accept feedback
- \[Cloud sessions\] Fixed the Add connector list in routine forms saying no connectors were available while they were still loading
- \[Cloud sessions\] Fixed the cloud environment editor shuffling environment variables and adding backslashes to values that contain both kinds of quote
- \[Cloud sessions\] Fixed the self-hosted environment details dialog in admin settings so its title, tabs and buttons stay in view while only the content scrolls
- \[Cloud sessions\] Fixed the “read documentation” tool row in cloud sessions, which showed escaped JSON instead of a readable page
- \[Claude Tag\] Fixed Claude in Slack posting a draft you approved for a channel into your DM by mistake; a post with no channel is now refused so it can go to the approved channel
- \[Claude Tag\] Fixed Allow and Deny on Claude’s approval cards in Slack doing nothing when the session had stopped; your answer now restarts the session
- \[Claude Tag\] Fixed Claude ignoring untagged messages in a Slack channel after its workspace moved to a different Claude organization, including unshared channels on Enterprise Grid
- \[Claude Tag\] Fixed Claude in a Slack channel posting a threaded reply before reading a newer message someone had just added to that thread
- \[Claude Tag\] Fixed the Slack page in Claude Tag admin settings saying no workspaces were connected when the list failed to load; it now shows an error with a Retry button
- \[Code Review\] Fixed a finished review showing no check on the pull request when earlier tries to create it failed; a final try now adds a completed check
- \[Code Review\] Fixed a push queued behind a running review still starting a review after `@claude review stop`; its check now closes and says why

[​](#2-1-308)

2.1.308

October 22, 2026

- Bug fixes and reliability improvements

[​](#2-1-307)

2.1.307

October 21, 2026

**Added**

- Added `/claude-api api-version` to move Claude API code to API version `2026-10-21`
- Added the `claude_code.safety_event` OpenTelemetry event for each tool call a permission rule, auto mode, a safety check, a hook or the sandbox stopped, prompted or sent back
- \[VSCode\] Added a notice on the microphone button when voice dictation stops by itself (15 seconds without recognized speech, or the 2-minute limit), saying why and that the text so far is kept
- \[Code Review\] Added `@claude review stop` (also `off` and `pause`) to Code Review, ending an `@claude review always` subscription on a pull request without starting a new review

**Changed**

- Changed the notice Claude gets when the WebSearch budget is used up to also tell it not to query search engines in a browser or through computer use
- Changed the `axScreenReader` setting and `CLAUDE_AX_SCREEN_READER` in a settings `env` block to apply only from user, managed or `--settings` settings (since 2.1.305)
- Self-hosted runner: Changed checkout hooks to be stopped after 30 minutes by default, failing the session’s setup; if yours needs longer, raise `--checkout-hook-timeout-min` or set it to `0`
- Self-hosted runner: Changed the certificate file built for Anthropic-managed git to filter its trusted certificates as the CLI does; a `[runner:warn]` line gives the number left out
- \[VSCode\] Changed the “still open somewhere else” notice to also cover a Claude process left over from an extension restart, which usually ends on its own within about 10 minutes
- \[VSCode\] Changed voice dictation to filter its trusted certificates as the CLI does
- \[VSCode\] Changed the extension’s own requests to filter their trusted certificates as the CLI does, and to trust the `NODE_EXTRA_CA_CERTS` file named in the environment or in user settings

Show 6 improvements

- Improved recovery from unparseable tool calls: Claude Code now retries the call up to twice before ending the turn with an error
- Improved fork subagents launched together: each is now told which launch is its own, so forks are much less likely to try to start each other’s work
- Improved browser sign-in: the success page now appears as soon as sign-in completes, without waiting for your account profile to load
- Improved web search errors in cloud and self-hosted runner sessions: a search refused with a 403 that gives a reason now shows that reason instead of a generic “Authentication error”
- Improved the time to the first reply in cloud sessions when one of the desktop app’s MCP servers can’t connect
- Improved Remote Control connect time for sessions whose transcript contains large pasted images or PDF reads

Show 26 bug fixes

- Fixed requests failing with a model-not-found error when `CLAUDE_CODE_DISABLE_1M_CONTEXT` is set and the model is an alias with the `[1m]` suffix, such as `opus[1m]`
- Fixed the `prompt-caching-scope` beta header being sent behind custom `ANTHROPIC_BASE_URL` gateways and on Foundry, where it has no effect
- Fixed MCP servers showing “needs authentication” in `claude -p` on macOS while the login keychain was locked; they now say why, and the next run after an unlock connects without a new sign-in
- Fixed MCP servers being reported as timed out, and staying failed in headless runs, when a macOS or Linux computer went to sleep while they were connecting
- Fixed HTTP MCP tool calls being sent twice when the connection closed mid-call; only read-only or idempotent tools are now retried
- Fixed a turn sometimes starting without an SDK MCP server’s latest tools when a background task was running
- Fixed some “Autocompact is thrashing” errors in turns that read many PDF pages, images or other large tool results
- Fixed `/autocompact` in cloud sessions going back to the default window after the session restarted
- Fixed a conversation cleared with `/clear` sometimes coming back when a cloud or self-hosted runner session restarted
- Fixed `CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS` being ignored in Claude apps gateway sessions
- Fixed telemetry from Claude Desktop sessions behind a Claude apps gateway being rejected when `OTEL_EXPORTER_OTLP_HEADERS` is set
- Fixed `/permissions` \> Recently denied not showing the denied shell command, and auto mode’s local classifier ignoring an approval from there when it checks a retried command; approving a row now names the command, not its description
- Fixed `/help` and the `/` command menu showing long model-facing descriptions for bundled skills such as `/claude-api` instead of their short descriptions
- Fixed subagent transcripts recording placeholder token usage and an empty stop reason for streamed responses
- Fixed model switches through the Agent SDK’s `setModel()`, and apps built on it, being refused when the API took more than 5 seconds to confirm the model; Claude Code now waits up to 15 seconds
- Fixed a background command stopped through a connected app (such as the desktop app archiving an idle session) being reported to Claude as stopped by the user; the notice now names its output file
- Fixed WebFetch in Cowork cloud sessions reporting a tool error when a site answered with a 4xx status or a robots.txt refusal; it is now a normal result, as in local sessions
- Fixed write tools on a directly configured GitHub MCP server showing a form that closed without creating anything in the desktop app’s Code tab
- Fixed Artifact tool reads failing with a connection reset when the server had closed a reused connection
- Self-hosted runner: Fixed sessions with `--use-anthropic-git-proxy` committing a `.claude/settings.local.json` left in the clone by an earlier session
- Self-hosted runner: Fixed archiving or requeueing a session, or stopping the runner, during its checkout hook leaving the hook’s processes running and the runner’s slot held
- \[VSCode\] Fixed a long prompt expanded with Show more covering the whole chat panel: a pinned prompt is now capped at 40% of the panel and scrolls
- \[VSCode\] Fixed part of a list item or table cell with LaTeX math pasting as a new list or table in rich text editors
- \[VSCode\] Fixed dictation failing behind a TLS-inspecting proxy when `NODE_EXTRA_CA_CERTS` is set only in `~/.claude/settings.json`; it now also follows `CLAUDE_CODE_CERT_STORE`
- \[Cloud sessions\] Fixed the repository picker saying “No repositories match” while a search was still running; it now shows “Searching…” until the results arrive
- \[Cloud sessions\] Fixed the “Waiting for a runner” status on self-hosted environments being cut off; with on-demand runners it now counts up from your last message and shows failed attempts

[​](#2-1-306)

2.1.306

October 21, 2026

- Fixed `claude -p` inside cloud sessions reporting “Not logged in” when started without the session’s environment variables
- Fixed an API error being replaced by “prompt is too long”, and an unneeded compaction, in sessions with many MCP tools

[​](#2-1-305)

2.1.305

October 20, 2026

**Added**

- Added `sandbox.allowNestedUserNamespaces` so sandboxed commands on Linux can create user namespaces (Chromium, rootless podman); this lets them get around the sandbox’s file protections
- Added `CLAUDE_CODE_RETRY_WATCHDOG_USAGE_LIMIT_RECHECK_MS` so unattended retry mode (`CLAUDE_CODE_RETRY_WATCHDOG`) notices a usage limit that was lifted before its reset
- \[VSCode\] Added a “Running start-up hooks” spinner status, with a screen reader announcement, while SessionStart or Setup hooks run
- \[Claude Tag\] Added public Slack channels Claude hasn’t joined to the Claude Tag admin Add place search, so admins can set one up from there

**Changed**

- Changed `allowedMcpServers` to stop filtering `managed-mcp.json` stdio servers that use `${VAR}` only in `env`: one your allowlist left out now loads on upgrade; use `deniedMcpServers` to keep it off
- Changed plugins that Claude Desktop mounts by path to no longer keep their `allowed-tools` when your organization’s managed settings set `allowManagedPermissionRulesOnly`
- Changed the `/artifacts` delete confirmation to take 1 or Enter to keep, 2 to delete, and Esc to cancel; `y` and `n` no longer answer it
- Changed a mod’s docked pane to stay within 45% of the terminal’s width, including a width kept from a wider terminal
- \[VSCode\] Changed the message shown when a session does not start in time and no hook is running: it now leads with the output logs and lists causes instead of pointing to sign-in and network first
- \[Code Review\] Changed Code Review re-reviews so they no longer open with LGTM while earlier blocking findings are still open

Show 6 improvements

- Improved `/usage`: each warning is now a one-line fix that names its source, and `f` applies the fixes; the same fixes appear in VS Code and `/doctor`
- Improved MCP consent dialogs so an Enter meant for the prompt is less likely to be taken as Accept
- Improved a mod’s `Image` to draw its picture in iTerm2 3.5 and later with fullscreen rendering, where it showed only its `alt` text
- Remote Control: Improved the spawn-mode messages: pressing `w` now says the new mode is saved for the folder, and a later `claude remote-control` start that uses the saved mode says where it came from
- \[Cloud sessions\] Improved deleting a self-hosted environment so the dialog and error messages say what blocks the delete and what it will affect
- \[Claude Tag\] Improved Claude Tag admin pages in large organizations so plugin, skill and bundle edits work while the channel list is still loading

Show 22 bug fixes

- Fixed every request failing on Vertex, Bedrock and other providers when the endpoint or a gateway rejects tool search, and behind gateways with ToolSearch disallowed or left out of `--tools` (a 2.1.304 regression): Claude Code now retries without it
- Fixed `/effort` and `/autocompact` settings not applying when the model name differed from a `modelOverrides` value by letter case or a `[1m]` tag
- Fixed new worktrees in a bare repository sometimes starting from local HEAD instead of the default branch, and unchanged subagent worktrees sometimes not being cleaned up
- Fixed Bash commands on a full disk failing with a raw `ENOSPC` file path: the error now says the disk is full and that nothing ran
- Fixed an MCP server passed by a cloud session or by the SDK’s `setMcpServers` being replaced later in the session by a same-named server from your own settings
- Fixed Claude naming the wrong model for a subagent’s work after the subagent switched to a fallback model
- Fixed cloud sessions and teammates not telling Claude when a compaction had to leave the oldest messages out of its summary to fit
- Fixed more cases of scheduled Cowork cloud sessions waiting five minutes for each subagent whose WebFetch needed a URL approval that nobody was there to give
- Fixed Workflow resume re-running already-completed `pipeline()` and `parallel()` agents instead of serving them from the run’s journal
- Fixed Remote Control leaving empty “(session)” entries in `/resume` after switching conversations with `/resume`
- Fixed `/usage` rows being cut off in narrow terminals
- Fixed startup warnings printing as raw text above the logo: they now go to the debug log, and permission rules that restrict nothing show as warning rows under the banner
- Fixed screen reader mode: search boxes now say “Search:” instead of a symbol VoiceOver read as “telephone recorder”, and highlighted prompt text, such as Ctrl+R search matches and “ultrathink”, no longer has spaces inside words
- Self-hosted runner: Fixed a start script that shares only its stdout with the runner or orchestrator failing with `Resource temporarily unavailable` when `TERM` is set (a 2.1.300 regression)
- Self-hosted runner: Fixed repository access failing since 2.1.296 when a git credential helper or askpass program reads its settings through `GIT_CONFIG`
- Self-hosted runner: Fixed the orchestrator reporting a spawn-runner hook as timed out when a runner it started in the background kept its output open
- \[VSCode\] Fixed the spinner cutting off “Compacting…” when your `spinnerVerbs` setting replaces the built-in verbs with short ones
- \[Cloud sessions\] Fixed the Cloud environments admin page wrongly refusing to save an existing environment with an “installs packages” error
- \[Claude Tag\] Fixed Claude Tag access bundles so a repository that moved to another GitHub account can be added again
- \[Claude Tag\] Fixed a routine set up in a Slack DM thread no longer posting after another routine in that thread restarted the conversation; both now keep posting there
- \[Claude Tag\] Fixed routines set up in a Slack thread reporting success without posting after the conversation ended; those runs are now skipped and the creator is told
- \[Code Review\] Fixed Code Review sometimes not reviewing the newest commit when several pushes landed on a pull request during a review

[​](#2-1-304)

2.1.304

October 19, 2026

**Added**

- Added a transcript line when a plugin that runs first skips one of your mod’s hooks, naming the event and the plugin
- Added `decider: "person"` to a mod’s `tool.check` answer: only the permission dialog or a host’s callback can approve the ask, and it is refused with the mod’s reason where nobody can be asked
- Added `e.isReadOnly` to a mod’s `tool.check` event, set when the tool call is read-only
- Added `/auto-mode-setup`: a guided setup that reads your project and recent sessions to teach auto mode about your environment, now also available on Bedrock, Vertex, Foundry, Claude apps gateway and telemetry-disabled sessions
- Added `/claude-api managed-agents-secure`, which compares a Managed Agents agent’s settings with Anthropic’s published security guide, without changing anything
- Added the names of the tools called earlier to the compaction summary in the transcript view (Ctrl+O)
- Added a warning on Pro and Max plans when resuming an inactive conversation would use a noticeable share of your 5-hour usage limit: resume anyway, or start a new conversation and Claude can look up the previous one if you refer to it
- \[VSCode\] Added mod drawing in the chat panel for sessions on Amazon Bedrock, Google Vertex AI and Microsoft Foundry, behind an LLM gateway, or with telemetry turned off
- \[Code Review\] Added review levels to Code Review: Owners choose Quick, Standard (the default), or Deep for the organization, and can give individual repositories their own level
- \[Code Review\] Added an option in Code Review admin settings to review every repository in a GitHub organization, including ones added later, without selecting them one by one

**Changed**

- Changed mods’ `settings.read` hooks to receive each settings layer and rewrite the merged settings, so a managed mod can make an organization’s setting a ceiling, including the `cleanupPeriodDays` the retention sweep uses
- Changed the `/artifacts` delete confirmation to show numbered choices: 1 or Enter keeps the artifact, 2 deletes it, and y, n and Esc still work
- Changed the question that turns on the mods Claude writes in a session to plain text with no link or session id; it stays up when a new turn starts, and Claude tells you what loaded when you turn them on
- Changed tool search to be on by default behind a custom `ANTHROPIC_BASE_URL`; a 400 or 422 from the gateway is retried without it
- Changed compaction to send Claude the skill list again afterwards; `/reload-skills` now sends only new or changed skills
- Changed skill hooks: the skills of one source (a repo, your own folder, or a plugin) can register at most 1,024 hooks and 16,384 matcher characters per session
- Changed skills under a policy that allows hooks from plugins only: a skill used in the main conversation whose hooks are kept out no longer gets its `allowed-tools`
- Updated the /claude-api skill to use the `ant` CLI on Claude Platform on AWS instead of falling back to the SDK or curl
- Removed the notes from `claude plugin validate` that predicted where a mod’s hooks would run
- Removed the “(research preview)” label from the `/fast` dialog title on Opus 5.5
- \[VSCode\] Changed background sub-agents to show as one status line under their Agent card instead of streaming every step into the chat; the full transcript stays in /tasks

Show 12 improvements

- Improved `/usage` to say when a rate limit on usage data ends instead of “try again in a moment”
- Improved the lines shown when a mod written in the session loads, reloads or fails to load
- Improved artifacts with several views: when you ask for links to them, Claude now writes out each view’s link and explains that the address bar stays the same as you switch views
- Improved cloud sessions: a new conversation’s first turn no longer waits for the local (stdio) MCP servers of plugins synced from claude.ai, unless a server sets `alwaysLoad: true`
- Improved how a remote session recovers its status when the server refuses a status update that carried other session data
- Improved session file size in auto mode: the safety classifier’s context is no longer stored with every request
- Improved the `claude -p` invalid-settings warning: a file that did not load lists only what stopped it, and long lists are capped per file
- Improved resume of large compacted sessions in SDK and headless mode: the first request after resuming is sent sooner
- Improved responsiveness and throughput when many subagents are running at the same time
- Improved memory use when sending requests in long or resumed conversations
- Self-hosted runner: Improved the error shown when the git host answers “not found” for a session’s repository: it now names the repository and whom to ask
- Windows: Improved git command start-up with a standard Git for Windows install by running its git.exe directly instead of through its cmd launcher

Show 43 bug fixes

- Fixed the organization policy not refreshing until the hourly check after approving an `ANTHROPIC_API_KEY` at startup or switching “Use custom API key” in `/config`
- Fixed sandboxed commands failing to start on Linux when a `sandbox.filesystem.denyRead` glob contains brackets that are not a character class, such as a `[user-id]` route folder
- Fixed `rm -r` of a mounted drive or a folder at its top level (`/Volumes`, `/media`, WSL’s `/mnt/c`) not getting the safety prompt that `rm -rf /Applications` gets
- Fixed `CLAUDE_CODE_TRANSCRIPT_LOCAL_GC` dropping messages from the saved transcript when the disk filled up while the file was being trimmed
- Fixed a plugin keeping a headless run going past `--max-turns`, Stop, or ended input by spawning subagents or re-running a finished one
- Fixed a failed mod reload removing the tools and commands of the version that stays loaded, and its messages being wrong or silent about whether the previous version is still loaded
- Fixed a click on a mod’s button being lost when buttons with the same label and no `key` were redrawn unchanged
- Fixed mod sharing in the built-in `plugin-authoring` skill stopping at the secret scan on machines with managed settings and on Team and Enterprise plans
- Fixed scheduled Cowork cloud sessions waiting five minutes again for each subagent whose WebFetch needed a URL approval that nobody was there to give
- Fixed Write results and rejected edits showing a file outside the working directory as `../../…`; they now show `~/…` or the full path
- Fixed a claude.ai Directory plugin’s skills not running as commands when picked from the ”/” menu in Cowork cloud sessions
- Fixed Remote Control permanently withholding a desktop conversation’s history when a different account was signed in to the terminal
- Fixed Remote Control failing to start from Claude Desktop when DISABLE_TELEMETRY or DO_NOT_TRACK is set on a paid plan
- Fixed model switches, messages and interrupts waiting behind a context usage check in SDK and desktop sessions
- Fixed `context_management: Extra inputs are not permitted` errors behind LLM gateways; Claude Code now resends the request without that field
- Fixed OpenTelemetry settings delivered through server-managed settings being ignored for the whole session after signing in during first-run setup or the first start after /logout
- Fixed unsandboxed Bash commands in Claude Desktop Code tab sessions on macOS and Linux not seeing environment variables exported in shell startup files such as ~/.zshrc
- Fixed the Consumer Terms notice being skipped for a day or longer after a server error
- Fixed `/privacy-settings` offering choices that may not apply to you after a network or server error
- Fixed a “Context limit reached” or “Prompt is too long” error after stopping a turn while Claude Code was compacting a conversation the API had rejected as too long
- Fixed subagents sometimes forgetting their most recent work when they were messaged or resumed right after finishing
- Fixed `claude --help` text for `--tools`, `--resume`, `--debug`, `--json-schema`, `--disable-slash-commands`, `--system-prompt-snapshot` and `claude update` to match actual behavior
- Fixed `claude --worktree` removing the worktree and its branch without asking at exit when HEAD was detached or on another branch, which could lose commits
- Fixed resumed and cloud sessions sending Claude the whole skill list again each time plugins reloaded at startup
- Fixed an interrupt not ending a Read that waits on an idle pipe or device named like an image
- Fixed `/effort status`, `/effort ultracode` and the prompt’s effort indicator showing a guessed effort level when `CLAUDE_CODE_EFFORT_LEVEL` is `auto` or `unset` and no level is sent
- Fixed a PreToolUse hook’s deny reason being replaced by a timeout error when an Agent SDK callback hook on the same tool call timed out
- Fixed Bash and PowerShell deleting a large command’s output file when it could not be copied to the session’s tool-results folder, unless the disk is full
- Fixed notes typed into a multiple-choice question with previews being cut off with ”…” in terminals under about 100 columns, hiding what was typed (anthropics/claude-code#82768)
- Fixed self-paced `/loop` wakeups scheduled at the 1-hour maximum firing just after the 1-hour prompt cache expired, so those wakeups no longer re-read the conversation uncached
- Fixed agent teams: approving a shutdown request from the main session no longer exits the whole CLI
- Fixed a skill’s `once` hook also removing another skill’s identical hook after it ran
- Fixed transcript mode’s `{` and `}` landing the prompt on an inconsistent row, or off screen, instead of the transcript’s first row
- Fixed `CLAUDE_CODE_AUTO_COMPACT_WINDOW=200k` silently setting a 100K window: the variable now accepts `k` and `M` suffixes like `--autocompact`, and warns when a value is out of range or ignored
- Fixed Ctrl+C in the agents view clearing a text selection without copying it when pressed before the mouse button was released
- \[VSCode\] Fixed one cause of sessions failing to start with “Subprocess initialization did not complete within 60000ms”: time a SessionStart command hook spends running no longer counts toward the limit, up to 10 minutes in total
- \[VSCode\] Fixed a session closed while it was starting keeping its Claude Code process running until the start ended
- \[VSCode\] Fixed a mod’s drawings disappearing from a long-open panel until the next turn on machines that also run an older Claude Code
- \[VSCode\] Fixed Past conversations hiding sessions when `claudeCode.claudeProcessWrapper` is set
- \[Cloud sessions\] Fixed folders in the composer’s @ list showing no name in cloud sessions, where picking one added only a space instead of a mention
- \[Claude Tag\] Fixed Claude going silent in a thread when its channel becomes shared across Enterprise Grid workspaces mid-task; it now posts a one-time note to @-mention it in a new thread
- \[Claude Tag\] Fixed `@Claude !fork` typed outside a thread getting no visible reply; Claude now shows you a private note saying to run it from inside a thread
- \[Code Review\] Fixed pull requests opened within a minute or two of an admin turning on Code Review being silently skipped; they are now retried and reviewed

[​](#2-1-303)

2.1.303

October 18, 2026

- Bug fixes and reliability improvements

[​](#2-1-302)

2.1.302

October 16, 2026

**Added**

- Added `CLAUDE_CODE_AUTO_MODE_MODEL` to choose the model the client-side auto mode classifier uses; it does not change the model for server-side auto mode
- Added an `Idle compaction` row to `/config` for turning idle compaction off or back on; the notices shown after an idle compaction now say how to turn it off
- Added a notice to `/design-sync` and `/design-login` that standalone Claude Design (claude.ai/design) closes by December 14, 2026
- \[Cloud sessions\] Added a banner on a routine’s page that says why its last run didn’t start, such as your organization reaching its limit on concurrent cloud sessions

**Changed**

- Changed `claude -p` and Agent SDK sessions with no permission mode to start in `default` mode on third-party providers, with telemetry off or on a fresh install; `--permission-mode auto` keeps auto
- Changed fork subagents (`subagent_type: "fork"`) to be on by default in `claude -p`, the Agent SDK, the desktop app and VS Code, as they already are in the terminal; `CLAUDE_CODE_FORK_SUBAGENT=0` turns them off, and `claude mcp serve` never offers them
- Changed the desktop app and VS Code to always run the main conversation’s subagents in the background, as the terminal does, rather than let Claude choose; a subagent’s own Agent calls in `claude -p`, the Agent SDK, the desktop app and VS Code now run in the foreground by default
- Changed the `← for agents` footer hint to hide 10 seconds after a session opens; the count of agents waiting on you still shows
- Changed where the Claude in Chrome instructions sit in the system prompt so that new conversations can read them from the shared prompt cache
- Changed prompt and agent hooks so that at most 12 of one event run at a time; the rest wait their turn
- Changed the message shown when your organization’s policy turns off `/feedback`: it now points to GitHub issues instead of an organization admin
- \[Claude Tag\] Changed Claude Tag admin settings to organize Claude’s access into four tabs: Bundles, Connectors, Skills and plugins, and Channels
- \[Claude Tag\] Changed the Roles page in organization settings to group the roles created for Claude Tag channel managers in a collapsed section below your organization’s own roles

Show 7 improvements

- Improved startup time with many plugins enabled: plugin command and agent files now take far fewer file system calls to load, most of all on Windows
- Improved auto mode with the server-side classifier: a conversation too long for the safety check is now compacted, instead of every checked tool call being denied
- Improved the message when a background session reopened from another folder has no LLM gateway: it now says why, instead of “Not logged in”
- \[Cloud sessions\] Improved the error shown when a cloud session fails to start: it now says “Connection lost” or “Server error” instead of “Something went wrong”
- \[Claude Tag\] Improved repository search in Claude Tag admin settings to cover up to 100 connected GitHub accounts and find private repositories past the first 5,000 of a GitHub App install
- \[Claude Tag\] Improved Add place in Claude Tag admin settings to list a channel you type or paste right away, instead of only after your organization’s full channel list has loaded
- \[Claude Tag\] Improved Add \> Domain on a workspace’s or channel’s page in Claude Tag admin settings to be available once that page loads, not only after every channel has loaded

Show 43 bug fixes

- Fixed a “Prompt is too long” error when stopping a turn while the conversation was being compacted
- Fixed requests failing with “diagnostics: Extra inputs are not permitted” after switching to Vertex or Bedrock mid-session
- Fixed the Read tool loading an image file of any size, or a pipe or device named like an image, entirely into memory; image sources over 128 MB are now refused
- Fixed `/autocompact` and `/effort` saving to the wrong model when a gateway names Opus 4 or 4.1 with a prefix, such as `anthropic/claude-opus-4-1`
- Fixed a prompt cache miss when a tool added mid-session was loaded again through ToolSearch or after compaction
- Fixed `claude plugin` and other subcommands sometimes exiting before a queued settings or config write finished, which could lose the change or leave a `.tmp` file behind
- Fixed plugin marketplaces re-cloning on every refresh, and newly installed git plugins showing version “unknown”, when git defaults to the reftable ref format
- Fixed the PowerShell tool not finding commands in a plugin’s `bin/` folder, and reporting an error when a search that finds nothing (rg, grep, findstr, git grep) is piped into `Select-Object` or another formatting cmdlet
- Fixed Claude in the desktop app pointing you to claude.ai settings or `/mcp` to authorize or reconnect an MCP server where that option isn’t available
- Fixed artifact publishes sometimes failing when Claude sent an empty list of edits, and Claude retrying an artifact update the wrong way after a newer version of the artifact turned it away
- Fixed `classifier_category` missing from OpenTelemetry `tool_decision` events for most auto mode classifier blocks, and new `tool_decision` attributes pushing out `tool_use_id`, `tool_source` and `tool_parameters` when `OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT` is low
- Fixed rows in the agents view staying blank after moving down a long list or folding a section
- Fixed `claude remote-control --help` not printing its usage and exiting when not signed in
- Fixed `/design consent` and `/design revoke` suggesting `/design-login` when they fail in a cloud session, where it isn’t available; the message now points to claude.ai/design/settings
- Fixed MCP servers showing no tools, or every tool call failing, when the server negotiates protocol version 2026-07-28 but omits `resultType`, `ttlMs` or `cacheScope`
- Fixed prompt suggestions spending usage credits on models your plan pays for only with credits: they are now skipped after a reply billed to credits
- Fixed URLs written in backticks being clickable only on their first row when they wrap; the whole URL is now one link in terminals that support hyperlinks
- Fixed `claude plugin details <name>@builtin` suggesting `claude plugin list`, which never shows built-in plugins, when the plugin isn’t found; it now points to `/plugin`
- Fixed an emoji that a link starts inside wrapping one column too wide, which hid it in question previews and turned tables into lists
- Fixed worktree isolation refusing to create or resume worktrees under git 2.56 or later when a stray `.git` file points at a directory that doesn’t exist
- Fixed a cloud session’s cost and usage restarting from zero after the session resumed in a new process
- Self-hosted runner: Fixed git fetches failing with “bad object refs/heads” in sessions that reuse a checkout stored in git’s reftable format
- Windows: Fixed every file write being refused or asked about for projects on exFAT or FAT32 drives, including in sessions started with `--plugin-dir`
- \[VSCode\] Fixed text after an unclosed code block in a list showing as plain text while a reply streams, then turning into code
- \[VSCode\] Fixed MCP server sign-in from the panel opening a broken authorization page when the server URL contains a query string
- \[VSCode\] Fixed the `@browser` banner saying “Browser connected” when no browser with the Claude extension can be reached
- \[Cloud sessions\] Fixed “Rewind to here” failing on every message except the newest in cloud sessions; self-hosted runners need Claude Code v2.1.246 or later
- \[Cloud sessions\] Fixed the pull request status bar in cloud sessions flipping a pull request with merge conflicts back to ready while GitHub rechecked it
- \[Cloud sessions\] Fixed routine runs showing as Completed after their cloud session stopped unexpectedly, and as Cancelled when archived before they started, instead of failed
- \[Cloud sessions\] Fixed the diff view in cloud sessions missing changes or failing to load after the session’s GitHub repository was renamed or moved
- \[Cloud sessions\] Fixed a scheduled routine run that failed partway being run again from the start an hour or more later, which could repeat work such as posting the same report twice
- \[Cloud sessions\] Fixed an open cloud session sometimes not showing messages sent from another device until you reloaded the page or clicked away and back
- \[Remote Control\] Fixed a subagent’s pane spinning forever in a Remote Control session after your computer goes offline; it now says Remote Control is disconnected
- \[Claude Tag\] Fixed “is thinking…” staying up under a mention in a Slack channel or DM after Claude answered it by editing one of its earlier messages
- \[Claude Tag\] Fixed URLs in code blocks under a numbered or bulleted step of Claude’s Slack replies being wrapped in angle brackets, which broke copied commands
- \[Claude Tag\] Fixed HEIC, SVG, TIFF and BMP images attached in Slack never reaching Claude; they now arrive as files in its working files, like other file types
- \[Claude Tag\] Fixed new channel managers losing access to Claude in Slack in organizations that restrict Claude Tag by role; the manager role now also grants Claude Tag in Slack
- \[Claude Tag\] Fixed custom connectors whose MCP servers share one host showing as a single connector in Claude Tag admin settings; each server is now its own connector
- \[Claude Tag\] Fixed Claude in Slack sometimes answering a direct message with “DMs are temporarily unavailable” and dropping it when a single Slack lookup stalled; it now retries first
- \[Claude Tag\] Fixed direct messages with Claude on a Slack Enterprise Grid ignoring Slack’s workspace dropdown; they now run under the connected workspace you last opened Claude in
- \[Claude Tag\] Fixed Claude in Slack’s notice for a channel’s monthly spend limit saying a channel manager can raise it; it now names an organization owner and links the usage page
- \[Claude Tag\] Fixed links in Claude’s Slack replies absorbing the closing bold or italic marks, or full-width punctuation, right after them, which broke the link and the formatting
- \[Code Review\] Fixed Code Review setup not resuming after you leave to connect GitHub; back in admin settings, it now reopens at the repository picker

[​](#2-1-301)

2.1.301

October 15, 2026

**Added**

- Added `CLAUDE_CODE_RETRY_WATCHDOG_MAX_USAGE_LIMIT_WAIT_MS` so unattended retry mode (`CLAUDE_CODE_RETRY_WATCHDOG`) ends a request at a usage limit that resets too far away instead of waiting
- Added OpenTelemetry tracing guidance to the `claude-api` skill, including setting up trace destinations with the `ant` CLI
- Added the `%` motion to vim mode: jump to the matching bracket, alone or with d/c/y
- Added `rows` to a mod’s `Input`: a text field of several lines in the terminal, where Enter submits and Shift+Enter or a backslash before Enter starts a new line
- Added `classifier_verdict` and `permission_mode` to OpenTelemetry `tool_decision` events, so auto mode classifier decisions can be told apart from permission rules
- Added `classifier_category` to OpenTelemetry `tool_decision` events, naming the built-in rule a classifier block matched, when `OTEL_LOG_TOOL_DETAILS=1`
- \[VSCode\] Added LaTeX math rendering in Claude’s responses, including `$$` and multi-line `\[ … \]` blocks and inline `$…$` and `\(…\)` math
- \[VSCode\] Added a “Get more usage” link to the usage-limit banner for Pro and Max plans in the VS Code and JetBrains panels

**Changed**

- Changed a mod hook’s `.catch` handler to run only when the hook throws or times out; events raised beneath the hook’s own calls now skip that hook without asking its `.catch`
- Changed a mod’s `$.env.set` to resolve with `{}` once the variable is set or unset, or with `{ deny }` saying why when the write is not made

**Improved**

- Improved switching to a model with a smaller context window: a conversation too long for the new model is now summarized by the previous model first
- Improved rendering performance while a long-running subagent works: its progress trail now updates incrementally instead of being reprocessed in full on every render
- Improved artifacts: pages Claude writes now paint the band above a sticky header, so scrolled text no longer shows there in the mobile apps
- Improved mods: in VS Code and the desktop and mobile apps, a tree drawn above the question dialog can now hold Markdown and up to 48 rows; the terminal keeps 12 plain rows

Show 37 bug fixes

- Fixed quitting removing a worktree made by a `WorktreeCreate` hook without asking when it may hold unpushed commits
- Fixed the `fable` (and `best`) model alias erroring on the Anthropic API when the newest Fable model is not available to your organization: Claude Code now retries once on the previous Fable model
- Fixed a misleading “Please run /login” error when a full disk keeps the login from being refreshed; the error now names the disk and says to delete files
- Fixed Grep and Glob reporting no matches when the search program failed unexpectedly before returning any results; they now return an error saying the search failed
- Fixed workflow agents sometimes skipping their step, and the run still reporting success, after reading the harness note that their task text carries no user authority
- Fixed artifact updates being refused where a PreToolUse hook covers Edit or Write; Claude now edits the file and then republishes instead of changing it in the publish call
- Fixed skills and commands with very many or very long argument names stalling for seconds when invoked; only the first 64 names, each up to 64 characters, are now filled in
- Fixed skills, commands and hooks using very large amounts of memory when their arguments fill many placeholders
- Fixed stray characters such as `>0q` covering the folder trust prompt, and `>4m` before the shell prompt at exit, in terminals built on VTE older than 0.53 such as MATE Terminal on RHEL 8
- Fixed stray `GOK` text appearing in the prompt at startup in some versions of iTerm2
- Fixed switching to a model whose name contains `application-inference-profile` running your `awsAuthRefresh` command and delaying model-switch hooks when the provider is not Bedrock
- Fixed sign-in refresh timeouts and unexpected sign-outs after a short command such as `claude auth status` or `claude plugin list` exited in the middle of a token refresh
- Fixed a tool call cut off by a message sent mid-turn during its permission check being reported to the model as rejected by the user
- Fixed a case where switching to a model with a smaller context window could spend usage credits on a summary by the previous model without asking first
- Fixed conversations being compacted over and over, on a model you didn’t pick, behind an LLM gateway whose responses name a different model than the one requested
- Fixed vim mode sometimes staying in INSERT after Escape on a slow or busy machine
- Fixed Esc discarding a typed AskUserQuestion answer in vim mode: the free-text field now supports vim NORMAL mode, and Esc cancels only from NORMAL
- Fixed the Read tool reading binary files such as .xlsm, .parquet, .epub and .heic as text
- Fixed a Markdown table with only a header row drawing nothing when too wide for the terminal, including in plans on the plan approval card
- Fixed the /claude-api skill saying CMEK external-key endpoints aren’t available on Claude Platform on AWS
- Fixed skills no longer being listed to the model after using `/rewind`
- Fixed the compaction row in a resumed session offering ctrl+o for history that is not loaded; it now says where the earlier messages are saved, and also shows in fullscreen
- Fixed the “new task? /clear to save tokens” hint coming back right after you interrupt a response
- Fixed the permission prompt for a plugin or skill hook’s `ask` decision not showing which plugin or skill the hook comes from
- Fixed `/diff` not noticing a conflicted cherry-pick or revert in reftable repositories when one of its git checks timed out or failed
- Fixed workflow scripts asking for permission or being refused when read, edited or re-run after a Bash `cd` in the same session
- Fixed dim text on the dark ANSI theme and 16-color terminals: faint inside filled boxes, not faint under selection and search highlights, and list descriptions dimmed like other secondary text
- Fixed a mod’s `$.model.fork` returning `nothing-to-fork` when called before the first response of a new Claude Code process had finished, as in `claude -p` runs and cloud sessions
- Fullscreen mode: Fixed `/compact` and auto-compact briefly freezing the UI while the visible transcript is rebuilt
- Self-hosted runner: Fixed sessions started from Slack being unable to find or attach a repository when managed settings restrict MCP servers; use `deniedMcpServers` to keep those tools off
- Self-hosted runner: Fixed sessions being reported as having a deleted source branch, and not retried, when an unrelated setup or session failure quoted git’s missing-ref wording
- Self-hosted runner: Fixed the log promising a retry of a failed or declined session release for a session that is ending; repeated failures now show a count
- Windows: Fixed stopped background PowerShell commands missing the closing `[killed]` line in their output file
- \[VSCode\] Fixed a conversation that crashes or freezes the panel being reopened on every reload
- \[VSCode\] Fixed the chat panel slowing down during long thinking: it no longer re-parses the whole thinking text on every update
- \[VSCode\] Fixed diagnostics showing “\[object Object\]” instead of the rule code (e.g. MD013) for some language servers
- \[VSCode\] Fixed the native dictation audio module being loaded, to check microphone permission, where dictation is not offered (non-claude.ai sign-ins, remote windows)

[​](#2-1-300)

2.1.300

October 14, 2026

**Added**

- Added `virtualText` to a mod’s prompt decorations: text drawn in the prompt box that never enters the draft or the submitted prompt
- Added `cache_creation_5m_tokens` and `cache_creation_1h_tokens` to the OpenTelemetry `api_request` event, splitting cache writes by lifetime
- Added `$.ui.view({ agentId })` for mods: shows an agent’s transcript in the main view when you ask, and `$.ui.view({})` goes back
- Added a `dir` prop on a mod’s `Text` for right-to-left text: on Windows and in VS Code’s terminal its rows read in that direction and sit flush right
- Added `/advisor` on Claude Platform on AWS; no advisor runs until you pick one with `/advisor`, `advisorModel` or `--advisor`, and `CLAUDE_CODE_DISABLE_ADVISOR_TOOL=1` turns it off
- Added OpenTelemetry GenAI semantic-convention attributes to trace spans, such as `gen_ai.provider.name`, `gen_ai.conversation.id`, `gen_ai.tool.name` and `error.type`
- Added support for rewriting a workflow agent’s `prompt` and `model` in the `agent.spawn` mod hook, which could only refuse workflow agents before
- Added the `prompt.change` mod hook, raised when the prompt box’s text changes without a typed edit: a recalled history entry, a clear, an undo, or a plugin’s fill
- \[VSCode\] Added the `claudeCode.attachSelection` setting to stop text selected in the editor from being added to your messages
- \[Claude Tag\] Added support for Slack Connect channels: an Owner or Claude Tag admin can let Claude in Slack answer in channels shared with another organization; it’s off by default
- \[Claude Tag\] Added a private Allow once / Deny card in Slack threads for connector actions that need your approval, so Claude asks instead of refusing; others only see that it’s waiting on you
- \[Claude Tag\] Added support for Slack voice clips in Claude in Slack: Claude reads Slack’s transcript of a clip when Slack has one

**Changed**

- Changed `CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST` sessions to ignore CA-bundle, tool-proxy, git TLS and git config variables like `SSL_CERT_FILE` in settings; under Claude Desktop, only in project settings
- Changed exit to force-kill background commands still running 1.5 seconds after being asked to stop; in fullscreen mode they could previously be left running
- Changed Claude Desktop’s Code tab to apply managed settings when `forceLoginGatewayUrl` names an Anthropic-operated gateway that serves the session’s hostname; that gateway must be reachable at start
- Changed `claude gateway` to stop at start, naming the key, on a `desktop:` policy key that Claude Desktop cannot use from a gateway, where it earlier started with a warning
- Changed large requests to api.anthropic.com to use gzip compression even when telemetry is disabled; set `CLAUDE_CODE_GZIP_REQUEST_BODIES=0` to turn it off
- Changed the `claude-api` skill to leave Managed Agents sessions in place unless you ask to archive or delete them
- Changed background sessions to resume a carried workflow through the Workflow tool’s approval instead of running it from the handoff file
- Changed local session transcripts to also record each API request’s system prompt, tools and parameters, so a transcript you choose to share can reproduce a request exactly
- Changed the `/sandbox` mode options to read “Sandbox commands” instead of “Sandbox BashTool”
- Changed `PermissionRequest` hooks in Cowork cloud sessions: a `setMode` update in a hook’s allow is now ignored; the rest of the approval still applies
- Changed hooks: `updatedInput` from PreToolUse and PermissionRequest hooks is now validated like Claude’s own input: unknown keys are dropped, and input the tool rejects denies the call
- Removed the `--sandbox` and `--no-sandbox` flags from `claude remote-control`, which had no effect; passing either now exits with an error. Set `sandbox.enabled` in settings to sandbox sessions
- \[Claude Tag\] Changed access bundles an admin attached to a Slack channel to keep applying once the channel becomes a Slack Connect channel, with no need to remove and re-attach them

**Improved**

- Improved WebFetch in Cowork cloud sessions to tell Claude that a page failed moments ago instead of fetching it again
- Improved mod sharing in the built-in `plugin-authoring` skill: Claude scans a mod’s files for keys before opening them, and asks before scanning a folder outside the project
- Improved the note Claude 3 models get about an @-mentioned PDF, so they less often answer without reading it
- Improved artifact updates: Claude now applies a small change and republishes the artifact in one call, and makes larger edits and republishes within a single response

Show 59 bug fixes

- Fixed cloud sessions telling Claude that an organization policy blocked a host when the session’s own network settings did
- Fixed `/autocompact` warning about high token usage when you choose a smaller auto-compact window
- Fixed SessionEnd hooks sometimes not running when you exit while a background command is still running
- Fixed `claude --help` naming a removed tool in its description of `--restricted`
- Fixed `claude agents` not refreshing any pull request’s status when the data for one of them came back incomplete
- Fixed Claude being told a background agent was lost, not resumable, after a cloud session’s container was replaced, when the agent had already been resumed once
- Fixed subagents you had typed messages to disappearing from `/tasks` shortly after finishing, leaving no way back to the conversation
- Fixed a completed parent agent dropping off the breadcrumb (its child shown re-rooted at top level) while you were viewing the child
- Fixed the agents view taking a typed word such as “up”, “down” or “escape” for that key when input arrived in a burst, which could move the peek mid-reply or clear a draft
- Fixed automatic tool search (`ENABLE_TOOL_SEARCH=auto`) turning off part-way through a conversation, for example while MCP servers reconnect after a resume
- Fixed a login refused by `forceLoginOrgUUID` leaving the refused organization’s token stored, or live after `/login`
- Fixed the diff view in Claude Desktop and Remote Control sessions not noticing a conflicted cherry-pick or revert in reftable repositories
- Fixed the Artifact tool’s verbose and ctrl+o line reading `Artifact("(unprintable path)")` while a call’s input arrives; its row now shows “Waiting…” and “Running…” as Bash’s does
- Fixed the first transcript entry written after resuming a session being lost when a crash had cut the transcript’s last line short
- Fixed `/branch` dropping messages, and `claude purge` skipping subfolder projects, when they contain a Unicode line or paragraph separator (U+2028, U+2029)
- Fixed plugin `WorktreeCreate` and `WorktreeRemove` hooks not running when Claude Code starts with `--worktree` (not yet with `--tmux`)
- Fixed OpenTelemetry `tool_result` events missing `git_commit_id` after `git commit -q` in repositories using reftable ref storage
- Fixed a prompt that a mod’s `prompt.submit` hook rewrote or dropped still being recorded as typed in the OpenTelemetry `user_prompt` event and interaction span, and in session title requests
- Fixed a note meant for Claude about mod hot-reloading appearing in the transcript as if you had typed it
- Fixed agent hooks ignoring their `model`: aliases like `haiku` now resolve, a subagent’s model no longer overrides it, and an unavailable model falls back to the caller’s instead of allowing the action
- Fixed `--worktree` sessions sometimes starting from the wrong commit when a tag or branch was named like a commit ID, and their starting git status naming a branch other than the new worktree’s
- Fixed the branch showing as “.invalid” and `--worktree` failing to reopen a worktree in repositories using git’s reftable ref storage
- Fixed Claude naming files in the session scratchpad by a bare filename or relative path instead of their full path
- Fixed `claude remote-control` servers giving up on renewing their connection after a brief sign-in error, such as a locked keychain; they now retry, and warn when you need to run `claude /login`
- Fixed `--worktree` failing in a worktree of a bare repository when origin’s default branch can’t be fetched; the fallback base is now the current checkout’s HEAD, not the main repository’s
- Fixed starting Claude Code in a VS Code, Cursor or Devin Desktop integrated terminal launching the editor’s command-line tool twice to check for the extension; it now launches it once
- Fixed a mod’s `prompt.edit` hook not being raised for a newline entered with the `chat:newline` keybinding (Ctrl+J, or a rebound Enter)
- Fixed a conversation failing on every turn with a 400 error when the API rejected an MCP tool’s input schema; Claude Code now sends that tool without parameters for the rest of the conversation
- Fixed resuming a headless or Agent SDK session losing the recent messages a compaction had kept, when the compaction followed a reply cut at the output token limit (compactions from this version on)
- Fixed Claude not being told about an MCP server’s tools and instructions until its next tool call, when the server finished connecting after a compaction
- Fixed Remote Control sessions being marked stopped while still running, on a computer serving several sessions at once
- Fixed resuming a headless or Agent SDK session losing its compaction summary or bringing back pre-compaction history, when the compaction followed a retried or unfinished reply in the same turn
- Fixed Claude polling a background command’s output file or sleeping while it runs
- Fixed feature flags and staged rollouts staying stale behind a TLS-inspecting proxy whose certificate is trusted only through the OS certificate store
- Fixed `claude daemon stop --any` printing “stopped” while a stuck background service kept running: it now waits, force-kills the service, and says so with exit 1 if it is still there
- Fixed `claude daemon stop` exiting with no output, and leaving sessions listed as running, when telemetry is turned off
- Fixed Write, Edit and NotebookEdit in Cowork cloud sessions reporting success for a path on your own computer, where the file never arrived
- Fixed Claude searching for deferred tools already loaded earlier in the conversation when a session resumes a history that never listed them
- Fixed secondary (dim) text looking the same as normal text under the dark ANSI theme and on 16-color terminals
- Fixed cloud sessions hanging 5 minutes per turn when the organization’s policy can’t be read; the turn now ends promptly and says why
- Fixed a cloud session sometimes running an already answered message a second time after the session restarted during a long reply
- Self-hosted runner: Fixed the runner and orchestrator freezing (no polls, `/healthz` or `SIGTERM` shutdown) while nobody reads their output; logs keep the latest 256 KiB and count drops (not on Windows)
- \[VSCode\] Fixed fast mode staying on after usage credits ran out, which made each request be refused and re-sent; it now turns off until you turn it back on, with an error notice
- \[VSCode\] Fixed the Thinking toggle switching to Off on models that always think; the toggle is no longer shown for those models
- \[VSCode\] Fixed “Edit prompt” on a flagged message opening the file or command menu over the restored prompt; Enter now sends it as written
- \[VSCode\] Fixed Shift+dragging a file onto the prompt on Windows inserting an unreadable `/c:/…` path instead of a mention relative to the working directory
- \[VSCode\] Fixed changes to VS Code’s chat font size settings needing a window reload or being undone by a theme change; diffs and the plan preview now follow them too
- \[VSCode\] Fixed “Resume session” and tabs restored after a reload opening an empty new conversation instead of one that had moved into a git worktree
- \[VSCode\] Fixed ↑ then Enter on a recalled slash command running it without its arguments; the command and file menus no longer open over a recalled prompt until you edit it
- \[VSCode\] Fixed Shift+dragging a file from the Explorer or an editor tab onto the prompt inserting nothing in WSL, SSH and Dev Container windows
- \[VSCode\] Fixed Ctrl+Alt+F toggling Focus view instead of opening Find in the Explorer, other tree views, or the Debug Console on Windows and Linux
- \[VSCode\] Fixed the check for sessions open in other windows or terminals creating extra processes on macOS: it now starts `/bin/ps` directly instead of searching PATH for `ps` on every check
- \[VSCode\] Windows: Fixed a conversation showing “still open somewhere else” after a crash or power loss, when Windows had since restarted and given the old process ID to another program
- \[Cloud sessions\] Fixed “Allow for this task” missing from Cowork’s approval prompts for connector tools where an organization turns off “Always allow” (regression in 2.1.292)
- \[Cloud sessions\] Fixed most commands in the / menu losing their descriptions in cloud sessions once you sent a second message
- \[Remote Control\] Fixed the diff view in Remote Control sessions on claude.ai and the desktop app showing deleted and renamed files as modified; requires Claude Code v2.1.296 or later on your machine
- \[Claude Tag\] Fixed Claude in Slack not answering another app that tags it in a thread under a message Claude itself posted to the channel
- \[Code Review\] Fixed Code Review ignoring `@claude review` comments from people with write access whose GitHub organization membership is private; their comments now start a review
- \[Code Review\] Fixed Code Review’s “paused for this repository” comment sending admins to Code Review settings; it now says who can fix it and links the Git providers page

[​](#2-1-299)

2.1.299

October 14, 2026

**Added**

- Added `CLAUDE_CODE_DISABLE_FILE_MENTIONS` environment variable: Claude gets the paths of `@` file mentions to read with its file tools, not the files’ contents
- Added idle compaction in the terminal: a 200K+ token conversation left idle for about 54 minutes is compacted before its one-hour prompt cache expires, so your next message doesn’t reprocess it all
- Added `CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS` to change idle compaction’s 200K-token minimum; `"idleCompaction": false` in settings.json turns it off. Both need v2.1.290 or later
- Added `$.prompt.media` so a `prompt.submit` hook of a mod installed by managed settings can read the bytes of an image or document attached to the prompt
- Added `$.session.identity()` for mods installed by managed settings: how the session is signed in, and its organization and email when managed `forceLoginOrgUUID` lists that organization
- Added `size`, `weight`, `mono` and `tabular` to a mod’s `Text` and named spacing steps (`xs` to `xl`) to its `Box`; `bold` is deprecated in favor of `weight`
- Added `--shutdown-drain-sec` to `claude self-hosted-runner orchestrator`: on SIGTERM it stops polling and gives the poll in flight and running spawn hooks up to that many seconds to finish
- Added the skill’s frontmatter, source, plugin name and file path to what a mod’s `skill.prompt` hook receives
- Added `/effort` and `/fast` in agent view to set what new sessions start with; a bare `/model`, `/effort` or `/fast` there now opens a picker
- Added a “safe mode” line to the agents view peek panel for background sessions started with `--safe-mode`
- Added a one-time note when plan mode won’t ask before most edits or commands because bypass permissions is available
- Added `--disallow-tools` and a `disallowed_tools` case field to `claude plugin eval` to keep specific built-in tools, such as Agent, out of eval runs
- Added support for turning off the attribution block in Claude Desktop’s Code tab: set `CLAUDE_CODE_ATTRIBUTION_HEADER=0` in the `env` of a Claude apps gateway’s `code` policy
- Added a field to the attribution block in Claude Code sessions behind a Claude apps gateway; remove the block with `CLAUDE_CODE_ATTRIBUTION_HEADER=0`
- Added a `queue` door to the `session.append` mod hook, so a mod can make the transcript’s queue records differ from the prompt as sent
- Added a note in `/plugin` and `claude plugin validate` naming a mod’s hooks that are skipped where an organization manages Claude Code
- Added `/usage` warnings for max effort, workflows, always-on context and large tool results
- \[Claude Tag\] Added the ability for Claude in Slack to delete a canvas it created in a channel when someone asks it to

**Changed**

- Changed plugin hooks and workflow scripts to refuse values they hand back that nest deeper than 28,000 levels, with an error naming the limit (workflow scripts allowed 100,000)
- Changed actions a plugin hook can block to be refused, not let through, when the hook cannot be handed them or cannot hand back its answer; a tool that already ran has its result withheld
- Changed requests to claude.ai’s connector proxy and to Anthropic-hosted MCP servers to no longer follow HTTP redirects; redirects by a connector’s own server are unaffected
- Changed MCP requests in cloud and self-hosted runner sessions to no longer follow HTTP redirects from the session’s MCP proxy
- Changed skill and command loading: one whose file or folder name has hidden, direction-changing or blank-like characters, `<` or `>` is no longer offered until renamed; such a `name:` is ignored
- Changed `ui.render` trees in `claude plugin test`: each mod’s Box or Text root now carries `part: { plugin }` naming the mod, so exact-tree assertions must include it
- Changed WebFetch page reads to pick their effort as web searches do: the caller’s level on the caller’s own model, otherwise the level settings give the small model
- Changed `claude plugin test` to fail a call to a mod’s served `$` method that has not answered within ten seconds, as a session does
- Changed MCP allow rules to reach only the server they name: `mcp__a` no longer allows a server named `a__b` or `a_`; write `mcp__<server>__*` with the server’s whole normalized name
- Changed agent `tools:` lists to take only the named MCP server’s tools; list a server whose name contains `__` as `mcp__<whole name>__*`
- Changed Claude in Chrome in Cowork cloud sessions outside auto mode: an approved-site action the safety classifier flags now asks you instead of being refused, unless managed settings apply
- Changed cloud session and Remote Control MCP connectors to negotiate MCP protocol version 2026-07-28 by default on installs that fetch no flags; `MCP_PROTOCOL_NEGOTIATION=legacy` opts out
- Changed MCP tool descriptions and server instructions from Anthropic’s first-party MCP servers at `api.anthropic.com` to reach Claude in full instead of being cut at 4,096 characters
- Changed auto mode in Cowork cloud sessions: a `PermissionRequest` hook can no longer approve shell commands or subagents; those prompts wait or are denied
- Changed the resume command printed at exit: it names the session by its ID and no longer by its name, so that nothing in a session name can run when the line is pasted
- Changed the resume command printed at exit of a worktree session: it uses `-w` and `-r` if the long flags do not fit the terminal. If neither fits a kept worktree, rows above it say where to run it
- Changed `/btw` side questions in non-interactive sessions to return a timeout error when still unanswered after 11 minutes
- Changed `UserPromptSubmit` hooks to run before a skill or custom slash command expands, so a hook that blocks the prompt now also stops its embedded shell commands
- Changed a skill’s own front-matter `UserPromptSubmit` hook to first run on the prompt after the one that invokes the skill
- Changed the `turn.start` mod hook to also hear subagents’ and teammates’ turns, not only the main loop’s; tell them apart by `e.agentId` (absent on the main loop)
- Changed the errors shown when `/ultrareview` can’t upload a repository to stop suggesting `git add .`, which could stage or commit untracked files such as `.env`
- Changed the cyber safeguard notice to no longer ask people to apply to the Cyber Verification Program
- \[Cloud sessions\] Changed deleting a self-hosted environment to turn off its routines right away, with the reason shown on each routine, instead of leaving their runs to fail
- \[Claude Tag\] Changed how Claude in Slack corrects a message it got wrong: it edits the message in place and adds a short “Edited” note instead of striking through the old text
- \[Claude Tag\] Changed Claude in Slack to join channels with more than 100 members quietly, with no intro message

Show 16 improvements

- Self-hosted runner: Improved what `setup` and `doctor` say when the runner’s machine has no git credentials
- Improved the error shown when a cloud session is refused because your claude.ai login was rejected or has expired: it now tells you to sign in again with `claude auth login`
- Improved enforcement of managed permission rules, managed hooks and organization MCP tool names against user-installed mods
- Improved memory and disk use when PDFs are @-mentioned: their bytes are no longer kept in the session transcript
- Improved sandboxed Bash on Linux: Esc and Ctrl-C now work while wildcard read rules are being expanded for a command
- Improved the startup warning for an unrecognized model ID: it is now one short line under the welcome banner with a docs link, instead of a long raw message
- Improved the plugin-authoring skill’s steps for sharing a mod: Claude asks public or private and checks the files before creating a GitHub repository
- Improved the Skill tool’s “Unknown skill” error to suggest a skill’s listed name when Claude wrongly adds the `anthropic-skills:` prefix to it
- Improved `/reload-skills` to say it re-sends the full skill list to Claude, which is how to get skills back after compaction
- Improved the error shown when a worktree cannot be created because its base commit does not resolve: it now says how the lookup ended and the likely reasons, such as a repository without a commit
- Improved the error for creating a worktree at a bare-repository layout’s root: it now explains the layout instead of an unrelated git error
- Improved artifact watching: a local session can now watch up to 25 published artifacts at once, up from 10
- Improved background agent notifications: they now say when an agent is only waiting on its own background work, got a message too late for its result, or was stopped by a usage limit
- \[VSCode\] Improved startup time in workspaces without a Python environment by starting Claude while the Python extension loads
- \[VSCode\] Improved startup: the model picker and slash command menu now fill in right away in a new window on a folder you’ve opened before
- \[Cloud sessions\] Improved the deploy command shown when you create a self-hosted environment or environment key: it shows in full, wraps between arguments, and has a visible copy button

Show 131 bug fixes

- Fixed the error for a denied cloud session, which could point to the wrong organization when a key from `apiKeyHelper` was in use
- Fixed sessions on a gateway-specific model name behind a custom `ANTHROPIC_BASE_URL` ending with “Prompt is too long · automatic compaction failed” near 200K tokens instead of sending the request
- Fixed a mod that submits a prompt at the end of every turn keeping a headless run going past `--max-turns`, `--max-budget-usd`, an interrupt, or the end of the host’s conversation
- Fixed cloud sessions sometimes showing the model’s follow-up text after a tool group’s one-line label
- Fixed the Write and Edit tools creating a mod in a session’s mods folder without asking in accept-edits mode when the config directory’s path has no `.claude` in it
- Fixed installed mods that kept running in an open session after being turned off remotely; they now unload between turns
- Fixed Edit and Retry in Cowork and claude.ai cloud sessions failing on a message stopped while its `UserPromptSubmit` or mod `prompt.submit` hooks were still running (regression in 2.1.296)
- Fixed an agent teammate started without a description keeping part of a credential from its prompt in the task description shown for it
- Fixed the claude.ai view of a Remote Control or cloud session freezing when a large batch of events could not finish uploading over a slow connection
- Fixed a sandboxed shell command being able to write into a `--plugin-dir` folder, whose code Claude Code reloads and runs outside the sandbox
- Fixed memory growth under heavy debug logging (`--debug`, `--debug-file`), and a hang on exit when the debug log is on a disk or network mount that stops accepting writes
- Fixed memory growing without bound when debug output goes to stderr and the parent process stops reading it
- Fixed rm prompts on shell `-c` scripts that don’t run `rm`. An rm built at run time in a script Claude Code can’t read no longer prompts unless `CLAUDE_CODE_STRICT_INLINE_SHELL_RM_PROMPT=1`
- Fixed double-clicking a word in an expanded transcript row in fullscreen mode collapsing the row instead of selecting the word
- Fixed `claude mcp list`, `claude doctor` and `/status` reporting an empty `.mcp.json` as invalid
- Fixed `/btw` jumping the transcript to the bottom when asked while scrolled up in fullscreen
- Fixed sandboxed commands failing on WSL2 with `bwrap: Can't mkdir /mnt/c/Program Files/ClaudeCode` when the sandbox can write to the Windows drive
- Fixed scheduled wakeups (ScheduleWakeup) not firing while a background task was running in Agent SDK, IDE and `claude remote-control` sessions
- Fixed a mod’s `prompt.submit` rewrite being silently dropped, sending the prompt as typed, for some prompts with a pasted image or an image that can’t be read
- Fixed a Remote Control prompt being lost when another queued prompt in the same batch failed to deliver
- Fixed a Remote Control prompt that had passed its hooks being dropped from prompt history when Stop interrupted the next queued prompt’s hook
- Fixed sign-in, MCP servers and project trust appearing lost on Linux after a sandboxed command left an empty `.config.json` in the config directory
- Fixed `/sandbox` reporting success when its setting could not be saved because the project folder is not writable; it now says nothing changed and why
- Fixed SDK and headless sessions staying in auto mode after the host switched to a model that doesn’t support auto mode
- Fixed MCP servers named `constructor` or `prototype` in an MCP config never being connected
- Fixed tools of an MCP server named `constructor` or `toString` asking for permission in auto mode and bypass permissions mode
- Fixed a spurious “synced\[0\] commands path not found” plugin error at startup when another Claude Code process had just updated a claude.ai-synced plugin
- Fixed the Artifact tool advising a retry when a publish that requests connectors or other access was refused by the server or a proxy (HTTP 403); it now says so and what to tell the user
- Fixed Cowork cloud sessions staying on an old account plugin after a plugin reload that timed out or a restart that reused a recent sync
- Fixed document blocks being dropped from your own message sent while Claude is working
- Fixed Claude in Chrome asking for permission while no browser is connected; it now says the extension is not connected
- Fixed the fullscreen “Update installed” notice being hidden behind the idle “/clear to save tokens” hint; it now shows beside the hint
- Fixed a mod hook, with or without a `.catch`, being run again without end when it waits on another mod’s noun that does its work outside the call
- Fixed the Claude apps gateway serving models that a policy’s `availableModelsMatch: exact` or `deniedModels` blocks; it now answers 400 and leaves them out of its model lists
- Fixed the server-managed settings request to Anthropic carrying a third-party gateway’s API key when a managed settings file sets `ANTHROPIC_BASE_URL`
- Fixed streams through a custom `ANTHROPIC_BASE_URL` being aborted after 180 seconds with no data arriving; they now wait 300 seconds, whether or not feature flags are loaded
- Fixed a mod’s `tool.describe` or `prompt.section` answer that changed after `$.ui.invalidate` never reaching Claude; the new answer is now sent on the next turn
- Fixed a settings file being ignored when `enabledMcpjsonServers` or `disabledMcpjsonServers` held a single server name (letters, digits, - or \_) as a plain string
- Fixed `claude plugin test` pausing a hook’s time budget while a served `$` method it had called kept making `$` calls after answering
- Fixed high memory use after resuming a cloud or Remote Control session that had run many subagents
- Fixed plugin hooks being skipped when they pass a very deeply nested tool input or message on with next()
- Fixed a value a mod’s hook passes to `next()`, returns, or sends to a `$` method being refused whole when one of its getters throws a `RangeError`; now only that key is refused
- Fixed `/usage`, the approaching-limit warning (terminal and VS Code) and the status line sometimes showing more than 100% used (anthropics/claude-code#92238)
- Fixed wrapped text mixing CJK or emoji with Latin words losing its last line or leaving a blank row at some terminal widths
- Fixed a cloud session sometimes ignoring the answer to a permission prompt or a question when the answer was given while the session’s worker was being replaced
- Fixed bold, italic and other nested text styles running over table borders or being lost on wrapped rows
- Fixed Cowork cloud sessions running the old version of an account plugin changed, removed or disabled from another device until the session restarted
- Fixed deny and ask rules for an MCP server (`mcp__<server>`) not applying when the server’s normalized name contains a double underscore
- Fixed long conversations losing newly attached images on every turn after one oversized image was refused by the API
- Fixed the `plugin_loaded` telemetry event reporting `has_hooks` as false for plugins whose hooks are a hooks module, built-in plugins included
- Fixed images attached while Claude is working (VS Code, desktop app, SDK) being sent at full size, which led to repeated image errors in long conversations
- Fixed the image coordinate hint being missing or slightly off for large near-square images on newer models
- Fixed feature flag, startup, fast mode, profile and feedback requests to Anthropic carrying the API key configured for a third-party gateway (`ANTHROPIC_BASE_URL`); Anthropic API keys are still sent
- Fixed a mod’s hot reload ignoring a fix saved right after a failed reload; saving a mod file without changing it no longer reloads the mod
- Fixed mods loaded from source files being refused when a hook hands `$` to a function declaration imported from another file of the mod
- Fixed a regression in 2.1.296 where cloud and headless sessions could run an approved tool call twice if a new message arrived as the session resumed after a restart
- Fixed scheduled tasks being announced for the wrong minute: the scheduling tools now report each job’s actual next run time
- Fixed mods’ hooks being handed values with `__proto__` keys silently removed, which could skip a `tool.check` guard on a tool call another mod made
- Fixed `claude -p` saying nothing when a settings file fails validation: text-output runs now list the file and the invalid entry on stderr
- Fixed long pastes in terminals without bracketed paste losing all text after an invisible control character, such as a mis-decoded curly quote
- Fixed managed settings and organization policy not being fetched when the stored login’s plan was changed locally on machines whose MDM or managed-settings file sets `forceLoginOrgUUID`
- Fixed MCP connections over HTTP hanging for 30 seconds and failing when a server never ends the body of its reply to a notification (anthropics/claude-code#99014)
- Fixed MCP servers added to a running headless or SDK session being connected before some policy checks ran; a blocked server is now reported as failed without being contacted
- Fixed `claude mcp list`, `claude mcp get` and subagent MCP servers starting a server that a policy check blocks; it is now reported as blocked without being started
- Fixed `/reload-plugins` not loading a plugin installed from another terminal a moment earlier
- Fixed blank rows appearing under CJK and emoji text squeezed into a one-cell column, as in a very narrow terminal
- Fixed text cut in the middle beside wide characters leaving a cell unused or being cut twice, and an emoji vanishing where a color changed inside it
- Fixed bare mode notices in background sessions telling you to restart without `--bare`, which keeps the mode; they now name `/stop` and `claude --resume`, as safe mode ones do
- Fixed `←` not saying why it stayed put over a queued message while Remote Control is on
- Fixed `$.http.fetch` in mods refusing a `304`, `204` or `205` response that declares a `Content-Length` over the 4 MiB body limit
- Fixed `/config` push notification toggles sending your account the previous setting instead of the one you just chose
- Fixed a cloud session leaving a reply unfinished when its worker was replaced just after the reply hit the output token limit
- Fixed Read failing on PDF page ranges in remote sessions on Linux that run without elevated privileges
- Fixed Enter answering a question or permission prompt that had been held back while you typed an unsent message
- Fixed a file attached to a message in a remote session being left out when its download stalled part way; the download is now tried again
- Fixed queued prompts sent as content blocks over `--input-format stream-json` running together without a line break when merged into one turn
- Fixed self-hosted runner sessions shutting down MCP servers added through an `--exec-path` wrapper’s own `--mcp-config` when connectors change mid-session
- Fixed `claude plugin eval` passing runs that the API refused: a run that ends on an API error now scores 0 without grading and makes the suite exit 1
- Fixed permission prompts cutting off or wrapping too early when the reason text contains keycap or joined emoji
- Fixed `forceLoginOrgUUID` and `forceLoginMethod` from MDM or the managed-settings file being hidden or replaced by server-managed settings
- Fixed `--bare` sessions leaving out an MCP server named `constructor` or `prototype` that `--channels` asked for
- Fixed resuming a conversation from before `/clear` reattaching to the Remote Control session of the conversation after it
- Fixed a prompt starting with `/`, sent with the Agent SDK’s `verbatimPrompts` option, running as a slash command when `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` re-ran it after a restart
- Fixed background sessions started with `--safe-mode` silently leaving safe mode when the session was woken or restarted
- Fixed scheduled tasks and loops firing again after every turn, or firing early, during the repeated hour when daylight saving time ends
- Fixed the diff view listing a new file whose name begins or ends with a space under the wrong name
- Fixed MCP tool calls in headless and SDK sessions sometimes failing or running twice when a background reconnect closed the connection they were running on
- Fixed `/btw` side questions in non-interactive sessions not being cancelled when the session ends, and running a second time when the same request arrived again mid-run
- Fixed sandboxed commands on macOS being able to read or write a denied path by its real location when the denied path passes through a symlink
- Fixed sandbox `denyRead` and `allowRead` globs with braces, parentheses or backslashes in a folder’s name being read differently by Claude Code’s settings checks than by the sandbox
- Fixed sandbox glob `allowRead` and `allowWrite` entries not being re-checked when the directory they start from is replaced by a symlink
- Fixed worktree-isolated sessions accepting some awk programs the isolation guard should refuse
- Fixed `claude mcp add <name> -- <command> --background` being started as a background session
- Fixed a prompt or reply of `--bg` or `--background` to a background session being taken for the flag, which could start new sessions over and over instead of delivering it
- Fixed a custom slash command’s embedded shell line running twice when a newer message interrupted the command while its prompt was being checked
- Fixed `--worktree` sessions leaving a folder behind in `.git/worktrees` in repositories using git’s reftable ref storage
- Fixed `claude self-hosted-runner` sessions using Anthropic-managed git showing tracked files as staged deletions when starting in a reused clone whose remote is still empty
- Fixed Ultracode not being announced to scheduled tasks and other delivered headless turns when `ultracode` is on in settings
- Fixed MCP OAuth sign-in, token refresh and sign-out not sending configured `headers`/`headersHelper` values, which broke servers behind an authenticating proxy
- Fixed the Artifact tool reporting a spurious one-line difference against the live page, and refusing the publish, when a large page with a line break after `<head>` is published again unchanged
- Fixed `$.ui.open` reporting a mod’s pane as placed in sessions where no surface draws it, such as Claude Code for VS Code and `claude -p`
- Fixed the `agent.spawn` mod hook not running when a finished subagent or a killed teammate is resumed: the hook’s event now carries `resume`, and a mod can refuse it
- Fixed `claude plugin validate` rejecting a mod’s `$.state` references when `plugin.json` has no `types` key and the contract is at `./types/index.d.ts`
- Fixed a mod’s `dimColor` text looking the same as plain text under the dark ANSI theme and on 16-color terminals
- Fixed plan mode running a write (an MCP tool’s, a file’s, a shell command’s) that a `PreToolUse` hook or a mod’s `tool.check` hook allowed
- Fixed background subagents in auto mode sometimes sending their final report twice, once as the result and once as a message
- Fixed `SendMessage` not finding a subagent by name after the CLI restarted and resumed the session (names given before the last compaction still need the agent ID)
- Fixed replies cut off at the output token limit ending the turn silently, with no retry or error, after a request fell back to non-streaming mode
- Fixed Read garbling UTF-16LE files with a byte-order mark, and Write dropping byte-order marks or silently converting Windows-1252, Shift-JIS, GBK or UTF-16BE files to UTF-8 (now refused)
- Fixed cloud sessions sometimes leaving a message unanswered when the worker was replaced right after a compaction
- Fixed cloud sessions and `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` sometimes answering a finished turn again after a restart, when a tool ended the turn and a skill loaded in the same step
- Fixed photos sent over Remote Control being dropped when their copy could not be saved on your computer; Claude now still sees the photo
- Fixed files sent over Remote Control sometimes not arriving in long-running sessions
- Fixed files of 30 to 35 MiB sent over Remote Control or to a cloud session not arriving
- Fixed a user-installed mod’s `$.env.set` changing the environment or shell prefix that command hooks from managed settings start with
- Windows: Fixed the process-liveness check leaving orphaned PowerShell processes behind on busy machines until memory ran out
- Windows: Fixed PreToolUse and PermissionRequest hooks that set no shell failing open when Git for Windows isn’t installed; a guard that fails now blocks the call
- Windows: Fixed Bash commands failing with “command not found” for a whole session when Git Bash did not report its PATH at startup
- Self-hosted runner: Fixed sessions that wrote output before their first turn being left with no release timer, ignoring `--retire-at` and delaying shutdown
- \[VSCode\] Fixed an unsent prompt and its attachments being lost when switching to another session and back
- \[VSCode\] Fixed unused blank chats keeping a background Claude process running after starting a new conversation
- \[VSCode\] Fixed the mic button showing an internal error message when you are signed out of claude.ai; it now offers to sign you in
- \[Cloud sessions\] Fixed a memory spike that could crash a session when many of its existing output files were re-sent to it at once
- \[Cloud sessions\] Fixed saving an edited routine silently moving it to a different environment when its own had been deleted or wasn’t in the list; the routine now keeps its environment
- \[Cloud sessions\] Fixed Sessions search in a self-hosted environment’s admin details finding nothing when you paste the session ID from a session’s link
- \[Cloud sessions\] Fixed the Sessions and Runners lists in a self-hosted environment’s admin details saying the list is empty when a search just has no matches
- \[Remote Control\] Fixed Remote Control sessions whose computer can’t be reached still appearing to send your messages; your text now stays in the box and Send is off until it reconnects
- \[Claude Tag\] Fixed Claude in Slack staying silent on untagged posts that a channel’s own instructions tell it to answer, such as posts that tag someone else, in channels with guests
- \[Claude Tag\] Fixed Claude in Slack reporting a reply to another channel’s thread as posted when it isn’t a member there; it now says the reply wasn’t delivered and how to fix that
- \[Claude Tag\] Fixed Claude in Slack sometimes ending a turn without posting its answer when a self-hosted runner’s image has no python3
- \[Code Review\] Fixed Code Review’s monthly spend-limit comment and check-run card sending admins to Claude Code settings; they now link the Usage page, where that limit is set

[​](#2-1-296)

2.1.296

October 9, 2026

**Added**

- Added a `code` key to the Claude apps gateway’s `managed.policies[]`: the same settings as `cli`, also applied in Claude Desktop’s Code tab; beside `desktop`, it turns on Claude Desktop’s gateway mode
- Added `autoCompactWindow` to subagent frontmatter and `--agents` definitions, so a subagent can auto-compact earlier than the main conversation’s window
- Added `CLAUDE_CODE_WORKFLOW_SUBAGENT_MODEL` to run every workflow agent on one model while other subagents keep theirs
- Added `CLAUDE_CODE_OVERLOADED_RETRY_MAX_DELAY_MS` environment variable to set a longer maximum delay for the backoff when retrying an overloaded (529) request
- Added a note in `/plugin` on a plugin whose hooks are left out because another enabled plugin has the same name
- Added an `allow_large` option to the Read tool so Claude can read a text file past the usual size limits in one call when it needs the whole file and the context has room
- \[Cloud sessions\] Added a status filter to the Sessions and Runners lists on a self-hosted environment’s Activity tab in admin settings; you can pick several statuses at once
- \[Claude Tag\] Added creating, editing and deleting workspace and channel memory files on the Activity page’s Memory tab for members with the Claude Tag Admin permission

**Changed**

- Updated `/cost`, the status line, `--max-budget-usd` and the SDK’s cost figures to price Sonnet 5.5 cache reads at \$0.10 per million tokens (was \$0.20)
- Updated the bundled dataviz skill: lighter violet for the seventh series in light mode, softer primary text in dark mode, and compact y-axis labels like 1K
- Changed the default limit on MCP tool descriptions sent up front and on MCP server instructions from 2,048 to 4,096 characters
- Changed `←`: a turn or `!` command started while the session moves to the background is now stopped instead of finishing out of sight
- \[VSCode\] Changed Claude in Chrome to ask before browser actions in every session, including one connected with `@browser`, as the terminal does; allowing a site for the session stops repeat asks
- \[Claude Tag\] Changed Claude in Slack to show the footer with the session link, model and cost only on its newest reply in a thread; the reply before it drops the footer

Show 9 improvements

- Improved fullscreen mode: the link under the mouse pointer is now underlined to show it can be opened
- Improved transcript toggle (ctrl+o) responsiveness in code-heavy conversations by caching syntax-highlighted code blocks
- Improved Claude Desktop’s Code tab behind a Claude apps gateway: when a session can’t start, including on a machine not set up for the gateway’s `code` settings, the reason shows as a reply
- Improved the errors for a refused cloud session: they now say why your organization’s policy couldn’t be loaded, and name an API key or auth token that overrides your claude.ai login
- Improved `--debug` output to name unrecognized frontmatter fields in custom agent files, with a hint for likely typos
- Improved auto mode: a tool call that wasn’t run because auto mode’s check had no usable answer now shows as a dim “Not run” row instead of a red error
- Improved `--debug` output for hooks: command hooks on tool calls, prompts, SessionStart and Stop now log their command, plugin, outcome and duration when they finish, so a slow hook is identifiable
- Improved `CLAUDE_CODE_TRANSCRIPT_LOCAL_GC`: a large transcript file is no longer rewritten when that would free under 10% of it
- \[Code Review\] Improved Code Review admin settings to say why a setting couldn’t be saved, such as a policy restriction, instead of a generic failure message

Show 56 bug fixes

- Fixed managed-settings `PreToolUse` hooks that deny a tool call with `"continue": false`, and managed `prompt` hooks that block one, refusing the call but not ending the turn
- Fixed PostToolUse hooks in managed settings not applying `updatedMCPToolOutput` in some sessions
- Fixed headless sessions starting a folder’s `.mcp.json` or plugin MCP server that was switched off for that folder, after changing directory or reloading plugins
- Fixed a Claude apps gateway that serves `allowedProviders` with `"gateway"` locking out laptops that name that gateway in user settings
- Fixed a saved Claude apps gateway sign-in being ignored on machines whose managed settings set `forceLoginMethod` to `gateway` with no `forceLoginGatewayUrl` (regression in 2.1.295)
- Fixed `--teleport` opening an empty conversation when the session’s history could not be read
- Fixed token counts for Haiku 5.5 and other models that take only adaptive thinking, which failed behind some gateways and were counted with budget thinking elsewhere
- Fixed resumed subagents being told that the user rejected a tool call that a session shutdown had interrupted
- Fixed hook output being altered when it contained text resembling a plugin hint tag
- Fixed secret redaction in shared transcripts and debug logs missing some values that follow a key with no value, including in JSON written inside a shell string
- Fixed a stray `52;c;…` escape sequence printed on screen after copying in older VTE-based terminals such as MATE Terminal
- Fixed toasts and notifications waiting unseen for as long as the `/diff` panel or dialog was open
- Fixed Esc or an interrupt during a `UserPromptSubmit` hook or a mod’s `prompt.submit` hook ending headless sessions, clearing the typed prompt, or letting the unchecked prompt through
- Fixed SessionStart hooks of a plugin loaded after a headless session starts being skipped when a different plugin with the same name, or another spelling of it, had already run
- Fixed `claude self-hosted-runner` printing misleading errors when registration is refused: it now names the org admin setting, or says a restarted on-demand runner needs a fresh work order
- Fixed a self-hosted runner session’s git fetch, pull and push failing while another session of the same repository starts on a runner with `--capacity` above 1
- Fixed workflow scripts silently truncating results, agent options and other values nested deeper than about 20,000 levels, and deeply nested results writing huge task output files
- Fixed a plugin’s served `$` methods running in the main session’s working directory instead of the calling agent’s, and ignoring the turn their calling hook holds
- Fixed `$.agent.register` succeeding from a mod’s hook that was still running after the mod was reloaded or removed; the call is now refused
- Fixed `$.http.fetch` in mods refusing a `HEAD` request when the response declares a `Content-Length` over the 4 MiB body limit
- Fixed `claude plugin marketplace add`, `marketplace update` and `plugin install` failing with an internal error for a marketplace named like `constructor`; `add` now refuses such names clearly
- Fixed a plugin secret named `constructor` or `prototype` being deleted by the next save of that plugin’s options
- Fixed cloud sessions skipping auto mode’s checks on Claude in Chrome actions that a saved permission allows when their feature flags had not loaded
- Fixed `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` re-running a finished turn after a restart when an MCP tool result had ended that turn
- Fixed Bash permission checks auto-approving some commands that assign the `BASH_ARGV0` shell variable and then use it; these now prompt for approval
- Fixed Edit and NotebookEdit replacing every non-ASCII character in files that are not valid UTF-8 (Windows-1252, Shift-JIS, GBK); such edits are now refused
- Fixed a prompt sent just after `←` being run twice, once unseen in the foreground, when the background service was slow to answer
- Fixed a prompt sent while SessionStart hooks were still running vanishing when `←` moved the session to the background; it is still not sent, but `↑` now brings it back
- Fixed a late-loading plugin’s SessionStart hook output reaching the new conversation after `/clear` in headless sessions
- Fixed PowerShell commands not seeing variables that hooks write to CLAUDE_ENV_FILE (when the file holds only plain assignments)
- Fixed Claude calling cloud sessions non-interactive and suggesting `/mcp` or `claude mcp` when an MCP server needs authentication
- Fixed `/code-review` ending on a raw JSON array in cloud sessions, the Agent SDK and IDE integrations; the findings now print as a numbered list
- Fixed auto mode occasionally refusing one update to your own artifact, saying its sharing had changed when it had not
- Fixed skills synced from claude.ai never finishing their install, and being downloaded again at every sync, when several sessions share a config directory
- Fixed a plugin synced from claude.ai being disabled when the marketplace dependency it declares was also synced from claude.ai
- Fixed a startup hang on macOS when plugin paths copied from a Linux machine pointed under /home
- Fixed the Workflow tool refusing script files with CRLF line endings, such as files checked out on Windows
- Fixed OpenTelemetry `tool_result` events missing `git_commit_id` after `git commit -q` or `git -C <dir> commit`
- Fixed `CLAUDE_CODE_TRANSCRIPT_LOCAL_GC` dropping a message from the saved transcript when its text held a Unicode line or paragraph separator (U+2028, U+2029)
- Fixed `claude purge` leaving a prompt in the history file when its text held a Unicode line or paragraph separator (U+2028, U+2029)
- Windows: Fixed PowerShell commands longer than about 1 KB always asking for permission, so allow rules and read-only detection now apply up to 32 KB
- Windows: Fixed stdio MCP servers being force-killed at shutdown; stdin now closes first and the process tree is killed only if the server is still running after 300 ms
- Windows: Fixed `claude plugin install` failing for GitHub `owner/repo` plugin sources on machines with no GitHub SSH key; the clone is now retried over HTTPS
- Windows: Fixed `rm -rf /c/Users/<name>` in Git Bash not asking in bypass permissions mode
- \[VSCode\] Fixed `claudeCode.spinnerVerbs` missing from the extension’s settings, so settings.json now completes and validates it; a malformed value no longer breaks the chat panel
- \[VSCode\] Fixed chat links written as a full Windows path, such as C:\repo\file.ts or file:///C:/repo/file.ts, not opening the file on Windows
- \[VSCode\] Fixed the working indicator still animating when reduced motion is turned on in your OS, in VS Code, or with the `prefersReducedMotion` setting
- \[VSCode\] Fixed the prompt cache clock reading warm after the panel caught up on messages late, such as after the display was off or a remote window reconnected
- \[Cloud sessions\] Fixed every cloud session waiting for a self-hosted runner showing the same queue position; each now shows how many sessions are ahead of it
- \[Cloud sessions\] Fixed a message you send while Claude is still replying in a cloud session jumping above that reply when it finishes; it now stays below it, including after a reload
- \[Claude Tag\] Fixed links to URLs that contain parentheses breaking in some of Claude’s Slack replies and task checklists, which showed stray bracket text and opened the wrong page
- \[Claude Tag\] Fixed Claude’s Slack replies drawing color swatches beside codes that only look like hex colors, such as six-digit pull request numbers
- \[Claude Tag\] Fixed the plugin confirmation card Claude posts in a Slack channel showing a plugin’s ID instead of its name
- \[Claude Tag\] Fixed Claude in Slack posting a card to remove a plugin the channel’s own settings don’t include; it now explains where the plugin comes from instead
- \[Claude Tag\] Fixed Claude in Slack sometimes losing its reply when a session in a self-hosted environment moved to a new runner partway through a task
- \[Code Review\] Fixed the Code Review check sometimes staying “in progress” on a pull request after the review finished; it now shows the review’s result

[​](#2-1-295)

2.1.295

October 8, 2026

**Added**

- Added `onFailure: "block"` for command and HTTP hooks: a hook that can’t start, times out, or exits with an unexpected code blocks the action instead of letting it through
- Added Program Status Protocol (OSC 7501) support: terminals that implement it can show whether Claude Code is working, waiting on you, or done
- Added quoted text to the `/copy` picker, so a drafted message copies without its `>` markers
- Added a warning to `claude plugin install`, `enable`, `disable` and `marketplace add` when the settings file they write to does not load
- Added a line on stderr, when it is a terminal, that says what a `claude -p` run is waiting for when it stays open after its last turn
- Added support for `timeouts.upstream_ttfb_ms` on the Claude apps gateway’s Bedrock, Vertex, Foundry and other cloud upstreams: a value you set now limits how long a stream may take to start there, after which it fails over or gets a 502
- Added a “Backgrounding cancelled” message when you stop the turn while `←` is waiting for the current tool to finish
- Added an optional `models` list to every Claude apps gateway upstream: only the listed models are sent there, on failover too, and one `*` in an entry is a wildcard
- Added support for `forceLoginMethod: "gateway"` and `forceLoginGatewayUrl` in your own user settings on machines with no managed settings, so `/login` opens on that Claude apps gateway
- Added advice to `claude plugin validate` when a plugin’s README has no install line: it prints the line to paste and never changes the exit code, even with `--strict`
- Added `upstream_request_id` to the Claude apps gateway’s `inference` audit event: the request ID from Amazon Bedrock, the Anthropic API or another upstream, for support cases
- Added `$.ui.notify` for mods: raises a native notification through your own notification setting and says which channel sent it
- Added children to a mod’s `Button`: strings and `Text`, so a row of a list is one pressable with a chip or a dim detail inside
- Added `CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS` to limit how long unattended retry mode (`CLAUDE_CODE_RETRY_WATCHDOG`) waits out 429 and 529 errors
- Added a `request-id` header to the Claude apps gateway’s successful inference responses, so `request_id` in Claude Code telemetry matches the gateway’s audit log
- \[VSCode\] Added a chat row for files Claude sends you: click a file’s name to open it in the editor; Claude’s caption shows underneath, and the row stays visible in Focus view
- \[Claude Tag\] Added a confirmation in Claude Tag admin settings before adding a channel manager moves that member to Custom roles, which can remove their other access

**Changed**

- Changed MCP tool descriptions the model loads through tool search to be cut at 16,384 characters instead of 2,048
- Changed subagents to preload at most 32 skills from the `skills` field, each once; a subagent with the Skill tool can still invoke the rest
- Changed Ctrl+C at the idle prompt of an attached background session to leave a pending `/loop` wakeup alone, so pressing it twice detaches and the loop keeps running; press Esc to stop it
- Changed `claude agents` stopped with its background service (macOS, or Linux without the service installed): running sessions now stop in about a minute unless it is run again, and a notice says so
- Changed claude.ai connectors to negotiate MCP protocol version 2026-07-28 by default on installs that fetch no flags; `MCP_PROTOCOL_NEGOTIATION=legacy` opts out
- Changed Artifact pages with no background of their own to show on white instead of off-white
- Changed what Claude and you read when a mod denies a tool call after the tool ran: it now says the tool ran and a plugin withheld its result
- Changed tab stops to count from where a text starts instead of from the screen’s left edge: an answer indented by 2 has its first stop 8 cells in, where it was 6
- Changed the Artifact tool’s permission prompts with telemetry disabled to the same five questions other installs get, instead of asking before each read of someone else’s artifact and each data edit
- Changed scheduled and Run now routine runs in installs with telemetry disabled to publish new private artifacts, and update your own, without asking, as in other installs
- Changed toasts from your organization’s mods to show ahead of other mods’ toasts instead of waiting behind them
- Changed the Claude apps gateway to start with a warning and serve a `desktop` policy key its bundled Claude Desktop schema doesn’t know, so new Desktop settings need no gateway upgrade
- Changed WebSocket (`ws`) MCP servers: a message over 16 MiB is no longer parsed and closes the connection, the limit the other transports already have
- Self-hosted runner: Changed the runner to stop passing `CCR_AUTO_MODE_ALLOW`, `CCR_AUTO_MODE_ENVIRONMENT` and `CCR_AUTO_MODE_SOFT_DENY` into a session’s environment
- \[Claude Tag\] Changed the settings confirmation cards Claude posts in a Slack channel to stay open for 30 minutes instead of 10
- \[Claude Tag\] Changed Claude’s notice that a channel shared across Enterprise Grid workspaces uses organization defaults to post only when someone mentions Claude, at most once a month

Show 13 improvements

- Improved token counts behind a Claude apps gateway on Amazon Bedrock, which `/context` and large file reads use: the gateway now gets them from AWS’s CountTokens API instead of a one-token model request. Grant `bedrock:CountTokens` to use it
- Improved the Claude apps gateway to log a warning every 30 seconds while its PostgreSQL database is read-only, saying what fails and how to recover
- Improved the status shown in Remote Control, claude.ai and the desktop app for a session waiting on a permission prompt to name an MCP tool by its server and readable name instead of its `mcp__server__tool` identifier
- Improved background requests behind a Claude apps gateway to use Haiku 4.5 instead of the session’s model, falling back to the session’s model where the gateway does not serve Haiku 4.5
- Improved how the Claude apps gateway handles models not listed under `models:` in Amazon Bedrock regions outside AWS’s US geography. AWS always refused those requests; the gateway now tries the model in your own region, and a refusal names the model to add
- Improved headless `rate_limit_event` usage-limit warnings to say whether the account has extra usage turned on
- Improved the built-in `plugin-authoring` skill: it no longer tells a session with no terminal to run terminal commands, and explains sharing a mod only when asked
- Improved Grep input handling: a search sent with grep’s `-l`, `-c` or `-r` flag now runs instead of failing the call
- Improved `claude plugin validate` and plugin loading: when a hooks module is refused over a rebound top-level `var`, the error now names the line that rebinds it, the cause, and a fix
- Improved the Workflow tool’s `scriptPath` refusal: it now says to pass the script inline via `script`, the route that works in sessions without a Read tool
- Improved what Claude is told when a large file it sends fails to upload with no reason given, so it reports the failure instead of shrinking the file
- \[Cloud sessions\] Improved how quickly a cloud session catches up after its connection drops: activity you missed now appears all at once instead of row by row
- \[Cloud sessions\] Improved the setup script box in the cloud environment form: it starts taller, grows with your script, and can be resized by dragging

Show 97 bug fixes

- Fixed every request failing on a `[1m]` model when a gateway, Bedrock, Vertex or Foundry refuses the context-1m beta; Claude Code now resends without it
- Fixed `claude -p` text output dropping earlier responses when background work started another turn; each turn’s response now prints when the turn ends
- Fixed remote MCP servers in headless and SDK sessions staying disconnected after an outage longer than 15 seconds, or reconnecting in a tight loop to a server that drops each connection right after it connects; repeated drops now back off, up to 30s
- Fixed remote MCP connections being dropped when a server’s error reply happened to contain a network error name
- Fixed MCP servers that repeat a pagination cursor being asked for the same page up to 20 times at every connect
- Fixed CSS, JavaScript and XML files returned by MCP tools being saved as .bin, which the Read tool refuses; font and icon files now get their own extension too
- Fixed Bash tool calls failing when the model passes `command_description` instead of `description`
- Fixed Claude in Chrome not applying a site deny rule written with port 80 (`host:80`) to plain `http://` pages on that host
- Fixed `/plugin`’s Errors tab removing a marketplace that failed to load, and uninstalling its plugins, on Enter without asking first
- Fixed `claude plugin marketplace add` reporting success for a marketplace whose name no plugin can be installed under; such an add is now refused
- Fixed `CLAUDE_AUTO_BACKGROUND_TASKS` moving a subagent to the background while an edit or shell command waited behind it, which started that call before the subagent finished
- Fixed PushNotification saying a push was not sent in `claude remote-control` sessions right after a phone message, without the `/config` toggle, or when started from inside Claude Code
- Fixed files sent from remote sessions being refused as “could not be vouched for” when more than 256 were sent at once
- Fixed a rare failure to load managed settings at startup right after a login refresh
- Fixed `/tui` exiting without a message, or with a raw system error, when Claude Code could not be started again
- Fixed a link address shown as text being hidden by a colour or conceal style a reply left on, including where it wraps in a table or a question preview
- Fixed Fable models listed in `availableModels` not appearing in the `/model` picker for sessions signed in to a Claude apps gateway; such a model now shows its built-in row in place of a `modelPicker` row added for the same model
- Fixed the Claude apps gateway’s admin spend view showing a developer’s old groups and group cap after their session stopped carrying groups
- Fixed `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` hiding the Claude apps gateway spend limit in `/usage` and the status line. The spend limit request goes to the gateway the session is signed in to
- Fixed subagents in their own linked worktree being shown the parent session’s git branch, status and recent commits
- Fixed Claude stopping at the end of the current tool when text typed in the prompt cancelled backgrounding with `←`; Claude now keeps working in the foreground
- Fixed `--tools` and `--restricted` not applying to built-in tools that register after launch, and deprecated tool names reaching tools outside the caller’s tool set
- Fixed an interrupt not ending the turn until a timeout while Claude waited for an MCP server’s resource list
- Fixed a mod’s hook being handed a deeply nested tool input cut short with no error, so a guard could pass content it never saw
- Fixed Esc not stopping a self-paced `/loop` that was moved to the background with `←`; cancelling a pending wakeup now shows a notice
- Fixed commands and hooks in background sessions inheriting `FORCE_COLOR=3`, which put color escape codes into the output Claude reads
- Fixed `claude agents` starting a new background service as it exited when both were stopped with a session open (for example at a reboot), which could delay shutdown and restart an interrupted session
- Fixed a custom agent named `worker` being shown as “Agent” in auto-mode denial notices and in the activity lists of task detail views
- Fixed Bash permission checks for for-loops over glob patterns, improving permission-check accuracy
- Fixed forked skills invoked from Workflow subagents delivering their results to the main conversation instead of the invoking agent
- Fixed in-process agent teammates failing their first SendMessage call until they loaded the tool through tool search
- Fixed Claude being told on resume that an unfinished background workflow may have been stopped by `TaskStop`, which can never be the cause
- Fixed Claude not being told when you stop a long-running MCP tool call from the tasks panel or a connected client
- Fixed a background session’s `/loop` stopping without notice when its next wakeup came due while the session’s process was down; the session now says so and Claude is told
- Fixed raw terminal hyperlink bytes in a reply or a teammate’s message being drawn as a clickable link with a hidden address
- Fixed plugin marketplaces whose repository has large git submodules failing to add or refresh: only the submodules that hold plugin files are now fetched
- Fixed the `/advisor` dialog showing a checkmark on a saved advisor model that is no longer available; it now opens on “No advisor”
- Fixed the notification for an MCP tool call that moved to the background showing a shortened task id
- Fixed vim mode’s `~` moving the cursor past the last character of a line, so `x` after it did nothing, and `3~` running on into the next line
- Fixed the cursor landing one character too far after pasting accented text copied from macOS (such as a file name) into the middle of the prompt
- Fixed the terminal freezing, with ctrl+c ignored, when a response ran to tens of thousands of lines
- Fixed calls a mod makes while it reloads during a plugin hooks worker restart getting past another mod’s guard hook that has a `.catch`; such calls are now refused
- Fixed plugins whose hooks module nests code thousands of levels deep failing to load or validate with a bare stack-overflow message
- Fixed `claude plugin test` passing a `session.append` hook that removes tool call, tool result or thinking blocks that a real session keeps
- Fixed Claude not being told it can resume background subagents with SendMessage after a session was killed and resumed a second time
- Fixed a file being treated as already read after a Bash command such as `cat` ran without printing it
- Fixed plugin options named `constructor` or `prototype` always reading as their default and never reloading the plugin when edited
- Fixed a mod’s hot reload missing a save made while `/reload-plugins` or session start was reading the mod’s files
- Fixed the mod hot-reloading question being asked again every turn for the whole session when it is approved without picking an answer
- Fixed `/model`, `/fast` and `/output-style` saving their setting without asking a plugin’s `config.set` hook
- Fixed bold text being drawn faint in piped output when it directly follows dim text
- Fixed replies whose quotes nest deeper every few lines freezing the terminal for seconds and using gigabytes of memory
- Fixed a mod’s hot reload missing a save made within a few milliseconds of its last reload, which left the mod on its old version until the next save
- Fixed `claude mcp serve` background Bash results not naming the output file, and its tool description promising a notification that never arrives
- Fixed an async SessionStart hook’s unchanged context being added to the conversation again on every resume
- Fixed variables a SessionStart hook writes to `CLAUDE_ENV_FILE` not reaching the Bash tool after an in-app `/resume` or `/branch`
- Fixed a skill’s `allowed-tools` and `effort` being dropped when the Skill tool finished before the response stream ended, which denied the skill’s Bash commands in `-p` runs
- Fixed a tampered cache of server-managed settings making a person’s own plugin count as organization-managed on machines whose managed settings list or enable plugins
- Fixed Claude 3 Opus and Claude 3.x Sonnet sessions being offered tool search, which those models reject, where feature flags are unavailable
- Fixed generated type files being written into a `--plugin-dir` plugin’s folder in `-p` and SDK sessions; they are now written only where a mod is being developed
- Fixed text with tabs or bidirectional control characters losing its end at the edge of the screen or drawing over nearby rows
- Fixed `/model` saying a Max effort pick was saved as your default for new sessions; Max applies to the current session only
- Fixed an async hook’s JSON output being ignored when it is printed over several lines
- Fixed the Read tool rejecting calls with an empty `pages` parameter instead of treating it as omitted
- Fixed project-scope plugins not loading in VS Code on Windows due to drive-letter casing (anthropics/claude-code#74612)
- Fixed `plugin install` and `uninstall` at project or local scope on Windows missing the install record, or adding a second one, when only the drive letter’s case differs
- Fixed a queued message being lost when pulled back into the prompt with `↑` or `Esc` just after `←`: prompt history now keeps it
- Fixed mod hot-reloading turning off for the whole session when an SDK host closed its enable question before anyone answered; the question is now asked up to three times
- Fixed a prompt that a mod’s `prompt.submit` hook rewrote or dropped still being saved as typed to prompt history and to the transcript’s queued-prompt records
- Fixed non-interactive sessions telling you about MCP servers that need authentication when your request doesn’t use them
- Fixed the `claude_code.auth` OpenTelemetry login event not being emitted on Claude apps gateway sign-in. The event is exported when OpenTelemetry is configured on the machine or the session is already signed in to the gateway
- Fixed a plugin that adds very large interfaces getting another plugin unloaded when the plugin hooks worker stalls
- Fixed Edit treating a file as fully read when its contents changed without its modification time advancing
- Fixed short command output with Windows line endings (CRLF) being drawn on a single line
- Fixed a stopped scheduled task coming back on resume after a rewind, and a scheduled task being lost on resume after Esc or a rewind following a compaction
- Fixed the terminal freezing for seconds or minutes while syntax highlighting code with very long lines, long runs of blank lines, or unclosed strings and heredocs
- Fixed temporary files left under `~/.claude/seed-admin` by an interrupted `/ultrareview` upload never being removed by the retention cleanup
- Fixed Desktop and SDK sessions refusing to switch back to auto mode until restart after `disableAutoMode` was removed from settings
- Fixed claude.ai-synced plugin hooks failing with “Plugin directory does not exist” in long-running sessions after another session synced a plugin update
- Fixed the prompt sent after a `/rewind` being lost, and the removed turns coming back, when the session was moved to the background or resumed after being killed
- Fixed cloud sessions hanging when a mod’s `session.receive` hook asked for permission before passing a message on
- Fixed macOS background sessions that restart together after an update sometimes running outside the stable app wrapper, so folder-access prompts could reappear
- Fixed an MCP sign-in or reconnect that finishes late in headless and SDK sessions relisting a server set with `setMcpServers()` as your own
- Fixed changing the auto-update channel in `/config` saving before a plugin’s `config.set` hook was asked
- macOS: Fixed a file count at session start that could reach other apps’ data and raise the “access data from other apps” prompt when a session starts in the home folder or above it
- \[VSCode\] Fixed “Fork conversation from here” and Rewind’s conversation restore failing with “Message not found in session” after a background agent’s activity or one of the panel’s own status lines
- \[VSCode\] Fixed Ctrl+Shift+Tab, Cmd+Shift+Tab and Alt+Shift+Tab in the chat input also switching the permission mode, and Ctrl+Tab accepting the suggested prompt
- \[VSCode\] Fixed keyboard focus bouncing between two Claude views visible at once, which could send typed text to the wrong conversation
- Self-hosted runner: Fixed git fetches being cut off while the git server was still reporting progress on a large repository; `CLAUDE_RUNNER_FETCH_SERVER_PROGRESS_CAP_MS` tunes or turns off the wait
- \[Cloud sessions\] Fixed a message sent right after unarchiving a cloud session sometimes getting no reply because no container could start for it
- \[Cloud sessions\] Fixed some older routines starting their runs without ever giving Claude their saved prompt; those routines now run their prompt again
- \[Claude Tag\] Fixed channel links and @-mentions in a forked thread’s “Continued from” card showing as raw Slack codes
- \[Claude Tag\] Fixed Slack’s Working status spinning on under a thread after `@Claude !restart` had already confirmed the restart
- \[Claude Tag\] Fixed another app’s or bot’s @Claude going unanswered in a busy channel where Claude had stopped reading untagged messages
- \[Code Review\] Fixed Code Review re-reviews saying no issues were found while earlier findings were still open; the comment now says how many remain open
- \[Code Review\] Fixed Code Review still skipping a large CLAUDE.md’s rules when the pull request edits that file
- Fixed web searches and `agent` hook evaluations taking much longer at `xhigh` and `max` effort

[​](#2-1-294)

2.1.294

October 8, 2026

- Fixed `prompt` and `agent` hooks written as instructions (such as “Block commands that…”) allowing what they should block
- Improved how `prompt` hooks on Stop and SubagentStop written as instructions (such as “Carry on if the build is broken”) are judged, so Claude is less likely to stop early

[​](#2-1-293)

2.1.293

October 7, 2026

**Added**

- Added Claude Haiku 5.5 (`claude-haiku-5-5`), now the default Haiku model on the Anthropic API — 1M context, \$0.10/\$0.50 per Mtok (\$0.50/\$2.50 for prompts over 100K)
- Added `agentType` to the `subagentStatusLine` payload, so scripts can tell custom subagent types apart
- Added `isDeferred` to `$.tool.register` for mods: `false` lists the tool’s schema in the prompt from the start instead of behind tool search

**Changed**

- Reverted the auto mode denial message change from 2.1.281 that told Claude a denial covers the outcome, not only the exact command
- Reverted the 2.1.290 fix for cloud sessions staying asleep after a container restart lost a pending `/loop` wakeup or scheduled task; Claude is no longer told, and the session stays asleep
- Changed claude.ai skill syncing to check for changes about every 40 minutes, instead of every 10, while no session is in use
- Changed the order of agent lists and of MCP servers announced to the model: names with non-ASCII characters now sort after ASCII names
- Changed OpenTelemetry `claude_code.at_mention` logging to emit at most 100 agent and 100 MCP-resource events each time a prompt is read
- Self-hosted runner: Changed the orchestrator to sleep 4 to 6 seconds between polls instead of a constant 5, so several replicas for one environment stop polling at the same moment
- \[Claude Tag\] Changed Claude in Slack to join announcement channels, where only admins can post, without posting its intro
- \[Claude Tag\] Changed the limit on channel rules in Claude Tag admin settings from 20 to 50 for each workspace and for the organization-wide Slack page

Show 7 improvements

- Improved startup for Team and Enterprise organizations: policy and managed settings are fetched earlier, and a stalled request is retried after 3 seconds
- Improved Claude in Chrome: fewer page actions are refused when the browser is slow to report its tabs
- Improved the Claude in Chrome message in cloud sessions when the browser can’t be reached: if you belong to more than one organization, it now says the extension must be signed in to the same one, and how to change that
- Improved the Bash edit diff note to say the listed files changed while the command ran, which can include writes by other processes
- Improved artifacts: Claude pins libraries to exact versions two weeks old or older
- \[Claude Tag\] Improved Claude Tag admin settings to list an Enterprise Grid that isn’t connected yet, with a Connect button
- \[Code Review\] Improved Code Review’s Add a repository dialog to list each repository that couldn’t be added and why, such as missing GitHub write access

Show 38 bug fixes

- Fixed Claude sometimes treating its own last actions before a context compaction as done after it, and retracting or redoing finished work
- Fixed a memory leak where an HTTP MCP connection kept every request it had sent until it closed
- Fixed a message sent while Claude was working being lost when `←` moved the session to the background; if a queued message can’t move, `←` now stays put and says so
- Fixed `/model` effort ←/→ wrapping past the highest or lowest level, which could accidentally save Low as a model’s default effort
- Fixed `/tui` disconnecting Claude in Chrome in a session started with `--chrome`, and ignoring `--no-chrome`
- Fixed Claude being told to continue or message subagents with `SendMessage` in sessions, including resumed ones, where a host, a permission rule or a `--tools` list removed that tool
- Fixed subagents and `--agent` sessions being told a built-in tool was disabled for the whole session when only their own tool list left it out
- Fixed a claude.ai-synced skill’s edited description sometimes not reaching the model until a new conversation or `/clear`
- Fixed `claude logs`, `stop`, `kill`, `rm` and `claude daemon status`, `stop`, `uninstall` sometimes signing you out when your login had expired or was about to
- Fixed the footer’s agents count disappearing after a momentary failure to read the sessions folder (for example, too many open files)
- Fixed a custom agent named `worker` being shown as “Agent” when it starts, and the agent detail dialog’s title losing the agent type once the agent finishes
- Fixed the Artifact tool’s transcript row briefly reading `Artifact("(unprintable path)")` while a publish call was still streaming in
- Fixed the `/ultrareview` upload on Linux wrongly refusing some repositories, such as one inside another checkout, over a settings file that “could not be parsed” while a sandboxed command was running
- Fixed the `/ultrareview` upload’s refusal over split-index files advising a git command that could leave git unable to read its index
- Fixed replies in very long Remote Control and cloud sessions that could still appear a block at a time instead of streaming in
- Fixed Remote Control uploading a session’s starting history again after every credential recovery
- Fixed PushNotification reporting “Remote Control inactive” in sessions started with `claude remote-control`
- Fixed a mod’s hooks on `classic.*` events being skipped while the plugin hooks worker restarts, which left settings hooks to answer without them
- Fixed `claude plugin test` failing for mods that call `$.session.append`; tests can read the appended rows back with the new `mock.session`
- Fixed `claude plugin eval` refusing every Bash-granting run on Macs with Docker Desktop (links under `~/.docker/bin`); the refusal now names which part of a credential store held the link
- Fixed the Claude apps gateway refusing to start when a `desktop` policy sets Claude Desktop’s built-in browser keys, such as `builtinBrowserEnabled`
- Fixed `claude agents` offering bypass permissions that background sessions then ignored when consent was saved only in `.claude/settings.local.json` or a `--settings` file; it now asks for consent first, and a session that ignores bypass shows a short notice that stays
- Fixed `←` backgrounding a session after 10 seconds while the prompt held unsent text (it now cancels the move) or a question was waiting for your answer
- Fixed Esc, or No without feedback, on a permission prompt not stopping the turn when `←` had just been pressed to move the session to the background
- Fixed the agents view briefly replacing the session list with placeholder rows when the sessions folder could not be read (for example, too many open files)
- Fixed path-scoped rules and nested CLAUDE.md files not loading when Claude views a file with a single-file cat, head, tail, sed -n or grep command in the Bash tool instead of the Read tool
- Fixed pasted text that begins and ends with the same words sometimes being sent to Claude as if it had been typed
- Fixed a skill name in pasted text being treated as typed when an accent typed or pasted right after the paste merged into its last letter
- Fixed `/feedback` returning to the drafts list after Ctrl+O or Ctrl+Z while a report was sending, leaving the send impossible to cancel
- Fixed `claude purge` stopping silently (exit 0, or a hang in a terminal) when a file or folder could not be deleted; it now deletes the rest, lists what it could not delete, and exits 1
- Fixed keybindings.json checks: a lone ” ” (space key) is no longer reported as an error, and keys like “ctrl+ k” now get a warning
- Fixed vim mode `>>` and `<<` on a line of only spaces leaving the cursor past the end of the line, where a following `x` deleted nothing
- Fixed vim mode: after deleting whole lines in Visual mode (`V` then `d`) the cursor lands on the first non-blank, and `.` after it acts on the cursor’s line
- Windows: Fixed stopping a status line, hook, or shell command sometimes terminating an unrelated process that had been given the same process ID
- \[Claude Tag\] Fixed Claude in Slack saying a workspace isn’t set up in Enterprise Grid channels shared across workspaces when Slack labels a message with a workspace that isn’t connected
- \[Claude Tag\] Fixed Claude in Slack stopping mid-task in a channel when an admin changed the channel’s connectors, plugins, skills or rules; the change now applies once Claude finishes
- \[Claude Tag\] Fixed asking Claude in Slack to run a thread’s routine now with extra notes starting a separate run that couldn’t post back; the run now continues in that thread
- \[Claude Tag\] Fixed an access bundle’s Add a connector dialog in Claude Tag admin settings showing every Google connector as connected after one Google sign-in

[​](#2-1-292)

2.1.292

October 6, 2026

**Added**

- Added `--marketplace <source>` to `claude plugin install`: adds the marketplace if needed, under the same policy checks as `claude plugin marketplace add`, then installs the plugin from it
- Added an `effort` parameter to the Agent tool, so Claude runs a sub-agent at the effort level you ask for
- Added `CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS` environment variable to set a longer base delay for the backoff when retrying an overloaded (529) request
- Added `prompt.autocomplete`, an event a mod hooks to add its own rows to the prompt box’s autocomplete list
- Added prompt caching to `$.model.complete` for mods: `prompt` and `system` take blocks of text, and `cache: true` on a block caches the request up to it
- Added workflow agents to the `agent.spawn` mod hook, with their run and index, so a mod can refuse them
- \[Claude Tag\] Added an Edit button to the Allowed domains card on a channel’s Configure page, so Enterprise admins can open the access bundle that sets the channel’s domains
- \[Code Review\] Added the period’s total with its change from the previous period, and a breakdown by repository, to the PRs reviewed chart in Code Review analytics

**Changed**

- Changed local (stdio) MCP server connections to negotiate protocol version 2026-07-28 by default on every install, including Bedrock, Vertex and Foundry; `MCP_PROTOCOL_NEGOTIATION=legacy` opts out
- Changed `claude plugin test`: a failed `expect` inside a hook the test registered, or a stub answer the engine refuses, now fails the test instead of passing silently
- Changed usage limit messages to write claude.ai settings links with https:// so terminals and apps can make them clickable
- Changed scheduled and Run now routine runs to publish a new artifact only you can see without asking for approval; artifacts that request connectors or other access still ask
- Changed agent names to allow at most 256 characters: a longer one is rejected, and a skill’s or a plugin file’s `name` longer than that is ignored
- \[Claude Tag\] Changed the first message of a Slack thread continued with `!fork` to a card showing where it came from, the request, and who asked, with a link to the original thread
- \[Claude Tag\] Changed the organization-wide and default spend limit boxes on Claude Tag’s spend limits page in admin settings to save only when you press Save or Enter, not when you click away

Show 13 improvements

- Improved startup of `claude -p` and SDK sessions: the first turn no longer waits for HTTP and SSE MCP servers to answer `resources/list`
- Improved rendering speed of long bulleted or numbered replies: they stream, resize and re-open in the transcript (ctrl+o) much faster
- Improved Ctrl+C draft recovery: a cleared prompt now stays reachable with Up after a slash command or a sent message
- Improved hook output handling: `<system-reminder>` tags written in a hook’s output are escaped before they reach Claude
- Improved tool input handling: Grep accepts `file_path` for `path`, and Write, WebFetch and Read ignore a few stray parameters instead of failing the call
- Improved the steps shown when a marketplace declared in a settings file has a name that looks like an official Anthropic marketplace
- Improved sandbox auto-allow: with strict sandbox mode set in user, managed or —settings settings, an interpreter command with an env var prefix like `FOO=bar python3 app.py` runs unprompted
- Improved the Artifact tool’s listing: Claude now sees how many published artifacts you have and can list up to 200 at once instead of 50
- Improved cloud sessions after a restart: Claude is now told which stopped background agents it can resume by id
- Improved the Claude in Chrome message in claude.ai cloud sessions when the browser can’t be reached: Claude is now told it may continue with alternatives if the user prefers
- Improved the /focus tip: it now invites you to try focus view mid-turn and shows how to switch back
- Improved startup with local (stdio) MCP servers that ignore the newer protocol check: after one slow connect they are remembered for 7 days and connected the older way without the wait
- \[Claude Tag\] Improved `@Claude !status` in a channel to say when Claude has stopped reading its untagged messages, why, and that an @-mention starts it reading again

Show 64 bug fixes

- Fixed subagent definitions with `permissionMode: auto` entering auto mode when auto mode is unavailable (disabled by settings, circuit breaker, or a model that doesn’t support it)
- Fixed sandboxed commands being able to read the staged file copies of `/ultrareview` uploads under `~/.claude/seed-admin`
- Fixed a managed sandbox read-deny path (and user ones beside it) that appears or re-points mid-session not dropping project grants inside it or ending credential injection from files it covers
- Fixed a notebook or PDF read on macOS and Windows being able to return a file outside what was approved, through a link swapped in mid-read
- Fixed a tampered on-disk cache of server-managed settings being able to switch off or unseat the built-in policy plugin while the settings fetch failed
- Fixed `rm -rf` on the 8.3 short name or another alternate Windows spelling of the home folder or a drive not being treated as removing it
- Security: Fixed PreToolUse hook approvals and auto mode bypassing the permission prompt for file reads from network (UNC) paths
- Fixed a skill’s or slash command’s `allowed-tools` rule coming back in a later turn when you leave auto mode or plan mode partway through that turn
- Fixed `NO_PROXY` being ignored for Claude Code’s own API requests (sign-in, policy, feedback, artifacts) when `HTTPS_PROXY` is set
- Fixed an MCP tool with a name longer than 128 characters making every request fail; that tool is now left out and an MCP error names it
- Fixed `claude plugin` commands such as `marketplace add` and `install` running before an organization’s managed settings had loaded on a first run
- Fixed one-shot `claude -p` and Agent SDK runs stopping a background command 5 seconds after the final result, and one-shot `claude -p` runs dropping a scheduled wakeup; both are now waited for
- Fixed plan mode not being restored when resuming a session from the `claude --resume` session picker or with `/resume`
- Fixed saved scheduled tasks created after `/resume`, `/branch` or `/clear` never firing, and saved tasks ignoring later creates and deletes after two writes to the tasks file milliseconds apart
- Fixed a background session’s `/loop` silently stopping when the session’s process restarted (for example after a crash), because its pending wakeup was lost
- Fixed Grep and Glob reporting no matches when the file or folder they were given could not be read; Claude now retries once or tells you
- Fixed the Read tool returning only the first entry, with no error, when a PDF’s `pages` was a list such as “6,9,15”; it now returns an error saying to read each page or range separately
- Fixed @-mentioned text files over 256KB being left out silently: Claude is now told the file’s size and to read it in portions
- Fixed the usage limit alert repeating once per background agent when agents failed on a limit that had already stopped the main conversation
- Fixed Remote Control viewers seeing an empty subagent pane for background subagents in sessions hosted by the desktop app or an IDE
- Fixed cross-session delivery notices showing two sessions with similar names as one recipient, and the expiry notice blaming the desktop app when a terminal session let the message lapse
- Fixed Send now in the desktop app ending the subagent a turn was waiting on when another message was already queued
- Fixed `/bug`, `/share` and `/feedback <text>` starting over after Ctrl+O or Ctrl+Z while a report was being sent, and closing as cancelled after it had been sent
- Fixed `/remote-env` replacing your saved default environment when you pressed Enter right away: the list now opens on your default, and no row has a check mark when no default is in effect
- Fixed some pasted text reaching Claude as typed text when several pastes overlapped in one prompt
- Fixed vim mode leaving the cursor past the end of a line, j/k losing their column on shorter lines, and `f`/`t`/`F`/`T`/`;`/`,` jumping to, or deleting up to, a match on another line of the prompt
- Fixed `/add-dir` path box letting Shift+Enter or a paste add a line break, and treating fast-typed “tab”, “up” or “down” as those keys
- Fixed fast typing, input-method text and decomposed accents being dropped while a prompt footer row was selected, and `!` leaving the row selected
- Fixed fullscreen mode sending a full-screen clear on every window resize and Ctrl+L when iTerm2 is detected, which may be what filled iTerm2’s scrollback with stale pages
- Fixed a spurious “could not be examined” note for @-words that name no file when a Read deny rule is set and the working directory is under a symlink
- Fixed “instruction file not loaded” lines going stale or missing after `/cd` or a permission change, and added a transcript line when a nested one isn’t loaded
- Fixed a compaction summary that repeated `/name` letting Claude invoke a skill that is reserved for the user
- Fixed Write, Edit, NotebookEdit and LSP rows, and single Read, Grep and Glob rows, hiding why a mod denied the call: the row now shows the reason
- Fixed a cloud session showing a turn that never ended when its worker was stopped just as the turn finished
- Fixed cloud sessions with a large transcript sometimes asking for a permission again after it was approved
- Fixed scheduled tasks and other queued notifications being lost in cloud sessions when a message was retried or edited while Claude was reading them
- Fixed cloud sessions forgetting the thinking setting chosen in the client when the session’s container restarted
- Fixed Cowork cloud sessions saying a proxy blocked artifacts when Anthropic couldn’t confirm the organization’s settings
- Fixed plugins whose hooks module makes many `$.state` calls through one const taking minutes to load or validate
- Fixed `claude plugin validate` listing a matcher or state value for a hooks module that the engine reads from elsewhere
- Fixed `claude plugin validate` listing a `$.state` value read through a top-level `var` that was declared again or reassigned; such a module is now refused
- Fixed a plugin’s served `$` method restarting the hook origin, which could run a guard hook with a `.catch` above it again without end
- Fixed plugin interface calls made while the plugin hooks worker restarts running without the hooks other plugins put on them
- Fixed a mod’s `config.set`, `state.set`, `env.set` or `agent.spawn` hook that denies after calling `next(e)` being answered as a refusal: the hook is now reported as failed, by name
- Fixed `/theme`, the `/config` Theme menu and the first-run theme step saving a theme before a plugin’s `config.set` hook was asked
- Fixed a plugin’s `tool.check` hook answering allow running a tool that requires your answer (a question, a plan approval) without showing its dialog
- Fixed a mod’s start-up prompt, command or subagent being queued a second time when the hooks worker was replaced
- Fixed a mod’s hook that called `next(e)` and then failed while the turn was interrupted letting the call through; the call is now rejected
- Fixed a plugin’s prompt drop or setting deny being ignored when its reason was longer than 4,096 characters
- Fixed an organization’s plugin being unloaded on its own reload, or after another plugin crashed, when it returned a `$` name that a user-installed mod had added; the mod is now unloaded instead
- Fixed tool calls made while the plugin hooks worker restarts being answered without the plugins’ permission hooks
- Fixed plugin `tool.call` hooks seeing some tool calls before misnamed parameters were repaired; a hook now sees the arguments the tool will run with
- Fixed a mod’s guard hook with a `.catch` being skipped silently for calls another mod’s hook makes beneath the guard’s own `$` call; its `.catch` is now asked
- \[Cloud sessions\] Fixed routine runs occasionally staying listed as running for hours after they had finished
- \[Cloud sessions\] Fixed editing or duplicating a routine turning off its push notifications when the routine had no saved notification setting
- \[Cloud sessions\] Fixed SVG, HEIC, TIFF and other less common image files failing to attach; they now attach as regular files
- \[Cloud sessions\] Fixed approval prompts offering “Always allow” for connector tools that an organization set to require approval; the choice had no effect
- \[Remote Control\] Fixed the first message of a new Remote Control session started from claude.ai/code accepting only images; it now accepts PDFs and other files like later messages
- \[Claude Tag\] Fixed replies sent in a Slack thread while Claude was still on its first request there being held until that request finished, or missed when sent seconds apart
- \[Claude Tag\] Fixed Slack threads woken only by GitHub pull request activity or a routine staying on their original model after an admin changed the channel or workspace default model
- \[Claude Tag\] Fixed Claude sometimes posting a spend limit notice in Slack when the real cause was that your organization had run out of usage credits
- \[Claude Tag\] Fixed a session hanging until interrupted when a permission prompt that can’t be answered from Slack was denied automatically
- \[Code Review\] Fixed a queued review failing when the pull request moved to a new base branch and the old one was deleted; the commit is now re-queued for review
- \[Code Review\] Fixed reviews ignoring a CLAUDE.md’s rules when the pull request edits that file; reviews now use its version from the base branch

[​](#2-1-291)

2.1.291

October 6, 2026

- Fixed a regression in 2.1.290 where cloud sessions could drop answers to permission prompts
- Fixed a regression in 2.1.288 where the last messages of a session could be lost when quitting

[​](#2-1-290)

2.1.290

October 5, 2026

**Added**

- Added `serverToolUses` to the result of a mod’s `turn.step` hook: the tool calls the API ran itself (the advisor), each with its id, name, input, start and end
- Added `agentId` to the `tool.check` event of plugin hooks, so a hook can tell a subagent’s permission check from the main session’s
- Added `ceiling` to the question and verdict a mod’s `tool.check` hook reads, naming the approval an organization requires for a tool
- Added `ThemeKey` and `Color` types to the plugin hooks typings, so an editor lists the theme colors a mod’s drawing can name
- Added to `claude plugin validate`: each hook a mod registers at a gating site is listed with whether it has a `.catch` (`gatingHooks` under `--json`)
- Added a Deny button to the Claude apps gateway’s sign-in approval page: it ends the pending sign-in, so the waiting terminal stops within seconds
- Added `claude attach <name>` and `claude logs <name>`: part of a session name works in place of the id
- Added `/claude-api managed-agents-onboard <url>` to set up the Managed Agents pattern a page describes as `ant apply` files
- Added `/claude-api managed-agents-onboard <quickstart-name>` to build a Console quickstart template, such as `deep-researcher`, with the `ant` CLI
- Added a warning when a managed settings file is a link to a file outside the managed settings folder
- Added a /status and doctor warning when managed settings ignore user-configured sandbox allowRead paths or allowed domains
- \[VSCode\] Added a screen reader announcement, “Message queued.”, when you send a message while Claude is working
- \[VSCode\] Added a way to review and run a plugin marketplace’s install or update command from the Manage plugins dialog
- \[Claude Tag\] Added fast mode in Slack: mention Claude with `!fast` to switch a thread to fast mode, moving it to Opus if needed, and `!fast off` to switch back; replies show (fast) while it’s on
- \[Claude Tag\] Added the optional Path prefixes field when creating a custom connection in an access bundle, so its allow rule can cover only those paths instead of the whole host

**Changed**

- Changed `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` to also skip the startup connection warm-up
- Changed Claude in Chrome so that a project’s settings files can no longer turn it on; use `--chrome`, `/chrome` or your user settings
- Changed the Bash tool to ask for permission before running `pyright`, which is no longer treated as a read-only command
- Changed what a mod’s `$.process.spawn` rejects with when another mod denies it after the child ran: it now says the call ran and a plugin withheld its result
- Changed the background daemon’s log to write a multi-line message as one JSON-quoted line
- Changed skills and custom commands to refuse a `!` shell command that contains raw control characters other than tab and newline, with a message that shows where they are
- Changed `/artifacts`: opening an artifact in your browser now closes the list
- Changed Bash permission checks so that more forms of the `ps` command ask for approval instead of running without asking
- Changed plugin hooks so long text is clipped and logged instead of being refused or dropped silently
- Changed background sessions whose scheduled task is gone: they now move to Completed about 20 seconds later and can be updated or shut down when idle
- Changed the “Press ← again” confirm on a just-cleared prompt: a second ← no longer has to wait a second before it switches, and holding ← down now switches too
- Changed the errors shown when the `/ultrareview` upload fails at a git step: they name the step and what to try, and no longer repeat git’s own error text
- Changed `/code-review` at medium effort to also report cleanup and CLAUDE.md conventions findings on models without tuned review settings, including Opus 5.5 and Sonnet 5.5
- Changed an in-process teammate’s `agent_id` in Agent results to its agent ID (its `name@team` address stays in `teammate_id`); TeammateIdle hooks no longer fire from its subagents or forks
- Changed background sessions waiting on a scheduled wakeup (`/loop`): they are now left running through updates and low memory, where being restarted or shut down could silently lose the wakeup
- Changed `/model`, `/effort` and `/rename` sent from `claude agents` to a busy background session to apply right away, without a confirmation, instead of when the turn ends
- Changed the Claude apps gateway’s minimum supported PostgreSQL version from 14 to 11
- Changed the interactive session’s WebSearch budget to refill over time (100 calls/hour; `CLAUDE_CODE_WEB_SEARCH_REFILLS_PER_HOUR` sets the rate, 0 turns it off) instead of ending after 200 calls
- Changed `CLAUDE_CODE_DISABLE_ATTACHMENTS` so a repository’s `.claude/settings.json` or `.claude/settings.local.json` can no longer set it; shell, user and managed settings still can
- Changed `claude plugin update` on a plugin loaded from a directory to print just its reason, without the “Failed to update plugin” prefix, as for built-in plugins
- Changed the built-in `gh api` in cloud sessions: a host other than github.com set in `GH_HOST` or `GH_REPO` is now refused (use `--hostname` or a full URL), and stderr notes requests to other hosts
- Changed the `claude-api` skill’s Managed Agents examples to turn off the web tools unless the agent needs them and to use the `auto` permission policy
- Self-hosted runners: Changed `claude --environment <id>` to create its session through the current Sessions API; printed and JSON session ids keep their session\_… form
- \[VSCode\] Changed message timestamps to show by default (turn them off with the Claude Code: Show Message Timestamps setting)
- \[Claude Tag\] Changed the channel instructions limit to 8,192 characters instead of bytes, so non-English text gets the same room, and added a character count beside Save on the Configure page

Show 19 improvements

- Improved MCP startup behind a network proxy: a server the proxy blocks (HTTP 403) is no longer retried three times
- Improved permission prompts from background agents to show the Ctrl+X Ctrl+K shortcut that stops all background agents
- Improved the built-in `plugin-authoring` skill: Claude now gives the one command another person runs to install a mod you made, and writes it in a README’s install section
- Improved the reply to `/plugin` in the desktop app’s Code tab: it now says where to install and manage plugins there
- Improved the Bash changed-files view: when a chained command includes git merge, pull or checkout, it lists the files without full diffs
- Improved the Claude apps gateway’s log when an upstream’s cloud credentials or connection fail: the warning now ends with the underlying cause
- Improved the error shown when a cloud session is started without a claude.ai sign-in: it now names `claude auth login` and /login and no longer blames API-key authentication
- Improved the Read tool’s message for binary files: it now points Claude to a skill or a shell command that can read the format
- Improved the error shown when a git config file stops the `/ultrareview` upload: it is about half as long and says what kind of file is the problem
- Improved the errors shown when the `/ultrareview` upload refuses a checkout: each known cause now has its own message, with a way to fix it
- Improved the Claude apps gateway to log a warning during the last 30 days before the certificate it presents to the identity provider expires
- Improved Claude in Chrome: a `browser_batch` call now gets 90 seconds, up from 60, before it is reported as timed out
- Improved the Claude apps gateway’s browser sign-in pages: brand fonts, centered layout, and dark mode
- Improved responsiveness while resuming large sessions: timers, input and rendering keep running while the transcript loads
- Improved the / and @ suggestion lists: the selected row now starts with a ❯ pointer, so you can see it without color
- \[VSCode\] Improved Continue After Reload: tabs reopened after VS Code restarts its extensions now also finish a step the restart interrupted
- \[VSCode\] Improved file pills in messages: hovering one now shows the file’s path from the project folder, so same-named files can be told apart
- \[Claude Tag\] Improved Claude’s notice in your direct messages when your own Claude plan’s usage limit is reached: it shows within seconds and says when the limit resets
- \[Claude Tag\] Improved the earlier Claude in Slack app’s reply when it can’t start a session: it now says what failed and who can fix it, in full only once per thread

Show 131 bug fixes

- Fixed requests failing behind proxies and gateways that reject one of Claude Code’s beta headers with a status other than 400, or together with a second beta
- Fixed long sessions with hundreds of images getting stuck on “Request rejected as unprocessable by the model” errors
- Fixed a turn ending at once when the API’s output content filter stopped a reply while Claude was still thinking; the request is now retried once before the error is shown
- Fixed resumed subagents and teammates losing their earlier thinking and prompt cache after receiving a message mid-run
- Fixed WebFetch silently dropping page text past 100,000 characters; it now says how much was unread and takes an `offset` to read on
- Fixed a crash (“Maximum call stack size exceeded”) when a response nested lists or quotes thousands of levels deep
- Fixed `/rewind` not listing a prompt sent while Claude was still working
- Fixed scheduled tasks (`/loop` with an interval, reminders) silently not coming back on resume once the conversation was compacted; covers compactions made from this version on
- Fixed scheduled tasks set in the foreground never firing after a ← or `/background` hand-off, and recurring ones firing an extra run on every resume, respawn or fork
- Fixed headless `--json-schema` runs exiting non-zero with `is_error: true` on a `success` result when the connection dropped after the structured output was already delivered
- Fixed plan mode letting the auto mode classifier approve non-read-only connector tools that carry a server-pushed ask policy
- Fixed a project `CLAUDE.md`, rule or `AGENTS.md` symlinked outside the working directories loading under `permissions.blockReadsOutsideWorkingDirectories` or a `Read` deny rule
- Fixed URL allow and deny patterns with a wildcard inside an `xn--` host label matching differently from one process to the next
- Fixed an MCP server provided by your organization being relisted as your own after signing in or reconnecting, including from a late result in headless and SDK sessions
- Fixed `/ultrareview` dropping uncommitted changes without a warning on Windows when `git stash create` failed, and refusing them after a `git add -N` file was deleted or moved
- Fixed the `plansDirectory` setting’s project-root check for paths that contain a backslash on macOS and Linux
- Fixed replies in very long Remote Control and cloud sessions that could appear a block at a time instead of streaming in
- Fixed the background daemon’s log passing terminal control characters to the screen under `claude daemon run` and `claude daemon logs`; they now show as `\uXXXX` escapes
- Self-hosted runner: Fixed a crafted, very long line of a session’s error output freezing the runner for several seconds
- Fixed a plugin hook with a `.catch` being unloaded, and its `.catch` skipped, when the hook kept the hooks worker busy on a prompt or tool call
- Fixed a mod’s `turn.step` result listing a tool call that a mid-response model fallback had discarded
- Fixed a Cowork cloud session’s reply sometimes never finishing when its container restarted just after Claude sent a message or a file
- Fixed `claude plugin validate` and plugin loading refusing a hooks module that destructures an option named like one of its top-level functions
- Fixed `/ultrareview` failing to upload uncommitted changes when `core.safecrlf=true` is set in git’s configuration
- Fixed the effort level changing when a flagged message is retried on a fallback model that has a different level saved in settings
- Windows: Fixed multi-line `!` shell blocks in skills and commands failing when the file is saved with CRLF line endings
- Fixed Claude Code hanging until killed when a `/permissions` tab was clicked while searching in fullscreen mode
- Fixed conversation compaction sometimes failing with a “null is not an object” error
- Fixed plugin hooks reading an empty `answer` on `turn.complete` for a subagent that hands its report back in auto mode
- Fixed a mod being unloaded without a message when a refresh followed its failed reload; its failure line now says the version loaded before is unloaded
- Fixed a mod’s `prompt.submit` hook that drops a prompt after calling `next(e)` being ignored silently: the hook is now reported as failed, by name
- Fixed a mod’s pane or band being redrawn without end when it followed its end over a tree that changed height at every drawing
- Fixed an image read on macOS and Windows being able to return a file outside what was approved, through a link swapped in mid-read
- Fixed a case where a user-installed mod could get an organization’s plugin unloaded; the mod is now the one unloaded
- Fixed `disableClaudeAiConnectors` and `allowedMcpServers` URL rules not being applied to some MCP entries declared in `.mcp.json`, plugins or agents
- Fixed a mod’s inline pane being redrawn without end when its tree changed height at every drawing
- Fixed an `@`-mention under the read block or `--restricted` being able to read a file outside the working directories through a link changed mid-read
- Fixed Esc in the agents view confirming “Press enter again to restart this session — it isn’t responding”; Esc now just reopens the session
- Fixed agent view losing a background session’s `/loop` run count, countdown and live status line after the session enters a worktree that it creates
- Fixed `claude agents` sessions in manual permission mode asking for approval to read an image pasted into a reply or a new agent’s prompt
- Fixed a deny or ask rule missing a command or path whose name came from a variable set as a prefix on `declare`, `typeset`, `export` or `readonly`
- Fixed Read deny rules not applying to image paths pasted or dragged into the prompt, or to file names listed for an @-mentioned folder
- Fixed a case where a user-installed mod could make an organization’s guard skip its check; such a mod is now unloaded
- Fixed plugin hooks stalling each redraw when a mod draws a long multi-line text holding non-Latin characters
- Fixed repeated Ctrl+X in the agents view deleting the whole next section after the bottom session of a section was deleted
- Fixed You should know writing its notes in English regardless of the `language` setting
- Fixed a freeze after sending some very long messages
- Fixed a slowdown when expanding the transcript (ctrl+o) or resizing over large tool output that contains non-ASCII characters such as arrows, dashes or box-drawing
- Fixed `claude respawn` re-sending an earlier message to a backgrounded session that has no saved transcript instead of starting it with an empty conversation
- Fixed Esc after an `n:` or Ctrl+F search in the agents view moving focus to a section header, where Ctrl+X twice would delete every session in the section
- Fixed `claude agents` saving a slash command it could not deliver to a stopped session and then running it by itself the next time that session restarted
- Fixed `/ultrareview` uploading uncommitted changes unfiltered for files under a git filter driver named `unset` or `unspecified`; the upload now stops and asks you to rename the driver
- Fixed auto mode denials suggesting a permission rule that would skip the classifier for a whole tool or that Claude Code would ignore
- Fixed `claude --teleport` and `/teleport` deleting the files in a folder that had replaced a tracked file of the same name when you chose to stash: the stash is now refused, and says why
- Fixed Esc confirming agent view’s “Press enter again to restart this session fresh” prompt
- Fixed agent view’s `/loop` run count freezing and its countdown disappearing after `/clear`; the count now restarts with the new conversation
- Fixed `--channels` permission relay: a reply ID that repeats within a session is now ignored instead of approving a different prompt
- Fixed `/chrome` “Reconnect extension” not restoring browser tools after a failed Chrome connection, and added an explanation when it can’t (anthropics/claude-code#98135)
- Fixed mods staying off for people who reach Claude through a gateway (`ANTHROPIC_BASE_URL` with `ANTHROPIC_AUTH_TOKEN`) and have no Anthropic account
- Fixed replies sent from `claude agents` just after a background session crashed being refused after 2 seconds: they are now retried for up to 12 seconds while the session restarts
- Fixed slash commands and answers to a multiple-choice question that `claude agents` could not deliver to a running session being saved and sent by themselves the next time it was restarted
- Fixed sandboxed commands that pipe a heredoc into another command (`cat <<EOF | python3`) asking for approval on every run
- Fixed `claude agents` failing with “Couldn’t restart the background service” and background sessions stopping after a Homebrew upgrade (takes effect from the upgrade after this one)
- Fixed agent view’s “restart this session fresh” re-sending an earlier message from the session instead of starting with an empty conversation
- Fixed Bash permission checks auto-approving some read-only commands (such as `rg` or `git grep`) whose arguments the shell would still expand as wildcards; these now prompt for approval
- Fixed `claude plugin test` refusing to run after an upgrade because of an out-of-date saved setting
- Fixed Bash permission checks auto-approving certain commands whose variable names zsh reads differently from bash; these now prompt for approval
- Fixed a short form of a `git clone` option keeping the sandbox exemption from a git pattern such as `git *` in `sandbox.excludedCommands`; it is now treated like the long form
- Fixed the first feature-flag request of a session ignoring a proxy or API endpoint set in a project’s settings
- Fixed `/ultrareview` of a local branch silently leaving uncommitted work out of the upload in a repository that keeps its branches outside `.git` (git 2.54+); it now refuses with an explanation
- Fixed cloud sessions staying asleep after a container restart lost a pending `/loop` wakeup or scheduled task; Claude is now told and can schedule it again
- Fixed the Claude apps gateway’s retention sweep deleting a returning developer’s identity row refreshed at the same moment, on PostgreSQL versions without the November 2025 fixes
- Fixed sandboxed Monitor tool commands skipping the permission prompt under sandbox auto-allow; they now follow your permission rules
- Fixed the Claude apps gateway failing to start when the certificate it presents to the identity provider has an empty subject
- Fixed the Claude apps gateway exiting with a bare “Invalid URL” when `store.postgres_url` can’t be parsed; the error now names the setting and says what the URL may hold
- Fixed background agents failing with “Agent stalled” and Workflow tool subagents restarting from their prompt when a Mac woke from sleep
- Fixed slow or failed startup since 2.1.285 under SDK hosts such as the VS Code extension when managed settings deny reads of many paths on a slow filesystem (notably Windows drives under WSL)
- Fixed a response interrupted by computer sleep being treated as a stalled stream on Bedrock, Vertex, Foundry, and custom gateways
- Fixed a freeze before the first request and in the `/sandbox` Config tab on Linux and WSL when a sandbox read rule such as `~/**/.env` covers a large folder
- Fixed skills not being found when asked for by the name in SKILL.md when their folder has a different name (for example a non-English name): the skill listing now shows both names
- Fixed a plan written in plan mode being lost when a cloud session’s container restarted before the plan was presented
- Fixed the Bash tool occasionally losing shell aliases, functions and plugin PATH entries for a whole session when its first command ran seconds after startup on a new config directory
- Fixed unbounded memory use when an HTTP MCP server sends a very large response
- Fixed artifact operations failing in a Claude Code run started from inside a cloud session (for example `claude -p` run from the Bash tool)
- Fixed files sent from remote sessions sometimes being refused as “not the one approved” when four or more were sent at once
- Fixed plan mode not being restored when resuming a session with `--continue` or `--resume <session-id>` in the terminal
- Fixed a marketplace named after another GitHub marketplace’s download folder stopping that marketplace from downloading
- Fixed automatic compaction giving up with “Prompt is too long” when a Mac went to sleep while it was running
- Fixed the rewind menu (Esc Esc / `/rewind`) freezing for hundreds of milliseconds per keypress when the conversation contains a very large pasted stack trace or source file
- Fixed a subdirectory’s AGENTS.md not being attached when a file under it is @-mentioned
- Fixed self-hosted runner sessions resumed after a stopped runner failing with “missing but already registered worktree” when the sessions folder is a relative symlink
- Fixed a freeze when the secret scan or a permission prompt met long token-like text
- Fixed Bash permission checks not applying Read deny rules or the outside-directory read block to a wildcard in some option values of read-only commands
- Fixed `CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS=5m` being read as 5 ms and cancelling remote dialogs at once; values with a unit suffix now fall back to `dialogExpiry`
- Fixed a stall when an MCP server’s tool listing contains very long runs of combining characters
- Fixed two pastes that overlap in one prompt being sent to the model partly as typed text instead of as one pasted block
- Fixed Claude in Chrome’s browser picker showing a message meant for Claude when the chosen browser is no longer connected, and the VS Code dialog’s list going stale after a switch
- Fixed background subagents losing write and Bash access in their worktree after the main session enters or exits a different worktree
- Fixed background commands, the agents view and daemon workers sending telemetry and a feature-flag request to Anthropic behind a Claude apps gateway when no managed settings on the machine force gateway login
- Fixed `--restricted` (and `CLAUDE_CODE_RESTRICTED=1`) sessions opening the cross-session messaging socket
- Fixed sessions moved to the background while idle reopening as “no saved transcript” after a restart or idle cleanup; they now resume their conversation
- Fixed background workers honoring `--allow-dangerously-skip-permissions` on respawn without the bypass-permissions disclaimer having been accepted
- Fixed Claude replying in an endless loop when a plugin’s async Stop hook passes an unquoted script path under a folder with a space, such as Application Support
- Fixed a freeze of several seconds when secret masking met very long unbroken text
- Fixed some permission rules and safety checks not being applied to a tool call after a PreToolUse hook rewrote its input
- Fixed first launch asking to pick a login method again after `claude auth login` or with a credentials file already in the config directory
- Fixed file names containing line breaks being displayed incorrectly in file tool errors and permission prompts
- Fixed a large paste expanded in place being sent to the model as typed text after the next keystroke when it held accents stored as separate characters, as macOS file names do
- Fixed macOS `/login` reporting success when the keychain refused the new login and kept an old one it could not remove
- Fixed SDK hosts using `--include-partial-messages` seeing a reply stay open after the turn ended when its stream was cut, interrupted or fell back to non-streaming
- Fixed sandboxed Bash commands on Linux running `ConfigChange` hooks and reloading settings mid-command when `.claude/settings.json` or `.claude/settings.local.json` does not exist
- Fixed errors reading “Premature close” instead of naming the missing program when a tool Claude Code runs, such as git or gh, is not installed (macOS, Linux)
- Fixed `/loop` and other recurring session-only scheduled tasks running an extra time after a sandboxed Bash command on Linux or after `.claude/scheduled_tasks.json` was deleted
- Fixed edits to the file a symlinked settings file points at running without the settings-file permission question
- \[VSCode\] Fixed a blank chat you never typed into keeping a background Claude process running after you open a saved conversation in its place
- \[VSCode\] Fixed settings dialogs blaming a timeout when Claude Code stopped unexpectedly during a save
- \[VSCode\] Fixed the branch switch dialog offering to switch when it could not check for uncommitted changes
- \[VSCode\] Fixed a permission prompt that arrived behind an open dialog taking keyboard focus, so a key pressed in the dialog could answer it
- \[VSCode\] Fixed sign-in and new sessions giving no clear reason when Claude Code cannot find or start its program
- \[VSCode\] Fixed the agent map showing a nested sub-agent with “Tool calls (0)” and placing the agents it starts under the main agent
- \[Cloud sessions\] Fixed turning off prompt suggestions through a cloud environment’s environment variables having no effect in new cloud sessions
- \[Cloud sessions\] Fixed the working indicator in a cloud session spinning on for several seconds after Claude’s reply had finished; it now stops with the reply
- \[Cloud sessions\] Fixed History on a never-run routine’s page still saying “No runs yet” after you pressed Run now; it now shows the new run
- \[Cloud sessions\] Fixed an unarchived cloud session looking as if Claude were still working until you sent another message
- \[Remote Control\] Fixed a computer that just started Remote Control taking up to a minute to appear in the Remote Control menu of a new session; it now appears within seconds
- \[Claude Tag\] Fixed members with the Claude Tag Admin permission getting “Couldn’t load memory files” on the Activity page’s Memory tab; they can now read workspace and channel memory
- \[Claude Tag\] Fixed a workspace guest’s Confirm on a Claude settings card in Slack removing its buttons for everyone; only the guest sees the refusal, and members can still confirm or cancel
- \[Claude Tag\] Fixed scheduled routines in Slack channels running on a model other than the channel’s default; each run that starts a new session now uses the current default model
- \[Claude Tag\] Fixed GitHub repositories in an access bundle attached by a channel-name rule being refused in the channels the rule covers; Claude can now add, list and clone them there
- \[Code Review\] Fixed blocking review comments sometimes opening with a “nit” label that contradicted their severity
- \[Code Review\] Fixed tips to comment “@claude review” being posted on fork and Manual-mode pull requests in organizations that have turned Code Review off

[​](#2-1-289)

2.1.289

October 3, 2026

**Added**

- Added `agent.spawn` for teammates, one agent id across plugin hook events, and idle and waiting states in `$.agent.list()`

**Changed**

- \[VSCode\] Reverted a 2.1.288 change to `claude auth status` that may have made sign-outs more frequent

**Improved**

- Improved how quickly large files open in a plugin code pane by laying the highlighted view out once at its final width
- Improved the line a mod’s author sees when its band or pane fails to draw: it names the mod and says nothing was drawn

Show 23 bug fixes

- Fixed a deny or ask rule on a nested part of a compound shell command not holding over a user-installed mod’s approval on managed machines
- Fixed the terminal freezing on short code blocks with many unclosed `<script>` tags or deeply nested `${` substitutions
- Fixed `Read` deny rules not applying to files @-mentioned, changed, or selected in the IDE through a symlink
- Fixed `plugin list`, `plugin eval` and `plugin update` showing a stale copy of a plugin installed from a local folder marketplace, and hot reload for a symlinked `--plugin-dir`
- Fixed installed mods not loading in the first session after an upgrade
- Fixed a plugin’s rows above the prompt showing a stale row while the Background tasks dialog was open in fullscreen
- Fixed plugin panes drawing nothing when a link used a localhost address, an `@` in its path, an uppercase host or a `file:` path
- Fixed a user-installed plugin being able to rewrite the descriptions of an organization-managed MCP server’s sign-in tools
- Fixed a freeze or forced quit at launch when a plugin drew a Box with a border style the terminal does not know
- Fixed supervised and background sessions ending when a plugin’s on-screen handler threw asynchronously
- Fixed sessions ending with an interface error when a plugin region with no height kept growing
- Fixed Bash deny and ask rules missing a command behind an environment variable prefix with an expanded value (e.g. `TZ="$HOME" rm -rf build`) when the sandbox auto-allows commands
- Fixed a Bash deny or ask rule being skipped under sandbox auto-allow when a bare variable assignment came before the command
- Fixed `claude plugin validate` skipping the plugin when the folder also holds a marketplace manifest
- Fixed sessions ending with “unrecoverable interface error” when a value a mod’s `ui.render` hook wrote made a row throw while drawn; the engine now draws its own row instead
- Fixed text with a tab, a stray escape and a C1 control, or a short text with a tab and CRLF line endings, drawing over the rows below it
- Fixed right-aligned content in a mod’s pane or band drawing under the close mark or `[-]`, which now also keep one column in from the terminal’s edge
- Fixed a mod’s `Client` that fails while drawn taking down everything the mod drew around it; it now fails alone and raises `ui.fault`
- Fixed `claude plugin validate` failing an Anthropic marketplace’s own plugin and listing a clean `plugin.json` in `--json`
- Fixed a mod’s band that fails to draw briefly telling the cards under it to step aside
- Fixed a failed plugin component showing `Error` or nothing as its reason when the failure carried no message
- Fixed published artifact pages freezing or crashing the reader’s browser tab on short code blocks with many unclosed `<script>` tags
- Fixed a mod’s Client region staying failed for the whole session after the terminal threw while drawing it

[​](#2-1-288)

2.1.288

October 2, 2026

**Added**

- Added `$.ui.selection()` for mods: returns the text you last selected in fullscreen mode and, when the selection lies within one transcript row, that row
- Added a built-in `gh api` to cloud sessions whose image has no GitHub CLI, and fixed the built-in sending control characters from file names, jq filters or GitHub errors to the terminal
- Added recovery for a prompt cleared with Ctrl+C: pressing Up on the empty prompt brings the draft back, including pasted text and images
- Added a re-authenticate prompt when an MCP server asks for more OAuth scope during a tool call
- Added `--max-findings <n>|all` to /code-review to report more or fewer findings than the usual limit; the choice is reused until you pass `--max-findings default`
- Added Ctrl+F to find a session by name and Alt+↑/↓ to jump between groups in the agents view; both, and rename, can be rebound in keybindings.json
- Added a screen reader mode announcement of the new permission mode when you approve a plan, including with Shift+Tab

**Changed**

- Changed the background command time limit to apply only in unattended sessions (`-p`, Agent SDK, CI, cloud); terminal, desktop app and VS Code sessions have no limit
- Changed the client-side auto mode classifier to ignore an `ANTHROPIC_DEFAULT_SONNET_MODEL` pin that names Claude Sonnet 5.5 or Opus 5.5 and use Claude Sonnet 5 instead
- Changed `claude project purge` to `claude purge`; the old name still works and prints a notice
- Changed the agents view `n:` filter (and Ctrl+F search) so Enter opens the session whose name matches best instead of the top row
- Changed `/autocompact` to save the auto-compact window per model, so each model keeps its own setting when you switch
- Changed MCP URL prompts from servers that can’t report when you’re done to wait for “I’m done, continue” before the tool call continues, so you can finish in the browser first

Show 12 improvements

- Improved auto mode: when a conversation grows too long for the client-side safety classifier to review, it is now compacted instead of prompting for, or failing, every tool call
- Improved screen reader mode: short announcements, such as a deleted word, now stay on screen until your next key press or until something above them on screen changes
- Improved screen reader mode: answered questions in question dialogs now say “answered” beside their box
- Improved the `/usage-credits` message shown to Team and Enterprise members whose organization has turned off usage credit requests
- Improved cloud sessions: a new conversation’s first turn no longer waits for a stdio MCP server whose config sets `alwaysLoad: false`
- Improved “You should know” notes to say “we”, “the main agent” or “you” depending on who was responsible for a decision
- Improved the error for an artifact database write refused at the database’s size limit: it now states the limit and what frees space
- Improved Bash permission prompts to give a shorter reason when part of a command can’t be checked before it runs
- Self-hosted runner: Improved the built-in `gh api`: a refused gh command now prints its `gh api` equivalent, `--paginate` follows every page of a repository’s lists, and a nested `claude` no longer removes it
- Improved Remote Control’s recovery from an expired server credential: sessions stay connected during renewal and are kept if it gives up after a server outage
- \[Claude Tag\] Improved Claude to also follow a related Slack thread in another channel that it only read, so updates there reach the conversation that depends on them
- \[Claude Tag\] Improved save errors on a channel’s Configure page: too-long channel instructions now say to shorten them, and a save refused for lost access no longer says to try again

Show 64 bug fixes

- Fixed mid-response API timeouts failing the turn: non-interactive sessions and subagents now continue from the partial response, and thinking-only responses are retried
- Fixed long conversations failing with “Prompt is too long” instead of auto-compacting when the last reply reported zero token usage
- Fixed `--resume` sometimes dropping files and other context that a compaction had just restored
- Fixed a resumed session sometimes not saving the last response of a turn, so that the next `--resume` showed the prompt unanswered
- Fixed resume occasionally loading a transcript cut short when the same session rewrote the file during the load
- Fixed resuming a conversation started on 2.1.286 or earlier dropping the model’s earlier thinking
- Fixed session titles, memory recall and prompt hooks failing on Mantle or behind gateways that reject structured outputs; added `CLAUDE_CODE_DISABLE_STRUCTURED_OUTPUTS` to turn structured outputs off
- Fixed auto mode denials pointing Claude at a Bash permission rule when the blocked tool was not Bash
- Fixed auto mode on Bedrock and Mantle switching to the local classifier for the rest of the session after a request to an older model, such as a WebFetch summary or a `sonnet` subagent
- Fixed cloud sessions that restarted on a newly picked model replying with that model after the server refused it
- Fixed Cowork cloud sessions staying marked as waiting for input after a WebFetch permission prompt for an unapproved URL went unanswered for five minutes
- Fixed prompt suggestions not appearing on a phone that joins a Cowork cloud session started on another device
- Fixed a mod’s button sometimes running a different button’s action when pressed on a view drawn before Claude Code restarted
- Fixed a plugin’s pane showing nothing when one `Code` element held a diff that does not parse; it now draws as plain code
- Fixed plugin LSP servers receiving literal `${user_config.*}` and `${CLAUDE_PLUGIN_ROOT}` placeholders in `initializationOptions` and `settings` instead of substituted values or manifest defaults
- Fixed a plugin’s `tool.call` hook making Bash fail and file searches read the wrong folder in subagents that run in a worktree
- Fixed `git-subdir` plugin installs failing, or caching an incomplete plugin, on older git (before 2.39, e.g. Ubuntu 22.04’s 2.34)
- Fixed plugins loaded with `--plugin-dir` not showing “Configure options” in `/plugin`
- Fixed background sessions ending when a plugin was reloaded or disabled while one of its timers or reads was still running
- Fixed sandboxed heredocs with an unquoted delimiter (`python3 <<EOF`) asking for approval on every run under sandbox auto-allow when the body holds only plain text and simple `$VAR` references
- Fixed Bash tool permission check to prompt before a `BASHPID` assignment whose value the shell would evaluate as arithmetic, instead of allowing it silently
- Fixed fullscreen sessions exiting with “unrecoverable interface error” when opening the background tasks dialog while a plugin or mod showed rows above the prompt
- Fixed Claude reporting a message to another session as delivered when that session held it: the notice now says it wasn’t delivered and names the session, and in SDK sessions Claude can now learn of it mid-turn
- Fixed OpenTelemetry `claude_code.tool.blocked_on_user` spans reporting `unknown` source or decision in `-p` and SDK sessions and for PreToolUse hook approvals
- Fixed permission asks that ended unanswered, in `-p` or on an interrupted turn, emitting no `tool_decision` event
- Fixed Edit and Retry in Cowork cloud sessions refusing a message sent before `/compact` even though its history was still saved
- Fixed unattended sessions (`CLAUDE_CODE_RETRY_WATCHDOG`) retrying for hours after a very long response stream failed; Claude Code now streams again, and gives up after three timeouts
- Fixed `/login` reporting “Login successful” when credentials could not be saved to secure storage; it now shows the failure, and offers a retry when the new login didn’t take effect (anthropics/claude-code#73861)
- Fixed a Stop during Bedrock credential lookup sometimes moving the session to a fallback model instead of ending the request
- Fixed a second `gcpAuthRefresh`/`awsAuthRefresh` browser sign-in opening when a laptop wakes from sleep while another Claude Code process is signing in
- Fixed agent teams: a plugin-defined agent spawned by name now runs with its own prompt, tools, disallowedTools and effort instead of the defaults
- Fixed headless (`-p` / SDK) sessions occasionally ignoring SIGTERM when a supervisor such as `timeout` or systemd sends SIGCONT alongside it
- Fixed restarted cloud sessions restoring a model that the organization’s enforced model list refuses
- Fixed MCP tool calls sometimes running twice when a remote server’s result was over 16 MB or could not be parsed
- Fixed subagents in Claude Desktop’s Code tab getting none of the tools of a user-configured MCP server named `memory`
- Fixed Claude in Chrome asking before every screenshot and page read on a site you allowed when auto mode is unavailable (such as with `disableAutoMode` or an older model); typing, navigation and JavaScript still ask
- Fixed `claude plugin install` failing for GitHub-source plugins on macOS and Linux machines with no GitHub SSH key: the clone now falls back to HTTPS and prints a notice
- Fixed `sandbox.credentials.files` entries on git config files not taking effect while `permissions.blockReadsOutsideWorkingDirectories` is on
- Fixed Claude leaving out your organization’s design systems when starting slides or a design with the Artifact tool on Team and Enterprise plans or machines with managed settings
- Fixed the keyboard not working on Windows after Claude Code restarts itself (first sign-in to a Claude apps gateway, provider setup, `/tui`)
- Fixed a stall when launching an agent whose `tools:` lists very many `Agent(...)` entries
- Fixed sessions on Claude 3 Opus and Claude 3 Sonnet failing on every turn after a whole PDF entered the conversation
- Fixed the npm auto-updater reporting success when the platform-native binary failed to download and only the placeholder `claude` stub was installed
- Fixed Remote Control cleanup archiving a session that is still connected or was just re-attached by another Claude Code process
- Fixed `owner/repo` plugin marketplaces showing only the second attempt’s error when both the SSH and HTTPS fetch fail; both errors are now shown, with the transport tried first on top
- Fixed path-scoped `.claude/rules` and nested CLAUDE.md files not loading when Write or Edit creates or changes a file in their scope (previously only Read loaded them)
- Fixed a dangerous `rm` (such as one on `/` or the home directory) inside a `bash -c` or `sh -c` script running without a prompt in bypassPermissions mode or under a shell allow rule (anthropics/claude-code#96300)
- Fixed LSP tool calls hanging indefinitely when a language server uses dynamic capability registration or stops responding; requests now time out after 60s (per-server `requestTimeout`)
- Fixed `idle_prompt` notification hooks firing while background agents are still running (anthropics/claude-code#93672)
- Fixed PreToolUse and PermissionRequest hooks being skipped when matching them failed or the tool’s input could not be serialized to JSON; the call is now blocked
- Fixed the first request in a fresh environment or after a model switch using the built-in output limit and auto-compact window, not the server’s; that request may now wait up to 1.5 seconds
- Fixed the “What should Claude do instead?” hint showing on the Interrupted row after sending queued messages with ctrl+enter
- Fixed `/login` in a `--bare` session running a sign-in the session never reads, which could replace your saved login; it now says which credentials work
- Fixed the InstructionsLoaded hook omitting agent_id and agent_type when a subagent’s file access loads a rule or nested CLAUDE.md; rules and nested CLAUDE.md files loaded on file access now also report effort
- Fixed the Agent tool in `claude mcp serve` always reporting no available agents and rejecting every subagent_type
- Fixed the terminal cursor not following the typed text in the fullscreen transcript viewer’s search and in `/theme`’s custom color search
- Fixed `/permissions` in screen reader mode: typing a rule’s number now picks it instead of opening the search box
- \[VSCode\] Fixed a claude.ai connector staying on “Needs authentication” after you authorize it: the MCP servers dialog now offers Check connection
- \[VSCode\] Fixed the opt-in New Conversation shortcut (Cmd/Ctrl+N) starting a conversation in every visible Claude view instead of only the one you are in
- \[VSCode\] Fixed the chat view resuming the next saved session after you archive the one it shows; it now starts a new conversation instead
- \[Cloud sessions\] Fixed the Cloud sessions switch in Claude Code admin settings staying locked off while an unrelated security setting was loading or had failed to load
- \[Cloud sessions\] Fixed pressing Stop while a self-hosted runner was still starting not cancelling the queued message, which could then run once the runner was up
- \[Claude Tag\] Fixed Claude Tag admin settings offering a “Remove this scope” option, which always failed, on channels whose settings were created automatically
- Fixed `claude plugin test` reporting mods as turned off remotely when it had only read an out-of-date saved setting

[​](#2-1-287)

2.1.287

October 1, 2026

**Added**

- Added Claude Mods: plugins may now modify deeper behavior
- Added You should know, a built-in mod where a side agent watches your back and flags things you or Claude might miss. Turn it on with `/plugin enable cc-plugin-you-should-know@builtin` (for first-party sessions with telemetry on)
- Added an `n:<text>` filter to the agents view that matches session names and tasks; a filter now shows matches in collapsed sections and Enter opens the first match
- Added `prompt_text` to the OpenTelemetry `user_prompt` event, a copy of `prompt` for backends that nest dotted keys; drop or mask it wherever you drop or mask `prompt` (anthropics/claude-code#70763)
- Added URL prompts from MCP servers on the 2025-11-25 protocol, for example to sign in. If a server no longer connects after this update, add “bareElicitationCapability”: true to its MCP config entry
- Windows: Added a startup warning when denying the Bash tool also turns off the PowerShell tool, so Claude has no shell tool
- Self-hosted runner: Added a built-in `gh api` (REST only) for sessions that use Anthropic-managed git on macOS and Linux machines where the GitHub CLI is not installed
- \[VSCode\] Added “Run in background” to a running command or sub-agent, to move it to the background and keep working
- \[VSCode\] Added the output of background shells and Monitors to their cards in the agent map

**Changed**

- Changed a shell write through a repo-committed symlink onto a sensitive file or out of the working tree to name where it lands and wait for a person, on lines with a `~` target too
- Changed Opus 4.7+ and Fable to use a 1M context window by default on Bedrock, Vertex, Foundry and the Claude apps gateway, with no `[1m]` suffix (`CLAUDE_CODE_DISABLE_1M_CONTEXT=1` keeps 200K)
- Changed replies from `claude agents` to arrive as queued messages; slash commands other than `/stop` sent while a turn is running now run when it ends
- Changed whole-tool `Bash` allow rules and allowing hooks to prompt for, not run, shell writes to files Claude Code’s file tools refuse outright (the Anthropic profile store, the host credentials file)
- Changed right-click paste on Windows and Linux, and middle-click paste on Linux, to happen when the button is released; moving the pointer away before releasing cancels it
- Changed MCP server `alwaysLoad: false` to defer all of that server’s tools behind tool search
- Changed screen reader mode to write new or changed lines without first pausing with the cursor at the start of the line; set `CLAUDE_AX_PREPARK_MS=50` to restore the pause
- Changed automatic model switches after a flagged message to keep your current effort level instead of the new model’s default
- Changed waiting permission prompts to show oldest first, so a new prompt no longer covers the one you’re reading (prompts with a countdown still open on top)
- \[VSCode\] Changed the Claude in Chrome “Enabled by default” switch to also connect the editor’s own sessions, which still ask before browser actions

Show 20 improvements

- Improved `/config`: settings that cycle show ‹ › and step both ways with ←/→, narrow terminals stack each value under its label, and PgUp/PgDn page the list
- Improved plugin marketplace errors to say in plain words why a marketplace was ignored or refused, and what to do
- Improved plugin listings to note when a plugin’s dependencies were not installed, and updating a plugin now retries an install that did not finish
- Improved the Claude apps gateway’s error when Amazon Bedrock rejects a model ID: developers now see which model is unavailable, and the gateway log names the ID that was sent
- Improved SDK sessions so a message sent with priority “now” no longer cancels a running web fetch or web search; it keeps loading in the background
- Improved `/memory`: the left and right arrow keys now flip its on/off settings, such as Auto-memory
- Improved `/skill` names typed mid-message: Claude is now told they are skills, including `disable-model-invocation` ones
- Improved the contrast of the prompt input border in light themes and of the ❯ before your earlier messages
- Improved delivery of files Claude sends from cloud sessions and Remote Control: an upload that fails on a timeout, a network error or a 502, 503 or 504 is now retried once
- Improved what Claude says when a file cannot be sent for a reason that may be temporary: it now mentions that you can ask for the file again in a few minutes
- Improved the prompt for a held message from another session to show the message between dashed lines, matching other permission prompts
- Improved MCP and other tool permission prompts to show the tool call between dashed lines, matching file edit prompts
- Improved MCP startup in headless mode: a remote server whose first connect fails transiently is now retried without waiting for the slowest server to finish connecting
- Improved files Claude sends from a remote session: large files now stream from disk instead of being read into memory, and a file over the size limit is refused with the server’s limit named
- Improved the explanation Claude gives when the server refuses a file it sends from a Remote Control or cloud session, such as an oversized image
- Improved handling of large MCP tool results: less memory, smaller session files, and no extra upload to count tokens for results far over the limit
- Windows: Improved Bash tool speed by removing a subshell that ran before every command
- \[VSCode\] Improved the Manage plugins dialog: a failed marketplace add, remove or refresh now says what went wrong
- \[Claude Tag\] Improved Claude’s task list in long Slack threads: background work no longer reposts it as a new message on its own, so people following the thread aren’t notified
- \[Code Review\] Improved the failed-review card on a pull request whose conversation is locked: it now says the lock blocked the review and that nothing was posted or charged

Show 67 bug fixes

- Fixed fast mode staying off in remote sessions owned by an agent with no user account, even when the organization allows it
- Fixed Remote Control not receiving messages for minutes at a time when a reconnect request got no response; it now gives up after 30 seconds and retries
- Fixed hooks configured with `asyncRewake` waking Claude over and over with “found issues” notifications when the hook’s script file is missing; the broken hook is now reported once
- Fixed tool heartbeats not reaching SDK hosts while the model’s response stream was stalled with no data arriving
- Fixed Bedrock and Vertex startup model checks ignoring an enforced `availableModels` list, which could collapse `/model` to one Opus row
- Fixed the Claude in Chrome browser picker showing a JSON parse error when Chrome could not be reached
- Fixed picking Fable in `/model` on a claude.ai login saving the current version’s id, so your saved default now follows the newest Fable like Opus and Sonnet do
- Fixed switching between Opus 5.5 and Sonnet 5.5 (`/model`, `opusplan`) rewriting earlier MCP tool announcements, which could drop earlier extended thinking
- Fixed Amazon Bedrock Guardrails blocks that arrive mid-response ending the turn with an API error instead of the guardrail’s message when the reply began with thinking
- Fixed a dangerous `rm` (such as one on `/` or the home directory) losing its always-ask safeguard when the same command also redirected output to a `~` or wildcard path
- Fixed `claude -p` and SDK sessions repeating a model fallback on every later message after the model was switched while a reply was running
- Fixed a folder’s CLAUDE.md being attached a second time after resuming a session or after a compaction
- Fixed background sessions that could not be reopened from `claude agents` after the agent exited and removed the worktree the session was started in
- Fixed `/advisor` pairing checks: Sonnet 5.5 can now advise Opus 4.7 and 4.8, and advisors the API would refuse are flagged up front instead of being silently dropped
- Fixed Bash permission prompts showing internal parser names such as “Contains simple_expansion” instead of a plain explanation
- Fixed a cause of fullscreen sessions on slow or busy machines exiting with “Claude Code exited after an unrecoverable interface error” while a scroll key was held in a long conversation
- Fixed organization per-tool permission ceilings being silently dropped for an MCP tool named `__proto__`
- Fixed Claude being told to page large MCP results saved as JSON with Read’s offset and limit, which cannot split one long line
- Fixed the commit attribution reminder being delivered inside a tool result after a compaction
- Fixed screen reader mode leaving the cursor away from the typed text in search boxes (such as /resume and /permissions) and sign-in code fields
- Fixed screen reader mode refusing Enter with nothing typed on /rewind’s summarize options, whose added context is optional
- Fixed screen reader mode showing a “Tab to amend” hint on approval prompts, where Tab does nothing
- Fixed screen reader mode listing arrow keys that do nothing in /permissions and /mcp, and saying “Select with numbers” in empty menus or while a search box has the keys
- Fixed screen reader mode leaving out the changed lines in file edit approval prompts and other diffs
- Fixed screen reader mode sending the `claude --teleport` progress screen, and an MCP form field while it is being checked, to the screen reader again on every spinner frame
- Fixed `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS` not removing the structured-output format from session-title and prompt-hook requests, which Bedrock-backed gateways reject
- Fixed screen reader mode leaving out the top lines of a second approval prompt, a changed /config row or the rejected-plan line when the previous screen was taller than the terminal window
- Fixed `--include-partial-messages` sending a cut-short reply’s `message_stop` late or never, so apps could show the reply as still in progress
- Fixed `claude agents` sometimes not showing the permission prompt a background session is waiting on
- Fixed `/ultrareview` giving advice about `.git/info/attributes` when the upload stops on a committed `.gitattributes` it cannot read, such as one saved as UTF-16
- Fixed `claude remote-control` failing to register behind an HTTP proxy with a misleading “Check your organization permissions” error (anthropics/claude-code#97352)
- Fixed sandboxed Bash commands on Linux inheriting an open handle on the Claude Code executable
- Fixed the running-tool dot and three spinners still moving with the “Reduce motion” setting on, and /rewind’s confirm screen updating its “ago” time while you type a note
- Fixed times in `claude agents` changing every second in screen reader mode; they now change at most every 10 seconds
- Fixed a revoked claude.ai login showing a generic `API Error: 401` instead of “OAuth token revoked”; in `-p` mode the error now starts with “Failed to authenticate”
- Fixed `/ultrareview` upload refusals advising you to copy a variable named by a repository’s settings file into your own user settings
- Fixed `--output-format stream-json` and the SDK not streaming the turns of a `context: fork` skill run by typing `/<skill>` as the prompt, as they do for the Skill tool’s fork
- Fixed /feedback and /bug: the pre-filled GitHub issue no longer includes your recent error messages, and the confirmation screen now lists them as part of the report
- Fixed `claude plugin marketplace add --sparse` and `git-subdir` plugin installs failing with “transport ‘http’ not allowed” when the repository is served over plain http
- Fixed cloud sessions sometimes losing the earlier conversation when the session restarted while it was being compacted
- Fixed a plugin reload that overlapped the startup `--plugin-url` download corrupting the session’s cached copy of the plugin archive
- Fixed `/desktop` quoting partial output when opening Claude Desktop timed out or printed too much output; the error now names the cause
- Fixed an MCP connector tool call occasionally running twice, or the connector’s calls failing until restart, when its server changed which MCP protocol version it supports
- Fixed SessionStart hooks from synced plugins not running in new cloud sessions
- Fixed the transcript’s “N hooks ran” summary and the verbose debug log’s matched-hooks count including Claude Code’s internal callbacks, so one configured hook no longer shows as two
- Fixed files Claude sends from cloud and Remote Control sessions failing when the upload finished just after the 30-second timeout; it now waits 35 seconds
- Fixed repositories added mid-session in cloud and SDK sessions not loading their skills and plugins, and loading CLAUDE.md late, after Claude changed directory
- Fixed PNG, JPEG and WebP images over 8,000 pixels on a side failing to send from a remote session; Claude now sends a scaled-down copy
- Fixed messages sent from the Claude apps with 17 to 20 attached files delivering only the first 16
- Fixed headless sessions reporting an MCP server as needing authentication after one refused call, even though later calls succeed
- macOS: Fixed Remote Control sessions started with `claude remote-control` stopping mid-turn when the Mac went to idle sleep
- Windows: Fixed interactive `claude` hanging or crashing with “Raw mode is not supported” when its input is piped or redirected; it now says why and exits (use `-p` for piped input)
- Bedrock, Vertex, Mantle: Fixed model availability checks under `CLAUDE_CODE_SKIP_*_AUTH` sending a different `Authorization` header than real requests when `ANTHROPIC_CUSTOM_HEADERS` repeats it
- \[VSCode\] Fixed settings dialogs blaming a timeout when Claude Code’s reply was too large to confirm a save
- \[VSCode\] Fixed reopening a cloud session that the side bar already brought to this machine opening it again in a new tab; the side bar is shown instead
- \[VSCode\] Fixed the side bar’s Web tab not listing cloud sessions started after the window loaded; a failed load now says “Remote server is not connected” instead of “No web sessions yet”
- \[VSCode\] Fixed a tab restored after a reload starting a second Claude process on a conversation the side bar already has open; it now shows the “still open somewhere else” notice
- \[VSCode\] Fixed tool-row file links, session-list links and two hints showing in plain text
- \[VSCode\] Fixed a background agent’s still-running command showing as failed once the main turn ended
- \[VSCode\] Fixed a user’s own `/usage` or `/context` command opening the extension’s dialog instead of running when picked from the command menu
- \[VSCode\] Fixed file links in the plan preview tab doing nothing when clicked; they now open the file like links in chat replies
- \[VSCode\] Fixed opening a tool’s input or output in an editor tab failing with “Timeout waiting after 1000ms” on remote hosts such as WSL when the tab is slow to appear
- \[Cloud sessions\] Fixed occasional failures to fetch from or push to GitHub when GitHub briefly refused a newly issued access token
- \[Claude Tag\] Fixed Claude posting a failure warning, such as a spend limit notice, in a Slack thread when a background event like GitHub activity woke it and nobody was waiting on a reply
- \[Claude Tag\] Fixed Claude Tag’s spend limits page in admin settings leaving out recently created and private channels in organizations with many channels
- \[Code Review\] Fixed finding comments and their “Why this was flagged” text stopping mid-sentence; they now end on a complete sentence
- \[Code Review\] Fixed Code Review skipping a pull request after a new push when its review had failed twice on the previous commit; it now reviews the latest commit

[​](#2-1-286)

2.1.286

September 30, 2026

**Added**

- Added a count such as “2 of 5” to the permission prompt when several permission requests stack up
- Added mouse support for the “N more” rows of lists in fullscreen mode: click one to jump to that end of the list, with hover and pressed states
- \[VSCode\] Added bookmarks: save Claude’s responses and keep them in view in a Bookmarks side panel
- \[VSCode\] Added the questions Claude asks and your answers to the conversation: after you answer a question card, a Questions row shows each question with your picks
- \[VSCode\] Added option previews to question cards in the chat panel: the highlighted choice’s mockup or snippet shows beside or under the options
- \[VSCode\] Added rows under a message that open to the terminal output, browser tab, browser instructions and selected code sent with it
- \[Claude Tag\] Added an Add channel button to Claude Tag’s spend limits page in admin settings, so a limit can be set on any channel, including a private one, from its channel ID or Slack link

**Changed**

- Changed prompts sent while nothing is running or queued to show in the normal text color right away instead of gray
- Changed how failed API requests are retried: one limit now covers a whole model call, so with the default retry settings a failing call sends at most 14 requests
- Changed `--bare` to connect only the MCP servers named on the command line, send the model no system reminders, and start no background tasks; under `--bare`, a shell command that reaches its timeout now stops instead of moving to the background
- Changed the send-now key (ctrl+enter) to move a skill’s own shell command to the background instead of ending it
- Changed the WebFetch error for a rate-limited domain safety check to tell Claude not to retry it in a loop
- Changed plugin installs to refuse npm sources that are git repositories or folders, and to install plugin dependencies only from registry packages
- Changed list screens (`/artifacts`, `/mcp`, `/skills`, `/hooks` and others) to always line up each row’s details in one column after the names
- Changed the overflow rows of lists to read ”↑ N more” / ”↓ N more” instead of “N more above” / “N more below”
- Changed `/hooks` to open on one list of your configured hooks grouped by event, so viewing a hook takes one Enter instead of three
- Changed the theme picker to a scrolling list that fits your terminal instead of pushing the preview off screen; number keys no longer pick a theme
- Changed `/exit`’s Remove worktree to run after Claude Code stops the servers and shells it started there, which on Windows could keep the folder from being deleted
- Changed the `claude-api` skill’s Managed Agents examples to create environments with limited networking
- Removed the browser link from `/ultrareview` and `claude ultrareview` output
- \[VSCode\] Changed Stop and Escape to end only the current turn; background agents keep running and can be stopped one by one from the agent map
- \[VSCode\] Changed the ”✻ Claude Code” status bar item to show in every window, so you can open Claude when no file is open
- \[Cloud sessions\] Changed a routine’s page to read “Due” with the scheduled time, instead of a next run time in the past, when a scheduled run is late and hasn’t started

Show 16 improvements

- Improved commit guidance: when your project or user skills include one named `verify`, Claude is now told to run it right before committing, except for docs-only and tests-only commits
- Improved send now (ctrl+enter) in a subagent’s view: it now moves the subagent’s running command to the background so your message is read right away
- Improved replies from background agents to your messages so they no longer open with a separate recap of what you said
- Improved claude.ai artifact link reads: WebFetch now asks the same questions as the Artifact tool’s read (no artifact prompt while the session’s network access is on, one per artifact while it is off), and an auto-mode yes no longer counts where only you can answer
- Improved fetch, skill, file read, sandbox network, Claude in Chrome, workflow script and notebook edit permission prompts to match the look of file edit prompts
- Improved Bash, PowerShell and Monitor permission prompts to show the command between dashed lines, matching file edit prompts
- Improved list scrollbars in fullscreen mode: in most lists the bar no longer shifts as the “N more” rows come and go, and it now has ↑/↓ arrows you can click or hold to scroll
- Improved the external editor (Ctrl+G): editors that take a line number now open on the line your cursor is on in the prompt
- Improved slash command suggestion responsiveness while typing when many skills or plugin commands are installed; command descriptions now match by word prefix
- Improved the output style picker: it now opens on your current style instead of Default, with each style’s description on the line under its name; number keys no longer pick a style
- Improved `/hooks`: the closing line of a hook’s detail screen now says “this hook” instead of “it”
- Improved the model fallback notice and the autocompact-thrashing error to say when a fallback dropped the context window from 1M to 200K tokens
- Improved responsiveness of SDK and `-p` sessions when a host re-sends an MCP server enable for a server that is already connected
- Improved the protocol page a Claude apps gateway serves at `/protocol`: it now says not to reject unknown input and matches what Claude Code sends today
- \[VSCode\] Improved the Manage plugins dialog: it says when a turned-off plugin is still on because of other settings, and explains a plugin folder clash
- \[Claude Tag\] Improved the titles of sessions started from Slack as shown on claude.ai: they now read as the words you typed, without Slack user IDs or escape codes

Show 49 bug fixes

- Fixed several Claude Code processes and IDE extensions each opening a login browser when gcpAuthRefresh or awsAuthRefresh credentials expire
- Fixed `claude --resume` and `--continue` sometimes losing every turn after a batch of parallel tool calls when the earlier session crashed or was killed
- Fixed API 400 errors after a tool or hook returned an object, number or boolean instead of text, including in resumed sessions
- Fixed cloud sessions with very large histories never waking up because the container was stopped while the transcript was still loading
- Fixed the Claude apps gateway’s spend meter pricing 1-hour prompt cache writes at the cheaper 5-minute rate, and counting only the first model call’s input tokens on streamed turns that run a server-side tool such as web search
- Fixed macOS sessions still showing “Not logged in” or “Login expired” after `/login` succeeds in another Claude Code window when a leftover `~/.claude/.credentials.json` exists
- Fixed every turn failing when the Anthropic API refuses the model your default or a model alias resolves to: Claude Code now retries once on the previous model of the same tier
- Fixed Remote Control sessions (including `claude remote-control`) staying connected after your organization’s policy turns Remote Control off; they now disconnect with a notice
- Fixed refusal and `--fallback-model` retries failing when the fallback model can’t run fast; they now run at standard speed, with a one-time notice in interactive sessions
- Fixed headless sessions repeating the “MCP servers require authentication” reminder after a successful re-authentication when the MCP discovery cache is enabled
- Fixed `claude auth status` reporting a Console sign-in’s stored API key as `claude.ai`; it now reports `api_key`, and the VS Code extension treats that session as an API key session
- Fixed `/status` listing an Anthropic profile beside an API key as if both were in effect; the profile is now marked as not in use
- Fixed Claude not being told when a file attached to a message sent over Remote Control did not arrive, and a file sometimes getting only 10 seconds for its last download try
- Fixed a Remote Control message that arrived while Claude Code was exiting being marked delivered and then never answered; it now stays queued for the session’s next run
- Fixed MCP error messages showing a credential’s value when “Bearer” or “Basic” came before its key name
- Fixed percent-encoded Bearer tokens being only partly masked in error messages
- Fixed redacted logs and transcripts showing a secret whose key name has an invisible character inside, such as a zero-width space
- Fixed logs and transcripts showing part of a URL password that contains punctuation such as `)`, quotes, `]`, `&` or a second `@`, or that runs past a `/` to a bracketed host such as `[::1]` in an ssh URL
- Fixed the session transcript in the zip that `/feedback` saves to disk containing invalid JSON lines after secret redaction
- Fixed MCP connectors listing no tools for up to a day after their server dropped the older MCP handshake
- Fixed a repeat MCP sign-in request from Claude replacing the pending sign-in link, which could stop that link from working
- Fixed `/usage` not crediting an MCP server for a tool call made while that server was still connecting or had only just connected, such as right after a restart
- Fixed plugins enabled on claude.ai occasionally going missing from Claude Code for a session after a transient server error
- Fixed a message typed into a running subagent showing twice in its transcript after the subagent read it
- Fixed subagent hand-back messages showing a raw task id instead of the agent’s name when the subagent had no registered name
- Fixed foreground subagents sometimes missing the task-tracking tools (TaskCreate/Get/Update/List, TodoWrite) in sessions that have them enabled
- Fixed subagents spawned with worktree isolation loading the project CLAUDE.md and its imports a second time from the worktree copy on their first file read
- Fixed Workflow tool subagents being restarted from their original prompt when a connection stalled for a few minutes mid-response
- Fixed `/compact`, `/clear`, and `/rewind` typed while viewing a background agent’s or teammate’s transcript silently acting on the main conversation: a dialog now names the target and asks first
- Fixed background jobs showing done while waiting for your approval
- Fixed the commit attribution reminder being re-sent inside tool output when a model fallback lasts only one turn
- Fixed a click on the space between words of a collapsed row (such as “Thought for 4s”) highlighting the row without expanding it in fullscreen mode
- Fixed a row with no details, such as an action row with a long name, pushing every other row’s details to the right in list screens
- Fixed files with very long names not reaching a cloud session when attached to it
- Fixed plugin errors for a marketplace Claude Code refuses to load: they now say why and how to fix it instead of “not found”
- Fixed `/plugin`’s Discover tab showing a marketplace name unquoted in its “Checking … for new plugins” line when its rows already show that name in quotes
- Windows: Fixed `claude --bg` and the agents view refusing a folder that `claude` already trusts when its trust record was saved with different letter case
- \[VSCode\] Fixed a second copy of a conversation opening in a tab when it was already open in the side bar; the side bar now switches to it
- \[VSCode\] Fixed settings dialogs reporting a failed save, without re-checking, when Claude Code printed more than 1 MB of output
- \[VSCode\] Fixed an endless “Teleporting session…” spinner when the extension stops responding
- \[Cloud sessions\] Fixed an answered question card or approved tool call getting no reply when the session had gone idle after Claude sent a message
- \[Cloud sessions\] Fixed clearing an organization environment’s setup script in admin settings leaving new cloud sessions still running the old script
- \[Cloud sessions\] Fixed the Runner actions menu on the self-hosted environments admin page closing on its own a few seconds after it opened
- \[Cloud sessions\] Fixed routine runs whose cloud session never started showing as Succeeded in the Runs pane, the routine’s page and the sidebar; they now show as Failed
- \[Cloud sessions\] Fixed clicking an audio or video file in a cloud session’s Outputs card opening an empty file search instead of playing the file
- \[Claude Tag\] Fixed memory recall finding nothing in organizations that cannot use the default Sonnet model
- \[Claude Tag\] Fixed a Slack channel losing its Claude settings when an Enterprise Grid admin moves it to another workspace and the first post afterward doesn’t mention Claude
- \[Claude Tag\] Fixed Claude in a Slack thread occasionally starting over on a fresh machine, losing work it hadn’t pushed, when your reply answered a question it had just asked
- \[Claude Tag\] Fixed public channel names on Claude Tag’s spend limits page in admin settings showing as raw Slack IDs in larger organizations

[​](#2-1-285)

2.1.285

September 29, 2026

**Added**

- Added `CLAUDE_CODE_DISABLE_WEB_FETCH` environment variable to turn off the WebFetch tool
- Added `claude --desktop` to open the Claude desktop app on the current directory, or on a session with `--continue` / `--resume <id>`
- Added `claude plugin configure <plugin>` to show a plugin’s options and which are unset, or save new values read from stdin with `--values-stdin`
- Added `<server>.<key>=<value>` to `claude plugin install --config`, so a bundled `.mcpb` MCP server’s own settings can be set at install time and it starts without visiting `/plugin` → Configure
- Added `allowedProviders` managed setting to limit which API providers a machine may use (Anthropic API, a custom endpoint, Bedrock, Mantle, Vertex AI, Foundry, Claude Platform on AWS, or a Cloud gateway)
- Added `CLAUDE_CODE_NONSTREAMING_TIMEOUT_RETRIES` environment variable to cap re-sends of a non-streaming fallback request that timed out
- \[VSCode\] Added a note under a restored tab’s last message when a window reload interrupted it and no reply will follow
- \[VSCode\] Added a plugin options form to Manage plugins: installing a plugin that has options asks for the unset ones, and a gear on its row changes them later
- \[VSCode\] Added an on-demand diagnostics tool so Claude in the panel can read the Problems panel’s current errors and warnings at any time, not only right after it edits a file
- \[Claude Tag\] Added direct messages with Claude for members on an Enterprise plan Standard or Usage-Based Chat seat who also have Cowork; a seat that includes Claude Code is no longer required

**Changed**

- Changed MCP tools so a tool that sets its own `_meta['anthropic/alwaysLoad']` to false stays deferred when its `--mcp-config`, Agent SDK or plugin server is set to `alwaysLoad`
- Changed background Bash and PowerShell commands to stop after a time limit (their `timeout` with `run_in_background`, default 30 min, max 2 h); Claude is notified when one is stopped
- Changed Code Review’s pull request reviews and `/ultrareview` to run when `disableWorkflows` is on, unless the machine running the review has it set by its own administrator (MDM or the managed-settings file)
- Changed sessions behind a custom `ANTHROPIC_BASE_URL` to use the 1M context window of models that have one (Opus 4.7+, Sonnet 5+, Fable); run `/autocompact 200k` if your gateway stops at 200K
- Changed Team and Enterprise sessions, and sessions whose sign-in plan Claude Code can’t determine, to withhold WebFetch until the organization policy loads if it couldn’t be loaded at startup
- Changed /memory so that Auto-memory can no longer be turned on from a background session or from a session one of Claude Code’s own tools started; turning it off there still works
- Changed the one-time offer to make auto mode your default permission mode to also show on third-party providers and with telemetry off, when your user settings default to another mode
- Changed `claude -p` and Python Agent SDK sessions on third-party providers or with telemetry off to start in auto mode when no permission mode is configured, like interactive sessions; `--permission-mode` still overrides it
- Changed Bedrock, Mantle and Claude Platform on AWS requests to a base URL with a non-default port to include the port in the SigV4-signed Host header
- Changed the MCP server name `widgets` to be reserved in cloud sessions and on self-hosted runners: your own server under it, or a close spelling such as `widgets_`, no longer loads, so rename it
- Changed `/ultrareview` on macOS and Linux to leave symbolic refs out when uploading a local checkout; a checkout whose current branch is a symbolic ref is now refused with an explanation
- Windows: Changed project and local settings `env` to no longer set `ALLUSERSPROFILE`, `SystemDrive`, or the `CommonProgramFiles` variables; set them in user or managed settings instead
- Changed `/tasks` to fold background work Claude Code runs for itself under one “System tasks” row; press Enter on it to show those tasks
- Changed `/ultrareview` on macOS and Linux to require git 2.31 or newer to upload a local repository; checkouts made with `--separate-git-dir` are now refused instead of being uploaded with an older method
- Changed `/ultrareview` uploads on macOS and Linux to send a partial clone as a working-tree snapshot on git 2.31 or newer, instead of falling back or refusing when git’s version looked too old
- Changed `/ultrareview` uploads on macOS and Linux to refuse, instead of fetching, a partial clone missing some of its working tree’s files on older git versions; a clone made without `--filter` uploads
- Changed Bedrock, Vertex and Mantle start-up model checks to identify themselves as Claude Code, like other Claude Code requests
- Changed `claude mcp get` to hide the command, arguments, and environment values of stdio MCP servers provided by plugins; variable names are still shown
- Changed `/claude-api` so it can no longer be run from Remote Control clients
- Changed `/config chrome=true` to direct you to the /config panel instead of enabling Claude in Chrome by default; `/config chrome=false` still turns it off when it was on
- Changed sandbox settings so project settings cannot widen or turn off an admin-required sandbox, replace the proxy behind a managed deny list, extend a strict allowlist, or reopen managed read-denies
- \[VSCode\] Changed the Manage plugins dialog to ask before removing a marketplace or turning off a plugin that your project’s shared `.claude/settings.json` turns on
- \[Cloud sessions\] Changed `MCP_DISCOVERY_CACHE=1`, when set in your cloud environment’s variables rather than a settings file, to reuse your connectors’ tool lists after a session restart; other MCP servers are no longer cached and connect at startup

Show 17 improvements

- Improved Claude in Chrome: the native host now reports your computer’s name, so connected browsers can be labeled by computer instead of “Browser 1” / “Browser 2”
- Improved Bedrock and Vertex AI sessions to switch to an older available model of the same tier, instead of failing, when an admin removes access to the default model; session titles and summaries now fall back with it
- Improved plugin marketplace errors to name why a git address is refused instead of citing enterprise policy
- Improved validation of git URLs for plugins, marketplaces and the current repository’s remote
- Improved Artifact tool results: they now suggest publishing in the same step as writing or editing the page, which can save a round trip
- Improved Remote Control: a `/btw` side question asked of a session hosted by an app such as Claude Desktop now sees the turn in progress, not only the last finished one
- Improved pictures Claude sends as BMP, HEIC, HEIF, AVIF or TIFF files: the Claude apps now show a preview where Claude Code can convert them
- Improved subagents in auto mode: a subagent’s run now ends as soon as it hands its report back to its caller, instead of taking extra turns that reach no one
- Improved Bedrock and Vertex start-up model checks: models your account cannot use are now remembered for up to a day instead of being re-checked on every launch
- Improved Artifact tool publish results to use fewer tokens: the note on updating an artifact is shorter, and where to find your artifacts is no longer repeated after every publish
- Improved SDK liveness during a non-streaming fallback request: with partial messages on, a `ping` stream event is now sent every 30 seconds on the Anthropic API, Claude Platform on AWS and gateways
- Improved `/resume` and `claude --resume` on a session that is running in the background: they now open that session instead of refusing, and a prompt given with `claude --resume <id> "prompt"` is sent to it as its next turn
- Improved per-turn performance when many permission deny rules and MCP tools are configured
- Improved responsiveness when leaving the ctrl+o transcript view in long sessions when fullscreen rendering is off
- Improved Bedrock, Vertex and Mantle start-up model checks to send the same User-Agent, x-app and session ID headers as regular requests
- \[VSCode\] Improved the Manage plugins dialog: a failed plugin action now opens a popup that explains it and, where there is one, offers the fix
- \[Code Review\] Improved the Code Review check run to say when your repository’s REVIEW.md wasn’t applied, for example on a very large pull request or when REVIEW.md is a symbolic link

Show 86 bug fixes

- Fixed `claude -p` with `CLAUDE_CODE_FORK_SUBAGENT=1`: a subagent’s own Agent call now runs in the foreground, so the subagent gets the child’s result
- Fixed plugin and marketplace installs and updates over SSH ignoring the ssh program set in `GIT_SSH` or in your git config’s `core.sshCommand`
- Fixed Claude Code refusing to start when the OS denies reading the managed settings file; it now warns and starts without that file’s policies. Other read errors and unparseable files stop every session
- Fixed cloud sessions that restarted after their conversation was compacted refusing the next update to an artifact the session had already read or published
- Fixed `claude plugin disable` and `enable` with a full `name@marketplace` id changing a settings entry in another letter case instead of the installed plugin’s own
- Fixed files attached to a message sent over Remote Control being left out after a single failed download; a network error, timeout or server error is now retried up to twice
- Fixed switching models mid-session with a `set_model` request (such as the Agent SDK’s `setModel`) leaving the new model on the built-in output-token limit and auto-compact window until restart
- Fixed redacted logs and transcripts showing part of a URL password that contains `@`, or all of it when the URL writes its `@` as `%40`
- Fixed SSH passphrase and new-host prompts from worktree and `/teleport` fetches taking over the terminal; these fetches now fail fast instead of asking
- Fixed switching off an MCP server added mid-session in SDK and `-p` sessions leaving its tools available
- Fixed `claude -p --permission-prompt-tool`: a background subagent’s permission request now goes to the prompt tool instead of being auto-denied
- Fixed `claude mcp list` and `claude mcp get`, and the not-found error of `claude mcp remove`, `login` and `logout`, printing line breaks and terminal escape sequences from MCP server names and values
- Fixed sandbox auto-allow asking for approval on every run of many inline scripts (`python3 -c`, `node -e`) just because they contain `=`
- Fixed fork subagents not keeping the session’s plan mode or `dontAsk` mode: a fork now runs under its parent’s permission mode and cannot exit plan mode
- Fixed `claude remote-control --help` saying `--[no-]chrome` defaults to the machine’s `/chrome` setting; spawned sessions keep Claude in Chrome off unless `--chrome` is passed
- Fixed background subagents in auto mode prompting a second, redundant reply after each report
- Fixed cloud session creation and `/remote-env` reading only the newest 20 of an account’s environments
- Fixed Remote Control marking a message as read as soon as it arrived instead of when Claude started on it, and losing a message still queued when the terminal quit (it now arrives on the next resume)
- Fixed installing a plugin with `claude plugin install` or `/plugin` putting it into an installed plugin’s cache or data folder when their ids differ only in `.`, `-`, `@` or (macOS, Windows) capitals; the install is now refused
- Fixed hooks and SDK permission callbacks seeing a missing or outdated plan on ExitPlanMode when the plan was written in the same response
- Fixed the first reply in cloud sessions arriving tens of milliseconds late, a regression in 2.1.283
- Fixed sessions that authenticate with `ANTHROPIC_AUTH_TOKEN` against the Anthropic API never loading the organization’s policy
- Fixed a failed `agent()`, `parallel()` or `pipeline()` call that a workflow script awaits later, or not at all, being treated as an unhandled promise rejection, which could end a background session
- Fixed synchronous hooks hanging Claude Code while a background process the hook started (for example `some-daemon &`) kept its output open; the hook now finishes shortly after its own process exits
- Fixed WebFetch reporting a rate-limited domain safety check as a network or enterprise policy block
- Fixed the fullscreen ctrl+o transcript freezing briefly when opened on turns with hundreds of file reads or searches; tool calls still running when the transcript opens now show their results when they finish
- Fixed Amazon Bedrock mid-stream `modelTimeoutException` and `serviceUnavailableException` errors showing a raw JSON body instead of the error message
- Fixed `/autofix-pr` and `/schedule` saying the Claude GitHub App is not installed on a repository whose install status had not been checked yet
- Fixed dismissing a row (x) in `/artifacts` unlinking its file from the artifact, so publishing the same file again created a new artifact instead of updating it
- Fixed Artifact tool publishes after a conversation rewind (Esc Esc) overwriting a file’s newer content that Claude had read only in the rewound turns; the publish is now refused until Claude re-reads the file
- Fixed an `Artifact` allow rule (“don’t ask again”) letting the Artifact tool publish a file outside the working directories without asking; add the file’s folder with `--add-dir` for the rule to cover it
- Fixed `/cost` and SDK `modelUsage` reporting a turn under the wrong model when the server answered a refusal with a different fallback model than the client expected
- Fixed the Artifact tool so that publishing a page no longer lets Claude overwrite its source file without re-reading it when Claude’s earlier read was cut short or the file had changed since
- Fixed auto mode skipping its classifier for Artifact tool asset uploads and reads of someone else’s artifact when you had approved that artifact earlier in another permission mode
- Fixed a misleading “core.worktree is set” error from `/ultrareview` when the project folder briefly could not be read
- Fixed `/ultrareview` on macOS and Linux failing to upload the working tree from a git worktree whose per-worktree config sets `core.longpaths`
- Fixed the Artifact tool sometimes reporting a publish as a conflict with another session after retrying a temporary server error, when the first attempt had actually succeeded
- Fixed `/ultrareview` uploads including uncommitted changes to credential files whose name has a colon before the extension, such as `server:8443.key`
- Fixed a rare auth failure when two sessions recover a login refresh lock left by a crashed process at the same time
- Fixed the PowerShell tool’s permission check skipping deny and ask rules, and caching that failure for later checks, when its command parser failed to start (for example when the machine was out of memory)
- Fixed `/ultrareview` uploads on macOS and Linux running slowly on some unusual file names, and their credential-file check missing file or folder names with many backup or editor marks
- Fixed a cancelled shell command or hook still starting, and running to its end, when the cancel arrived while it was being set up
- Fixed vim mode: after editing in the external editor (Ctrl+G), `x` or `r` in NORMAL mode no longer breaks a pasted-text placeholder at the end of the prompt
- Fixed responses blocked by the API’s output content filter being re-sent and retried, sometimes for minutes, instead of showing the filter’s error right away
- Fixed plugins silently skipping a bundled `.mcpb` MCP server that still needs configuration: `/plugin`, the install message and `claude plugin install` now say so and point to Configure
- Fixed compacting or resuming a session failing, opening without its history, or crashing when its saved transcript holds a compaction marker or loop wakeup entry with missing or malformed fields
- WSL: Fixed `/ultrareview` refusing to upload a checkout on a Linux volume when a changed file’s name has a colon or ends in a dot or space
- Fixed `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` re-running a turn that had ended at `--max-turns`
- Fixed sign-in that could wait forever after the browser showed success
- Windows: Fixed `/ultrareview` uploading a linked worktree of a repository rooted at your home folder in some cases
- Fixed cloud sessions reporting the uploads folder as missing before any file had been uploaded
- Fixed a reply sent from `claude agents` to a background session waiting on a permission prompt sometimes approving the pending command
- Fixed `claude attach`, `logs`, `stop`, `respawn` and `rm` starting a new session with the command name as its prompt when options came before it, such as from a shell alias
- Fixed `claude mcp list` leaving out WebSocket (`ws`) MCP servers; each is now listed with its URL and health status
- Fixed `claude mcp get` showing no Type, Command, Args, or Environment for stdio servers whose config entry omits the `type` field
- Fixed `.claude/settings.local.json` allow rules being held back outside a git repository when git’s trace2 output is configured
- Fixed the `/claude-api` eval runner scaffold and report builder writing through a symlink or hard link planted at an output file
- Fixed the `/claude-api` eval runner scaffold counting responses cut off at `max_tokens` in the score averages; they are now marked truncated and counted separately
- Fixed `&nbsp;` showing as literal text in the terminal when a reply uses it to indent text, such as row labels in a markdown table
- Fixed a brief freeze (up to a second) partway through long sessions outside fullscreen mode, which came back after `/clear` or `/compact`
- Fixed an approved Edit never going through when its target is a device, such as a file symlinked to /dev/null, and the approval came from the IDE diff view or changed the edit
- Fixed a failing API request being retried up to 21 times when streaming kept failing; the non-streaming fallback now shares the request’s retry budget instead of getting a fresh set of retries
- \[VSCode\] Fixed pressing Enter after typing a slash command running an unrelated menu item picked by fuzzy match, or doing nothing
- \[VSCode\] Fixed an open agent transcript losing the agent’s newer messages during a long session
- \[VSCode\] Fixed a message that quotes a Claude Code or IDE tag losing the rest of its text in the chat
- \[VSCode\] Fixed a message sent while Claude was working disappearing from the conversation after the session was reopened
- \[VSCode\] Fixed the session list’s Web tab showing the previous account’s sessions after an account switch
- \[VSCode\] Fixed restored tabs re-running an interrupted turn when VS Code was started with `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` set, even with Continue After Reload off
- \[VSCode\] Fixed Escape stopping the running turn instead of closing the command menu after clicking one of its rows
- \[VSCode\] Fixed opening Past conversations replacing a live conversation with its saved copy
- \[VSCode\] Fixed a Claude tab reloaded after an extension restart staying blank instead of saying how to recover
- \[VSCode\] Fixed opening a conversation that is already open in another window or app starting a second copy of it without warning; it now asks first
- \[VSCode\] Fixed a hook’s reason for blocking or stopping a prompt disappearing after a window reload
- \[VSCode\] Fixed tabs stuck on a conversation that can’t be resumed: the error now says so and offers to start a new conversation
- \[VSCode\] Fixed every file Read, Write and Edit stalling for ten minutes and then being skipped when the editor stops responding to the extension’s automatic save before the tool runs
- \[VSCode\] Fixed the agent map labeling a sub-agent with the session’s model instead of the model it actually ran on (e.g. under `CLAUDE_CODE_SUBAGENT_MODEL_FORCE` or an agent’s own `model`)
- \[VSCode\] Fixed uninstalling a plugin from the Manage plugins dialog, which removed the wrong installation or failed for a plugin installed for the project
- \[VSCode\] Fixed sign-in staying on the authorization-code step after going back and choosing the same sign-in method again
- \[VSCode\] Fixed the chat panel stalling when a long session trims its oldest rows
- \[VSCode\] Fixed the conversation disappearing from a session when many agents run
- \[VSCode\] Fixed the editor tab keeping an old name after a session was renamed with /rename, by a SessionStart hook, or on claude.ai
- \[VSCode\] Fixed the agent map’s transcript view leaving out messages sent to a running agent
- \[Cloud sessions\] Fixed Run now on a routine showing internal error text when the run is refused before it starts; it now shows the same explanation as the routine’s failure notification
- \[Claude Tag\] Fixed the Default model setting in admin settings and a channel’s Configure page offering models your organization can’t use, which made saves or new sessions fail
- \[Claude Tag\] Fixed the note under Claude’s Slack messages saying it answered on a fallback model, and why, disappearing when Claude later edited that message
- \[Code Review\] Fixed the organization menu in Code Review’s “Add a repository” dialog showing only a few of your GitHub organizations; it now loads more as you scroll

[​](#2-1-284)

2.1.284

September 28, 2026

**Added**

- Added Claude Sonnet 5.5 (`claude-sonnet-5-5`), now the default Sonnet model on the Anthropic API — 1M context, \$2/\$10 per Mtok with \$0.20/Mtok cache reads
- Added a “Yes, but ask again next time” answer to auto mode’s prompt before a read outside the working directories, so you can allow that one read and still be asked about later ones
- Added dollar amounts to the Claude apps gateway spend limit in `/usage` and the status line (for example “\$271.40 / \$500.00 spent this month”) when the gateway runs this version or later; the status line’s `rate_limits.spend_limit` also gains `used_usd`, `limit_usd` and `period`
- Added `effortSlider:decreaseEffort`, `increaseEffort` and `toggleUltracode` keybinding actions, so the `/effort` slider’s arrow and Tab keys can be rebound in `keybindings.json`
- Added `/rate-limit-options` to `/help` and the command menu for claude.ai subscribers, so the usage-limit notices that mention it point to a command you can find
- Added `/mcp reconnect all` in the interactive terminal to retry every MCP server that failed to connect or needs authentication at once
- Added Claude apps gateway startup warnings when a managed policy’s `availableModels` is empty, or leaves out the model Claude Code starts on without setting `model` or `enforceAvailableModels`
- Added `auth: { google: {} }` for Claude apps gateway `telemetry.forward_to` destinations, so telemetry can be exported straight to Google Cloud’s OTLP endpoint using the gateway’s Google Cloud credentials
- Added certificate client authentication (`private_key_jwt`) between the Claude apps gateway and its identity provider, for identity providers that issue certificate credentials instead of client secrets
- \[VSCode\] Added an optional time above each prompt and response, with a date line where the day changes (Claude Code: Show Message Timestamps setting, off by default)
- \[VSCode\] Added plugin load errors and notes to the Manage plugins rows, with a popup to disable, uninstall or copy the error
- \[VSCode\] Added an Ultracode on/off switch under the Effort slider, replacing the slider’s Ultracode stop; the model pill shows ”· Ultracode” at any effort level
- \[Claude Tag\] Added model family choices such as “Opus (latest)” for a thread, a channel default or your DM, so the choice follows the newest model in that family
- \[Claude Tag\] Added the spend that counts toward your organization-wide limit to the analytics spend projection chart, with how much of the limit is used

**Changed**

- Changed interactive terminal and VS Code sessions to start in auto mode when no permission mode is configured, on every plan and provider; `permissions.defaultMode` still overrides it
- Changed Ultracode into its own toggle in `/effort` (Tab, or `/effort ultracode [on|off]`): it no longer forces xhigh effort and stays on at any effort level
- Changed retries after a dropped connection mid-response to share one budget with the rest of the request’s retries, so a failing request gives up sooner
- Changed the notice shown when a Sonnet model’s safeguards flag a message to explain why it happened and to offer editing and retrying
- Changed safety-related model switches in sessions that pin an Opus model with `ANTHROPIC_DEFAULT_OPUS_MODEL` or `modelOverrides`: on the Anthropic API, the API now picks the model to switch to for each kind of flag, not the pinned model
- Changed the non-interactive first turn to still wait up to 2s for connecting MCP servers named by `--allowedTools` or an `mcp_tool` hook, even when `CLAUDE_CODE_MCP_STARTUP_WAIT_MS` is `0`
- Changed `/recap` to decline with a short notice when it arrives relayed from a chat thread (your own included) or from a routine or webhook; typed in the terminal, the Claude apps, Remote Control, `-p` or an SDK host, it runs as before
- Changed `/artifacts` to show its filter tabs beside the title with one-word labels (All, Mine, Shared), using the same tab bar as `/config` and `/plugin`
- Changed artifact publishing to refuse a file on a network share (a `\\host\share` path or a `/net` automount) unless it is on a mapped network drive added with `--add-dir`
- \[VSCode\] Changed `CLAUDE_CONFIG_DIR` in the `claudeCode.environmentVariables` setting to apply only when it is an absolute path, and passed it to terminals that continue the chat
- \[Claude Tag\] Changed Claude to post its private sign-in notice at every @mention from someone who hasn’t connected their Claude account, instead of going quiet after the first

Show 18 improvements

- Improved the usage-limit wait: the limit’s state and the countdown with the usage-credits option now show as one block under the prompt, and limit messages no longer repeat the countdown
- Improved the “No such tool available” error for Claude in Chrome tools called without their prefix: it now names the tool to call
- Improved Monitor event rows to show what each event printed instead of repeating the description, and stopped repeating an unchanged “Waiting for N … to finish” line after every event
- Improved Workflow tool sandbox hardening for errors thrown by async script hooks
- Improved startup time and memory use by building only the parts of the settings schema that your settings files actually use
- Improved `/claude-api`: `hillclimb` no longer spends rounds on prompt rewordings too small for the eval to measure, and an extra page you ask for beside `report.html` is built as one local file that loads nothing from the network
- Improved lists such as `/tasks`, `/copy` and `/hooks`: the details after each name now line up in one column when they fit, and otherwise sit at the right edge
- Improved `claude plugin marketplace add` to say when it replaces a marketplace already added under the same name from a different source, and how to undo it
- Improved the startup refusal when managed settings require a sign-in (`forceLoginMethod` or `forceLoginOrgUUID`) and an API key, token or `apiKeyHelper` is configured: it now names the credential in use, where it is set, and how to remove it
- Improved auto-memory loading: invisible characters and tags that imitate Claude Code’s own markup are neutralized in `MEMORY.md` and recalled memory notes before they reach Claude
- Improved `claude remote-control`: in a folder you haven’t trusted yet, it now asks for workspace trust on the terminal instead of exiting
- Improved artifact pages: Claude writes its design plan into the page instead of the reply, and uses the name you already gave something as the page title
- Improved the Artifact tool so that when Claude is given a claude.ai chat or project link, an artifact from a chat, or an artifact id on its own, it asks for the right link or the content instead of stopping
- \[Claude Tag\] Improved “Notify members now” in admin settings: one press reaches every workspace your organization claimed in an Enterprise Grid, and more members in large workspaces
- \[Claude Tag\] Improved Claude’s wait notice on self-hosted environments with on-demand runners: it now says whether a runner is starting, a start will be retried, or no runner will start
- \[Claude Tag\] Improved the error shown when adding a channel manager fails because the channel’s Slack workspace can’t be confirmed as connected to your organization
- \[Claude Tag\] Improved a channel’s access lists in admin settings to show the connectors, repositories and plugins an auto-join pattern attaches, and where each comes from
- \[Claude Tag\] Improved adding repositories as a channel manager: when your GitHub sign-in can’t confirm you’re a repository admin, the page asks you to sign in with GitHub

Show 57 bug fixes

- Fixed a damaged response stream showing raw errors such as “JSON Parse error” or “undefined is not an object”, or writing the word “undefined” into an answer, instead of being retried or reported as an interrupted response
- Fixed an overloaded or server error arriving right after a thinking block ending the turn with an error instead of being retried
- Fixed “Prompt is too long” errors that persisted after compacting: when the compacted request is still too long, Claude Code now compacts once more, keeping less of the recent conversation
- Fixed a session whose model is unavailable, with no fallback model left, showing a bare “is currently unavailable” message (or “Something went wrong” in cloud sessions) instead of the model-unavailable notice and its Learn more link
- Fixed Agent SDK sessions crashing when a user message contains an image with a malformed `source`, and failing on every later turn after a malformed document block; a malformed image is now replaced with an explanatory note
- Fixed MCP tool calls in a resumed session failing with “No such tool available” while their server was still connecting; the call now waits up to 10 seconds for the server
- Fixed repeated calls to the plan-usage endpoint after it rate-limits or rejects your login: `/usage`, `/extra-usage` and IDE usage views now back off instead of re-asking
- Fixed `claude mcp add` reporting success when managed settings restrict MCP servers to plugins; it now refuses and says what to do, instead of saving a server that never loads
- Fixed the `/plugin` configure screen: boolean options are now a true/false choice instead of free text, number options refuse invalid input, and ←/→ change an options field instead of switching tabs
- Fixed `ANTHROPIC_FOUNDRY_RESOURCE` being interpolated into the Foundry endpoint host unvalidated; a value that is not a plain resource name is now refused
- Fixed Claude Desktop behind a Claude apps gateway offering no 1M context option: the gateway now marks each 1M-capable model for Desktop automatically
- Fixed ↓ in shell mode selecting a hidden background-tasks pill, which stopped Backspace and Ctrl+U from editing the prompt
- Fixed Bash tool failing on Windows with many plugins enabled: plugin `bin/` directories that don’t exist are no longer added to PATH, and inherited entries aren’t added twice
- Fixed `sparsePaths` plugin marketplaces cloning empty and replacing a working local copy on older git (before 2.39), which failed every refresh with “marketplace.json file is no longer present”
- Fixed fullscreen rendering erasing the terminal output above the session when `[` in transcript mode writes the conversation to scrollback (macOS and Linux)
- Fixed fullscreen scroll position jumping to the previous message or to the bottom when a reply finished streaming while scrolled up
- Fixed tab bars in dialogs such as `/config` and `/plugin` breaking the title and tab labels mid-word in a narrow terminal; a tab that doesn’t fit now moves to the next line whole
- Fixed the `/model` picker showing “+1 model” below the list after scrolling to the last model; the count now covers only the models below the visible rows
- Fixed `/keybindings` writing Backspace and Delete bindings for a footer action that does nothing into the generated `keybindings.json`
- Fixed a rebound agent panel close key (`footer:close`) typing “x” instead of itself on the row of the agent you’re viewing
- Fixed vim mode `.` not repeating text typed very fast (for example over ssh or in tmux) or pasted without bracketed paste, and leaving the prompt in INSERT mode after repeating a change with nothing typed (such as `cw` then Esc)
- Fixed vim mode leaving the cursor on an image placeholder’s opening bracket after `dd` on the last line or `yy` at the end of the prompt, where `r` or `x` would break or delete the image
- Fixed a key pressed the instant the terminal regained focus answering the Remote Control enable prompt before its short safety delay restarted
- Fixed the workspace trust dialog appearing a second time after switching renderers or updating when Claude Code was started in the home directory
- Fixed rules symlinked into `.claude/rules` from outside the project being skipped without ever showing the external-imports approval prompt; a `.claude` directory symlinked from outside the project now asks for the same approval
- Fixed plugins from marketplaces, claude.ai and npm pre-approving their own tools via `allowed-tools` under managed `allowManagedPermissionRulesOnly`; only plugins from an official Anthropic source or a source that managed settings vouch for keep that pre-approval
- Fixed a failed first `claude plugin install` leaving the plugin enabled and recorded when a dependency’s version range could not be met
- Fixed the debug log dropping a failed hook’s stderr when the hook also wrote to stdout, and logging nothing for a failed hook with no output; failed hooks now also log their status code
- Fixed `{"decision":"block"}` returned by Elicitation and ElicitationResult hooks being ignored; it now declines the MCP elicitation, as exit code 2 does
- Fixed sessions launched without the `SendMessage` tool (such as by Claude Desktop) still being told to message other sessions with it
- Fixed a photo sent from the Claude app over Remote Control being lost when its queued message was pulled back into the terminal prompt to edit, and the cursor moving one character for a photo with no caption
- Fixed typing a message during an automatic usage-limit wait taking the wait out of the “Continue automatically at usage limit” setting’s control when that turn hit the limit again
- Fixed usage-limit warnings suggesting `/upgrade` to users already on the highest Max plan; the warnings and `/upgrade` itself now point at `/usage-credits` when it is available
- Fixed the Explore subagent switching to Opus on the Claude API when the session runs a model ID Claude Code doesn’t recognize, such as a custom model behind a proxy; Explore now inherits that model
- Fixed `/loop` status updates in self-paced mode often not being shown because Claude wrote them only in its reasoning; Claude now writes each update, and the outcome when the loop stops, as visible text
- Fixed `/ultrareview` failing to upload the working tree when started from a git worktree that the Claude desktop app created on macOS or Linux
- Fixed sandboxed Bash commands failing to start on Linux when the working directory is write-denied and contains a read-denied directory
- Fixed artifact database write results telling Claude that every viewer sees a write to a viewer’s private `data/users/` subtree, and added a “view” level to `as_level`
- Fixed the Claude apps gateway answering `431 Request Header Fields Too Large` to every request from a sign-in whose identity provider lists many groups; it now accepts request headers up to 256 KiB
- \[VSCode\] Fixed Reload Claude from the Memory dialog restarting before an edited file was saved
- \[VSCode\] Fixed a restored tab opening a conversation another Claude process still has open; it now asks first
- \[VSCode\] Fixed Focus view sections you expanded closing on their own while a sub-agent is working or when the section’s first step is trimmed from view
- \[VSCode\] Fixed typing `/model` and Enter printing usage text into the chat instead of opening the model selector
- \[VSCode\] Fixed `/feedback` on Vertex, Bedrock and Foundry being refused after you pressed Send; the report is now saved on this computer, as the terminal does
- \[VSCode\] Fixed sign-in waiting up to a minute for the Python extension after a window reload
- \[VSCode\] Fixed Claude Code tabs that stopped responding after Restart Extensions: they now reopen on their conversation
- \[VSCode\] Fixed a message from another agent with no recorded sender showing as raw XML in the chat
- \[VSCode\] Fixed messages from other agents, sessions or channels disappearing after a reload
- \[VSCode\] Fixed a user’s own `/mcp`, `/config` or `/settings` command being shadowed by the extension’s dialog
- \[VSCode\] Fixed Escape stopping every background agent when no turn was running
- \[VSCode\] Fixed plugin install links replacing a marketplace you already have that uses the same name
- \[VSCode\] Fixed “Prompt is too long” errors after compaction when a large text file is attached to a message
- \[VSCode\] Fixed chat links to files with non-ASCII characters, spaces or brackets in their path not opening
- \[Cloud sessions\] Fixed a routine’s Edit and Duplicate controls saying the routine was still loading while you were offline; they now tell you you’re offline
- \[Claude Tag\] Fixed the earlier Claude in Slack app’s progress card and link previews omitting the repository and Create PR button when a GitHub Enterprise host name contains an underscore
- \[Claude Tag\] Fixed Claude staying silent in a channel whose environment declines to start it; it now posts one notice asking you to contact an admin, and retries when @-mentioned
- \[Code Review\] Fixed Code Review giving up without posting a finished review when an unsubmitted review under its GitHub App was open on the pull request; it now retries the post first

[​](#2-1-283)

2.1.283

September 25, 2026

**Added**

- Added `x-claude-code-prompt-id` to the gateway hint headers so LLM gateways can group the requests that serve one user prompt; opt in with `CLAUDE_CODE_GATEWAY_HINT_HEADERS=1`
- Added `availableModelsMatch` managed setting: with `"exact"`, an `availableModels` entry allows only the model version it names, so new releases stay blocked until listed
- Added `deniedModels` managed setting to block specific models, even when `availableModels` allows them
- Added MCP tool, WebFetch and WebSearch outputs to the `tool.output` OpenTelemetry span event when `OTEL_LOG_TOOL_CONTENT=1`
- Added `/doctor prompt-audit` (also `/checkup prompt-audit`) to audit your CLAUDE.md files, skills, agents and commands for prompting patterns written for older models
- Added click-to-expand for truncated messages from your other sessions in fullscreen mode
- Added `path` to `--plugin-dir` load-failure entries in the stream-json `system/init` `plugin_errors`, naming the directory that did not load
- Added an opt-in `load_test_mode` block to the Claude apps gateway config: requests are built and signed but not sent upstream, and clients get a canned reply, so a deployment can be load tested
- Added a `mantle` upstream provider to the Claude apps gateway for Amazon Bedrock’s Mantle endpoint
- \[Claude Tag\] Added a “Channels Claude can search” admin setting that limits Claude’s Slack search to public channels it has been added to, set per organization, workspace or channel
- \[Claude Tag\] Added a Back to Slack button on the page shown after connecting your Claude account, returning you to the thread you started from

**Changed**

- Changed interactive sessions on third-party providers or with telemetry off to start in auto mode when no permission mode is configured; `permissions.defaultMode` still overrides it
- Changed the `/ultrareview` launch dialog to say that reviewing a local branch may upload uncommitted changes to tracked files
- Changed the `/model` picker’s Opus row and the Default model’s name to drop “(1M context)” where Opus already has a 1M context window; the window is unchanged
- Changed prompt suggestions in the terminal to appear less often after 20 in a row go unused; using one brings them back
- Changed `--system-prompt` and `--append-system-prompt` to accept their text and `-file` forms together; the file’s text comes first
- Changed `Skill(anthropic-skills:<name>)` deny rules to also block that skill when Claude Desktop delivers it as a plugin, and `Skill(skill:<name>)` denies to match the skill’s alias and display name
- Changed `/rewind` and `/diff` lists to move on the same keybinding actions as every other list (`select:*`); `messageSelector:*`/`diff:*` rebinds still work
- Changed the `/workflows` run list to size itself like other lists: half the terminal inline, and it keeps its title on screen when the prompt shows below
- Changed `claude plugin eval` to require git 2.31 or later when git is installed; a run on an older git is refused with a message naming the version
- Changed artifact watching: a watch that was armed automatically (not one you asked for) now ends after 3.5 hours with no activity; publishing or watching the artifact again re-arms it
- Self-hosted runner: Changed lifecycle hooks’ git to skip a repository’s Git LFS `pre-push` hook, ignore a writable system `core.hooksPath`, and not sign commits without `--configure-git`
- Self-hosted runner: Changed `GIT_SSL_CAINFO` and `GIT_SSL_NO_VERIFY` under Anthropic-managed git: the runner’s own git always verifies Anthropic’s git route, and warning lines say what applies where
- Reverted the 2.1.282 reservation of the `claude-ai` name: skills, commands, workflows and MCP servers’ skills and prompts so named load again, and `Skill(claude-ai:*)` rules are ordinary prefix rules
- \[Cloud sessions\] Changed new routine schedules to default to a few minutes past the hour, with a note that routines set exactly on the hour can start several minutes late

Show 16 improvements

- Improved the `/mcp` tool list: it shows more tools at once, scrolls with the page keys and mouse, and marks tools your organization blocked with a warning icon
- Improved MCP tool results: images returned by MCP tools are now also saved to a file, so Bash, Read and other tools can open them
- Improved `/tasks`: rows show a status icon, the name and whole facts, the title and key hints stay on screen with many tasks, and the list gains paging keys, the mouse wheel and clicks
- Improved lists in `/help`, `/hooks`, `/copy`, `/chrome`, `/memory`, `/ide`, `/release-notes`, `/rewind`, `/diff`, `/remote-env`, `/plugin` and other pickers with page keys, mouse wheel and clicks
- Improved lists beside a search box, such as `/skills` and `/artifacts`, to draw their pointer dim while the search box has the keys, so only one pointer is highlighted
- Improved the compaction spinner: its timer now starts when compaction begins and it counts the summary’s tokens as they stream, replacing the percentage bar
- Improved the browser page shown after signing in to an MCP server: centered layout, dark mode, and new artwork
- Improved the Skill tool’s reply when a skill belongs to a plugin that failed to load, so Claude tells you the plugin could not be loaded instead of calling the skill uninstalled
- Improved `prompt-audit` on Claude Code configuration: stale paths, stale commands and contradicting instruction files now lead the report, and thinking keywords that Claude Code documents are kept
- Improved recovery from an `installed_plugins.json` that cannot be read at all: its contents are kept in a file beside it before it is rebuilt, and `claude plugin list` names that file
- Improved artifact database reads: an ordered query that returns a full page now says it is one page and how to read the rest
- Improved first-reply latency: a pattern-compile step that ran at the end of a session’s first reply now runs while the reply streams in
- Improved first-request latency by reusing the preconnected API connection
- Improved startup: `claude -p` and Claude Code Remote no longer load the interactive UI, and the auto-mode classifier’s rules and the Artifact tool load on first use instead of at launch
- Improved startup for claude.ai accounts whose Artifact tool features aren’t known yet, as on a first run: the prompt no longer waits up to 1.5 s to check them; the first message waits if needed
- \[Cloud sessions\] Improved adding a repository to a running cloud session: a private repository your GitHub account can read but not push to now attaches for reading

Show 53 bug fixes

- Fixed SDK sessions losing a deferred tool call or finished tool result when a turn ended early, a held approval prompt after a worker restart, and a non-streaming fallback’s `result.usage`
- Fixed MCP progress notifications being discarded once a long-running tool call moved to the background; the background task now shows the latest progress
- Fixed stdio MCP servers being left running when the session ended while they were still starting
- Fixed a brief HTTP 404 from a stateless remote MCP server (for example a proxy mid-redeploy) leaving that server unusable for the rest of the session while still shown as connected
- Fixed MCP sign-in for a server with no valid URL failing with an opaque SDK error; `/mcp` no longer offers Authenticate for such servers
- Fixed the weekly Fable limit not appearing in `/usage` and the VS Code usage meters when telemetry is disabled
- Fixed `/model` accepting Sonnet 4.6 or Sonnet 5 with `[1m]` when the id carried a date or `-v1:0` suffix, in the cases where the plain id was refused
- Fixed `/model` picker showing a hardcoded Haiku version and price when `ANTHROPIC_DEFAULT_HAIKU_MODEL` pins a different model
- Fixed dynamic workflows started during a model fallback running every agent on the fallback model instead of retrying the configured model
- Fixed `DISABLE_PROMPT_CACHING_HAIKU` having no effect when Haiku is the session’s main model
- Fixed `claude plugin validate` saying Claude Code accepts a plugin or marketplace name it cannot install; such names in `marketplace.json` now fail validation
- Fixed `claude plugin validate` passing plugins whose `outputStyles`, `themes`, `monitors`, or `lspServers` paths are missing or point outside the plugin directory
- Fixed `claude plugin details` showing 0 MCP servers for plugins that declare their servers in `plugin.json`
- Fixed `claude plugin marketplace remove` not saying which installed plugins it uninstalled with the marketplace; it now lists them
- Fixed `claude plugin uninstall` removing the other of two installed plugins whose ids differ only in case, with its options and secrets, when the one named had no `enabledPlugins` entry at that scope
- Fixed plugins that declare no version being silently restored at their source’s newest commit, not the installed one, when their cached files were missing
- Fixed user-installed plugins and marketplaces failing to load with “cache-miss” after the home or config directory was moved, for example in bind-mounted devcontainers
- Fixed `installed_plugins.json` showing no plugins when it holds a record under an invalid plugin id; such a file loads again
- Fixed `installed_plugins.json` being rewritten, losing records, when it holds a record this version cannot read; `claude plugin` commands now name the record and say how to recover
- Fixed permission dialogs in screen-reader mode reading quoted commands and paths as if they were the dialog’s own text
- Fixed `/context` not counting MCP server instructions: they now appear as their own row and count toward the total
- Fixed markdown links in the Warp terminal rendering as plain text instead of clickable hyperlinks
- Fixed `claude mcp add`, `add-json`, and `remove` reporting success when the user or local config file could not be written, for example inside a sandbox
- Fixed the first words of a reply in a cloud session sometimes appearing late instead of streaming as Claude writes them
- Fixed Claude’s built-in keybindings guide saying chords time out after 1 second instead of 3, and calling `cmd` an alias of `meta`, which could produce `cmd+` shortcuts most terminals never send
- Fixed `keybindings.json` silently accepting a misspelled modifier such as `ctl+k`; it now warns in the debug log and suggests the fix
- Fixed footer hints still saying “Enter to view” after `footer:openSelected` was rebound or unbound in `keybindings.json`
- Fixed keys typed quickly together (type-ahead, key repeat, bursts over ssh or tmux) sometimes being handled against stale state
- Fixed worktree checkouts failing certificate verification (for example on Git LFS downloads) when the CA certificate is passed to git as `GIT_CONFIG_COUNT` environment pairs
- Fixed sandboxed `git` asking credential helpers to store the sandbox proxy’s login, which printed “failed to store”
- Fixed managed `sandbox` settings being ignored entirely when one nested value was invalid; the invalid value now fails closed and the rest of the block still applies
- Fixed Claude’s edits to its own auto-memory notes being blocked as sensitive-file writes when Claude Code was started in a subdirectory of a git repository
- Fixed Remote Control being unavailable on paid plans when telemetry is turned off with `DISABLE_TELEMETRY` or `DO_NOT_TRACK`
- Fixed the `/remote-control` menu cutting its QR-code hint mid-word in narrow terminals
- Fixed vim mode `.` dropping a Shift+Enter newline, leaving the cursor inside an accented letter, and repeating an older change after `3J` or Visual-mode `J` on the last line
- Fixed vim mode cursor placement: recalling a prompt over 10,000 characters in normal mode no longer leaves the cursor past the end, and `V` then `p` now lands on the first non-blank
- Fixed vim mode `J` joining lines with different spacing than Vim (such as a space before `)` or after a tab), and `3J` or Visual-mode `J` on the last line not moving the cursor as Vim does
- Windows: Fixed the PowerShell tool letting `cmd /c rd`, `rmdir`, `del` or `erase` delete drive roots, the home folder and other folders that `Remove-Item` refuses
- \[VSCode\] Fixed the permission mode indicator showing Default while the session kept running in auto or bypass mode after an automatic switch out of it failed; the switch is now retried until it lands
- \[VSCode\] Fixed a session teleported from the web dropping the messages sent while Claude was working
- \[VSCode\] Fixed a Web session staying hidden from the session list, and an empty chat opening in its place, when an older version had saved an empty local copy of it
- \[VSCode\] Fixed a reopened session splitting a turn at a message Claude received mid-turn, such as an automatic continuation
- \[VSCode\] Fixed a reloaded session showing a rewound-away turn, or only the rows before a compaction
- \[VSCode\] Fixed the footer’s agents pill drawing its icon off-center, with the status dot against the edge, in narrow panels
- \[VSCode\] Fixed the chat input showing its text slightly below the cursor and selection after pasting lines that end with a line break into a long prompt
- \[Cloud sessions\] Fixed cloud sessions occasionally redoing an already-finished step, such as posting a duplicate comment or push, after recovering from a server-side restart
- \[Claude Tag\] Fixed a channel’s configure page listing no connectors or plugins when the channel gets its access bundle through an attach rule; rule-attached bundles are now shown
- \[Claude Tag\] Fixed access-bundle repository search missing repositories on GitHub App installs that are limited to a large list of selected repositories
- \[Claude Tag\] Fixed Claude occasionally posting the same reply twice when a new message interrupted it mid-reply
- \[Claude Tag\] Fixed channel routines that stopped running in older private channels whose Slack channel ID changed, for example after a Slack Connect share
- \[Claude Tag\] Fixed conversations in a channel set to “Channel only” all ending when a non-guest member joined and Slack was slow to confirm their membership
- \[Code Review\] Fixed “@claude review” requests going silent when GitHub failed to return the pull request: the request is retried once, and a comment explains if it still fails
- \[Code Review\] Fixed billing for a review that stopped at its time limit with nothing verified: it now shows as incomplete, isn’t charged, and is retried once

[​](#2-1-282)

2.1.282

September 24, 2026

**Added**

- Added a `maxProseWidth` setting that caps the width of Claude’s prose in wide terminals while tables and code blocks keep the full width
- Added a startup notice, and `/status` and `claude doctor` entries, listing telemetry variables in a project’s settings files that were ignored or that turned telemetry off
- Added the `allowClaudeInChromeWithManagedMcp` managed setting to let `claude --chrome` run alongside an exclusive `managed-mcp.json`; the error shown when Chrome is blocked now names it
- Added `store.readiness_grace_seconds` to the Claude apps gateway so `/readyz` can stay ready through a short Postgres outage such as a database failover
- Added a scrollbar to the `/feedback` drafts list in fullscreen mode; it appears while the mouse is over the list
- \[Cloud sessions\] Added Claude GitHub App status to Settings › Connectors › GitHub: whether the app is installed and reachable for your account, plus steps to connect, install or reconnect
- \[Cloud sessions\] Added “Open repository” and “Open compare page” links to the repository menu of a cloud session whose repository is hosted on a Git server other than GitHub
- \[Cloud sessions\] Added attaching a repository from a different GitHub owner, such as a fork’s upstream, to a running cloud session that already has one, including sessions started from Slack

**Changed**

- Updated the `claude-api` skill: pre-output refusal billing now links to the How refusals are billed docs, mid-stream refusals bill at normal rates, and pre-output refusals count against rate limits
- Updated the `claude-api` skill to recommend `ant apply` for keeping Managed Agents resources as version-controlled files
- Changed auto mode to use the server-side classifier by default on a direct Anthropic API connection when telemetry is off (`CLAUDE_CODE_AUTO_MODE_SERVER=0` opts out)
- Changed `sandbox.excludedCommands` to ignore project and local settings entries when managed settings or `--settings` set `allowUnsandboxedCommands: false`, or managed `allowManagedDomainsOnly: true`
- Changed project and local settings to ignore OpenTelemetry variables that turn on export, set its endpoint, or capture content, like `CLAUDE_CODE_ENABLE_TELEMETRY` and `OTEL_LOG_*`
- Changed Windows/WSL managed settings so an admin policy that is present but invalid or unreadable (HKLM, `managed-settings.json`) keeps user-writable HKCU and WSL `/etc/claude-code` from applying
- Changed `Skill(anthropic-skills:*)` and `Skill(claude-ai:*)` allow rules to cover only skills synced from claude.ai, not plugins or other skills that merely use such a name
- Changed skill folders, command files and workflow commands in the `anthropic-skills` or `claude-ai` namespace to no longer load; a plugin so named still loads but yields name ties to synced skills
- Changed MCP servers configured under the name `anthropic-skills` or `claude-ai` to list no skills or prompts (their tools still work); rename the server in your MCP configuration to list them again
- Changed the `ultracode` visuals in `/effort` and the prompt input to plain styling (no ripple, border flourish or keyword glimmer) and removed the dynamic-workflows spinner tip
- Changed the Clawd mascot’s feet in the start-up banner to sit under the corners of his body
- \[Claude Tag\] Changed the bordered cards Claude uses in Slack replies for plans, tables and details to render wide by default instead of a narrow width
- \[Claude Tag\] Changed newly connected Slack workspaces to follow the current default model instead of keeping whichever model was the default when they were connected

Show 6 improvements

- Improved the time to resume very large sessions, including ones that were never compacted
- Improved the error shown on Windows when a session can’t be resumed because its transcript file could not be read (EBADF): it now names possible causes and what to try
- Improved the Claude Desktop unknown-model error to suggest switching to a different model
- Improved rendering of unusual Unicode in permission prompts
- Improved `/artifacts`: titles line up in one column, details are dropped whole instead of cut mid-word, and the list supports PgUp/PgDn, Home/End, the mouse wheel and clicks
- \[Cloud sessions\] Improved how quickly the Routines page and the sidebar’s Scheduled list load for accounts whose past sessions scheduled many check-in reminders

Show 59 bug fixes

- Fixed every request failing with a 400 error in conversations whose history holds web search results the API cannot decrypt (for example, from a turn answered through a third-party gateway)
- Fixed more cases of continued or resumed sessions (`--continue`, `--resume`) re-sending earlier messages in a changed form, which could make the API drop Claude’s earlier reasoning
- Fixed earlier extended thinking being dropped when `/model`, `/rename`, `/artifacts` or another immediate slash command was used while Claude was working
- Fixed continued or resumed conversations losing earlier extended thinking when relaunched with a `--tools` list that leaves out a built-in tool offered earlier in the conversation
- Fixed sessions failing on every turn with an “Invalid `data` in `redacted_thinking` block” API error; Claude Code now drops the conversation’s thinking blocks and retries once
- Fixed compaction failing when the summarization request is refused; it now retries on a fallback model
- Fixed a failed turn (“Effort ‘xhigh’ isn’t available with thinking turned off”) after a safety-related model switch in sessions with thinking off and effort above high
- Fixed an unanswered Fable usage-credits prompt switching models in SDK-hosted sessions such as Claude Desktop; the turn now ends instead, and Remote Control clients now see the model-switch notice
- Fixed `/model` with a full Fable model id stopping at an API error instead of opening the usage-credits prompt when the plan needs usage credits that aren’t turned on yet
- Fixed requests failing for up to a minute with an “another Claude Code process is refreshing it” login error after that other process was closed or killed mid-refresh
- Fixed sessions started while another Claude Code window was refreshing the sign-in (common with several VS Code windows) not retrying their organization policy fetch
- Fixed CLAUDE.md and rules being read at startup through a repository symlink reaching macOS’s `/Network` via `..` or a `/.vol`-style kernel path, or a rules link to macOS’s `/home` being listed
- Fixed Bash permission rules with a mid-pattern `:*` being skipped in settings files while `--allowedTools` honored them; they now work from every source, with a startup warning on how they match
- Fixed a command approved on a restored permission prompt running twice when a remote session’s worker restarted
- Fixed managed settings ignoring a mistyped value for boolean lock keys such as `disableClaudeAiConnectors` or `allowManagedPermissionRulesOnly`; the lock now applies and startup names the key
- Fixed managed `permissions`, `autoMode`, `worktree` and `attribution` settings being ignored entirely when one nested value was invalid; the rest of the block now still applies
- Fixed repository, user and `--add-dir` skills, commands and skills-directory plugin manifests pre-approving their own tools via `allowed-tools` under managed `allowManagedPermissionRulesOnly`
- Fixed safeguard block messages on Amazon Bedrock and Bedrock Mantle not showing a request ID; block messages now also show the message ID
- Vertex AI: Fixed web search not being offered for models Claude Code doesn’t recognize yet, such as newly released ones
- Fixed Bash and PowerShell hiding a full disk quota behind “Exit code 1” and leaving large output files in temp
- Fixed tool input validation errors naming only an unknown, missing or mistyped parameter when other parameters in the same call were also invalid; those are now listed too
- Fixed pasted multi-line text being submitted line by line after the terminal’s bracketed paste mode was reset mid-session
- Fixed the prompt’s example text flashing and disappearing at startup in projects with a `SessionStart` hook
- Fixed a blank screen flashing before the first frame when starting in fullscreen mode
- Fixed garbled, misplaced rows in the non-fullscreen renderer after the screen got shorter while still taller than the terminal, e.g. deleting a prompt line while a shell command streams output
- Fixed a stale character left in the last column of a diff when a redrawn line’s CJK character or emoji wrapped to the next row
- Fixed the cursor landing before the end of a prompt recalled from history when the prompt contains a tab
- Fixed the send-now hint showing ctrl+enter on terminals that send it as a newline (Windows Terminal before 1.25); it now shows ctrl+x ctrl+s there
- Fixed `claude remote-control --debug` failing with “Unknown argument: —debug”, although Remote Control’s own eligibility error says to run with `--debug`
- Fixed `/install-github-app` saying “cancelled” and then still pushing the branch and saving the API key secret; leaving now stops the remaining steps and reports what was already done
- Fixed /feedback, /bug and /share on Bedrock, Vertex and other third-party providers still saving the report file after you cancelled during the save
- Fixed plugin uninstall reporting success and deleting the plugin’s saved options when its settings file still enabled it or could not be read; it now stops and names the file
- Fixed plugin uninstall deleting a plugin’s saved options and secrets when the list of installed plugins could not be read after the removal; they are now kept and the uninstall says so
- Fixed a key typed right after `/` in `/skills` moving the skill list instead of reaching the search box
- Fixed the terminal cursor jumping from the `/skills` search box to the skill list while typing, which could hide the caret and put IME input in the wrong place
- Fixed lists with a scrollbar, such as `/skills` and `/mcp`, being two columns narrower outside fullscreen mode, where the scrollbar can never appear
- Fixed the agent panel footer wrapping onto two lines with long rebound keys, and its “Esc to collapse” hint ignoring a rebound collapse key
- Fixed a doubled `·` separator in the `/tasks` dialog footer when the stop-all-agents shortcut is unbound in `keybindings.json`
- Fixed artifact publishes failing when Claude gave the version a label longer than 60 characters; the label is now shortened
- Fixed screen-reader mode, quoted lists and very long lists dropping the blank lines at the top of a code block that opens a list item, directly or inside a quote
- Fixed PDF page-read error messages: paths with accented or non-Latin characters now appear readably, and a folder named like “password” or “invalid” can no longer make the error name the wrong cause
- Fixed vim mode `>>` indenting empty lines, `r` with a count longer than the line changing text, `2J` joining one line too many, and a count on the last line (`2dd`, `2>>`) shifting or deleting it
- Fixed vim mode cursor placement: after `dd`, `dj`, `dG` or a whole-line `p`/`P` it lands on the first non-blank, `yy` no longer moves it, and Esc after an emoji no longer leaves it inside the emoji
- Fixed vim mode ignoring a count typed before `.` when repeating `x`, `s`, `p`, `d` or `c`, and whole-line `p`/`P`, `o`, `O`, `J`, `>>` and `<<` acting on the wrong line when a line above wraps
- Fixed vim mode leaving the cursor past the end of a prompt recalled from history or pulled back from the queue in normal mode, so `x` did nothing
- \[VSCode\] Fixed long replies falling behind the stream: the panel no longer re-parses the whole reply on every update
- \[VSCode\] Fixed the dictation mic button covering the message input’s scrollbar when the input is tall enough to scroll
- \[VSCode\] Fixed Remote Control sessions started on this computer not opening from their Web entry in the session list; they now open the local conversation unless it’s running elsewhere
- \[VSCode\] Fixed an editor tab’s sign-in screen hanging silently after the extension host restarts; it now shows the “stopped responding” notice too
- \[Cloud sessions\] Fixed the next run time shown for an hourly routine being 30 minutes off for people in half-hour-offset time zones such as India
- \[Claude Tag\] Fixed auto-join channel patterns saved for one workspace in Claude Tag admin settings being ignored on an Enterprise Grid org-wide install; Claude now joins matching new channels
- \[Claude Tag\] Fixed Claude not responding in an Enterprise Grid channel shared between two workspaces of one organization when the channel’s Claude Tag version was saved from the other workspace
- \[Claude Tag\] Fixed the earlier Claude in Slack app’s progress card for sessions on a GitHub Enterprise Server repository: it now names the repository and offers a working Create PR button
- \[Claude Tag\] Fixed Slack threads whose model has been retired falling back to another model on every reply, slower and with a fallback note each time; the thread now moves to a working model
- \[Claude Tag\] Fixed files Claude uploads to Slack not being able to carry a caption containing a table; captions now render with the same formatting as replies
- \[Claude Tag\] Fixed Claude’s threads in Slack’s Agents & tools view sometimes being listed under their first message instead of their name; later renames now update the list too
- \[Claude Tag\] Fixed removing a GitHub organization’s grant from an access bundle’s Repositories tab in Claude Tag admin settings failing to save after that GitHub organization was disconnected
- \[Claude Tag\] Fixed Claude always replying “Couldn’t check this channel just now” in a channel shared with a Grid workspace it isn’t added to; the notice now says which workspace needs the app
- \[Claude Tag\] Fixed the cost and token totals in Claude’s reply footer reading many times too high after the session’s cloud worker restarted

[​](#2-1-281)

2.1.281

September 23, 2026

**Added**

- Added Claude apps gateway support for newer Claude Desktop keys in `desktop` policy blocks, including `blockReadsOutsideWorkingDirectories` and `disableBypassPermissionsMode`
- Added `assume_role` on Claude apps gateway Bedrock upstreams: the gateway calls Bedrock as an IAM role it assumes through STS, in another AWS account if needed, optionally one session per developer
- Added `guardrail: {id, version}` on Claude apps gateway Bedrock upstreams to apply an Amazon Bedrock guardrail to every request sent through them (set it on all Bedrock upstreams or none)
- Added `telemetry.resource_attributes` to the Claude apps gateway config, to put fixed labels on the telemetry of Claude Desktop and `/login` sessions
- Added `"attribution": false` in `settings.json` to hide all commit and PR attribution; older CLI versions skip a settings file that holds it, so keep the object form in files shared across versions
- Added MCP URL-mode elicitation on 2026-07-28 protocol connections, so servers can ask Claude Code to open a browser-based flow; no waiting dialog is left on screen when the server has no way to confirm completion
- Added MCP server checks to `claude plugin validate`: it reports `.mcp.json` entries that would be silently dropped at load, undeclared `${user_config.*}` references, and insecure URLs
- Added an auto mode recommendation to `/insights` that estimates how many permission prompts auto mode could have handled in your recent sessions
- Added a scrollbar to the `/skills`, `/mcp` and `/plugin` Installed lists in fullscreen mode, like the one `/workflows` now has: it appears while the mouse is over the list and can be clicked or dragged
- \[VSCode\] Added a Continue/Stop prompt in the VS Code and JetBrains panels when auto mode falls back to billed classifier requests, replacing the unanswerable warning line
- \[Claude Code on the web\] Added a Fast mode switch to the composer’s model menu in cloud sessions, shown when your plan includes fast mode and the selected model supports it
- \[Claude Code on the web\] Added a settings shortcut on the GitHub setup tip and a “Troubleshoot GitHub connection” link in the repository pickers, both opening your GitHub connection page
- \[Claude Tag\] Added a short line in the Slack thread after someone presses Stop, naming who stopped Claude’s response and saying to mention @Claude to continue

**Changed**

- Changed send now (ctrl+enter or ctrl+x ctrl+s) to move running tools to the background instead of cancelling the turn
- Changed auto mode so that, where its classifier review runs server-side, read-only and sandboxed shell commands also wait for that review and are blocked when it flags them
- Changed `CLAUDE_CODE_AUTO_MODE_SERVER` to also apply on a direct Anthropic API connection: `0` opts out of the server-side auto mode classifier (the local classifier then counts toward usage), `1` opts in
- Changed the dangerous `rm` prompt in `--dangerously-skip-permissions` and auto mode to wait 2 minutes for an answer, then deny the command with a rewrite hint so unattended sessions keep going (`CLAUDE_CODE_DISABLE_DANGEROUS_RM_TIMEOUT=1` turns this off)
- Changed AGENTS.md support to also work on Amazon Bedrock, Google Vertex AI, Microsoft Foundry, LLM gateways, and sessions with telemetry disabled
- Changed Claude apps gateway to refuse to start when a `managedMcpServers` entry’s `envHelper` path starts with `\??\` or `/??/`, a path form current Claude Desktop refuses to run
- Changed self-hosted runners to pass system prompts to Claude Code as private files instead of command-line text, so large prompts no longer fail the launch; a wrapper or `command` hook that appends `--system-prompt` or `--append-system-prompt` must switch to `--system-prompt-file` or `--append-system-prompt-file`
- Changed queued messages to show in the conversation above the spinner instead of under it
- Changed the session artifact links under the prompt into one footer pill (`⧉ name` or `⧉ N`) that opens `/artifacts`, which now lists this session’s artifacts first
- Changed the Artifact tool to let Claude load scripts from unpkg.com in artifact pages
- Changed hovering a list row in fullscreen mode, including in `/config`, to tint the row instead of drawing a second ❯ pointer beside the focused row’s
- Changed /mcp: each server’s row now starts with its status icon and name, says its state once, and in a narrow terminal drops trailing facts like “managed” before shortening the name
- Changed /workflows: each run’s row leads with its status icon and elapsed time, and a narrow terminal keeps the run’s name and time, dropping the agent and token counts first
- Changed Remote Control attachment downloads to reuse connections and to skip files already downloaded in the session
- Changed MCP resource lists (the resource list tool and @-mention suggestions) to skip MCP Apps UI resources; reading one by URI still works
- Changed `claude plugin uninstall --json` and the /plugin dialog to say a plugin’s data was kept when its folder stays because another installed plugin uses it or install records cannot be read
- Changed the background tasks list (`/tasks`): pressing `x` on a running `/ultrareview` now asks for confirmation before stopping the review
- Removed the leftover “(removed)” `/agents` entry from the command menu and `/help`; typing `/agents` still explains where the wizard went
- \[Claude Tag\] Changed the routine list Claude gives when asked in a Slack thread to show that thread’s own scheduled tasks by default instead of every routine in the channel

Show 33 improvements

- Improved Claude Desktop sign-in and usage-limit error messages to point at the app instead of terminal commands
- Improved startup: managed settings and policy fetches no longer retry requests that can never succeed
- Improved interactive startup time: git reads, startup telemetry and the Bedrock/Vertex model-upgrade checks no longer run before the first frame
- Improved the time to resume long sessions that read many files; the restored file cache now matches the files as they were read
- Improved the time to resume very long sessions that have been compacted, most noticeably through the Agent SDK and Claude Desktop
- Improved “Prompt is too long” recovery in sessions dominated by one very large first prompt: that prompt is now summarized on its own instead of being left out of the summary
- Improved auto mode after resuming a session in a new process: the permission classifier can now reuse its earlier prompt cache instead of rewriting it
- Improved the auto mode denial message so Claude treats a denial as covering the outcome, not only the exact command
- Improved the dangerous-rm check to also flag a removal at a shell variable followed by a top-level directory name, at a variable derived from the working directory, or at a backslash-only target
- Improved sandbox guidance on macOS: when a local dev server can’t bind a port, Claude now points to `sandbox.network.allowLocalBinding`
- Improved `--agents` to accept the path to a JSON file (with `-p`) as well as inline JSON, and to allow an empty `prompt`
- Improved `/batch` to run where a WorktreeCreate hook provides the agent worktrees, not only inside a git repository
- Improved plugin hook-failure errors to name the offending plugin, and added a `claude plugin validate` warning when a shell-form hook leaves `${CLAUDE_PLUGIN_ROOT}` unquoted (it breaks on plugin paths with spaces)
- Improved the `/` menu, `/skills`, `/context` and the `/plugin` Installed list to show skills synced from claude.ai by their short name when no other command uses it, not `anthropic-skills:<name>`
- Improved `/deep-research` reliability on long research briefs by removing unused required fields from the scope step’s output
- Improved the writing in published artifact pages: the bundled artifact-design skill now asks Claude for plain, direct prose
- Improved artifact publishing on slow connections: large page uploads are now sent compressed
- Improved the large CLAUDE.md startup notice to also count instruction files together, so many mid-sized files and @-imports are caught
- Improved debug logs to name settings `env` variables ignored because the session’s launch environment already sets them
- Improved keyboard navigation in tabbed dialogs such as `/permissions` and `/usage`: ↑/↓ move focus between the tab row and the content, and a list responds to keys only while it has focus
- Improved `/help` and `/sandbox`: ←/→ and Tab switch tabs from inside a tab’s list, and ↓ on an empty Custom commands tab in `/help` no longer leaves the keys stuck until Esc
- Improved `/install-github-app`, `/desktop`, the `/permissions` auto mode environment prompts, and the `/plugin` “Add marketplace?” and “Run this command?” prompts: they now use the standard dialog frame with key hints, and Ctrl+C or Ctrl+D cancels them on the second press like other dialogs
- Improved the `/workflows` and `/mcp` lists: they page (PgUp/PgDn, Home/End) and take j/k and the mouse like other lists, their arrows follow `select:previous`/`select:next` rebinds, and `x` in `/workflows` stops the run the pointer is on
- Improved the `/plugin` plugin and marketplace details menus and the `/remote-control` already-connected menu: they now support Home/End and clicking a row
- Improved the background workflow row below the prompt: it now shows the name, a progress bar, the agent count on wide terminals, elapsed time, total tokens, and the large-workflow warning
- Improved the /plugin Installed list: rows now line up in columns (status, name, type, details) across every section
- Improved `/skills`: each row now leads with the skill’s name, with ✔ or ◯ alone showing on or off, and stays on one line in narrow terminals
- Improved narrow list rows (`/skills`, `/workflows`, `/feedback`): a name keeps 20 columns beside its first detail, and details are shown whole or not at all
- Improved `/diff`: a scrollbar shows where you are in a long list of changed files, and long paths no longer wrap their rows
- Improved `/hooks`: a hook’s detail screen now says what kind of hook it is and where to change it, instead of always pointing at settings.json, and the hooks-disabled, safe mode and managed-hooks-only notices each say what is happening in one plain sentence
- Improved screen-reader output in `/mcp`: a disabled server is read as “off” instead of “pending”
- Improved the Remote Control confirmation: its options are briefly inactive again after the terminal window regains focus, so a key pressed while switching back cannot answer it
- \[Claude Code on the web\] Improved the file card shown when a cloud session can’t open a file: it now says whether the file no longer exists or the session’s permission settings block reading it

Show 112 bug fixes

- Fixed a crash (“unrecoverable interface error”) that could end a session while an API request was being retried
- Fixed a turn that could retry indefinitely, ignoring `--max-turns`, when the model alternated unparseable tool calls and output-limit truncation
- Fixed resumed sessions re-sending earlier turns in a changed form (a parallel tool-call turn, an MCP tool call’s input or a tool-search result while its server was still reconnecting, or a tool-search result whose loading turn was interrupted), which could make the API drop the conversation’s prior reasoning
- Fixed resuming a very large session sometimes restoring only its last few messages
- Fixed a session resumed after a restart during a pending permission prompt sending a different history than before, which broke the prompt cache from that point
- Fixed resuming a session that ended during a tool call: Claude now sees the call and is told its outcome is unknown, and a manual resume no longer adds a hidden “Continue” message
- Fixed sessions with an earlier advisor result the API could no longer read failing one request every turn and repeatedly losing earlier reasoning; the history is now repaired once
- Fixed the prompt cache being lost when an MCP server disconnects mid-conversation, or is still connecting after a resume, while tool search is off (for example behind a proxy or gateway)
- Fixed responses cut short by a proxy or gateway that closes the stream cleanly being shown as complete with no warning, and tool calls running twice on duplicated stream events
- Fixed responses failing with “Content block not found” when a proxy drops a stream event mid-response; the partial response is now kept, and web search keeps results that already arrived
- Fixed an empty completed response being requested twice when the connection dropped before the stream’s final event
- Fixed the stop reason being lost when a proxy sends a trailing usage-only frame
- Fixed `CLAUDE_CODE_RETRY_WATCHDOG` sessions failing on the first 5xx or dropped connection after a run of 429/529 waits, and sleeping uncapped and silently on a long `Retry-After` from a 5xx
- Fixed fast mode retrying rate-limited requests back to back when the server sent `Retry-After: 0`
- Fixed a tool that returned an oversized image leaving sibling tool calls unanswered and still running, or ending the turn with no final message
- Fixed conversations getting permanently stuck on “tool_use.name: String should have at most 200 characters” after the model called a tool by an overlong name
- Fixed tool calls failing with “Failed to get memory usage”, or being reported as failed after they ran, when Claude Code cannot read its own memory usage, for example when it has run out of file descriptors
- Fixed `--input-format stream-json` sessions (Agent SDK, VS Code extension) and scheduled cloud sessions failing every turn with an error when an earlier assistant message had plain-string content
- Fixed non-interactive sessions (`-p`, Agent SDK) failing on the next turn after the directory they were started in was deleted mid-session
- Fixed headless sessions with host-side (SDK) MCP servers stalling on the first message when the host stops responding mid-handshake; remote sessions now wait a few seconds at most
- Fixed interactive startup waiting on the managed-settings network request (about 80 ms, 17+ seconds when the network is unreachable) when no MCP servers or plugins are configured
- Fixed a delay of up to two minutes before responding when reading or @-mentioning a PDF larger than 3 MB
- Fixed an interrupted Read of specific PDF pages leaving its page render running for up to two minutes
- Fixed permission dialogs and attachment checks reading a path under macOS’s `/.vol`, `/.nofollow` or `/.resolve` (which can reach a network mount) before approval
- Fixed a recursive `rm` whose target is only command-substitution output, such as `rm -rf "$(pwd)"`, running unprompted in auto and `--dangerously-skip-permissions` mode; it now asks even with a Bash allow rule, unless run with `CLAUDE_CODE_DISABLE_SUBSTITUTION_RM_PROMPT=1`
- Fixed a permission rule containing a NUL byte being expanded into a wildcard match; such a rule now matches nothing
- Fixed sandbox `excludedCommands` entries not matching `git rev-parse --git-dir`, programs named like shell builtins, and commit messages containing `[WIP]` or `#` lines
- Fixed sandboxed Bash commands being unable to write to `$TMPDIR` when `CLAUDE_CODE_TMPDIR` is set
- Fixed `claude --bg` starting a background session, and running its project hooks, in a directory that had not passed the workspace trust prompt; it now asks for trust first, or exits when not run interactively
- Fixed `--setting-sources` (and SDK `settingSources`) not being forwarded to spawned sessions: teammates, `/bg`, `claude agents` sessions and `--worktree --tmux` now start with the parent’s restriction
- Fixed Read, Write, Edit and NotebookEdit: a file path containing a null byte now fails that tool call with a clear error instead of ending the whole turn
- Fixed Write refusing a call that gives the file path or content twice under two parameter names with identical values
- Fixed CLAUDE.md and rules files from an `--add-dir` directory inside the working directory being sent to the model twice in headless and SDK sessions
- Fixed remote sessions staying on “needs approval” with a stale prompt after a permission prompt and a sandbox network-access prompt overlapped and both were answered
- Fixed cloud sessions not telling Claude about background agents that finished just before a worker restart
- Fixed scheduled routine and notification turns in remote sessions not receiving turn-start notices (newly available tools, MCP changes, date, todos) until after the first tool call
- Fixed scheduled tasks and `/loop` wakeups being fired again every second when their delivery failed, which could make Claude Code exit at the end of a turn
- Fixed Remote Control reporting “disabled by your organization’s policy” when the org policy simply hadn’t loaded yet; it now retries the fetch and says it couldn’t verify
- Fixed the Artifact tool missing from Remote Control sessions that `claude remote-control` starts for you to open from Claude Desktop, claude.ai or the mobile app
- Fixed macOS credential writes dropping stored MCP OAuth tokens or deleting the keychain entry when the login keychain was locked (e.g. right after wake)
- Fixed `gcpAuthRefresh`/`awsAuthRefresh` login processes being left running (and holding their localhost callback port on Windows) when Claude Code exits or the refresh times out
- Fixed the “Not logged in · Run /login” footer and missing claude.ai connectors persisting in a session after logging in from another Claude Code process
- Fixed `mcp_tool` hooks on blocking events (PreToolUse and similar) being skipped while their MCP server was still connecting; they now wait for it, up to the MCP connect timeout
- Fixed the same MCP server being connected twice when a plugin or claude.ai connector and a configured server spell its URL differently (host letter case, default port, trailing slash)
- Fixed `MCP_CONNECTION_NONBLOCKING=0` giving up on claude.ai connectors after 1s instead of honoring `MCP_CONNECT_TIMEOUT_MS`
- Fixed `--channels` plugin entries being checked against the installed plugin’s marketplace alone; the installed plugin’s name must now match the entry as well
- Fixed `--plugin-dir` on a folder of plugins that also has a `.claude-plugin/marketplace.json` loading one empty plugin instead of the plugins in it
- Fixed `claude plugin uninstall` refusing to remove a project-scope plugin that isn’t enabled, saying it is “enabled at project scope” while `claude plugin disable` says it is already disabled
- Fixed `claude plugin update` failing for project-scoped plugins when `--scope` is omitted — it now resolves the scope the plugin is installed at instead of assuming user
- Fixed `claude plugin validate` reporting `privacyPolicyUrl`, `supportUrl` and other listing metadata keys in plugin.json as unknown fields
- Fixed `known_marketplaces.json` recording a marketplace as refreshed when its remote could not be reached and `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE` kept the existing clone
- Fixed the `/plugin` Errors tab showing no confirmation after its last error is resolved
- Fixed `/plugin` starting a second uninstall or update of the same plugin when Enter was pressed again while the first was still running
- Fixed a `y` held while `/plugin` checks a marketplace source adding the marketplace the instant the “Add marketplace?” question appears, before it can be read
- Fixed `1` answering Yes in `/permissions`’ delete and remove-directory confirms while the pointer is on No, which let a held `1` remove one workspace directory after another
- Fixed Alt+T and `/config` offering to turn thinking off on models that can’t; thinking now stays on there, with a one-line reason in place of the switch
- Fixed `/context` total leaving out messages added since the last response; it now matches its categories and can read higher than the status line
- Fixed `/model` showing the raw API error JSON and request ID when the API refuses the picked model; it now shows the server’s message and says the model was not changed
- Fixed API errors from an HTML error page (such as a proxy’s 429 or 502 page) printing the page’s raw markup or leaving out the HTTP status, and error messages breaking onto a second line when the server’s error text ended in a newline
- Fixed /feedback, /bug and /share still sending your report after you cancelled it while it was being sent
- Fixed /feedback, /bug and /share failing every send with “Couldn’t send feedback” after a Remote Control Stop arrived while the dialog was open
- Fixed `/ide` showing “No available IDEs detected” while also listing a running IDE
- Fixed the terminal being left in a broken state (crash or garbled input) when `/setup-bedrock` or `/setup-vertex` restarts Claude Code to apply new settings
- Fixed `/config` exiting when `respectGitignore` or `copyFullResponse` in `~/.claude.json` holds `null`
- Fixed the session name from /rename disappearing while Claude asks a multiple-choice question, so side-by-side sessions stay identifiable
- Fixed one-line pastes showing on their own lines in the sent message for prompts from VS Code or Remote Control and for expanded paste placeholders
- Fixed a message queued while Claude is working losing or changing the IDE selection it was written with, and queued messages not showing their selection
- Fixed pressing Shift+Tab twice quickly landing on the wrong permission mode
- Fixed Ctrl+C or Ctrl+D pressed twice quitting Claude Code instead of closing the dialog in the remaining dialogs and pickers, such as `/memory`, `/hooks`, `/mcp` (including a server’s sign-in screen), `/export`, `/copy`, `/theme`, and `/teleport`’s uncommitted-changes and login prompts (where Esc also quit)
- Fixed keys that arrive in one burst of input (e.g. over Remote Control), such as an arrow key followed by Enter, `x` or `s`, acting on the previous selection: a stale effort level in `/effort` and the model picker, and the previously highlighted row in `/skills`, the background task rows under the prompt, MCP server prompts and `/install-github-app`
- Fixed `/install-github-app` updating the workflow after “Skip workflow update” was chosen, running setup twice on a repeated Enter, and ↑ on the repository step blocking a typed repository name when no repository was detected
- Fixed vim mode: `dj`/`dk`/`dG`/`dgg` and their `c`/`y` forms acting on part of a line; `1G` going to the last line; `d0`/`c0`/`y0` doing nothing; the cursor being off by one after `.` repeats an insert; and `o`/`p` on a `!`-prefixed line switching to shell mode
- Fixed vim mode `cw` on a space, an empty line, a word’s last letter or a one-letter word also changing the next word; word motions stopping inside words in Hindi, Bengali and other scripts; and `.`, `p` or `P` that inserts text starting with `!` switching to shell mode, losing text or editing the wrong character
- Fixed the prompt cursor moving one character too far after an accent typed as its own key
- Fixed an extra blank line above a list item whose text starts on the line after its bullet, in screen-reader mode, quoted lists and long lists
- Fixed bulleted lists of plain numbers (like `- 316.`) showing as letters, roman numerals or the wrong numbers
- Fixed the agent panel’s footer hint ignoring keys rebound in `keybindings.json`, and showing a stray `·` when the stop-all-agents shortcut is unbound
- Fixed the agent panel footer offering “Enter to view” and “x to stop” on the agent you are already viewing (where x types into its input), and “Enter to view” on the main row when main is already shown
- Fixed a mouse click on an agent-panel row leaving the keyboard cursor on the previously selected row
- Fixed Esc interrupting the running turn instead of deselecting the selected agent-panel row
- Fixed PgUp and PgDn doing nothing in a dialog’s list (for example `/skills`) in fullscreen mode
- Fixed `/heapdump` summary saying most memory is native when it is in the JS heap snapshot
- Fixed Bash edit-diff snapshot directories piling up in the temp folder: abandoned ones are now deleted right away and the rest when Claude Code exits
- Fixed /workflows moving the pointer to a different run, and `x` stopping it, when a new run started while the list was open
- Fixed the selected tab in tabbed dialogs (`/config`, `/plugin`, `/permissions`) showing no highlight while the tab bar has focus when color is off (`NO_COLOR`)
- Fixed the mouse wheel over the `/plugin` Installed list scrolling the pane behind it instead of the list
- Fixed the hover highlight lingering on a list row in fullscreen mode after scrolling or filtering moved it away from the mouse
- Fixed long list rows, such as in the /remote-control menu, wrapping onto a second line in narrow terminals; they’re now cut with …
- Fixed `/hooks` and `/mcp` detail views printing a long value over the row below it in narrow terminals
- Fixed lists such as a skill’s state options in `/plugin` not being answerable by typing a number in screen-reader mode
- Windows: Fixed Bash commands that write to `$TMPDIR/…` failing with “Permission denied”
- Windows: Fixed a race in which Claude Code sessions updating at the same moment could delete each other’s `claude.exe` backup, which could leave no `claude.exe` behind
- \[VSCode\] Fixed opening a Web session with no messages saving an empty local copy that could not be resumed; an error now says where to continue it
- \[VSCode\] Fixed a claude.ai/code session opening empty or with only part of its conversation, with no error, when the server failed to return its history, part of it failed to load, or a network sign-in page answered in its place; it now shows an error and can be opened again
- \[VSCode\] Fixed conversations in editor tabs hanging silently after the extension host restarts; the tab now tells you to reopen it from the session list
- \[VSCode\] Fixed Claude attaching option previews to multiple-choice questions in the chat panel, where the question card never shows them
- \[VSCode\] Fixed the session manager’s cost and usage block wrapping mid-text on a narrow side bar, and showing totals from a previous login after an account switch
- \[Claude Code on the web\] Fixed routines with a GitHub trigger for a pull request being converted to draft never firing; they now start a run when the pull request is converted
- \[Claude Code on the web\] Fixed cloud sessions on a repository that isn’t hosted on GitHub showing a Create PR button that could never work; the button is now hidden there
- \[Claude Code on the web\] Fixed the GitHub setup tip on claude.ai/code covering the repository picker’s search box and rows while the picker is open; it now steps aside until the picker closes
- \[Claude Tag\] Fixed Slack channels where Claude could permanently stop responding to replies inside threads; affected channels now recover on their own with the next new message to Claude
- \[Claude Tag\] Fixed Claude resuming a stopped request after you press Stop in Slack, for example when a check-in fired or a background task ended; messages sent mid-response are now read
- \[Claude Tag\] Fixed Slack replies arriving many minutes late, or never, after Claude’s session crashed mid-task, such as on a failed setup script; it now restarts on its own within minutes
- \[Claude Tag\] Fixed Claude in Slack promising an automatic restart, then failing generically, when a session’s configuration is too large to start; the thread now says why and how to retry
- \[Claude Tag\] Fixed very long Slack threads: Claude could silently withhold a reply after judging it against weeks-old messages, and a restart deep into the thread could lose recent context
- \[Claude Tag\] Fixed Claude answering every mention with “Couldn’t check this channel just now” in a Slack channel moved from Enterprise Grid org-wide sharing into a single workspace
- \[Claude Tag\] Fixed very large Enterprise Grid workspaces reached mostly through channels shared across workspaces getting “Couldn’t check this channel” again after a quiet hour
- \[Claude Tag\] Fixed a Slack request blocked by your organization’s inference hook showing a generic retry notice; the thread now shows the hook’s deny message and Claude doesn’t retry
- \[Claude Tag\] Fixed Claude in Slack offering to switch to models your organization can’t use; it now lists and offers only models the switch will actually accept
- \[Claude Tag\] Fixed requests to DynamoDB and Kinesis account-based endpoints failing to authenticate when sent through an AWS connection in Claude Tag
- \[Claude Tag\] Fixed the Plugins sections in Claude Tag admin settings failing to load for organization admins and listing attached plugins as raw IDs; they now load and show each plugin’s name
- \[Code Review\] Fixed a pull request getting no review when its reviewed commit was force-pushed away while a failed review was being retried in a repository not set to review every push

[​](#2-1-280)

2.1.280

September 22, 2026

**Added**

- Added Claude Opus 5.5 (`claude-opus-5-5`), now the default Opus model — 1M context, \$4/\$20 per Mtok with \$0.20/Mtok cache reads
- Added mouse support to more lists in fullscreen mode: the wheel scrolls the `/skills` list, and a skill’s state options in `/plugin` can be clicked
- Added `CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH` to change the 2,048-character cap on MCP tool descriptions and server instructions for every MCP server in the session
- Added hook output sizes and the number of oversized outputs saved to a file to the `hook_execution_complete` OpenTelemetry event
- \[VSCode\] Added a Status dialog, with a typed `/status`, showing the session’s version, account, model and server details
- \[VSCode\] Added a Sandbox dialog for the sandbox mode, the unsandboxed fallback and excluded commands, opened from the panel menu or by typing `/sandbox`
- \[VSCode\] Added a Claude in Chrome dialog (extension status, the install, reconnect and permissions pages, the enabled-by-default setting), opened from the panel menu or by typing `/chrome`
- \[VSCode\] Added Export conversation, with a typed `/export`, to copy or save the conversation as plain text
- \[VSCode\] Added each skill’s source, token estimate and on/off state to the Slash commands dialog, with a click to change the state, and a typed `/skills` that opens it
- \[VSCode\] Added a typed `/plan` that switches to plan mode, sends a first planning prompt, or shows the session’s plan
- \[Claude Tag\] Added Slack’s native Working indicator, Stop button and thread title to Claude’s threads in channels; the indicator stays up until Claude finishes, and Stop interrupts the task
- \[Claude Tag\] Added a short notice in the Slack channel when a guest joining, or the last guest leaving, changes how Claude responds there under a Restrict or Channel only guest setting

**Changed**

- Reverted `ctrl+l` / `cmd+k` in fullscreen mode clearing the transcript view (added in 2.1.260); they redraw the screen again
- Changed the default model on Pro and Team Standard plans from Sonnet to Opus, matching Max, Team Premium, and Enterprise
- Changed an effort level saved before `/effort` became per-model to no longer apply to newly released models such as Opus 5.5; they start at their default until you pick a level
- Changed Opus 4.7, Opus 4.8 and Fable 5 to stop holding their launch-default effort over `/effort` in `-p` or the Agent SDK, a project, managed or `--settings` `effortLevel`, or a per-model level
- Changed `/autocompact`’s footer hint to name ←/→, the keys that adjust other ordered values
- Changed `/fast`’s footer to name Space as the toggle key
- Self-hosted runner: Changed git in lifecycle hooks to ignore hook folders and programs named in the runner’s shared git files; local-path and `git://` remotes there now need `GIT_ALLOW_PROTOCOL`
- Changed plugin marketplaces whose name imitates a reserved marketplace name to be refused when added, and to stop loading if one was already added
- Changed `PermissionRequest` hooks: an agent-type hook no longer runs there, since its answer could never allow or deny the request; it now shows an error pointing to command or http hooks
- \[VSCode\] Changed “Open in New Tab” to open Claude beside the editor group you are working in rather than after the last group
- \[Claude Code on the web\] Changed the admin Routines on/off setting to live under Admin settings → Capabilities → Remote sessions; the Claude Code admin page now links to it
- \[Claude Code on the web\] Removed the empty repository picker shown when starting a session on a self-hosted environment in an organization where an admin has turned GitHub off

Show 21 improvements

- Improved `/permissions`: focus returns to the rule list after viewing, adding or deleting a rule, and the delete-rule and remove-directory confirmations now default to No
- Improved `/permissions` tab navigation: ←/→ and Tab pressed in a rule list now switch tabs without moving focus to the tab bar
- Improved `/cost` cache-miss causes to name thinking mode and thinking display changes
- Improved the Artifact tool so that when Claude cannot read an artifact link it was given, it tells the user before continuing
- Improved `/install-github-app`: the GitHub CLI check and repository selection steps now show “Esc to cancel”
- Improved the `/artifacts` and `/workflows` lists: a scrollbar at the right edge shows how much of a long list is hidden and where you are in it
- Improved the workflow progress tree: running agents and phases now show a dim dot instead of ⟳
- Improved `/plugin`’s Add Marketplace form in fullscreen: it no longer draws a box inside the pane, and its text and key hints line up with the rest of `/plugin`
- Improved the `/workflows` detail view in fullscreen: it no longer draws a second horizontal rule under the pane’s divider
- Improved code blocks that don’t name a language: they are now colored like inline code, so commands stand out from the surrounding text
- Improved `/btw` asked while a tool is still running: the side question now knows that call is in progress instead of reading it as a failed one
- Improved the UserPromptSubmit hook timeout notice and the debug log to name which hook command timed out
- Improved `@` file suggestions: a file whose name contains the query now ranks above one that only matches across its folder names
- Improved artifact pages: no Print buttons, confirm dialogs or device features the viewer blocks, email and phone details shown as text, and dark mode that reaches form controls and scrollbars
- Improved `/ultrareview` uploads: renamed copies of key files, such as `id_rsa copy` or `kubeconfig (1).yaml`, now also stay on your machine
- Improved the cross-session messaging startup warning to explain that `--debug-file` writes a debug log to a path you choose
- \[VSCode\] Improved pasted-text handling in the chat box: a paste over 800 characters or over 2 line breaks is now marked so Claude can tell it from what you typed
- \[VSCode\] Improved prompt handling in the chat box: invisible Unicode formatting and tag characters are removed from pasted text with a notice, and from anything else before it is sent
- \[Claude Code on the web\] Improved cloud sessions viewed in the Claude app: Claude now saves files meant for you where the app can open them
- \[Claude Tag\] Improved the GitHub banner in Claude Tag admin settings to say why GitHub isn’t connected: not signed in, app not linked or not installed, sign-in expired, or SSO not authorized
- \[Code Review\] Improved the Code Review check run to say when REVIEW.md instructions were cut or left out of a review for exceeding a size limit, naming the file and the limit

Show 69 bug fixes

- Fixed writes through a symlinked path being judged by their in-tree spelling: the prompt names where the write lands, and `acceptEdits`, allow rules and auto mode no longer approve one landing outside
- Fixed auto mode retrying an action over and over when a safety check declined to review it; the action is now denied once, noting that retrying won’t help
- Fixed auto mode denying actions over and over without pause when a safety check gave no answer; retries now back off, and the turn stops with a message after ten in a row
- Fixed Write calls failing validation when a model sends `path`, `file_text`, `file_content` or a stray `description` instead of `file_path` and `content`
- Fixed Ctrl+C or Ctrl+D pressed twice in most dialogs (`/model`, `/effort`, `/config`, `/status`, `/usage`, `/plugin`, `/sandbox`, `/permissions`, `/artifacts`, `/mobile`, `/login`, `/upgrade`, `/usage-credits`, `/install-github-app`, `/setup-bedrock`, `/setup-vertex`) quitting Claude Code instead of closing the dialog
- Fixed a click that only brought the terminal window to the front also triggering the item under the pointer — in search pickers, tab bars, agent/workflow rows, slash-command links and suggestion dropdowns
- Fixed a stray `n` closing dialogs and a stray `y` confirming them; Enter and Esc accept and cancel (bind `y`/`n` to `confirm:yes`/`confirm:no` in `keybindings.json` to restore)
- Fixed text fields in dialogs losing a typed letter, digit or Space to a keybinding on that key
- Fixed the prompt line staying scrambled on Windows terminals after invisible characters were removed on Enter; the screen is now repainted so you review the exact text that will be sent
- Fixed the invisible-character cleanup removing the zero-width non-joiner that Persian and Arabic text uses to attach a suffix to a Latin word or number, such as the plural of “PDF”
- Fixed voice dictation not stopping on Ctrl+C (the prompt cleared but the microphone kept recording), Esc not cancelling while a transcript was processing, and held Space starting dictation from the transcript view and vim NORMAL mode
- Fixed a model switch made from a host app (Claude Desktop, VS Code, SDK) while Claude is working causing a prompt-cache miss on the next prompt
- Fixed resumed fork subagents rebuilding their tool list instead of re-sending the one they first used, which broke prompt caching for that agent
- Fixed subagent hand-back messages showing an internal provenance preamble when expanded outside verbose mode
- Fixed `installed_plugins.json` keeping the install-time commit after updating a plugin from a GitHub repository or git URL that tracks a branch or tag
- Fixed skills in `~/.claude/skills/` being moved to `~/.claude/skills/.trash/` when a `manifest.json` in that folder listed their names
- Fixed the session feedback survey showing no hover highlight on light and ANSI themes
- Fixed `/workflows` briefly showing a one-row list before opening the only run
- Fixed the mouse wheel not scrolling selection lists with hidden options (such as `/model` and `/permissions`) in fullscreen mode
- Fixed a skill you switched off showing the same red ✘ as a plugin that failed to load in `/plugin` and `/skills`; off now shows a dim ◯
- Fixed multi-select option descriptions being indented under the option number instead of under the label
- Fixed the search box in `/plugin`, `/skills` and `/mcp` losing its right border in fullscreen mode
- Fixed `/mcp` showing △ in the server list but ⚠ in the detail view for the same server; the list, detail views and `/plugin` now all show ⚠
- Fixed Home and End doing nothing in the `/config` settings list and in selection lists such as `/model`, `/memory` and permission prompts
- Fixed PgUp/PgDn in the `/skills` menu wrapping past the first or last skill instead of stopping there
- Fixed Tab silently changing the selected setting’s value in the `/config` list; it now does nothing there
- Fixed conversations failing on every turn with a “role ‘system’ must precede an ‘assistant’ message” API error
- Fixed conversations with the advisor on failing every turn with API Error 400 “Input tag ‘advisor_20260301’” behind a proxy or gateway that doesn’t support it; the request now retries without it
- Fixed a session failing on every turn and `/compact` when its saved history held a malformed notice about MCP tools that could not be loaded
- Fixed a crash when resuming a session whose saved transcript holds a malformed system message or a memory-saved notice without its file list
- Fixed one cause of long-running fullscreen sessions exiting with “Claude Code exited after an unrecoverable interface error”: a damaged cached message list is now rebuilt
- Fixed Claude Code hanging when a settings file, or a file it re-reads after an edit, is replaced by a named pipe mid-read
- Fixed `/config` crashing and some on/off preferences being misread when a preference that has moved to `settings.json` still holds a value like `null` or `"false"` in `~/.claude.json`
- Fixed resuming a session with unfinished background agents, shells or workflows starting a model turn on its own before you typed anything
- Fixed messages sent to a background subagent being silently lost in headless and SDK sessions when the subagent was finishing its turn
- Fixed a finished subagent’s report being lost when the conversation that launched it was compacted before the report was read
- Fixed background subagents being unable to use the LSP tool when an LSP plugin is active
- Fixed background shell tasks reporting benign non-zero exits (e.g. grep with no matches) as failures
- Fixed background sessions (`claude --bg`) being unable to run git, hooks, plugins and other helper programs when an environment variable handed to the session contained a NUL character
- Fixed Ctrl+C needing three or four presses to exit while background subagents are running; two presses now exit
- Fixed IDE selection being dropped when a sent prompt comes back into the input, such as pressing Esc to edit it, rewinding to it, or pressing Esc while startup hooks run
- Fixed a `!` shell-mode prompt stashed with Ctrl+S coming back as a plain prompt when restored, and `/` listing file paths right after stashing one
- Fixed `claude agents` showing a blank, unresponsive screen instead of an error when the temp directory is full, not writable or owned by another user
- Fixed an MCP server re-added under the same name after `claude mcp remove` still showing as needing authentication instead of reconnecting
- Fixed background plugin marketplace auto-update ignoring git credential helpers, so private-repo marketplaces were re-cloned every run or never updated
- Fixed `claude plugin update` clearing a plugin’s recorded commit and moving it to version “unknown” when the official marketplace’s snapshot file is a link or too large
- Fixed the Artifact tool silently disappearing when your organization’s policy can’t be loaded (for example behind a web proxy); Claude now says what’s blocking it
- Fixed artifact republishes silently resetting stored database access rules or dropping the viewer profile scope when that capability was re-sent without them; they are now refused
- Fixed `/ultrareview` reporting a stopped cloud review as completed or as an error to retry, and waiting out the full timeout when its session was deleted or the signed-in account changed
- Fixed the Claude app showing a missing or stale context usage figure for Remote Control and cloud sessions right after /compact or /clear
- Fixed the Claude app’s diff view for Remote Control and cloud sessions dropping a branch’s committed files whenever there are also uncommitted changes
- Fixed cloud and self-hosted runner sessions failing with “Authentication failed” after waiting out a long overload during which the session’s access token was rotated
- Fixed memory write conflicts in Cowork sessions showing Claude only the start and end of a memory file over about 10,800 characters, so the retried write dropped the middle
- Self-hosted runner: Fixed lifecycle-hook commits failing to sign under `--configure-git`
- Windows: Fixed background cleanup deleting a directory symlink or junction used to relocate `~/.claude/session-env`, `image-cache` or another cleaned-up folder
- Self-hosted runner: Fixed a turn that ended right at a `--retire-at` release losing its finished signal; the runner now briefly waits for the turn to be reported before stopping the session
- \[VSCode\] Fixed the effort chip showing a stale saved effort level instead of the level the session runs at
- \[VSCode\] Fixed Claude Code never starting when the Python extension hangs while activating; it now starts after 60 seconds without the Python environment
- \[VSCode\] Fixed the plan approval card never offering auto mode: when auto mode is available, its first option is now “Yes, and use auto mode”, as in the terminal
- \[VSCode\] Fixed arrow-key navigation in the session list stopping after archiving or unarchiving a session from the keyboard
- \[VSCode\] Fixed paste marker lines showing in your own messages after reopening a session
- \[Claude Code on the web\] Fixed `gh` and GitHub API calls inside a cloud session on a GitHub Enterprise Server repository failing after about eight hours; the token now renews automatically
- \[Claude Code on the web\] Fixed a routine that resumes an existing session running with its old prompt and name when it was edited moments before the scheduled run started
- \[Claude Code on the web\] Fixed file links in a cloud session transcript that point outside the session’s working directory opening a file card that never loads; they’re now disabled and say why
- \[Claude Code on the web\] Fixed auto mode refusing to retry a tool call because an approval prompt that expired unanswered, or was superseded by a newer message, had been recorded as your rejection
- \[Claude Tag\] Fixed scheduled routines silently failing to run in Slack workspaces that were connected to Claude before the workspace joined its Enterprise Grid
- \[Claude Tag\] Fixed Claude asking you to re-upload a Slack file when a brief file-scanning outage, not the file, was the problem; it now retries the scan and is told when the scanner is down
- \[Claude Tag\] Fixed a bullet in Claude’s Slack reply whose text starts with +, - or \* rendering as an empty bullet with a stray nested item; it now shows as one bullet with the character kept
- \[Claude Tag\] Fixed the Slack notice for a failed cloud environment setup script sometimes being a generic “mention me to retry”; it now names the setup script and says to fix it first

[​](#2-1-278)

2.1.278

September 19, 2026

- Changed auto mode for Claude API and Enterprise users, and on Bedrock, Vertex, Foundry and gateways, to default to the server-side classifier, which does not charge for classifier overhead (`CLAUDE_CODE_AUTO_MODE_SERVER=0` opts out on Bedrock, Vertex, Foundry and gateways); warns on billed fallback. See [https://code.claude.com/docs/en/auto-mode-classifier-billing](../17-Billing-Plans/auto-mode-classifier-billing.md)
- Added an `Auto mode server` row to `/status` showing whether this session’s auto mode classifier runs on the server

[​](#2-1-277)

2.1.277

September 18, 2026

**Added**

- Added AGENTS.md support: in a project with no CLAUDE.md, Claude Code reads AGENTS.md instead; change it under “Project instructions” in `/config`
- Added `CLAUDE_GATEWAY_PROXY_IS_EGRESS_BOUNDARY=1` for Claude apps gateways whose only egress is a forward proxy: every outbound request hands the proxy the hostname instead of resolving it locally
- Added an optional `headers:` map on Claude apps gateway upstreams, to send static headers to a proxy you run in front of a provider
- Added a line saying a background task’s update is waiting when it finishes while a panel such as `/tasks` is open
- \[VSCode\] Added a Sign out row to the panel menu, with `/logout` in the typed command menu
- \[VSCode\] Added background shells and other running tasks to the agent map, each with a Stop, and a typed `/tasks` that opens it
- \[VSCode\] Added a Copy response button on responses and a typed `/copy`
- \[VSCode\] Added a one-time notice when inactive sessions are archived automatically, and an “Unarchive all” action on the Archived sessions group
- \[VSCode\] Added the session’s cost and token usage to the Account & usage dialog and the session manager where plan limits do not apply (Vertex, Bedrock, Foundry, API key)
- \[Claude Code on the web\] Added Personal and Organization sections to the environment picker on Team and Enterprise plans, and admins can now share a personal environment with the organization

**Changed**

- Changed Fable to always appear in `/model` on the Anthropic API; it is greyed out only when your organization’s settings disable it
- Changed the Bash sandbox instructions on Bedrock, Vertex and Foundry to the first-party wording, which frames the sandbox as the boundary of what the task was given
- Changed `/ultrareview` in non-interactive sessions to refuse when the repository has no base branch or shared history
- Changed subagent results to reach the main agent under a header marking them as subagent output, with the result indented, so text in a subagent’s result cannot pass as the session’s own instructions
- Changed workflow scripts’ computed `agent()` prompts on Bedrock, Vertex and Foundry to reach the subagent framed as script-authored text, so the safety classifier does not read them as the user
- Removed the background Haiku auto-title request from `claude -p` runs launched outside an SDK or IDE
- Removed the deprecated TaskOutput tool; Claude reads a background task’s output file with Read instead, and the `taskOutputMaxChars` setting and `TASK_MAX_OUTPUT_LENGTH` no longer have any effect
- \[Claude Code on the web\] Changed organization environments to open as a read-only summary from the Code tab on Team and Enterprise plans, with editing under Admin settings → Cloud environments
- \[Claude Code on the web\] Changed the admin Claude Code setting labeled “Web” to “Cloud sessions” and removed the redundant read-only Mobile row beneath it
- \[Claude Tag\] Changed the Pylon credential preset in Claude Tag access bundles so admins can point it at Pylon’s EU host

Show 10 improvements

- Improved session start-up for SDK and headless (`-p`) use: the first turn no longer waits on the per-directory CLAUDE.md lookup
- Improved the Claude apps gateway’s loopback error messages to name `CLAUDE_GATEWAY_ALLOW_LOOPBACK`
- Improved `/plugin` Installed: an MCP server listed apart from its plugin now shows which plugin it belongs to
- Improved `claude plugin install` on an already-installed plugin: it now says when the marketplace offers a newer version and names the `claude plugin update` command
- Improved the startup notice overflow line under the logo: it now reads “N more notices hidden” instead of “+N more · /status”
- Improved prompt handling: invisible Unicode formatting and tag characters in a prompt are removed and the cleaned prompt is shown for review before it is sent
- Improved `/ultrareview` when there’s nothing to review: messages say which case you’re in, offer a command that reviews your latest commit, and a new repository’s first commit is reviewed in full
- Improved artifact link handling so Claude reads claude.ai artifact links with the Artifact tool instead of WebFetch when that tool is available
- Improved the dangerous-rm permission prompt to name the flagged rm command and suggest a `${VAR:?}` guard, so headless runs can recover
- Improved the Artifact tool’s permission prompts: shorter sentences, pages and artifacts named by title or file name, and links listed after the text

Show 57 bug fixes

- Fixed `claude -p` and Agent SDK sessions that could hang with no result after an internal error; they now report the error and exit with code 1
- Fixed conversations failing every request with “text content blocks must be non-empty” when an earlier assistant turn held an empty text block beside other content, including after `--resume`
- Fixed being unexpectedly logged out when an older Claude Code build (for example an IDE extension’s bundled CLI) runs on the same machine as the current one
- Fixed interactive start-up hanging or showing an error for `ANTHROPIC_API_KEY` users when `~/.claude.json` holds a malformed `customApiKeyResponses` value
- Fixed update checks erroring every 30 minutes, and `claude update` hanging when a minimum or maximum version is set, if a proxy returns an invalid version; a malformed `minimumVersion` is now ignored
- Fixed `claude update` on winget- or apk-managed installs reporting “up to date” when the version lookup failed
- Fixed `claude plugin install` sometimes failing and breaking the installed copy when reinstalling a plugin version that a session or another program was using; an unchanged copy is now left alone
- Fixed Grep and Glob reporting no matches when the search could not start because the system was out of processes, memory or file handles; they now return an error saying so
- Fixed the Write tool silently ending the turn as a declined permission when the target path is an existing directory; it now reports a clear error
- Fixed the Edit tool treating an escaped backslash followed by `uXXXX` text as a `\uXXXX` escape, which could make an edit of a non-ASCII character rewrite an escaped backslash sequence instead
- Fixed the Edit tool reporting “Invalid regular expression: regular expression too large” instead of “String not found in file” when a very large edit containing non-ASCII text did not match the file
- Fixed a turn ending early with “Path contains null bytes” when a tool call’s file path contained `\u0000` written as an escape sequence; escaped control characters now stay as literal text
- Fixed background sessions (`claude --bg`) exiting when a plugin’s LSP server exited or closed its stdin
- Fixed a crash (“Type error”) when opening `/mcp` or `/plugin manage` with a malformed `claudeAiMcpEverConnected` value in `~/.claude.json`
- Fixed a crash at launch when `~/.claude.json` holds a malformed `theme` value
- Fixed a crash (“unrecoverable interface error”) when the prompt held text containing terminal color codes, for example a prompt recalled from history or text loaded from the external editor
- Fixed a crash when resuming a session whose saved history holds an assistant message stored as a plain string
- Fixed sessions on slow or heavily loaded machines sometimes exiting with “Claude Code exited after an unrecoverable interface error” when the first spinner appeared
- Fixed a rare case where the screen could stop updating for the rest of the session after an internal rendering error
- Fixed a rare case on Windows where a turn could stop with an error such as “Out of memory” right after Claude replied, so that reply’s tool calls never ran
- Fixed sessions continued after `/clear` (restart, `--continue`, `--resume`) missing part of their first message when a SessionStart hook printed output, causing a full prompt-cache miss
- Fixed messages from other agents (such as a subagent’s SendMessage) that arrived mid-turn showing up below the “Ran N shell commands” row instead of where they arrived
- Fixed the “copied” notice not appearing after drag-selecting text in the fullscreen `/resume` picker and other panels that cover the prompt area
- Fixed `$TMPDIR` expanding empty in Bash commands that run outside the sandbox while sandboxing is enabled
- Fixed WebFetch and WebSearch in Cowork cloud sessions not telling Claude why a request was refused, such as a used-up fetch budget or an admin policy
- Fixed the Claude apps gateway’s telemetry relay ignoring a collector hostname or domain listed in `NO_PROXY` when a proxy is set
- Fixed one malformed `strictKnownMarketplaces` or `blockedMarketplaces` entry silently disabling the whole enterprise marketplace policy
- Fixed failed auto-updates leaving large staged downloads behind in `~/.cache/claude/staging`
- Fixed `/plugin` not stripping terminal control characters from messages on the Installed tab, such as the error of a failed plugin update
- Fixed `/plugin` → Installed and `/skills` crashing when a skill or legacy command is named like a built-in Object property such as `constructor` or `toString`
- Fixed `/plugin` closing with no message when every install in a multi-select failed
- Fixed uninstalled plugins reappearing as “failed to load” rows in `/plugin` Installed, and Remove not clearing such a row
- Fixed plugins from the official marketplace being recorded without their commit in `installed_plugins.json`, and `installed_plugins.json` keeping the old commit after updating a pinned-commit plugin
- Fixed plugin reload previews keeping every previewed copy of a plugin archive unpacked until exit, and overwriting the cached `--plugin-url` archive a reload falls back to when its download fails
- Fixed Remote Control session bookkeeping failing when `~/.claude.json` holds a malformed placeholder record
- Fixed the error after a revoked claude.ai login blaming an expired Anthropic profile; it now leads with `/login`
- Fixed typed or pasted text occasionally coming out scrambled in the `claude agents` dispatch input during key repeat or very fast input
- Fixed a crash (“unrecoverable interface error”) when resuming a session whose saved transcript contains a stop hook summary without a well-formed hook list
- Fixed Enter on a selected agent panel row doing nothing when `keybindings.json` rebinds Enter in the Chat context, for example to `chat:queueSubmit`
- Fixed PDF page reads on Windows failing when the working folder’s path is long (about 120 characters or more)
- Fixed a headless resume (`claude -p --resume`, the SDK, a VS Code extension window reload) starting the session’s cost and usage totals at zero; headless sessions now save their totals at exit
- Fixed project skills from the main repository not loading in `--worktree` sessions when `.claude/skills` is untracked
- Fixed a `sandbox.excludedCommands` glob exempting an entire compound Bash command from the sandbox when only one part matched; every part must now match
- Fixed resumed subagents and teammates re-rendering the MCP tool definitions they had loaded, which broke prompt caching for that agent
- Fixed rate-limited artifact publishes telling Claude to stop retrying; Claude is now told nothing was published and when to send the same publish again
- Fixed attachments recorded earlier in a conversation being re-rendered after a resume or relaunch, which dropped extended thinking and missed the prompt cache
- Fixed Console sign-in showing only “Request failed with status code 400” when the server refuses to create an API key; it now shows the server’s message
- Fixed messages typed while Claude is still working sometimes being ignored by the model
- \[VSCode\] Fixed the “General config” menu row showing `/config` usage text instead of opening settings, and made typed `/mcp`, `/hooks`, `/memory`, `/rewind` and similar commands open their dialogs
- \[VSCode\] Fixed the effort slider’s level not persisting into later sessions on a model that already had a level saved with `/effort`
- \[VSCode\] Fixed Auto missing from the mode picker for conversations opened in an already-used panel when the saved model setting is a differently-cased alias such as “Sonnet”
- \[VSCode\] Fixed `/fast` not saving fast mode as the default, so it was lost when the extension relaunched Claude Code
- \[Claude Code on the web\] Fixed a cloud environment saved with Custom network access and no domains silently reverting to Trusted; the dialog now asks for at least one domain
- \[Claude Tag\] Fixed routines created in a Slack channel on an Enterprise Grid org-wide install failing to read other public channels in their workspace when they ran
- \[Claude Tag\] Fixed the “Learn more” links on credential presets in Claude Tag access bundles to open each vendor’s credential-setup page instead of a generic API reference
- \[Claude Tag\] Fixed Google Cloud credential forms in Claude Tag access bundles: a refused key file now says why, the website and scopes stay locked, and a rejected rotation keeps the pasted key
- \[Claude Tag\] Fixed the network events log in Claude Tag admin settings showing no response status for requests through connections that use AWS signing, client certificates or a custom CA

[​](#2-1-276)

2.1.276

September 18, 2026

- Fixed every request failing with `400 … Input tag 'advisor_20260301'` when `ANTHROPIC_BASE_URL` points at a proxy or gateway (2.1.275 regression)

[​](#2-1-275)

2.1.275

September 17, 2026

**Added**

- Added the signed-in account to Claude apps gateway sign-in: when the gateway names it, you confirm it before the credential is saved, and `/status` shows it
- Added a send-now key (ctrl+enter, or ctrl+x ctrl+s) that interrupts the current turn and sends all queued messages at once; sent and queued messages show in gray until the model receives them
- Added a startup warning when a configured `otelHeadersHelper` fails, so sessions that silently export no telemetry are noticed
- Added syncing of the skills and plugins enabled on your claude.ai account to terminal sessions signed in with it; opt out with `syncClaudeAiSkills: false` or `syncClaudeAiPlugins: false`
- Added `/plugin install <plugin> --marketplace <source>`, which offers to add the marketplace before installing the plugin
- \[VSCode\] Added viewing, editing and deleting a saved memory inside the Memory dialog
- \[VSCode\] Added sending an attached image without typing any text
- \[VSCode\] Added a Retry link to the MCP servers dialog when the server list fails to load
- \[VSCode\] Added accept and reject buttons under each change in the proposed-change diff tab, so an edit can be reviewed change by change
- \[Claude Code on the web\] Added a “New routine” button to the page shown when a routine link no longer resolves, next to the link back to your routines list
- \[Claude Tag\] Added attach conditions for access bundles in Claude Tag settings: an Owner can let a bundle also apply in channels with guests or Slack Connect channels, not just member-only
- \[Claude Tag\] Added Amazon CloudWatch, CloudWatch Logs, Amazon SNS, Google Cloud Monitoring and Cloud Logging presets to an access bundle’s Credentials tab in Claude Tag admin settings
- \[Claude Tag\] Added Datadog presets for the US3, AP1, AP2 and US1-FED sites; new Datadog connections are now limited to Datadog’s read and query API routes

**Changed**

- Updated `/logout` for Claude apps gateway sign-ins to also end the session on gateways that advertise token revocation
- Changed hosted sessions to keep an unanswered permission prompt up after a container restart, instead of asking again
- Changed the Artifact tool to ask for a one-word tab icon on a first publish instead of an emoji favicon
- Changed Claude in Chrome in auto mode to skip the extension’s per-site check for classifier-approved calls, as bypass mode does, fixing `browser_batch` “Permission denied” after a redirect
- Changed plugins installed from an npm source to be fetched with `npm pack --ignore-scripts` and integrity-verified, so a package’s install scripts no longer run
- Changed scheduled and Run now routine runs to save data to, and republish the page of, an artifact you can edit without asking; public artifacts, first publishes and deletes still ask
- Removed the startup notice that told you a one-off scheduled routine had run since your last session
- \[VSCode\] Changed New session in a Claude editor tab to open in the sidebar when Preferred Location is set to Sidebar, instead of always opening another tab
- \[VSCode\] Changed a message sent while Claude is working to wait at the bottom of the conversation until Claude starts on it

Show 13 improvements

- Improved prompt caching for a `--system-prompt` that contains a `__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__` line: the text above it is now cached globally, as the SDK’s array form already is
- Improved the `/desktop` error when Claude Desktop does not open: it now says why and what to do next
- Improved the Artifact tool’s publish and read results: they now say who can open the page and what the owner’s Share menu offers
- Improved artifact publish results: they name the tab icon sent, warn when the page contains a NUL byte, and retry a flaky fetch of the newer page to merge after a stale publish
- Improved pasted and attached images: they are now saved where Claude can open them as files without a permission prompt, including in Desktop and VS Code
- Improved the Artifact tool’s guidance so Claude updates a shared artifact in place when you were given edit access to it, instead of publishing a separate copy
- Improved plan-usage reads: editor windows and non-interactive sessions on one machine now share a read made in the last minute instead of each calling the usage endpoint
- Improved the `ListPlugins` tool description so Claude knows it lists plugins enabled on your claude.ai account, not plugins installed locally with `/plugin`
- Improved responsiveness when the terminal is slow or paused: output no longer falls further behind while the terminal catches up
- Improved Write and Edit results for files in the synced account-skills folder: they now say the change is not saved to your account and how to save it
- \[VSCode\] Improved the agent map: the pill counts running agents and turns red after a failure, the main agent stays in view while the map scrolls, and agents sort by state then end time
- \[Claude Code on the web\] Improved what Claude tells you when asked to edit, delete or run a routine it didn’t create: it now links to the routine’s page so you can do it yourself
- \[Claude Tag\] Improved Claude’s notices in Enterprise Grid channels shared across workspaces: they now say when no workspace is set up yet, or why only organization defaults apply

Show 60 bug fixes

- Fixed a restored memory file’s age note changing between requests after a compaction or resume, which caused prompt cache misses
- Fixed `--forward-subagent-text` stream-json and SDK output dropping the messages of subagents spawned by a `context: fork` skill, and of forked skills invoked by a subagent or another forked skill
- Fixed @-mention file suggestions being buried below MCP resources when using a custom `fileSuggestion` command or typing `@.`/`@./`
- Fixed fullscreen mode placing background-task completion notices beneath a long turn’s collapsed tool row instead of where they arrived; each notice now closes the open row
- Fixed `claude plugin marketplace update` deleting a GitHub marketplace’s local copy when the fetch failed and the marketplace was named after its repository
- Fixed plugin and marketplace messages, logs and `claude plugin marketplace list` showing a password or token stored in a git, ssh or marketplace URL
- Fixed a resumed cloud session leaving an unanswered question open in the transcript after a queued message superseded it
- Fixed vim mode placing the cursor one character right after a dot-repeated ”!” or a fast-typed “i!” switched a non-empty prompt into shell mode
- Fixed fullscreen mode freezing or blanking for several seconds when scrolling up past a large file diff
- Fixed a stray `</ccmemory>`-style closing tag occasionally appearing in responses
- Fixed plugin messages, logs and the VS Code plugin dialog showing the wrong server for some git addresses
- Fixed a terminal `API Error: 400` on every turn for users behind a network gateway that rewrites API error responses when a beta request header is rejected
- Fixed sandboxed Bash commands on Linux reporting exit code 0 for failed commands when the shell is zsh
- Fixed the Read tool hanging instead of reporting an error when part of a large file could not be decoded under memory pressure
- Fixed `--resume`, the resume picker preview, resumed background agents and the transcript view failing on a session whose saved history contains a malformed task-reminder or @-file attachment entry
- Fixed a crash when resuming a conversation whose transcript contains a malformed message entry, and a fullscreen crash when such a conversation received new messages while scrolled up
- Fixed sessions failing to resume or start when their saved transcript contains a malformed message content block
- Fixed Grep, Glob and @-file suggestions hanging or running out of memory on searches over the 20MB output cap, and system ripgrep reporting “no matches” instead of an error after a flood of warnings
- Fixed `/rewind` in a forked or background session restoring a zero-filled or truncated file when the session’s file-history backups could not be fully copied
- Fixed fullscreen sessions sometimes exiting with “Claude Code exited after an unrecoverable interface error” when typing fast or holding a key with the slash-command dropdown open
- Fixed background sessions crashing and restarting their worker when a command fed through stdin ran on a machine that had run out of file descriptors
- Fixed a crash at launch when `~/.claude.json` holds a malformed `mcpNeedsAuthNoticed` value
- Fixed `--resume` and `--continue` dropping a conversation’s earlier thinking when a built-in tool it started with has since been switched off by a server-side flag
- Fixed text selected with the mouse in the fullscreen `claude --resume` session picker never reaching the clipboard
- Fixed plugin reload previews replacing a running session’s extracted plugin files when the plugin was loaded from a `--plugin-dir` or `--plugin-url` archive
- Fixed self-hosted runners with `--drain-wait-sec` losing the final result of a turn that finished during a SIGTERM drain; the runner now waits briefly for the turn to be reported
- Fixed `SubagentStop` hooks with a specific `matcher` firing for every stopping subagent whose agent type was empty
- Fixed sandboxed Bash commands being unable to write to project directories named `hooks/` or `config/`
- Fixed Artifact updates failing with “File not found” after a session resumes on another machine or its scratchpad is cleared: the page’s last published version is restored
- Fixed `/update-config` writing `Write(path)` permission rules, which file permission checks don’t match, instead of `Edit(path)` rules
- Fixed four dead documentation URLs (Pricing, Computer Use, Skills, CLI) in the bundled claude-api skill’s live-sources table
- \[VSCode\] Fixed the transcript creeping toward the bottom in small steps while a permission card waits and content keeps arriving
- \[VSCode\] Fixed rewound and forked conversations not keeping the permission mode you had picked for the original conversation
- \[VSCode\] Fixed an empty `CLAUDE_CONFIG_DIR` entry in the `environmentVariables` setting making Claude Code keep its files in the workspace
- \[VSCode\] Fixed plugin install links opening the Manage plugins dialog for plugin names and marketplace addresses that can’t be used in a link
- \[VSCode\] Fixed Remote Control staying shown as connected after a turn-off that Claude Code reported as failed; it now shows as off
- \[VSCode\] Fixed the scroll to the bottom on send stopping short of the reply when the reply starts arriving during the scroll
- \[VSCode\] Fixed the agent map showing agents a crash left unfinished as stopped instead of failed once the session is reopened
- \[VSCode\] Fixed the “Continuing the step” notice not appearing, and the continue limit resetting, after a reload that follows a crash with background tasks still running
- \[VSCode\] Fixed the session list showing when a session was last reopened, such as after a window reload, instead of when its last message was sent
- \[VSCode\] Fixed “Fork conversation from here” failing on the message right after one sent while Claude was working
- \[VSCode\] Fixed the prompt cache clock showing too few minutes after reopening a session with a message sent while Claude was working
- \[VSCode\] Fixed a background agent that finished while Claude was running a tool losing its completion notice, and its result on the agent map, after a window reload
- \[VSCode\] Fixed a rare case where text selected in a git-ignored file could be sent to Claude after the extension was unresponsive for several seconds
- \[VSCode\] Fixed renaming a running session reverting to the generated name (regression in 2.1.269)
- \[VSCode\] Fixed slash commands typed while Claude is responding being sent to the model as text instead of running once the response finishes
- \[VSCode\] Fixed unreadable code in the plan preview and the Hooks and Permission rules dialogs with the High Contrast Light theme
- \[VSCode\] Fixed `/remote-control` being ignored while Remote Control is still connecting: running it again now turns Remote Control off immediately
- \[VSCode\] Fixed the conversation pulling you back to the bottom while a reply streams after you scroll up, and added a `claudeCode.scrollToBottomOnSend` setting to turn off the jump on send
- \[VSCode\] Fixed the Manage plugins dialog showing a password or token that was typed into a marketplace URL
- \[Claude Code on the web\] Fixed routine “paused” and “on hold” notifications being cut off mid-sentence; the paused-subscription notice now says to turn the routine back on yourself
- \[Claude Code on the web\] Fixed cloud environments with a very long allowed-domains list saving fine and then failing every session start; saving now fails up front and says how much to trim
- \[Claude Code on the web\] Fixed Claude’s guidance when a cloud session on a personal account is denied GitHub access: it now links to claude.ai/connect-github instead of an admin settings page
- \[Claude Tag\] Fixed S3 uploads from recent AWS CLI and SDK versions failing with a 502 error when sent through an AWS connection
- \[Claude Tag\] Fixed Claude treating a channel as inactive, and skipping untagged messages there, while it was still posting in that channel from a routine or a thread
- \[Claude Tag\] Fixed a thread’s “Claude \[task\]” display name reverting to plain “Claude” after the session behind that thread was refreshed or restarted
- \[Claude Tag\] Fixed the model you switched to in a Slack thread silently reverting to the channel’s default after that thread’s session was restarted or refreshed
- \[Claude Tag\] Fixed Claude sometimes replying twice when another app or bot @mentioned it in a top-level channel message
- \[Code Review\] Fixed reviews occasionally dropping part of their analysis when one of the reviewing agents returned its findings in an unexpected format
- \[Code Review\] Fixed pull requests with more than 100 Claude reviews getting a full re-review on every clean merge from the base branch instead of the lighter merge-focused review

[​](#2-1-274)

2.1.274

September 17, 2026

**Added**

- Added a visible warning when memory usage is critical, with steps to free memory or restart safely
- Added `CLAUDE_CODE_MCP_STARTUP_WAIT_MS` to bound how long the first non-interactive turn waits for connecting MCP servers (`0` = don’t wait)
- Added `effort` attribute to the `claude_code.llm_request` OpenTelemetry trace span, matching the `api_request` event
- Added `claude_code.managed_settings_resolved` OTel event: managed-settings sources and policy helper state; redacted settings and digests with `OTEL_LOG_MANAGED_SETTINGS=1`
- Added `store.connect_timeout_seconds` to the Claude apps gateway config to lengthen the Postgres connect timeout (default 5 seconds), and improved the boot error when the database is unreachable to point to `store.postgres_url` and the configured timeout
- Added `enduser.sub`, the IdP subject, to the telemetry Claude Desktop and Cowork send through a Claude apps gateway
- Added a Claude apps gateway warning when a replica has more requests open than the 256 it sends upstream at once, and a startup log line showing that limit
- Added click-to-expand for collapsed teammate and agent messages in fullscreen mode
- \[VSCode\] Added continuation of the step a window reload interrupted, labeled in the chat, with a Claude Code: Continue After Reload setting to turn it off
- \[VSCode\] Added Memory and Instructions entries to the Customize menu: Memory shows the auto-memory toggles, the saved memories and the memory folders, and Instructions edits the CLAUDE.md files
- \[VSCode\] Added a `claudeCode.lockEditorGroups` setting to stop Claude from locking the editor groups it opens in
- \[Claude Code on the web\] Added a “Compare against” branch picker to a cloud session’s diff view, so you can diff its changes against any branch instead of only the base branch
- \[Claude Tag\] Added a Guests setting to the Add channel and Add workspace forms in Claude Tag admin settings, so owners can pick Inherit, Allow, Channel only or Restrict up front

**Changed**

- Changed Bedrock, Vertex, Foundry and telemetry-disabled installs to use the v2 MCP client and MCP 2026-07-28 negotiation with direct HTTP servers by default, as other installs already do (opt out: `MCP_SDK_GENERATION=v1` or `MCP_PROTOCOL_NEGOTIATION=legacy`)
- Changed `/code-review` to use leaner inline review prompts for every model that has no tuned settings of its own, instead of spawning many review subagents
- Changed `"type": "sdk"` MCP entries in `.mcp.json`, settings, plugins and agent files to be skipped with a warning: only an SDK host application can register in-process servers
- Changed artifact watching in local sessions: a new version published elsewhere no longer starts a turn; Claude learns of it from a later Artifact tool result
- Changed plugin and marketplace clones to leave Git LFS files as pointers instead of downloading them; `git lfs pull` in the checkout fetches them
- Changed self-hosted runners to skip a read-only repository the git host refuses at the access check instead of failing the session start
- Changed the `/status` GitHub line to read “Cloud sessions”, and `/web-setup`, `/ultrareview`, and teleport messages to say “cloud session” instead of “Claude Code on the web”
- \[VSCode\] Changed the default global gitignore file to `$XDG_CONFIG_HOME/git/ignore` when `XDG_CONFIG_HOME` is an absolute path
- \[Claude Code on the web\] Changed routines to skip a run and retry for up to 72 hours when the owner’s GitHub connection is missing, instead of switching the routine off at the first failed check
- \[Claude Code on the web\] Changed a routine’s on-hold notice: when your subscription is paused it now tells you to turn the routine back on yourself instead of promising an automatic resume
- \[Claude Tag\] Removed the repeated guest-attribution note Claude appended to a Slack canvas each time it edited one in a channel using the “Channel only” guest setting

Show 13 improvements

- Improved startup in `--input-format stream-json` sessions: the first turn no longer waits up to 2s for still-connecting MCP servers whose tools tool search defers; they arrive on a later turn
- Improved Monitor tool notifications: a script’s final output and its exit now arrive as one notification instead of two, saving a model turn
- Improved Artifact tool errors: when you are not signed in to claude.ai the terminal now says so on the first attempt, and Claude is told to stop retrying a rejected call sooner
- Improved artifact publishing: a publish built on an older version is stopped before it is sent, with the newer page to merge
- Improved safety checks before removing an agent worktree that contains submodule checkouts
- Improved `OTEL_LOG_RAW_API_BODIES=file:<dir>` output: a new `index.jsonl` and `request_body_id` / `message.id` event attributes link each response to its request file and transcript message
- Improved Claude apps gateway boot: it now tries the first Postgres connection up to three times before exiting, so a database that is reachable a few seconds late no longer fails the boot
- Improved the Claude apps gateway’s spend-limit check under load: it now takes one database round trip instead of four, so fewer checks time out on a busy gateway
- Improved Claude apps gateway sign-in rate limit errors: `/login` now explains the refusal, and the gateway log says which limit was hit and which setting to change
- \[VSCode\] Improved screen reader navigation of the conversation: each message is announced as “You” or “Claude”, with the tool name for tool steps
- \[Claude Tag\] Improved Claude’s live progress checklist in Slack: capped at 2,000 characters, reposted at most every 15 minutes in busy threads, with older “Latest task list” links updated
- \[Code Review\] Improved how Code Review words each posted finding: short plain sentences that say who is affected, where the code goes wrong, and the fix up front
- \[Code Review\] Improved the check-run card and PR comment when a review is skipped because of an organization limit: each cause now links the admin page that fixes it

Show 71 bug fixes

- Fixed sessions getting stuck endlessly retrying “unexpected tool_use_id” 400 errors: corrupted transcripts now self-heal where possible, and otherwise a clear error (with a `/rewind` hint) ends the loop
- Fixed MCP servers configured as `http` that only speak legacy HTTP+SSE failing to connect when they answer the first request with 422 or another 4xx error
- Fixed Streamable HTTP MCP tool calls timing out after about 5 minutes even when a longer per-server `timeout` was set
- Fixed MCP prompts and resources not refreshing when a server sends list-changed notifications without declaring `listChanged`
- Fixed MCP tool calls refused with 403 insufficient_scope being reported as an expired sign-in: the error now names the missing permissions and points to `/mcp` re-authentication
- Fixed hook-driven sessions (such as an active `/goal`) ending with “Prompt is too long” instead of compacting when the context overflowed again after a reactive compaction
- Fixed an active `/goal` being lost when resuming (`--continue` / `--resume`) a session that had compacted
- Fixed `claude agents` losing `--model`, `--effort`, `--permission-mode`, `--allow-dangerously-skip-permissions` and `--agent` after an auto-update relaunch
- Fixed a per-turn slowdown when a language server publishes project-wide diagnostics for thousands of files
- Fixed subagents with `model: "opus"` on Bedrock, Vertex or Foundry leaving the session’s model when its id has no recognizable model family (unless `ANTHROPIC_DEFAULT_OPUS_MODEL` is set)
- Fixed self-hosted runner sessions failing every turn with a 401 after a few failed token refreshes, until the next scheduled refresh; the runner now keeps retrying, and fetches a new token after a 401
- Fixed clickable links to local file paths doing nothing in VS Code and other terminals that require a `file://` URI
- Fixed the transcript renumbering ordered lists in your own messages (typing “3. 2. 1.” displayed “3. 4. 5.”); numbers and “N)” markers now show as typed
- Fixed AskUserQuestion preview notes being attached to a previously chosen option instead of the highlighted one
- Fixed AskUserQuestion preview mode dropping the highlighted option when submitting a note with Enter
- Fixed a resumed background agent keeping half of an interrupted tool batch when one of its calls was approved with a message
- Fixed a local `claude -p --resume` started with `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` not reporting background tasks the previous process left unfinished
- Fixed the first turn of a cloud session sometimes starting without the tools of an SDK-hosted MCP server that was still connecting
- Fixed background agent notifications claiming the agent had no live background work when it was still waiting on its own background task and would resume
- Fixed error hints in Claude Desktop sessions to suggest slash commands like `/usage-credits` instead of CLI flags that cannot be used there
- Fixed `/schedule` saving a routine’s prompt without its message role when Claude writes the routine in the shape that listing routines returns
- Fixed `/status` not showing the `apiKeyHelper` failure that its own error banner told you to check
- Fixed `/fast on` in non-interactive sessions reporting on and then turning off under an organization’s managed fast mode policy; it now says the organization has disabled it
- Fixed the Artifact tool asking you to approve an update to an artifact that it then refused because the session had not read the latest version
- Fixed Cowork and claude.ai cloud sessions with network access on treating reads of a teammate’s artifact as if network access were off
- Fixed a plugin or marketplace directory with no git repository of its own taking its version from an enclosing git repository, such as a git-managed `~/.claude`
- Fixed `--strict-mcp-config` with an empty `--mcp-config` holding the first non-interactive turn for up to `MCP_TIMEOUT` on incidental MCP servers
- Fixed Stop prompt hooks re-sending their whole prompt on every block in a conversation; repeat blocks now name the condition with a 500-character label
- Fixed extra empty editor windows opening at startup on Linux under Wayland when running inside the Cursor or VS Code terminal
- Fixed an unhandled promise rejection in the Claude apps gateway when Postgres drops a connection during a spend check
- Fixed Claude apps gateway cutting every open stream on SIGTERM: it now lets in-flight requests finish for up to 25 seconds before exiting (`CLAUDE_GATEWAY_DRAIN_TIMEOUT_MS`)
- Fixed `installed_plugins.json` being rewritten on nearly every start-up when plugin policy comes from remote managed settings, which made Claude Desktop reload every open session’s plugins
- Fixed headless and SDK sessions making a separate model call for every background task that finished; completions already queued are now answered by one call
- Fixed the Bash tool re-sourcing the shell profile (a multi-second stall on the next command) after every plugin reload; it now does so only when the plugins’ `bin/` directories changed
- Fixed plugins with a top-level `$schema` in `hooks/hooks.json` showing an “unknown key” notice
- Fixed MCP connection errors and the MCP login tool’s description showing secrets resolved from `${VAR}` placeholders in MCP configs
- Fixed Bash permission checks for commands that loop over or assign certain special shell variables; these commands now ask for permission
- Fixed worktree-isolated sessions accepting Bash commands with certain nested shell expansions; these are now refused
- Fixed the Edit permission prompt preview sometimes showing a different location than the approved edit in files with multi-byte characters
- Fixed background commands being stopped after 30 idle minutes on machines under mild memory pressure; they’re now stopped only when memory is critically low, and the debug log says why
- Fixed a message a subagent sends to the main session disappearing from the Claude Desktop transcript after a relaunch
- Fixed a plugin loaded from a `.zip` being served from a stale extraction after several overlapping reloads
- Fixed a sub-agent’s progress summary being replaced by a runaway multi-paragraph reply
- \[VSCode\] Fixed a `/btw` side question asked in a new conversation’s first seconds occasionally showing another session’s side-question history
- \[VSCode\] Fixed a brief freeze when the extension first looks up your global gitignore file
- \[VSCode\] Fixed a message sent while Claude was running a tool disappearing from the conversation after a window reload
- \[VSCode\] Fixed the Manage Plugins enable toggle and MCP servers dialog rows being unreachable from the keyboard
- \[VSCode\] Fixed sign-ins and sign-outs made in a terminal not showing until a reload after `CLAUDE_CONFIG_DIR` changed in the Environment Variables setting
- \[VSCode\] Fixed Edit diffs in the chat being cut off at the bottom at some panel widths and for long wrapped lines; diff boxes now fit the rows shown
- \[VSCode\] Fixed overlapping settings writes from the extension leaving `~/.claude/settings.json` unparseable or dropping a setting
- \[VSCode\] Fixed Open in New Tab (Ctrl/Cmd+Shift+Esc) sometimes leaving the new tab’s message box unfocused, so typing went nowhere until you clicked it
- \[VSCode\] Fixed reopening a closed Claude tab splitting the editor layout when its locked group still holds another Claude tab and a file
- \[VSCode\] Fixed New session opening another locked editor group whenever a file tab shared the group with your Claude tab
- \[VSCode\] Fixed session names shifting sideways in the session picker while typing a search query
- \[VSCode\] Fixed the plan review card cutting off its Send feedback button and reason field when a plan has several comments; the comment list now scrolls
- \[VSCode\] Fixed inline code and code blocks in chat replies being unreadable under the High Contrast themes
- \[Claude Code on the web\] Fixed git operations in cloud sessions failing with “service unavailable” when GitHub’s token renewal briefly errors
- \[Claude Code on the web\] Fixed editing a routine occasionally making it fire twice or re-enabling a routine that had just been paused
- \[Claude Code on the web\] Fixed commits in cloud sessions occasionally failing with a signing error for a few minutes after the session’s credentials refreshed
- \[Claude Code on the web\] Fixed the toast after saving a routine whose GitHub trigger couldn’t be linked to show the reason, such as a per-repository trigger limit, instead of only “edit to retry”
- \[Claude Code on the web\] Fixed sessions sometimes flipping back to unread right after you mark them read
- \[Claude Tag\] Fixed Claude not answering when another Slack app or bot @mentions it; the tag now gets a reply and wakes Claude in a channel it had stopped following after days of inactivity
- \[Claude Tag\] Fixed Claude missing another app’s message that tagged @Claude right after a new Slack channel was created; it’s now delivered once Claude has joined
- \[Claude Tag\] Fixed Claude folding a follow-up sent minutes after its last Slack message into it as a silent edit; late updates such as blockers now post as a new reply that notifies
- \[Claude Tag\] Fixed Claude’s Slack search failing with an error whenever it searched within a single channel; it now returns that channel’s matching messages
- \[Claude Tag\] Fixed a safety-filter stop silently resetting a Slack thread’s context when nobody was waiting; Claude now always says so and no longer cancels background work still running
- \[Claude Tag\] Fixed email addresses in Claude’s Slack replies rendering with a visible `mailto:` prefix; they now show as the plain, clickable address
- \[Claude Tag\] Fixed Claude refusing to watch an Enterprise Grid channel shared with the whole organization when asked from another workspace in the grid
- \[Claude Tag\] Fixed the Environment picker in Claude Tag admin settings showing a raw environment ID instead of the environment’s name for archived or app-created environments
- \[Code Review\] Fixed re-reviews occasionally leaving a fixed finding’s thread open when the new review also filed a lower-severity note under it
- \[Code Review\] Fixed rare reviews ending with “Code review encountered an error” when GitHub or an internal service failed transiently at launch; they now wait and retry

[​](#2-1-273)

2.1.273

September 15, 2026

**Added**

- Added `x-claude-code-request-class`, `x-claude-code-agent-type`, `x-claude-code-prev-tool-durations`, `x-claude-code-compaction` and `x-claude-code-context-compacted` request headers for LLM gateways; opt in with `CLAUDE_CODE_GATEWAY_HINT_HEADERS=1`
- Added a notification when an MCP server disconnects mid-session and automatic reconnection gives up, pointing at `/mcp`
- Added forking a session started with `claude --remote-control` or `/remote-control` from the Claude app; the fork runs as a background session on your computer
- \[Claude Code on the web\] Added a “Discard unsaved changes?” confirmation before the New routine page or the Edit routine dialog throws away a routine name, prompt or edit you typed

**Changed**

- Reverted a 2.1.268 change that checked Read and Edit deny rules on Bash lines the permission checker can’t analyze (`eval`, `env -C`); commands like `time -p make build` prompt again instead of being denied
- Changed auto mode on Bedrock, Vertex and Foundry to use the local classifier by default for now; set `CLAUDE_CODE_AUTO_MODE_SERVER=1` to use the platform’s server-side classifier
- Changed `OTEL_LOG_TOOL_DETAILS=1` to also include real agent, skill, plugin and MCP server names on cost and token metrics
- Changed sign-in with a Claude account to also request access to your claude.ai plugins
- Changed `/bug` and `/feedback` reports to include only model-behavior params (model, system prompt, tools) from the last API request, omitting request metadata and `CLAUDE_CODE_EXTRA_BODY` fields
- \[Claude Code on the web\] Changed the admin “Share cloud sessions” setting to live under Data and privacy instead of the Claude Code page, where Data and privacy admins can also manage it
- \[Claude Code on the web\] Removed the full-page desktop-app download screen that new users without a cloud environment saw on Mac and Windows; they now go straight to setup
- \[Claude Tag\] Changed Claude to start watching related public channels on its own, such as an incident channel a conversation depends on, instead of only when asked

Show 17 improvements

- Improved responsiveness in long sessions: hook progress and sub-agent activity no longer re-process the whole conversation on every update
- Improved the Artifact tool’s error when a publish includes a file type artifacts don’t serve: Claude is told which types are served and what to do instead, and the terminal shows one plain line
- Improved the Artifact tool’s page read to state the capabilities and database rules the artifact service holds for the page, for anyone who can publish to it
- Improved artifact database writes: an update can now remove a single field instead of rewriting the whole document
- Improved artifact publishing: a publish whose connection drops after reaching claude.ai is now re-sent safely instead of failing or creating a duplicate version
- Improved the cloud-session GitHub error for an IP allow list, a suspended app installation or SAML single sign-on to show the cause instead of a generic install hint
- Improved `/autofix-pr`: when `gh pr view` fails it now shows gh’s own error (sign-in, SAML, rate limit) instead of a generic exit-code line
- Improved `/autofix-pr` to say why GitHub webhook delivery couldn’t be set up for the PR (for example, no linked GitHub account) instead of a generic warning
- Improved `/web-setup` errors: a refused GitHub token now lists the likely reasons and the fix, and a connection failure names a configured proxy or TLS certificate problem
- Improved the in-session SSL certificate and proxy connection errors to name the error code and what to fix, such as `NODE_EXTRA_CA_CERTS` for an untrusted corporate CA
- Improved the error when a cloud session can’t be created because your Claude login expired or was revoked: it now tells you to run `/login`
- Improved the error shown when an MCP server’s sign-in expires mid-session to say how to re-authenticate (`/mcp`)
- Windows: Improved the network-path permission check for UNC paths when a mapped network drive was added with `--add-dir`
- \[Claude Code on the web\] Improved the routine detail page: menu and rename in the breadcrumb, the on/off switch and Run now at the top, and run history beside the routine’s settings
- \[Claude Tag\] Improved AWS connection failures: when a request can’t be signed, such as a hostname with no region, Claude is told why and how to fix it instead of a bare error
- \[Code Review\] Improved suggested fixes to say what the fix must keep working when other code depends on the behavior being changed
- \[Code Review\] Improved review comments that point to a second affected location to state that location’s issue in a full sentence instead of a cut-off stub

Show 35 bug fixes

- Fixed Bash commands the permission checker cannot fully analyze skipping the prompt under `permissions.blockReadsOutsideWorkingDirectories`, and a subshell hiding a dangerous `rm` in bypass mode
- Fixed skills synced from claude.ai staying available after your organization turns Skills off; they now move to the recoverable trash
- Fixed `allowManagedMcpServersOnly`, `deniedMcpServers` and `disableClaudeAiConnectors` set via MDM or `managed-settings.json` being ignored when server-managed settings are also present
- Fixed 401/403 errors on Bedrock, Vertex and Foundry, and Claude apps gateway 403s, telling you to run `/login`; the message now names the credential to refresh or points to your gateway administrator
- Fixed `/login`, `/upgrade`, and `/extra-usage` discarding earlier thinking from the conversation, which forced a full prompt-cache rewrite on the next request
- Fixed auto mode stopping for approval when the Artifact tool uploads a file you attached to the chat in a cloud or Remote Control session
- Fixed a long-running session recreating a stub `.git/info/exclude` after the repository’s `.git` directory was removed or moved away
- Fixed the main prompt dropping a `!` typed at the start while already in shell mode, so negated commands like `! grep …` can be typed
- Fixed Read on macOS refusing a dragged-in screenshot, or any file the system reports under a second path, with “symlink resolution changed after permission was checked”
- Fixed `permissions.blockReadsOutsideWorkingDirectories`: a memory directory chosen by a repository’s settings is no longer loaded into the prompt, recalled, indexed, or used by memory extraction
- Fixed sub-agents and background agents being reported as failed, with their result never delivered, when the final streamed reply omitted token usage or carried no model id
- Fixed the context meter and auto-compact counting advisor-tool turns at roughly twice their real context size, which made auto-compact fire at about half the real window
- Fixed `/tui` refusing to restart because of an agent-team teammate that had already finished its work and was no longer shown in the agents panel
- Fixed saved scheduled tasks running in the wrong session after `.claude/scheduled_tasks.json` was copied into another folder, such as a new worktree
- Fixed SDK and `--output-format stream-json` output dropping a subagent’s remaining messages and final report after it is moved to the background mid-run (e.g. by `CLAUDE_AUTO_BACKGROUND_TASKS`)
- Fixed `/install-github-app` reporting a SAML single sign-on block as “admin permissions required”
- Fixed Remote Control clients attached to a Claude Desktop, VS Code or JetBrains session being refused when they ask for the session’s context window usage
- Fixed the spinner showing a doubled ellipsis (”……”) on compaction status lines such as “Running PreCompact hooks…”
- Fixed a false-positive spinner tip suggesting the frontend-design plugin after reading or publishing Artifacts
- \[VSCode\] Fixed “Report a problem” still appearing, and `/bug` / `/feedback` opening a report form, for organizations that have product feedback disabled
- \[VSCode\] Fixed a red “Claude Code process exited with code 4294967295” banner appearing after completed turns on Windows
- \[Claude Code on the web\] Fixed routines losing access to an organization connector, and still calling the old one, after an admin removed and re-added that connector
- \[Claude Code on the web\] Fixed creating a self-hosted environment from organization settings occasionally failing with a server error and leaving a half-created environment behind
- \[Claude Tag\] Fixed Claude going silent minutes after reinstalling the app when an Enterprise Grid was disconnected but one of its workspaces stayed connected
- \[Claude Tag\] Fixed scheduled tasks set up in an organization-shared private Slack channel silently never posting; they now keep running in the thread they were created in
- \[Claude Tag\] Fixed replying in an older Slack thread while Claude is mid-task sometimes restarting it from scratch and losing work it had not pushed yet
- \[Claude Tag\] Fixed Claude occasionally dropping a message with an incorrect “couldn’t find a Claude Code environment” notice right after your account token refreshed
- \[Claude Tag\] Fixed AWS connections refusing region-less endpoints such as Budgets, Savings Plans, WAF Classic and Import/Export; Global Accelerator requests now sign correctly
- \[Claude Tag\] Fixed OAuth client-credentials and JWT-bearer connections failing with providers that return a lowercase token type; requests now send the standard Bearer scheme
- \[Claude Tag\] Fixed adding a channel manager being refused on Enterprise Grid shared channels, on channels where Claude hasn’t been used yet, and on legacy private channels
- \[Claude Tag\] Fixed the admin Memory page not listing Slack channels Claude set up on its own even when they had saved memory; admins can now open, edit and delete that memory
- \[Code Review\] Fixed merging the base branch into a PR whose earlier review listed “Additional findings” triggering a full re-review; these pushes now get the lighter follow-up review
- \[Code Review\] Fixed a whole REVIEW.md being ignored because of an @-mention, a code span wrapped across lines, or a backticked HTML tag; only lines linking to changed files are withheld
- \[Code Review\] Fixed `/ultrareview --post` so a retry after a GitHub error posts the findings comment exactly once instead of never or twice; the comment now names the reviewed commit
- \[Code Review\] Fixed empty or content-identical pushes being re-reviewed on GitHub repositories whose owner or name contains a capital letter; these pushes are now skipped

[​](#2-1-272)

2.1.272

September 15, 2026

- Bug fixes and reliability improvements

[​](#2-1-271)

2.1.271

September 14, 2026

**Added**

- Added fast mode in Claude Code Remote sessions (cloud and self-hosted runners): the host’s fast-mode setting or `/fast` typed in the session applies where your organization allows it
- Added mouse support to the `/config` panel in fullscreen mode: the wheel scrolls the settings list, a click on a setting’s value changes it, and the row under the pointer is highlighted
- Added `claude self-hosted-runner --drain-marker-file <path>`: when that file exists at a SIGTERM drain, the runner reports its exit to the server as a host drain (telemetry only)
- Added per-command `allowed_domains` to Bash, PowerShell and Monitor in auto mode with sandboxing: the hosts a command needs are reviewed with it and opened for it alone; other hosts are refused
- Added `omitClaudeMd` to agent frontmatter and `--agents` JSON, letting custom and plugin subagents run without user, project and local CLAUDE.md files; managed policy files still load
- Added `--accept-command <sha256>` to `claude plugin install` and `claude plugin update` to accept exactly the command a previous `--json` run displayed, instead of `-y`
- Added support for a `multiplier` above 1, up to 10, in the `modelPricing` managed setting and the Claude apps gateway `pricing` block, for marked-up internal chargeback rates
- Added a spinner tip pointing Bedrock, Vertex AI, Foundry and LLM gateway users to the Claude desktop app; the claude.ai desktop app tip now suggests `/desktop`, which offers to download the app
- \[VSCode\] Added an Attach Open File setting that, when turned off, stops the open file from being added to messages; selected text is still attached
- \[Claude Code on the web\] Added a Custom network access option to the Cloud environments editor in admin settings, with the same allowed-domains list the environment dialog on claude.ai/code offers

**Changed**

- Changed auto mode so that a skill’s or slash command’s inline `!` shell commands follow default-mode permission rules instead of the classifier; a command no rule decides runs as a reviewed tool call
- Changed auto mode so a subagent reports back to its caller through a dedicated hand-back call that the safety classifier reviews, instead of its last message being reviewed after the fact
- Changed Monitor watches to always have a deadline (at most 30 minutes; 10 in single-prompt `-p` runs) and notify Claude to re-arm, replacing the no-timeout `persistent` option
- Changed the IDE selection indicator in the prompt to a `[⧉ …]` pill that wraps with the text instead of squeezing multi-line prompts; delete it with Backspace to leave the selection out
- Changed the default dynamic workflow size to small on Pro plans and lowered the medium size guideline from 15 to 10 agents
- Changed Claude apps gateway, Bedrock, Vertex AI, and Foundry sessions so that they no longer refresh a leftover claude.ai login that the session does not use
- Updated the bundled `claude-api` skill to enable `eager_input_streaming` on streaming custom tools, and to start deliverable-shaped Managed Agents work with `user.define_outcome`
- \[VSCode\] Changed the on state of toggle switches from Claude orange to the editor theme’s button color
- \[Claude Code on the web\] Changed the Routines page on claude.ai/code to a new layout with Yours and Templates tabs and two-column routine cards that show run status, and removed its calendar view

Show 18 improvements

- Improved terminal rendering performance: large diffs and long transcripts render faster, with fewer slow frames
- Improved startup time slightly by skipping a redundant validation of built-in model data on every launch
- Improved hook feedback: while a SessionStart, UserPromptSubmit, PreToolUse or SessionEnd hook runs, the spinner says so with elapsed time, and Esc cancels a prompt waiting on a SessionStart hook
- Improved the spinner status during long thinking: it now reads “deep in thought” after 45s, and shows “picking the thought back up” while recovering from the output-token limit
- Improved dynamic workflows to pause when you hit your usage limit and continue automatically when it resets, instead of dropping the affected agents
- Improved Remote Control to leave fewer empty sessions on claude.ai when setup fails on a flaky network
- Improved the Claude in Chrome message in cloud sessions when the browser can’t be reached: it now says the computer may be asleep before it suggests an install
- Improved `claude mcp serve`: a running tool call now sends a progress update every 30 seconds, so clients show it is still running and idle timeouts don’t abort a long command that prints nothing
- Improved Foundry and Claude Platform on AWS sessions: an `alwaysLoad` MCP server that finishes connecting mid-conversation is usable on the next turn without a tool-search round trip
- Improved Markdown files published as artifacts: they now render as styled document pages (title header, document typography, syntax-highlighted code)
- Improved Artifact tool publish errors: a publish with no file now says to write the page to a file first, and an unsupported file type is reported before a missing favicon
- Improved the Artifact tool’s error when a page declares a capability its contract version lacks: it now lists every supported capability and notes when a newer contract version has it
- Improved artifact watching: a session can now watch up to 10 published artifacts at once for republishes made elsewhere, up from 5
- Improved PDF @-mentions to say “page count unknown” instead of a page count guessed from the file size when pdfinfo cannot count the pages
- Improved `/mobile` to show a single QR code for claude.ai/mobile, which opens the right app store for your phone
- \[VSCode\] Improved the Hooks dialog: a save refused because of the settings file itself now opens a popup with an “Open settings file” button and the reason behind “Copy error”
- \[Claude Code on the web\] Improved the Cloud environments admin page: it shows the default environment for Claude Tag and Claude Code, with a link to change it, and marks the recommended kind to create
- \[Claude Tag\] Improved the Environment picker in Claude Tag admin settings: options are labeled Anthropic-hosted or self-hosted, with links to edit that environment or create one

Show 59 bug fixes

- Fixed a cached organization policy being reused after switching accounts, organizations, or API keys, and the policy not refreshing until the hourly check when the credential changes mid-session
- Fixed the tool and command lists not updating when the organization policy finishes loading after startup or changes mid-session
- Fixed an enterprise `managed-mcp.json` that can’t be read or parsed being ignored: it now keeps exclusive MCP control (user, project and plugin servers don’t load) and warns at startup
- Fixed org policy being fetched through, and rejected by, third-party local proxies set via `ANTHROPIC_UNIX_SOCKET`; they are again treated like other custom gateways, including for Remote Control
- Fixed cloud sessions rejecting every subagent tool call (“updatedInput … failed schema validation”) when a workflow or agent approval was applied after the session’s worker restarted
- Fixed `/fast off` answering “Fast mode unavailable” instead of turning fast mode off when the organization has fast mode disabled
- Fixed sessions started with `CLAUDE_CODE_SKIP_FAST_MODE_ORG_CHECK` re-sending fast requests every turn after the API rejected fast mode; the rejection now stands and its reason is shown
- Fixed fast mode under `CLAUDE_CODE_RETRY_WATCHDOG` failing the turn on a usage-credits limit, or retrying an overload at fast speed, instead of falling back to standard speed
- Fixed Bash permission checks missing the file that `fmt`, `column` and similar commands read when it follows an option the checker doesn’t recognize
- Fixed Bash permission checks skipping files a wildcard expands to when the wildcard sits in a command’s pattern or option value (for example `grep -v dir/* file`)
- Fixed Bash permission checks so that shell variable declaration flags cannot misrepresent the command being run
- Fixed Bash commands with two directory changes, a subshell, or a `cd`+`git` chain skipping the prompt under `permissions.blockReadsOutsideWorkingDirectories` in bypass and auto mode
- Fixed a stale `.git/config.lock` breaking `git checkout -b`, `git push -u` and `git config` for the rest of a session after a sandboxed command failed to start (Linux)
- Fixed settings file changes made outside the session going unnoticed on macOS machines whose system file-event service is saturated; the watcher now falls back to polling
- Fixed resumed `claude -p` sessions whose tools all come from MCP servers failing with “At least one tool must have defer_loading=false”
- Fixed turns failing with “API returned an empty or malformed response” when an LLM gateway returns the non-streaming reply as `text/plain`
- Fixed sustained high CPU usage and repeated tool-list requests when an MCP server sends `list_changed` notifications in a tight loop
- Fixed MCP OAuth mishandling client registrations: denying consent forced a new one, one for another redirect URI was reused, and a concurrent write could delete a valid one or keep a mismatched one
- Fixed tool search returning no match when Claude selects an MCP tool by its bare name instead of its full `mcp__server__tool` name
- Fixed Ctrl+O cancelling pending MCP server reconnects, and `/mcp` sent from Remote Control failing while the transcript view is open
- Fixed the Claude in Chrome prompt telling the model to load tools through ToolSearch when ToolSearch is unavailable
- Fixed cross-session messages held by the receiving session’s permission-mode policy leaving no trace: headless senders now get a delivery notice, and `SendMessage` results no longer imply it was read
- Fixed Claude starting a second copy of a background command (such as a watch task or dev server) that was still running after the conversation was compacted
- Fixed `/model` warning about losing the conversation cache when switching back to the model the conversation actually ran on
- Fixed `/reload-skills` reporting a skill count that disagreed with the slash menu after `/cd`
- Fixed `/resume` and `/continue` showing only 1-2 sessions in fullscreen mode on short terminals
- Fixed `/resume` and `/teleport` keeping the previous conversation’s file-read tracking, so Claude could edit files the resumed conversation had never read
- Fixed `--resume` dropping the 1M context window (`[1m]`) when the resumed session’s model family differs from the configured default model
- Fixed artifacts attached with `/artifacts` disappearing from the session after `--resume`
- Fixed background sessions (`claude --bg`, `claude agents`) not watching the artifacts they publish for republishes made elsewhere
- Fixed custom agents, slash commands and output styles beyond the first not loading from a virtual drive that reports inode 0, such as an encrypted vault mounted as a Windows drive
- Fixed self-hosted runner sessions silently losing all host config (settings, skills, plugins, MCP servers) when the host config directory exceeds 64 MiB; added `--host-config-snapshot disk|memory`
- Fixed skills synced from claude.ai staying on disk indefinitely after signing out; copies not refreshed within `cleanupPeriodDays` now move to the recoverable trash at the next launch
- Fixed spinner tips suggesting commands that aren’t available for your account type or are disabled in your session
- Fixed the `/add-dir` path input: the left and right arrow keys now move the cursor, and Enter adds only the typed path instead of also adding the highlighted completion
- Fixed text fields outside the main prompt moving a leading `!` to the end of what you typed (`!foo` came out as `foo!`)
- Fixed the interactive `/hooks` menu crashing when a hook matcher is named after an inherited object property such as `__proto__` or `constructor`
- Fixed a fullscreen rendering glitch where text kept a stale background color after the box around it lost its background
- Fixed Delete in st and Alt+arrow keys in rxvt-unicode not working in attached background sessions
- Fixed the terminal’s replies to capability queries (`^[[?1;2c`) appearing at the shell prompt or in an editor when Claude Code exits, is suspended, or opens an editor right after starting
- \[VSCode\] Fixed the Hooks and Permission rules dialogs reporting a save that landed as failed, and the Hooks dialog going blank under a plugin-only policy lock or showing color codes in save errors
- \[VSCode\] Fixed Hooks dialog saves: no duplicate hook on replace, a header name retyped in other capitals keeps its secret, and settings.local.json is gitignored before the save returns
- \[VSCode\] Fixed session history showing only the current session when the workspace is on a Windows mapped network drive or SUBST drive
- \[VSCode\] Fixed the session list’s Active filter hiding open idle sessions when Open is also checked in the filter menu
- \[VSCode\] Fixed a new chat switching back to the previous chat when the session list refreshed
- \[VSCode\] Fixed open tabs and the side bar keeping the old config folder until a window reload after `CLAUDE_CONFIG_DIR` changed in the `environmentVariables` setting
- \[VSCode\] Fixed console windows flashing on Windows when the extension runs background commands such as git, ripgrep, and the sign-in status check
- \[VSCode\] Fixed the prompt cache clock’s hover text appearing only after a delay, and the auto-compact icon showing the browser’s own tooltip beside its popup
- \[Claude Code on the web\] Fixed a cloud session sometimes taking about ten minutes to respond after its process exited while the session still looked live; sending a message now restarts it right away
- \[Claude Tag\] Fixed Claude in a channel where it stays active losing its working context about once an hour when the conversation is mostly in threads; thread activity now keeps it from being reset
- \[Claude Tag\] Fixed a thread that asked Claude to watch a pull request no longer hearing about CI failures, comments and reviews after Claude was restarted in that thread
- \[Claude Tag\] Fixed deleting the first message of a thread Claude had already replied in not ending Claude’s work there; it now stops, as it did when a message with no replies was deleted
- \[Claude Tag\] Fixed Claude holding back a post because of an earlier instruction addressed to a different bot or assistant; only instructions addressed to Claude bind it, and it asks when unsure
- \[Claude Tag\] Fixed the reply-mode card Claude posts on joining a busy channel saying it “sees a lot of automated posts” when the channel is only chatty or large; the card now names the real reason
- \[Code Review\] Fixed a pull request in a repository reviewed once per PR sometimes getting no review when a commit arrived while its review was waiting to start; it now reviews the requested commit
- \[Code Review\] Fixed Code Review occasionally posting the same findings two or three times when GitHub reported an error for a review it had in fact created
- \[Code Review\] Fixed follow-up reviews re-posting a security finding a person had already resolved when a later push moved the lines it was anchored to
- \[Code Review\] Fixed reopening a finished /ultrareview cloud session in the Claude app starting the whole review over again unprompted
- Windows: Fixed PowerShell commands failing with “Exit code 1” and no output when the session’s temp output path reaches 260 characters

[​](#2-1-270)

2.1.270

September 12, 2026

- Fixed read-only git commands in Bash unexpectedly asking for permission after a session had been running for a while (regression in 2.1.269)

[​](#2-1-269)

2.1.269

September 11, 2026

**Added**

- Added `claude plugin eval`: run a plugin’s eval suite against Claude Code and get scored, reproducible results (JSON + HTML report); see `claude plugin eval --help`
- Added `/output-style [name]` to list and switch output styles, including over Remote Control and in cloud and other headless sessions
- Added a diff of the files a Bash command changed to the Bash tool result when the Bash tool handles file edits (setting `bashEditDiffEnabled`)
- Added `OTEL_METRICS_INCLUDE_REPOSITORY` to tag OpenTelemetry metrics and events with `vcs.*` repository attributes; commit events get `vcs.ref.head.*` with `OTEL_LOG_TOOL_DETAILS`
- Added `CLAUDE_CODE_GATEWAY_MODEL_DISCOVERY_TIMEOUT_MS` to extend the LLM gateway `/v1/models` discovery timeout (default 3s)
- Added a spinner tip suggesting `/focus` for a view with just your prompt, a one-line work summary, and the response
- Added `CLAUDE_CODE_WORKFLOW_MAX_CONCURRENT_AGENTS` (1–256) to raise the Workflow tool’s per-run concurrent agent limit for inference-bound fan-outs
- \[VSCode\] Added an agent map: an “N agents” footer pill opens a map of the session’s sub-agents with per-agent cards, Stop agent, and read-only transcripts
- \[VSCode\] Added a Hooks dialog to the command menu for viewing hooks and adding, editing, or removing them in user, project, and local settings; managed, plugin, and session hooks stay read-only
- \[VSCode\] Added live progress rows for running subagents under the tool-call groups in Focus view
- \[VSCode\] Added a Permission rules dialog that lists permission rules and adds or removes them in user, project, and local settings; startup-option, session-only, and managed rules stay read-only
- \[VSCode\] Added a Cancel button to the Switch account screen that returns to your session as the current account
- \[Claude Code on the web\] Added taking back a queued message in a cloud session before Claude reads it: remove it from the queue, or press Esc or Up, and the text returns to the message box
- \[Claude Tag\] Added a confirmation dialog before Connect all or Disconnect on a GitHub installation in admin settings, to guard against accidental organization-wide changes

**Changed**

- Changed `/ultrareview --post` to post the PR comment directly when the findings arrive and print the comment link, instead of starting a second cloud session to post it
- Changed artifact database reads that save into the session scratchpad so they no longer stop for working-folder approval
- Changed skills synced from claude.ai in cloud sessions to be named `anthropic-skills:<name>`, matching Claude Desktop; the bare name still works when nothing else uses it
- \[VSCode\] Changed the current-file chip in the message box: an X now removes it, replacing the Hide toggle
- \[VSCode\] Removed the Claude Code items from a session tab’s right-click menu and the editor title bar’s ”…” menu; they could not act on the tab the menu was opened on
- \[Claude Code on the web\] Changed the Cloud environments admin page to list every environment instead of capping each table at five rows behind a Show more control that could be unreachable
- \[Claude Code on the web\] Changed claude.ai/code for Free-plan users to open the plans page with a path to upgrade, instead of a “Disabled by org admin” page with no way forward

Show 11 improvements

- Improved the `/diff` panel to open fully rendered in one step instead of showing a loading state first
- Improved prompt suggestion filtering for Japanese, Chinese and Korean text: mixed-script and single-word suggestions are kept, and meta or evaluative text is dropped as it is for English
- Improved the Skill tool’s “Unknown skill” error to name the plugin skill’s full name when a bare name matches exactly one plugin skill
- Improved keyboard support over SSH and in unrecognized terminals: terminals that answer the kitty keyboard query (such as foot and Alacritty 0.16+) now get Shift+Enter and Ctrl+Shift shortcuts
- Improved responsiveness in long sessions: transcript updates no longer re-process the whole conversation to build the collapsed tool-use summaries
- Improved first-party sessions with telemetry disabled: an `alwaysLoad` MCP server that finishes connecting mid-conversation is usable on the next turn without a tool-search round trip
- \[VSCode\] Improved documents and messages written for someone other than the user: Claude now writes them for that audience and names it at the top of its reply
- \[VSCode\] Improved screen reader and keyboard accessibility in the slash-command menu, @-mention menu, output-style picker, Send/Stop button, permission and question cards, and onboarding checklist
- \[Claude Tag\] Improved load time of the admin settings page and its Slack channel picker, most noticeably for organizations with many channels or several connected workspaces
- \[Claude Tag\] Improved scheduled routines in Slack channels: a routine run can now reply in an existing thread instead of always posting a new top-level channel message
- \[Claude Tag\] Improved the timestamp on Claude’s live progress checklists to show each reader’s local time and how long ago it was updated, instead of a fixed UTC time

Show 66 bug fixes

- Fixed the prompt cache being partially invalidated on the turn after a response was cut off at the output-token limit and automatically resumed
- Fixed a case where resuming a session after interrupting Claude mid-thought could change how earlier context was re-sent, hurting prompt-cache reuse
- Fixed F1/F2/F4 not working in kitty-protocol terminals and Delete in st, Alt+arrows acting as Escape in rxvt-unicode, and Shift+punctuation typing the unshifted key in WezTerm (regression in 2.1.247)
- Fixed remote and headless sessions reporting “waiting for your input” while background agents were still running (set `CLAUDE_CODE_BG_TASKS_REPORT_RUNNING=0` to restore the old behavior)
- Fixed the terminal’s replies to capability queries (`^[[?1;2c`) appearing as stray text at startup in some terminals
- Fixed rows at the top or bottom of the transcript going blank in fullscreen after resizing the terminal
- Fixed a deny or ask permission rule starting with `!` applying beyond the settings source that wrote it; such a rule now applies only within its own source, and a bare `!` negation is ignored
- Fixed the git status Claude is told after a compaction: it is now the current status, not the one from the start of the session
- Fixed synced plugin MCP servers not connecting when a remote session resumes
- Fixed resumed headless sessions losing a turn’s replies when the model was switched or a request was retried mid-turn
- Fixed terminal escape codes, line breaks and oversized text from a background task’s on-disk record reaching the task list and task notifications when work is resumed
- Fixed CMYK JPEG images failing to attach with “cannot decode”; they are now converted and resized like other JPEGs
- Fixed the managed settings approval dialog not naming the collector for a gRPC telemetry endpoint set without a scheme
- Fixed plugin `headersHelper` consent prompts showing a URL path that could be misread as a different host
- Fixed plugin errors showing `[redacted URL]` in place of a relative Windows path with a folder name that starts with `@`
- Fixed missing cursor in the permission-rule, auto-mode-rule, add-directory, session-rename and feedback-review text fields when the terminal’s native cursor is enabled
- Fixed repeated clicks on a `/fork` receipt, each under a second apart, never backgrounding the session right away while it waited for the current tool to finish
- Fixed plugin LSP servers that reject `shutdown` params (e.g. rust-analyzer) being left running at session end; `exit` is now sent even if `shutdown` fails
- Fixed the attribution reminder overriding a CLAUDE.md or memory rule against commit and pull request attribution; lines set by managed settings still apply
- Fixed prompt suggestions being dropped for text in Japanese, Chinese, Thai and other languages written without spaces between words
- Fixed synchronized output being assumed from the terminal’s name in GNOME Terminal and Konsole versions that do not support it
- Fixed `permission_denials` in `--output-format stream-json` results omitting Read, Edit and Write calls blocked by a path-scoped deny rule
- Fixed sessions run through the SDK or the desktop app showing an unknown status in other sessions’ agent list
- Fixed `/insights` failing on Bedrock, Vertex, Foundry, and gateway deployments whose account can’t reach the default Opus model by using the session model there instead
- Fixed organization policy limits not loading for the session when another Claude Code process refreshed the login at the same moment
- Fixed Claude Desktop sessions using Bedrock, Vertex, or a gateway not getting the contextual “what Claude needs” turn-end notification text
- Fixed MCP servers reconnecting when an updated config only changed the order of the server URL’s query parameters
- Fixed the prompt box’s top border splitting into extra lines when viewing a background agent whose name or description has line breaks or is wider than the terminal
- Fixed sessions getting permanently stuck on “Prompt is too long” when auto-compaction had no complete earlier exchange to summarize (mostly Agent SDK sessions with very large prompts)
- Fixed `/goal` runs silently stalling after API errors, network drops, or token limits: the goal now retries with backoff, or pauses and says why, including until a usage limit resets
- Fixed prompt cache misses in cloud sessions by waiting briefly for server configuration before the first request
- Fixed `/btw` answers that contained made-up tool calls and output: the side question is now told not to write them, and any that appear are flagged as not executed
- Fixed `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` re-running a turn that had failed with an API error over 6 hours earlier, or longer ago than `CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS` when set
- Fixed organization plugins enabled through managed settings not loading in headless sessions and on Claude Desktop (once Desktop bundles this CLI version); they load from the next session
- Fixed plugin archives extracted for a session being readable by other local users, extracted files keeping world-writable bits from the archive, and stale files surviving re-extraction
- Fixed `Edit()` deny rules and the write-path check not applying to the file a Bash `tee` command writes; a `Bash(tee:*)` allow rule no longer covers destinations outside the working directories
- Fixed stray characters like `22c`, or a terminal’s color or version reply, being typed into the prompt at startup over slow connections (ssh, browser terminals)
- Fixed the terminal’s block cursor showing under the interface in rxvt-unicode after leaving or re-entering fullscreen
- Fixed the cursor block staying visible after returning from an external editor in fullscreen mode on rxvt-unicode
- Fixed the interface being drawn twice after returning from an external editor (Ctrl+G) outside fullscreen mode
- Fixed the interface being drawn twice in Konsole after returning from an external editor
- Windows: Fixed PowerShell tool commands sent to the background stopping when Claude Code exits
- \[VSCode\] Fixed Focus view showing a turn started by a delivered plain-text prompt, such as a scheduled task’s, as part of the previous turn
- \[VSCode\] Fixed the footer’s prompt cache clock hiding its minutes when the panel is narrow
- \[VSCode\] Fixed the session list keeping sessions from the default folder when `CLAUDE_CONFIG_DIR` is set in a settings file or the `environmentVariables` setting
- \[VSCode\] Fixed a plan preview that finished loading late sometimes hiding its comment box or showing an older plan
- \[VSCode\] Fixed a plan preview accepting comments that went nowhere after its Claude tab closed
- \[VSCode\] Fixed the prompt cache clock and reopen notice for a session compacted after its last reply and then closed, which now reads as cold when reopened
- \[VSCode\] Fixed a session renamed in the extension while Remote Control is on keeping its old name on claude.ai/code
- \[VSCode\] Fixed the “Enable Remote Control for all sessions” toggle keeping its last position after the setting was reset to default from a terminal
- \[VSCode\] Fixed restored Claude tabs not counting as open in the session list after a window reload until clicked, and their row opening a second tab
- \[VSCode\] Fixed Switch account making a tab forget its dismissed usage-limit warnings when you sign back in as the same account
- \[VSCode\] Fixed a session rename being replaced by the generated name after a window reload when the session was renamed during a long turn
- \[VSCode\] Fixed the sidebar usage meter keeping a stale per-model weekly limit row after the account loses that limit
- \[VSCode\] Fixed a rare case where an @-mention sent with the keyboard shortcut while a new chat view was still starting could be inserted into the input long after the keystroke
- \[VSCode\] Fixed the session list jumping down when the Account & usage header appeared a moment after opening the Claude side bar
- \[Claude Code on the web\] Fixed `/model default` in a cloud session leaving every later message failing in organizations that restrict which models Claude Code can use
- \[Claude Code on the web\] Fixed one-off scheduled routines occasionally running a second time after a transient server error
- \[Claude Code on the web\] Fixed routine runs that use subagents sometimes being treated as finished too early, which could skip the retry after a real failure or start a duplicate run
- \[Claude Code on the web\] Fixed file links in cloud session transcripts opening a GitHub 404 when Claude was working from a subfolder of the repository
- \[Claude Tag\] Fixed threads occasionally going silent after a failed turn because the failure notice was dropped when Slack briefly rate-limited it; the notice is now retried
- \[Claude Tag\] Fixed Claude accepting a switch to a model your organization hasn’t enabled and then quietly answering with a fallback model; it now declines and says an admin can enable it
- \[Claude Tag\] Fixed a table posting as raw pipe text when Claude attached files to the same message; the table now posts as a normal reply and the files follow with a plain caption
- \[Claude Tag\] Fixed `@Claude !restart` at the top level of a channel where Claude isn’t active starting an unrelated conversation; it now privately says there is nothing to restart
- \[Claude Tag\] Fixed plugin rows in Slack access settings showing an unlabeled raw ID with no way to turn the plugin off; they now show its name and link to the bundle that manages it
- \[Claude Tag\] Fixed the shared-session banner and Share dialog on sessions started from Slack claiming the whole organization could open the link; they now name the Slack channel’s audience

[​](#2-1-268)

2.1.268

September 10, 2026

**Added**

- Added to the Claude apps gateway: with `pricing:` set in `gateway.yaml`, signed-in Claude Code clients receive the same rates through managed settings, so `/cost` and telemetry match the spend meter
- Added a startup warning for gateways when `access_control.allow_cidrs` is empty, and a one-time warning the first time a request arrives from a public address
- Added the `gatewayInternalNetworks` managed setting, letting administrators allow `/login` to a Claude apps gateway on their organization’s own public IPv4 block
- Added `claude self-hosted-runner --remove-session-state` (default off): delete each session’s per-session directories under `<base-dir>/_sessions/` when the session ends
- Added `configDirectory` to the output of `claude auth status --json`
- Added `--json` to `claude plugin install`, `uninstall`, `update`, `enable` and `disable`, and `errorDetails`/`noteDetails` to each row of `claude plugin list --json`
- Added browser-tab icons for published artifacts, chosen by Claude to match each page
- \[VSCode\] Added Left and Right arrow keys to change where an always-allow permission rule is saved, for keyboard and screen reader users
- \[VSCode\] Added a “Claude Code: Focus last message” command that moves keyboard focus to the newest message in the conversation, for keyboard and screen reader users
- \[Claude Tag\] Added a link from a Slack channel’s configure page back to the organization’s Claude in Slack admin settings
- \[Code Review\] Added a note under the still-open findings list in follow-up reviews: resolving a finding’s thread, not just replying to it, stops later reviews from counting it as open

**Changed**

- Changed the system prompt on Bedrock, Vertex and Foundry to deliver environment, model and settings details as attachments, matching first-party sessions
- Changed Bedrock, Vertex and Foundry sessions to keep the tool list byte-stable across a conversation (late-connecting tools load deferred instead of rewriting it), matching first-party sessions
- Changed the task-tracking tools (TaskCreate/Get/Update/List, TodoWrite) to be offered only on Claude 3.x, Opus 4.0–4.7, Sonnet 4.0–4.6, Haiku 4.5; set `CLAUDE_CODE_ENABLE_TODO_TOOLS=1` elsewhere
- Changed the artifact data-edit permission prompt in the terminal to a card that shows the document count and who can open the artifact
- Changed local Cowork sessions set to skip all approvals: the Artifact tool now refuses a local file outside the session’s folders, or behind a symlink, instead of reading it without asking
- Changed plain `WebFetch` deny and ask rules to no longer apply to Artifact tool reads and updates; use an `Artifact` rule (or `WebFetch(domain:claude.ai)`) to block or gate them
- Changed the “N MCP servers need authentication” startup notice to announce each server once instead of at every launch
- \[VSCode\] Changed the Manage plugins dialog to apply installs, enables, disables and uninstalls to open sessions without a restart
- \[VSCode\] Changed some artifact permission prompts to omit the “don’t ask again” choice, matching the terminal
- \[Claude Tag\] Changed memory in public channels: each channel now keeps its own notes, and Claude no longer recalls notes it saved in other public channels; workspace notes stay shared

Show 16 improvements

- Improved fullscreen mode: adding or removing a prompt line (Shift+Enter) now repaints as fast as typing a character instead of re-rendering the visible transcript
- Improved `--continue` / `--resume`: the conversation appears immediately instead of waiting for SessionStart hooks, and the first message no longer re-reads the whole transcript
- Improved responsiveness during tool-heavy turns by no longer redrawing the transcript for a hidden per-tool-batch reminder
- Improved startup time in projects with `.claude/workflows/` scripts: listing them no longer parses each script
- Improved auto mode denials: the message Claude receives now names the rule that blocked the action and asks Claude to try a safer method and finish unrelated work before stopping to ask you
- Improved Claude in Chrome: long page reads now stay inline instead of being saved to a file and read back
- Improved the MEMORY.md truncation warning to say how many lines were cut and where the cut starts
- Improved the terminal permission prompt for artifacts: it now leads with the ask’s question
- Improved the prompt footer: an editor or `/diff` selection now shows inside the prompt input, and fullscreen mode shows Remote Control status in the header instead of the footer
- Improved the “Usage credits required for 1M context” message to say that usage credits turned on mid-session take effect after restarting Claude Code
- Improved `/plugin`: installing, enabling or disabling a plugin now takes effect when you close the menu; `/reload-plugins` is no longer needed afterwards
- \[Claude Code on the web\] Improved routine creation from a conversation: when the new routine has no connectors, Claude now says so and how to add them instead of only confirming it
- \[Claude Tag\] Improved how Claude explains a blocked action: it now says whether a permission check, its own decision to confirm first, or missing access stopped it
- \[Claude Tag\] Improved reply speed: Claude now runs several read-only lookups (searching Slack, reading a thread, finding people) at once instead of one after another
- \[Claude Tag\] Improved formatting of comparisons: sentence-length comparisons now come as lists instead of wide tables that scroll sideways, and long table cells wrap
- \[Claude Tag\] Improved the message shown when your Claude account is in a different organization than the Slack workspace: it now explains how to connect the workspace to your org

Show 59 bug fixes

- Fixed every turn failing with HTTP 400 on third-party Anthropic-compatible endpoints (`ANTHROPIC_BASE_URL`) since 2.1.265: a regex in the Artifact tool’s input schema that those endpoints reject
- Fixed WebFetch hanging indefinitely on a server that keeps the response open without finishing; a fetch now fails after 300 seconds. Set `CLAUDE_CODE_WEBFETCH_DEADLINE_MS` to override the deadline (0 turns it off)
- Fixed a respawned in-process teammate picking up tools or a system prompt from a same-named agent file in a folder you have not trusted
- Fixed sustained high CPU usage: a busy loop in long-running idle sessions no longer pins a CPU core, and rapid terminal focus reports during a session recap no longer keep the CPU high
- Fixed Claude sometimes replying “your message came through empty” after an MCP tool call
- Fixed deny and ask permission rules on symlinked directories (`/etc`, `/tmp`, `/var` on macOS; `/bin` on Linux) not applying when a path was given by its real location, and Bash commands ignoring deny rules written on a symlinked path spelling
- Fixed a case where a Read or Edit deny rule did not apply when an `env -C`, `eval` or similar command the permission checker cannot analyze was on the same line
- Fixed plugin and marketplace errors showing a token or password from a git source URL
- Fixed `/mcp` and `/plugin` server details, `claude mcp list`/`get`, and MCP login errors showing secrets resolved from `${VAR}` placeholders in MCP configs
- Fixed prompt caching and extended thinking breaking mid-session for SDK sessions using `excludeDynamicSections`: the first message is no longer re-rendered each request
- Fixed entitled users being told a model is restricted after restart or in the Desktop Code tab when a cached model-access denial was stale
- Fixed a running session silently switching to the organization’s default model when another Claude Code process refreshed a stale model-access entry
- Fixed long-context 429s on Fable models showing the usage-credits consent prompt instead of the 1M-context message on Pro and Team plans
- Fixed workload identity federation via a profile (as claude-code-action configures it): processes sharing the profile could fail mid-run with `401 … jti reused`
- Fixed MCP server OAuth sign-in failing with “No available ports for OAuth redirect” when the local callback port range can’t be bound
- Fixed the conversation summary produced by `/compact` and auto-compact mangling text that contained `$` sequences
- Fixed resuming a conversation that ended with `/compact`: its restored-file notes now load in the same order on every resume
- Fixed SDK prompt suggestions, side questions and `/rename` sending the conversation from before a compaction
- Fixed `@` file and `/` command suggestions not appearing after recalling a previous prompt with the up arrow and editing it
- Fixed `claude agents`: pressing ← again at a natural pace to go back to the agent list no longer gets ignored until you pause for over a second
- Fixed `claude agents` session delete getting stuck when a worktree can’t be removed: the message names the cause and next step, and for a git worktree ctrl+x again deletes the directory anyway
- Fixed background agent and workflow rows in the agents panel expanding to many lines when their text contained line breaks
- Fixed Claude in Slack sessions losing their Slack tools when org managed settings set an MCP allowlist
- Fixed Claude in Chrome asking to allow the host “https” when a navigation URL had a scheme but a host that could not be parsed
- Fixed the spinner wrapping onto several lines when the current task’s label is long; the label and the “Next:” task line now stay within one terminal row
- Fixed the `/bug` and `/feedback` description field showing no cursor when the terminal’s native cursor is enabled
- Fixed Remote Control sessions served by `claude remote-control` showing a generated name instead of their session title in `ListAgents`
- Fixed `claude plugin validate` rejecting plugin paths whose directory name begins with two dots, which the plugin loader accepts
- Fixed plugins silently skipping a default monitors file or root SKILL.md that could not be checked
- Fixed WebFetch’s error for localhost and other dotless hostnames to explain why the URL is refused and suggest curl
- Fixed PermissionRequest hooks not firing in `--print` mode
- Fixed policy-helper warnings not printing on headless (`-p`) runs
- Fixed `/resume` listing a `/fork` background session under its parent’s name instead of its own `⑂` fork name
- Fixed `/remote-control` and other claude.ai-gated commands to suggest `/login` when signed out instead of showing a Claude for Enterprise migration message
- Fixed `CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS` not extending SessionEnd hooks that have no per-hook `timeout` (they were still cancelled after 1.5 seconds)
- Fixed `/autofix-pr` and other cloud-session commands saying to retry or install the Claude GitHub App when no GitHub account is connected; they now point to `/web-setup` or the web connect page
- Fixed cloud-session commands such as `/teleport` and `/remote-env` to explain when an organization policy turns them off, instead of answering “Unknown command”
- Fixed Bash sandbox instructions over-stating confinement: no unenforced path lists when filesystem isolation is off, and strict mode no longer claims commands can never run unsandboxed
- \[VSCode\] Fixed the session list, settings toggles, and chat tabs when `CLAUDE_CONFIG_DIR` is set in a settings file or the `environmentVariables` setting
- \[VSCode\] Fixed the model pill, model picker and command menu going blank in open tabs for a few seconds after a login, logout or account switch
- \[VSCode\] Fixed Auto disappearing from the mode picker in new-tab or just-reloaded conversations when a project or local setting overrides the model named in `~/.claude/settings.json`
- \[VSCode\] Fixed session names reverting to the last prompt after a window reload when a SessionStart hook is configured
- \[VSCode\] Fixed the footer’s model pill and Remote Control pill waiting for the new tab’s Claude process to start when another tab in the window is already up
- \[VSCode\] Fixed a second Claude process running through its full startup when a session tab’s launch arrived more than half a second after its config read
- \[VSCode\] Fixed resuming a session from the session list ignoring `claudeCode.preferredLocation: "sidebar"` (it always opened a panel), and programmatic opens resetting that setting to “panel”
- \[VSCode\] Fixed Windows issues: the WSL install prompt no longer appears on machines without WSL installed, and IDE diagnostics are now returned correctly for Windows files when WSL is installed
- \[VSCode\] Fixed the custom style builder saving a User level style in a folder the CLI does not read when `CLAUDE_CONFIG_DIR` is set through settings
- \[Claude Code on the web\] Fixed cloud sessions running longer than about six hours silently losing files saved to persisted session folders; saves now persist for up to a day
- \[Claude Code on the web\] Fixed “Invalid effort level” errors when a routine resumes a session, or a session starts with no set effort, in orgs where an admin caps a model’s effort
- \[Claude Tag\] Fixed the admin settings page hanging on a loading skeleton or going blank after a transient load failure; a section that fails to load now shows a Retry button
- \[Claude Tag\] Fixed a Slack Enterprise Grid channel losing its Claude settings (repository, environment, access) after a Slack admin moved it to another workspace
- \[Claude Tag\] Fixed `@Claude !restart` in a thread with its own session sometimes also posting a contradictory “this thread is handled by the channel session” notice
- \[Claude Tag\] Fixed Markdown links whose URL is wrapped in angle brackets showing as literal bracket text in Slack instead of a clickable link
- \[Claude Tag\] Fixed a workspace guest’s top-level @mention in a channel where guests may use Claude sometimes getting a “your Slack account isn’t connected” reply instead of an answer
- \[Claude Tag\] Fixed a channel’s long-running session being replaced with a fresh one mid-conversation; the scheduled refresh now waits until the channel and its threads are quiet
- \[Claude Tag\] Fixed channel-settings cards clicked more than once telling the proposing session the change was refused after it had already applied; the outcome is now sent once
- \[Code Review\] Fixed reviews sometimes ending as incomplete when one of the agents verifying a finding failed midway; the review now replaces that agent and reaches a verdict
- \[Code Review\] Fixed a push-triggered review that was queued behind a running review still posting after the pull request had been converted to draft
- \[Code Review\] Fixed reviews ignoring a directory’s CLAUDE.md conventions when the PR edited a root file (e.g. README.md) that only shares a name with a file that CLAUDE.md lists

[​](#2-1-267)

2.1.267

September 9, 2026

**Added**

- Added `maxEffortLevel` setting (top-level or per model under `modelSettings`): caps the effort level on every provider, including Bedrock, Vertex and Foundry; users can still pick a lower level
- Added `--system-prompt-snapshot off` to render the system prompt fresh on every request instead of reusing the conversation’s recorded prompt (for iterating on prompt text)
- \[Claude Tag\] Added a “Use a custom connector” link to the preset connection forms in Claude Tag admin settings, so you can switch to a custom connection without starting over

**Changed**

- Self-hosted runner: Changed `--use-anthropic-git-proxy` to be reported to the server at registration and to print a warning for each session that still clones through the legacy git proxy
- Gateway: Changed `forward_user_identity` upstreams to return a 429 as-is to a developer whose email was forwarded, instead of failing over to the next upstream, so the proxy’s per-user limits hold

Show 7 improvements

- Improved the `/diff` panel: it no longer flashes “0 files changed” and a spinner before settling, and its empty state is centered in the panel
- Improved the Bash tool’s description guidance so Claude describes what a command does in plain words instead of echoing the command
- Improved sandbox guidance so Claude suggests `/copy` when clipboard commands such as `pbcopy` fail inside the sandbox
- Improved `--resume` first-render time for sessions with many Bash tool calls
- Improved prompt input responsiveness: keystrokes no longer occasionally wait a frame behind spinner or streaming repaints
- Improved prompt-cache stability: subagents and sessions started with `--system-prompt` or `--append-system-prompt` now record the system prompt and tool definitions once instead of re-rendering them
- Improved Artifact tool publish errors: when a publish is refused, the message now says why and what to do about it

Show 41 bug fixes

- Fixed Cowork scheduled tasks in the cloud failing at startup for organizations whose managed settings require sandboxing
- Fixed `/context` and other local command output rendering blank on mobile clients
- Fixed shift+enter and option+backspace not working after reconnecting to a tmux or ssh session inside an agent view
- Fixed the dim last-prompt header not appearing at the top of the conversation when scrolling up in fullscreen mode
- Fixed Workflow `agent()` calls with large output schemas being refused in auto mode instead of being checked by the safety classifier
- Fixed a case where a marketplace entry path containing a backslash could bypass the containment check for fetched marketplaces on macOS and Linux
- Fixed expired AWS or Google Cloud credentials under a host app such as Claude Desktop retrying ten times with a generic “request failed” before the re-authenticate error appeared
- Fixed resuming a session after `/compact` or another slash command ran via `-p --resume`: a spurious “Continue from where you left off.” turn is no longer inserted
- Fixed resuming a large session (transcript over 5 MB): parallel tool calls and their hook output are no longer dropped from the reloaded conversation
- Fixed managed `allowedHttpHookUrls`, `httpHookAllowedEnvVars` and `allowedChannelPlugins` to admit nothing, not everything, when unreadable
- Fixed `/login` on machines whose managed settings require Claude apps gateway sign-in: Esc now closes the dialog instead of doing nothing
- Fixed artifact publishes cut off by a dropped connection mid-upload: they now retry once when Claude Code can tell the upload never completed, instead of reporting an unknown outcome
- Fixed `effort:` frontmatter on custom commands, skills, and subagents being ignored on models whose default effort is still pinned (Opus 4.7, Opus 4.8, Fable 5)
- Fixed artifact publish failing with an unhelpful error when the page file isn’t valid UTF-8 or contains a replacement character (U+FFFD); the error now names the line and column to fix
- Fixed `claude agents` `@` directory menu not listing repositories created after the session started
- Fixed Remote Control clients that join a Claude Desktop or VS Code session showing a stale permission mode until it was changed again
- Fixed `claude remote-control` exiting and dropping every attached session when its server credential expires (about 30 days after start); the host now re-registers and keeps going
- Fixed the usage-limit warning flickering on and off during a session when requests for different models or modes report different limit windows
- Fixed earlier reasoning being dropped when an MCP server re-sends, or a built-in tool re-renders, a tool the model already loaded
- Fixed a tool that disappears mid-conversation, from a disconnected MCP server or an upgrade, rewriting the tool list and discarding earlier thinking
- Fixed a background worker forked from a conversation adding EnterWorktree to the conversation’s tool block mid-session, which broke prompt-cache reuse
- Fixed mid-session MCP and plugin tools being added to the tool list in sessions without ToolSearch, which broke prompt-cache reuse; supported models now receive them as deferred definitions
- Fixed switching models with /model re-sending every tool definition (a prompt-cache miss); commit and PR attribution text now arrives as a conversation note that updates on model changes
- Fixed resumed sessions rewriting the inline tool set when an MCP connector reconnects at a different moment than before
- Fixed resumed sessions re-rendering tool descriptions instead of replaying the recorded ones when the first turn ran a tool
- Fixed prompt-cache misses and dropped extended thinking when a claude.ai connector’s tools change between a session and its resume
- Fixed resumed sessions rewriting earlier MCP tool announcements (and dropping extended thinking) before their connectors reconnect
- Fixed a prompt-cache break when a print-mode (`-p`) conversation is resumed interactively: the system prompt prefix no longer changes
- \[VSCode\] Fixed the extension host hanging at 100% CPU when forking, editing an earlier message, or rewinding in a conversation whose saved transcript contains a cyclic parent link
- \[VSCode\] Fixed pasting a screenshot on WSL2/WSLg inserting raw image bytes into the chat input; the image is now attached when the clipboard provides it, otherwise the paste is ignored
- \[VSCode\] Fixed chat diff blocks always rendering with a dark editor theme; they now follow the active VS Code color theme, including high contrast
- \[VSCode\] Fixed mixed right-to-left and English text rendering in the wrong order while typing in the message input
- \[VSCode\] Fixed accepting an edit in the diff view on a file with Windows (CRLF) line endings failing with “String not found in file”
- \[VSCode\] Fixed @-mentions dropping files whose paths contain spaces
- \[VSCode\] Fixed the sessions list view failing to load in windows connected over Remote-SSH when the workspace folder exists only on the remote host
- \[VSCode\] Fixed runaway ripgrep processes when viewing files in large or symlink-heavy workspaces
- \[Claude Code on the web\] Fixed GitHub Enterprise Server sessions showing your GitHub account as disconnected once its token expired; PR and issue operations now refresh it automatically
- \[Claude Code on the web\] Fixed `gh` and GitHub API calls failing in organizations without the Claude GitHub App; they now use your connected GitHub account and say so when none is connected
- \[Claude Tag\] Fixed Claude replying “The API rejected the request as invalid” when the organization has run out of usage credits; the reply now says so and explains how to add more
- \[Claude Tag\] Fixed thread requests to edit or delete a message Claude posted at the channel’s top level being answered with a correction instead of reaching the session that posted it
- \[Claude Tag\] Fixed **Connect** on Tool access requests under Admin settings \> Review requests failing with “Authorization failed” or showing the requested access bundle as deleted

[​](#2-1-266)

2.1.266

September 8, 2026

- Fixed a 2.1.265 regression affecting LLM-gateway and proxy setups: the undocumented `CLAUDE_CODE_USE_GATEWAY` environment variable, previously ignored unless `ANTHROPIC_BASE_URL` and `ANTHROPIC_AUTH_TOKEN` were both set, began forcing Cloud-gateway sign-in on its own in 2.1.265, so configurations that set it alongside an API key, `apiKeyHelper`, or custom auth headers failed every request with “Not signed in to the Cloud gateway”. The variable on its own is ignored again; no configuration change is needed

[​](#2-1-265)

2.1.265

September 8, 2026

**Added**

- Added `user.email` and `user.groups` to the telemetry Claude Desktop and Cowork send through a Claude apps gateway, matching terminal sessions
- Added support for pointing `--plugin-dir` at a folder of plugins: each child folder with a manifest loads, and children added or removed while running are picked up
- Added a 1 GB cap on tool results saved to disk; the in-conversation preview says when a saved file was truncated
- \[VSCode\] Added automatic archiving of sessions inactive for a set period (new “Archive inactive sessions” setting, default 14 days)

**Changed**

- Updated the `.claude` folder permission option to say what it actually allows: editing files in the project’s `.claude` folder (or `~/.claude`) for the session
- Changed machines with `forceLoginGatewayUrl` in managed settings to be Claude apps gateway sessions from startup, like `forceLoginMethod: "gateway"`; a leftover claude.ai login or API key is not used
- Changed image processing to use the runtime’s built-in image support; the CLI no longer extracts a native image module to the temp directory
- Changed plugin display metadata to prefer the marketplace entry over `plugin.json` on the Installed tab and `claude plugin details`, filling gaps from `plugin.json`
- Changed Claude apps gateway sessions to export OpenTelemetry directly to a collector the gateway’s managed settings name in `OTEL_EXPORTER_OTLP_ENDPOINT`, instead of through the gateway’s relay; sessions without a named collector still use the relay

Show 7 improvements

- Improved `--worktree` startup on large repositories: the new worktree is now checked out in parallel (git 2.32+)
- Improved `/workflows` agent detail: tool calls are marked running, failed or done, the subagent’s task list is shown when it has one, and Enter unfolds the listed calls with their inputs and results
- Improved slash commands typed mid-prompt: matches now show in a list (Tab opens it outside fullscreen) instead of a single suggestion, and a plugin skill is now found by its bare name
- Improved remote MCP servers that need sign-in: Claude Code no longer registers an OAuth client with them until you actually authenticate
- Improved the time to resume long sessions that read many files
- Improved the error shown when an image over the size limits cannot be decoded: it now names the cause and how to fix it instead of only citing the limit
- Improved the Artifact tool’s read of an artifact someone else wrote: the summary now treats the page as untrusted content and flags embedded instructions rather than relaying them

Show 34 bug fixes

- Fixed resuming a foreground-spawned subagent changing its tool list and system prompt prefix, which broke prompt-cache reuse for that agent
- Fixed agent teammates and resumed subagents moving SubagentStart hook context and preloaded skills out of the prompt prefix on later turns, which broke prompt-cache reuse
- Fixed resume after the previous process died while a tool was running: the last prompt is no longer rewritten, and the interrupted tool call is kept and marked interrupted
- Fixed `/model opusplan[1m]` being rejected with “Model not found”
- Fixed syntax-highlighted code in permission prompts and messages sometimes omitting a character after a Ruby `?`, Erlang `$`, or Perl `$` sigil
- Fixed the fullscreen transcript jumping by one row whenever the slash-command or @-file suggestion list opened or closed
- Fixed a plugin path containing a backslash bypassing the symlink containment check on macOS and Linux
- Fixed plugin directories whose names begin with two dots being wrongly refused as outside the plugin root
- Fixed VS Code and SDK sessions occasionally requiring re-login when a session was closed while refreshing its token
- Fixed Remote Control sessions sending the end-of-turn signal before the reply’s last message, which could show a reply as finished in the Claude app before its last part arrived
- Fixed background (`--bg`) sessions occasionally being retired mid-turn when a message arrived just before the idle timeout
- Fixed Claude Code’s own git status and diff probes running clean filters configured by a nested repository inside the working tree
- Fixed the advisor tool and its instructions being re-decided per request from the request’s model; the decision is now made once and announced in the conversation when it changes
- Fixed artifact publish accepting connector tool names the connector doesn’t expose; the publish is now refused when none of the declared tools exist, and warned when only some don’t
- Fixed `/add-dir <subdirectory>` refusing to load a subdirectory’s agents when managed settings lock only skills to plugins, and promising agents when only agents are locked
- Fixed two-key keyboard shortcuts cancelling silently when the second key arrived more than a second later, as happens inside tmux; they now wait 3 seconds and show a notice when they time out
- Fixed forked skills (`context: fork`) not streaming their kickoff prompt and, with `--forward-subagent-text`, their text turns as progress events in stream-json
- Fixed a plugin’s default component folder that the OS cannot check, such as a symlink loop, being silently skipped; it is now reported in `/plugin` with the error code
- Fixed the Claude apps gateway’s OTLP telemetry relay pausing all forwarding to a collector for 30 seconds after it rejected a few payloads as malformed or too large
- Fixed `/plugin` Discover/Browse and `claude plugin list --json --available` showing no description or display name for marketplace plugins whose metadata lives only in their `plugin.json`
- Fixed `/login` showing “no gateway URL is configured” when re-run in a session that signed in to a Claude apps gateway set by managed settings
- Fixed `/model` claiming a model was “saved as your default” when the settings file couldn’t be written; it now says the save failed and why
- Fixed `/clear` from Remote Control waiting on SessionStart hooks and on open terminal dialogs before completing
- Fixed the `/config` dialog changing height when switching between its tabs
- Fixed resuming a workflow run after its container restarted; a resume whose run journal is missing now fails with a clear error instead of rerunning every agent
- Fixed the `claude-api` skill’s error-code reference: model access failures return 404 and unavailable beta headers return 400, not 403
- Fixed non-interactive sessions (`-p` with stream-json input, Agent SDK, cloud sessions) resetting the shell working directory at each new user message; a `cd` now persists across turns
- Fixed MCP servers configured as `http` that only speak the legacy HTTP+SSE transport never connecting; Claude Code now falls back to SSE as the MCP spec describes
- Fixed some claude.ai connectors in cloud sessions showing as needing authentication even though they are connected in claude.ai (servers that answer an unsupported request with HTTP 401)
- Fixed remote sessions keeping their sandbox container alive while a connector approval or sign-in link waits for you
- Fixed resumed sessions showing long model-facing recovery instructions in “background task didn’t finish” notices instead of a short status line
- Windows: Fixed Read, Write and Edit refusing every file (“symlink resolution changed after permission was checked”) when running inside an AppContainer or restricted-token sandbox
- \[VSCode\] Fixed the sidebar chat coming back blank after Reload Window or a restart when the conversation had been open for more than 10 minutes
- \[VSCode\] Fixed the timeline dot sitting below the text on the “Remote Control is active” message

[​](#2-1-263)

2.1.263

September 6, 2026

- Bug fixes and reliability improvements

[​](#2-1-261)

2.1.261

September 4, 2026

**Added**

- Added an “Organization policy” line to `/status` and `claude doctor` that says why your organization’s policy could not be loaded, such as a proxy not passing the endpoint through
- Added `bashOutputMaxChars` and `taskOutputMaxChars` settings to raise how much command and background-task output Claude receives inline before it is saved to a file, up to 128K characters
- Added `--append-subagent-system-prompt-file` to read the subagent system prompt from a file, for prompts too large to pass on the command line
- Added `/skill-doctor` to show which loaded skills go unused and what they cost in context, so you can prune them
- \[VSCode\] Added a “Build a custom style” walkthrough to the Output styles menu that writes a custom output style file and lists it right away
- \[VSCode\] Added an Add server form and a Remove action to the MCP servers dialog, so MCP servers can be added and removed without leaving the IDE
- \[VSCode\] Added a hollow ring in the session list for sessions open in a terminal, another VS Code window, or Claude Desktop, so they no longer look closed
- \[VSCode\] Added a fold button to permission and question prompts so the conversation behind them can be read without dismissing them; the space beside the prompt now scrolls the conversation
- \[VSCode\] Added “Archive session” to the session list’s right-click menu and gave Unarchive its own icon

**Changed**

- Changed a Claude apps gateway 403 on the managed settings load (at startup or after `/login`) to say Claude Code may not be enabled for the organization, instead of advising a new sign-in
- Changed machines whose managed settings pin `forceLoginMethod: "gateway"` to ignore a leftover API key or claude.ai login and ask for `/login`; Bedrock, Vertex AI, and Foundry sessions are unaffected
- Changed auto mode to treat a link that packs content into a public diagram renderer’s URL as an upload to that site: no longer auto-approved unless you asked for it
- Changed the prompt’s word-editing keys to match Bash: Ctrl+W deletes back to whitespace, Alt+F and Alt+D stop at word end, punctuation separates words; `keybindingFlavor` no longer has any effect
- Changed `/context` token counting to use a local estimate when the token-counting API is unavailable, instead of extra small-model requests
- \[VSCode\] Changed the model picker to one flat list of every model, with rows kept for older model spellings listed last

Show 5 improvements

- Improved the `/model` picker and the VS Code model pill to show a model’s name instead of its raw Bedrock, Vertex AI, or LLM gateway ID when Claude Code recognizes it
- Improved startup on Google Vertex AI when `GOOGLE_APPLICATION_CREDENTIALS` is set: API client creation no longer re-runs Google Cloud project discovery or spawns extra `gcloud` processes
- Improved streaming performance: already-rendered blocks are no longer re-checked by layout on each update
- Improved the dangerous-`rm` safety prompt to also catch `rm -rf` on positional parameters and inside double-quoted `sh -c` scripts
- Improved handling when the API sends no response headers: the retry now waits up to `API_TIMEOUT_MS` (10 minutes by default) instead of another 3 minutes, and the messages say what to change

Show 47 bug fixes

- Fixed typed or pasted characters occasionally landing out of order or being dropped during fast input or key repeat
- Fixed `/add-dir <subdirectory>` printing a false “couldn’t be resolved” error when the working directory is on a `/net` automount
- Fixed the Bedrock setup wizard hanging when AWS or an AWS credential helper never responds (it now times out with a clear error), and its model checks failing behind a TLS-inspecting proxy
- Fixed cloud sessions discarding a plugin synced from claude.ai when managed settings force-enable it in `enabledPlugins`, then falling back to a marketplace clone that could fail
- Fixed being unable to delete the character immediately before an inline `[Image #N]` chip in the prompt input
- Fixed resuming a session losing hook output and other context around parallel tool calls, which changed the resumed request
- Fixed Remote Control showing a stale permission mode when a phone, browser, or claude.ai app attaches to a terminal session or after the mode changes in the terminal
- Fixed Remote Control sessions showing as still working (stuck spinner and Stop button) after stopping a turn from a connected phone or browser, or after a local slash command like `/clear`
- Fixed SDK and cloud sessions ignoring a Stop or interrupt sent just after the first prompt, before the turn had started; the turn now stops instead of running to completion
- Fixed Remote Control uploading a session pulled with `/teleport` into the connected session, which appeared appended to the original on phone and web
- Fixed Remote Control’s inbound event stream failing behind TLS-inspecting corporate proxies on native Windows
- Fixed Remote Control sessions showing the default effort level on claude.ai when the effort comes from settings
- Fixed `gcpAuthRefresh` opening a browser at startup when the Google credential check was slow, even though the credential was still valid
- Fixed claude.ai connectors staying absent for the whole session when the startup connector fetch timed out — the CLI now retries in the background
- Fixed sustained high CPU usage when a background agent could not be resumed and its wake-up was retried in a tight loop
- Fixed feature flags gated to a newer version occasionally applying to an older Claude Code version running on the same machine
- Fixed `/usage` and the VS Code usage panel dropping a model-specific weekly limit row when the usage endpoint is rate limited or when opened right after startup
- Fixed `claude -p --resume <file>` adopting a malformed session ID recorded in the transcript; it now resumes under a fresh session ID instead
- Fixed the terminal progress indicator (iTerm2, Ghostty, ConEmu) showing the session as finished while a background workflow or agent was still running
- Fixed a rare layout glitch where a box could render with the wrong height after its container switched between row and column direction
- Fixed Claude apps gateway client IP when a trusted proxy appends a port to `X-Forwarded-For`; with an access list set, an unreadable entry now gets 403
- Fixed Claude apps gateway telling Claude Desktop to export OpenTelemetry as JSON even when the terminal CLI uses protobuf, so protobuf-only collectors rejected Desktop’s data
- Fixed Desktop and web showing a session as busy while it only watches an artifact for updates
- Fixed Claude in Chrome `file_upload` failing with “paths: expected array, received undefined” in local Cowork sessions run from the Claude Desktop app
- Fixed `SendMessage` to an offline Remote Control session on another machine reading as delivered; the result now says delivery is queued until that machine reconnects
- Fixed plugin install hints from CLIs run in background Bash commands: they are now detected, and the raw `<claude-code-hint>` tag no longer leaks into the conversation
- Fixed in-process agent-team teammates re-sending their first-turn tool and skill announcements on the second turn, which changed the request prefix and missed the prompt cache
- \[VSCode\] Fixed a session teleported from Claude Code on the web treating a question that was cut off when the cloud session shut down as declined
- \[VSCode\] Fixed the session tab’s Rename box opening empty for a tab restored with the window; it now starts with the current name
- \[VSCode\] Fixed collapsed sections in the session list panel briefly showing expanded each time the panel loaded
- \[VSCode\] Fixed Focus view showing a tool call as still running after Claude had moved on, such as while a question waited for your answer
- \[VSCode\] Fixed the session list’s active-row highlight going stale when an unfocused Claude tab’s session ID is corrected
- \[VSCode\] Fixed Cmd/Ctrl+Shift+T reopen and deep-link opens placing the Claude tab outside the Claude editor group when a Claude tab has focus
- \[VSCode\] Fixed the session tab’s “Add to group” putting a session opened from Claude Code on the Web in two groups; it now moves the entry the session list shows
- \[VSCode\] Fixed the model picker showing models an organization has since disabled until the window was reloaded twice
- \[VSCode\] Fixed a tab opened from the session list jumping back to that session, and a tab opened from a Web session restarting its teleport or staying empty, after VS Code reloads the tab’s view
- \[VSCode\] Fixed `/btw` side-question history from earlier sessions being overwritten when a question is asked right after a window reload or while a settings file has errors
- \[VSCode\] Fixed the pending question card not reappearing after the Claude panel reloads when signed in with a Claude.ai or Console account
- \[VSCode\] Fixed claude.ai-only features staying visible in a window’s other Claude panels after one panel picked up a third-party provider from a settings file
- \[VSCode\] Fixed the sign-in screen appearing despite the Disable Login Prompt setting when Claude Code reports no login or a request fails for lack of one
- \[VSCode\] Fixed the next queued permission prompt keeping text typed on the previous prompt and accepting an immediate second click
- \[VSCode\] Fixed install-plugin links opening the Claude sidebar without the install dialog in a window where only the session list had been shown
- \[VSCode\] Fixed the sidebar usage meter staying empty on a new window until the Account & usage dialog was opened, and a 0% usage limit being left out of the meter
- \[VSCode\] Fixed “Start new session in this group” losing the group after New conversation, and a missing unread dot for a session that finished before the sidebar’s unread list loaded
- \[VSCode\] Fixed the editor tab badge showing unread during a running turn or missing on a tab opened from the session list, and “Add Session Tab to Group” doing nothing for an archived session
- \[VSCode\] Fixed “Enable Remote Control for all sessions” so flipping it also applies right away to sessions open in other VS Code windows
- \[VSCode\] Fixed the session list’s Open filter for sessions continued from claude.ai whose tab was still recorded under the web session, and labeled the filter menu’s sections for screen readers

[​](#2-1-260)

2.1.260

September 3, 2026

**Added**

- Added a diff panel that opens beside the conversation in fullscreen mode and shows your uncommitted changes as Claude edits; toggle it with `/diff`
- Added a likely cause for prompt-cache misses (e.g. tool definitions or system prompt changed, idle past the TTL) to `/cost` and the status line’s `prompt_cache` field
- Added `/reload-plugins` to headless sessions, so it appears in the Claude Code Desktop and SDK command lists
- Added a text form of `/advisor` (`/advisor`, `/advisor <model>`, `/advisor off`) for the desktop app, Remote Control, and other headless (`-p`/Agent SDK) sessions
- Added `oidc.scope_on_refresh` to the Claude apps gateway for IdPs that return an id_token on refresh only when asked for `openid` again
- Added Claude apps gateway support for newer Claude Desktop keys in `desktop` policy blocks, including `userPluginMarketplacesEnabled` and `userPluginUploadsEnabled`
- \[VSCode\] Added the selected effort level to the footer model pill, fixed a stale effort level after switching models, and returned the footer pills to their earlier compact size
- \[VSCode\] Added Open and Closed to the session list’s status filter menu

**Changed**

- Reverted the 2.1.259 change applying `Read()` deny rules to Bash arguments; it denied `npm run build` under a `Read(./**/build/**)` rule in every mode and made `cd … && grep` prompt even in auto mode
- Updated the bundled `claude-api` skill so its Go, Java, and C# samples use current-generation model IDs, and clarified that cheaper worker or sub-agent models should be current-generation too
- Changed `ctrl+l` / `cmd+k` in fullscreen mode to clear the transcript view like a terminal `clear`; scroll up to see earlier messages
- Changed permission rules with text after the closing parenthesis (e.g. `Bash(ls) x`), which never matched anything, to be reported as invalid settings instead of being silently ignored
- Changed server-managed settings so a managed CLAUDE.md (`claudeMd`) no longer triggers the security approval dialog; hooks, shell-command, sandbox, and unsafe `env` settings still require approval
- Changed Claude in Chrome to follow your organization’s Claude in Chrome admin setting; when an admin turns it off, `--chrome`, `/chrome` and the browser tools are unavailable
- Changed Claude apps gateway to send `orgPluginSettings` in the list form read by Claude Desktop 1.15200.0 and later; older desktops ignore it
- Changed Claude apps gateway to also refuse to start, naming the field, when a `desktop` policy misspells a field in a nested object of a `managedMcpServers` or `orgPluginSettings` entry
- Changed commands typed at the `!` bash-mode prompt to run outside the sandbox even when strict sandbox mode (`sandbox.allowUnsandboxedCommands: false`) is on, like typing into your own terminal
- Changed self-hosted runner `--kill-session-after-min` to release a session that is only waiting on its user (paused, resumable on the next message) instead of killing it and reporting a failure
- Removed the one-hour time limit on background commands started by subagents; they now run until they exit or are stopped, matching the main session

Show 9 improvements

- Improved structured output: Workflow `agent({schema})` rejects a JSON Schema that can never be satisfied up front, and retry-cap errors now include the last validation failure
- Improved deleting a background session whose worktree has unpushed commits: the message now names the branch and commit count, and deleting again discards the worktree
- Improved the Claude apps gateway’s refresh-failure log to name the step that failed
- Improved idle CPU usage of non-interactive (`-p` / SDK) sessions
- Improved the Claude apps gateway on Amazon Bedrock: input tokens for an aborted request are now counted with AWS’s free CountTokens API (grant `bedrock:CountTokens`) instead of a one-token request
- Improved the settings error for rules such as `Edit(C:\dir\(name)\**)`, where `\(` is read as an escaped parenthesis rather than a path separator, to suggest an unambiguous spelling
- Improved auto-compact for 1M-context models: Opus and Fable sessions now compact shortly before the 1M-token limit, and recovery compaction on very large contexts no longer times out at 10 minutes
- Improved `/ultrareview` and `claude ultrareview` to wait up to 45 minutes (previously 30) for long-running cloud reviews
- Improved `/effort` on Claude Fable 5.1 so changing effort mid-session no longer invalidates the prompt cache

Show 38 bug fixes

- Fixed `Edit`/`Write`/`Read` permission rules whose path contains parentheses being dropped as invalid or ignored by the Bash sandbox, which left “read-only” folders writable
- Fixed one file permission rule with an uncompilable pattern (e.g. an unclosed `[`) making every file edit fail with `Invalid regular expression`; such a deny rule now guards the literal path it spells
- Fixed Bash permission checks auto-approving zsh commands that hide a command substitution in a REPORTTIME, REPORTMEMORY or DIRSTACKSIZE assignment; these now prompt for approval
- Fixed Bedrock model discovery, token counting and AWS SSO/STS credential calls failing with “unable to get local issuer certificate” when the corporate root CA is only in the OS certificate store
- Fixed `permissions.blockReadsOutsideWorkingDirectories` on macOS hiding the user’s git config from sandboxed git and hiding a worktree-isolated sub-agent’s own checkout
- Fixed managed settings not loading for claude.ai Enterprise/Team users who also had a leftover API key from an earlier `/login`
- Fixed `/status` listing a signed-in claude.ai account and a configured API key as if both were in effect; the credential not in use is now marked
- Fixed managed `skillOverrides` entries keyed on a bundled skill’s alias (e.g. `checkup` for `/doctor`) not applying, and `Skill(name)` deny rules not covering a nested skill listed as `<dir>:name`
- Fixed `model: fable` agents ignoring the `[1m]` tag on an `ANTHROPIC_DEFAULT_FABLE_MODEL` pin and silently running with a 200K context window
- Fixed the `/model` picker not showing Fable 5.1 for organizations that can use it, which was only accepted when typed as `/model claude-fable-5-1`
- Fixed prompt caching on Claude Fable 5.1 not covering the context attached after tool results, so it was re-sent as uncached input on every tool-call turn
- Fixed model switching staying blocked for the rest of the session after a plugin hook load failure; each switch now re-checks and the refusal names the cause
- Fixed model switching being blocked for the session when an organization-managed plugin’s marketplace could not be loaded
- Fixed SDK-provided MCP servers (e.g. Desktop connectors) sometimes missing from the first turn and only appearing on the next one
- Fixed Claude in Chrome tools failing with “Not connected” mid-task in cloud-hosted claude.ai sessions when a connector was added or removed
- Fixed flags, joined emoji and accented letters splitting across wrapped lines, and stale text staying on screen when a flag or joined emoji falls in the terminal’s last two columns (now shown as `…`)
- Fixed Remote Control accepting a model pick that is not a valid model name; it is now refused with an error instead of failing on the next message
- Fixed `/rewind` and `--rewind-files` reporting success when checkpoint backup files were missing and nothing was actually restored
- Fixed `/rewind` leaving stale file-read tracking from the rewound-away turns, which caused “File unchanged since last read” stubs and full-file re-injection after external edits
- Fixed `-p --resume`/`--continue` (as used by the desktop app) failing on every retry once a session’s worktree directory lost its git metadata; it now fails once, then resumes without the worktree
- Fixed a subagent that resumed another agent via SendMessage never being woken by that agent’s completion (the notification went to the main conversation instead)
- Fixed agent teams: an in-process teammate’s transcript losing messages, or going blank, during long API retry waits (e.g. under `CLAUDE_CODE_RETRY_WATCHDOG`) as retry notices evicted real messages
- Fixed a session that moved to the background appearing twice in ListAgents (once as a phantom “interactive” twin with the same name) and receiving SendMessage deliveries in the viewer
- Fixed intermittent “task output swap refused” errors when many sessions share a project directory
- Fixed Ctrl+Z in fullscreen leaving the shell on the alternate screen, drawn over the paused interface
- Fixed Workflow tool subagents being restarted as stalled while a long context compaction was still in progress
- Fixed plugins from a URL marketplace failing to install with “marketplace entry path does not stay inside the marketplace directory” when a host app (e.g. Claude Desktop) stores it as a directory
- Fixed an extra browser tab opening when an artifact is published in a session you’re driving from claude.ai, the desktop app, or mobile (Remote Control)
- Fixed the Artifact tool’s first call failing with an “Invalid tool parameters” validation error in some Cowork sessions
- Fixed IDE line selections being dropped when running a skill or slash command (the “N lines selected” context now reaches Claude)
- Fixed repository detection for GitLab projects in nested subgroups (e.g. `gitlab.com/group/subgroup/project`)
- Fixed `owner/repo#123` issue references in rendered output linking to github.com when working in a GitLab repository; they now link to the gitlab.com issue
- Glob/Grep: Fixed the search path being probed on disk before the permission check; a missing path is now reported after permission is decided, as Read does
- \[VSCode\] Fixed the welcome screen disappearing in a new session when Remote Control turns on automatically
- \[VSCode\] Fixed the session history picker loading a session a second time when it is already open in another tab; it now switches to that tab
- \[VSCode\] Fixed the session tab’s Rename command silently doing nothing while the tab’s view was reloading; it now always applies
- \[VSCode\] Fixed a half-finished message, an empty tool card or an extra “Thought for” line staying on screen after Claude Code retried a dropped response
- \[VSCode\] Fixed “Enable Remote Control for all sessions” not applying to a session tab that was still starting when the toggle was flipped

[​](#2-1-259)

2.1.259

September 2, 2026

**Added**

- Added `managedMcpServers` managed setting: organizations can provide HTTP/SSE MCP servers to every user (same entry shape as `.mcp.json`); entries that name a command to run are skipped
- Added `--permission-prompts none` for unattended headless hosts: anything that would prompt is denied automatically while the active permission mode (including auto mode) keeps deciding
- Added recognition of `glab mr create/merge/close/reopen/note/update` so GitLab merge requests show as `MR !N` in the collapsed tool summary and refresh the footer MR badge
- Added `--json` to `claude plugin validate` for a machine-readable validation report
- \[VSCode\] Added an Active quick filter and a status filter menu (Needs input, Working, Completed) to the session list sidebar

**Changed**

- Changed `allowedMcpServers` to govern only servers users add: a literal `managed-mcp.json` server your allowlist used to filter out now loads on upgrade; use `deniedMcpServers` to keep it off

Show 5 improvements

- Improved terminal resize and first-render performance for long responses by reusing text measurements
- Improved `/workflows` agent detail: JSON outcomes are pretty-printed with syntax colors and real line breaks, and long outcomes fold behind an expand toggle
- Improved headless/SDK session start: the first turn begins up to 50 ms sooner when MCP servers finish connecting
- Improved `/install-github-app` to explain it is GitHub-only and point to the GitLab CI/CD docs when run inside a GitLab repository
- Improved nested background subagent results to be saved in the parent subagent’s transcript, so resumed subagents keep them and shared transcripts show the delivery

Show 26 bug fixes

- Fixed concurrent sessions silently reverting each other’s `~/.claude.json` changes — workspace trust no longer resets and MCP/project state is no longer lost when running many sessions at once
- Fixed a conversation whose thinking was rejected once being rejected again on every later turn
- Fixed Bash `Read()` deny rules not covering files given as option values (`--ignore-revs-file=.env`, `-f.env`, `@file`), `git diff`/`git grep` file operands, or `cd DIR && cat FILE` compounds; `grep -r`/`cp -r` over a directory holding a denied file now asks
- Fixed the prompt cache being invalidated when the OAuth token refreshed in sessions with telemetry disabled
- Fixed fullscreen mode showing a blank conversation after a long turn with hundreds of tool calls
- Fixed auto mode running a turn on a model it doesn’t support when a command or skill’s frontmatter `model:` named one; the turn now keeps the session model
- Fixed `CLAUDE_CODE_MAX_CONTEXT_TOKENS` being ignored for Vertex-style model IDs (`@YYYYMMDD` suffix) of model versions Claude Code doesn’t recognize
- Fixed the live output preview of a running shell command hiding its newest lines when an earlier line wrapped
- Fixed a background GitHub connection check that ran on every launch for claude.ai users; the result is now remembered across launches
- Fixed `--resume` failing (and `--continue` opening an empty conversation) when a saved session contains an attachment entry with no payload
- Fixed frontmatter `model:` on custom commands and skills being ignored in interactive sessions
- Fixed Artifact publishing failing once with an “unexpected parameter `note`” error in conversations continued from an older version
- Fixed managed `forceRemoteSettingsRefresh` being ignored at startup when a policy helper configured by MDM or the managed settings file had already run
- Fixed worktree isolation refusing hook-created worktrees on machines where `git rev-parse` fails with a message other than “not a git repository”
- Fixed OpenTelemetry metrics and events from cloud sessions missing the `user.email`, `organization.id`, and `user.account_uuid` attributes
- Fixed MCP servers that disconnect while their tools are being listed at startup showing as connected with no tools instead of reporting the error
- Fixed the file edit permission dialog sometimes showing a changed line cut short with no indication
- Fixed repository detection dropping a known repo identity after a transient git probe failure
- Fixed managed settings silently going unenforced when the managed-settings file, a drop-in, the MDM plist, or the HKLM value cannot be parsed: Claude Code now refuses to start and names the source
- Fixed Stop not actually stopping background agents and workflows in remote-control sessions: killed tasks now stay visible and re-stoppable until their processes exit
- Fixed resuming a workflow run while its previous stopped run was still exiting, which could run duplicate copies of its agents
- Fixed marketplace repo URLs on github.com with a trailing slash or dangling `?`/`#` producing an unusable `.git` clone URL
- Fixed blocking Stop hooks causing the turn after a block to lose the model’s reasoning from that turn and, on some models, miss the prompt cache
- Fixed remote (claude.ai) sessions taking 60 seconds to start a turn after a browser-hosted MCP server’s page had gone away
- Fixed worktree-isolated sessions refusing common Bash loops, xargs pipelines and launcher-wrapped commands that cannot reach the main checkout
- Fixed remote and scheduled sessions doing nothing after a connector-tool permission prompt was approved while the session was paused

[​](#2-1-258)

2.1.258

September 1, 2026

- Fixed Claude Code failing to launch on macOS 12 (Monterey), a regression introduced in 2.1.255
- Fixed remote and scheduled sessions failing with “user messages must have non-empty content” after a re-sent permission approval could not be applied

[​](#2-1-257)

2.1.257

September 1, 2026

**Added**

- Added Claude Fable 5.1 (`claude-fable-5-1`), now the default Fable model — 1M context, \$10/\$50 per Mtok with \$0.25/Mtok cache reads
- Added “Time format” (`timeFormat`) and `timeZone` settings: 12-hour, 24-hour, 24-hour UTC, or a strftime pattern for the turn-end clock and transcript-view timestamps
- Added a Containment Escape rule to auto mode so cloud metadata-credential fetches, egress evasion, and cross-tenant reach are no longer auto-approved unless your environment marks them expected
- Added `CLAUDE_CODE_SUBAGENT_MODEL_FORCE` to apply `CLAUDE_CODE_SUBAGENT_MODEL` (or the main model) to every subagent, ignoring per-spawn and agent-definition model overrides
- Added `s` in `/effort` to change effort for the current session only, matching `/model`
- Added a `/doctor` warning for stale sandbox mask files left by a killed session
- Added a one-time prompt in auto mode before the first file read outside the working directories, with the option to block such reads (`permissions.blockReadsOutsideWorkingDirectories`)
- Added support for a gateway-supplied `description` on discovered `/model` picker entries (`CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY`); entries without one still read “From gateway”
- \[VSCode\] Added collapsible ACCOUNT & USAGE and SESSION MANAGER section headers to the session list panel, with the account email, the usage meter, and a View details link opening the usage dialog
- \[VSCode\] Added a model pill to the input footer that shows the current model and opens the model picker, with an Effort row and a “More models” page
- \[VSCode\] Added a collapse toggle to the Ungrouped section of the session list
- \[VSCode\] Added output style selection to the command menu, including custom styles

**Changed**

- Changed `--effort` to lift a new model’s default-effort hold for that session only rather than permanently; an effort picked on claude.ai for a Remote Control session now applies during the hold
- Changed a `policyHelper` in MDM or `managed-settings.json` shadowed at launch by cached server-managed settings to run (or exit) as soon as the fetch reports them removed, not at the next launch
- Changed `managedSourcesBehavior: "merge"` to take `sandbox.credentials.awsPairs` and `sandbox.ripgrep` whole from the highest managed source that sets them instead of combining the sources’ values
- Changed gateway model discovery (`CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`) to run even when `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` is set, since it only queries your gateway
- Changed `claude --resume <session-id> --bg` to continue that session under its own ID when nothing is running it, instead of silently starting a copy; a copy is now announced
- Changed `/btw` history browsing from `←`/`→` to `Shift+←`/`Shift+→` (or `[`/`]`), stepping through your recent side questions and back to the live answer
- Changed `defaultMode: "bypassPermissions"` in `.claude/settings.json` or `.claude/settings.local.json` to be ignored, like `"auto"`; set it in user or managed settings, or pass `--permission-mode`
- Changed `fable` and `best` in Claude apps gateway sessions to keep resolving to Fable 5 for now, since gateways not yet configured for Fable 5.1 reject it; pick Fable 5.1 in `/model` to use it
- Changed `--add-dir`, `/add-dir`, and `additionalDirectories` to refuse network paths (UNC shares, `/net/<host>` automounts) with a message before touching them; on Windows use a mapped drive letter
- Changed Claude apps gateway sign-in and token refresh requests to verify the gateway’s pinned TLS certificate, as the managed settings fetch already does
- Changed Cowork and claude.ai cloud sessions: reading an artifact that isn’t yours now always asks you first, even in auto mode
- Removed the Ctrl+E command explanation on Bash and PowerShell permission prompts
- \[VSCode\] Changed the action menu to list slash commands in a filterable “Slash commands” dialog instead of inline; picking one runs it; the MCP servers dialog gained the same filter box
- \[VSCode\] Changed “Delete session” to “Archive session”: archived sessions move to a collapsible “Archived sessions” group at the bottom of the list with an Unarchive action

Show 11 improvements

- Improved rendering performance: less re-render work per turn in long conversations, streaming no longer slows down as the reply grows, and background-agent updates no longer re-render the whole screen
- Improved prompt input responsiveness by reducing per-keystroke rendering work
- Improved policy helper diagnostics — refresh failures now show in `/status`, declining the managed-settings dialog prints why Claude Code exited, and helper timeouts are reported as timeouts
- Improved `/code-review --comment` to post findings on GitLab merge requests via `glab mr note` instead of reporting the target as unsupported
- Improved notifications: an MCP elicitation or permission ask queued under another dialog now sends its idle desktop notification at the same delay as a visible ask
- Improved verbose/transcript output: async hook completion notices that arrive together now appear on one line instead of one line per hook
- Improved `claude self-hosted-runner --configure-git` to also enable git push negotiation, so the first push of a new branch from a stale clone uploads only the new commits instead of the whole tree
- Improved liveness reporting to SDK hosts while a response is held open by gateway keep-alives, so long waits under a raised `CLAUDE_STREAM_IDLE_TIMEOUT_MS` are not mistaken for a hung session
- Improved MCP connection and OAuth debug/error logs so credentials carried in a server’s URL or request headers are redacted
- Improved `/fork` to keep the original conversation’s prompt cache in the new background session: its worktree briefing now arrives as a message instead of a system-prompt change
- Improved emoji autocomplete to accept the remaining GitHub/Slack shortcode aliases (`:satisfied:`, `:telephone:`, `:collision:`, …)

Show 67 bug fixes

- Fixed settings in a `.claude/` folder created after startup not being picked up until restart
- Fixed sessions dispatched from an agent view opened with `←` always starting in the original session’s permission mode, overriding the target directory’s `defaultMode` and the agent’s `permissionMode`
- Fixed `keybindings.json` rebinds of Ctrl+G being ignored in `claude agents`; its Ctrl+S / Ctrl+T are now rebindable via the new `Agents` context
- Fixed background sessions failing to start on macOS npm installs during a self-update, and on Windows when a stale daemon lock file pointed at a reused process id
- Fixed the working spinner stopping while a response streams behind a slash-command panel
- Fixed a background session’s `state.json` `detail` repeating its own dispatch prompt after a scheduled wake-up
- Fixed `claude agents` keeping a background session you re-prompted buried in Completed after it finished again; Completed now orders by the latest finish
- Fixed `claude --bg` from a directory that was just deleted reporting “backgrounded” and leaving a crashed session row; it now prints the reason and exits 1
- Fixed Remote Control connecting mid-session re-sending the Bash tool definition, causing a prompt-cache miss
- Fixed a doubly-listed custom `Authorization` header overriding the configured credential on Bedrock, Mantle, Vertex, and WIF, and the Vertex setup wizard picking up a leftover Anthropic profile from `~/.config/anthropic`
- Fixed Claude apps gateway sending stray host `Authorization` or profile headers to Foundry, Vertex, and Bedrock, and Foundry Entra ID upstreams not starting when `ANTHROPIC_FOUNDRY_API_KEY` is set
- Fixed a leftover Anthropic API key or auth token being sent alongside your Foundry subscription key in API-key mode
- Fixed `/schedule` routines whose prompt was saved without a message role and then ran with nothing to do
- Fixed `claude agents` not saying that a background session is waiting for you to approve a message from another session, or who sent it
- Fixed a prompt stashed with Ctrl+S inside an opened background session being lost when the session went idle or was stopped and then reopened
- Fixed telemetry (OTEL) settings pushed through server-managed settings being ignored on warm starts, including desktop-app Code sessions
- Fixed a teammate permission request being answered twice when the leader’s mailbox write was briefly locked
- Fixed a phantom duplicate slash-command row rendering below the in-flight turn while a command’s auto-continued response streamed
- Fixed `policyHelper` `timeoutMs` and `refreshIntervalMs` values above the timer maximum (2147483647) causing failures or re-runs every millisecond; they are now clamped
- Fixed the token counter freezing or crawling after switching to another subagent’s transcript, and made background subagents’ and teammates’ counters update live while a response streams
- Fixed sandbox network hosts written with a trailing dot (`example.com.`): a `deniedDomains` entry didn’t block the host inside the sandbox, and “don’t ask again” for such a host kept prompting
- Fixed dismissing the Remote Control consent prompt (Esc, or `n` at `claude remote-control`) counting as consent, so the next request connected without asking
- Fixed `/mcp` reconnect and enable still connecting a settings-file MCP server that a managed MCP allow/deny list or `strictPluginOnlyCustomization` loaded after startup should block
- Fixed `claude mcp remove` leaving a remote server’s stored OAuth credentials behind when `strictPluginOnlyCustomization` locks MCP to plugin-only servers
- Fixed Remote Control (`claude remote-control`) sessions started from the Claude app ignoring the selected model and running on the machine’s default instead
- Fixed `--disallowedTools` and session deny rules being dropped after the first settings reload when `allowManagedPermissionRulesOnly` is enabled
- Fixed `--resume` listing a backgrounded conversation twice and `--continue` reopening its stalled pre-background copy; `--continue` now also opens finished background sessions
- Fixed fullscreen mode not letting you click `!` shell command output to expand it
- Fixed background sessions left running an older Claude Code binary piling up across auto-updates instead of being retired
- Fixed `claude agents --json` briefly switching the terminal to raw mode and undoing another program’s terminal settings on exit
- Fixed Proactive output style sessions busy-looping with filler messages and repeated log reads instead of idling while a background command or Monitor they started is still running
- Fixed subagents stopping when a response was cut off mid-stream by a computer sleep, dropped connection, or server error; they now automatically continue instead of ending with an incomplete response
- Fixed `←` doing nothing in the `/btw` panel inside a `claude agents` session: it now returns to the agents list (even mid-answer), and the panel comes back when you reopen the session
- Fixed sessions with an advisor model set missing the prompt cache on background requests (compaction, `/recap`, prompt suggestions) and re-sending the full conversation uncached each time
- Fixed `claude -p` exiting about 5 seconds after its final result while a Monitor the model armed was still running; it now waits for the watch to fire or time out
- Fixed a `permissions.ask` rule being skipped in auto mode when the matching command ran inside a compound command or subshell, letting it run without the confirmation prompt
- Fixed plugins being able to read files outside their own directory through a declared command, agent, skill, hooks or other component path that is a symlink; such paths are now refused with an error
- Fixed `/add-dir` rejecting a directory inside the current working directory; it now loads that directory’s skills, commands, and agents like `--add-dir` does at startup
- Fixed the main agent not being told when you resume a subagent you had stopped from its transcript view
- Fixed a crash when pasting ANSI-colored text (e.g. a CI log) into dialogs like `/feedback`
- Fixed `claude mcp add/remove` hanging or exhausting memory when the project’s `.mcp.json` is a FIFO or a device-file symlink; it now fails fast with an actionable message
- Fixed unbounded memory growth when non-JSONL data is piped into `claude -p --input-format stream-json`; it now fails fast with a clear error
- Fixed backgrounding a turn (`←` or Ctrl+B) while a subagent or other tool was running occasionally making the background session treat that tool as rejected instead of re-running it
- Fixed Bash `Read()`/`Edit()` deny rules not applying to `< file` redirects and reader commands like `tac` and `egrep`; a deny rule on any argument or redirect target now refuses the command
- Fixed resuming or messaging a subagent whose transcript had grown past 5 MB (for example after reading many images) failing with “No transcript found”
- Fixed worktree-isolated sessions refusing Bash loops, `$VAR` reads, `"$(…)"` and heredocs that never touch git as “too complex to verify that it stays inside the worktree”
- Fixed `/model` and `/effort` showing a prompt-cache warning after rewinding a conversation back to empty
- Fixed prompt-cache misses on every turn in long screenshot-heavy sessions once images exceeded the per-request size cap
- Fixed the Edit permission prompt’s diff view rendering emoji and multi-code-point characters with incorrect widths
- Fixed WebSocket MCP server connection failures being logged as “\[object ErrorEvent\]” instead of the underlying error
- Fixed background sessions failing to open with “Couldn’t start the background service” while another Claude Code process was downloading an npm update; the start now waits for it
- Fixed background commands that detach from their shell (for example under `timeout` or `setsid`) surviving a task stop or Claude Code exit
- Fixed Claude not being told when you stop a background command from the tasks panel or a connected client
- Fixed stopping a background subagent leaving its monitors running
- Fixed sandboxed git commands in a linked worktree losing write access to the repository’s common `.git` directory after `cd` into a subdirectory
- Fixed Bedrock and Bedrock Mantle requests going silent during long hidden-thinking phases on Opus 4.7 and later, which let idle timeouts cut the connection; the stream now carries progress events
- Fixed launching Claude Code after a Claude apps gateway expired or revoked your session: it now says the session ended and offers `/login` instead of reporting a network error
- Fixed cloud sessions losing git/GitHub credentials for the rest of the session when the session’s network proxy failed to start at launch; it now retries in the background and recovers
- Fixed leftover `cc-daemon-*` folders in the system temp directory after an interrupted background daemon start; the `cleanupPeriodDays` retention sweep now removes them
- Fixed Bash permission checks auto-approving certain `[[ ]]` conditionals that zsh parses differently from bash; these commands now prompt for approval
- Fixed the managed-settings approval prompt showing the generic warning instead of its telemetry wording when the settings also turn detailed tracing or raw API body logging off, or trace export on
- Fixed agent-team teammates in tmux/iTerm2 panes sometimes staying open after acknowledging a shutdown request
- Fixed the keyless Console sign-in (“Sign in with your Console account”) not applying your organization’s server-managed settings, and `/status` not showing the Organization for that sign-in
- \[VSCode\] Fixed third-party provider deployments (Bedrock, Vertex, and others) still showing claude.ai-only features (remote sessions, dictation, usage) and calling claude.ai with a leftover login
- \[VSCode\] Fixed the session list panel’s usage meter staying blank after the panel loads; it now shows the last known usage immediately
- \[VSCode\] Fixed the “Enable Remote Control for all sessions” toggle so turning it on or off applies to sessions that are already open, not only to new ones
- \[VSCode\] Fixed screen reader announcements: a control character before a fence or heading no longer drops visible lines from speech, and bold markers spanning a heading are no longer mis-paired

[​](#2-1-252)

2.1.252

August 31, 2026

- Fixed Bash commands failing with “task output swap refused (tasks dir moved or linked)” on some Macs
- Fixed “always allow” not saving in a project that has no .claude/settings.local.json yet
- Fixed Remote Control sessions hosted by Claude Desktop or VS Code stalling for minutes after a tool finished when the connection to claude.ai was degraded
- Fixed background task notifications with very large failure output (for example git errors on a full disk) making the conversation exceed the API request size limit

[​](#2-1-251)

2.1.251

August 28, 2026

**Added**

- Added `PreModelSwitch` and `PostModelSwitch` hook events (block, confirm, or annotate a model switch); `SessionStart` resume hooks now receive session staleness and the estimated re-cache cost
- Added live streaming of a foreground subagent’s tool calls and results to Remote Control clients (background subagents, the default, still show status only)
- Added a Spend limit bar to `/usage` and a `rate_limits.spend_limit` status line field for developers behind a Claude apps gateway with spend limits
- Added a per-session prompt-cache line to `/cost` (hit ratio, misses, tokens re-cached, warm/cold) and a matching `prompt_cache` object for status line scripts
- Added `attach`, `logs`, `stop`, `respawn`, and `rm` to `claude --help`; the `--resume` message for a running background session now names the exact `claude attach <id>` command

**Changed**

- Changed `/radio` to be available on Bedrock, Vertex AI, Foundry, and Claude Platform on AWS, and when telemetry is disabled
- Changed Claude in Chrome so browser actions always go through Claude Code’s permission checks, including in sessions with telemetry disabled, which previously used the Chrome extension’s own prompts
- Changed `CLAUDE_CODE_SUBAGENT_MODEL` to set the default subagent model rather than override everything: an agent definition’s `model:` and an explicit per-spawn model now take precedence over it
- Changed the default commit trailer to `Co-Authored-By: Claude Code` when the active model isn’t a recognized Claude model (e.g. third-party models behind a custom `ANTHROPIC_BASE_URL`)
- Changed the default model for seat-based Enterprise subscriptions to Opus 5, matching other premium plans
- Changed `/effort` to save your default effort level per model, so each model keeps its own setting when you switch
- Changed analytics to no longer turn off before sign-in solely because managed settings force gateway login (or cannot be read); they stay off once signed in to the gateway or via `DISABLE_TELEMETRY`
- Changed the footer PR badge on Bedrock, Vertex, and Foundry, and when telemetry is off, to call the GitHub API directly (via `gh auth token`, `GH_TOKEN`, or `GITHUB_TOKEN`) instead of `gh pr view`
- Changed how Bash command output files are created and read back when commands run in the sandbox, so a sandboxed command cannot redirect or replace them
- Changed plugin/LSP install suggestions and the auto-mode default offer to wait until you’ve sent or cleared what you’re typing, so the Enter that sends your prompt can’t answer them
- Changed server-managed settings that terminate sandbox TLS, route sandbox traffic through your own proxy, inject credentials, or weaken sandbox isolation to require approval before they apply
- Changed `ANTHROPIC_CUSTOM_HEADERS` from managed or project settings to require approval when it sets a credential, org/tenant, routing, or API-behavior header (e.g. `Authorization`, `Host`)
- Changed project-level `.claude/settings.json` `env` to no longer set `CLAUDE_CONFIG_DIR`, `CLAUDE_CODE_TMPDIR`, or `TMPDIR`/`TMP`/`TEMP`; set them in your shell, user, or managed settings instead
- Removed syntax highlighting for six rarely used languages (1c, gml, isbl, mathematica, maxima, sqf); the binary is 2.5 MB smaller
- \[VSCode\] Changed the Remote Control banner to a footer pill (shown while Remote Control is on or has failed) that opens the session on claude.ai/code; turn it on or off with `/remote-control`

Show 10 improvements

- Improved CPU usage during turns in interactive sessions by cutting redundant UI re-renders
- Improved install size: the native binary is about 5 MB smaller
- Improved cloud sessions: when the session’s network proxy drops a connection during a Bash command, the tool result now names the host and reason instead of only “connection reset”
- Improved `/schedule` to explain that MCP servers configured in Claude Code can’t be attached to cloud routines, instead of a bare “No MCP connectors” message
- Improved framing of messages from your own subagents: Claude is told the sender is a worker inside this session, not an unrelated Claude session
- Improved the prompt placeholder to read “Message @name…” while viewing a background subagent or fork transcript opened from the subagent panel or `/tasks`
- Improved sanitization of MCP server names in error messages, menus, and command results
- Improved Amazon Bedrock session start under `CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST` (e.g. Claude Desktop): a session given a Bedrock model ID or ARN no longer waits for inference-profile discovery
- Improved the managed settings approval dialog to list only the settings that changed since you last approved them
- Improved retry when the model’s tool call is malformed: the broken output is now dropped from the retry context, including on Bedrock, Vertex, and Foundry

Show 41 bug fixes

- Fixed file tools (Read, Write, Edit) following a symlink swapped inside the working directory after the permission check, which could read or write outside the approved location
- Fixed plugin commands declared in a marketplace entry being able to point outside the plugin directory; such paths are now rejected with a path-traversal error
- Fixed project settings being able to enable detailed beta tracing or raw API body logging, and a lower-scope beta tracing endpoint bypassing an OTLP collector pinned by managed settings or a host app
- Fixed the Workflow tool reading (and quoting in errors) a `scriptPath` outside what the session may read before the permission check ran
- Fixed Grep and Glob not applying `Read(...)` deny rules to files reached through a symlinked search path
- Fixed conversations getting stuck on “text content blocks must be non-empty” errors after a turn where the model produced only thinking
- Fixed the first launch on a fresh install starting in default mode instead of auto mode for accounts whose startup default is auto mode
- Fixed Opus 5 requests failing with “effort … is not supported when thinking is disabled” when effort was xhigh/max and thinking was turned off; effort is now sent as `high` in that case
- Fixed replying to a message Claude Desktop delivered from another session: `SendMessage` to that session id now delivers through Claude Desktop instead of failing with “not reachable”
- Fixed TUI lag with many parallel subagents: per-second progress ticks now replace their predecessor instead of piling up in the transcript
- Fixed agent teams: a teammate’s final answer not reaching the team lead — it now arrives in the idle notification instead of a content-free “available” notice
- Fixed background subagents being unable to reply to a message from an unnamed sibling or parent agent (`from` was the agent type, which is not an address)
- Fixed managed-settings `disableAutoMode` arriving mid-session not moving an already-running auto-mode session back to default mode
- Fixed a “switch to Opus 1M for 5x more context” tip that appeared even when the current Opus model already has a 1M context window
- Fixed Claude apps gateway sessions treating a stored Anthropic profile (e.g. a Console sign-in) as active: listing it in `/status` and retrying gateway 401s with it, though requests never use it
- Fixed cloud sessions telling Claude the model had changed when the host was only setting the session’s initial model
- Fixed Remote Control reporting a failure when an organization’s policy disables it; it now shows a single quiet notice instead
- Fixed `/mcp reconnect` on Remote Control showing a generic withheld-detail error instead of the real remedy when a server was disabled in another session
- Fixed `--input-format stream-json`: client-injected assistant tool calls sent without a message id were merged into the first one and their results lost, including when resuming older sessions
- Fixed session transcripts being silently overwritten when a directory change relocated a session onto an existing same-ID transcript
- Fixed background sessions and their subagents being unable to edit files inside a git worktree they created with `git worktree add`
- Fixed background sessions occasionally starting without any plugin skills (and staying that way) when another Claude Code process was refreshing the plugin marketplace at the same moment
- Fixed selecting text in an opened background session inside tmux over SSH: it now copies to the tmux buffer like a foreground session instead of falling back to OSC 52
- Fixed SDK and cloud sessions hanging indefinitely when an SDK MCP server’s handshake acknowledgment was lost; the wait now times out after 70 seconds and marks only that server failed
- Fixed self-hosted runner leaving a stuck session’s Bash tool processes running after the session was force-stopped
- Fixed `/usage-credits` for Team and Enterprise members whose admin set the org’s usage-credit limit to \$0: it now offers to ask the admin instead of saying a cap was reached
- Fixed `--worktree --tmux` with a merge-request number on a gitlab.com origin trying a doomed GitHub-style fetch first instead of fetching the GitLab ref directly
- Fixed Ctrl+G failing with “Emacs quit unexpectedly” in background sessions for editors that open `/dev/tty`, such as `emacs -nw` and `micro`
- Fixed an `additionalDirectories` entry containing a null byte crashing startup, or breaking `/add-dir` and later settings updates when it came from an SDK host, IDE, or hook; it is now skipped
- Fixed the MCP server menu’s copy shortcut: it now says how the sign-in URL was copied instead of always claiming success
- Fixed italic text (such as the session recap line) rendering as highlighted blocks in GNU screen and in tmux sessions using a `screen` terminal type
- Fixed `claude mcp add --header` and `claude mcp add-json` help text naming the wrong transports
- Fixed `claude ultrareview` and `/ultrareview` waiting the full 30 minutes when the cloud session fails to start; they now stop early and report the reason
- Fixed Bash permission checks auto-approving commands that assign an arithmetic expression to an integer shell variable (e.g. `OPTIND=1/0`, `RANDOM=2+2`); these now prompt for approval
- Fixed backgrounded sessions (`←`, `/background`, `--bg`) losing a Vertex/Bedrock gateway (`ANTHROPIC_*_BASE_URL` + `CLAUDE_CODE_SKIP_*_AUTH`) exported in the shell, so every request failed
- Fixed `claude --bg --model fable` on Max plans stopping to ask for usage credits while the interactive session on the same account still had Fable allowance
- Fixed the one-time “make auto mode your default” offer appearing in unattended sessions (e.g. agent-team teammate panes), where a stray keypress could accept it unread
- Fixed the managed-settings approval prompt re-appearing after signing in again to the same Claude apps gateway when the settings are unchanged
- Fixed disabled `/bug` and `/share` reporting that `/feedback` was disabled; tips, `/help`, and refusal messages no longer suggest `/feedback` when an org policy or env var turns it off
- Fixed cloud session creation advising GitHub setup after a transient GitHub connection failure — the message now says to retry instead
- \[VSCode\] Fixed the sign-in screen’s “Bedrock, Foundry, or Vertex” button opening the docs at the top of the page instead of the third-party provider setup section

[​](#2-1-250)

2.1.250

August 28, 2026

- Bug fixes and reliability improvements

[​](#2-1-248)

2.1.248

August 27, 2026

**Added**

- Added `--restricted` (or `CLAUDE_CODE_RESTRICTED=1`): removes the built-in tools that run commands or code and `WebFetch` (unless named in `--tools`), keeps file tools inside the working directory, refuses `bypassPermissions`, and ignores user, project and local settings files
- Added `experimental.cacheTtl` (`"5m"` or `"1h"`) to agent frontmatter: a per-agent prompt cache TTL used when no subagent TTL setting is configured
- Added `claude self-hosted-runner --client-label <label>` (or `SELF_HOSTED_RUNNER_CLIENT_LABEL`) to override the label the runner registers with (default: hostname)
- Added server-managed settings diagnostics: a startup warning when the settings fail to load, and a `/doctor` and `/status` line explaining a load failure or why they weren’t fetched (Bedrock/Vertex/third-party provider, custom `ANTHROPIC_BASE_URL`)
- Added a warning in `/web-setup` when the GitHub CLI token lacks the `workflow` scope, since pushes to very large repositories can be rejected without it
- Added `/usage-credits` for Enterprise organizations billed through AWS Marketplace, self-serve Enterprise, and Enterprise trials, so members can request a higher usage limit from their admin
- Added cross-session messaging (`SendMessage` / `ListAgents`) between sessions on the same machine on Bedrock, Vertex, and Foundry, and when telemetry is disabled

**Changed**

- Changed shift+enter in the agent view dispatch input to insert a newline (matching the prompt); ctrl+enter now dispatches and attaches
- Changed `/loop`: self-paced dynamic mode and the no-prompt autonomous default are now always available, including on Bedrock/Vertex/Foundry
- Changed Anthropic telemetry export failures to log at debug level as `[Anthropic telemetry]` instead of `[3P telemetry] OTEL diag error`, so they are not mistaken for your OTel collector failing
- Changed cross-session messaging in Linux user namespaces: root-equivalent trust for unmapped owners is limited to canonical system directories
- Changed `SendMessage` from a subagent to another session: the result now notes that any reply is delivered to the parent session’s conversation, not to the subagent

Show 5 improvements

- Improved the Workflow tool’s prompt footprint: its description is now about 1k tokens instead of 5.7k, with the script-writing reference moved into a bundled `workflow-authoring` skill
- Improved the prompt-footer PR badge to check GitHub less often while the pull request is unchanged; a push or a `gh pr` command still refreshes it right away
- Improved managed settings: client-side timeout, MCP startup-mode, and stream-watchdog env vars no longer trigger the settings-approval prompt
- Improved `/ultrareview <PR#>` to check before launch that the GitHub account connected to your Claude account can access the repository, and to explain how to fix it, instead of failing after the cloud session starts
- Improved cross-session messaging: falls back to a private per-user `/tmp` directory when the default one can’t be used, and the notice and `/status` name the directory to fix

Show 32 bug fixes

- Fixed a prompt-cache miss (and lost extended-thinking context) roughly once an hour in long sessions, caused by tool definitions being re-rendered after an OAuth token refresh
- Fixed the `ScheduleWakeup` tool definition changing between a session and its `--resume` when the account had entered usage overage, causing a full prompt-cache miss on the resumed session’s first turn
- Fixed Claude Desktop and Cowork sessions disappearing after 30 days: the transcript cleanup now keeps desktop-written sessions while they are in the app (unless org policy manages retention); the new `desktopSessionCleanupPeriodDays` setting caps the exemption
- Fixed being sent to the login screen when another Claude Code process held the token refresh lock while the session token had expired; the request now fails with a retryable error instead
- Windows: Fixed the `claude agents` list not responding to the keyboard after detaching from a session, or when launched in a terminal tab left in win32-input-mode
- Fixed the recommended Console sign-in in `/login` failing with an OAuth error before showing a sign-in URL on machines where it can’t be used (for example when `ANTHROPIC_API_KEY` or an API key helper is set); it now falls back to the API-key sign-in
- Fixed model names in `/model` and fast-mode switch notices to render as code, so suffixes like `[1m]` display literally instead of as a link
- Fixed `claude agents` skipping the workspace trust prompt when the `CI` environment variable is set
- Fixed `claude agents` crashing on launch when the PR-status cache held a malformed entry
- Fixed agent view resurrecting a weeks-old background session after the machine was off: such a session now shows as stopped at its real end, and opening it asks before resuming its saved conversation
- Fixed agent view sometimes opening an older conversation, and dropping the typed prompt, when starting a new session
- Fixed `claude agents`: opening a stopped session that you already resumed in another terminal no longer starts a second process on that conversation; the row now says it is open in a terminal
- Fixed `claude agents` and `claude rm` refusing to delete a session (“has commits that are not pushed anywhere”) when its worktree branch was already merged into your checked-out default branch (e.g. local `main`) but not yet pushed
- Fixed background sessions waiting silently when a `PermissionRequest` or `PreToolUse` hook prints an invalid answer: the `claude agents` row now names the hook and the schema error
- Fixed hooks silently treating a stdout `{…}` object that isn’t valid JSON as plain text; it’s now reported as a hook error with the parse message
- Fixed `/mcp` listing a project `.mcp.json` entry that declares the claude.ai connector type under the trusted “claude.ai” heading; it now appears under its real scope
- Fixed MCP servers whose `headersHelper` supplies the `Authorization` header falling into OAuth discovery on a 401 instead of re-running the helper and retrying the call as documented
- Fixed `/login` to a Claude apps gateway hanging when the managed-settings security approval dialog was required
- Fixed gateway model discovery (`CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY`) never running when `apiKeyHelper` is the only credential
- Fixed `claude logs` leaving mouse tracking, bracketed paste and the alternate screen switched on in the terminal it was run from
- Fixed the trust dialog’s list of repo permission rules showing a garbled character when a long rule was cut off in the middle of an emoji
- Fixed the permission mode indicator staying hidden behind the “Press Ctrl-C again to exit” hint when you press shift+tab right after ctrl+c
- Fixed `/ultrareview` and locally seeded cloud sessions uploading uncommitted edits to `prod.env`-style and `*.tfvars` files, or to editor swap, temp, and backup copies of credential files (e.g. `key.pem.tmp`, `id_rsa.swo`); they now stay on your machine
- Fixed Remote Control sessions occasionally never showing a permission prompt or the latest messages on the connected device after the CLI silently reconnected
- Fixed cloud sessions occasionally failing at startup when the container’s session credentials were not yet readable
- Fixed `claude remote-control` rejecting its own flags (e.g. `--spawn`, `--name`) when a global flag or a wrapper-injected option precedes the subcommand
- Fixed startup warnings (e.g. “N MCP servers need authentication”) rendering one column right of the rest of the transcript
- Fixed a backgrounded worktree session losing its checkout: the background session now holds the worktree’s lock while it runs, so cleanup and `git worktree remove` leave it alone
- Fixed @-mentions of other sessions not matching names typed with non-Latin characters (for example Korean entered through an IME)
- Fixed an invalid `crossSessionInbound` value being silently ignored: it now warns and holds cross-session messages (user settings) or refuses them (managed settings) until fixed
- Fixed rate-limit, usage, and fast-mode messages telling you to run `/usage-credits` when that command isn’t available for your organization (e.g. hidden with `DISABLE_EXTRA_USAGE_COMMAND`)
- \[VSCode\] Fixed a chat tab getting stuck on “No conversation found” when its session was never saved; it now starts a new conversation instead

[​](#2-1-247)

2.1.247

August 26, 2026

**Added**

- Added the `SendFeedback` tool: when something goes wrong in a session, Claude can draft a feedback report for you to review and send from `/feedback` (turn off with the `feedbackDrafts` setting)
- Added `{id, text, cooldownSessions, priority}` entries, `tipsFile`, and `label` to `spinnerTipsOverride`, so organizations can rotate their own tips alongside the built-in ones
- Added a tip on Bash permission prompts pointing to auto mode, with a one-keystroke “Yes, and switch to auto mode” option
- Added `/claude-api cost-optimize` to profile an existing project’s Claude API spend and work through cost levers (caching, token hygiene, batch, effort, model choice) one measured change at a time

**Changed**

- Updated the `/claude-api` skill with Admin API coverage (organization members, invites, workspaces, API keys, rate limit reports, workload identity federation, CMEK)
- Changed Sonnet 5’s default auto-compact window to its full 1M context, so sessions on the 1M window now auto-compact at about 967K tokens instead of about 934K
- Changed cross-session peer messages to collapse by default to a one-line `Message from @<sender>: <first line>` preview; Ctrl+O expands the full body
- Changed terminal hyperlinks in rendered markdown: link targets that point at a network or automounter path, contain a control character, or lead with an invisible character now render as plain text
- Changed the prompt-footer PR badge to skip its GitHub re-check on terminal refocus when the last check is under a minute old
- Changed analytics to stay off from startup, not only after login, when managed settings force gateway login or a custom OAuth deployment is configured
- Changed Claude apps gateway sign-in requests to identify Claude Code (a `surface=claude_code` device-authorization parameter and a `claude-code/<version>` User-Agent)
- Changed organization sign-in enforcement to exit at start when the administrator’s managed settings cannot be read, even if host-supplied or per-user Windows registry settings exist

**Improved**

- Improved plugin marketplace hardening: names containing control or invisible characters are rejected, and marketplace-supplied text in `/plugin` and `claude plugin` output is escape-safe
- Improved Bedrock, Vertex, and Foundry sessions (and any with telemetry disabled): Claude is now told when a configured MCP server failed to connect, instead of concluding its tools don’t exist

Show 19 bug fixes

- Fixed fast arrow-key + Enter sequences acting on the row above the one you navigated to in history search, `/config`, `/mcp`, `/skills`, background tasks, and `/model`
- Fixed sub-agents dying on a first-call model 404: they now use the session’s fallback model chain, and the error returned to the parent includes the error type, status, request id, and model
- Fixed a hook or background agent that printed megabytes of error output being able to overflow the conversation and wedge the session on “Prompt is too long”
- Fixed Ctrl keyboard shortcuts not firing under non-Latin (e.g. Cyrillic) keyboard layouts in kitty-protocol terminals
- Fixed text like `<35;150;7M` being inserted into the prompt when a mouse report arrived split across reads right after the escape prefix
- Fixed the Bash sandbox’s after-command cleanup deleting a dotfile-managed `~/.claude/settings.json` symlink (nix/home-manager, stow) when it is repointed outside the sandbox’s writable area
- Fixed `/terminal-setup` overwriting your entire Zed `keymap.json` instead of merging in its keybinding
- Fixed `/rename` silently confirming when the session registry could not be updated; it now says other sessions may still show the old name
- Fixed `/compact` and “Summarize from here” in sessions started with `--agent` summarizing under the default system prompt instead of the conversation’s own
- Fixed a background session showing “opening…” forever in `claude agents` after its terminal host process died; the row now fails within seconds with the reason, and Enter restarts it
- Fixed unbounded memory growth when a hook’s or background task’s output file could not be written; the file now notes where output was lost
- Fixed `/install-github-app` over SSH: the copy shortcut now says how the sign-in URL was copied instead of always claiming success, and the URL appears immediately when no browser can open
- Fixed shell commands carried over from the foreground logging an internal error or showing a misleading `[exited with code -1]` line when they finish in background sessions
- Fixed a version-less marketplace plugin’s live cache directory being deleted and recreated on a second-scope install, which could disrupt a running session using it
- Fixed Remote Control sessions started with `/remote-control` not reporting the working-tree diff to connected clients
- Fixed self-hosted runner sessions reporting `running` before Claude Code had started, which could trigger a premature “Claude is waiting for your input” notification from the Claude desktop app
- Fixed first-run setup exiting with “Unable to connect to Anthropic services” when managed settings configure Claude apps gateway sign-in and Anthropic endpoints are unreachable
- Fixed cloud sessions (Claude Code on the web, desktop and mobile apps) sometimes showing the previous permission mode when you switch modes right after sending a message
- Fixed cloud sessions going silent when the session’s container restarts between turns while a background agent, shell, or monitor is still running — the resumed session now reports the lost work

[​](#2-1-246)

2.1.246

August 25, 2026

**Added**

- Added a startup warning for Bash allow rules with a wildcard before the subcommand (e.g. `Bash(git * main)`), since they also match options inserted before the subcommand
- Added an Auto mode tab to `/permissions` for viewing and editing auto mode classifier rules
- Added the turn’s completion time to the end-of-turn duration line, e.g. `✻ Sautéed for 23s · done 6:05 PM`

**Changed**

- Changed `/code-review` so Claude can also start it on its own on Bedrock, Vertex AI, and Foundry, through the Claude apps gateway, and when telemetry or non-essential traffic is disabled
- `/goal`: Changed idle sessions to start at most three check-ins on long-running background work per goal; your next message allows three more
- Changed `claude install` and `claude update` to defer a pending managed-settings consent prompt to the next interactive session instead of prompting mid-command
- Changed OpenTelemetry plugin events for plugins synced from claude.ai: `plugin_id_hash` now reflects the plugin’s real marketplace, and `enabled_via` is `admin-install` for admin-installed plugins

Show 5 improvements

- Improved `/cd`: the new directory’s project settings, hooks, `.mcp.json` servers (behind the usual approval prompt), skills, and agents now take effect right after the move instead of on `--resume`
- Improved Bash tool latency on bash shells by replaying snapshot functions without a base64 subshell per function
- Improved subagent results: a subagent that stops at its `maxTurns` limit now returns its output marked as partial, with a hint to continue it via `SendMessage`, instead of appearing finished
- Improved non-interactive sessions (`-p`, SDK, cloud sessions) to automatically continue a response cut off mid-stream by a server error, connection loss, or stall instead of ending with an error
- Improved attribution of usage telemetry to your organization for workload identity federation sessions, events sent while `apiKeyHelper` runs at startup, and after a login token expired while idle

Show 49 bug fixes

- Fixed fullscreen mode showing a blank transcript after resizing the terminal and jumping to the bottom until the next keypress
- Fixed a severe transcript slowdown when a diff contained a very long single line (e.g. a base64 string); such lines now render truncated with a marker
- Fixed erratic fullscreen scrolling when positioned at an earlier message, including jump-to-bottom getting stuck mid-transcript
- Fixed background sessions failing to open after 45 seconds when Claude Code’s starting directory had been deleted, the machine had slept, or the host is slow to start processes
- Fixed background sessions failing to open with “Couldn’t start the background service … EACCES” when another Claude Code process was re-installing the npm package at that moment
- Fixed markdown rendering being disabled for a whole message when its first 500 characters contained no markdown, and for `+`/`N)` lists and setext headings
- Fixed MCP tool calls interrupted by an incoming message in headless/remote sessions being reported to the model as “completed with no output” instead of an explicit interrupted error
- Fixed MCP tool arguments being sent as JSON strings when the parameter’s schema is empty (`{}`), instead of their real type
- Fixed a command interrupted mid-run showing as “Ran 1 shell command” with no sign it was cut
- Fixed pressing ← or running `/background` during a dynamic workflow restarting its finished subagents; it now asks first and says how many subagents would restart
- Fixed opening a just-started session in `claude agents` while its worker was still booting (common on Windows) stopping it with “was stopped while the respawn was in flight”
- Fixed `claude agents` listing a backgrounded named session twice; backgrounding the same conversation again now numbers the new row (e.g. `my-session (2)`)
- Fixed the background retention sweep removing git worktrees under `.claude/worktrees/` that you created yourself when an old background-session record pointed at them
- Fixed auto mode tool calls being denied as “temporarily unavailable” on very large sessions by scaling the safety-check deadline with prompt size
- Fixed the plugin cache creating duplicate SHA-named directories for the same plugin
- Fixed plugin skills whose frontmatter `name` already includes the `<plugin>:` prefix showing it doubled in the slash menu (e.g. `/plugin:plugin:skill`)
- Fixed `claude plugin update` failing for an installed plugin given its bare name (only the fully-qualified name worked)
- Fixed plugin installation failing when `plugin.json` was saved with a UTF-8 byte-order mark (BOM)
- Fixed `/reload-plugins` reporting 0 skills for plugins that define skills under `skills/*/SKILL.md`
- Fixed hook error messages showing a literal `${CLAUDE_PLUGIN_ROOT}` instead of the resolved plugin path
- Fixed `/rename` replacing the theme’s prompt border color (including a custom theme’s `promptBorder`) with the default cyan; the border now keeps your theme’s color unless you pick one with `/color`
- Fixed custom theme diff colors (`diffAdded`/`diffRemoved` and their dimmed variants) being ignored in diffs and the `/theme` preview
- Fixed a `keybindings.json` binding with an unknown action name silently deadening that key; it is now skipped so the default binding keeps working, and a warning is logged under `--debug`
- Fixed `/stats` activity heatmap showing each day’s activity one cell off (Sunday’s count under Monday) in timezones east of UTC
- Fixed `/fork` from an already-forked or backgrounded session starting the new session with an empty conversation
- Fixed prompts beginning with `/--` (e.g. Lean doc comments) being rejected as an unknown slash command instead of being sent to Claude
- Fixed the `@` file picker staying open after the typed text stopped matching a real path
- Fixed the status line’s cost and duration resetting to zero after navigating to the agents view and back
- Fixed fullscreen mode moving keyboard focus onto the control under the pointer when you clicked the terminal window only to bring it back into focus
- Fixed path completion failing when the completion token or working directory contained a null byte
- Windows/macOS: Fixed headless sessions not cleaning up stale entries in `~/.claude/sessions` left by sessions that exited uncleanly
- Fixed the UI stopping with a render error on the first tool call when a third-party Anthropic-compatible endpoint (`ANTHROPIC_BASE_URL`) streams a `tool_use` block without an `id`
- Fixed the Write tool reporting “Out of memory” or freezing for a long time after overwriting a very large existing file, even though the file had been written
- Fixed `claude plugin install <name>` exiting silently (or hanging in a terminal) instead of reporting an error when `~/.claude/plugins/known_marketplaces.json` is empty or corrupted
- Fixed resumed sessions failing every turn with a 400 when the saved history contains tool blocks the Anthropic API does not accept (typically written by a third-party API proxy)
- Fixed `curl -fsSL https://claude.ai/install.sh | bash` failing with “Raw mode is not supported” for some Team/Enterprise users with server-managed settings
- Fixed sessions that ended in plan mode resuming outside plan mode in the VS Code extension, and in `claude -p --continue`/`--resume` with a permission prompt tool, when no permission mode was set
- Fixed the `Notification` hook not firing while the sandbox “Network request outside of sandbox” permission prompt is waiting
- Fixed Bash permission checks to always require approval for malformed commands with a dangling `&&` or `||` operator
- Fixed `--strict-mcp-config` sessions prompting to approve `.mcp.json` servers they would never load, which left background sessions waiting at startup
- Fixed telemetry and metrics requests to Anthropic carrying the API key configured for a third-party gateway (`ANTHROPIC_BASE_URL`); a credential is now only sent to its own host
- Fixed a visible API error on the first prompt after idle when `apiKeyHelper` returns short-lived JWTs: an expired cached token is now refreshed before sending, and 401/403 auth errors retry quietly
- Fixed memory growing with session length in the fullscreen and Ctrl+O transcript views: each rendered message row no longer retains a full copy of the transcript-wide tool lookups
- Fixed `/ultrareview` runs and cloud sessions launched at the same time from one repository (e.g. from several worktrees) sometimes starting with another launch’s uncommitted changes
- Fixed the task progress count (e.g. `3/5`) shown for background cloud sessions such as `/autofix-pr` occasionally missing a task
- Fixed Remote Control sessions keeping their placeholder name in claude.ai and the Claude app until the second prompt; the auto-generated title now appears after the first prompt
- Fixed MCP tools marked `requiresUserInteraction` still offering “Yes, and don’t ask again” in their permission prompt; the option wrote an allow rule the tool then ignored
- Fixed the self-hosted runner ending its live sessions or exiting when a work-poll response is malformed (e.g. an intercepting proxy’s HTML page); it now retries the poll
- Fixed the command sandbox’s filesystem configuration not respecting `--setting-sources`

[​](#2-1-245)

2.1.245

August 25, 2026

- Fixed a crash on startup on Linux distributions that ship glibc 2.44 (for example Arch Linux, CachyOS and Fedora Rawhide)

[​](#2-1-243)

2.1.243

August 25, 2026

**Added**

- Added a Loops breakdown to `/usage`: per-loop run count, total tokens, tokens per run, and last run, so runaway or chatty `/loop` tasks are easy to spot
- Added `modelPicker` setting: curate the `/model` picker with an ordered, labeled list of models (any id spelling, including Vertex/Bedrock ids), appended to or replacing the built-in lineup
- Added `promptCacheTtl` and `subagentPromptCacheTtl` settings so API-key and cloud-provider users can keep a 1-hour prompt cache on the main conversation while subagents stay at 5 minutes
- Added `modelPricing` managed setting so an organization’s contracted per-model rates and discount multiplier are used for `/cost`, the status line, and telemetry cost figures instead of list price
- Added a keyless sign-in under `/login` → Anthropic Console: “Sign in with your Console account” (recommended) alongside creating an API key, so organizations that don’t allow API keys can sign in
- Added a `Skipped sources` line to `/status` that lists managed settings sources (for example `managed-settings.json`) present but not applied because a higher-precedence managed source is active
- Added a `managed` marker in `/mcp` and `/plugins` on claude.ai connectors whose authentication is managed by your organization
- Added a tip pointing claude.ai users who haven’t connected GitHub for Claude Code on the web to `/web-setup`
- Added a `/status` line showing whether GitHub is connected for Claude Code on the web (Pro/Max), pointing to `/web-setup` when it isn’t
- Added the model (and effort level) each subagent ran on to `/tasks` and the agent detail dialogs

**Changed**

- Changed the sandboxed Bash tool prompt to no longer list allowed network hosts, so Claude attempts requests (and you can approve new hosts) instead of assuming unlisted hosts are blocked
- Updated the `/model` picker and the bundled `claude-api` skill to show Sonnet 5’s \$2/\$10 per Mtok pricing as its standard list price rather than a limited-time promo
- Changed computer use on macOS so clicking the desktop, Dock, or a Finder window requires granting Finder via the access dialog, like any other app
- Changed `/model`, `/fast`, and `/effort` to also run immediately instead of queueing until the turn ends on Bedrock, Vertex, and Foundry and when telemetry is disabled
- Changed the cross-session messaging inbox socket to close connections that send no complete line within 30 seconds; scripts posting to it should connect once their data is ready

Show 12 improvements

- Improved startup time: sandbox and MCP bring-up no longer block the first frame, bare launches skip subcommand registration, and workflow discovery, settings, and trust-store work is cheaper
- Improved native install and auto-update download size: the binary is now zstd-compressed (about 75 MB instead of 340 MB on Linux x64)
- Improved attribution of usage telemetry to your organization for sessions that authenticate with `ANTHROPIC_AUTH_TOKEN` directly against the Anthropic API, so its data-handling settings apply
- Improved native binary size: about 2 MB smaller by storing the bundled skill and prompt text more compactly
- Improved memory usage of native builds: code is now loaded on demand instead of keeping the whole bundle resident (roughly 40–70 MB less memory per session)
- Improved peak memory usage in long-running sessions (the runtime now garbage-collects sooner as the heap grows)
- Improved `/login` over SSH: the sign-in URL appears immediately, pressing `c` reports how the URL was copied instead of always claiming success, and a hint explains how to select text in fullscreen
- Improved the error when effort `xhigh`/`max` is used with thinking turned off: it now names the level, the setting that disabled thinking, and `/effort high` as the fix
- Improved `/loop`: consecutive wake-ups where Claude has nothing to do now fold into a single line in the terminal instead of printing each one
- Improved the notice when resuming a conversation whose Remote Control is held by another terminal: it now says sessions on other machines can’t be seen from, or reach, this one
- \[VSCode\] Improved history trimming in long sessions: older tool-activity rows are dropped first so your messages and Claude’s replies stay visible
- \[VSCode\] Improved attribution of the extension’s own usage telemetry to your organization when you are signed in with a Claude account, so its data-handling settings apply

Show 33 bug fixes

- Fixed remote MCP servers in non-interactive (`-p`) and SDK sessions never recovering after a dropped connection; they now reconnect automatically or report as failed
- Fixed MCP server sign-in started from the desktop app failing with “Invalid redirect URI” on servers that support client ID metadata documents (for example Linear)
- Fixed auto mode staying unavailable at startup when a temporary server-side disable was cached and later flag fetches failed
- Fixed auto mode tool calls being denied as “temporarily unavailable” after about a minute of waiting when the API was briefly overloaded and asked the client to retry
- Fixed the `/model` picker silently ignoring an Ultracode selection; picking Ultracode now applies it to the current session
- Fixed `/resume` only listing the 50 most recent sessions; the picker now loads more as you scroll
- Fixed cloud sessions resuming after a mid-turn restart with a pending hook or background-task notification re-sent as the prompt instead of the normal continuation message
- Fixed cross-session messaging silently turning off inside user namespaces and rootless containers after the 2.1.232 socket-directory hardening
- Fixed text that hangs outside its container (for example the sign-in URL in `/login`) losing its leading columns when another part of the screen repaints
- Fixed `spellcheck` not underlining a misspelled word typed directly after an emoji
- Fixed background subagents not waking when their last background Bash task completes
- Fixed sessions going silent for 10+ minutes when the Anthropic API never starts a response: the request now times out after ~3 minutes, retries once, then shows `API Error: No response from API`
- Fixed auth, model-availability, and other client-generated error messages rendering like model output instead of as error lines
- Fixed workload identity federation in CI: processes in one job share the exchanged token instead of re-exchanging the single-use token; a rejected exchange fails fast with the server’s message
- Fixed server-managed `companyAnnouncements` not showing at startup in a session that began with signing in (for example the first launch after `/logout`)
- Fixed hook `if` conditions like `Bash(cat *)` firing on unrelated Bash commands when the command contained `$()` or backtick command substitution followed by more arguments
- Fixed plugin dependencies declared with a `marketplace` field never resolving when both plugins are loaded together via `--plugin-dir`
- Fixed `/reload-plugins` keeping the LSP tool after the last LSP plugin is disabled; it now also warns before an LSP plugin change that would re-read the conversation
- Fixed `--agents` silently ignoring invalid JSON or invalid agent definitions; it now exits with a clear error, like `--mcp-config`
- Fixed `/status` showing “Found invalid entries in: .” with no filename when `~/.claude.json` has an invalid MCP server entry
- Fixed `/clear` removing the `/rename` session name from the prompt bar even though the name was kept for the new session
- Fixed Ctrl+R history search and up-arrow history breaking when `~/.claude/history.jsonl` contains a malformed entry
- Fixed Ctrl+\[ not leaving vim INSERT mode in terminals that encode modified keys (modifyOtherKeys / kitty protocol)
- Fixed the local IDE connection being routed through `HTTPS_PROXY` (and sometimes failing) when `localhost` was listed in `NO_PROXY` but not lowercase `no_proxy`; both casings are now honored
- Fixed sandbox network-violation details being dropped from the Bash tool result when the blocked command still exited 0 (for example `curl` printing the proxy’s 403 page)
- Fixed the status line `rate_limits` fields and `/usage` still showing a rate-limit window’s pre-reset usage percentage after the window reset while the session was idle
- Fixed `claude --teleport <session>` exiting on uncommitted changes instead of offering to stash them and continue, as the session picker already does
- Fixed `/web-setup` repeatedly asking you to log in when an older GitHub CLI (without `gh auth token`) was already authenticated
- Fixed Claude in Chrome losing its connection to Claude Code after an auto-update cleaned up the version it was set up with; the native host now launches via the stable `claude` launcher
- \[VSCode\] Fixed sessions started before feature flags were first fetched (for example right after install) opening in the default permission mode instead of auto mode or your configured default mode
- \[VSCode\] Fixed Focus view sections you expanded collapsing on their own during subagent tool activity
- Fixed `claude remote-control` exiting and stranding attached Remote Control sessions when the server drops its environment mid-session; it now recovers
- Fixed Remote Control sessions served by `claude remote-control` sometimes getting stuck after it was stopped and restarted, for Team and Enterprise members without an admin or owner role

[​](#2-1-241)

2.1.241

August 23, 2026

- Bug fixes and reliability improvements

[​](#2-1-240)

2.1.240

August 22, 2026

- Bug fixes and reliability improvements

[​](#2-1-239)

2.1.239

August 21, 2026

**Added**

- Added the one-time fullscreen renderer offer on Bedrock, Vertex, Foundry and other previously excluded setups; new installs there now start in fullscreen
- Added `/claude-api upgrade` to migrate Python projects from `anthropic` 0.x to 1.x, and updated the skill’s Python reference for 1.x (timeouts use `anthropic.Timeout`, not `httpx.Timeout`)

**Changed**

- Cost estimates (`/cost`, status line, `--max-budget-usd`) now include the 1.1× US-only-inference premium for data-residency workspaces
- Cloud sessions: plugins synced from claude.ai now show as `name@synced`, work with `claude plugin enable/disable <name>@synced`, and never override a same-named plugin you installed
- Alpine/musl builds: native image paste, clipboard, and audio-capture add-ons now load (musl-built binaries instead of glibc ones refused by the runtime)
- The usage-limit message shown when your monthly spend limit is already used up now also says when your session or weekly limit resets
- Long file paths on tool-use rows now truncate in the middle to stay on one line
- Remote sessions keep sending keep-alives while a long `SessionStart` or `Setup` hook runs, so the container is not idle-reaped mid-hook
- `/goal`: repeat check-ins on long-running background work now back off (30 min, then 1 h, then every 2 h) instead of repeating every 30 minutes
- `/goal`: resuming a session from the `claude --resume` picker now restores its active goal
- `ListAgents` now tells a session its own name (the one peers use to message it), and `SendMessage` to your own name says so instead of “no agent named …”
- `ListAgents` and `/list-agents` now list your live teammates (previously only subagents and other sessions appeared, so a reachable teammate looked absent)
- `keybindingFlavor: "readline"` now also matches Bash for word keys: Alt+F and Ctrl/Option+→ stop at the end of the word, Alt+D deletes to it (Ctrl+Y pastes it back), and punctuation separates words
- Persistent retry mode (`CLAUDE_CODE_RETRY_WATCHDOG`) now fails immediately on organization spend-limit and out-of-credits errors instead of waiting indefinitely for a reset
- Claude in Chrome: `/clear` now closes the session’s Chrome tab group, and empty groups are closed on `/resume` and when Claude Code exits
- Remote sessions: images uploaded from mobile now include their saved file path, so Claude can copy them into files it creates
- Claude Code on the web: requests from Bash and other tools to non-API anthropic.com hosts (e.g. www, docs) now go through the session’s network proxy, so your environment’s allowed domains apply
- Remote Control: clearer message and `claude doctor` wording when Remote Control isn’t enabled for your account
- Windows: cross-session messaging is now available, so Claude Code sessions across your machines can message each other with `SendMessage` and find each other with `ListAgents`, as on macOS and Linux
- \[VSCode\] “View usage” in the usage-limit banner now sits inline with the warning text instead of floating mid-banner

**Improved**

- Improved the reminder shown after compaction so a skill’s original arguments are not re-run as a new request

Show 38 bug fixes

- Fixed Bedrock streaming behind proxies that strip the response Content-Type header, which silently doubled billed API calls by re-running every turn non-streaming
- Fixed Claude Code hanging at startup behind an HTTPS proxy when using Bedrock with an SSO profile and `awsAuthRefresh` — the credential pre-check now honors `HTTPS_PROXY`
- Fixed a raw crash dump when starting Claude Code from a directory that no longer exists; it now prints a clear message
- Fixed Edit and Write calls pausing for about 5 seconds in JetBrains IDE terminals when the Claude Code plugin is connected
- Fixed a race where pressing Esc with a prompt queued could let the next turn finish early, leaving the session idle while Claude was still working and letting a later resubmit repeat actions
- Fixed WebFetch retaining expired page content in memory for the whole session instead of the intended 15 minutes
- Fixed cloud sessions (Claude Code on the web, desktop and mobile apps) resuming out of plan mode after an idle worker restart
- Fixed MCP elicitation forms taller than the terminal being clipped in fullscreen mode: the form now fits the window, with hidden fields reachable by scrolling and Accept/Decline always visible
- Fixed remote MCP servers staying failed after a transient 5xx on a mid-session reconnect in cloud sessions or via SDK `setMcpServers()`
- Fixed custom session titles disappearing from `/resume` after more than ~64 KB of conversation was written following the rename
- Fixed `claude -c`/resume picking up sessions from a different directory whose path differed only by characters like `_`, `-`, or `.`
- Fixed `/resume` and the agents view showing a session as recently changed (and reordering it) when only its file was touched or it was merely reopened
- Fixed `/resume` in all-projects mode telling you to `cd` into a deleted directory (e.g. a removed worktree); such sessions now resume in the current directory
- Fixed the `dark-ansi` theme rendering expanded tool results in fullscreen mode with text the same color as the background
- Fixed the fullscreen renderer prompt reappearing on every launch when it could never be answered; it now stops after being shown on three launches
- Fixed `.worktreeinclude` patterns starting with `**/` silently matching nothing when the target lived in a gitignored directory
- Fixed agents, skills, and commands whose `.md` file starts with a UTF-8 BOM being silently ignored
- Fixed `/insights` echoing literal `<message>` tags in its response on some models
- Fixed marketplace `metadata.pluginRoot` having no effect: bare plugin source names now resolve under it as the docs describe
- Fixed mouse movement in browser-based terminals inserting text like `"35;150;7M"` into the prompt when a mouse report arrived split across writes
- Fixed custom theme overrides for the effort/ultracode status badge colors being ignored
- Fixed OpenTelemetry trace fragmentation: tool executions deferred by a `PreToolUse` hook now resume in the original turn’s trace instead of starting a new trace
- Fixed vim mode in the agent view: Escape now switches to NORMAL mode and keeps your text instead of clearing the prompt
- Fixed the `selection:copy` keybinding silently dropping a text selection that had been extended with Shift+Arrow keys
- Fixed the `/voice` startup tip still appearing after voice dictation was enabled via the `voice.enabled` setting
- Fixed shell-mode (`!`) Tab completion dropping the `./` from a `./script` path, which left a command the shell couldn’t run
- Fixed fullscreen mode answering a permission prompt or pressing a button when you clicked the terminal window only to bring it back into focus
- Fixed slash-command panels (e.g. `/config`, `/model`) in fullscreen mode covering the latest messages; the conversation now stays pinned above the panel
- Fixed the `/workflows` detail dialog overflowing the terminal and losing its header off-screen when opened while Claude is still responding
- Fixed the Linux sandbox making a nonexistent `.git/config.worktree` unreadable, which broke every sandboxed git command in repos with `extensions.worktreeConfig` set
- Fixed hooks failing with “posix_spawn ENOENT” after the session’s working directory was deleted; they now run from the project root or home directory instead
- Fixed `claudeMdExcludes` not excluding a symlinked `.claude/rules` file when the pattern names the rules directory or the symlink rather than its target
- Fixed runaway session-title syncing to Remote Control when two Claude Code processes shared one background job’s state (2.1.232 regression); title updates are now deduplicated and rate-limited
- Fixed sessions whose title starts with `/` being unaddressable by `SendMessage` and shown as “(untitled)” in `ListAgents`
- Fixed Ctrl+W, Ctrl+U, Ctrl+K, Option+Backspace, Option+D and vim `df`/`dt` leaving a broken `[Pasted text #N]` placeholder when the cursor was inside it
- Fixed masked (password-style) inputs such as the login code field letting their text be pasted back with Ctrl+Y elsewhere or saved to prompt history when cleared with double Esc
- Fixed Ctrl+Backspace deleting one character instead of a word in search boxes
- Fixed a request rejected by an organization policy check being re-sent before the rejection was shown

[​](#2-1-238)

2.1.238

August 20, 2026

**Added**

- Added a `keybindingFlavor` setting: set it to `"readline"` to make Ctrl+W in the prompt delete back to the previous whitespace, as in Bash; the default (`"classic"`) is unchanged
- Added `claude self-hosted-runner --defer-shutdown-max-min <minutes>`: on SIGTERM, keep serving attached sessions, park what is left after that many minutes, then exit
- Added `claude self-hosted-runner --proxy-authorization-command` / `--proxy-authorization-file` for egress proxies that require a freshly issued `Proxy-Authorization` header on every connection

**Changed**

- Plugin marketplaces: `headersHelper` on a url marketplace or a catalog entry runs a command that mints HTTP headers (e.g. a short-lived token) for catalog and same-origin archive fetches
- A catalog entry’s `headersHelper` runs only when you install or update that plugin, after its command is shown; `claude plugin install/update` ask `[y/N]` (or pass `-y`)
- Cross-session messaging: sending to a session on this machine that refuses inbound messages (e.g. `crossSessionInbound: "refuse"`) now reports “refused” to the sender instead of a silent success
- Cross-session messaging: a session whose inbox drops your messages (rate limit or full queue) now tells your session, instead of the messages vanishing silently
- Updated the bundled `claude-api` skill for the Managed Agents Aug 19 release: web search/fetch domain settings and memory stores on self-hosted sandboxes
- Changed Ctrl+L and Cmd+K in fullscreen to always just repaint — the double-press `/clear` shortcut was removed, and 1-row nvim terminals no longer trigger automatic `/clear` loops
- Changed `claude mcp list` and `claude mcp get` to show disabled servers as `⊘ Disabled` instead of connecting to them for a health check
- MCP `headersHelper` in a project `.mcp.json`, and inline MCP servers in project or `--add-dir` agent files, now require that folder’s trust dialog to have been accepted (also under `claude -p`)
- MCP `headersHelper` from a project `.mcp.json`, plugin, or agent file runs without inherited credential env vars; user, managed and claude.ai-scope helpers now run from the Claude config dir

**Improved**

- Improved startup: bare `claude` starts sooner on macOS
- Improved Bash tool permission checking for zsh-specific syntax in shell conditionals
- Improved Remote Control connection resilience: brief HTTP 403 refusals from a network edge, VPN, or proxy are now tolerated for up to 3 minutes, with the refusing party named when a block persists
- Improved startup responsiveness: the automatic update check now runs about 10 seconds after launch instead of competing with startup for CPU

Show 23 bug fixes

- Fixed unbounded memory growth in long interactive sessions: subagent tool results are now released once they leave the recent display window
- Fixed custom, project, and plugin output styles drifting back to the default voice mid-session
- Fixed `CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=true` not keeping prompt suggestions on when your account is near, but not over, its usage limit
- Fixed worktree-isolation Bash refusals telling you to remove a redirect when the command had none
- Fixed self-hosted runners occasionally being removed by the server after a single slow or lost poll request, handing their healthy session to another runner
- Fixed MCP elicitation dialogs showing nothing for URLs longer than 4,096 characters, and permission prompts dropping the “don’t ask again” option when the project path didn’t fit the terminal width
- Fixed leftover `/tmp/claude-*-cwd` files when a Bash command is killed, times out, or is interrupted
- Fixed held Backspace being ignored on terminals that send Ctrl+H for Backspace when keystrokes arrive in large bursts (slow SSH/mosh links)
- Fixed text-wrapping in permission prompt diffs: lines containing wide multi-code-point characters (such as emoji) or tabs are no longer clipped
- Fixed killing a suspended (Ctrl+Z) session sometimes leaving the terminal in bracketed-paste mode with the cursor hidden
- Fixed stdio MCP servers receiving a `server/discover` request before `initialize`, forcing lazy servers to start their backend on every session open
- Fixed a proxy’s refusal of a connection being reported as a generic network error instead of naming the proxy
- Fixed the `/model` and `/effort` cache-miss warning appearing when the prompt cache had already expired
- Fixed per-task Stop from the Remote Control tasks panel doing nothing on CLI-hosted sessions
- Fixed remote sessions exiting when a client delivered a user message without a valid role
- Fixed Remote Control sessions started by `claude remote-control` inheriting session-scoped environment variables from the launching shell
- Fixed a Remote Control session whose process crashed staying unavailable until `claude remote-control` was restarted; it can now be reused when you next message it
- Fixed Remote Control messages sent from the web or Desktop while Claude is mid-turn disappearing from the transcript after the turn finishes
- Fixed Remote Control model picks made on a phone or web not updating the model shown in the terminal
- Fixed Remote Control disconnecting with “login expired” when a brief network hiccup delays renewing your sign-in; it now retries and stays connected
- Fixed Remote Control reporting a failed reconnect on sign-out; signing out now ends the session with a clear message
- Fixed `ListAgents`/`SendMessage` reporting “Remote Control is not connected” in sessions run by `claude remote-control` (server mode) or Desktop/IDE hosts; they now list and reach Remote Control peers
- Fixed `ListAgents` and `SendMessage` exposing the idle worker that the agent view pre-warms for your next background session; it now appears only once a task claims it

[​](#2-1-237)

2.1.237

August 20, 2026

- Fixed prompt caching for sessions using an LLM gateway or custom base URL
- Added a built-in “Concise” output style: Claude leads with results and skips preamble and narration, while doing the work just as thoroughly. Select it under Output style in /config.

[​](#2-1-236)

2.1.236

August 19, 2026

**Added**

- Added `ANTHROPIC_DEFAULT_MODEL` environment variable: sets the model new sessions start on, while a `/model` pick still overrides it and persists across restarts (unlike `ANTHROPIC_MODEL`)
- Added `notify_when_idle` to cross-session `SendMessage`: ask another Claude Code session on this machine to send one notice when it next goes idle — opt-in, one-shot, no polling (macOS and Linux)
- \[VSCode\] Added screen reader support for the transcript: live announcements for replies, permission requests, errors, and status changes, plus per-turn heading navigation

**Changed**

- Sandbox: on macOS, wildcard read-deny rules (e.g. `**/.env`) now take precedence inside allowed read regions, cover matched directories’ contents, and can’t be bypassed by renaming the denied file
- Changed the `/model` picker to highlight only the newest model’s name, so the highlight marks the new release rather than an arbitrary subset of the list
- `/goal`: an idle session whose goal is parked behind long-running background work now checks in automatically after 30 minutes (then 1h, 2h) instead of waiting for you to return
- `/usage` now shows the usage-credits spend row for Team and Enterprise members, and shows a capped row at 0% before anything is spent
- SIGTERM in print/SDK mode no longer records an interrupted turn or synthetic tool denials before exiting; running commands are still terminated and the process still exits with code 143
- Pressing Enter on a slash-command typo or a command unavailable in this session now reports it instead of running the closest fuzzy match; prefixes and aliases still run
- Remote Control now marks a session offline within seconds when the CLI exits or its terminal closes
- `SendMessage` now refuses further messages to a session up front once a rapid burst would exceed what that session’s inbox accepts, instead of reporting them sent while they were dropped
- Aligned the session title chip on the prompt border with the footer’s right edge
- Right-aligned footer items (goal indicator, session state, background agent status) and truncated notices now share a consistent right margin with the rest of the prompt area

**Improved**

- Improved startup performance: the session counter is now written in the background
- Improved auto mode: `Monitor` allow rules are now set aside while auto mode is active, so Monitor commands are reviewed the same way Bash commands are
- Improved auto mode on Bedrock, Vertex AI, and Foundry, and when telemetry is disabled: the classifier now uses the same defaults as on the Claude API, including severity-scored classification
- Improved auto mode: the git status check can no longer be fooled by a repo’s `status.showUntrackedFiles=no` setting into reporting a clean tree

Show 16 bug fixes

- Fixed clipboard copy, background housekeeping, background sessions, and local MCP logs breaking after the directory a session had switched into was removed (since 2.1.229)
- Fixed the fullscreen renderer failing permanently after a single failed start: it now falls back to the classic renderer instead of exiting on every subsequent launch
- Fixed the `/model` picker rendering taller than the terminal: it now shows only as many models as fit the window, with the rest reachable by scrolling
- Fixed `SendMessage` calls being rejected when a malformed closing tag left the message text inside the summary field
- Fixed unhandled promise rejections when a subprocess fails to start, for example `powershell.exe` on WSL with Windows interop disabled (regression in 2.1.234)
- Fixed fullscreen mode sometimes not showing a newly sent message until the next update after the terminal was resized
- Fixed a blank band that could remain above the prompt after clearing a multi-line prompt, and panes not repainting after resizing the terminal away and back, in fullscreen mode
- Fixed the managed-settings approval prompt sometimes not appearing at startup while still capturing the first keypress as approval
- Fixed terminal tab titles jumping in tmux (iTerm tmux integration): the title is now written only when its text changes instead of animating every 960ms
- Fixed an unclear error when the cloud environments list came back empty or malformed
- Fixed the Fable 5 first-time usage-credits prompt auto-selecting the fallback model after 60 seconds with no answer when using Remote Control
- Fixed spinner tips never appearing, with a repeated background error, when the cached guest-pass reward in `~/.claude.json` was malformed
- Fixed skills hot-reload in SDK/VS Code sessions raising an error on every skills change after the session’s working directory was deleted (2.1.229+)
- Fixed self-hosted runner sessions released on idle, retire, or startup timeout occasionally resuming on another runner before the post-session hook had finished
- Fixed the Clawd mascot’s eyes and feet rendering unevenly in iTerm2 at some font sizes
- Fixed occasional runaway session recaps: recap text (automatic and `/recap`) is now capped at 400 characters, cut at a word boundary

[​](#2-1-235)

2.1.235

August 18, 2026

**Added**

- Added an optional `spellcheck` setting that underlines misspelled words in the prompt input as you type, using your installed `aspell`, `hunspell`, or `ispell`

**Changed**

- Vim mode: NORMAL mode and cursor position are now preserved when toggling the detailed transcript (ctrl+o) or closing a panel
- Dialogs: arrow keys and Enter pressed in quick succession now select the option you navigated to instead of the previously highlighted one
- `SendMessage` now refuses messages too large for cross-session delivery up front instead of silently dropping them
- Remote Control: `claude rc` now applies the same enterprise-gateway availability check as interactive startup

**Improved**

- Improved memory and CPU usage while cloud sessions such as `/ultrareview` or `/autofix-pr` run in the background — their event streams are no longer re-scanned and re-rendered on every update
- Improved permission dialogs: display text and “don’t ask again” options now always match what a grant would cover, and “don’t ask again” is withheld when contents cannot be fully displayed
- Improved the embedded `grep` in native macOS/Linux builds: pathological patterns now fail fast instead of exhausting memory, and `-m N` with `-A/-C` prints correct context
- Improved the context-limit error to say when auto-compact is off and point to `/config` to re-enable it

Show 10 bug fixes

- Fixed whole-prompt-cache invalidation when a language server disconnected or reconnected mid-session
- Fixed nested markdown list items misaligning at depth 3+ and added a hanging indent to wrapped list items in the terminal UI
- Fixed prompt input highlights (slash commands, keywords, mentions) appearing shifted by one or more characters in some multi-line prompts
- Fixed Shift+Tab inside the permission prompt’s comment field approving the edit and granting session-wide edit permission instead of closing the field
- Fixed the Agent tool advertising a general-purpose default in sessions where that agent is unavailable: an omitted `subagent_type` there now gets a clear error listing the available agents
- Fixed notebook cell delete/replace approval dialogs silently omitting the existing cell content when the notebook or cell could not be read; the dialog now says why
- Fixed slash commands run while Claude is responding showing HTML entities instead of the actual characters
- Fixed the prompt footer not showing the “Update installed” restart notice after a background auto-update
- Fixed the expanded task list (`ctrl+t`) always starting collapsed when resuming or relaunching into a session that still has open tasks
- \[VSCode\] Fixed focus jumping between open Claude tabs on its own when a window with several Claude panels is restored or reloaded

[​](#2-1-234)

2.1.234

August 17, 2026

**Added**

- Added the optional `CLAUDE_CODE_PROJECT_DIR_NAME` environment variable: hosts that give each session its own config directory can choose a short name for the per-project transcript directory
- Added the `selection:clear` keybinding action, so a key can be bound to clear an in-app text selection; also works in the agents view
- Added a GitLab merge request badge to the footer and statusline: repos with a GitLab remote and an authenticated glab CLI show MR !N with draft/pending/green states

**Changed**

- Claude Code now continues your session automatically when a claude.ai usage limit resets; turn it off in `/config` (“Continue automatically at usage limit”)
- Claude is now told to use your account email only to identify you, and not to send it to unrelated services unless you ask
- Security: remote file reads, session restore, CLAUDE.md includes, workflow scripts and file uploads now reject Windows NT-namespace (`\??\`) paths, hardening the remaining pre-approval file accesses against the NTLM credential-leak vector
- Remote Control: signing this computer in to a different claude.ai account or organization now stops the running session within seconds and says why, instead of a misleading HTTP 404 hours later
- Remote Control sessions started from Claude Code Desktop or VS Code now keep phones and claude.ai/code updated on the session’s permission mode (and claude.ai/code on the model) as they change
- Remote Control: effort picks made on a phone or on claude.ai/code now apply to terminal- and Desktop/VS Code-hosted sessions, and the session publishes its effort level to connected clients
- `SendMessage` and `ListAgents` now say when your account’s session list was too long to check completely, instead of treating unseen sessions as absent
- Expired Anthropic profile credential now points you at `/login` when a claude.ai login would take precedence
- Reduced the context cost of loading the built-in `claude-api` skill from ~200k+ tokens to ~25k by loading reference docs on demand
- `/permissions` can now be opened while Claude is working — rule changes apply to the rest of the current turn
- `/add-dir <path>` can now be used while Claude is working; `/add-dir`, `/autocompact`, `/theme`, `/help`, `/config` and `/advisor` dialogs open mid-turn in the fullscreen TUI
- `/goal` now clears itself with a notice when a turn dies on an unrecoverable error (e.g. revoked auth, an exhausted credit balance, or a context overflow) instead of staying armed
- `/goal`: when background tasks keep a goal waiting for 30+ minutes, Claude now checks in on them instead of waiting indefinitely (set `CLAUDE_CODE_GOAL_CHECKIN_MINUTES=0` to opt out)
- `claude setup-token` now rejects unexpected extra arguments instead of silently ignoring them
- Changed Esc in fullscreen mode to no longer clear a mouse text selection: it interrupts or dismisses as usual and the selection stays highlighted
- Removed the redundant “Allowed by auto mode classifier” line that auto mode showed under every Agent tool call
- Removed the “Default teammate model” setting from `/config`; agent-team teammates now use the leader’s model unless the spawn names one
- Dimmed the elapsed-time counter on the running tool header so it no longer competes with the bold counts
- Background task notifications delivered between turns are now sent to the model inside `<system-reminder>` tags, matching mid-turn delivery
- Mantle: skip the admin-pin availability probe at startup when a main-loop model is already picked
- Windows: startup no longer stalls on repeated rename retries when `~/.claude.json` is read-only

**Improved**

- Improved the transcript: your own prompts now render markdown (highlighted code blocks, inline code, lists) the same way replies do
- Improved the “API returned an empty or malformed response” error to say what came back (content type, body kind, size, request ID) and why the original streaming request failed
- Improved auto-generated session titles to read as short, specific names (e.g. “Login button bug”) rather than sentences restating your request (e.g. “Fix the login button on mobile”)

Show 24 bug fixes

- Fixed auto mode in very long sessions repeatedly re-checking and denying sandboxed commands’ network access after the conversation had been compacted
- Fixed session-scoped permission answers (including denies) being dropped when answering background subagent tool permission prompts
- Fixed a crash when an API response on the non-streaming fallback path (typically via third-party gateways) contained a thinking block missing its thinking field or a text block missing its text field
- Fixed markdown rendering becoming extremely slow for some messages containing unusual Unicode sequences
- Fixed `SendMessage` rejecting a recipient copied from `ListAgents` when the session name is at the 200-character cap or emoji-heavy
- Fixed repository detection mis-reading the host of git remotes with unusual userinfo, producing links and repo-specific behavior for the wrong host
- Fixed MCP diagnostics printing resolved secrets: scope-conflict warnings now show the configured `${VAR}` form, and connection-failure details show only the server origin
- Fixed `strictKnownMarketplaces` allowlists accepting SCP-style git marketplace sources whose host differs from the one git would actually connect to
- Fixed modal text such as the `/login` OAuth URL losing characters when copied in fullscreen
- Fixed a `---` horizontal rule in rendered markdown running into the line after it
- Fixed consecutive shell commands splitting into multiple “Ran 1 shell command” rows when todo/task updates were interleaved between them
- Fixed dialogs like `/permissions` opened while a `!` shell command was running being dismissed when the command finished
- Fixed a queued `!` shell command being sent to the model as plain text after pressing up-arrow to edit the queued input
- Fixed queued messages reappearing in the prompt history while still queued, Esc while selecting a queued message no longer interrupts the turn, and `!` mode no longer sticks after a mid-turn submit
- Fixed accepting the “Try the new fullscreen renderer?” prompt restarting the session without its permission mode (e.g. `--dangerously-skip-permissions`), tool allow/deny rules, model or effort flags
- Fixed `/tui` dropping launch `--allowed-tools`/`--disallowed-tools` rules when it restarts; it now declines to switch, with the reason, when the session has restrictions a restart can’t carry over
- Fixed trust prompts omitting the repository-wide scope warning when the directory was first seen before the repository existed there
- Fixed a case where an IDE diff tab closing during a permission re-prompt could answer the new prompt with the previous input
- Fixed: files sent to the user during Remote Control sessions hosted by Claude Code Desktop or VS Code now upload, so they open on phone and web instead of showing an empty card
- Fixed: after `/login` while `CLAUDE_CODE_OAUTH_TOKEN` is set, the stale-token reminder no longer leaks into Claude’s automatically resumed turn — it now appears only to you
- Fixed: permission previews now relay only to channel servers admitted by the inbound trust gate, and a server’s explicit permission-capability opt-out is honored
- Fixed: credential masking on relayed permission previews can no longer hide commands, paths, or destinations from the approver; oversized private-key blocks now redact under full-strength redaction
- Fixed: provider API tokens that mask on permission previews now mask even when directly followed by shell delimiters
- Fixed Claude Desktop inter-session messages being silently dropped by the recipient session when cross-session messaging read as disabled, which left the sender’s query “thinking” for many minutes

[​](#2-1-233)

2.1.233

August 14, 2026

**Added**

- Added GitLab merge request URL support to the `--worktree` flag and the `claude agents` view (where MRs display as `!N`)
- Added an opt-in `forward_user_identity` apps gateway setting on Anthropic upstreams that sends the signed-in user’s identity as headers, so a proxy behind the gateway can attribute spend per user
- Added opt-in memory cgroup support for Bash tool commands on Linux (`CLAUDE_CODE_TOOL_MEMORY_LIMIT`) so a runaway build can’t stall the session
- Added `CLAUDE_CODE_WEBFETCH_CACHE_TTL_MS` environment variable to configure the WebFetch session URL cache TTL (default unchanged: 15 minutes)

**Changed**

- Changed the GitHub app setup tip to no longer appear in repositories whose origin remote is on gitlab.com or bitbucket.org; the enterprise marketplace tip now covers non-GitHub internal git hosts
- Todo/task-tracking tools (TaskCreate/Get/Update/List, TodoWrite) are no longer available on Opus 4.8, Sonnet 5, Fable 5, Mythos 5, and newer models; set `CLAUDE_CODE_ENABLE_TODO_TOOLS=1` to bring them back
- Reverted the 2.1.232 Bash permission changes for Cygwin-style symlinks on Windows and for input redirections (`< file`); a narrower version will return in a later release

Show 5 improvements

- Improved `claude self-hosted-runner` session start time: the session branch is now created without rewriting the working tree, and two server round trips no longer block the agent’s launch
- Improved apps gateway error forwarding: 400/413 errors from Vertex, Foundry, and Claude Platform on AWS upstreams now carry the upstream’s own message; fixes a bug with auto-compact on apps gateway
- Improved `claude plugin validate` to check a bare `.claude/skills` directory, reporting SKILL.md files whose frontmatter fails to parse
- Improved screen reader mode: the `/effort` selector renders as a numbered list with a typed-number prompt, and hint and dialog text is no longer clipped
- Improved print mode diagnostics: a `[claude-code:unrecognized_model]` line is written to stderr when a request goes out for a model ID Claude Code doesn’t recognize; map it with `modelOverrides` to silence

Show 8 bug fixes

- Fixed cloud sessions occasionally being marked as lost when the environment shut down while Claude was waiting on a permission prompt
- Fixed MCP v2 connections endlessly reopening the subscriptions/listen stream against servers that terminate long-held streams on a fixed timeout (e.g. serverless hosts)
- Fixed Notification hooks not firing for permission prompts when running under Claude Desktop or VS Code
- Fixed idle sessions on Linux sometimes keeping one CPU core at 100% when sandboxing is enabled
- Fixed bundled skill aliases like `/checkup` and `/review` reporting “Unknown command” in `-p` mode or with plugins/MCP loaded when a user or project skill shadows the bundled skill
- Fixed skill/command argument substitution to prevent argument values from being re-expanded as template markers
- Fixed Windows paths spelled with the NT `\??\` device prefix bypassing UNC path validation, closing an NTLM credential-leak vector
- Windows: fixed auto mode repeatedly stopping for manual approval on ordinary `cd <dir> && <command> > file` Bash commands (a 2.1.232 regression)

[​](#2-1-232)

2.1.232

August 13, 2026

**Added**

- Added `/config` rows for “Dialog expiry” and “Messages from your other sessions” (cross-session inbound accept/hold/refuse)
- Added secret redaction for GitLab token families (`glrt-`, `gloas-`, `glptt-`, `glagent-`, `glimt-`, `glsoat-`, `glcbt-`, `glft-`, `glffct-`) and full redaction of routable `glpat-`/`gldt-` tokens; the `glab` CLI config store gets the same sandbox and credential-path protection as `gh`
- Added GitLab support to plugin marketplaces: bare `gitlab.com` repo URLs (including nested subgroups) now clone like `github.com` URLs, and clone auth-failure hints name your actual git host

**Changed**

- Subagent forking is now on by default: a `subagent_type: "fork"` subagent inherits the full conversation and prompt cache, and non-teammate agent spawns in interactive sessions now run in the background by default
- Type `@` in the prompt to mention another Claude session by name; Claude then uses `SendMessage` to reach that session directly
- `SendMessage` now delivers to a bare name that exactly matches one live session, instead of asking to confirm with a ref first
- Interactive sessions on one machine now keep unique names: starting or renaming a session to a name another live session already uses gives it a `name-word-word` variant and tells you
- Settings: `additionalMarketplaces` and `allowedMarketplaces` are now accepted as friendlier aliases for `extraKnownMarketplaces` and `strictKnownMarketplaces`
- Enterprise policy: a url-typed `blockedMarketplaces` entry for a bare repo URL keeps blocking that URL when the CLI classifies it as a git clone
- Gateway: the `desktop:` overlay now accepts every released Desktop setting (was 11 hand-listed keys), validated at boot against Desktop’s own schema; unknown or invalid keys fail boot
- Gateway: empty `managed.policies[].match.groups`/`admin.admin_groups` entries and malformed `email_domain` values (empty, or containing `@`, whitespace, or commas) now fail at boot instead of silently matching no one or granting admin access
- Fable 5 is offered as an advisor in `/advisor` again for organizations with Fable access, with usage-credits consent set up through `/model fable`
- Remote Control: resuming a conversation whose session was deleted from claude.ai or the app now starts a replacement instead of failing with a message about your login (regressed in v2.1.227)
- `/feedback` and `/bug` now open immediately when invoked while Claude is responding, instead of waiting for the turn to finish
- `/plugin install plugin@marketplace` now refreshes the marketplace first, so newly published plugins install without a manual marketplace update
- `/code-review` at high, xhigh, and max effort now runs in a background agent like the other levels
- Pasted and clipboard images are read without blocking the event loop
- Remote Control now keeps reconnecting for about 30 minutes after a network blip and no longer drops after a few blips spread across an hour
- Remote Control: resuming a conversation no longer silently takes Remote Control away from another Claude Code on the same machine that still has it; run `/remote-control` there to move it
- Updated agent panel: completed subagents hide immediately with a `/tasks` footer hint, and the ”↓ N more” overflow indicator moved left for visibility
- Remote Control: the terminal now says whether a session was taken over by another device, ended from another app, or deleted, and stops suggesting a reconnect that would undo it
- Bash input redirections (`< file`) are now permission-checked like their argument spellings on all platforms
- Shortened the message shown when resuming a completed background agent
- Cowork sessions no longer inline external @-imports from user-scope memory files
- Hardened the auto-generated cross-session messaging socket directory on shared `/tmp`: a pre-planted symlink or another user’s directory is now refused instead of used
- Hardened the Linux filesystem sandbox against a protected-path bypass
- Changed `sandbox.ripgrep` to be honored only from user, managed, and `--settings` settings; project settings can no longer override the sandbox’s ripgrep binary
- Removed the startup tip suggesting you create custom subagents, and the matching nudge in the `/powerup` tour

**Improved**

- Improved fullscreen streaming: long sessions stay responsive because the whole conversation is no longer re-normalized on every update
- Improved the managed settings approval dialog: shows endpoint URLs, uses clearer wording for telemetry-only changes, skips routine OpenTelemetry options, and requires approval for server-managed sandbox binary overrides (`sandbox.bwrapPath`, `sandbox.socatPath`, `sandbox.ripgrep`)

Show 19 bug fixes

- Fixed a PowerShell permission bypass where variable-writing parameters could silently overwrite `$PSDefaultParameterValues` and redirect later commands’ file access
- Fixed a Windows permission bypass where Git Bash followed Cygwin-style symlinks that path validation saw as regular files; writes through them now require permission approval
- Fixed nested git repositories inheriting trust from a parent directory; each repository now requires its own trust confirmation
- Fixed MCP connections hanging for the full 30-second connect timeout when a server fails to answer or sends a malformed reply to the protocol-version probe
- Fixed Remote Control sessions hosted by a bridge inside a cloud session inheriting that session’s transcript or credentials
- Fixed Remote Control sessions started from Claude Desktop or an IDE appearing as a new claude.ai session each time the local session was resumed; they now reattach to the existing one
- Fixed Remote Control sessions appearing unreachable to newly attached clients while idle
- Fixed Remote Control bridge sessions not restoring conversation history when the session worker restarts
- Fixed Cloud gateway `/login` exiting silently or leaving an unresponsive terminal after “Press Enter to continue” when managed settings failed to load; the reason is now shown
- Fixed voice mode on native builds getting stuck on “listening…” when the voice service rejected the connection; the rejection is now shown immediately
- Fixed mTLS client certificate rotation requiring a restart; Claude Code now reloads the rotated cert and key automatically on connection errors
- Fixed malformed AWS or Vertex region values being used to build request URLs; they now fall back to the default region
- Fixed stream idle timeout errors failing the request instead of recovering on Bedrock, Vertex, and gateway deployments
- Fixed content-sized overlays containing truncated text rendering one column too wide, and start-truncated text collapsing to an ellipsis
- Fixed a stray garbled character where a long shell-command or agent-description preview was cut off mid-emoji
- Fixed a startup race that could silently unregister a plugin marketplace due to concurrent writes to `known_marketplaces.json`
- Fixed `/update` and `/tui` refusing to restart while work that survives the relaunch was running
- Fixed usage-limit guidance suggesting unavailable slash commands in SDK and remote sessions
- Fixed the consent message for interactive `--advisor fable` launches, which told you to run `/model fable` in an interactive session that had just exited

[​](#2-1-231)

2.1.231

August 13, 2026

- Fixed MCP OAuth sign-in failing with a redirect URI mismatch for servers that use a pre-registered OAuth client, such as Slack

[​](#2-1-229)

2.1.229

August 12, 2026

**Added**

- Added server-supplied Claude Code hook support for self-hosted runner sessions, matching managed-environment behavior
- Added SSE keepalive pings to gateway streaming responses during long thinking pauses, preventing idle-timeout disconnects on Vertex and Bedrock upstreams
- Added plugin marketplace `command` sources: a local command (e.g. an IDE) prints the plugin directory, which is re-resolved each session and applied without a restart; `mode: "link"` uses it in place
- \[VSCode\] Added session groups in the sidebar — right-click to create, rename, or delete; Cmd/Ctrl- or Shift-click to move several sessions at once

**Changed**

- Documented `claude remote-control --continue` for resuming the most recent Remote Control session
- `ListAgents` now marks disconnected Remote Control sessions as `offline` and labels your cloud sessions as `cloud`
- Updated `/login` to repeat the `CLAUDE_CODE_OAUTH_TOKEN` override warning after a successful login
- Changed `/commit-push-pr` so git/gh commands with dangerous flags (`--force`, `--amend`, `--no-verify`, etc.) are no longer auto-approved
- Changed self-hosted runner Windows startup to require an explicit `--base-dir`; there is no default checkout directory on Windows
- \[VSCode\] “Report a problem” and `/bug` now open the built-in feedback dialog instead of a retired survey link
- \[VSCode\] Made the `/btw` side-question panel resizable by dragging its boundary, in both side-docked and stacked layouts

**Improved**

- Improved workflow fan-outs to stagger same-prefix sibling agents so subsequent agents read the cached prompt prefix instead of re-paying it (`CLAUDE_CODE_WORKFLOW_PREFIX_STAGGER_MS=0` disables)
- Improved “prompt is too long” errors to explain why automatic compaction could not recover instead of only suggesting `/compact`
- Improved sandbox: IPv6 literals in network domain lists are now bracketed (`[::1]:443`), and ambiguous spellings are enforced fail-closed and flagged by `/doctor`

Show 18 bug fixes

- Fixed long responses partly disappearing while streaming and being printed twice in the terminal
- Fixed a crash to the error screen (including on `--resume` of the affected session) when a tool call had a non-string `glob`, `file_path`, or `command` value
- Fixed a RangeError crash when a progress bar or markdown table rendered in a very narrow terminal window (could also crash `claude --continue`/`--resume` at startup)
- Fixed a crash on Windows when a tool call or message referenced a file by an extended-length (`\\?\`) or UNC path
- Fixed auto mode failing on every tool call for users who disable the attribution header via `CLAUDE_CODE_ATTRIBUTION_HEADER` (direct Anthropic API connections)
- Fixed `/model` rejecting Sonnet/Opus 1M for claude.ai subscribers using a custom `ANTHROPIC_BASE_URL` gateway
- Fixed MCP OAuth with strict authorization servers by using `127.0.0.1` instead of `localhost` in the redirect URI
- Fixed Remote Control clients showing a stuck working spinner after a slash command typed in the laptop terminal
- Fixed the Claude Code Review workflow generated by `/install-github-app` completing without posting its review on the pull request
- Fixed multi-second UI stalls after editing a file with thousands of IDE diagnostics while the IDE extension is connected
- Fixed one-shot `claude plugin` commands leaving a stray liveness file that could prevent cleanup of outdated plugin versions
- Fixed dynamic workflows inside CPU-limited containers using the host machine’s core count instead of the container’s CPU limit
- Fixed a file-watcher handle leak after atomic file replacements, and an uncaught error on Windows when the scheduled-tasks watcher failed on a network or virtual filesystem
- Fixed SDK and `--input-format stream-json` sessions getting a 400 API error when a whitespace-only message was submitted
- Fixed conversations whose messages alone exceed the API’s 32 MB request limit retrying compaction when no images or documents can be stripped; they now fail once with a clear message
- Fixed OpenTelemetry export from Claude Desktop sessions being rejected by the Desktop-managed gateway when that gateway is also the telemetry endpoint
- Fixed self-hosted runner and other remote sessions exiting at startup when `managed-mcp.json` is deployed and the server delivers MCP servers; those servers are now skipped with a warning
- Fixed self-hosted runner repository preparation hanging on a Git Credential Manager prompt; git now fails fast when credentials are missing

[​](#2-1-228)

2.1.228

August 11, 2026

**Changed**

- Hardened skills synced from claude.ai: they no longer shadow local commands or MCP prompts, their descriptions are sanitized and labeled, and on your machine their bodies don’t run `!` commands or expand `@` files
- Updated terminal title busy-spinner glyphs to reduce tab-bar jitter on some terminals
- Changed the Write tool so newer models can overwrite an existing file they haven’t read this session, matching the Edit tool’s rules; older models still require the read first
- Removed the outdated note about auto mode sessions costing slightly more from the first-use notice for Pro, Max, and Team plans

**Improved**

- Improved cross-session messages: the sender and body now display inline instead of a collapsed line, and messages to Remote Control sessions on other machines show your Remote Control session name as the sender
- Improved Vertex AI credential handling: expired or missing Google Cloud credentials now fail within seconds instead of retrying for minutes
- Improved compaction progress: the retry countdown and stall hint now appear during compaction instead of only a progress bar

Show 11 bug fixes

- Fixed interactive sessions that could stop redrawing entirely, while the process kept running, after a rare internal layout error
- Fixed `git` / Git Bash not being found on Windows when Claude Code is launched from a parent folder of the git installation
- Fixed `/tui` reverting the session to an earlier model when `/model` had been changed since the last response
- Fixed cross-session messaging sometimes starting without an inbox in the first session after install or upgrade
- Fixed Remote Control `/resume` while connected leaking the resumed conversation’s title or history into the connected session
- Fixed `claude self-hosted-runner` sessions failing on every fresh runner when the `checkout` hook fails for a repository the session doesn’t push to; that repository is now skipped with a warning
- Fixed self-hosted runners ending sessions in the gap between a background task finishing and the follow-up turn starting
- Fixed session cleanup deleting contents inside a project’s memory folder
- Fixed background plugin-cache cleanup deleting a plugin’s cache when its only version is a symlinked development checkout
- Fixed a settings-merge issue where a marketplace entry redefined in a higher-precedence settings tier could inherit another tier’s custom headers; marketplace entries now merge as whole entries
- Fixed the deferred-tools reminder occasionally being sent to the model twice after a skill invocation

[​](#2-1-227)

2.1.227

August 10, 2026

- Fixed feature flags being evaluated without the user’s subscription tier when a session started with an expired login token, which could wrongly prompt Max plan users to enable usage credits for Fable
- Fixed every Bash command failing under `claude-code-action` with `allowed_non_write_users` on GitHub-hosted runners
- Fixed `/tui` bringing back a conversation that had been rewound to before its first message
- Improved slash-command menu: blue now marks only the selected row, matched characters are bolded instead of recolored, and emoji or accented names keep their glyphs
- Improved performance: fewer event-loop stalls on file-not-found suggestions and at-mention size checks

[​](#2-1-226)

2.1.226

August 8, 2026

- Bug fixes and reliability improvements

[​](#2-1-225)

2.1.225

August 8, 2026

**Added**

- Added gateway spend-limit support to Claude Code’s usage warning; the limit-reached message now names the cap, its reset time, and the operator’s message (requires the gateway on 2.1.225)
- Added a workspace trust prompt to `claude agents` for untrusted directories, matching the behavior of `claude`

**Changed**

- SendMessage can now start a conversation with your Remote Control sessions on other machines by name (`ListAgents` shows them as `name [ref]`), instead of only replying after they message you first
- SendMessage: a Remote Control recipient you already confirmed is never swapped for a same-named session on this machine when its own list couldn’t be checked

**Improved**

- Improved Remote Control: photos attached from the Claude app are now shown to Claude directly instead of being read from disk with a separate tool call

Show 9 bug fixes

- Fixed a transient 401 replacing a long-lived `CLAUDE_CODE_OAUTH_TOKEN` with a stored login’s short-lived token, breaking headless sessions until restart
- Fixed MCP OAuth servers on macOS intermittently failing with a burst of 401 errors, as if never authenticated, after a keychain read timed out
- Fixed auto mode counting a safety-filter refusal of its own permission check toward the consecutive-block limit; the action is still denied, but the model is now told to move on rather than retry
- Fixed cross-session messages staying parked without a notice or expiry in headless sessions and during startup
- Fixed conversation history breaking on Remote Control session resume after very large conversations were compacted
- Fixed hovering over a session in another project in the agents list changing the directory the next agent starts in
- Fixed `claude self-hosted-runner` registering and then failing every session when `--base-dir` cannot be created or written; it now exits at startup with a clear error
- Fixed Claude Code on the web sessions being misreported as stuck, re-sending a growing event backlog on every reconnect
- \[VSCode\] Fixed Focus view folding away the latest to-do list, a pending question’s context, and settled answers; thinking-only folds show “Thought for Ns” and re-collapse when their turn completes

[​](#2-1-224)

2.1.224

August 7, 2026

**Added**

- Added self-hosted environments: `claude self-hosted-runner` turns your own machines or containers into a place Claude Code web, mobile, and desktop sessions can run, on Team and Enterprise plans
- Added `archive` plugin source: install plugins from a zip over HTTPS without git or npm, with optional SHA-256 pinning
- Added a cancel-and-confirm step when removing an unavailable paste changes a command’s text
- Added `ANTHROPIC_BEDROCK_REGION_PREFIX` env var for Bedrock to prefer a specific cross-region inference profile over the `AWS_REGION`-derived one
- Added `crossSessionInbound` and `dialogExpiry` settings: cross-session messages sent to a session running with bypassed permissions are held for your approval, and messages to other sessions auto-deliver
- Added sandbox credential-masking options: `extract` and `onExtractNoMatch` for structured env values, `decode: "jwt"` with `maskClaims` for JWT-aware masking, and `awsPairs`/`sigv4` for AWS SigV4 re-signing; these need `network.tlsTerminate` and are honored only from user, managed, or `--settings` settings
- Added cross-session `SendMessage`: Claude Code sessions can now message each other, on any of your machines, with `ListAgents` to discover them (macOS and Linux)

**Changed**

- Removed the 200-subagent-per-session spawn cap; long-running sessions no longer refuse new agents (concurrency and depth limits still apply)
- Changed managed settings: the approval prompt no longer re-appears after re-login or org switching when the organization’s settings are unchanged
- Changed the feedback-survey transcript share: with your consent it now also uploads the last request’s model settings — the system prompt (which includes your `CLAUDE.md` instructions), tool definitions, and model parameters. Secrets are redacted as before, and these fields are dropped first if the share is too large
- Changed the Bash tool description to always note that command output is displayed to the model, not reliably to the user
- Changed recalled paste placeholder numbers to renumber when accepted into the input
- Changed Remote Control to archive the stale server session instead of leaving a dead one listed when a fresh session is minted after compaction or `/resume`

**Improved**

- Improved fullscreen mode to keep the full pre-compaction history in scrollback across repeated compactions, instead of only the most recent interval
- Improved Remote Control: attached web and mobile clients now see compaction progress and the post-compaction boundary instead of a silent pause; `/clear` resets now propagate to attached clients
- Improved Remote Control: connection failures now show a persistent failure indicator with details and a reconnect shortcut, instead of only an 8-second toast

Show 15 bug fixes

- Fixed long (\>200 char) project paths resolving to another project’s session directory under a shared sanitized prefix; session list, rename, fork, delete and `/resume` no longer cross projects
- Fixed `SendMessage` reporting “Message sent” when the write to a teammate’s inbox had actually failed; failed deliveries are now reported as errors
- Fixed sandbox filesystem deny entries written with a trailing slash (e.g. `denyRead: "~/.aws/"`) being silently bypassable on Linux and macOS
- Fixed sandbox violation details never appearing in Bash tool results; Claude now sees which file or network access was denied and why
- Fixed MCP tools that connect mid-turn being deferred for tool search without their names announced to the model
- Fixed plugin install records being silently corrupted when the same plugin is installed in multiple projects
- Fixed recalled or restored paste content occasionally attaching wrong data or silently losing text when the paste had aged out or placeholder numbers collided
- Fixed copy-on-select on Wayland sometimes not reaching the clipboard; the two selection writes no longer race
- Fixed the feedback survey’s transcript share silently failing on long sessions; a failed share now shows an error instead of a success message
- Fixed Remote Control auto-start intermittently failing with “Remote credentials fetch failed” on a cold start with a stale login token
- Fixed Remote Control and SDK clients showing a blank “(no content)” message after `/clear` and other output-less commands
- Fixed a Remote Control session recreated after its server session expired uploading prior local conversation history into the new session
- \[VSCode\] Fixed the extension showing Remote Control as connected after the connection failed
- Fixed a session resume silently reconnecting Remote Control after the user turned it off (`--resume`, SDK hosts, and the VS Code extension)
- \[VSCode\] Fixed sessions not honoring `remoteControlAtStartup` when explicitly enabled

[​](#2-1-223)

2.1.223

August 6, 2026

**Added**

- Added owner wildcard entries (`"owner/*"`) to the `strictKnownMarketplaces` and `blockedMarketplaces` managed settings for allowing or blocking all marketplace repos under a GitHub org
- Added a warning when workflow agents, forked skills, slash commands, or resumed background agents’ requested subagent model is restricted and the parent model runs instead
- Added a `/teleport` hint in cloud sessions showing how to continue locally with `claude --teleport <session id>`

**Changed**

- Changed `CLAUDE_CODE_DISABLE_1M_CONTEXT` to hold every Claude model with a native 1M window to 200K via auto-compaction, not just a fixed list; a startup warning now appears when auto-compaction isn’t holding the session to 200K
- Changed auto-compact to keep sessions on unrecognized model IDs within the assumed context window instead of letting them grow past it; set `CLAUDE_CODE_DISABLE_UNKNOWN_MODEL_WINDOW_ENFORCEMENT=1` to restore the previous behavior
- Changed `/review` to be an alias of `/code-review`, which reviews the current diff or a PR (`/code-review <level> <pr#>`); use `/code-review ultra` for a deep cloud review
- Changed `/code-review` with no effort level to reuse the level you typed last; type a level like `/code-review high` to change it

Show 12 bug fixes

- Fixed a Bash permission bypass where a crafted command could hide parts of itself from permission checks
- Fixed permission prompts so commands padded with tabs or invisible Unicode can no longer hide part of the command from the approval dialog
- Fixed workflow scripts being able to use dynamic `import()` to run code outside the workflow sandbox
- Fixed a permission gap where an agent definition’s `bypassPermissions` mode ignored the org bypass-permissions disable policy
- Fixed resuming a session after a mid-session `/cd` coming back empty
- Fixed gateway model discovery hiding Claude models registered under provider-prefixed IDs such as `vertex_ai/claude-*` or `bedrock/anthropic.claude-*`
- Fixed `modelOverrides` keys that aren’t Anthropic model IDs being treated as the session’s canonical model ID; unknown keys are now ignored as documented
- Fixed managed settings: server-delivered settings no longer disable the env block of a machine-local `managed-settings.json` or MDM profile; admin env now merges per key
- Fixed sandboxed commands failing to start on Linux when `sandbox.filesystem.denyWrite` covers the working directory
- Fixed forked background agents getting stuck “already resuming” for the rest of the session when rebuilding the fork’s parent prompt failed during resume
- Fixed a resumed session failing every turn, or leaving the interactive app on an unresponsive error screen, when its history held a malformed diagnostics attachment
- Fixed a rare hang when parsing unusual `git push` output

[​](#2-1-222)

2.1.222

August 4, 2026

**Changed**

- Changed Remote Control auto-start so repo-local settings (`.claude/settings.json` or `.claude/settings.local.json`) can no longer turn it on (they can still turn it off); enable it at user scope via `/config`
- Removed ultraplan feature

**Improved**

- Improved auto mode safety: messages sent to other agent sessions via `SendMessage` are now evaluated by the permission classifier before dispatch
- Improved the refusal when Claude tries to invoke a skill with `disable-model-invocation`: Claude is now told to ask you to run the skill instead of replicating its workflow
- Improved the `/diff` view, the Remote Control workspace diff, and file-edit diffs in Claude Code on the web sessions to use raw git blob content, ignoring workspace-configured diff drivers and textconv

Show 16 bug fixes

- Fixed worktree-isolated sessions and their subagents being able to run destructive git commands against the main checkout; isolation now applies to file edits and Bash in every session type
- Fixed PreToolUse auto-allow hooks bypassing tool restrictions in background agent tasks (summaries, compaction, renames)
- Fixed `/usage-credits` on Team and Enterprise showing “you’ve already sent a usage credit request” for members whose earlier request was dismissed, blocking them from sending a new one
- Fixed the startup connectivity check hanging and then failing behind an HTTPS proxy; it now uses the same proxy-aware transport as API requests and times out with a clear message
- Fixed “Connection closed mid-response” errors being reported on responses that had actually completed
- Fixed `/usage` overattributing usage to MCP servers: a server’s share now reflects only the requests that actually consumed its tool results, instead of every turn after any call to it
- Fixed sessions not linking to pull requests created after the branch was pushed, including through the GitHub REST API
- Fixed org-restricted `model: opus`-style subagent and teammate family aliases dropping to the parent model instead of stepping down to the newest org-allowed model in the family
- Fixed stream idle timeout firing on custom `ANTHROPIC_BASE_URL` gateways despite server keep-alive pings arriving on the wire
- Fixed claude.ai connectors being falsely marked as needing authorization when the session token is invalid — they now show a `/login` hint instead
- Fixed tool errors not being displayed for tools no longer available locally, for example after an MCP server is removed
- Fixed `SendMessage` rejecting a long summary — it now truncates instead, so sends no longer fail on a character limit
- Fixed the spinner’s effort label in a subagent’s transcript view showing the session’s effort level instead of the subagent’s own `effort:` setting
- Fixed rare crashes when a file watcher hit a filesystem error or during file-watcher teardown
- Fixed screen readers re-reading the whole input line on every backspace in `--ax-screen-reader` mode — end-of-line deletions now echo just the deleted characters
- Fixed host model-selection keys not taking precedence over a stale on-disk `managed-settings.json` when `CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST` is set

[​](#2-1-221)

2.1.221

August 4, 2026

**Added**

- \[VSCode\] Added Focus view: a chat-menu toggle that hides tool activity behind an expandable per-turn summary with a live running-tool indicator, toggled with `Ctrl+Alt+F` or the “Claude Code: Toggle Focus view” command
- Added `mode: "mask"` for sandbox credential files on Linux and WSL — sandboxed commands read a sentinel copy (the whole file, or just the spans captured by an `extract` regex) while the sandbox proxy substitutes the real value on egress; on macOS file masking falls back to `deny`
- Added warnings to `claude plugin validate` when a marketplace or plugin name would be rejected by Claude Desktop’s managed marketplace sync
- Added a `prompt-audit` subcommand to the `claude-api` skill for auditing prompts and tool descriptions for patterns written for older models

**Changed**

- Reduced prompt-cache costs for auto-mode permission checks by reusing the cached conversation prefix across decisions
- Changed background sessions to commit and push to preserve work, open a draft PR only when the task calls for one, follow your CLAUDE.md git instructions, and always end by reporting where the work lives
- Changed `/plugin install` to refresh a stale marketplace catalog and retry before reporting a plugin not found
- Changed plugins installed from `/plugin` to activate immediately when safe, instead of always requiring `/reload-plugins`
- Changed plugins to accept `"."` as a `skills` path, and the root-level `SKILL.md` validation error now suggests using the plugin root
- Changed `/status` to show the session kind: `interactive`, or a background job that is `attached` or `unattended`
- Changed emoji autocomplete to accept common alternate shortcodes like `:thumbsup:`, `:thumbsdown:`, and `:love:`
- Changed sessions forked with `/fork` to create a new worktree of their own instead of working in the original session’s checkout
- Changed Claude in Chrome to close the browser tabs it opens once it no longer needs them
- Changed fast mode to report on the stream when usage credits run out mid-session, instead of failing silently
- Changed Monitor: a watch that exits without producing any output now says so instead of reporting “stream ended”
- Changed the Gateway `model` field validation: non-string values are rejected with a 400 instead of being forwarded
- Removed the repeated “Permission mode changed while the auto-mode classifier call was queued” notice from approval prompts

Show 5 improvements

- Improved tool search on Google Vertex AI: re-enabled for Claude 4.5-generation and newer models
- Improved auto mode: permission checks for parallel tool calls are now cache-efficient, and switching modes while a check is pending reliably prompts instead of applying the stale result
- Improved Stats panel to count cache tokens in its token totals, with a breakdown by input, output, cache read, and cache write
- Improved `/ultrareview` error messages when a repo shares no history with its base: a checkout with no branches is now refused up front with advice to create one, and refusal hints no longer suggest `git fetch --unshallow` on clones that are already complete
- Improved Windows startup: process creation times are now read via a native kernel32 call instead of spawning PowerShell, so endpoint security tools that gate `powershell.exe` no longer prompt

Show 17 bug fixes

- Fixed a Bash tool permission-check bypass where zsh could execute hidden commands in `[[ ]]` regex conditionals; affected commands now prompt for permission
- Fixed PowerShell permission checks mishandling paths containing quote characters on Windows; such paths now prompt for approval
- Fixed the thinking toggle having no effect for the rest of a session that started with thinking off; disabling an MCP server mid-connect no longer silently reverts
- Fixed MCP servers from `--mcp-config` not being connected before the first turn in print mode (`-p`), which made the model emit tool calls as literal text
- Fixed @-mentioned files being silently dropped when pressing Esc to retract a prompt and resubmitting it
- Fixed a crash when preparing API requests for SDK MCP tools named after built-in object properties such as `constructor`
- Fixed WebSearch failing with a 400 error at effort `xhigh`/`max` when thinking is disabled
- Fixed sandboxed large uploads failing with TLS errors through the sandbox proxy
- Fixed Team and Enterprise spend-limit message incorrectly blaming the org’s monthly limit instead of your individual spend limit
- Fixed Bedrock authentication with AWS SSO named profiles failing in desktop-managed sessions on Windows machines that set a stray `HOME` environment variable
- Fixed `CLAUDE_CODE_RESUME_INTERRUPTED_TURN=0` not disabling interrupted-turn auto-resume; falsy values are now honored
- Fixed a rare wake-from-sleep race where two Claude Code processes could both refresh the same MCP connector or WIF OAuth token at once, forcing re-authentication
- Fixed renaming a session from Claude Code Desktop or claude.ai not updating the CLI’s session name; session names from every rename surface are now sanitized
- Fixed plugin- and org-delivered skills named after terminal-only built-ins (e.g. `/help`, `/feedback`) being un-invocable in non-interactive sessions
- Fixed the “Plugins changed” notification lingering after plugins were reloaded instead of clearing
- Fixed Vim mode: the yank register now survives dialogs, history search, and the transcript view instead of being silently emptied
- Fixed Vim mode: undoing back to an empty prompt now arms the “press ← again” confirm before returning to the agent view

[​](#2-1-220)

2.1.220

July 25, 2026

- Bug fixes and reliability improvements

[​](#2-1-219)

2.1.219

July 24, 2026

**Added**

- Added Claude Opus 5 (`claude-opus-5`), now the default Opus model — 1M context, fast mode at \$10/\$50 per Mtok
- Added `sandbox.network.strictAllowlist` setting to deny non-allowlisted hosts for sandboxed commands without prompting
- Added `DirectoryAdded` hook that fires after `/add-dir` or the SDK `register_repo_root` control request registers a new working directory mid-session
- Added `mcp_server_errors` to the headless stream-json init event, listing `--mcp-config` entries skipped by config validation; terminal runs print a startup warning
- Added the `workflowSizeGuideline` settings key so the advisory Dynamic workflow size guideline can be set from any settings file; the `/config` row is hidden while one does
- Added nested subagent forwarding in stream-json: subagents spawned at depth-2+ now appear when `--forward-subagent-text` is set, keyed by their spawning Agent `tool_use` id
- Added HTTP status and error text to `claude mcp list` and `/mcp` when a server fails to connect, and a warning for MCP config values with hidden leading or trailing whitespace
- Added the current default workflow size to the running-workflow status line, with a pointer to `/config` for changing it

**Changed**

- Changed dynamic workflows to default to a medium size guideline (aim for fewer than 15 agents); pick another size or unrestricted with Dynamic workflow size in `/config`
- Changed managed MCP allowlist/denylist `${VAR}` entries to resolve from the startup environment and managed-settings env instead of settings-file env
- Changed the `/model` picker to highlight only the newest model’s name, so the highlight marks the new release rather than an arbitrary subset of the list
- Removed Opus 4.7 from fast mode; `/fast` now applies to Opus 5 and Opus 4.8
- Updated the claude-api skill to default to Claude Opus 5, with a migration path from Opus 4.8
- Subagents can now spawn nested subagents up to depth 3 by default (was 1); set CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1 to disable nesting

**Improved**

- Improved the “Remote Control is only available via api.anthropic.com” error to name the specific setting that caused it
- Improved `claude --teleport` to show which repo your current checkout points at when it doesn’t match the session’s repo

Show 8 bug fixes

- Fixed `claude -p` text output dropping the answer already produced when a turn dies on a mid-stream API error
- Fixed the Fable model row showing “Requires usage credits” for plans that include it, when a stale cache had baked the label in
- Fixed the `/model` picker showing the merged Opus row as plain “Opus” instead of “Opus (1M context)”
- Fixed copy-on-select inside GNU screen printing base64 into the terminal instead of copying the selection
- Fixed Remote Control clients keeping a stale fast-mode status after a model switch, reconnect, or failed org check
- Fixed `CLAUDE_CODE_GIT_BASH_PATH` on Windows exiting or being used as bash when the path isn’t a bash/sh binary; it’s now ignored with a warning
- Fixed Vim mode: pressing ← on an empty prompt now returns to the agent view from NORMAL mode, not just INSERT
- Fixed screen-reader mode rewriting the entire input line on every keystroke instead of echoing only the typed character

[​](#2-1-218)

2.1.218

July 22, 2026

**Added**

- Added screen-reader announcements of deleted text for word and line deletions (`Option+Delete`, `Ctrl+W`, `Cmd+Backspace`, `Ctrl+U`, `Ctrl+K`) in `--ax-screen-reader` mode
- Added an announcement when fast mode changes as a result of switching models via `/config model=<x>` or Remote Control
- Added `yes`/`no`/`on`/`off`/`1`/`0` (case-insensitive) as accepted values for skill and plugin frontmatter booleans, alongside `true`/`false`

**Changed**

- Changed `/code-review` to run as a background subagent, so review work no longer fills your conversation and keeps stacked slash commands as its review target
- Changed `/deep-research` to start only when invoked manually; Claude no longer launches it on its own
- Changed plan mode with auto to no longer prompt for Bash commands the static analyzer can’t prove read-only; the auto-mode classifier judges them instead
- Changed server-managed settings so benign feature and cost toggles no longer trigger the settings-approval prompt
- Changed agent markdown files to reject agent names containing `:`, which is reserved for plugin namespacing
- Changed skills with `context: fork` to run in the background by default; opt out per skill with `background: false`

**Improved**

- Improved `/ultrareview` error feedback so Claude can correct an invalid argument instead of retrying it unchanged
- Improved auto mode: the dangerous-rm, background-`&`, and suspicious-Windows-path checks no longer open permission dialogs; the auto-mode classifier adjudicates them instead
- Improved sandbox command restrictions for IDE interactions
- Improved trust dialogs to name the repository root the grant covers

Show 23 bug fixes

- Fixed Windows paths with `\u`-prefixed segments (like `C:\Users\unicorn`) being corrupted into CJK characters in tool inputs, which made those files inaccessible
- Fixed the left arrow key discarding the conversation with no undo: presses right after editing now ask to confirm, and Esc in the agent view returns to the conversation it backgrounded
- Fixed multi-line paste collapsing into one line with `j` in place of newlines in terminals that encode pasted newlines as Ctrl+J
- Fixed `/context` reporting stale pre-compact token usage after compacting from the message picker
- Fixed `/ultrareview` failing on descriptive arguments like “review my auth changes” — they now run a review of your current branch with the text applied as a note to the findings
- Fixed `/code-review ultra` silently running a local review in non-interactive sessions — it now launches the cloud review
- Fixed gateway spend metering to price Bedrock application-inference-profile ARNs and other config-mapped upstream model IDs at the configured model’s rates
- Fixed mojibake when a long IDE selection was truncated mid-emoji, and a case where a tool executor error could be silently dropped
- Fixed an engine teardown race that could start and abandon a phantom turn, and made input pushed after close consistently rejected
- Fixed spurious “\[Request interrupted by user\]” messages after interrupted tool calls, and an unpaired `tool_use` block left in the transcript when a tool aborted mid-response
- Fixed VoiceOver reading “new line” instead of echoing the typed space at the end of the input in `--ax-screen-reader` mode
- Fixed plugin and settings panels not moving the terminal cursor to the focused row, so screen readers and magnifiers can follow arrow-key navigation
- Fixed crashes (maximum call stack exceeded) when a deeply nested watched directory tree was deleted or moved, and when rendering deeply nested UI trees
- Fixed pull request events occasionally being lost when a session exited immediately after creating or linking a PR
- Fixed the Bedrock setup wizard failing profile verification for assume-role profiles in partitioned AWS regions and on proxy-only networks
- Fixed rare negative or incorrect turn duration measurements after a system clock adjustment by timing turns with a monotonic clock
- Fixed the “N MCP servers need authentication” startup notice over-counting claude.ai connectors that aren’t connected in claude.ai
- Fixed prompt history entries being dropped or duplicated when history writes raced or failed
- Fixed a retry loop that re-sent identical doomed requests after a context-overflow error with a large thinking budget; `Ctrl+B` backgrounding now applies the same background-shell caps as other paths
- Fixed agent frontmatter hooks running from untrusted folders: hooks now require the agent file’s own folder to have accepted workspace trust
- Fixed fork-session lineage being lost after compaction in headless and SDK sessions
- Fixed a resumed session failing every turn, or crashing on resume, when its history held a malformed delta attachment
- Fixed remote sessions continuing to send heartbeats after their worker was replaced, which left long-lived desktop and IDE processes retrying a rejected request every few seconds forever

[​](#2-1-217)

2.1.217

July 21, 2026

**Added**

- Added emoji shortcode autocomplete in the prompt input: type `:heart:` to insert ❤️, or `:hea` for suggestions — disable with the `emojiCompletionEnabled` setting
- Added warnings when transcript writes are failing (e.g. disk full) or when session saving is off due to an inherited environment variable, instead of losing transcripts silently
- Added a cap on concurrently-running subagents (default 20, override with `CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS`) so one message can’t fan out unbounded background agents

**Changed**

- Changed the login-expiry warning to appear 3 days before expiry instead of 5
- Capped the frontend-design plugin suggestion tip at 3 lifetime impressions instead of repeating indefinitely
- Changed subagents to no longer spawn nested subagents by default; set `CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH` to allow deeper nesting

**Improved**

- Improved footer PR badge links to be clickable hyperlinks even when terminal support can’t be detected (e.g. over ssh/tmux); set `FORCE_HYPERLINK=0` to opt out

Show 13 bug fixes

- Fixed a memory leak where truncated MCP tool outputs kept the full untruncated result in memory for the rest of the session
- Fixed Windows auto-update failures that could leave `claude.exe` missing; failed updates now restore the preserved executable automatically
- Fixed background session isolation not canonicalizing symlinked working directories, which could let sessions escape their workspace folder
- Fixed auto-compact never triggering for Claude Opus 4.8 on Bedrock and `/compact` failing once over the limit
- Fixed corporate mTLS, TLS-verify, OAuth scope, and proxy settings being ignored in Claude Desktop sessions
- Fixed screen reader mode’s startup announcement being cut off by the first prompt render, and the thinking status row re-rendering every few seconds to update elapsed time and token counts
- Fixed managed settings that set `OTEL_EXPORTER_OTLP_ENDPOINT` not governing all signals — lower-scope signal-specific overrides no longer redirect telemetry away from the managed endpoint
- Fixed `--resume`/`--continue` and `/resume` failing with a TypeError when a transcript has a malformed attachment entry
- Fixed Remote Control sessions not showing a pending permission prompt or dialog to viewers that connected after it appeared
- Fixed background shells sometimes becoming impossible to stop after a session is sent to the background (`/background` or `←`) or when the session exits on a heavily loaded machine, most visible on Windows
- Fixed a `CLAUDE.md` or `SKILL.md` paths frontmatter value with many brace groups OOM-killing or stalling the CLI at startup — brace expansion is now budget-bounded
- Fixed the transcript preview sitting flush against the input area when attaching to a starting background session; it now leaves the same one-line gap as the live layout, so the transcript no longer shifts when the session takes over
- Fixed `--max-budget-usd` not stopping background subagents: once the cap is reached, new spawns are denied and running background agents are halted

[​](#2-1-216)

2.1.216

July 20, 2026

**Added**

- Added `sandbox.filesystem.disabled` setting to skip filesystem isolation while keeping network egress control

**Changed**

- `/context` now shows an explicit warning when the conversation exceeds the context window, and a failed `/compact` displays as an error
- `/rewind` no longer restores or deletes files through symlinks or hard links at tracked paths and reports how many paths it skipped
- Background sessions: `/mcp` and `/install-github-app` now park a “needs input” request in the agent view when no client is attached
- Updated the bundled dataviz skill: reordered the default chart palette and fixed guidance that suggested direct labels for four-series charts

Show 5 improvements

- Improved the `/fork` confirmation to one line with the new session’s name, `claude attach` id, and a note when the copy shares your checkout
- Improved validation of `git` and `gh` command arguments in the PowerShell tool
- Improved the `/ultrareview` diff-too-large error to show configured limits, measured diff size, and largest contributing files
- Improved `/code-review ultra` empty-diff message to name the exact base ref and suggest passing an explicit base
- Improved the spend limit adjustment prompt to show the server’s reason when a spend limit change is rejected

Show 30 bug fixes

- Fixed a slowdown in long sessions where message normalization cost grew quadratically with the number of turns, causing multi-second stalls and slow resumes
- Fixed auto mode denying commands with “HTTP 401” classifier errors after the OAuth token expired or rotated mid-session
- Fixed AskUserQuestion telling Claude to continue even when your answer asked it to wait or explain first — free-text answers now get neutral wording
- Fixed Claude Code on the web re-asking the same question and dropping your answer after the session sat idle for a few minutes
- Fixed @-mentions silently attaching nothing after file-modifying hooks, vim dot-repeat of `c`-operators and paste, statusline running twice on resume, and resume-picker hangs on failure
- Fixed resumed background agent sessions reverting to the default agent: the agent’s prompt and tool restrictions are now restored
- Fixed worktree-isolated subagents redirecting git into the shared checkout via `git -C`, `--git-dir`, or `GIT_DIR`/`GIT_WORK_TREE`
- Fixed worktree sessions landing in another project’s leftover worktree when the working directory did not match the selected project
- Fixed background sessions whose worktree has no git repository being undeletable
- Fixed `claude daemon stop --any` potentially terminating an unrelated process via a stale legacy daemon lockfile
- Fixed Esc-Esc at an idle prompt not opening the rewind picker in long-running sessions with background tasks
- Fixed Bash command permission checking for compound statements with redirects inside `&&` lists or negations
- Fixed pressing Ctrl+X twice in the agent list failing to delete a session, and deleted sessions reappearing when their background worker had died
- Fixed background subagents getting cancelled when a high-priority message arrives during their startup window
- Fixed mouse and focus garbage in the terminal while a GUI editor from `/memory`, `/plan`, `/keybindings`, or Ctrl+G is open; `/memory` no longer waits for the editor to close
- Fixed Claude-in-Chrome 403-looping on reconnect when the session’s OAuth token lacks a required scope
- Fixed workflow saves and scheduled-task writes following a symlink at `.claude`, which could redirect writes outside the project
- Fixed MCP re-authenticate revoking working credentials before the new sign-in succeeds, and the reconnect needs-auth message in background sessions pointing at an unusable command
- Fixed read-only commands on Windows accessing network paths without a permission prompt
- Fixed Bash command parsing of non-ASCII characters to match real shell word boundaries
- Fixed PowerShell tool permission validation of commands containing invisible Unicode characters
- Fixed dialogs in fullscreen mode stretching past the right-hand edge of their panel
- Fixed the `/config` settings list in fullscreen mode clipping its keyboard-hint footer
- Fixed the transcript-mode (Ctrl+O) footer hint wrapping on terminals narrower than 104 columns
- Fixed the Prometheus metrics endpoint (`OTEL_METRICS_EXPORTER=prometheus`) emitting invalid `# UNIT` lines
- Fixed skills and commands changed during a session not appearing in the slash menu until restart
- Fixed plugin skills with a `name` frontmatter field losing their plugin prefix in slash-command autocomplete
- Fixed telemetry misreporting permission denials: failed permission-prompt requests no longer count as user rejections, and user interrupts are now reported as user aborts instead of rejections
- \[VSCode\] Fixed right-to-left text (Arabic, Hebrew, Persian) rendering in the wrong order when mixed with English or code
- Fixed cloud sessions dropping the in-flight message when the session’s container restarts mid-turn — the interrupted turn now re-runs on resume instead of leaving the session unresponsive

[​](#2-1-215)

2.1.215

July 19, 2026

- Claude no longer runs the `/verify` and `/code-review` skills on its own; invoke them with `/verify` or `/code-review` when you want them

[​](#2-1-214)

2.1.214

July 18, 2026

**Added**

- Added the EndConversation tool: Claude can end sessions with highly abusive users or jailbreak attempts, as on claude.ai since 2025 — see [https://www.anthropic.com/research/end-subset-conversations](../19-Reference/end-subset-conversations.md)
- Added a periodic progress heartbeat for long-running tool calls that previously went silent
- Added an ISO `modified` timestamp to memory file frontmatter
- Added `message.uuid`, `client_request_id`, and `tool_source` attributes to OpenTelemetry log events for message-level correlation and tool provenance
- Added `CLAUDE_CODE_OTEL_CONTENT_MAX_LENGTH` to configure the 60 KB truncation limit on OpenTelemetry content attributes
- Added reasoning effort to the `subagentStatusLine` payload, so custom agent rows can render model and effort
- Added permission prompts for `docker` commands (including the Podman `docker` shim) carrying daemon-redirect flags (`--url`, `--connection`, `--identity`, and Podman’s remote mode) that previously ran without one

**Changed**

- Changed single-segment `dir/**` hook `if:` conditions to match only `<cwd>/dir`; write `**/dir/**` for any-depth matching. `deny`/`ask` permission rules keep their any-depth match.
- Changed `file` commands using `-m`/`--magic-file` or `-f`/`--files-from` to require permission instead of being auto-allowed as read-only
- Changed keep-alive connection pooling to disable after a stale-connection error, so retries open a fresh socket
- Changed SessionStart hooks to report source `"fork"` when a session begins as a fork instead of `"resume"`

**Improved**

- Improved the `claude rc` workspace-trust error in the home directory to say trust there is never saved and to suggest running from a project directory

Show 35 bug fixes

- Fixed single-segment `dir/**` allow rules like `Edit(src/**)` auto-approving writes to nested `dir/` directories anywhere in the tree instead of only `<cwd>/dir`
- Fixed a permission-check bypass affecting commands run in Windows PowerShell 5.1 sessions
- Fixed Bash permission checks to fail closed on file-descriptor redirect forms that bash parses differently than the permission analyzer
- Fixed Bash permission checks misjudging very long commands — commands over 10,000 characters now always prompt instead of running automatically
- Fixed Bash permission checks treating zsh variable subscripts and modifiers in `[[ ]]` comparisons as inert text — these commands now prompt for approval
- Fixed Bash permission checks to no longer auto-approve certain `help` and `man` commands that could run unsafe options, command substitutions, or backslash paths
- Fixed permission prompts on remote sessions that could proceed before the local confirmation dialog
- Fixed a crash when a GrowthBook feature evaluates to null, and a bug where a malformed flag payload could wipe the cached feature flags
- Fixed Bash tool killing the Claude session when a `pkill -f` pattern accidentally matched the CLI’s own process (Linux)
- Fixed unbounded memory growth when `--settings` points at a device file or multi-GB file; oversized (\>2 MiB) settings files now fail at startup with a clear error
- Fixed streaming turns failing with “Socket is closed” behind corporate proxies on Windows
- Fixed stream-json output truncation at exit for slow-reading SDK/pipeline consumers; the exit drain now scales with queued bytes instead of a flat 2s cap
- Fixed scheduled tasks refusing their own configured prompt as untrusted input — the fired prompt is now delivered as the session’s assigned task
- Fixed PowerShell tool commands hanging until timeout when a child process waited on standard input (Windows)
- Fixed Python scripts under the PowerShell tool crashing with UnicodeDecodeError when reading non-UTF-8 data from standard input (Windows)
- Fixed Python scripts run via the PowerShell tool crashing with UnicodeEncodeError on non-ASCII output, and PowerShell 7 error messages containing raw ANSI escape sequences (Windows)
- Fixed the PowerShell tool reporting `where.exe`, `fc.exe`, and `diff.exe` as errors when they return a valid negative answer (Windows)
- Fixed `>` and `>>` under the PowerShell tool on Windows PowerShell 5.1 writing UTF-16LE files that other tools couldn’t read as UTF-8
- Fixed a displaced background daemon deleting its successor’s control socket on shutdown, which made the next client kill the healthy replacement daemon
- Fixed background sessions parked with `←` or `/background` and left idle keeping the background daemon and a worker process alive indefinitely
- Fixed completed background sessions being impossible to remove via `claude rm` or the agent view once the background service had gone idle
- Fixed background sessions dispatched from a non-git folder being impossible to delete from the agents view
- Fixed reopening a stopped background session failing to restore its saved conversation when an unreadable folder exists in the session store
- Fixed the Remote Control “session ready” push notification firing for sessions where Remote Control was not explicitly enabled
- Fixed `/install-github-app` and the `/mcp` settings menu being blocked in agent-view sessions — they’re now refused only in background sessions with no terminal attached
- Fixed plugins enabled via the `--settings` CLI flag not loading (regression since v2.1.181)
- Fixed feature flags going stale in long-running sessions after the OAuth token rotates
- Fixed `/ultrareview` refusing to run in repos with no merge base — it now offers to review all tracked files
- Fixed `claude update` and `claude doctor` hanging silently, and the `/status` System diagnostics section going blank, when a shell-config path is a directory
- Fixed memory frontmatter values being silently truncated at an inline `#` when memory files are saved
- Fixed session cost and token telemetry double-counting on streams that emit multiple cumulative `message_delta` frames
- Fixed a spurious “check your network” warning that appeared while the advisor was thinking
- Fixed hooks with exit code 2 not blocking as documented when the hook’s stdout JSON fails schema validation
- Fixed OTel log events emitted outside the turn’s async context missing the interaction span’s trace context
- Fixed MCP transient errors during prompts/resources refresh clearing the server’s slash commands and resources

[​](#2-1-212)

2.1.212

July 17, 2026

**Added**

- Added `claude auto-mode reset` to restore the default auto-mode configuration, with a confirmation prompt (pass `--yes` to skip)
- Added a session-wide limit on WebSearch tool calls (default 200, tunable via `CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION`) to stop runaway search loops
- Added a per-session cap on subagent spawns (default 200, override with `CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION`) to stop runaway delegation loops; `/clear` resets the budget

**Changed**

- `/fork` now copies your conversation into a new background session (its own row in `claude agents`) while you keep working; the in-session subagent it used to launch is now `/subtask`
- MCP tool calls running longer than 2 minutes now move to the background automatically so the session stays usable; configure the threshold or disable with `CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS`
- Typing `/resume` in the agent view now opens a picker of past sessions — including sessions deleted from the list — and resumes your pick as a background session
- Reduced token usage in inter-agent messaging: `SendMessage` bodies are no longer duplicated into replayed history and tool results
- Changed `/fork` to name the copy after your prompt when the session has no title, so the row is recognizable in the agent view
- Changed bare `/btw` to reopen the side-question panel on your most recent exchange so you can browse earlier answers
- Changed the `←` footer hint to pulse `N done` for a moment when a background agent finishes while nothing needs your input
- Deprecated the Task tool’s `mode` parameter (now ignored); subagents inherit the parent session’s permission mode by default
- Changed Enterprise `forceLoginMethod` to be enforced for VS Code extension, SDK, `setup-token`, and `install-github-app` logins, not just the terminal
- Changed session transcripts to record the reasoning effort level on each assistant message
- Changed headless/SDK sessions to apply a `set_model` control request mid-turn; the next model round-trip uses the new model instead of waiting for the next turn
- Changed agent view / `claude agents --json`: sessions waiting on a sandbox, MCP-input, or managed-settings prompt now show as “Needs input” instead of “Working”
- Updated the auth status panel title from “Cloud authentication” to “Authentication”
- Corrected an earlier release note (2.1.200): tmux through the 3.6 series lacks synchronized output; newer tmux with support is detected automatically

**Improved**

- Improved web search and web fetch reliability by retrying 529 errors and rate-limited requests with bounded backoff
- Improved prompt caching: the mid-conversation system block now works behind LLM gateways and custom base URLs (Bedrock, Vertex, 1P)
- Improved background agent attach: cold-attaching now instantly shows the formatted transcript while the session boots, instead of a blank wait

Show 28 bug fixes

- Fixed plan mode auto-running file-modifying Bash commands (e.g. `touch`, `rm`) without a permission prompt or SDK `canUseTool` callback
- Fixed worktree creation following a repository-committed symlink at `.claude/worktrees`, which could create files outside the repository
- Fixed a `continue:false` hook’s halt being dropped when the tool fails or completes mid-stream, and hook infrastructure errors being misreported as user rejections
- Fixed SIGTERM during a running Bash tool orphaning the command’s process tree in print/SDK mode; the CLI now aborts the turn, kills the tree, and exits 143
- Fixed `/background` and `claude --bg` failing with “EUNKNOWN: unknown error, uv_spawn” on Windows when Group Policy blocks PowerShell 5.1; the daemon now prefers PowerShell 7
- Fixed shell mode (`!`) not executing commands containing file paths while the path autocomplete popup was open
- Fixed auto-mode denial notifications rendering broken characters when a long denial reason was truncated mid-emoji
- Fixed Ctrl+J not inserting a newline in the agent view dispatch input on terminals with extended key reporting, and surfaced the newline shortcut in the `?` help overlay
- Fixed `/ultrareview` rejecting PR references like `#123`, `PR 123`, and pasted PR URLs; error hints now name the command you actually typed
- Fixed `/ultrareview <branch>` not fetching the branch from origin when it exists remotely; it now suggests the closest branch name on typos
- Fixed `/ultrareview` skipping the billing confirmation in a new conversation after `/clear`
- Fixed `/ultrareview`’s “not a git repository” error on Claude Desktop now suggesting the project’s repository folder instead of terminal commands
- Fixed hosted (host-managed) sessions failing at startup when repository settings configured mTLS certs, extra CA bundles, or OAuth scopes; these transport settings are now ignored with a warning
- Fixed a spurious “File has not been read yet” error when editing a file that had been read with offset/limit before resuming a session
- Fixed `ExitWorktree` failing with “no active EnterWorktree session” after resuming a session with `--continue`/`--resume` in print/SDK mode
- Fixed the workflow agent grid staying empty for Remote Control clients that join a session mid-run
- Fixed streaming-mode control requests being marked complete before their handler finished, which could lose the request on session restart
- Fixed background sessions created with `/fork` losing their live-parent protection after a state write failure
- Fixed reopening a stopped background session from the agent view failing silently — it now resumes the session, or shows why it can’t and lets you force a restart
- Fixed agent teams: a stopping teammate could send the leader duplicate idle notifications when team initialization re-ran within a session
- Fixed the plan-approval dialog footer splitting “ctrl+g to edit in `<editor>`” apart when the file path is long
- Fixed the welcome banner keeping its old panel widths after a combined width+height terminal resize in fullscreen mode
- Fixed diff previews losing their line numbers and +/- markers in narrow layouts
- Fixed @-mentions attaching nothing after a partial file read, plugin uninstall targeting the wrong marketplace, and false “Command timed out” on exit code 143
- Fixed OpenTelemetry HTTP exports being rejected with 411/400 by Azure Monitor and other endpoints that don’t accept chunked transfer encoding
- Fixed OTLP event log records missing `trace_id`/`span_id` when `TRACEPARENT` is set in SDK/headless mode
- Fixed conversations with many images incorrectly failing with “Request too large” errors, and improved the error message to explain the actual cause
- Fixed web search and web fetch returning “API Error” text as search results or page content when the API was overloaded

[​](#2-1-211)

2.1.211

July 15, 2026

**Added**

- Added `--forward-subagent-text` flag and `CLAUDE_CODE_FORWARD_SUBAGENT_TEXT` environment variable to include subagent text and thinking in stream-json output

**Changed**

- Hardened synced skill/plugin directory naming on Windows and kept CCR web fetch/search proxies working after `/clear`
- Updated integer environment variables (timeouts, token budgets, retry counts) to accept scientific notation and digit-separator spellings like `1e6` and `64_000`
- Updated documentation links to the current docs sites
- Changed “always allow” permission rules to save at the repository root, so approvals granted in a git worktree persist across sessions and worktrees
- Changed `/usage-credits` to ask for confirmation before sending a request to organization admins
- Changed Vim mode `s` and `S` (substitute char/line) to work in NORMAL mode, matching vim behavior
- \[VSCode\] Updated the Remote Control banner to describe what it does
- Claude in Chrome: hardened file-upload path validation
- Claude in Chrome: `save_to_disk` on screenshot actions now writes the image to disk and returns the path; previously it did nothing

**Improved**

- Improved terminal layout and rendering performance
- Improved background agent result reporting — Claude now reports the status of still-running agents and waits for the real completion instead of fabricating results
- Improved the memory index over-limit warning to measure only loaded content, excluding frontmatter and HTML comments

Show 24 bug fixes

- Fixed permission previews relayed to chat channels not neutralizing bidirectional-override, zero-width, and look-alike quote characters, so tool inputs cannot visually alter the approval message
- Fixed auto mode overriding a PreToolUse hook’s `ask` decision for unsandboxed Bash — a hook `ask` now floors the decision at a prompt
- Fixed parallel Claude Code sessions all logging out simultaneously after wake-from-sleep when many sessions share one credential store
- Fixed plugin MCP servers not reconnecting after an idle web session woke, leaving MCP calls failing until the next message
- Fixed Claude Code on Vertex and Bedrock attempting the default Opus model at startup and printing a spurious fallback notice when a model is explicitly configured
- Fixed subagents spawned with an explicit model override reverting to the parent’s model when resumed or sent a follow-up message
- Fixed nested `.claude/rules/*.md` files loading even when setting sources exclude project settings
- Fixed file upload validation: filenames ending in a DOS device suffix (`.prn`) or trailing dot are now accepted, and files with multiple hard links are refused
- Fixed file uploads to Claude in Chrome from remote and CLI sessions
- Fixed edits that leave the input as ”?” being silently swallowed and toggling the shortcuts panel
- Fixed a startup hang when the Claude in Chrome extension is enabled but Chrome is not running
- Fixed a 300ms delay revealing async content (Settings tabs, Stats, diff views, and other loading states)
- Fixed reopening a just-stopped background session from the agents view starting a blank conversation under the same session id
- Fixed `/loop` hiding the session from `/resume` after a single use
- Fixed screen reader users losing the audible terminal bell after `/terminal-setup` or onboarding terminal setup
- Fixed background jobs on LLM gateway auth (`ANTHROPIC_AUTH_TOKEN` + `ANTHROPIC_BASE_URL`) coming back “Not logged in” after the daemon respawns them
- Fixed `claude agents` jobs becoming permanently undeletable when git no longer recognizes their worktree — the row now shows why the delete was refused instead of silently reappearing
- Fixed `/clear` not resetting the session cost counter — the statusline’s cost now starts at \$0 after `/clear`
- Fixed Claude in Chrome setup pages failing to open in the browser on Windows
- Fixed headless print-mode sessions on Windows crashing or silently exiting when stdin is unreadable
- Fixed background session titles in the agents view showing the naming model’s refusal text when the prompt contains a link
- Fixed background agents killed by the user auto-respawning, and revived agents re-running stale prompts from old sessions
- Fixed routines with no schedule reporting a next run time in the year 1
- Fixed a prompt-caching regression on Bedrock, Vertex, Mantle, and Foundry that billed the trailing system context block as fresh input tokens on every request.

[​](#2-1-210)

2.1.210

July 14, 2026

**Added**

- Added a live elapsed-time counter to the collapsed tool summary line so long-running tool calls visibly tick instead of looking stuck
- Added a startup warning for `Write(path)`, `NotebookEdit(path)`, and `Glob(path)` permission rules — use `Edit(path)` or `Read(path)` instead

**Changed**

- Hardened the Agent tool against indirect prompt injection via content a subagent read
- Memory writes that leave a MEMORY.md index over its read limit now produce an explicit error instead of silent truncation
- Screen reader mode now announces permission mode changes aloud when cycling modes with Shift+Tab
- The agents footer hint now shows how many background agents are waiting on your input, with a brief color emphasis when the count changes
- Agent view: the session you pressed ← from stays visibly marked even after mouse hover or arrow keys move the selection
- Fable temporarily shows as unavailable in the advisor picker while a server-side issue causing Fable advisor failures is fixed

**Improved**

- Improved the Bash/PowerShell tool message when a command hits its timeout and is auto-backgrounded, so the model can distinguish a hang from an explicit background request
- Improved auto mode: the permission classifier now defaults to Sonnet 5 for external sessions, validated on the session’s first request and pinned for the session
- Improved the bundled dataviz skill’s chart color validation with perceptual OKLab color difference and recalibrated color-blindness thresholds

Show 22 bug fixes

- Fixed `isolation: 'worktree'` subagents being able to run git-mutating commands against the main repo checkout instead of their own isolated worktree
- Fixed the `ultracode` keyword opt-in firing on non-human-originated input such as webhook payloads and relayed PR comments
- Fixed a rendered text fragment leaking into crash telemetry when a UI component returned content outside a styled text element
- Fixed paste markers leaking into external editors opened from Claude Code, which could appear as stray È/É characters around pasted text
- Fixed `claude attach` sometimes failing with “job not found” or “agent is still starting” errors during session transitions — attach now waits for the daemon to settle, and terminal resizes during a slow attach are applied once it completes
- Fixed a session crash when a tool’s result renderer returned a numeric bigint value or plain text instead of a UI element
- Fixed a hook callback timeout being misreported to the model as a user rejection, which made unattended sessions stop and wait
- Fixed Claude assuming a `cd` took effect after its command was moved to the background; the tool result now states the working directory is unchanged
- Fixed plugin-provided MCP servers being torn down when MCP servers are re-synced mid-session
- Fixed plan approvals without edits being labeled “(edited by user)” and overwriting the plan file with a stale snapshot
- Fixed `/doctor` skipping its auto-mode-default proposal on Bedrock, Vertex, and Foundry, where auto mode no longer needs an opt-in
- Fixed Grep content mode claiming “No matches found” when paginating past the end of results
- Fixed unmatched `$1`/`$2` positional placeholders in skills and commands being silently stripped; they are now preserved verbatim
- Fixed plugin cache writes leaving temp files behind on failure and failing on locked-file renames on Windows and network filesystems
- Fixed background workers crash-looping when a client resets its connection to the background service
- Fixed `claude agents --effort ultracode` not reaching dispatched sessions; the value was silently dropped
- Fixed pressing ← to open the agents view dropping the task tracker when returning to the session
- Fixed the agents dashboard retaining pasted images from abandoned reply drafts after their session was deleted
- Fixed killed background sessions leaving a permanent `git worktree lock` behind; the periodic sweep now releases locks whose owning process is gone
- Fixed SDK MCP servers registered via an `initialize` control request waiting until the next turn to start connecting
- Fixed returning to the agents view from a session leaving overlapping ghost frames with `CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1`
- Fixed late-appearing `.claude/*` symlinks not being reconciled into the sandbox deny-write list

[​](#2-1-209)

2.1.209

July 14, 2026

- Fixed /model and other dialogs being blocked in `claude agents` background sessions (reverts an overly broad guard)

[​](#2-1-208)

2.1.208

July 14, 2026

**Added**

- Added screen reader mode: opt-in plain-text rendering for screen reader users. Run `claude --ax-screen-reader`, set CLAUDE_AX_SCREEN_READER=1, or add “axScreenReader”: true to settings.
- Added `vimInsertModeRemaps` setting: map two-key insert-mode sequences like `jj` to Escape in vim mode
- Added `CLAUDE_CODE_PROCESS_WRAPPER`: agent view and the background service now honor a corporate launcher by running every Claude Code self-spawn through a required wrapper executable
- Added mouse-click support for multi-select menus and “Other” input rows in fullscreen mode

**Changed**

- Changed the Fable 5 usage-credits consent prompt to start with the decline option focused
- Reduced per-tool-call CPU overhead in print/SDK sessions with many MCP tools by caching tool-pool assembly (up to 7x faster tool rounds at high tool counts)
- Reduced memory usage by bounding the file edit read cache to 16 MB instead of pinning up to 1,000 full files
- Reduced session transcript size (up to 79x in edit-heavy sessions) and bounded checkpoint disk usage by pruning superseded file-history backups
- Reduced memory usage when resuming sessions with background agents or forks spawned from large conversations
- Completed background agents now stay listed in `/tasks` until cleanup instead of vanishing the moment they finish
- Attaching to a stopped background agent now shows its transcript immediately while the session warms up, instead of a blank “Session is starting” screen
- Background sessions: an older daemon no longer silently restarts workers spawned by a newer version onto the older binary
- Agent view: Ctrl+X now deletes renamed-branch worktrees, never destroys unpushed commits, keeps the session row when a worktree is kept, and reused worktree names reset to the current base
- Catastrophic removals (e.g. `rm -rf ~`) in commands containing `$(…)`/backticks/`<(…)` now prompt in `--dangerously-skip-permissions` and auto mode, matching the plain form
- `/install-github-app` and the `/mcp` settings menu no longer open in background sessions
- MCP servers configured with an empty URL now show as “not configured” in `/mcp` instead of a config error
- `/usage` now shows your last-known usage bars with an “as of” note when the usage endpoint is rate-limited, instead of an error screen

**Improved**

- Improved input responsiveness while agent task lists update — task updates no longer re-render the entire UI

Show 28 bug fixes

- Fixed fast mode staying off after switching back to a model that supports it — it now restores automatically when enabled in settings
- Fixed replies typed to a background agent being lost when delivery fails — the text is now saved and delivered when the session restarts
- Fixed background-session attach failing permanently (“Couldn’t start the background daemon”) after an update replaced the binary a running `claude agents` process was launched from
- Fixed the context window (and auto-compact indicator) briefly resetting to 200k after the CLI auto-updates, causing a false “100% context used” when resuming long-context sessions
- Fixed supervised and background sessions crashing when a server closed an HTTP/2 connection with a GOAWAY while requests were in flight
- Fixed truncated stream-json/JSON output and missing result message when piping large responses from `claude -p`
- Fixed `CLAUDE_CODE_MAX_OUTPUT_TOKENS` and similar env vars silently using the mantissa of scientific-notation values (`1e6` became `1`)
- Fixed very large markdown tables stalling rendering or using excessive memory; tables over 200 rows show the first 200 with a ”… N more rows” notice
- Fixed the Edit tool failing on files modified after reading when the target text still matches uniquely
- Fixed Read reporting empty files as “shorter than offset”, Grep silently returning “No files found” for invalid regex patterns, Grep count mode under-reporting totals when paginated, and Glob crashing with an unclear error when the pattern, path, or working directory contained a null byte
- Fixed `apiKeyHelper` script failures being hidden behind a generic 401 after ~10 silent retries; the script’s own error is now shown within 3 attempts
- Fixed Bedrock streaming requests failing with a misleading “Truncated event message received” when a gateway transforms the response — the error now names the content-type and points at the proxy
- Fixed `/upgrade` showing a login flow instead of the upgrade URL when the browser fails to open
- Fixed stream-json input killing the session on blank CRLF or whitespace-only lines from Windows-style SDK hosts
- Fixed headless stream-json sessions hanging permanently when a `control_request` carried a non-string `set_model` payload; the CLI now answers with an error response
- Fixed repeated “No completion record was found” notices on session resume — orphaned background tasks now collapse into a single summary
- Fixed Remote Control clients attaching to a terminal-hosted session not seeing background agents and workflow progress until a task started or stopped
- Fixed the Agent tool launching with no tools when a subagent’s `tools` list resolves to nothing — it now returns a clear error naming the unrecognized entries
- Fixed `/usage` showing stale cached bars over fresher data, and `/mcp` not reclassifying placeholder servers after config edits
- Fixed “Change directory” in SDK hosts (e.g. Claude Desktop) failing with “A turn is in progress” on idle sessions that have a running background task
- Fixed the workflow save dialog showing `~/.claude/workflows/` instead of the `CLAUDE_CONFIG_DIR` location for user-scope saves
- Fixed `/release-notes` adding the viewed notes to the model’s context — “Show all” previously injected the entire changelog into every subsequent request
- Fixed a memory leak in the agent view where pasted images were retained for the screen’s lifetime after sending peek replies
- Fixed SDK sessions losing agents defined via the initialize request when a plugin refresh ran before the client attached
- Fixed several memory leaks in long sessions: MCP stdio server stderr accumulating up to 64 MB per server, LSP documents staying open indefinitely (now LRU with 50-doc cap), async hook output retained after backgrounding, and unbounded growth in headless/SDK sessions from large tool-result payloads
- Fixed a memory blowup when reading files with extremely long single lines using offset/limit — the read now returns a clean error instead of loading the whole line
- Fixed multi-second per-turn slowdowns in sessions with many permission deny/ask rules — rule matchers are now compiled once and cached
- Fixed Bedrock auth failing with “Session token not found or invalid” for AWS SSO profiles whose sso_region differs from the Bedrock region (2.1.207 regression)

[​](#2-1-207)

2.1.207

July 11, 2026

**Changed**

- Auto mode is now available without `CLAUDE_CODE_ENABLE_AUTO_MODE` opt-in on Bedrock, Vertex AI, and Foundry; disable via `disableAutoMode` in settings
- Changed Bedrock, Vertex, and Claude Platform on AWS to default to Claude Opus 4.8
- Changed auto mode to no longer read `autoMode` from `.claude/settings.local.json` (repo-resident); use `~/.claude/settings.json` instead
- Plugin hooks/monitors/MCP headersHelper: `${user_config.*}` in shell-form commands is now rejected (shell-injection fix). Hooks: use exec form (`args` array) or `$CLAUDE_PLUGIN_OPTION_<KEY>`; monitors and headersHelper: read the value inside the script (config file or the server’s `env` block).
- Plugin option values (`pluginConfigs`) are no longer read from project-level `.claude/settings.json`; only user, `--settings`, and managed settings are honored

**Improved**

- Improved agent view: pasting the same text again now expands the collapsed `[Pasted text #N]` placeholder instead of adding a second one
- Improved agent view: blocked session peeks now lead with the question and show a worded staleness clock (`waiting 3m`) instead of the same timestamp twice

Show 17 bug fixes

- Fixed the terminal freezing and keystrokes lagging while streaming responses containing very long lists, tables, paragraphs, or code blocks
- Fixed remote managed settings from a non-interactive run (`claude -p`, the SDK) being permanently recorded as consented without ever showing the security consent dialog
- Fixed spurious prompt-injection warnings triggered by benign system-generated conversation updates
- Fixed the auto-updater overwriting a custom launcher script or symlink at `~/.local/bin/claude` on every release; `/doctor` now reports an externally managed launcher
- Fixed compound commands with `cd` prompting for permission when the only output redirect was to `/dev/null`
- Fixed the transcript jumping above the start of the answer when a response finishes streaming
- Fixed `extensions.worktreeConfig` being left in the repo’s `.git/config` (breaking go-git tools like `tea`) after the last `worktree.sparsePaths` worktree was removed
- Fixed malformed bracket patterns in rules globs, skill paths, `.ignore`, and `.worktreeinclude` breaking file reads, file suggestions, and worktree creation
- Fixed a crash loop in agent teams where a malformed teammate mailbox message caused repeated errors every second until the mailbox file was manually deleted
- Fixed background sessions auto-named by accepting a plan not showing that name on their agent-view row
- Fixed background sessions that entered a git worktree resuming blank after a cold reopen from the agent list
- Fixed Remote Control task status updates being lost when the connection recovered from a network interruption or credential refresh
- Fixed Remote Control sessions hosted by the desktop app not showing background agent and workflow progress on mobile and web
- Fixed Deep research runs labeling every Fetch-phase agent “unknown” — chips now show the source hostname
- Fixed Bedrock repeatedly requesting fresh AWS SSO credentials from IAM Identity Center on every API request
- Fixed an indefinite hang on Windows when AWS credential resolution stalls (e.g. a stuck `credential_process`): the 60-second stall guard now fires instead of waiting forever.
- Fixed `/usage-credits` amount inputs silently stripping malformed values (e.g. a pasted timestamp) to digits; malformed amounts are now rejected with an error, and amounts over \$1,000 require a typed confirmation

[​](#2-1-206)

2.1.206

July 9, 2026

**Added**

- Added directory path suggestions to `/cd`, matching `/add-dir` behavior
- Added a `/doctor` check that proposes trimming checked-in `CLAUDE.md` files by cutting content Claude could derive from the codebase

**Changed**

- `/commit-push-pr` now auto-allows `git push` to the repo’s configured push remote (`remote.pushDefault`, or the sole remote when only one is configured) in addition to `origin`
- Gateway: `/login` now supports Anthropic-operated public gateway endpoints
- `EnterWorktree` now asks for confirmation before entering a git worktree outside the project’s `.claude/worktrees/` directory
- Background agents now upgrade to a new version in the background right after a Claude Code update, instead of paying a slow stale-session upgrade when you attach
- Changed agents view: Ctrl+X now permanently removes a completed session, and sessions no longer render twice; deleted background jobs stay deleted

**Improved**

- Improved `/code-review` findings quality on claude-opus-4-8 across all effort levels
- Improved agents view: status column now uses full terminal width instead of truncating at 64 characters

Show 18 bug fixes

- Fixed an expired login failing every model with a misleading “There’s an issue with the selected model” error instead of prompting to run `/login`
- Fixed `claude --resume` and `--continue` not responding to keyboard input on startup
- Fixed MCP servers configured via `--mcp-config` or `.mcp.json` ignoring a per-server `request_timeout_ms`, which caused long-running MCP tool calls to time out at the 60s default in fresh sessions
- Fixed `CLAUDE_CODE_EXTRA_BODY` being silently ignored by `claude agents` / `--bg` background workers; the shell-exported override now follows the dispatching session
- Fixed OAuth MCP servers requiring manual re-authentication after a single failed token refresh
- Fixed `--permission-prompt-tool` pointing at an MCP server crashing with “MCP tool not found” on cold start before the server finishes connecting
- Fixed `/model` picker rows printing a price for a different model than the row named, and stopped quoting first-party list prices on providers that don’t bill them
- Fixed server-provided model rows being misplaced in the `/model` picker when an entitlement or allowlist restriction drops the row they were positioned against
- Fixed desktop sessions getting stuck showing “running” after a slash command was sent mid-turn
- Fixed keyboard input being ignored in the agents view when a setup prompt appeared before a bare `claude --resume` on Windows
- Fixed `claude rm` leaving the removed job in the daemon roster, causing the row to reappear in `claude agents`
- Fixed `/remote-control` showing “Unknown command” when logged out — it now explains how to sign in
- Fixed left arrow not stepping back out of a phase or agent in the workflow detail view
- Fixed `/status` listing the same broken-install warning twice
- Fixed false “disused plugin” tips and skewed disuse telemetry for LSP plugins
- Fixed `/doctor`’s update check to compare Homebrew installs against their cask’s channel instead of the settings channel
- Fixed the fullscreen jump-to-bottom pill suggesting Ctrl+End on macOS, not showing rebound chords, and wrapping over the transcript
- Bedrock: fixed a multi-minute startup hang when using an `awsCredentialExport` helper on networks with restricted egress

[​](#2-1-205)

2.1.205

July 8, 2026

**Added**

- Added an auto mode rule that blocks tampering with session transcript files

**Changed**

- Auto-update binary downloads now stream to disk instead of buffering in memory, cutting the updater’s peak memory usage by roughly 400 MB
- Background task notifications now explicitly state that no human input has occurred, preventing fabricated in-transcript approvals from being acted on
- `/doctor` is now a full setup checkup that can diagnose and fix issues; `/checkup` is its alias
- Reserved the “Claude Browser” MCP server name (alongside “Claude Preview”) ahead of the Claude Desktop pane rename; user-configured MCP servers can no longer register under either name

**Improved**

- Improved auto mode to ask before running `rm -rf` on a variable it can’t resolve from context
- Improved agent view: sessions that edit, merge, comment on, or push to an existing PR now link it in `claude agents`
- Improved agent view: rows now show a colored state word and a classifier-written headline instead of raw tool call text, and the peek opens with full status including the exact ask for blocked sessions

Show 15 bug fixes

- Fixed `--json-schema` silently producing unstructured output when the schema was invalid, and schemas using the `format` keyword being rejected
- Fixed a message sent while Claude was working being silently lost when the turn ended at the `--max-turns` limit
- Fixed Windows worktree removal deleting files outside the worktree when an NTFS junction or directory symlink existed inside it
- Fixed background agents staying shown as “failed” or “completed” in the agent list after being resumed with `SendMessage`
- Fixed background jobs flipping from “needs input” back to “working” in the agent list when the agent’s turn contained no readable text
- Fixed `claude attach` erroring when a background agent was mid-upgrade restart instead of waiting for it to come back
- Fixed session-to-PR linking missing a PR created in a Bash call whose output exceeded the 30K inline limit
- Fixed `claude mcp add-from-claude-desktop` getting stuck when a server name contains unsupported characters; invalid names are now reported and remaining servers still import
- Fixed a plugin LSP server that fails to initialize preventing a valid LSP server from another plugin handling the same file extension
- Fixed a Windows crash when the directory Claude was launched from is deleted, locked, or unmounted while a command is running
- Fixed a crash when a file watcher was closed while a directory scan was still in flight
- Fixed project verify skills being rewritten on every session instead of only when a documented command changed
- Fixed the agent view rendering one line too high and clipping its header when the job list slightly overflowed the screen
- Fixed background tasks in the web and mobile Remote Control panels showing stale “Running” status by forwarding full task state on every membership change
- Fixed Cowork VM-mode local-agent sessions failing to start with “Not logged in · Please run /login” on CLI 2.1.203+

[​](#2-1-204)

2.1.204

July 8, 2026

- Fixed hook events not streaming during SessionStart hooks in headless sessions, which could cause remote workers to be idle-reaped mid-hook

[​](#2-1-203)

2.1.203

July 7, 2026

**Added**

- Added a warning when your login is about to expire, so you can re-authenticate before background sessions are interrupted
- Added a grey ⏸ badge to the footer when in manual permission mode, making the active mode always visible
- Added the session’s additional working directories to MCP `roots/list`, with `notifications/roots/list_changed` sent when the set changes
- \[VSCode\] Added a Settings toggle for “Enable Remote Control for all sessions”

**Changed**

- Reduced binary size by ~7 MB and startup memory by ~7 MB by loading a large bundled dependency lazily instead of inlining it
- Changed left arrow to no longer close the background tasks, diff, and workflow detail views — press Esc instead
- Changed the empty `claude agents` view to always show the organized sections (Needs input / Working / Completed) with descriptions
- Removed the startup “claude command missing or broken” warnings — they now appear in `/doctor` and `/status` instead
- Removed a redundant navigation hint from the `claude agents` footer

**Improved**

- Improved responsiveness while long responses stream: live-preview updates no longer re-render the whole screen
- Improved subagent behavior: agents are now less likely to re-delegate their entire task to another subagent

Show 26 bug fixes

- Fixed opening or switching background agent sessions on macOS stalling for 15–20 seconds due to a false low-memory detection (regression in 2.1.196)
- Fixed background sessions becoming permanently unresponsive to attach, replies, and stop when the daemon’s session token went stale — the session now recovers automatically
- Fixed returning to `claude agents` silently stopping running subagents and re-running the prompt from scratch — their work now carries over
- Fixed a memory and per-turn CPU regression in interactive sessions: the context-usage indicator no longer re-analyzes the entire transcript after every turn
- Fixed background agents inheriting a stale `PATH` from the daemon instead of the dispatching shell, causing missing tools on Windows
- Fixed background and agent-view sessions dropping a shell-exported `ANTHROPIC_BASE_URL`, which sent API keys to the default endpoint and failed with 401
- Fixed Bash failing with “argument list too long” in repos with many git worktrees
- Fixed worktree-isolated subagents sometimes running shell commands in the parent checkout instead of their own worktree
- Fixed worktree creation rejecting nested repositories in multi-repo workspaces, leaving background sessions unable to isolate and edit
- Fixed background agents crash-looping when their working directory was deleted, replaced by a file, or became an invalid path — they now fail once with a clear error
- Fixed a background daemon auto-upgrade failure silently killing all running background sessions
- Fixed `TaskStop` and `TaskOutput` failing to find background agents spawned by another agent — errors now list running agents by id and description
- Fixed the `claude agents` composer discarding your typed message when a slash command isn’t available there
- Fixed the agent list crashing when opening a stopped session whose conversation was already open in another session
- Fixed background sessions showing “Needs input” in the agent list after the question was already answered
- Fixed background agent startup failures showing only “exit_with_message” instead of the actual error
- Fixed background sessions ignoring `effortLevel` changes in settings.json when forked through the daemon
- Fixed attached background sessions ignoring `CLAUDE_CODE_DISABLE_MOUSE` and `CLAUDE_CODE_DISABLE_MOUSE_CLICKS` opt-outs
- Fixed `/exit` incorrectly warning about running background agents after all named agents had completed
- Fixed background sessions started from a non-git directory unable to edit files when a `WorktreeCreate` hook was configured
- Fixed the `@` directory picker in `claude agents` not showing registered git worktrees
- Fixed background task output on Windows being permanently replaced by an empty file after `/clear`
- Fixed content jumping when scrolling up through long transcript history
- Fixed the terminal flickering and jumping while typing in bash mode when a shell-history suggestion was shown
- Fixed literal `^[[I` / `^[[O` escape codes being printed when reattaching to a background session
- Fixed LSP-only plugins being incorrectly flagged for disuse when their language servers deliver diagnostics or answer navigation requests

[​](#2-1-202)

2.1.202

July 6, 2026

**Added**

- Added a “Dynamic workflow size” setting in `/config` for controlling how large Claude generally makes dynamic workflows (small/medium/large agent counts) — an advisory guideline, not an enforced cap
- Added `workflow.run_id` and `workflow.name` OpenTelemetry attributes to telemetry emitted by workflow-spawned agents, so a workflow run’s activity can be reconstructed from OTel data

**Changed**

- Changed `/review <pr>` back to a fast single-pass review; use `/code-review <level> <pr#>` for the multi-agent review at a chosen effort level

**Improved**

- Improved `/workflows` agent list layout: wider titles, a dedicated time column, shorter model names, and no per-row tool-call counts
- Improved MCP error messages: clearer error when a server config has `url` but no `type`, suggesting `"type": "http"` instead of the misleading “command: expected string”

Show 13 bug fixes

- Fixed a crash in the inline Ctrl+R history search when accepting or cancelling while the search was still scanning the history file
- Fixed `/rename` on background sessions being reverted when the job restarts, which broke addressing the session by its new name
- Fixed transient mTLS handshake failures when settings were re-applied during an in-place client certificate rotation
- Fixed commands sent from Remote Control (mobile/web) into an interactive session failing with “Unknown command”
- Fixed images and files sent from the Remote Control mobile or web app without a caption being silently dropped
- Fixed the sign-in URL printed by `claude auth login` and `claude mcp login --no-browser` not being reliably clickable when it wraps over SSH — it is now emitted as a single hyperlink
- Fixed opening a chat from `claude agents` sometimes failing with “currently running as a background agent” followed by a worker crash/respawn loop
- Fixed workflow scripts with unicode quote escapes in strings being corrupted before parsing; workflow parse errors now show the offending line instead of always blaming TypeScript
- Fixed voice dictation retrying in an unbounded loop when the microphone or audio recorder fails — repeated capture failures now pause voice input
- Fixed `/remote-control` sessions showing the wrong permission mode in the mobile and web apps
- Fixed resuming a session by name, or opening the resume picker, taking minutes and using a large amount of memory in repositories with many git worktrees
- Fixed installer and updater downloads failing immediately with “aborted” when a proxy or network drops the connection mid-download — transient connection drops now retry
- Fixed re-invoking an already-loaded skill appending a duplicate copy of its instructions to context

[​](#2-1-201)

2.1.201

July 3, 2026

- Claude Sonnet 5 sessions no longer use the mid-conversation system role for harness reminders

[​](#2-1-200)

2.1.200

July 3, 2026

**Changed**

- Changed `AskUserQuestion` dialogs to no longer auto-continue by default; opt into an idle timeout via `/config`
- Changed the “default” permission mode to “Manual” across the CLI, `--help`, VS Code, and JetBrains; `--permission-mode manual` and `"defaultMode": "manual"` are accepted alongside `default`

**Improved**

- Improved screen-reader output: decorative glyphs are now hidden, transcript symbols read as short labels, and nested tables read as `Header: value.` lines
- Improved the install script to explain when installation is killed by the system running out of memory

Show 13 bug fixes

- Fixed a crash at startup when `disabledMcpServers` or `enabledMcpServers` in `.claude.json` is set to a non-array value
- Fixed background sessions silently stopping mid-turn after sleep/wake or when reopening a stalled session
- Fixed background sessions re-running a turn cancelled with Esc after a stall respawn
- Fixed background agents never starting again after a crash left a stale `daemon.lock` whose PID the OS reused
- Fixed background-agent daemon handover so a reinstalled older build can no longer take over the daemon; build recency is now judged by the version’s embedded build timestamp
- Fixed background-agent roster issues: transient corruption permanently disabling orphan cleanup, older binaries not preserving fields written by newer versions, and socket auth tokens being stripped during daemon restarts
- Fixed subagents cut off by a rate limit before producing any text output returning an empty result instead of failing cleanly
- Fixed control bytes from background-agent output reaching the terminal in the agent view
- Fixed `claude agents --plugin-dir <dir>` not showing the plugin’s agents and skills in the agent view when the flag is placed after `agents`
- Fixed project-scoped plugins not loading correctly from git worktrees of the same repository
- Fixed `/mcp` server list not tracking focus for screen readers and magnifiers
- Fixed voice dictation showing a misleading “Voice connection failed” message when a recording captures no audio
- Fixed rendering flicker under tmux 3.4+ by enabling synchronized terminal output

[​](#2-1-199)

2.1.199

July 2, 2026

**Changed**

- Stacked slash-skill invocations like `/skill-a /skill-b do XYZ` now load all leading skills (up to 5), not just the first
- Transient server rate-limit errors (429s unrelated to your usage limit) are now retried automatically with backoff for subscribers instead of failing the turn
- `CLAUDE_CODE_RETRY_WATCHDOG` now raises the default retry count for non-capacity transient errors to 300 and lifts the cap of 15 on `CLAUDE_CODE_MAX_RETRIES`
- `claude agents` session rows now show pull-request links as bare `#N` without the redundant “PR” label

Show 20 bug fixes

- Fixed SSL certificate errors (TLS-inspecting proxies, missing `NODE_EXTRA_CA_CERTS`, expired certs) burning retries before showing actionable guidance — they now fail immediately with the fix hint
- Fixed streaming responses being discarded when the API emits a mid-stream overloaded/server error after partial output — the partial is now kept with an incomplete-response notice
- Fixed subagents cut off by a rate limit or server error silently failing instead of returning their partial work to the parent
- Fixed subagents reporting API errors (e.g. usage limit reached) as successful results — the error is now reported to the parent agent
- Fixed the background-agent daemon on Linux killing itself and every running agent every ~50 seconds after an unclean shutdown left a corrupted worker record
- Fixed background agents failing to cold-start over SSH on macOS with “Could not switch to audit session” (regression in 2.1.196)
- Fixed `claude stop` being silently undone when it raced a background-agent respawn — the respawn now honors the stop
- Fixed background job progress indicators stalling for minutes while the job ran long commands
- Fixed background sessions on memory-starved machines showing a generic error — they now indicate low memory and suggest freeing resources
- Fixed remote sessions briefly flapping between Working and Idle in the agent view when a background agent completes
- Fixed idle subagents vanishing from the agent panel while other subagents were still working; surplus idle agents now collapse into an expandable summary row
- Fixed typing `/model` or `/fast` while viewing a subagent silently opening the lead’s model picker — a notice now explains the command applies to the lead
- Fixed `SessionStart`, `Setup`, and `SubagentStart` hooks silently hiding stderr when exiting with code 2 — the error is now shown in the transcript
- Fixed `claude --dangerously-skip-permissions daemon <subcommand>` being treated as a chat prompt instead of running the subcommand
- Fixed `SendMessage` silently misrouting when a re-spawned agent reuses a previous agent’s name — the tool now detects the mismatch and asks the caller to retarget
- Fixed opening or resuming a session with no new messages needlessly growing the transcript file
- Fixed backgrounding a session with `←` or `/background` dropping its `/color` from the agent view row
- Fixed resetting a corrupted config file from the startup recovery dialog destroying it unrecoverably — it now backs up the file first
- Fixed Claude in Chrome repeatedly opening the reconnect page when sessions run from different builds or config directories
- Fixed plan mode not prompting for state-changing browser tool calls; read-only `browser_batch` calls are now correctly auto-allowed

[​](#2-1-198)

2.1.198

July 1, 2026

**Added**

- Added background agent notifications in `claude agents` — sessions that need input or finish now fire the `Notification` hook (`agent_needs_input` / `agent_completed`)
- Added `/dataviz` skill for chart and dashboard design guidance with a runnable color-palette validator
- Gateway: added Claude Platform on AWS (anthropicAws) as an upstream provider; model-not-found responses now advance the failover chain

**Changed**

- Subagents now run in the background by default, so Claude keeps working while they run and is notified when they finish (previously a gradual rollout)
- Claude in Chrome is now generally available
- Background agents launched from `claude agents` now commit, push, and open a draft PR when they finish code work in a worktree, instead of stopping to ask
- The built-in Explore agent now inherits the main session’s model (capped at opus) instead of running on haiku
- Subagents and context compaction now inherit the session’s extended thinking configuration, improving output quality on delegated tasks
- Keyboard shortcut hints now show opt/cmd instead of alt/super when connected from a Mac over SSH
- `/login` now opens the sign-in dialog from the `claude agents` view instead of saying it isn’t available
- Subagents now treat messages from the agent that launched them as normal task direction; an agent’s message is still never treated as the user’s approval
- Removed the `/agents` wizard; ask Claude to create or manage subagents, or edit `.claude/agents/` directly

**Improved**

- Improved focus mode: subagents launched in a turn now appear in its activity summary, and completed background notifications fold into a single count
- Improved syntax highlighting accuracy in code blocks, diffs, and file previews by upgrading to highlight.js 11
- Improved API retry UX: the error reason is now shown after the second attempt, and a status page link replaces the spinner tip when the API is overloaded

Show 18 bug fixes

- Fixed brief network drops mid-response aborting the turn — transient errors like ECONNRESET now retry with backoff instead of failing
- Fixed excessive background classifier requests when sandboxed processes repeatedly accessed the same network host
- Fixed background tasks in web, desktop, and VS Code task panels getting stuck on “Running” after they finish or after resuming a session
- Fixed agent teams: a teammate that dies on an API error now reports “failed” to the lead, and messaging a stuck teammate wakes it to retry immediately
- Fixed the `/diff` panel not refreshing when you switch branches or commit outside the session
- Fixed markdown tables overflowing and wrapping their right border when rendered in fullscreen mode
- Fixed Claude Platform on AWS and Mantle sessions dead-ending with “Please run /login” when the STS token expires — `awsAuthRefresh` now runs automatically
- Fixed “no route to host” for local-network hosts in macOS background agent sessions by declaring Local Network entitlements
- Fixed `/desktop` failing with “Cannot determine working directory” after entering and exiting a worktree
- Fixed background agents repeatedly showing “Reconnecting…” every ~52 seconds on macOS while the agents view was open
- Fixed pressing `←` inside `claude attach <id>` exiting to the shell instead of opening the agent view
- Fixed `claude --bg` silently creating an unattachable session when combined with `--print`/`-p`; the conflicting flags are now rejected up front
- Fixed the workflow progress view dropping the earliest agents from the list while the phase counter stayed correct in SDK and desktop-app sessions
- Fixed `.claude/rules/` conditional rules not loading when the target file is reached via a symlinked path
- Fixed Cmd+click not opening URLs in fullscreen mode in Warp on macOS
- Fixed double-click word selection in fullscreen mode to select the entire URL including the scheme
- Fixed plan mode not auto-allowing read-only tool calls when a session starts in plan mode
- Fixed `/branch` deriving its default fork name from the compaction summary instead of the first real prompt

[​](#2-1-197)

2.1.197

June 30, 2026

- Introducing Claude Sonnet 5: now the default model in Claude Code, with a native 1M-token context window and promotional pricing of \$2/\$10 per Mtok through August 31. Update to version 2.1.197 for access. [https://www.anthropic.com/news/claude-sonnet-5](../19-Reference/claude-sonnet-5.md)

[​](#2-1-196)

2.1.196

June 29, 2026

**Added**

- Added support for organization default models — admins set it in the org console; it shows as “Org default” (or “Role default”) in `/model` when you haven’t picked one yourself
- Added readable default names for sessions at start, making them easier to identify and message
- Added clickable file attachments in chat — Cmd/Ctrl-click reveals the file in Finder/Explorer

**Changed**

- Security: `claude mcp list`/`get` no longer spawn `.mcp.json` servers that a repo self-approved via a committed `.claude/settings.json`; untrusted workspaces show `⏸ Pending approval`
- Reduced per-frame rendering work in the terminal UI by skipping no-op subtree walks during streaming
- The streaming idle watchdog is now on by default for all providers — it aborts and retries when a response stream produces no events for 5 minutes. Set `CLAUDE_ENABLE_STREAM_WATCHDOG=0` to disable.
- Remote Control is now disabled when `ANTHROPIC_BASE_URL` points at a non-Anthropic host, matching the existing behavior under `CLAUDE_CODE_USE_BEDROCK`/`_VERTEX`/`_FOUNDRY`
- Changed opening the agents view from a foreground session to require a single `←` press instead of two, matching the behavior in background sessions

**Improved**

- Improved background session reliability: long-running commands and workflows now survive the session’s process being stopped, restarted, or updated — including on Windows, where background shells are handed off instead of being killed
- Improved background agents: workers killed by a daemon restart are now automatically resumed from where they left off the next time the agents view opens
- Improved `/code-review` workflow: merged five cleanup finders into one, cutting token usage by roughly 25%

Show 16 bug fixes

- Fixed waking a background job permanently deleting its conversation and re-running the original prompt when the transcript probe misread a real transcript; the file is now set aside, never deleted
- Fixed the rate-limit warning flickering off and rate-limit telemetry being over-counted when multiple parallel requests were in flight at the moment a usage limit was hit
- Fixed duplicate recap lines after a background session’s turn: a schema-rejected StructuredOutput attempt no longer renders alongside its retry
- Fixed PowerShell `git diff`/`git grep`, `egrep`/`fgrep`, and quoted search patterns containing `|` being reported as failures when they exit 1, matching Bash behavior
- Fixed multiple `claude agents` side panel issues: keyboard focus getting stuck when opening an agent, background jobs losing their subagent types on every open, and sessions showing incorrect status while actively running
- Fixed `claude agents --dangerously-skip-permissions` silently falling back to auto mode instead of showing the bypass disclaimer and applying bypass mode to spawned agents
- Fixed mid-turn crash recovery for Remote sessions — sessions interrupted by a server restart now auto-resume on the next worker
- Fixed sessions moved with `/cd` reappearing in the old directory’s resume list after a non-graceful exit when the old path contained special characters
- Fixed `claude plugin validate` skipping local plugins whose source is ”.” and stopping after the first error class
- Fixed Esc Esc at an idle prompt not opening the rewind menu (regression); use Ctrl+C or Ctrl+X Ctrl+K to stop background agents
- Fixed MCP OAuth requesting the authorization server’s full `scopes_supported` catalog when no scope is specified, causing `invalid_scope` failures on GitLab self-hosted and other enterprise IdPs
- Fixed `/context` showing 0 tokens for all tool groups on Bedrock
- Fixed `/deep-research` misreporting verifier failures as “all claims refuted” instead of `unverified`
- Fixed plugin dependency version pins not being honored when the marketplace was added as a local folder path backed by a git repo
- Fixed `claude agents` session status: completed rows no longer flip between “Done” and “Needs your input”, stalled agents are now labeled “Needs attention”, and results that mention a PR show a clickable link
- Fixed voice dictation swallowing spaces and spuriously starting a recording during very fast typing when voice mode is enabled

[​](#2-1-195)

2.1.195

June 26, 2026

**Added**

- Added `CLAUDE_CODE_DISABLE_MOUSE_CLICKS` to disable mouse click/drag/hover in fullscreen mode while keeping wheel scroll

**Improved**

- Improved voice mode on Linux: now distinguishes “no microphone” from “SoX not installed” when SoX is present but no audio capture device exists
- Improved `claude agents` completed list to fill available vertical space; on short terminals the header compacts so live sessions stay visible
- Improved Remote session startup with a provisioning checklist while the container starts

Show 8 bug fixes

- Fixed hook matchers with hyphenated identifiers (e.g. `code-reviewer`, `mcp__brave-search`) accidentally substring-matching — they now exact-match. Use `mcp__brave-search__.*` to match all tools from a hyphenated MCP server.
- Fixed voice dictation on macOS capturing silence in long-running sessions after the default input device changes
- Fixed voice dictation auto-submit never firing for languages written without spaces (Japanese, Chinese, Thai)
- Fixed external plugins enabled only by project `.claude/settings.json` not requiring explicit install consent on every loader path
- Fixed `/plugin` Enable/Disable not working when a plugin’s `plugin.json` `name` differs from its marketplace entry name
- Fixed background jobs disappearing from `claude agents` or losing data when written by a newer Claude Code version
- Fixed reopening a crashed background task showing a blank screen for up to 5 seconds instead of its restart
- Fixed background agent daemons running unreachable when the control socket fails to start, blocking restarts

[​](#2-1-193)

2.1.193

June 25, 2026

**Added**

- Added `autoMode.classifyAllShell` setting to route all Bash/PowerShell commands through the auto-mode classifier instead of only arbitrary-code-execution patterns
- Added auto-mode denial reasons to the transcript, the denial toast, and `/permissions` recent denials
- Added `claude_code.assistant_response` OpenTelemetry log event containing the model’s response text. Redacted unless `OTEL_LOG_ASSISTANT_RESPONSES=1`; when that var is unset it follows `OTEL_LOG_USER_PROMPTS`, so deployments that already log prompt content will start receiving response content on upgrade — set `OTEL_LOG_ASSISTANT_RESPONSES=0` to keep prompts-only.
- Added live file path autocomplete to bash mode (`!`)
- Added a startup notice when MCP servers need authentication, pointing at `/mcp`
- Added automatic memory-pressure reaping for idle background shell commands (disable with `CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP=1`)

**Improved**

- Improved background agents: the launch result no longer instructs Claude to “end your response” — it keeps working on other tasks while the agent runs
- Improved MCP `headersHelper` auth: the helper now re-runs and reconnects automatically when a tool call returns 401/403
- Improved plugin auto-rename: marketplace `renames` maps are now followed automatically, updating your settings to the new name
- Improved `/add-dir` message when the directory is already a working directory

Show 5 bug fixes

- Fixed `/model` and other client-data-gated UI showing stale/empty state immediately after `/login`
- Fixed backgrounding (←←) spuriously cancelling with “N background tasks would be abandoned” when all running tasks carry over to the new session
- Fixed pinned background agents being re-prompted to “Continue from where you left off” after every auto-update
- Fixed backgrounding the main turn spawning a phantom “general-purpose (resumed)” subagent that re-ran the main conversation
- Fixed agent panel hiding sibling agents when viewing a subagent

[​](#2-1-191)

2.1.191

June 24, 2026

**Added**

- Added `/rewind` support for resuming a conversation from before `/clear` was run

**Changed**

- Reduced CPU usage during streaming responses by ~37% by coalescing text updates to 100ms
- Reduced long-session memory growth from terminal output cache

Show 5 improvements

- Improved sandbox network permission dialog: hosts you allow with “Yes” are now remembered for the rest of the session instead of re-prompting on every connection
- Improved MCP server reliability: capability discovery (`tools/list`, `prompts/list`, `resources/list`) now retries transient network errors with short backoff
- Improved MCP OAuth: discovery and token requests now retry once after transient network errors, and headless environments skip the browser popup and go straight to the paste-the-URL prompt
- Improved MCP error messages: HTTP 404 errors now show the URL and point to your MCP config
- Improved vim mode prompt-history search (NORMAL `/`) to hint how to reach slash commands

Show 12 bug fixes

- Fixed scroll position jumping to the bottom while reading earlier output during a streaming response
- Fixed background agents resurrecting after being stopped — stopping an agent from the tasks panel is now permanent
- Fixed `/voice` showing a generic “not available” message when disabled by an organization’s policy — it now explains the restriction
- Fixed `/login` URL opening truncated in Windows Terminal when it wraps across lines
- Fixed Cmd+click on links in fullscreen mode for Ghostty over ssh/tmux
- Fixed `claude agents` sending builtin slash commands like `/usage` to background sessions as prompt text instead of showing a hint
- Fixed `claude agents` job rows showing full filesystem paths for pasted images instead of the `[Image #N]` placeholder
- Fixed hooks with comma-separated matchers (e.g. `"Bash,PowerShell"`) silently never firing
- Fixed `/permissions` Recently-denied tab: approving a denial now persists on close instead of being silently discarded
- Fixed the agent panel jumping by one row when scrolling the roster past the overflow cap
- Fixed the welcome splash art overflowing the default 80×24 macOS Terminal window
- Fixed managed settings: `forceRemoteSettingsRefresh` now takes effect when set via MDM or file policy, and the fetch sends `Cache-Control: no-cache` to prevent proxies from serving stale responses

[​](#2-1-190)

2.1.190

June 24, 2026

- Bug fixes and reliability improvements

[​](#2-1-187)

2.1.187

June 23, 2026

**Added**

- Added `sandbox.credentials` setting to block sandboxed commands from reading credential files and secret environment variables
- Added org-configured model restrictions to the model picker, `--model`, `/model`, and `ANTHROPIC_MODEL`, with a “restricted by your organization’s settings” message when a restricted model is selected
- Added mouse click support to select menus (permission prompts, `/model`, `/config`, etc.) in fullscreen mode

**Improved**

- Improved `/install-github-app`: GitHub Actions workflow setup is now optional — you can install just the GitHub App and skip the workflow/secret steps
- Improved `/btw` with ←/→ arrow navigation to step through earlier answers
- Improved `/plugin` to surface plugins you haven’t used recently so you can clean them up

Show 15 bug fixes

- Fixed `--resume` failing with “No conversation found” when the original `-p` run produced no model turns
- Fixed `--json-schema` and workflow `agent({schema})` structured output: the model can no longer re-call `StructuredOutput` indefinitely after a successful call, and follow-up turns now reliably return structured output
- Fixed remote MCP tool calls that hang with no response for 5 minutes — they now abort with an error instead of blocking indefinitely (override with `CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT`)
- Fixed Claude Code Remote sessions taking ~2.7s longer to start after the agent proxy CA system-trust install was added
- Fixed pasted Korean/CJK text turning into mojibake in terminals that deliver paste as per-byte extended-key events
- Fixed `/update` over Remote Control hanging when a startup trust dialog would have shown
- Fixed background jobs in the agents view getting stuck in “working” indefinitely when the agent ended a turn without producing structured output
- Fixed channel connections dropping after navigating to the agents view and back, and after `/bg`, `/tui`, or `/update`
- Fixed agent stop notifications not correctly attributing who stopped the agent, and improved wording (“finished”/“stopped” instead of “came to rest”)
- Fixed subagent depth tracking: resumed subagents now restore their original spawn depth, and forked subagents now count toward the depth cap
- Fixed leaked agent worktree registrations: locked `.git/worktrees/` entries from killed agents are now cleaned up automatically
- Fixed Cmd+click not opening URLs in fullscreen mode in Ghostty on macOS
- Fixed `claude --help` not listing the `--bg`/`--background` flag
- Fixed Esc, Ctrl-C, and Ctrl-D not working while `/share` is uploading
- \[VSCode\] Fixed extension becoming unresponsive when resuming a large session

[​](#2-1-186)

2.1.186

June 22, 2026

**Added**

- Added `claude mcp login <name>` and `claude mcp logout <name>` to authenticate MCP servers from the CLI without opening the interactive `/mcp` menu, with `--no-browser` stdin redirect support for completing over SSH
- Added status filtering (press `f`) to the `/workflows` agent detail view
- Added a “Skills” section to the `/plugin` Installed tab
- Added `teammateMode: "iterm2"` setting with a warning when auto mode cannot find the `it2` CLI
- Added “Claude Platform on AWS - refresh credentials” option to `/login` when `awsAuthRefresh` is configured

**Changed**

- `!` bash commands now trigger Claude to respond to the output automatically; set `"respondToBashCommands": false` in settings.json to keep the previous context-only behavior
- Changed `CLAUDE_CODE_MAX_RETRIES` to cap at 15; for unattended sessions, use `CLAUDE_CODE_RETRY_WATCHDOG` instead
- Changed background subagents to surface permission prompts in the main session instead of auto-denying; the dialog shows which agent is asking, and Esc denies just that tool
- Changed `/review <pr>` to use the same review engine as `/code-review medium`

**Improved**

- Improved `claude mcp get` and `claude mcp remove` to suggest the closest configured server name on a typo and truncate long server lists
- Improved memory: the agent is now reminded to compact its `MEMORY.md` index when nearing the size limit
- Improved skill frontmatter: `display-name`, `default-enabled`, `fallback`, and `metadata.*` keys now accept kebab-case, snake_case, and camelCase
- Improved malformed `SKILL.md` YAML frontmatter handling: loads the skill body with empty metadata instead of failing silently

Show 20 bug fixes

- Fixed streaming requests failing with “Content block not found” or JSON parse errors after the machine wakes from sleep
- Fixed subagent transcript scroll position bleeding into the main transcript on exit
- Fixed background task previews flashing raw tool names before the agent’s plan loaded
- Fixed Chrome tab-group isolation not applying when the in-product permissions gate is off for concurrent CLI sessions
- Fixed background session recaps being duplicated; the agent’s own end-of-turn summary now shows as the recap line
- Fixed opening a background session from `claude agents` leaving the previous screen painted behind it
- Fixed `Agent(type)` deny rules and `Agent(x,y)` allowed-types restrictions not being enforced for named subagent spawns
- Fixed Esc and Ctrl+C not responding while background agents are still running after the main turn ends
- Fixed misaligned option numbers in permission prompts when the option text overflows
- Fixed pressing `x` on a finished subagent in the agent panel not dismissing it
- Fixed a misleading “MCP server disconnected” notice for intentionally retired tools when resuming older sessions
- Fixed `/plugin` Installed showing a “more above” indicator when already scrolled to the top
- Fixed `~~strikethrough~~` showing literal tildes in assistant messages instead of rendering as strikethrough
- Fixed `--tools` allowing feature-gated tools to slip through before flags loaded on a cold first launch
- Fixed background job status in `claude agents` showing a stale “needs input” message after replying
- Fixed a dark-theme flash when opening a background session from `claude agents` on a light terminal
- Fixed mouse-selected text staying highlighted after deleting it in `claude agents`
- Fixed session cost not showing for usage-based Enterprise and Team subscribers
- Fixed agent teams: teammates spawned via tmux/pane backends now inherit the leader’s `--effort` level
- Fixed Workflow `agent({schema})` subagents looping forever on repeated schema validation failures instead of aborting after 5 attempts

[​](#2-1-185)

2.1.185

June 20, 2026

- The stream-stall hint now reads “Waiting for API response · will retry in …” instead of “No response from API · Retrying in …”, and triggers after 20s of silence instead of 10s

[​](#2-1-183)

2.1.183

June 19, 2026

**Added**

- Added a warning when the requested model is deprecated or automatically updated to a newer model, shown on stderr in print mode (`-p`) and now also covering models set in agent frontmatter
- Added `attribution.sessionUrl` setting to omit the claude.ai session link from commits and PRs in web and Remote Control sessions
- Added `/config --help` to list all available shorthand keys for `/config key=value`

**Changed**

- Changed `/config` toggle behavior: Enter and Space both change the selected setting, and Esc now saves and closes instead of reverting
- Removed the startup “setup issues” line under the logo — run `/doctor` to see configuration issues or use `--debug`

**Improved**

- Improved auto mode safety: destructive git commands (`git reset --hard`, `git checkout -- .`, `git clean -fd`, `git stash drop`) are now blocked when you didn’t ask to discard local work, `git commit --amend` is blocked when the commit wasn’t made by the agent this session, and `terraform destroy`/`pulumi destroy`/`cdk destroy` are blocked unless you asked for the specific stack

Show 11 bug fixes

- Fixed `thinking.disabled.display: Extra inputs are not permitted` 400 errors on subagent spawns and session-title generation for affected configurations
- Fixed WebSearch returning empty results in subagents
- Fixed the terminal cursor being stranded above the prompt after navigating history in vim mode with the native cursor enabled
- Fixed fullscreen TUI corruption (statusline mid-screen, duplicated spinner rows, merged text) in Windows Terminal under heavy nested-subagent load
- Fixed turns silently completing with no visible output when the model returned only a thinking block; Claude now re-prompts once
- Fixed user-level skills appearing multiple times in slash-command autocomplete when multiple plugins are enabled
- Fixed MCP servers requiring authentication exposing auth-stub tools to the model in headless/SDK mode
- Fixed tmux teammate panes failing to launch when the shell has slow rc-file initialization, and keystrokes typed during agent spawn leaking into the new tmux pane instead of the leader prompt
- Fixed background tasks started by a teammate being killed when the teammate finishes a turn
- Fixed scheduled task and webhook trigger deliveries being treated as keyboard input; they now classify as task notifications and can no longer approve a pending action or set the session title in auto mode
- Fixed focus mode showing “Ran N PostToolUse hooks” timing lines under each response

[​](#2-1-181)

2.1.181

June 17, 2026

**Added**

- Added `/config key=value` syntax to set any setting from the prompt (e.g. `/config thinking=false`) — works in interactive, `-p`, and Remote Control
- Added `sandbox.allowAppleEvents` opt-in setting that lets sandboxed commands send Apple Events on macOS
- Added `CLAUDE_CLIENT_PRESENCE_FILE` environment variable: point it at a marker file to suppress mobile push notifications while you’re at the machine

**Changed**

- Upgraded the bundled Bun runtime to 1.4
- Changed fullscreen mode URL opening to require Cmd+click (macOS) / Ctrl+click, matching native terminal behavior
- Changed the `Improved N memories` line to no longer list individual files outside verbose mode

**Improved**

- Improved streaming of long paragraphs: text now appears line-by-line instead of waiting for the first line break
- Improved auto-retry: API connection drops mid-thinking now automatically retry instead of showing “Connection closed while thinking”
- Improved the subagent panel: idle subagents auto-hide after 30s, the list caps at 5 rows with scroll hints, and keyboard hints now show in the footer
- Improved the MCP OAuth browser page to match Claude Code’s visual style and auto-close on success

Show 29 bug fixes

- Fixed prompt caching not reading on custom `ANTHROPIC_BASE_URL` and on Foundry due to a per-request attestation token changing every turn
- Fixed Write/Edit producing 0-byte or truncated files on network drives and cloud-synced folders
- Fixed `open`, `osascript`, and browser-based auth flows failing with error -600 on macOS by adding the Apple Events entitlement
- Fixed a startup regression (~120ms per launch in fresh environments, introduced in 2.1.169): the first prompt no longer waits for the managed-settings fetch when no MCP servers are configured
- Fixed startup blocking with a blank terminal for up to 15 seconds when the account settings fetch is slow on a degraded network
- Fixed startup crash (`TypeError: Cannot read properties of null`) when `.claude.json` contains corrupted null project entries
- Fixed macOS TUI freezing at session start (Ctrl+C unresponsive) when Spotlight is busy reindexing
- Fixed long-running idle sessions losing their history when another Claude Code process ran the 30-day transcript cleanup
- Fixed foreground subagents spawning unbounded nested chains; they now respect the same 5-level depth limit as background subagents
- Fixed `/recap` and conversation forks using the previous model immediately after a model switch
- Fixed subagent “Thinking” duration showing the parent agent’s elapsed time instead of the subagent’s own
- Fixed subagents blocked on a nested agent showing a ticking elapsed time instead of “waiting” in the agent panel
- Fixed the API retry indicator (“Retrying in 0s · attempt N/10”) staying on screen after the retry succeeded
- Fixed AWS `awsCredentialExport` credentials with a short remaining lifetime causing credential refreshes every minute, and now accepts the JSON shape from `aws configure export-credentials`
- Fixed `claude mcp get`/`list` showing `✓ Connected` when tools/list fails; they now show `! Connected · tools fetch failed` with the error detail
- Fixed `/remote-control` leaving a stale “connecting…” line; it now confirms in the transcript once connected
- Fixed ExitWorktree refusing to remove a clean worktree with “Could not verify worktree state” when bare `git` cannot be resolved on Windows
- Fixed settings changes (such as `/effort` or `/model`) failing with ENOENT when `~/.claude/settings.json` is a relative symlink under a symlinked `~/.claude`
- Fixed IDE selection line numbers in context reminders being off by one (IntelliJ and VS Code)
- Fixed Ctrl+C in fullscreen after a native terminal selection (modifier+drag) overwriting the clipboard with the app’s prior selection
- Fixed Ctrl+V showing “No image found in clipboard” instead of pasting when the clipboard contains text
- Fixed agent creation failing with “EEXIST: file already exists” when the agents directory already exists (Windows/OneDrive)
- Fixed AskUserQuestion preview content being cut off at the dialog edge instead of word-wrapping
- Fixed AskUserQuestion multi-select questions silently dropping a typed “Other” free-text answer when submitting
- Fixed `/stats` “Most active day” and daily token chart dates showing one day early in UTC-negative timezones
- Fixed `/copy` and copy-on-select on Linux not detecting a clipboard utility installed after Claude Code started
- Fixed tab-indented code rendering with incorrect indentation in the Write (create-file) preview
- Fixed user prompts queued mid-turn not showing a full-width background highlight in the transcript
- Fixed the activity spinner’s pulse dwelling on the wrong glyph size in Ghostty

[​](#2-1-179)

2.1.179

June 16, 2026

- Fixed mid-stream connection drops: partial responses are now preserved instead of showing a raw error, and the spinner no longer gets stuck at “running tool”
- Fixed mouse-wheel scrolling in WSL2 under Windows Terminal and VS Code (regression in 2.1.172)
- Fixed a sandbox `denyRead`/`allowRead` glob over a large directory tree making the Bash tool description enormous and the session unusable on Linux
- Fixed the feedback survey capturing a single-digit reply as a session rating immediately after a turn completes
- Fixed the welcome screen stacking multiple promotional banners — at most one promo now shows per session
- Fixed Ctrl+O not showing the subagent’s transcript when viewing a subagent
- Fixed clicking the prompt input not returning focus from the subagent/footer panel
- Fixed remote session background tasks appearing stuck as “still running” between turns
- Improved plugin loading performance in remote sessions

[​](#2-1-178)

2.1.178

June 15, 2026

**Added**

- Added `Tool(param:value)` syntax for permission rules to match a tool’s input parameters (with `*` wildcard), e.g. `Agent(model:opus)` to block Opus subagents

**Changed**

- Agent teams: removed the `TeamCreate` and `TeamDelete` tools. With `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` set, every session now has one implicit team — spawn teammates directly with the Agent tool’s `name` parameter, no setup step needed. The `team_name` parameter on the Agent tool is still accepted but ignored.
- Skills in nested `.claude/skills` directories now load when working on files there; on a name clash, the nested skill appears as `<dir>:<name>` so both stay available
- Nested `.claude/` directories: the agent, workflow, and output-style closest to the working directory now wins when names collide; project-scope workflow saves now target the closest existing `.claude/workflows/`
- Changed the workflow prompt keyword to use a purple shimmer highlight and trigger only on explicit phrases like “run a workflow” or “workflow:”, not on any mention of the word
- `/bug` now requires a description before submitting, and no longer uses model-refusal text as the GitHub issue title

**Improved**

- Improved auto mode: subagent spawns are now evaluated by the classifier before launch, closing a gap where a subagent could request a blocked action without review
- Improved `/doctor` with consistent flat tree layout across all sections, clearer section status icons, and highlighted command names
- Improved the skill listing truncation warning to show how many skill descriptions are affected
- Improved Remote Control error messages: connection failures now show a persistent red “/rc failed” indicator in the footer, and the “not yet enabled” error now explains whether it’s a gate, a check failure, stale entitlement, or org policy

Show 14 bug fixes

- Fixed a crash (out-of-memory) when the CLI inherits a stale websocket/OAuth file-descriptor environment variable from a parent process
- Fixed Claude in Chrome silently failing to connect when the OAuth token belongs to a different account than the Claude Code login
- Fixed nested `.claude/skills` skills with directory-qualified names being blocked by permission prompts in non-interactive runs
- Fixed several subagent issues: viewing a subagent’s transcript now shows tool results and live progress, messages sent while it finishes its turn are no longer dropped, and backgrounding a running subagent (ctrl+b) no longer restarts it from scratch
- Fixed `claude agents` workers failing with `401 Invalid bearer token` when the daemon was started from a shell with a custom API gateway via `ANTHROPIC_BASE_URL` and `ANTHROPIC_AUTH_TOKEN`
- Fixed compaction not honoring `--fallback-model`: compaction now falls back to the configured fallback model chain on overload or model-availability errors
- Fixed model requests continuing to fail with auth errors after credentials were refreshed outside the session, due to a stale cached request configuration
- Fixed background sessions created with `/bg` or `←←` after a turn finished showing “Working” forever in the agents list
- Fixed Linux sandbox failing to start when `.claude/skills` or `.claude/hooks` is a symlink
- Fixed `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1` preventing fresh marketplace installs from cloning
- Fixed MCP server-level specs (`mcp__server`, `mcp__server__*`, `mcp__*`) in subagent `disallowedTools` being silently ignored
- Fixed vim mode undo: `u` now steps through NORMAL/VISUAL-mode commands one at a time instead of merging commands in quick succession into a single undo step
- Fixed statusline links with custom URI schemes (e.g. `vscode://`) not opening when clicked in `claude agents`
- \[VSCode\] Fixed pressing Esc to dismiss a CJK IME candidate window canceling the running Claude task

[​](#2-1-176)

2.1.176

June 12, 2026

**Added**

- Added `footerLinksRegexes` setting for regex-matched link badges in the footer row, configurable via user or managed settings

**Changed**

- Session titles are now generated in the language of your conversation (set the `language` setting to pin a specific language)
- Background sessions now show clearer guidance when a window left open across an auto-update can’t submit a reply, and `claude daemon status` explains version-skew behavior

**Improved**

- Improved Bedrock credential caching: credentials from `awsCredentialExport` are now cached until their `Expiration` instead of a fixed 1 hour

Show 18 bug fixes

- Fixed `availableModels` enforcement: alias model picks can no longer be redirected to a blocked model via `ANTHROPIC_DEFAULT_*_MODEL` environment variables, and `/fast` now refuses to toggle when it would switch to a model outside the allowlist
- Fixed auto mode failing on Fable 5 for organizations without Opus 4.8 enabled — the classifier now falls back to the best available Opus model
- Fixed hook `if` conditions for Read/Edit/Write tool paths: documented patterns like `Edit(src/**)`, `Read(~/.ssh/**)`, and `Read(.env)` now match correctly
- Fixed Linux sandbox failing to start when `.claude/settings.json` is a symlink with an absolute target
- Fixed `/copy` and mouse-selection copy not reaching the system clipboard inside tmux over SSH, and tmux paste buffer not loading on versions older than 3.2
- Fixed Remote Control connecting from web/mobile silently switching the session’s model
- Fixed Remote Control disconnect notifications showing a bare numeric code instead of a human-readable reason, and connection failures adding a duplicate line to the conversation transcript
- Fixed Remote Control sessions not disconnecting when you sign in to a different account
- Fixed `/cd` and worktree moves leaving the session reporting the previous directory’s git branch
- Fixed `claude agents`: pressing back in one window no longer detaches other windows attached to the same session
- Fixed backgrounded sessions showing “Working” forever when `/bg` mid-turn had nothing left to continue
- Fixed background agent search by PR URL: PRs opened during scheduled wakeups or while a job was blocked now appear in `claude agents` search
- Fixed the agents view input showing no text cursor on Windows
- Fixed `claude --bg -cn <name>` not seeding the session name
- Fixed background sessions to neutralize Windows network paths in persisted state before respawn
- Fixed background-session respawn rejecting malformed resume IDs from corrupted state files
- Fixed the Windows background-service daemon not starting when `~/.claude/daemon` has the ReadOnly attribute set
- Fixed cloud sessions failing with “Could not resolve authentication method” when idle for too long before being claimed

[​](#2-1-175)

2.1.175

June 12, 2026

- Added `enforceAvailableModels` managed setting — when enabled, the `availableModels` allowlist also constrains the Default model (a Default that would resolve to a disallowed model now falls back to the first allowed model), and user or project settings can no longer widen a managed `availableModels` list

[​](#2-1-174)

2.1.174

June 12, 2026

**Added**

- Added `wheelScrollAccelerationEnabled` setting to disable mouse-wheel scroll acceleration in fullscreen mode
- \[VSCode\] Added usage attribution to the Account & usage dialog (`/usage`) showing cache misses, long context, subagents, and per-skill/agent/plugin/MCP breakdowns over the last 24h or 7d

Show 11 bug fixes

- Fixed the `/model` picker hiding the model family that Default resolves to — Opus now appears as its own row on Max/Team Premium/Enterprise plans, Sonnet on Pro/Team plans, and Opus on pay-as-you-go API accounts
- Fixed `/model` picker showing a hardcoded Sonnet version label when `ANTHROPIC_DEFAULT_SONNET_MODEL` pins a different Sonnet
- Fixed the “Fable 5 is now consuming usage credits” banner incorrectly showing for enterprise accounts with usage-based billing
- Fixed Bedrock GovCloud regions (`us-gov-*`) deriving the wrong inference profile prefix (`global` instead of `us-gov`), causing 400 errors on derived model IDs
- Fixed background sessions inheriting another session’s `ANTHROPIC_*` provider env (gateway URL, custom headers, `/model` aliases) from the shell that started the background daemon
- Fixed a 1-2 second pause when exiting Claude Code shortly after a shell command was interrupted or killed on macOS and Linux
- Fixed git commit co-author attribution showing an incorrect model name for some models
- Fixed the `/advisor` dialog pre-selecting a saved advisor model that is blocked by the `availableModels` allowlist
- Fixed skill hot-reload re-sending the entire skill listing when a single skill changed; only changed skills are now re-announced
- Fixed Workflow tool `agent()` subagents missing per-agent attribution headers
- Fixed pre-warmed background workers failing with “Could not resolve authentication method” when claimed after sitting idle

[​](#2-1-173)

2.1.173

June 11, 2026

- Fixed Fable 5 model names with a `[1m]` suffix not being normalized — Fable 5 includes 1M context by default, so the suffix is now stripped automatically
- Fixed a spurious “sandbox dependencies missing” startup warning on Windows when sandbox was enabled in settings

[​](#2-1-172)

2.1.172

June 10, 2026

**Added**

- Added a search bar when browsing a marketplace’s plugins in `/plugin`
- Added `model` attribute to the `claude_code.lines_of_code.count` OTEL metric

**Changed**

- Sub-agents can now spawn their own sub-agents (up to 5 levels deep)
- Amazon Bedrock now reads the AWS region from `~/.aws` config files when `AWS_REGION` isn’t set, matching AWS SDK precedence; `/status` shows where the region came from
- Disable mouse tracking on Windows consoles that don’t fully support it
- Reduced idle CPU usage: `/goal` status chip no longer re-renders the terminal at 5 Hz while idle, and fewer UI re-renders while subagents run in parallel
- `/code-review` now keeps the `ultra` option visible when you’re not signed in to claude.ai, with an explanation that the cloud review requires a claude.ai account
- Shortened the Remote Control footer indicator to “/rc active” and hid it on narrow terminals
- Stopped promoting `/loop` in remote sessions, where pending loops don’t keep the container alive

**Improved**

- Improved performance in long conversations by removing redundant message normalization and avoiding full message-history transforms when streaming tool-use state is unchanged
- Improved Claude in Chrome tool loading: browser tools now load in a single batched call instead of one per tool
- Improved the non-interactive Usage Policy refusal message to suggest starting a new session or changing your model

Show 18 bug fixes

- Fixed sessions using 1M context without usage credits getting permanently stuck — the session now automatically compacts back under the standard context limit
- Fixed a repeating “an image in the conversation could not be processed and was removed” error when the conversation contained multiple images
- Fixed the agents view keeping a session under Working with a busy spinner for up to 30 seconds after the worker replied
- Fixed background agents potentially reading another directory’s project settings (`.mcp.json` approvals, trust) when dispatched onto a pre-warmed worker
- Fixed background-session attach failing with EAUTH for sessions started on an older version after the daemon auto-updated
- Fixed a background sub-agent staying stuck as “active” in the agent panel after a nested agent it spawned was stopped
- Fixed `/model` suggestions in the `claude agents` dispatch input rendering with a misleading slash prefix and showing models disabled for your org
- Fixed `availableModels` restrictions not being applied to subagent model overrides, the agent dispatch model picker, and the advisor model
- Fixed `availableModels` allowlists hiding the `/model` picker’s Opus and Sonnet 1M rows when entries use version-specific IDs like `claude-opus-4-8`
- Fixed the `/model` picker on Bedrock offering models the provider doesn’t serve — selecting one silently switched the session model and lit the selection marker on multiple rows
- Fixed model IDs getting a doubled 1M-context suffix (e.g. `[1M][1m]`) when `ANTHROPIC_DEFAULT_OPUS_MODEL` already includes one
- Fixed `opusplan` model setting not shipping with 1M context in plan mode for entitled users; the `opusplan[1m]` workaround now also correctly switches to Opus in plan mode
- Fixed `WebFetch(domain:*.example.com)` wildcard domain rules never matching subdomains in allow, deny, and ask position, and file permission rules with mid-pattern wildcards (e.g. `Read(secrets-*/config.json)`) being rejected at startup
- Fixed up-arrow prompt history showing the main agent’s prompts while a subagent’s chat tab is open
- Fixed memory recall not finding mounted team memory stores (`CLAUDE_MEMORY_STORES`) in remote sessions
- Fixed workflow validation rejecting scripts whose prompt strings or comments merely mention `Date.now()`/`Math.random()`
- Fixed the `/plugin` marketplace list losing its cursor after backing out of a long plugin list, and Esc from the plugin browser returning to the wrong tab
- \[VSCode\] Fixed PowerShell tool calls rendering as raw JSON instead of a proper command display and permission dialog, and stripped ANSI escape codes from displayed shell output

[​](#2-1-170)

2.1.170

June 9, 2026

- Introducing Claude Fable 5: a Mythos-class model that we’ve made safe for general use. Fable’s capabilities exceed those of any model we’ve ever made generally available. Update to version 2.1.170 for access. [https://www.anthropic.com/news/claude-fable-5-mythos-5](../19-Reference/claude-fable-5-mythos-5.md)
- Fixed sessions not saving transcripts (and not appearing in —resume) when launched from the VS Code integrated terminal or any shell that inherited Claude Code environment variables.

[​](#2-1-169)

2.1.169

June 8, 2026

**Added**

- Added `--safe-mode` flag (and `CLAUDE_CODE_SAFE_MODE`) to start Claude Code with all customizations (CLAUDE.md, plugins, skills, hooks, MCP servers) disabled for troubleshooting
- Added `/cd` command to move a session to a new working directory without breaking the prompt cache mid-session
- Added a `disableBundledSkills` setting and `CLAUDE_CODE_DISABLE_BUNDLED_SKILLS` environment variable to hide bundled skills, workflows, and built-in slash commands from the model
- Added a tip suggesting `claude agents` when running multiple concurrent sessions

**Changed**

- `/workflows` now opens immediately even while a turn is in progress
- Reduced CPU usage while responses stream and during spinner animations
- Restored a default 5-minute idle timeout on Vertex/Foundry so a stalled stream aborts instead of hanging indefinitely; set `API_FORCE_IDLE_TIMEOUT=0` to opt out
- Remote-managed settings with an invalid entry now apply their remaining valid policies and surface the validation error, instead of silently dropping the whole payload
- Background sessions now preserve `--ide`, `--chrome`, `--bare`, `--remote-control`, and other flags across retire→wake, and respawn state validation was hardened
- Background sessions are now told that shared-checkout edits are blocked until they enter a worktree, avoiding a wasted rejected edit before `EnterWorktree`
- The “CLAUDE.md is too long” warning threshold now scales with the model’s context window
- Auto-updater on Windows now stops retrying within a session once `claude.exe` is held by another process
- Promo credit claims for Apple/Google-billed subscribers without a payment method now explain where to add one

**Improved**

- Improved `TaskCreate` reliability: malformed inputs are repaired automatically and validation errors for unloaded tools include the schema
- Improved the error message shown when your organization has disabled API key authentication, with guidance based on where the active API key comes from
- Improved color contrast for skill tags in the slash-command menu

Show 14 bug fixes

- Fixed Up/Down arrows jumping to command history past the wrapped rows of a long input line — they now move through each visual row first, and history recall enters at the near edge
- Fixed enterprise managed MCP policies (`allowedMcpServers`/`deniedMcpServers`) not being enforced on reconnect, IDE-typed configs, `--mcp-config` servers during the first session after install, or before remote settings loaded; also fixed slow cold starts for orgs without remote settings
- Fixed a ~30-50ms UI stall at the start of each turn for macOS users logged in with claude.ai credentials
- Fixed `claude -p` being slow or appearing to hang on Windows while waiting for the slash-command/skill scan (regression in 2.1.161)
- Fixed Remote Control getting stuck on “reconnecting” after resuming a session when an OAuth token refresh happened at the same time
- Fixed Git Credential Manager’s “Connect to GitHub” popup appearing on Windows at startup when background git commands ran without cached credentials
- Fixed footer hints (e.g. “esc to interrupt”) not showing for users with a custom statusline
- Fixed stale permission and dialog prompts reappearing every time you reattached to a remote session whose worker had died while waiting on them
- Fixed `claude agents --json` omitting blocked and just-dispatched background sessions; added `--all` to include completed sessions, plus new `id` and `state` fields
- Fixed agents view leaving a stale/garbled frame after navigating back from an agent on WSL in Windows Terminal
- Fixed background agents ignoring project-level settings `env` values (e.g. `ANTHROPIC_MODEL`) when dispatched onto a pre-warmed worker
- Fixed MCPB plugin cache being spuriously invalidated on Windows, causing unnecessary re-extraction
- Fixed plugin `.in_use` PID lock files accumulating without bound; stale markers from crashed sessions are now swept once per day
- Fixed untrusted project settings being able to set OTEL client-certificate paths without trust confirmation

[​](#2-1-168)

2.1.168

June 6, 2026

- Bug fixes and reliability improvements

[​](#2-1-167)

2.1.167

June 6, 2026

- Bug fixes and reliability improvements

[​](#2-1-166)

2.1.166

June 6, 2026

**Added**

- Added `fallbackModel` setting to configure up to three fallback models tried in order when the primary model is overloaded or unavailable; `--fallback-model` now also applies to interactive sessions
- Added glob pattern support in deny rule tool-name position (`"*"` denies all tools); allow rules reject non-MCP globs, and unknown tool names in deny rules warn at startup

**Changed**

- Hardened cross-session messaging: messages relayed via `SendMessage` from other Claude sessions no longer carry user authority — receivers refuse relayed permission requests, and auto mode blocks them
- `MAX_THINKING_TOKENS=0`, `--thinking disabled`, and the per-model thinking toggle now disable thinking on models that think by default via the Claude API (3P providers unchanged)
- Claude Code now retries a turn once on the fallback model when the API rejects an unexpected non-retryable error; auth, rate-limit, request-size, and transport errors still surface immediately
- `claude update` now announces the target version before downloading instead of going silent
- `claude agents`: typing a URL into the list now filters to the session whose first prompt contained it

Show 14 bug fixes

- Fixed a recurring “image could not be processed” error and extra token usage when an unprocessable image was sent in a session
- Fixed remote sessions becoming permanently stuck when a brief backend disruption occurred during worker registration at startup
- Fixed flickering in JetBrains IDE terminals (IntelliJ, PyCharm, WebStorm, etc.) on 2026.1+ by enabling synchronized output
- Fixed Shift+non-ASCII characters (e.g. Shift+ä → Ä) being dropped in terminals using the Kitty keyboard protocol (WezTerm, Ghostty, kitty)
- Fixed PowerShell command validation occasionally hanging far past its time budget on Windows when a killed process’s children held its output pipes
- Fixed orphaned `claude --bg-pty-host` processes spinning at 100% CPU after the daemon dies while connected on macOS
- Fixed voice mode requiring `/login` to clear a stale auth check after toggling `/voice`
- Fixed managed settings with an invalid entry silently disabling enforcement of their remaining valid policies
- Fixed managed-settings `allowedMcpServers`/`deniedMcpServers` predicates not matching when they use `${VAR}` references
- Fixed background agent sessions that entered a git worktree crash-looping with “No conversation found” when reopened from `claude agents`
- Fixed duplicated thinking text in the Ctrl+O transcript view while streaming
- Fixed `/doctor` showing a contradictory failed “Not inside a remote session” check when run inside a remote session
- Fixed the cursor sticking at the end of the first line when typing a multiline prompt in the `claude agents` dispatch and reply inputs
- Fixed blank lines appearing between background agent rows in the task list on terminals without Unicode support

[​](#2-1-165)

2.1.165

June 5, 2026

- Bug fixes and reliability improvements

[​](#2-1-163)

2.1.163

June 4, 2026

**Added**

- Added `requiredMinimumVersion` and `requiredMaximumVersion` managed settings — Claude Code refuses to start if its version is outside the allowed range and directs the user to an approved version
- Added `/plugin list` command to list installed plugins, with `--enabled`/`--disabled` filters
- Added a “c to copy” shortcut to `/btw` that copies the raw markdown answer to the clipboard, preserving formatting when pasted elsewhere
- Skills: added `\$` escape syntax to include a literal `$` before a digit in command bodies

**Changed**

- Hooks: Stop and SubagentStop hooks can now return `hookSpecificOutput.additionalContext` to give Claude feedback and keep the turn going without being labeled a hook error
- stdio MCP servers now receive the same `CLAUDE_CODE_SESSION_ID` as hooks/Bash on `--resume`
- Background agent sessions now update to a new Claude Code version in the background, so opening a session after an update no longer waits on a cold restart
- Clearer descriptions for built-in commands and skills in the / menu
- The subscription-switch suggestion now shows in the startup announcement slot instead of a toast
- `claude agents` dispatching from the state-grouped view now starts the session in the directory the agent view was opened from

Show 12 bug fixes

- Fixed `claude -p` hanging forever after its final result when a backgrounded command never exits — background shells are now stopped ~5s after the result once stdin closes
- Fixed `claude -p` failing with “ANTHROPIC_API_KEY required” on Bedrock/Vertex/Foundry when `CI=true` and no Anthropic API key is set
- Fixed bash commands failing under bazel and EDR-protected Go workflows: `$TMPDIR` was overridden to `/tmp/claude-{uid}` for all commands instead of only sandboxed ones (regression in 2.1.154)
- Fixed Bash commands failing on Windows with “EEXIST: file already exists” on the session-env directory when it has the read-only attribute or is inside OneDrive
- Fixed org-managed permission rules not applying for the entire session when the managed settings fetch completed during startup on a fresh config directory
- Fixed background sessions in `claude agents` losing their running background tasks when reattached after a Claude Code update
- Fixed terminal misalignment and a multi-second hang when exiting the agent view by pressing Esc
- Fixed clicking Stop on a background-task chip in the desktop app not clearing the chip when the underlying process was already gone
- Fixed keyboard input becoming permanently unresponsive after a paste operation whose end marker is dropped by the terminal
- Fixed hook `if: "Bash(...)"` conditions firing on every Bash command containing `$()` or `$VAR`; the pattern now matches against commands inside subshells and backticks too
- Fixed deny rules on home-directory paths (e.g. `Read(~/Desktop/**)`) not blocking Bash commands that reference the path via `$HOME`
- Fixed a stray “(no content)” line left in the transcript after closing panel dialogs like /mcp and /plugins

[​](#2-1-162)

2.1.162

June 3, 2026

**Changed**

- `claude agents --json` now includes `waitingFor` showing what a waiting session is blocked on (e.g. permission prompt)
- `--tools`: explicitly listing Grep/Glob now provides the dedicated search tools on native builds with embedded search (previously these names were silently ignored)
- `/effort` now confirms when your chosen level will persist as the default for new sessions
- Clicking a slash command in the autocomplete menu now fills it into your prompt instead of running it immediately; press Enter to run
- Remote Control now shows as a persistent footer pill (with a link to the session) instead of a startup message
- Renamed Windsurf to Devin Desktop in the `/ide` menu, `/terminal-setup`, and `/scroll-speed`, following the editor’s rebrand
- Quieter startup: notices group by severity, and session info and announcements share a single line per launch
- Startup warnings rewritten to be shorter and clearer, each with a concrete fix
- Launch-prompt warnings (deep link/pre-filled prompt) now stay pinned below the input until you act instead of scrolling away
- Failed turns now show a compact warning line instead of a multi-line red error block
- Background dispatch spawn failures now report the error class name when no errno is available
- Removed the “Claude in Chrome enabled” and “marketplace installed” startup messages; model auto-updates and the team-onboarding tip now show as quiet notices under the logo

**Improved**

- Improved background service startup and `claude update` verification to wait out endpoint-security scanning of new binaries instead of failing after 5 seconds

Show 15 bug fixes

- Fixed a silent startup hang when the config directory is read-only or unwritable — Claude Code now starts with in-memory config and surfaces startup errors instead of showing a blank screen
- Fixed WebFetch permission rules not being applied to built-in preapproved domains; explicit `WebFetch(domain:...)` deny/ask/allow rules now take precedence over the preapproved-host auto-allow
- Fixed Windows permission rules never matching when spelled with backslashes (`~\`, `\\server\share`) or case-variant paths, and Read deny rules not hiding files from Glob/Grep results
- Fixed an interrupt (Esc) sent at the very start of a turn being silently dropped in stream-json/SDK sessions, leaving the turn running with no “Interrupted” feedback
- Fixed API 400 `no low surrogate in string` errors for classifier side-queries and MCP server descriptions containing emoji near a truncation boundary
- Fixed MCP per-server `timeout` config values below 1000 ms being floored to a 1-second watchdog that aborted every tool call; sub-1000 ms values are now ignored (falling back to `MCP_TOOL_TIMEOUT` or default), and `claude mcp get` annotates them accordingly
- Fixed the LSP tool’s `workspaceSymbol` operation returning no results; it now accepts a `query` parameter and passes it to the language server
- Fixed `claude agents` cutting live status text (tool args, replies, prompts, exec output) at 60–120 columns on wide terminals; the status detail now uses the full terminal width
- Fixed `claude agents` truncating long session names at 40 columns; the name column now grows with terminal width
- Fixed `claude agents` attach occasionally bouncing straight back to the session list on the first try after a background-service restart
- Fixed `claude agents` Ctrl+V image paste doing nothing in the dispatch input and the session reply box; pasting with no image now shows a hint
- Fixed backgrounding a session with ← silently losing the conversation when the background service cannot start; the session stays in the list as a failed row you can wake with Enter
- Fixed replies from the agents view that fail to send being lost; they are now queued for delivery on the next session start
- Fixed cross-session messaging (`SendMessage`) silently breaking when `CLAUDE_CODE_TMPDIR` or `$TMPDIR` points at a deep directory
- Fixed opening a running background session from `claude agents` stalling for 5 seconds before attaching

[​](#2-1-161)

2.1.161

June 2, 2026

**Added**

- \[VSCode\] Added a tip suggesting disabling terminal GPU acceleration (or running `/terminal-setup`) to fix garbled glyphs

**Changed**

- `OTEL_RESOURCE_ATTRIBUTES` values are now included as labels on metric datapoints, so you can slice usage metrics by custom dimensions like team or repo
- `claude agents` rows now show `done/total` before the detail when work is fanned out; peek shows the longest-running item
- `/mcp` now collapses claude.ai connectors you’ve never signed in to behind a “Show unused connectors” row
- Parallel tool calls: a failed Bash command no longer cancels other calls in the same batch — each tool returns its own result independently
- Fullscreen mode: clipboard now uses `wl-copy`/`xclip`/`xsel` on Linux when available, copies to both the clipboard and PRIMARY selection for middle-click paste, and the “hold `{key}` for native selection” hint now shows the correct key per terminal

**Improved**

- Improved terminal rendering performance by stabilizing the layout engine’s JIT compilation profile
- Improved rendering performance for large file writes

Show 14 bug fixes

- Fixed the `/effort` dialog, workflow animations, and prompt keyword shimmer not honoring the “Reduce motion” setting
- Fixed `forceLoginOrgUUID`/`forceLoginMethod` managed-settings policies blocking third-party provider sessions (Bedrock, Vertex, Foundry, Mantle) alongside the org pin (regression in 2.1.146)
- Fixed background subagent output corrupting `claude -p` stdout when using `--output-format text` or `json`
- Fixed `/usage-credits` starting a re-login for Team and Enterprise admins instead of pointing to the organization’s usage settings page
- Fixed `/autofix-pr` reporting “cannot run on the default branch” when the session is inside a git worktree or another repository
- Fixed `--resume` picker not showing sessions from the current directory when it isn’t a git worktree (e.g., jj workspaces)
- Fixed Windows hooks that invoke bash explicitly (e.g., `/usr/bin/bash script.sh`) failing with “command not found” or “cannot execute binary file”
- Fixed OpenTelemetry log events (`user_prompt`, `api_request`, `tool_result`, `tool_decision`) being silently dropped when emitted before telemetry initialization completed
- Fixed `claude mcp` list/get/add printing secrets to the terminal: `${VAR}` references are no longer expanded, and credential headers and URL secrets are redacted
- Fixed Workflow agents spawned with `isolation: "worktree"` in background sessions being blocked from editing files inside their own worktree
- Fixed background sessions dispatched from `claude agents` booting on a stale model from the daemon’s environment instead of the model in `settings.json`
- Fixed a potential crash when rendering Write tool results after resuming a session
- Fixed completed subagents getting stuck showing as running when an error occurs while finalizing their result
- Fixed `EADDRINUSE` errors from tools that bind Unix sockets under `$TMPDIR` when `CLAUDE_CODE_TMPDIR` is set to a deep path

[​](#2-1-160)

2.1.160

June 2, 2026

**Added**

- Added a prompt before writing to shell startup files (`.zshenv`, `.zlogin`, `.bash_login`) and `~/.config/git/`, which could otherwise lead to unintended command execution

**Changed**

- `acceptEdits` mode now prompts before writing build-tool config files that grant code execution (`.npmrc`, `.yarnrc*`, `bunfig.toml`, `.bazelrc`, `.pre-commit-config.yaml`, `.devcontainer/`, etc.)
- Edit no longer requires a separate Read after viewing a file with `grep`: single-file `grep`/`egrep`/`fgrep` commands now satisfy the read-before-edit check
- Removed `CLAUDE_CODE_OPUS_4_6_FAST_MODE_OVERRIDE`; the environment variable is now a no-op
- Removed the JetBrains plugin install suggestion from startup
- Renamed the dynamic-workflow trigger keyword from `workflow` to `ultracode`. The word “workflow” no longer triggers a run; asking for one in your own words still works. The trigger keyword is highlighted in violet in the prompt input

**Improved**

- Improved performance of opening recently-inactive background agent sessions in `claude agents`
- Improved auto mode classifier latency by reducing reasoning on routine actions, lowering the chance of “could not evaluate this action” blocks
- Improved background-session teardown (`claude rm`/`stop`, idle reap) to send SIGTERM to running shell subprocesses before SIGKILL, so cleanup handlers run

Show 18 bug fixes

- Fixed copy-on-select not writing to the Windows clipboard on WSL — now uses PowerShell interop instead of OSC 52, which terminals like MobaXterm don’t support
- Fixed restoring a completed session from `claude agents` dropping chat history and re-running the original prompt
- Fixed background sessions re-attached after overnight retire losing their conversation and re-running the original prompt
- Fixed `claude --bg` occasionally failing with “socket missing” when the background daemon was cold-starting on a loaded machine
- Fixed an issue on Windows where the directory a background session was started in could not be deleted after `claude rm` until the background daemon exited
- Fixed background agents that resumed work being shown under Completed in the agents list
- Fixed `claude agents` freezing for several seconds when returning to the session list due to the auto-updater re-checking on every exit
- Fixed Esc, arrow keys, and typing becoming unresponsive on Windows when attached to a background session or in the agent view while the host is under heavy CPU load
- Fixed background agents emitting terminal sync-output markers to terminals that don’t support them (Apple Terminal, tmux), causing render artifacts when entering a running agent
- Fixed mouse wheel scrolling prompt history instead of the transcript right after opening a session from the agents list
- Fixed CJK IME composition appearing at the bottom-left of the screen instead of at the input caret in the `claude agents` view
- Fixed valid `file:///C:/...` links being rewritten to a broken path on Windows terminals with hyperlink support
- Fixed voice mode failing to connect when the project directory or branch name contains non-ASCII or special characters
- Fixed the auto mode unavailability message on third-party providers (Bedrock/Vertex/Foundry) to point to the `CLAUDE_CODE_ENABLE_AUTO_MODE` opt-in instead of incorrectly blaming the model
- Fixed `/effort ultracode` incorrectly blaming the dynamic workflows setting when the model cannot run xhigh; ultracode is no longer offered on models that do not support it
- Fixed model-not-found errors suggesting `--model` when running via the SDK or other hosts where the CLI flag doesn’t apply
- Fixed Claude’s past replies disappearing from scrollback when resuming a brief mode session with brief mode turned off
- Fixed vim mode `p` pasting on the line below instead of at the cursor when the register was yanked with `v$`

[​](#2-1-159)

2.1.159

May 31, 2026

- Internal infrastructure improvements (no user-facing changes)

[​](#2-1-158)

2.1.158

May 30, 2026

- Auto mode is now available on Bedrock, Vertex, and Foundry for Opus 4.7 and Opus 4.8. Opt in by setting `CLAUDE_CODE_ENABLE_AUTO_MODE=1`

[​](#2-1-157)

2.1.157

May 29, 2026

**Added**

- Added `claude plugin init <name>` to scaffold a new plugin in `.claude/skills`
- Added autocomplete for `/plugin` arguments: subcommands, installed plugin names, and plugins from known marketplaces
- Added a “Workflow keyword trigger” setting in /config to stop the word “workflow” in a prompt from triggering a dynamic workflow

**Changed**

- Plugins in `.claude/skills` directories are now automatically loaded, no marketplace required
- `claude agents`: the `agent` field in `settings.json` is now honored for dispatched sessions, with `--agent <name>` to override it
- `EnterWorktree` can now switch between Claude-managed worktrees mid-session
- `tool_decision` telemetry events now include `tool_parameters` (bash commands, MCP/skill names) when `OTEL_LOG_TOOL_DETAILS=1`
- Worktrees managed by Claude are now left unlocked when the agent finishes, so `git worktree remove`/`prune` can clean them up
- `/terminal-setup` now disables GPU acceleration in VS Code/Cursor/Windsurf integrated terminals to prevent garbled-text rendering
- The Feature of the Week credit-claim status now appears as a notification in the status area instead of a line above the prompt
- `claude agents`: slash-command autocomplete in the dispatch input now matches substrings
- Removed the “bash commands will be sandboxed” startup banner — sandbox status still shows in `/status` and when a command is blocked
- Removed the “/ide for …” startup hint toast
- Pressing backspace right after a workflow trigger keyword now dismisses the workflow request (same as alt+w) instead of deleting a character

**Improved**

- Improved performance of long and resumed conversations by eliminating redundant message-rendering recomputations

Show 18 bug fixes

- Fixed unprocessable images (zero-byte, corrupt) attached via paste, MCP, or dialog crashing the request instead of becoming a text placeholder
- Fixed sandbox network permission prompts appearing in auto and bypass-permissions mode when using the desktop app, IDE extensions, or SDK
- Fixed `claude agents` completed sessions not retiring when an idle subagent was still parked or had leaked a backgrounded shell
- Fixed `claude agents` pressing Esc not cancelling a slow “opening…”, leaving the list unresponsive
- Fixed background agent worktrees under `.claude/worktrees/` being orphaned after the 30-day job retention sweep
- Fixed background sessions re-attached after a sleep/wake not telling the model the correct date
- Fixed copy-on-select in `claude agents` not reaching the system clipboard inside tmux with `set-clipboard on` (regression in 2.1.153)
- Fixed `--resume` not reporting background subagents that were running when the previous Claude Code process exited
- Fixed the `--resume` session picker leaving its contents on the terminal after exiting in fullscreen mode
- Fixed `--worktree` and `--worktree --tmux` returning to the canonical repo root instead of the current linked worktree
- Fixed the `/model` picker showing an incorrect “Newer version available” hint when the selected model is already the newest in its family; the pinned-model row now shows the model’s description instead of its raw ID
- Fixed literal markdown markers (backticks, asterisks) appearing in the in-progress message text in fullscreen mode
- Fixed the terminal freezing after approving the managed-settings security dialog at startup
- Fixed a rare duplicate line appearing in scrollback after the terminal UI redraws
- Fixed right-click paste duplicating the clipboard in the VS Code, Cursor, and Windsurf integrated terminals
- WSL: fixed image paste (`alt+v` keybinding), screenshot paste on Windows 11, and added support for dragging images from Windows Explorer
- \[IDE\] Fixed clicking Stop while a background subagent is running not actually stopping it
- \[VSCode\] Fixed the fast mode indicator not appearing on Opus 4.8

[​](#2-1-156)

2.1.156

May 29, 2026

- Fixed an issue when using Opus 4.8 where thinking blocks were modified, leading to API errors.

[​](#2-1-154)

2.1.154

May 28, 2026

**Added**

- Introducing dynamic workflows: ask Claude to create a workflow and it orchestrates work across tens to hundreds of agents in the background, so you can take on larger, more complex tasks. Run `/workflows` to view your runs
- Added Claude Opus 4.8 support and 4.7 → 4.8 migration guidance to the `/claude-api` skill

**Changed**

- Opus 4.8 is here! Now defaults to high effort · /effort xhigh for your hardest tasks
- Fast mode on Opus 4.8 is now available at a fraction of its previous cost: 2x the standard rate for 2.5x the speed
- The lean system prompt is now the default for all models except Haiku, Sonnet, and Opus 4.7 and earlier
- Claude now reserves the multiple-choice question prompt for decisions it genuinely cannot make itself, instead of asking when it already has enough context to proceed
- `/simplify` now runs a cleanup-only review (reuse, simplification, efficiency, altitude) and applies the fixes, instead of running the full `/code-review --fix` bug-hunting review
- Renamed the `/effort` slider labels from “Speed”/“Intelligence” to “Faster”/“Smarter” for clarity
- `claude agents`: type `! <command>` to run a shell command as a background session you can attach to and detach from. Also available as `claude --bg --exec '<command>'`
- `claude agents`: `/logout` now signs you out instead of being sent to a background session
- `←←` to open the agents view now works on Bedrock, Vertex, Foundry, and with telemetry disabled
- Claude in Chrome: pick which connected browser to use via `/chrome` → “Select browser…”, or in-chat when a browser action runs with multiple connected
- Plugins can now declare `defaultEnabled: false` in `plugin.json` or a marketplace entry; enable them with `/plugin` or `claude plugin enable`. Dependencies of enabled plugins are still enabled automatically
- The `/plugin` Discover tab now pins plugins whose relevance signals match the current directory with a “suggested for this directory” annotation
- Streaming tool execution is now always enabled, including when telemetry is disabled or on Bedrock/Vertex/Foundry (previously behind a feature flag)
- Stdio MCP server subprocesses now receive `CLAUDE_CODE_SESSION_ID` and `CLAUDECODE=1` in their environment
- `claude mcp list`/`get` now show unapproved `.mcp.json` servers as `⏸ Pending approval` instead of auto-approving and connecting when output is piped
- `/remote-control` autocomplete now shows “Disconnect Remote Control” when Remote Control is already active
- Deprecated `CLAUDE_CODE_OPUS_4_6_FAST_MODE_OVERRIDE` (will be removed on 06/01). To use fast mode on Opus 4.6, switch with `/model claude-opus-4-6[1m]` and then `/fast on`
- Removed the stale ”& for background” hint from the shortcuts help panel
- \[VSCode\] Auto mode no longer requires the bypass-permissions setting to appear in the mode picker, and a dismissable notice on the new-session screen explains auto mode the first time it’s active

**Improved**

- Improved the auto-mode classifier’s detection of data exfiltration, particularly bulk transfers of repository contents

Show 22 bug fixes

- Fixed `rm -rf $HOME` not being blocked as a dangerous path when `HOME` has a trailing slash
- Fixed `$TMPDIR` resolving to different directories in sandboxed vs unsandboxed Bash commands within the same session
- Fixed unreadable highlighted-row text in `claude agents` when the Claude Code theme doesn’t match the terminal background
- Fixed background-agent completion notifications triggering premature “out of context” behavior on some 1M-context models
- Fixed background-session classifier losing the user’s goal when a scheduled `/command` fires
- Fixed pinned background sessions respawning every minute after a Claude Code update, causing repeated agent-start notifications and process churn at idle
- Fixed background sessions stuck at “blocked”, “running”, or “working” not retiring after the idle grace period
- Fixed subagents in background sessions bypassing the worktree-isolation guard and writing to the shared checkout
- Fixed orphaned `claude --bg-pty-host` processes spinning at 100% CPU after the daemon exits on macOS
- Fixed number key shortcuts not working for options shown below the divider in option dialogs
- Fixed `worktree.baseRef: "head"` resolving to the main checkout’s HEAD instead of the current worktree’s HEAD when spawning subagents or calling `EnterWorktree` from inside a linked worktree
- Fixed a stray leading space on wrapped lines when the previous line ended exactly at the terminal width
- Fixed intermittent terminal rendering corruption in VS Code by capping the number of distinct colors the thinking spinner produces
- Fixed plan file names including `[Image #N]` / `[Pasted text #N]` placeholders when a plan-mode prompt starts with pasted images or text
- Fixed a phantom expand/click affordance on colored tool output: short ANSI-colored lines that fit on screen no longer show a “ctrl+o to expand” hint
- Fixed a single invalid `allowedMcpServers`/`deniedMcpServers` entry in managed settings discarding all managed-settings policy; the bad entry is now dropped with a `claude doctor` warning
- Fixed API 400 errors on models that don’t support the effort parameter when `CLAUDE_CODE_ALWAYS_ENABLE_EFFORT` is set
- Windows: Fixed update failures caused by `claude.exe` being in use showing a generic error instead of telling you to close other sessions and retry
- Fixed the task panel below the prompt showing a stray unselectable “main” row when only a workflow is running
- Fixed /mcp tools list and tool detail rendering when MCP servers have long or multi-line tool names or long descriptions
- Fixed the /model picker not showing fast mode pricing on the Default option for API (pay-as-you-go) users when fast mode is on
- Fixed auto mode incorrectly blocking actions with “could not evaluate this action” when the safety classifier ran out of output tokens while reasoning

[​](#2-1-153)

2.1.153

May 28, 2026

**Added**

- Added `skipLfs` option to `github`/`git` plugin marketplace sources to skip Git LFS downloads during clone and update

**Changed**

- Claude Code now shows a one-time notice when your npm global install can’t auto-update; `/doctor` lists the fixes
- Status line commands now receive `COLUMNS` and `LINES` environment variables so scripts can size output to the terminal width
- `claude agents`: autocomplete in the dispatch input now suggests native slash commands and bundled skills, not just project skills
- `claude agents`: PR column now shows `PR #N` for a single PR or `N PRs` for multiple
- `claude doctor` now shows the result of your last update attempt
- Combined the separate “needs authentication” startup notifications for MCP servers and connectors into a single message
- macOS: background agents now appear as “Claude Code” in Privacy & Security and keep their permission grants across upgrades
- `--strict-mcp-config` no longer strips inline `mcpServers` from explicitly-passed agent definitions (`--agents` / SDK `agents`), and blocked subagent MCP servers now surface a visible warning
- `/bg` while Claude is responding now continues the response in the background session instead of dropping it
- `/model` now saves your selection as the default for new sessions (matching the IDE). Press `s` in the picker to switch models for the current session only.
- If you customized the `modelPicker:setAsDefault` keybinding, rename it to `modelPicker:thisSessionOnly` in keybindings.json (the `d` action was replaced by `s`)

Show 24 bug fixes

- Fixed stateful MCP servers without the optional GET SSE stream reconnect-looping on `tools/list` (regression in v2.1.147)
- Fixed a regression where a custom API gateway could receive the user’s Anthropic OAuth credential instead of the gateway’s own token
- Fixed subagent (Agent tool) frontmatter MCP servers ignoring `--strict-mcp-config`, `--bare`, remote mode, enterprise managed MCP config, and managed-settings MCP server allow/deny policies
- Fixed the Windows PowerShell installer reporting “Installation complete!” when installation actually failed
- Fixed `claude update` installing the latest version instead of the configured release channel’s version for npm installations
- Fixed excessive memory usage (multiple GB) when resuming a session by transcript file path on machines with many stored sessions
- Fixed `claude agents` and `claude --bg` running on a stale daemon started before binary-takeover support, even after upgrading
- Fixed a hang where the CLI could fail to exit when stdin was closed without EOF in stream-json mode, leaving a stale session marker behind
- Fixed malformed `file://` links in Claude’s responses not being clickable in the terminal
- Fixed `claude --help` rendering unwrapped output on terminals narrower than 92 columns
- Fixed MCP tool progress notifications not rendering in the collapsed tool view
- Fixed `Agent` tool with `subagent_type: 'claude'` running in an undocumented temporary worktree, which could silently discard outputs written to gitignored paths
- Fixed `/btw` keyboard shortcuts becoming unresponsive in background sessions while a task is running
- Fixed background sessions writing temp files to `$CLAUDE_JOB_DIR` triggering a “sensitive file” permission prompt
- Fixed recovering a background agent whose working directory was deleted showing a truncated stack trace instead of a clear error message
- Fixed `EnterWorktree` not being available immediately in background sessions (previously required `ToolSearch` first)
- Fixed `cmd+k` in iTerm2/Terminal.app not repainting attached background sessions
- Fixed the IME candidate window appearing at the bottom of the screen instead of next to the input caret in attached background sessions on Windows
- Fixed background-color bleed when attaching to a background agent from 256-color-only terminals after the agent had rendered file diffs
- Fixed `/copy` and copy-on-select silently failing to update the system clipboard when attached to a background session inside tmux
- Fixed opening `claude agents` with Remote Control enabled leaving zombie session entries on the Code tab after exiting
- Fixed `/rename` in background sessions not updating the session banner immediately
- Fixed Windows update rollback: if a Windows update fails, Claude Code now restores the original executable by copy and tells you how to recover
- \[VSCode\] Fixed Claude Code processes not shutting down cleanly when VS Code closed on Windows, causing false “unclean exit” reports and orphaned MCP servers

[​](#2-1-152)

2.1.152

May 27, 2026

**Added**

- Added `/reload-skills` command to re-scan skill directories without restarting the session
- Added a `MessageDisplay` hook event that lets hooks transform or hide assistant message text as it is displayed
- Added `pluginSuggestionMarketplaces` managed setting: admins can allowlist org marketplaces whose plugins may be suggested via context-aware tips
- Added the session entrypoint as an OpenTelemetry metric attribute (`app.entrypoint`, opt-in via `OTEL_METRICS_INCLUDE_ENTRYPOINT=true`)

**Changed**

- `/code-review --fix` now applies review findings to your working tree after the review, surfacing reuse, simplification, and efficiency suggestions; `/simplify` now invokes `/code-review --fix`
- Skills and slash commands can now set `disallowed-tools` in frontmatter to remove tools from the model while the skill is active
- `SessionStart` hooks can now return `reloadSkills: true` to re-scan skill directories, making skills installed by the hook available in the same session
- `SessionStart` hooks can now set the session title via `hookSpecificOutput.sessionTitle` on startup and resume
- `claude plugin marketplace remove` now accepts `--scope user|project|local` for symmetry with `marketplace add`, `install`, and `uninstall`
- Claude Code now switches to your configured `--fallback-model` for the rest of the session when the primary model is not found, instead of failing every request
- Auto mode no longer requires opt-in consent
- Vim mode: `/` in NORMAL mode now opens reverse history search (like Ctrl+R), matching bash/zsh vi-mode
- The `/usage` breakdown now includes large session files; files are scanned with a streaming read so memory usage stays flat
- Thinking summaries in the collapsed group now stay readable for at least 3 seconds, render as markdown, and cap at 10 lines (`Ctrl+O` shows the full thinking)
- In fullscreen mode, the “Thinking for Ns” indicator now counts up live while the model is thinking, and keeps its value if you interrupt mid-thought
- Simplified the Workflow tool’s inline progress display — live agent counts now show only in the persistent workflow status row below the prompt
- The post-response timer now shows “Waiting for N background agents/workflows to finish” when backgrounded agents or workflows are still running, and reports the cumulative time once their results are processed

Show 16 bug fixes

- Fixed terminal styling degrading in very long sessions by recycling the renderer’s style pool
- Fixed the sandbox-enabled warning not appearing in condensed startup mode — it now shows in every layout
- Fixed the loading spinner showing “still thinking”/“almost done thinking” while a tool is running, and reset the thinking status to “thinking” after each tool
- Fixed focus mode showing a spurious “N messages hidden” count on turns with no hidden activity
- Fixed clicking a link inside an expanded tool result collapsing the section instead of opening the link
- Fixed markdown table cell borders inheriting the color of inline code, wrapped continuation lines losing their style, and empty header cells showing a label in the narrow-terminal stacked layout
- Fixed plugin MCP servers with the same command but different environment variables being incorrectly deduplicated
- Fixed `/doctor` reporting “marketplace not found” or “plugin not found” for stale `enabledPlugins` entries referencing removed marketplaces or dropped plugins
- Fixed plugins that track a git branch silently no longer receiving updates after the plugin registry was rebuilt
- Fixed remote MCP servers failing to connect in Claude Code Remote sessions when the egress proxy is enabled
- Fixed the effort-change confirmation dialog appearing when the conversation has no messages or when switching between effort levels that resolve to the same underlying value
- Fixed the Agent tool description referencing an agent list that is never delivered when running with `--bare` or with attachments disabled
- Fixed a background worker crash in `claude agents` when accepting a stale permission prompt after a subagent was cancelled
- Fixed `cache_creation_input_tokens` reporting as 0 in transcript and result usage when the API reports cache writes only via the nested `cache_creation` breakdown
- Fixed the PushNotification tool incorrectly reporting “Mobile push not sent (Remote Control inactive)” in SDK-hosted sessions when Remote Control is enabled
- Fixed sessions getting stuck after a model or login switch left stale thinking-block signatures in history; now stripped proactively with a retry safety-net

[​](#2-1-150)

2.1.150

May 23, 2026

- Internal infrastructure improvements (no user-facing changes)

[​](#2-1-149)

2.1.149

May 22, 2026

**Added**

- Enterprise: added the `allowAllClaudeAiMcps` managed setting to load claude.ai cloud MCP connectors alongside `managed-mcp.json`

**Changed**

- `/usage` now shows a per-category breakdown of what’s driving your limits usage — skills, subagents, plugins, and per-MCP-server cost
- `/diff` detail view can now be scrolled with the keyboard (arrows, `j`/`k`, `PgUp`/`PgDn`, `Space`, `Home`/`End`)
- Markdown output now renders GFM task list checkboxes (`- [ ] todo` / `- [x] done`) instead of plain bullets

**Improved**

- Improved `/feedback` reports to include the conversation that happened before context compaction, making issues from earlier in long sessions easier to triage

Show 21 bug fixes

- Fixed a PowerShell permission bypass: built-in `cd` functions (`cd..`, `cd\`, `cd~`, `X:`) changed the working directory undetected, letting a later command read outside the workspace
- Fixed the sandbox write allowlist in git worktrees covering the entire main repository root instead of only the shared `.git` directory (with `hooks/` and `config` denied)
- Fixed PowerShell prefix/wildcard allow rules (e.g. `PowerShell(dotnet.exe build *)`) not pre-approving native executables and scripts
- Fixed a permission-analysis gap where the parser trusted stale variable-tracking values for `PWD`/`OLDPWD`/`DIRSTACK` across `cd`/`pushd`/`popd`
- Fixed `find` in the Bash tool exhausting the macOS system file/vnode table and crashing the host on large directory trees
- Fixed the managed-settings approval dialog leaving the terminal frozen after accepting at startup
- Fixed `/ultraplan` and remote session creation failing with “Could not capture uncommitted changes” when the working tree has no real changes
- Fixed `otelHeadersHelper` failing silently when the script path contains spaces; helper failures are now reported in `/doctor` and the debug log
- Fixed the thinking spinner staying amber across tool calls and onto fresh thinking bursts
- Fixed collapsed Bash output reporting the wrong hidden-line count for outputs with many short lines
- Fixed slash-command argument-hint clipping trailing typed characters when the hint overflows the input box
- Fixed argument-hint and progressive arg suggestions not appearing after Tab-completing a skill whose frontmatter `name:` differs from its directory basename
- Fixed the status bar showing the user’s baseline `/effort` setting instead of the effort level applied by skill/agent `effort:` frontmatter
- Fixed Ctrl+O transcript view freezing at the moment it was opened instead of tailing new messages
- Fixed editing a recalled prompt-history entry losing the edit when navigating further up/down with arrow keys
- Fixed `/config` exit summary reporting phantom changes to auto-compact and theme when toggling unrelated settings
- Fixed `/insights` crashing when cached session-meta files are missing optional fields
- Fixed malformed PowerShell and History tool calls with missing input being misclassified as reads in transcript collapsing
- Fixed renaming a Remote Control session from claude.ai or the Claude mobile app not updating the local session name for `claude --resume`
- Fixed a race where a just-submitted prompt could appear twice in the up-arrow history
- Fixed tapping the “Jump to bottom” pill in fullscreen mode not dismissing it immediately

[​](#2-1-148)

2.1.148

May 22, 2026

- Fixed the Bash tool returning exit code 127 on every command for some users (a regression introduced in 2.1.147)

[​](#2-1-147)

2.1.147

May 21, 2026

**Changed**

- Pinned background sessions (`Ctrl+T` in `claude agents`) now stay alive when idle, are restarted in place to apply Claude Code updates, and are shed under memory pressure only after non-pinned sessions
- Renamed `/simplify` to `/code-review`. It now reports correctness bugs at a chosen effort level (e.g., `/code-review high`); pass `--comment` to post findings as inline GitHub PR comments. The old cleanup-and-fix behavior has been removed
- Prompt history no longer records consecutive duplicate entries — recalling a prompt with arrow-up and submitting it again won’t add another copy

**Improved**

- Improved auto-updater: retries transient network failures, reports specific error categories and OS error codes on failure, and shows the current version when an update fails
- Improved diff rendering performance for large file edits

Show 28 bug fixes

- Fixed enterprise login restrictions (`forceLoginOrgUUID` and `forceLoginMethod` managed-settings) not being enforced against third-party-provider and API-key sessions
- Fixed `&` in `!` command output displaying as `&amp;`, which broke copy-pasting URLs from commands like `gcloud auth login` on headless machines
- Fixed unknown slash commands silently doing nothing in headless/SDK mode — they now show an error message
- Fixed `/help` rendering a broken tab header and showing only one command per page on small terminals when not in fullscreen mode
- Fixed shell snapshot dropping user functions whose names start with a single underscore, which broke aliases referencing them
- Fixed plugin agents that declare multiple `Agent(...)` types in `tools:` frontmatter dropping all but the last entry
- Fixed hook `if` conditions like `PowerShell(git push*)` never matching — only `PowerShell(*)` worked
- Fixed PowerShell tool dropping output for commands that rely on the default formatter
- Fixed: on Windows, “Yes, and don’t ask again” for a PowerShell script invocation now writes a rule that actually matches on subsequent runs
- Fixed PowerShell tool failing on Windows with exit code 1 when `pwsh` is installed via winget or the Microsoft Store
- Fixed `/effort` opening with the slider on the wrong level — it now starts at your current effort
- Fixed paginating MCP servers dropping resources, templates, and prompts past page 1
- Fixed full-screen strobing in attached background sessions on Windows Terminal while Claude is streaming
- Fixed: on Windows, removing a background-job worktree no longer follows NTFS junctions into the main repo
- Fixed `/background` refusing sessions whose only typed input was a skill or custom slash command
- Fixed auto mode suppressing `AskUserQuestion` when the user or a skill explicitly relies on it; the auto-mode classifier now sees the user’s answers as intent signal
- Fixed `/theme` “New custom theme” and color editor dialogs not responding to Esc
- Fixed an uncaught exception at the end of streaming sessions when running via the Agent SDK
- Fixed a rare hang when waiting for scroll to settle on Windows
- Fixed stale and doubled rows in the agent view list on Windows when background session results contain wide (CJK) characters
- Fixed pasted text being delivered to agents as an unreadable `[Pasted text #N]` placeholder instead of the actual content
- Fixed plugin component counts in `claude plugin details` and `/plugin` being doubled when a plugin’s manifest listed paths overlapping its default directories
- Fixed backgrounded sessions re-prompting for tool permissions you already granted with “don’t ask again”
- Fixed GNOME Terminal right-click and middle-click paste not inserting text
- Fixed `CLAUDE_CODE_SUBAGENT_MODEL` not applying to teammate processes spawned by agent teams
- Fixed slash commands followed by a tab or newline being treated as an unknown command
- Fixed several spacing and layout glitches in the `/plugin`, `/status`, `/mobile`, `/sandbox`, and `/permissions` menus
- Fixed stripped images prompting the model to repeatedly re-read media that was no longer present

[​](#2-1-145)

2.1.145

May 19, 2026

**Added**

- Added `claude agents --json` to list live Claude sessions as JSON for scripting (tmux-resurrect, status bars, session pickers)
- Added `agent_id` and `parent_agent_id` attributes to `claude_code.tool` OTEL spans, and fixed trace parenting so background subagent spans nest under the dispatching Agent tool span

**Changed**

- Status line JSON input now includes GitHub repo and PR information when detected
- `/plugin` Discover and Browse screens now show a plugin’s commands, agents, skills, hooks, and MCP/LSP servers before installation
- `claude agents` terminal tab title now shows the awaiting-input count so an alt-tabbed window tells you when an agent needs attention
- Slash command and @-mention suggestion list now supports mouse hover and click in fullscreen mode
- Stop and SubagentStop hook input now includes `background_tasks` and `session_crons` fields

**Improved**

- Improved the Read tool to return a truncated first page with a “PARTIAL view” notice instead of a hard error when a whole-file read exceeds the token limit

Show 12 bug fixes

- Fixed a permission-prompt bypass where bare variable assignments to non-allowlisted environment variables in Bash commands were auto-approved
- Fixed MCP prompt slash commands showing raw server validation errors when a required argument is omitted — the error now names the missing argument and shows expected usage
- Fixed the spinner and elapsed-time display freezing until a keypress after the terminal was resized or refocused
- Fixed the cross-project resume hint failing in default Windows PowerShell 5.1 — Windows now uses `;` as the command separator
- Fixed voice push-to-talk not working in the agent view’s reply pane
- Fixed task lists rendering in random order when several tasks are created at once
- Fixed stale “Failed to install Anthropic marketplace” banner showing when the marketplace is already installed
- Fixed the PR badge in the footer not updating immediately after `gh pr create` and other PR-state-changing commands run in-session
- Fixed Agent Teams teammates with non-ASCII names failing every API call due to invalid header encoding
- Fixed `/review` using a deprecated `projectCards` GraphQL query that errored on repos with Classic Projects
- Fixed `claude plugin validate` not flagging `skills:` entries that point at a file instead of a directory — the error now suggests the parent directory
- Fixed an infinite loop where a skill using `context: fork` could repeatedly re-invoke itself instead of running

[​](#2-1-144)

2.1.144

May 19, 2026

**Added**

- Added `/resume` support for background sessions — sessions started via `claude --bg` or agent view now appear alongside interactive ones, marked with `bg`
- Added elapsed duration to background subagent completion notifications (e.g. “Agent completed · 3h 2m 5s”)

**Changed**

- The `/plugin` browse and discover panes now show when a plugin was last updated
- `/model` now changes the model for the current session only; press `d` in the model picker to set a default for new sessions
- Renamed “extra usage” to “usage credits” across CLI copy; `/extra-usage` is now `/usage-credits` (old name still works)
- Reduced terminal rendering glitches in VS Code by reducing spinner animation color count
- Fewer spurious tool errors during search: `head`/`tail` file views now satisfy the read-before-edit check, and a “no matches” result (exit code 1) from `egrep`, `fgrep`, `git grep`, or `git diff` is no longer reported as a command failure
- Resumed sessions now keep the model they were using instead of picking up another session’s `/model` choice
- `/bg` and `←`-detach now preserve directories added via `/add-dir`
- `claude agents` / `--bg` rejection messages now name the specific gate (non-TTY, env var, or setting) instead of a generic message
- `claude --bg --name <label>` now echoes the name in the post-spawn confirmation
- `claude agents`: renaming a background session with Ctrl+R now updates the attached session’s banner immediately
- Background session worktree isolation guard now applies for non-git VCS users with `WorktreeCreate` hooks configured
- Plugin marketplace add/update now respects `CLAUDE_CODE_PLUGIN_PREFER_HTTPS`
- `/plugin` now returns to the Installed list after enabling, disabling, or uninstalling a plugin
- `/doctor` now shows an exec-form example when a command hook is missing the `command` field
- Skill-listing truncation is no longer shown as a startup notification — run `/doctor` for the full breakdown
- The post-survey follow-up hint now appears after every non-dismiss survey response with context-aware copy, making it easier to share more detail via /feedback.

**Improved**

- Improved recovery from rare pre-response stream stalls — now retries streaming once instead of falling back to a slower non-streaming request
- Improved SDK/headless MCP startup: pre-wait now overlaps startup instead of blocking before the first turn (up to 2s faster with slow MCP servers)

Show 30 bug fixes

- Fixed startup hanging up to 75s when `api.anthropic.com` is unreachable (captive portal, firewall, VPN issues) — side-channel API calls now time out after 15s
- Fixed garbled terminal output after a missed window-resize event (e.g. dragging a VS Code split-pane divider) — now self-heals on the next frame instead of requiring Ctrl+L
- Fixed progressive terminal display corruption (stale/garbled glyphs) that could appear in very long sessions and only cleared on terminal resize or restart
- Fixed macOS background sessions crashing with “exit 1 before init” when the project lives under a Full Disk Access-protected folder (regression in 2.1.143)
- Fixed an unrecoverable conversation when reading a file whose image extension doesn’t match its contents (e.g. HTML saved as .png) — now falls back to text
- Fixed `/branch` failing with “No conversation to branch” after entering a worktree or in some background sessions
- Fixed pressing Escape in the AskUserQuestion notes field aborting the turn instead of returning to answer selection
- Fixed model selection not applying when changed via the IDE model picker or `applyFlagSettings` after startup
- Fixed Bedrock and Vertex users unable to select “Opus (1M context)” from the `/model` picker (regression in v2.1.129)
- Fixed remote-session login failing with “Can’t access this organization” for users with `forceLoginMethod` and `forceLoginOrgUUID` set
- Fixed MCP servers with paginated `tools/list` responses only returning the first page, silently dropping tools
- Fixed MCP images with unsupported MIME types (e.g. SVG) breaking the conversation — now saved to disk and referenced in the tool result
- Fixed file descriptor exhaustion when a build runs inside a skill directory — non-`.md` files no longer trigger skill reloads
- Fixed session title being generated from plugin monitor output instead of the user’s first prompt
- Fixed Skill tool failing with permission error in headless mode (regression in v2.1.141)
- Fixed plugins enabled in your own settings showing “not cached” errors after first load on a fresh machine; plugins enabled only by a project’s `.claude/settings.json` now show an actionable `claude plugin install` hint
- Fixed `claude mcp list` silently reporting no servers when `.mcp.json` can’t be parsed (e.g. using VS Code’s `"servers"` key instead of `"mcpServers"`) — now shows configuration errors
- Fixed background side-queries on custom `ANTHROPIC_BASE_URL` setups and Bedrock Mantle not using Haiku — now falls back correctly when a first-party API key is configured or no Haiku model is set
- Fixed scrolling in attached background sessions on Windows — PgUp/PgDn, mouse wheel, and Ctrl+O transcript navigation now work
- Fixed a crash when closing the terminal while attached to a background session
- Fixed on Windows, pressing ← in `claude agents` leaving the list unresponsive to keyboard input
- Fixed ghost characters at the left edge when switching panes in Agent View on Windows Terminal with CJK content
- Fixed Edit/Write refusing with “background session hasn’t isolated its changes yet” right after detaching a session that was already editing in place
- Fixed `claude respawn <id>` on a stopped background session showing “stopped” instead of running
- Fixed `/resume` picker not showing sessions forked from a background session
- Fixed opening a session from `claude agents` or running `claude logs <id>` hanging when the background service is unresponsive — now times out after 10s with a recovery hint
- Fixed background Bash tasks spawned by subagents staying “Running” in SDK task panels after the process exits
- Fixed completed or stopped background sessions briefly failing to wake being permanently marked as a startup crash
- Fixed markdown links in `claude agents` attached sessions rendering as plain text instead of clickable hyperlinks
- Fixed custom `spinnerVerbs` applying to the post-turn duration message — past-tense built-ins like “Worked for 5s” are restored there

[​](#2-1-143)

2.1.143

May 15, 2026

**Added**

- Added plugin dependency enforcement: `claude plugin disable` now refuses when another enabled plugin depends on the target (with a copy-pasteable disable-chain hint), and `claude plugin enable` force-enables transitive dependencies
- Added projected context cost (per-turn and per-invocation token estimates) to the `/plugin` marketplace browse pane
- Added `worktree.bgIsolation: "none"` setting to let background sessions edit the working copy directly without `EnterWorktree`, for repos where worktrees are impractical

**Changed**

- PowerShell tool now passes `-ExecutionPolicy Bypass`. Opt out with `CLAUDE_CODE_POWERSHELL_RESPECT_EXECUTION_POLICY=1`
- Background sessions now preserve the model and effort level you set after waking from idle
- Shift+Tab in attached agent sessions now includes auto mode in the cycle
- The PowerShell tool is now enabled by default on Windows for Bedrock, Vertex, and Foundry users. Opt out with `CLAUDE_CODE_USE_POWERSHELL_TOOL=0`.
- `claude agents` now accepts `--add-dir`, `--settings`, `--mcp-config`, and `--plugin-dir` and applies them to the dashboard and to background sessions dispatched from it
- `claude agents` accepts `--permission-mode`, `--model`, `--effort`, and `--dangerously-skip-permissions` to set defaults for sessions dispatched from the view
- `claude --bg --dangerously-skip-permissions` now persists across retire→wake
- Worktree cleanup no longer falls back to `rm -rf` when `git worktree remove` fails, preventing loss of gitignored or in-progress files
- `/bg` now preserves `--mcp-config`, `--settings`, `--add-dir`, `--plugin-dir`, and `--strict-mcp-config`, so backgrounded sessions keep their MCP servers and settings across respawn.
- Background sessions launched from `claude agents` now honor `permissions.defaultMode` from settings.json (was previously overridden to auto mode)
- `/bg` and `←`-detach now preserve `--fallback-model`, so backgrounded workers degrade to the fallback model on overload instead of hard-failing.
- `/bg` and `←`-detach now preserve `--allow-dangerously-skip-permissions`, so the forked worker keeps bypass-permissions available in its Shift+Tab cycle.

Show 18 bug fixes

- Fixed a corrupt `.credentials.json` with a non-array `scopes` value hanging the CLI on startup or silently aborting OAuth token refresh
- Fixed right-click paste in `claude agents` on Windows Terminal and WSL
- Fixed stop hooks that block repeatedly looping forever — the turn now ends with a warning after 8 consecutive blocks (override via `CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`)
- Fixed Esc/Ctrl+C not cancelling a pending `/loop` wakeup while Claude is idle between iterations
- Fixed `/goal` evaluator firing while background shells or delegated subagents are still running
- Fixed `NO_COLOR`/`FORCE_COLOR` in settings.json `env` stripping Claude Code’s own UI colors — they now apply to subprocesses only
- Fixed agent view spawning repeated PowerShell processes on Windows when listing sessions
- Fixed `/bg` without a prompt sending “continue” to the forked session — the fork now waits for input
- Fixed `--agent <name>` not finding plugin-contributed agents without the `plugin:` prefix
- Fixed deleting a session from agent view not removing its transcript file
- Fixed stale-fragment rendering when scrolling in attached background sessions on Windows Terminal
- Fixed background agents false-positive worker-stall detection storm after host sleep or macOS App Nap
- Fixed 5xx error messages pointing at status.claude.com instead of naming the configured gateway or cloud provider
- Fixed background sessions silently capturing IDE file references into the warm spare’s input, which caused the reference to be prepended to the next prompt dispatched from `claude agents`
- Fixed background-job sessions on macOS getting “Operation not permitted” errors when reading files under `~/Documents`, `~/Desktop`, or `~/Downloads`, even with Full Disk Access granted.
- Fixed: on Windows, pressing ← in `claude agents` while a response was streaming could leave the agents list unresponsive to all input
- Fixed: background daemon spawn now falls back to the running binary when the `~/.local/bin/claude` launcher is missing or non-executable
- Fixed `claude agents --allow-dangerously-skip-permissions` defaulting dispatched sessions to bypass mode instead of making it available in the permission cycle

[​](#2-1-142)

2.1.142

May 14, 2026

**Added**

- Added new `claude agents` flags: `--add-dir`, `--settings`, `--mcp-config`, `--plugin-dir`, `--permission-mode`, `--model`, `--effort`, and `--dangerously-skip-permissions` to configure dispatched background sessions

**Changed**

- Fast mode now uses Opus 4.7 by default (previously Opus 4.6). Set `CLAUDE_CODE_OPUS_4_6_FAST_MODE_OVERRIDE=1` to pin fast mode to Opus 4.6
- Plugins with a root-level `SKILL.md` and no `skills/` subdirectory are now surfaced as a skill
- The `/plugin` details pane and `claude plugin details` now show LSP servers a plugin provides
- `/web-setup` warns before replacing an existing GitHub App connection
- Removed stale `/model claude-sonnet-4-20250514` suggestion from Usage Policy refusal messages

**Improved**

- Improved reactive compaction: the first summarize attempt now seeds from the original request’s overflow size, avoiding a wasted near-full-context retry
- Improved hook configuration error: configuring a prompt- or agent-type hook for `SessionStart`/`Setup`/`SubagentStart` now shows a clear “use a command-type hook instead” error

Show 16 bug fixes

- Fixed `MCP_TOOL_TIMEOUT` not raising the per-request fetch timeout for remote HTTP and SSE MCP servers, which capped tool calls at 60 seconds regardless of the configured value
- Fixed background sessions not recognizing pre-existing git worktrees, blocking Edit while EnterWorktree refused to create a duplicate
- Fixed background sessions disappearing and daemon reconnect failing after macOS sleep/wake — the daemon now detects clock jumps instead of treating them as elapsed idle time
- Fixed daemon not exiting cleanly after the binary is upgraded (e.g. `brew upgrade`), causing dispatched agents to crash-loop on the deleted path
- Fixed background agents crash-looping when the Claude-in-Chrome extension is connected without a shared tab
- Fixed clicking links in an attached `claude agents` session — the background worker’s headless browser shim no longer applies while attached
- Fixed `claude agents` “v to open in editor” using the daemon’s default editor instead of your shell’s `$EDITOR`/`$VISUAL`
- Fixed `claude agents` deadlocking on Windows with network-drive working directories; Ctrl+C now works during startup
- Fixed background-color bleed when attaching to a `claude agents` session from Apple Terminal or other 256-color-only terminals
- Fixed `claude --bg --dangerously-skip-permissions` not persisting across retire/wake
- Fixed session titles being derived from the URL when the first message is a link
- Fixed redundant `set_model` requests from remote clients injecting duplicate `/model` breadcrumbs into the transcript
- Fixed plugins using `skills: ["./"]` showing a false “path escapes plugin directory” error
- Fixed plugin cache cleanup deleting the active plugin version directory when no installation metadata is present
- Fixed `/plugin` browse pane showing “0 installs” for newly published plugins
- Fixed plugin advisories not naming every `plugin.json` key that shadows a default folder

[​](#2-1-141)

2.1.141

May 13, 2026

**Added**

- Added `terminalSequence` field to hook JSON output so hooks can emit desktop notifications, window titles, and bells without a controlling terminal
- Added `CLAUDE_CODE_PLUGIN_PREFER_HTTPS` to clone GitHub plugin sources over HTTPS instead of SSH, for environments without a GitHub SSH key
- Added `ANTHROPIC_WORKSPACE_ID` environment variable for workload identity federation — scopes the minted token to a specific workspace when the federation rule covers more than one
- Added `claude agents --cwd <path>` to scope the session list to a directory
- Rewind menu: added “Summarize up to here” to compress earlier context while keeping recent turns intact

**Changed**

- `/feedback` can now include recent sessions (last 24 hours or 7 days) for issues spanning more than the current session
- Auto mode permission dialog now explains when a `permissions.ask` rule caused the prompt
- Restored the “view diff in your IDE” option on file-edit permission prompts when an IDE is connected
- Background agents launched via `/bg` or `←←` now preserve the current permission mode instead of reverting to default
- `claude agents`: agents that finish work but leave a background shell running now move to Completed instead of staying under Working
- Bedrock: `awsCredentialExport` now always runs when configured instead of being skipped when ambient AWS credentials resolve, fixing auth for cross-account access
- \[VSCode\] Voice mode: the WSL error now suggests installing `sox libsox-fmt-pulse` for WSLg users
- `claude agents`: launching a session no longer fails when the pre-warmed background worker is unhealthy — now falls back to a fresh launch
- `claude agents` no longer shows empty placeholder sessions left over from backgrounding a fresh REPL, and shows onboarding text when entered via ← with no other agents
- Empty idle background sessions left over from `←` are now automatically retired by the daemon after 5 minutes

**Improved**

- Improved spinner feedback during long thinking periods — the spinner now warms to amber after 10 seconds to signal Claude is still working
- Improved plugin menu navigation: `→`/Tab switch tabs, `↑` moves to the tab strip, and tab headers and search box are clickable in fullscreen mode

Show 44 bug fixes

- Fixed background side-queries sending an unavailable Haiku model ID on Bedrock/Vertex/Foundry/gateway when no `ANTHROPIC_SMALL_FAST_MODEL` override is set — now falls back to the main-loop model
- Fixed `claude daemon status` and `/doctor` on Windows throwing when the daemon pipe key file is locked or unreadable — now shows the underlying error instead of an opaque failure
- Fixed `claude agents` showing the agent-type list instead of the dashboard when launched through a wrapper that adds flags
- Fixed `claude agents` opening a crashed session firing redundant dispatches when the working directory was deleted
- Fixed background jobs on a custom `ANTHROPIC_BASE_URL` gateway not getting auto-named — the namer now uses the main model when no Haiku model is configured
- Fixed `/model` in one session silently changing the autocompact threshold in other concurrent sessions
- Fixed switching permission mode while a tool-permission prompt is open not auto-dismissing the prompt when the new setting permits the tool
- Fixed pressing Enter while a permission/dialog prompt is open also submitting text in the input box
- Fixed hooks receiving a non-existent `transcript_path` after `EnterWorktree` switches the working directory
- Fixed markdown tables with cell wrapping falling back to the vertical key-value layout instead of rendering as a bordered grid (regression in 2.1.136)
- Fixed cancelled prompts being removed from Up-arrow history when auto-restored into the input box, avoiding duplicate entries
- Fixed prompts cancelled with Ctrl+C/Esc before any response being dropped from Up-arrow history
- Fixed Ctrl+C not interrupting a running turn while in vim INSERT/VISUAL mode
- Fixed alternative `chat:submit` keybindings (e.g. `meta+enter`, `ctrl+enter`) not working when `enter` is rebound to `chat:newline`
- Fixed prompt suggestions being silently disabled when an output style was configured
- Fixed `spinnerVerbs` setting not being honored in turn-completion messages
- Fixed AskUserQuestion popup hiding the last line of preceding chat content
- Fixed Web Search status showing “Did 0 searches” when searches returned errors
- Fixed multi-line statusline output dropping or corrupting rows when any line exceeds terminal width
- Fixed light-ansi theme using invisible white for diff context lines on light backgrounds — now uses black
- Fixed error overlay dumping minified bundle source that hid the original error message
- Fixed pressing Enter after typing a feedback survey rating digit submitting it as a chat message instead of the rating
- Fixed pressing `x` on a selected subagent in the agent panel typing into the prompt instead of stopping the agent
- Fixed session title being derived from plugin monitor notifications before the user’s first prompt
- Fixed “Allowed by PermissionRequest hook” repeating once per tool call under a collapsed read/search group
- Fixed `/tui` silently dropping running background shells and subagents — now refuses and asks to wait for them to finish
- Fixed welcome banner showing “API Usage Billing” on Bedrock, Vertex, Foundry, and other third-party providers — now shows the provider name
- Fixed `/mcp` server list not keeping the focused server visible in short terminals in fullscreen mode
- Fixed redaction in `/feedback` bundles producing invalid JSON for quoted values like session IDs
- Fixed desktop and third-party provider sessions incorrectly inheriting `apiKeyHelper`/`ANTHROPIC_AUTH_TOKEN` from host managed-settings
- Fixed early analytics events being silently dropped when fired before logger initialization
- Fixed `claude plugin install` failing for plugins whose marketplace `ref` no longer exists upstream when a `sha` is also pinned
- Fixed plugin details pane showing 0 MCP servers for plugins that declare them via `.mcp.json`
- Fixed plugin MCP servers with unset config variables showing a generic connection failure instead of a “config issue” message with a fix-it hint; malformed `.mcp.json` entries no longer drop other MCP servers
- Fixed MCP server configs using POSIX shell parameter expansions (e.g. `${var%pattern}`) being incorrectly flagged as missing environment variables
- Fixed MCP HTTP/SSE servers returning 403 on connect showing as “failed” instead of “needs auth”
- Fixed remote MCP servers disconnecting unnecessarily when the optional server-events stream failed to reconnect — tool calls continue over POST
- Fixed Remote Control MCP connectors all failing with 401 when the worker session token rotated mid-session
- Fixed Remote Control automatically re-enrolling a trusted device when the server rejects a stale token, instead of looping through `/login`
- Fixed a race where early OTel spans could be silently dropped in SDK/headless mode with beta tracing enabled
- Fixed custom `voice:pushToTalk` keybindings and `"space": null` unbinds being silently ignored
- Fixed Windows Alt+V image paste reporting “no image found” when the clipboard contains a screenshot
- Fixed SDK “Claude Code native binary not found” on Linux when both glibc and musl platform packages are installed
- \[VSCode\] Fixed in-chat mic showing no feedback when the microphone produced only silence — now shows “No audio detected”

[​](#2-1-140)

2.1.140

May 12, 2026

**Changed**

- Updated agent color palette
- Plugins now warn when a default component folder (e.g. `commands/`) is silently ignored because `plugin.json` sets the matching key. Shown in `/doctor`, `claude plugin list`, and `/plugin`.

**Improved**

- Improved Agent tool `subagent_type` matching to accept case- and separator-insensitive values (e.g. `"Code Reviewer"` resolves to `code-reviewer`)

Show 10 bug fixes

- Fixed `/goal` silently hanging when `disableAllHooks` or `allowManagedHooksOnly` is set — now shows a clear message instead of an indicator that never resolves
- Fixed a regression in settings hot-reload where symlinked settings files caused misattributed change events and spurious `ConfigChange` hooks
- Fixed `claude --bg` failing with “connection dropped mid-request” when the background service was about to idle-exit
- Fixed background service startup failing on machines with enterprise endpoint security by allowing more time
- Fixed remote managed settings not retrying on 401 — now retries once with a force-refreshed token
- Fixed managed `extraKnownMarketplaces` auto-update policy not being persisted to `known_marketplaces.json`
- Fixed `/loop` scheduling redundant wakeups to poll for background tasks that already notify on completion
- Fixed a recurring event-loop stall on Windows when a missing executable (e.g. `gh`) triggered synchronous `where.exe` re-spawns on every check
- Fixed `Read` tool calls failing validation when `offset` is passed as a whitespace-padded or `+`-prefixed string
- Fixed native terminal cursor not staying at the input caret when the terminal loses focus

[​](#2-1-139)

2.1.139

May 11, 2026

**Added**

- Added agent view (Research Preview): a single list of every Claude Code session — running, blocked on you, or done. Run `claude agents` to get started. See [https://code.claude.com/docs/en/agent-view](../09-Agents-Patterns/agent-view.md)
- Added `/goal` command: set a completion condition and Claude keeps working across turns until it’s met. Works in interactive, `-p`, and Remote Control. Shows live elapsed/turns/tokens as an overlay panel
- Added `/scroll-speed` command to tune mouse wheel scroll speed with a live preview
- Added `claude plugin details <name>` to show a plugin’s component inventory and projected per-session token cost
- Added transcript view navigation: `?` for keyboard shortcuts, `{`/`}` to jump between user prompts, `v` to toggle shortcut panel
- Added hook `args: string[]` field (exec form) that spawns the command directly without a shell, so path placeholders never need quoting
- Added hook `continueOnBlock` config option for `PostToolUse` — set to `true` to feed the hook’s rejection reason back to Claude and continue the turn

**Changed**

- MCP stdio servers now receive `CLAUDE_PROJECT_DIR` in their environment, matching hooks. Plugin configs can reference `${CLAUDE_PROJECT_DIR}` in commands
- Compaction prompt now asks the model to preserve sensitive user instructions
- `/mcp` Reconnect now picks up `.mcp.json` edits without a restart, and shows the HTTP status and URL when reconnecting fails
- `/context all` per-skill token estimates now account for the model’s tokenizer and show rounded values
- `claude plugin install <name>@<marketplace>` now auto-refreshes the marketplace and retries before reporting a plugin as not found
- `/plugin` installed-plugin details now show hook event names and MCP server names cleanly
- `/context` now shows the providing plugin’s name for plugin-sourced skills
- Remote MCP server reconnect retry on transient failures is now enabled for all users
- API requests from subagents now carry `x-claude-code-agent-id` / `x-claude-code-parent-agent-id` headers, and `claude_code.llm_request` OTEL spans include `agent_id` / `parent_agent_id` attributes
- Remote Control, `/schedule`, claude.ai MCP connectors, and notification preferences are now disabled when `ANTHROPIC_API_KEY` / `apiKeyHelper` / `ANTHROPIC_AUTH_TOKEN` is set, even if a Claude.ai login also exists. Unset the API key to use these features
- \[VSCode\] Press Cmd/Ctrl+Shift+T to reopen the most recently closed session tab, configurable via `claudeCode.enableReopenClosedSessionShortcut`

Show 32 bug fixes

- Fixed a deadlock where expired credentials and the `forceRemoteSettingsRefresh` policy setting blocked `claude auth login`/`logout`/`status` with no way to recover
- Fixed `autoAllowBashIfSandboxed` not auto-approving commands with shell expansions like `$VAR` and `$(cmd)`
- Fixed a bug where a hook writing to the terminal could corrupt an on-screen interactive prompt; hooks now run without terminal access
- Fixed unbounded memory growth when an HTTP/SSE MCP server streams non-protocol data — response bodies now capped at 16 MB per SSE frame
- Fixed `Skill(name *)` permission rules — the wildcard form now works as a prefix match, matching `Bash(ls *)` behavior
- Fixed settings hot-reload not detecting edits to symlinked `~/.claude/settings.json`
- Fixed plugin details failing to load when the marketplace key differs from the manifest name
- Fixed `/model` picker “Default” row not reflecting `ANTHROPIC_DEFAULT_OPUS_MODEL`/`ANTHROPIC_DEFAULT_SONNET_MODEL` overrides
- Fixed spurious “stream idle timeout” 5 minutes after a response completed, caused by the watchdog timer not being cleared on stream cancellation
- Fixed silent `exit 1` when 10+ MCP servers are configured and the cache directory is unwritable — the error message now includes the underlying cause
- Fixed a typing cursor blinking on tab names, list pointers, and select rows in dialogs
- Fixed transcript view letter shortcuts not working after mouse click
- Fixed Bash-mode up-arrow history repeating the first entry and clobbering the in-progress draft
- Fixed pasting or dropping multiple images only inserting the last one
- Fixed hyperlinks using unreadable dark navy on dark themes — they now adapt to the active theme
- Fixed model picker showing a redundant “Current model” row for third-party users whose model is set to the `opus` alias
- Fixed legacy Opus picker entry on PAYG 3P providers resolving to the same model as the default entry
- Fixed mouse wheel scrolling speed in Cursor and VS Code 1.92–1.104; the trackpad now scrolls at a steady rate and the mouse wheel keeps ~3 lines per notch
- Fixed scroll behavior in Windows Terminal and VS Code when attached to background sessions
- Fixed MCP resources from disconnected servers lingering in `@server:` autocomplete
- Fixed two-file diff snippets over-reporting the number of truncated lines by one
- Fixed Grep results not relativizing Windows drive-letter paths and count mode reporting wrong totals for single-file paths
- Fixed border-embedded text overflowing on CJK/emoji due to visual cell width miscalculation
- Fixed fuzzy-match highlighting splitting emoji and astral-plane characters mid-pair
- Fixed skill argument names containing regex metacharacters breaking argument substitution
- Fixed ProgressBar rendering a full block for an almost-full fractional cell
- Fixed task polling and `fs.watch` being resurrected when the last subscriber leaves while a fetch is in flight
- Fixed plugin dependency resolution leaving a stale count when the manifest name differs from the source identifier
- Fixed Insights Time-of-Day chart skewing when a session has an unparseable timestamp
- Fixed keybindings using only the cmd/super/win modifier being flagged as unparseable
- Fixed `claude_code.active_time.total` OpenTelemetry metric not being emitted in `--print` mode
- Fixed `claude plugin update` not preserving cross-plugin symlinks inside a marketplace

[​](#2-1-138)

2.1.138

May 9, 2026

- Internal fixes

[​](#2-1-137)

2.1.137

May 9, 2026

- \[VSCode\] Fixed extension failing to activate on Windows

[​](#2-1-136)

2.1.136

May 8, 2026

**Added**

- Added `CLAUDE_CODE_ENABLE_FEEDBACK_SURVEY_FOR_OTEL` to re-enable the session quality survey for enterprises capturing responses through OpenTelemetry
- Added `settings.autoMode.hard_deny` for auto mode classifier rules that block unconditionally regardless of user intent or allow exceptions

**Changed**

- WSL2: image paste from Windows clipboard now works via a PowerShell fallback when xclip/wl-paste cannot read image data
- Changed plugin marketplace removal key to `d` (matching delete elsewhere) instead of `r` which collided with retry

**Improved**

- Improved visual consistency across slash command dialogs: standardized footer hints, dialog spacing, and arrow-key styling, and the dialog frame now appears immediately during loading instead of popping in after
- Improved error message when `--worktree` collides with an existing or stale worktree

Show 46 bug fixes

- Fixed MCP servers configured in `.mcp.json`, plugins, and claude.ai connectors silently disappearing after `/clear` in the VS Code extension, JetBrains plugin, and Agent SDK
- Fixed a rare login loop where a concurrent credential write could overwrite a freshly-rotated OAuth token and force re-login
- Fixed MCP OAuth refresh tokens being lost when multiple servers refresh concurrently — users with several remote MCP servers should no longer need daily re-authentication
- Fixed an API error (400) when extended thinking emitted a redacted thinking block after a tool call
- Fixed `--resume` / `--continue` not finding sessions when the project path contains underscores
- Fixed plan mode not blocking file writes when a matching `Edit(...)` allow rule exists
- Fixed plugin `Stop`/`UserPromptSubmit` hooks failing when cache cleanup deletes a version still in use by a running session
- Fixed colors appearing at wrong positions in bash command output and markdown code blocks
- Fixed ReasonML diffs rendering corrupted “undefined” text artifacts at word-diff boundaries
- Fixed worktree exit dialog warning about uncommitted files in the wrong directory after worktree removal
- Fixed `@` file picker not matching files created mid-session in small non-git directories
- Fixed `@`-mention file picker not finding files in directories with more than 100 entries
- Fixed failed tool calls not being click-to-expand in fullscreen mode when their output was truncated
- Fixed Backspace and Ctrl+Backspace getting swapped after using Ctrl+G to open an external editor on terminals with persistent extended-key modes
- Fixed `/usage` weekly reset showing time of day instead of the calendar date
- Fixed welcome banner ellipsis causing column overflow on CJK terminals
- Fixed `/insights` crash when session history contains tool calls with malformed input fields
- Fixed a renderer crash when a tool’s collapsibility classification changes mid-session
- Fixed a `skills` entry in `plugin.json` hiding the plugin’s default `skills/` directory, and listing a file path now shows an error instead of failing silently
- Fixed IDE shell-integration lock files not respecting `CLAUDE_CONFIG_DIR`
- Fixed trailing whitespace in copied terminal output during streaming
- Fixed plugin uninstall and enable/disable not matching slugs case-insensitively
- Fixed tool error truncation marker showing a negative count for surrogate-pair strings
- Fixed env vars from `CLAUDE_ENV_FILE` SessionStart hooks going stale after `/resume` or `/clear`
- Fixed `/branch` saving a multi-line session title when given a pasted multi-line name
- Fixed a stray leading space on the second line of wrapped text at the column boundary
- Fixed Esc not dismissing dialogs in `/install-github-app`, `/desktop`, `/resume`, and `/web-setup`
- Fixed `/doctor` MCP schema errors not naming the missing field or showing the source file path
- Fixed Bash permission prompts showing an internal parser diagnostic instead of a user-readable explanation
- Fixed plugin slash commands with spaces (e.g. `/myplugin review`) not resolving to their namespaced form
- Fixed `AskUserQuestion` discarding multi-select answers when supplied as an array
- Fixed `/clear <name>` not labeling the cleared session for `/resume`
- Fixed `CronList` output missing qualifiers and the scheduled prompt
- Fixed “Jump to bottom” overlay leaving color artifacts on CJK characters in fullscreen mode
- Fixed wide markdown tables leaving a stale bordered render in terminal scrollback while streaming
- Fixed pasted text being silently dropped when a long prompt with a pasted-text placeholder was auto-truncated
- Fixed `/release-notes` getting stuck on an old version after a failed changelog refresh
- Fixed `/mcp` server list not scrolling when there are more servers than fit in the terminal
- Fixed mid-input slash command autocomplete not working after an initial slash command
- Fixed scrolling to bottom re-engaging auto-follow with `autoScrollEnabled: false`
- Fixed prompt suggestions being auto-submitted by Enter on an empty input instead of requiring Tab or arrow to accept
- Fixed keyboard shortcut hints not reflecting rebound keys from `keybindings.json`
- Fixed `/settings` language change being reverted on Escape after confirming
- Fixed `/terminal-setup` only appearing in autocomplete on exact name match instead of partial prefixes
- Fixed “Chat about this” on an `AskUserQuestion` dialog erasing the question text
- Fixed MCP tool results being invisible when the server returns content blocks

[​](#2-1-133)

2.1.133

May 7, 2026

**Added**

- Added `worktree.baseRef` setting (`fresh` \| `head`) to choose whether `--worktree`, `EnterWorktree`, and agent-isolation worktrees branch from `origin/<default>` or local `HEAD`. **Note:** the default `fresh` changes `EnterWorktree`’s base back to `origin/<default>` (it has been local `HEAD` since 2.1.128) — set `worktree.baseRef: "head"` to keep unpushed commits in new worktrees
- Added `sandbox.bwrapPath` and `sandbox.socatPath` managed settings (Linux/WSL) to specify custom bubblewrap and socat binary locations
- Added `parentSettingsBehavior` admin-tier key (`'first-wins' | 'merge'`) to let admins opt SDK `managedSettings` (parent tier) into the policy merge

**Changed**

- Hooks now receive the active effort level via the `effort.level` JSON input field and the `$CLAUDE_EFFORT` environment variable, and Bash tool commands can read `$CLAUDE_EFFORT`
- `claude --help` now lists `--remote-control` alongside `--remote-control-session-name-prefix`

**Improved**

- Improved focus mode behavior
- Improved memory usage by releasing warm-spare background workers under memory pressure

Show 10 bug fixes

- Fixed parallel sessions all dead-ending at 401 after a refresh-token race wiped shared credentials
- Fixed `Edit`/`Write` allow rules scoped to a drive root (`C:\`) or POSIX `/` matching incorrectly and always prompting
- Fixed an unhandled rejection (`ECOMPROMISED`) when a history or session-log file lock is compromised by clock skew or slow disk
- Fixed pressing Esc during conversation compaction showing a spurious “Error compacting conversation” notification
- Fixed `HTTP(S)_PROXY` / `NO_PROXY` / mTLS not being respected for the full MCP OAuth flow including discovery, dynamic client registration, token exchange, and token refresh
- Fixed Read/Write/Edit being denied on mapped network drives passed via `--add-dir` / SDK `additionalDirectories`
- Fixed Remote Control stop/interrupt from claude.ai not fully canceling the CLI session the same way local Esc does, causing queued messages to never advance after interrupting a stuck tool or prompt
- Fixed `/effort` in one session unexpectedly changing the effort level of other concurrent sessions, and a related issue where an IDE effort change could be silently dropped
- Fixed subagents not discovering project, user, or plugin skills via the Skill tool
- \[VSCode\] Fixed `claudeCode.claudeProcessWrapper` failing with “Unsupported platform” when the extension build doesn’t bundle a Claude binary

[​](#2-1-132)

2.1.132

May 6, 2026

**Added**

- Added `CLAUDE_CODE_SESSION_ID` environment variable to the Bash tool subprocess environment, matching the `session_id` passed to hooks
- Added `CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1` env var to opt out of the fullscreen alternate-screen renderer and keep the conversation in the terminal’s native scrollback
- Added a “Pasting…” footer hint while a Ctrl+V image paste is being read from the clipboard

**Changed**

- Updated the `/tui fullscreen` startup banner to describe additional renderer benefits (lower memory usage, mouse support, auto-copy on select)

**Improved**

- Improved visual consistency in slash command dialogs and `/login`, `/upgrade`, `/extra-usage` dialog spacing

Show 23 bug fixes

- Fixed external SIGINT (e.g. IDE stop button, `kill -INT`) not running graceful shutdown — terminal modes are now restored and the `--resume` hint is printed instead of an abrupt exit
- Fixed an uncaught exception when the terminal is closed or SSH disconnects mid-session under the native build
- Fixed `--resume` failing with `no low surrogate in string` when a tool error truncation split an emoji; pre-corrupted sessions are sanitized on load
- Fixed `--permission-mode` flag being ignored when resuming a plan-mode session with `-p --continue`/`--resume`, and plan mode not being re-applied after `ExitPlanMode` within the same session
- Fixed fullscreen mode showing a blank screen after laptop sleep/wake or Ctrl+Z/`fg` until the next keystroke or stream output
- Fixed cursor landing mid-grapheme on Ctrl+E/A/K/U/arrow keys when an Indic conjunct or ZWJ emoji wraps across lines
- Fixed vim operators corrupting text containing decomposed (NFD) accented characters
- Fixed pasting text starting with `/` silently swallowing the input or triggering an unknown-command reply
- Fixed pasting dumping stray escape sequences into the prompt when focus events or mouse-tracking reports interleave with the bracketed paste
- Fixed mouse wheel scrolling being too fast in Cursor and VS Code 1.92–1.104 due to an upstream xterm.js bug
- Fixed scroll-wheel handling in JetBrains IDE 2025.2 terminals (spurious arrow keys, wrong-direction events, runaway acceleration)
- Fixed `/usage` Ctrl+S hanging when copying the stats screenshot to the clipboard on Linux/X11
- Fixed `/terminal-setup` showing a contradictory error in Windows Terminal — Shift+Enter is natively supported there
- Fixed `/effort` picker not reflecting the `CLAUDE_CODE_EFFORT_LEVEL` env var override
- Fixed `/status` showing the wrong default model for some users
- Fixed slash command autocomplete popup being capped at ~3–5 visible commands instead of scaling with terminal height
- Fixed statusline `context_window` token counts reflecting cumulative session totals instead of current context usage
- Fixed Alt+T (thinking toggle) not working on macOS terminals without “Option as Meta” enabled (iTerm2, Terminal.app defaults)
- Fixed dead keyboard input on Windows after re-opening a background session from `claude agents`
- Fixed unbounded memory growth (10GB+ RSS) when a stdio MCP server writes non-protocol data to stdout
- Fixed MCP servers that connect but fail `tools/list` silently showing 0 tools — they now retry once and show “connected · tools fetch failed” in `/mcp`
- Fixed unauthorized claude.ai MCP connectors showing as “failed” instead of “needs auth”, and headless `-p` mode retrying non-transient 4xx connection failures
- Fixed Bedrock and Vertex 400 errors when `ENABLE_PROMPT_CACHING_1H` is set

[​](#2-1-131)

2.1.131

May 6, 2026

- Fixed VS Code extension failing to activate on Windows due to a hardcoded build path in the bundled SDK (`createRequire` polyfill bug)
- Fixed Mantle endpoint authentication failing with missing `x-api-key` header

[​](#2-1-129)

2.1.129

May 6, 2026

**Added**

- Added `--plugin-url <url>` flag to fetch a plugin `.zip` archive from a URL for the current session
- Added `CLAUDE_CODE_FORCE_SYNC_OUTPUT=1` env var to force-enable synchronized output on terminals that auto-detection misses (e.g. Emacs `eat`)
- Added `CLAUDE_CODE_PACKAGE_MANAGER_AUTO_UPDATE`: when set on Homebrew or WinGet installations, Claude Code runs the upgrade command in the background and prompts to restart

**Changed**

- Plugin manifests: `themes` and `monitors` should now be declared under `"experimental": { ... }`. Top-level declarations still work but `claude plugin validate` will warn
- Gateway `/v1/models` discovery for the `/model` picker is now opt-in via `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` (was automatic in 2.1.126–2.1.128)
- Ctrl+R history picker now defaults to searching all prompts across all projects, matching pre-2.1.124 behavior. Press Ctrl+S to narrow to the current project or session
- Third-party deployments (Bedrock, Vertex, Foundry, or `ANTHROPIC_BASE_URL` gateway) no longer see spinner tips pointing at first-party Anthropic surfaces
- `skillOverrides` setting now works: `off` hides from model and `/`, `user-invocable-only` hides from model only, `name-only` collapses description
- The `claude_code.pull_request.count` OTel metric now counts PRs/MRs created via MCP tools, not just shell commands
- Policy refusal error messages now include the API Request ID for easier support debugging

Show 17 bug fixes

- Fixed API errors with unrecognized 400 status codes showing raw JSON instead of the underlying error message
- Fixed `/clear` not resetting the terminal tab title after a conversation
- Fixed session title chip from `/rename` disappearing while a permission or other dialog is active
- Fixed agent panel below the prompt being hidden when subagents are running (regression in 2.1.122)
- Fixed external-editor handoff (Ctrl+G) blanking the conversation history above the prompt
- Fixed `/context` dumping its rendered ASCII visualization grid into the conversation, wasting ~1.6k tokens per call
- Fixed `/agents` Library list arrow-key navigation: the highlighted agent now stays visible when the list exceeds the viewport
- Fixed `/branch` success message not including the new branch’s session id for `/resume`
- Fixed bold headers with keycap/ZWJ/skin-tone emoji losing trailing characters in fullscreen mode
- Fixed server-managed settings policy not applying for enterprise/team users whose stored OAuth credentials lacked the `user:inference` scope
- Fixed OAuth refresh race after wake-from-sleep that could log out all running sessions
- Fixed 1-hour prompt cache TTL being silently downgraded to 5 minutes
- Fixed cache-miss warning appearing spuriously after `/clear` or compaction when changing `/effort` or `/model`
- Fixed `Bash(mkdir *)`, `Bash(touch *)` and similar allow rules not being honored for in-project paths
- Fixed `deniedMcpServers` patterns with a `*://` scheme wildcard not matching mixed-case hostnames
- Fixed harmless WebSocket warning being logged as an error in `--debug` during voice mode
- \[VSCode\] Fixed `/clear` not clearing the conversation context and displayed transcript

[​](#2-1-128)

2.1.128

May 4, 2026

**Changed**

- Bare `/color` (no args) now picks a random session color
- `/mcp` now shows the tool count for connected servers and flags servers that connected with 0 tools
- `--plugin-dir` now accepts `.zip` plugin archives in addition to directories
- `--channels` now works with console (API key) authentication — console orgs with managed settings must set `channelsEnabled: true` to enable
- Updated `/model` picker: collapsed duplicate Opus 4.7 entries, and current Opus now shows as “Opus” instead of “Opus 4.7”
- Subprocesses (Bash, hooks, MCP, LSP) no longer inherit `OTEL_*` environment variables, so OTEL-instrumented apps run via the Bash tool no longer pick up the CLI’s own OTLP endpoint
- MCP: `workspace` is now a reserved server name — existing servers with that name will be skipped with a warning
- Reconnecting MCP servers no longer flood the conversation with full tool-name lists on every reconnect — re-announced tools are summarized by server prefix
- SDK hosts now receive a persistent `localSettings` suggestion for Bash permission prompts, so “Always allow” writes to `.claude/settings.local.json`
- `EnterWorktree` now creates the new branch from local HEAD as documented, instead of `origin/<default-branch>` — unpushed commits are no longer dropped
- Auto mode: when the classifier can’t evaluate an action, the error now includes a hint (retry, `/compact`, or run with `--debug`)
- Headless `--output-format stream-json`: `init.plugin_errors` now includes `--plugin-dir` load failures in addition to dependency demotions

Show 25 bug fixes

- Fixed focus mode briefly dimming the previous response when submitting a new prompt
- Fixed stray “4;0;” desktop notification on every `/exit` in Kitty and other terminals that interpret OSC 9 as a notification
- Fixed Remote Control showing an empty “Opening your options…” message on rate limit instead of actionable upsell options
- Fixed drag-and-drop image upload hanging on “Pasting text…” when the image read fails
- Fixed crash loop when piping very large input (\>10 MB) to `claude -p` via stdin
- Fixed long URLs not being individually clickable on every wrapped row in fullscreen mode
- Fixed `/plugin` Components panel showing “Marketplace ‘inline’ not found” for plugins loaded via `--plugin-dir`
- Fixed MCP tool results dropping images when the server returns both structured content and content blocks
- Fixed fenced code blocks inside list items carrying leading whitespace into the clipboard on copy-paste
- Fixed tab navigation in `/config` stranding focus — the tab header now stays focused so arrows and Esc keep working
- Fixed markdown link labels being lost on terminals without OSC 8 hyperlink support — links now render as `label (url)` instead of just the URL
- Fixed sessions on 1M-context models with a smaller autocompact window being falsely blocked with “Prompt is too long” before reaching the actual API limit
- Fixed parallel shell tool calls: a failing read-only command (grep, git diff, ls) no longer cancels sibling calls
- Fixed banner showing “with X effort” on models that don’t support effort
- Fixed `/fast` on 3P providers fuzzy-matching to an unrelated skill instead of showing “not available”
- Fixed Bedrock default model resolving to `global.*` instead of the region-appropriate prefix
- Fixed vim mode: `Space` in NORMAL mode now moves the cursor right, matching standard vi/vim behavior
- Fixed terminal progress indicator (OSC 9;4) flickering off between tool calls — stays visible across the full turn
- Fixed `/rename` without args failing on resumed sessions whose last entry is a compact boundary
- Fixed stale “remote-control is active” status lines from prior sessions appearing after `--resume`/`--continue`
- Fixed stale `installed_plugins.json` entries pointing at deleted cache directories polluting PATH
- Fixed MCP stdio servers receiving corrupted arguments when `CLAUDE_CODE_SHELL_PREFIX` is set and an argument contains spaces or shell metacharacters
- Fixed sub-agent progress summaries missing the prompt cache (~3× `cache_creation` reduction)
- Fixed `/plugin update` never detecting new versions of npm-sourced plugins
- Fixed sub-agent summaries firing repeatedly while a sub-agent’s transcript is static, capping worst-case token cost on idle sub-agents

[​](#2-1-126)

2.1.126

May 1, 2026

**Changed**

- The `/model` picker now lists models from your gateway’s `/v1/models` endpoint when `ANTHROPIC_BASE_URL` points at an Anthropic-compatible gateway

- - Added `claude project purge [path]` to delete all Claude Code state for a project (transcripts, tasks, file history, config entry) — supports `--dry-run`, `-y/--yes`, `-i/--interactive`, and `--all`

- `--dangerously-skip-permissions` now bypasses prompts for writes to `.claude/`, `.git/`, `.vscode/`, shell config files, and other previously-protected paths (catastrophic removal commands still prompt as a safety net)

- `claude auth login` now accepts the OAuth code pasted into the terminal when the browser callback can’t reach localhost (WSL2, SSH, containers)

- `claude_code.skill_activated` OpenTelemetry event now fires for user-typed slash commands and carries a new `invocation_trigger` attribute (`"user-slash"`, `"claude-proactive"`, or `"nested-skill"`)

- Auto mode: the spinner now turns red when a permission check stalls, instead of looking like the tool is running

- Host-managed deployments (`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`) no longer auto-disable analytics on Bedrock/Vertex/Foundry

- Windows: PowerShell 7 installed via the Microsoft Store, MSI without PATH, or `.NET global tool` is now detected

- Windows: when the PowerShell tool is enabled, Claude now treats PowerShell as the primary shell instead of defaulting to Bash

- Read tool: removed the per-file malware-assessment reminder that could cause spurious refusals and “this is not malware” commentary on legacy models

- Bounded total size of file-modified reminders when a linter touches many files at once

- Windows: clipboard writes no longer expose copied content in process command-line arguments visible to EDR/SIEM telemetry; also fixes \>22KB selections not reaching the clipboard

- PowerShell tool: bare `--` (e.g. `git diff -- file`) is no longer mis-flagged as the `--%` stop-parsing token

Show 19 bug fixes

- **Security:** Fixed `allowManagedDomainsOnly` / `allowManagedReadPathsOnly` being ignored when a higher-priority managed-settings source lacked a `sandbox` block
- Fixed pasting an image larger than 2000px breaking the session — images are now downscaled on paste, and oversized images in history are automatically removed and the request retried
- Fixed showing the login screen for “OAuth not allowed for organization” errors — now shows guidance to contact your admin
- Fixed OAuth login failing with timeout on slow or proxied connections, in IPv6-only devcontainers, and when the browser callback can’t reach localhost
- Fixed a rare race where a concurrent credential write could clear a valid OAuth refresh token
- Fixed API retry countdown sticking at “0s” instead of counting down between attempts
- Fixed “Stream idle timeout” error after waking Mac from sleep mid-request
- Fixed background and remote sessions falsely aborting with “Stream idle timeout” during long model thinking pauses
- Fixed a hang where the assistant could finish thinking but show no output after a run of empty turns
- Fixed overly fast trackpad scrolling in Cursor and VS Code 1.92–1.104 integrated terminals
- Fixed claude.ai MCP connectors being suppressed by manual servers stuck in needs-auth state
- Fixed Japanese/Korean/Chinese text rendering as garbled characters on Windows in no-flicker mode
- Fixed `Ctrl+L` clearing the prompt input — it now only forces a screen redraw, matching readline behavior
- Fixed deferred tools (WebSearch, WebFetch, etc.) not being available to skills with `context: fork` and other subagents on their first turn
- Fixed plan-mode tools being unavailable in interactive sessions launched with `--channels`
- Fixed `/plugin` Uninstall reporting “Enabled” instead of “Uninstalled”
- Fixed `/remote-control` retries appearing stuck on “connecting…” — each retry now shows its result
- Fixed Remote Control failure notification not showing the error reason for initial connection failures
- Fixed Agent SDK hang when the model emits a malformed tool name in a parallel tool call batch

[​](#2-1-123)

2.1.123

April 29, 2026

- Fixed OAuth authentication failing with a 401 retry loop when `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1` is set

[​](#2-1-122)

2.1.122

April 28, 2026

**Added**

- Added `ANTHROPIC_BEDROCK_SERVICE_TIER` environment variable to select a Bedrock service tier (`default`, `flex`, or `priority`), sent as the `X-Amzn-Bedrock-Service-Tier` header
- OpenTelemetry: added `claude_code.at_mention` log event for `@`-mention resolution

**Changed**

- Pasting a PR URL into the `/resume` search box now finds the session that created that PR (GitHub, GitHub Enterprise, GitLab, and Bitbucket)
- `/mcp` now shows claude.ai connectors hidden by a manually-added server with the same URL, with a hint to remove the duplicate
- Clarified the `/mcp` message shown when an MCP server is still unauthorized after the browser sign-in flow
- OpenTelemetry: numeric attributes on `api_request`/`api_error` log events are now emitted as numbers, not strings
- Voice mode: keybindings bound to Caps Lock now show an error since terminals don’t deliver Caps Lock as a key event

Show 11 bug fixes

- Fixed `/branch` producing forks that fail with “tool_use ids were found without tool_result blocks” when the source session contained entries from rewound timelines
- Fixed `/model` not showing the Effort option for Bedrock application inference profile ARNs, and those ARNs not receiving `output_config.effort`
- Fixed Vertex AI / Bedrock returning `invalid_request_error: output_config: Extra inputs are not permitted` on session-title generation and other structured-output queries
- Fixed Vertex AI `count_tokens` endpoint returning 400 errors for users behind proxy gateways
- Fixed `spinnerTipsOverride.excludeDefault` not suppressing the time-based spinner tips
- Fixed ToolSearch missing MCP tools that connected after session start in nonblocking mode
- Fixed `!exit` / `!quit` in bash mode terminating the CLI instead of running as a shell command
- Fixed images sent to newer models being resized to 2576px per side instead of the correct 2000px maximum
- Fixed remote control session idle status redrawing twice per second, which could flood `tmux -CC` control pipes and pause the terminal
- Fixed assistant messages appearing blank in some sessions due to a stale view preference
- Fixed a malformed hooks entry in `settings.json` no longer invalidating the entire file

[​](#2-1-121)

2.1.121

April 28, 2026

**Added**

- Added `alwaysLoad` option to MCP server config — when `true`, all tools from that server skip tool-search deferral and are always available
- Added `claude plugin prune` to remove orphaned auto-installed plugin dependencies; `plugin uninstall --prune` cascades
- Added a type-to-filter search box to `/skills` so you can find a skill in long lists without scrolling
- OpenTelemetry: added `stop_reason`, `gen_ai.response.finish_reasons`, and `user_system_prompt` (gated behind `OTEL_LOG_USER_PROMPTS`) to LLM request spans

**Changed**

- PostToolUse hooks can now replace tool output for all tools via `hookSpecificOutput.updatedToolOutput` (previously MCP-only)
- Fullscreen mode: typing into the prompt no longer jumps scroll back to the bottom after you’ve scrolled up to read earlier output
- Dialogs that overflow the terminal are now scrollable with arrow keys, PgUp/PgDn, home/end, and mouse wheel in both fullscreen and non-fullscreen modes
- Clicking any line of a long URL that wraps across rows in fullscreen mode now opens the full URL
- SDK and `claude -p`: `CLAUDE_CODE_FORK_SUBAGENT=1` now works in non-interactive sessions
- `--dangerously-skip-permissions` no longer prompts for writes to `.claude/skills/`, `.claude/agents/`, and `.claude/commands/`
- `/terminal-setup` now enables iTerm2’s “Applications in terminal may access clipboard” setting so `/copy` works, including from tmux
- MCP servers that hit a transient error during startup now auto-retry up to 3 times instead of staying disconnected
- The terminal tab session title is now generated in your configured `language` setting
- Claude.ai connectors with the same upstream URL are now deduplicated instead of appearing as duplicates
- Vertex AI: support X.509 certificate-based Workload Identity Federation (mTLS ADC)
- Faster startup after upgrading: removed the Recent Activity panel from the release-notes splash
- LSP diagnostic summaries now expand on click/ctrl+o and show the expand hint
- SDK: `mcp_authenticate` now supports `redirectUri` for custom scheme completion and claude.ai connectors
- \[VSCode\] Voice dictation now respects the `accessibility.voice.speechLanguage` setting when no Claude Code language is configured
- \[VSCode\] `/context` now opens a native token usage dialog
- Reduced peak file descriptor usage during `find` in the Bash tool on large directory trees

Show 18 bug fixes

- Fixed unbounded memory growth (multi-GB RSS) when processing many images in a session
- Fixed `/usage` leaking up to ~2GB of memory on machines with large transcript histories
- Fixed memory leak when long-running tools fail to emit a clear progress event
- Fixed Bash tool becoming permanently unusable when the directory Claude was started in is deleted or moved mid-session
- Fixed `--resume` crashing on startup in external builds
- Fixed `--resume` failing on large sessions when a transcript line was corrupted by an unclean shutdown — the corrupt line is now skipped
- Fixed `thinking.type.enabled is not supported` error when using Bedrock application inference profile ARNs
- Fixed Microsoft 365 MCP OAuth failing with duplicate or unsupported `prompt` parameter
- Fixed scrollback duplication when pressing Ctrl+L or triggering a redraw in non-fullscreen mode on tmux, GNOME Terminal, Windows Terminal, and Konsole
- Fixed claude.ai MCP connectors silently disappearing when the connector-list fetch hits a transient auth error at startup
- Fixed “Always allow” rules for built-in tools in remote sessions not surviving worker restarts
- Fixed `NO_PROXY` not being respected for all HTTP clients when set via `managed-settings.json` under the native build
- Fixed managed settings approval prompt exiting the session even when accepted — now applies settings and continues
- Fixed `/usage` returning “rate limited” after a stale OAuth token — now refreshes automatically
- Fixed invalid legacy enum values in `settings.json` invalidating the entire settings file
- Fixed `/usage` dialog content being clipped when no-flicker mode is off
- Fixed `/focus` showing “Unknown command” when the fullscreen renderer is off — now explains how to enable it
- Fixed embedded grep/find/rg shell wrappers failing when the running binary is deleted mid-session — now falls back to installed tools

[​](#2-1-120)

2.1.120

April 28, 2026

**Added**

- Added `claude ultrareview [target]` subcommand to run `/ultrareview` non-interactively from CI or scripts — prints findings to stdout (`--json` for raw output) and exits 0 on completion or 1 on failure

**Changed**

- Windows: Git for Windows (Git Bash) is no longer required — when absent, Claude Code uses PowerShell as the shell tool
- Skills can now reference the current effort level with `${CLAUDE_EFFORT}` in their content
- Set `AI_AGENT` environment variable for subprocesses so `gh` can attribute traffic to Claude Code
- Spinner tips that recommend installing the desktop app or creating skills/agents are now hidden when you already have them
- Show a “use PgUp/PgDn to scroll” hint when the terminal sends arrow keys instead of scroll events
- Faster session start when you have many claude.ai connectors configured but not authorized
- The auto mode denial message now links to the configuration docs
- `claude plugin validate` now accepts `$schema`, `version`, and `description` at the top level of `marketplace.json` and `$schema` in `plugin.json`
- Auto-compact in auto mode now displays `auto` (lowercase, no token count) instead of a misleading token value
- \[VSCode\] `/usage` now opens the native Account & Usage dialog instead of returning plain-text session cost
- \[VSCode\] Voice dictation now respects the `language` setting in `~/.claude/settings.json`

Show 10 bug fixes

- Fixed pressing Esc during a stdio MCP tool call closing the entire server connection (regression in 2.1.105)
- Fixed `/rewind` and other interactive overlays not responding to keyboard input after launching with `claude --resume`
- Fixed terminal scrollback duplication in non-fullscreen mode (resize, dialog dismiss, long sessions)
- Fixed `DISABLE_TELEMETRY` / `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` not suppressing usage metrics telemetry for API and enterprise users
- Fixed false-positive “Dangerous rm operation” permission prompts in auto mode for multi-line bash commands containing both a pipe and a redirect
- Fixed long selection menus clipping below the terminal in fullscreen mode — the focused option now stays on screen as you scroll
- Fixed Write tool output collapsing instead of expanding when clicking “+N lines” in fullscreen
- Fixed slash command picker jumping while typing, and improved highlight to only match contiguous substrings in blue
- Fixed `/plugin` marketplace failing to load when one entry uses an unrecognized source format — that entry is shown but installing it prompts you to update
- Fixed `find` in the Bash tool exhausting open file descriptors on large directory trees, causing host-wide crashes (macOS/Linux native builds)

[​](#2-1-119)

2.1.119

April 23, 2026

**Added**

- Added `prUrlTemplate` setting to point the footer PR badge at a custom code-review URL instead of github.com
- Added `CLAUDE_CODE_HIDE_CWD` environment variable to hide the working directory in the startup logo

**Changed**

- `/config` settings (theme, editor mode, verbose, etc.) now persist to `~/.claude/settings.json` and participate in project/local/policy override precedence
- `--from-pr` now accepts GitLab merge-request, Bitbucket pull-request, and GitHub Enterprise PR URLs
- `--print` mode now honors the agent’s `tools:` and `disallowedTools:` frontmatter, matching interactive-mode behavior
- `--agent <name>` now honors the agent definition’s `permissionMode` for built-in agents
- PowerShell tool commands can now be auto-approved in permission mode, matching Bash behavior
- Hooks: `PostToolUse` and `PostToolUseFailure` hook inputs now include `duration_ms` (tool execution time, excluding permission prompts and PreToolUse hooks)
- Subagent and SDK MCP server reconfiguration now connects servers in parallel instead of serially
- Plugins pinned by another plugin’s version constraint now auto-update to the highest satisfying git tag
- Vim mode: Esc in INSERT no longer pulls a queued message back into the input; press Esc again to interrupt
- Slash command suggestions now highlight the characters that matched your query
- Slash command picker now wraps long descriptions onto a second line instead of truncating
- `owner/repo#N` shorthand links in output now use your git remote’s host instead of always pointing at github.com
- Security: `blockedMarketplaces` now correctly enforces `hostPattern` and `pathPattern` entries
- OpenTelemetry: `tool_result` and `tool_decision` events now include `tool_use_id`; `tool_result` also includes `tool_input_size_bytes`
- Status line: stdin JSON now includes `effort.level` and `thinking.enabled`
- Tool search is now disabled by default on Vertex AI to avoid an unsupported beta header error (opt in with `ENABLE_TOOL_SEARCH`)
- Windows: removed false-positive “Windows requires ‘cmd /c’ wrapper” MCP config warning

Show 32 bug fixes

- Fixed pasting CRLF content (Windows clipboards, Xcode console) inserting an extra blank line between every line
- Fixed multi-line paste losing newlines in terminals using kitty keyboard protocol sequences inside bracketed paste
- Fixed Glob and Grep tools disappearing on native macOS/Linux builds when the Bash tool is denied via permissions
- Fixed scrolling up in fullscreen mode snapping back to the bottom every time a tool finishes
- Fixed MCP HTTP connections failing with “Invalid OAuth error response” when servers returned non-JSON bodies for OAuth discovery requests
- Fixed Rewind overlay showing “(no prompt)” for messages with image attachments
- Fixed auto mode overriding plan mode with conflicting “Execute immediately” instructions
- Fixed async `PostToolUse` hooks that emit no response payload writing empty entries to the session transcript
- Fixed spinner staying on when a subagent task notification is orphaned in the queue
- Fixed `@`-file Tab completion replacing the entire prompt when used inside a slash command with an absolute path
- Fixed a stray `p` character appearing at the prompt on startup in macOS Terminal.app via Docker or SSH
- Fixed `${ENV_VAR}` placeholders in `headers` for HTTP/SSE/WebSocket MCP servers not being substituted before requests
- Fixed MCP OAuth client secret stored via `--client-secret` not being sent during token exchange for servers requiring `client_secret_post`
- Fixed `/skills` Enter key closing the dialog instead of pre-filling `/<skill-name>` in the prompt
- Fixed `/agents` detail view mislabeling built-in tools unavailable to subagents as “Unrecognized”
- Fixed MCP servers from plugins not spawning on Windows when the plugin cache was incomplete
- Fixed `/export` showing the current default model instead of the model the conversation actually used
- Fixed verbose output setting not persisting after restart
- Fixed `/usage` progress bars overlapping with their “Resets …” labels
- Fixed plugin MCP servers failing when `${user_config.*}` references an optional field left blank
- Fixed list items containing a sentence-final number wrapping the number onto its own line
- Fixed `/plan` and `/plan open` not acting on the existing plan when entering plan mode
- Fixed skills invoked before auto-compaction being re-executed against the next user message
- Fixed `/reload-plugins` and `/doctor` reporting load errors for disabled plugins
- Fixed Agent tool with `isolation: "worktree"` reusing stale worktrees from prior sessions
- Fixed disabled MCP servers appearing as “failed” in `/status`
- Fixed `TaskList` returning tasks in arbitrary filesystem order instead of sorted by ID
- Fixed spurious “GitHub API rate limit exceeded” hints when `gh` output contained PR titles mentioning “rate limit”
- Fixed SDK/bridge `read_file` not correctly enforcing size cap on growing files
- Fixed PR not linked to session when working in a git worktree
- Fixed `/doctor` warning about MCP server entries overridden by a higher-precedence scope
- \[VSCode\] Fixed voice dictation’s first recording producing nothing on macOS while the microphone permission prompt is showing

[​](#2-1-118)

2.1.118

April 23, 2026

**Added**

- Added vim visual mode (`v`) and visual-line mode (`V`) with selection, operators, and visual feedback
- Added `DISABLE_UPDATES` env var to completely block all update paths including manual `claude update` — stricter than `DISABLE_AUTOUPDATER`
- Added a “Don’t ask again” option to the auto mode opt-in prompt
- Added `claude plugin tag` to create release git tags for plugins with version validation

**Changed**

- Merged `/cost` and `/stats` into `/usage` — both remain as typing shortcuts that open the relevant tab
- Create and switch between named custom themes from `/theme`, or hand-edit JSON files in `~/.claude/themes/`; plugins can also ship themes via a `themes/` directory
- Hooks can now invoke MCP tools directly via `type: "mcp_tool"`
- WSL on Windows can now inherit Windows-side managed settings via the `wslInheritsWindowsSettings` policy key
- Auto mode: include `"$defaults"` in `autoMode.allow`, `autoMode.soft_deny`, or `autoMode.environment` to add custom rules alongside the built-in list instead of replacing it
- `--continue`/`--resume` now find sessions that added the current directory via `/add-dir`
- `/color` now syncs the session accent color to claude.ai/code when Remote Control is connected
- The `/model` picker now honors `ANTHROPIC_DEFAULT_*_MODEL_NAME`/`_DESCRIPTION` overrides when using a custom `ANTHROPIC_BASE_URL` gateway
- When auto-update skips a plugin due to another plugin’s version constraint, the skip now appears in `/doctor` and the `/plugin` Errors tab

Show 21 bug fixes

- Fixed `/mcp` menu hiding OAuth Authenticate/Re-authenticate actions for servers configured with `headersHelper`, and HTTP/SSE MCP servers with custom headers being stuck in “needs authentication” after a transient 401
- Fixed MCP servers whose OAuth token response omits `expires_in` requiring re-authentication every hour
- Fixed MCP step-up authorization silently refreshing instead of prompting for re-consent when the server’s `insufficient_scope` 403 names a scope the current token already has
- Fixed an unhandled promise rejection when an MCP server’s OAuth flow times out or is cancelled
- Fixed MCP OAuth refresh proceeding without its cross-process lock under contention
- Fixed macOS keychain race where a concurrent MCP token refresh could overwrite a freshly-refreshed OAuth token, causing unexpected “Please run /login” prompts
- Fixed OAuth token refresh failing when the server revokes a token before its local expiry time
- Fixed credential save crash on Linux/Windows corrupting `~/.claude/.credentials.json`
- Fixed `/login` having no effect in a session launched with `CLAUDE_CODE_OAUTH_TOKEN` — the env token is now cleared so disk credentials take effect
- Fixed unreadable text in the “new messages” scroll pill and `/plugin` badges
- Fixed plan acceptance dialog offering “auto mode” instead of “bypass permissions” when running with `--dangerously-skip-permissions`
- Fixed agent-type hooks failing with “Messages are required for agent hooks” when configured for events other than `Stop` or `SubagentStop`
- Fixed `prompt` hooks re-firing on tool calls made by an agent-hook verifier subagent
- Fixed `/fork` writing the full parent conversation to disk per fork — now writes a pointer and hydrates on read
- Fixed Alt+K / Alt+X / Alt+^ / Alt+\_ freezing keyboard input
- Fixed connecting to a remote session overwriting your local `model` setting in `~/.claude/settings.json`
- Fixed typeahead showing “No commands match” error when pasting file paths that start with `/`
- Fixed `plugin install` on an already-installed plugin not re-resolving a dependency installed at the wrong version
- Fixed unhandled errors from file watcher on invalid paths or fd exhaustion
- Fixed Remote Control sessions getting archived on transient CCR initialization blips during JWT refresh
- Fixed subagents resumed via `SendMessage` not restoring the explicit `cwd` they were spawned with

[​](#2-1-117)

2.1.117

April 22, 2026

**Changed**

- Forked subagents can now be enabled on external builds by setting `CLAUDE_CODE_FORK_SUBAGENT=1`
- Agent frontmatter `mcpServers` are now loaded for main-thread agent sessions via `--agent`
- The `/resume` command now offers to summarize stale, large sessions before re-reading them, matching the existing `--resume` behavior
- Faster startup when both local and claude.ai MCP servers are configured (concurrent connect now default)
- `plugin install` on an already-installed plugin now installs any missing dependencies instead of stopping at “already installed”
- Plugin dependency errors now say “not installed” with an install hint, and `claude plugin marketplace add` now auto-resolves missing dependencies from configured marketplaces
- Managed-settings `blockedMarketplaces` and `strictKnownMarketplaces` are now enforced on plugin install, update, refresh, and autoupdate
- Advisor Tool (experimental): dialog now carries an “experimental” label, learn-more link, and startup notification when enabled; sessions no longer get stuck with “Advisor tool result content could not be processed” errors on every prompt and `/compact`
- The `cleanupPeriodDays` retention sweep now also covers `~/.claude/tasks/`, `~/.claude/shell-snapshots/`, and `~/.claude/backups/`
- OpenTelemetry: `user_prompt` events now include `command_name` and `command_source` for slash commands; `cost.usage`, `token.usage`, `api_request`, and `api_error` now include an `effort` attribute when the model supports effort levels. Custom/MCP command names are redacted unless `OTEL_LOG_TOOL_DETAILS=1` is set
- Native builds on macOS and Linux: the `Glob` and `Grep` tools are replaced by embedded `bfs` and `ugrep` available through the Bash tool — faster searches without a separate tool round-trip (Windows and npm-installed builds unchanged)
- Windows: cached `where.exe` executable lookups per process for faster subprocess launches
- Default effort for Pro/Max subscribers on Opus 4.6 and Sonnet 4.6 is now `high` (was `medium`)

**Improved**

- Improved `/model`: selections now persist across restarts even when the project pins a different model, and the startup header shows when the active model comes from a project or managed-settings pin

Show 14 bug fixes

- Fixed Plain-CLI OAuth sessions dying with “Please run /login” when the access token expires mid-session — the token is now refreshed reactively on 401
- Fixed `WebFetch` hanging on very large HTML pages by truncating input before HTML-to-markdown conversion
- Fixed a crash when a proxy returns HTTP 204 No Content — now surfaces a clear error instead of a `TypeError`
- Fixed `/login` having no effect when launched with `CLAUDE_CODE_OAUTH_TOKEN` env var and that token expires
- Fixed prompt-input undo (`Ctrl+_`) doing nothing immediately after typing, and skipping a state on each undo step
- Fixed `NO_PROXY` not being respected for remote API requests when running under Bun
- Fixed rare spurious escape/return triggers when key names arrive as coalesced text over slow connections
- Fixed SDK `reload_plugins` reconnecting all user MCP servers serially
- Fixed Bedrock application-inference-profile requests failing with 400 when backed by Opus 4.7 with thinking disabled
- Fixed MCP `elicitation/create` requests auto-cancelling in print/SDK mode when the server finishes connecting mid-turn
- Fixed subagents running a different model than the main agent incorrectly flagging file reads with a malware warning
- Fixed idle re-render loop when background tasks are present, reducing memory growth on Linux
- \[VSCode\] Fixed “Manage Plugins” panel breaking when multiple large marketplaces are configured
- Fixed Opus 4.7 sessions showing inflated `/context` percentages and autocompacting too early — Claude Code was computing against a 200K context window instead of Opus 4.7’s native 1M

[​](#2-1-116)

2.1.116

April 20, 2026

**Changed**

- `/resume` on large sessions is significantly faster (up to 67% on 40MB+ sessions) and handles sessions with many dead-fork entries more efficiently
- Faster MCP startup when multiple stdio servers are configured; `resources/templates/list` is now deferred to first `@`-mention
- Smoother fullscreen scrolling in VS Code, Cursor, and Windsurf terminals — `/terminal-setup` now configures the editor’s scroll sensitivity
- Thinking spinner now shows progress inline (“still thinking”, “thinking more”, “almost done thinking”), replacing the separate hint row
- `/config` search now matches option values (e.g. searching “vim” finds the Editor mode setting)
- `/doctor` can now be opened while Claude is responding, without waiting for the current turn to finish
- `/reload-plugins` and background plugin auto-update now auto-install missing plugin dependencies from marketplaces you’ve already added
- Bash tool now surfaces a hint when `gh` commands hit GitHub’s API rate limit, so agents can back off instead of retrying
- The Usage tab in Settings now shows your 5-hour and weekly usage immediately and no longer fails when the usage endpoint is rate-limited
- Agent frontmatter `hooks:` now fire when running as a main-thread agent via `--agent`
- Slash command menu now shows “No commands match” when your filter has zero results, instead of disappearing
- Security: sandbox auto-allow no longer bypasses the dangerous-path safety check for `rm`/`rmdir` targeting `/`, `$HOME`, or other critical system directories
- Claude Code and installer now use `https://downloads.claude.ai/claude-code-releases` instead of `https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases`

Show 12 bug fixes

- Fixed Devanagari and other Indic scripts rendering with broken column alignment in the terminal UI
- Fixed Ctrl+- not triggering undo in terminals using the Kitty keyboard protocol (iTerm2, Ghostty, kitty, WezTerm, Windows Terminal)
- Fixed Cmd+Left/Right not jumping to line start/end in terminals that use the Kitty keyboard protocol (Warp fullscreen, kitty, Ghostty, WezTerm)
- Fixed Ctrl+Z hanging the terminal when Claude Code is launched via a wrapper process (e.g. `npx`, `bun run`)
- Fixed scrollback duplication in inline mode where resizing the terminal or large output bursts would repeat earlier conversation history
- Fixed modal search dialogs overflowing the screen at short terminal heights, hiding the search box and keyboard hints
- Fixed scattered blank cells and disappearing composer chrome in the VS Code integrated terminal during scrolling
- Fixed an intermittent API 400 error related to cache control TTL ordering that could occur when a parallel request completed during request setup
- Fixed `/branch` rejecting conversations with transcripts larger than 50MB
- Fixed `/resume` silently showing an empty conversation on large session files instead of reporting the load error
- Fixed `/plugin` Installed tab showing the same item twice when it appears under Needs attention or Favorites
- Fixed `/update` and `/tui` not working after entering a worktree mid-session

[​](#2-1-114)

2.1.114

April 18, 2026

- Fixed a crash in the permission dialog when an agent teams teammate requested tool permission

[​](#2-1-113)

2.1.113

April 17, 2026

**Added**

- Added `sandbox.network.deniedDomains` setting to block specific domains even when a broader `allowedDomains` wildcard would otherwise permit them

**Changed**

- Changed the CLI to spawn a native Claude Code binary (via a per-platform optional dependency) instead of bundled JavaScript
- Fullscreen mode: Shift+↑/↓ now scrolls the viewport when extending a selection past the visible edge
- `Ctrl+A` and `Ctrl+E` now move to the start/end of the current logical line in multiline input, matching readline behavior
- Windows: `Ctrl+Backspace` now deletes the previous word
- Long URLs in responses and bash output stay clickable when they wrap across lines (in terminals with OSC 8 hyperlinks)
- `/extra-usage` now works from Remote Control (mobile/web) clients
- Remote Control clients can now query `@`-file autocomplete suggestions
- Subagents that stall mid-stream now fail with a clear error after 10 minutes instead of hanging silently
- Bash tool: multi-line commands whose first line is a comment now show the full command in the transcript, closing a UI-spoofing vector
- Running `cd <current-directory> && git …` no longer triggers a permission prompt when the `cd` is a no-op
- Security: on macOS, `/private/{etc,var,tmp,home}` paths are now treated as dangerous removal targets under `Bash(rm:*)` allow rules
- Security: Bash deny rules now match commands wrapped in `env`/`sudo`/`watch`/`ionice`/`setsid` and similar exec wrappers
- Security: `Bash(find:*)` allow rules no longer auto-approve `find -exec`/`-delete`

**Improved**

- Improved `/loop`: pressing Esc now cancels pending wakeups, and wakeups display as “Claude resuming /loop wakeup” for clarity
- Improved `/ultrareview`: faster launch with parallelized checks, diffstat in the launch dialog, and animated launching state

Show 22 bug fixes

- Fixed MCP concurrent-call timeout handling where a message for one tool call could silently disarm another call’s watchdog
- Fixed Cmd-backspace / `Ctrl+U` to once again delete from the cursor to the start of the line
- Fixed markdown tables breaking when a cell contains an inline code span with a pipe character
- Fixed session recap auto-firing while composing unsent text in the prompt
- Fixed `/copy` “Full response” not aligning markdown table columns for pasting into GitHub, Notion, or Slack
- Fixed messages typed while viewing a running subagent being hidden from its transcript and misattributed to the parent AI
- Fixed Bash `dangerouslyDisableSandbox` running commands outside the sandbox without a permission prompt
- Fixed `/effort auto` confirmation — now says “Effort level set to max” to match the status bar label
- Fixed the “copied N chars” toast overcounting emoji and other multi-code-unit characters
- Fixed `/insights` crashing with `EBUSY` on Windows
- Fixed exit confirmation dialog mislabeling one-shot scheduled tasks as recurring — now shows a countdown
- Fixed slash/@ completion menu not sitting flush against the prompt border in fullscreen mode
- Fixed `CLAUDE_CODE_EXTRA_BODY` `output_config.effort` causing 400 errors on subagent calls to models that don’t support effort and on Vertex AI
- Fixed prompt cursor disappearing when `NO_COLOR` is set
- Fixed `ToolSearch` ranking so pasted MCP tool names surface the actual tool instead of description-matching siblings
- Fixed compacting a resumed long-context session failing with “Extra usage is required for long context requests”
- Fixed `plugin install` succeeding when a dependency version conflicts with an already-installed plugin — now reports `range-conflict`
- Fixed “Refine with Ultraplan” not showing the remote session URL in the transcript
- Fixed SDK image content blocks that fail to process crashing the session — now degrade to a text placeholder
- Fixed Remote Control sessions not streaming subagent transcripts
- Fixed Remote Control sessions not being archived when Claude Code exits
- Fixed `thinking.type.enabled is not supported` 400 error when using Opus 4.7 via a Bedrock Application Inference Profile ARN

[​](#2-1-112)

2.1.112

April 16, 2026

- Fixed “claude-opus-4-7 is temporarily unavailable” for auto mode

[​](#2-1-111)

2.1.111

April 16, 2026

**Added**

- Added `xhigh` effort level for Opus 4.7, sitting between `high` and `max`. Available via `/effort`, `--effort`, and the model picker; other models fall back to `high`
- Added “Auto (match terminal)” theme option that matches your terminal’s dark/light mode — select it from `/theme`
- Added `/less-permission-prompts` skill — scans transcripts for common read-only Bash and MCP tool calls and proposes a prioritized allowlist for `.claude/settings.json`
- Added `/ultrareview` for running comprehensive code review in the cloud using parallel multi-agent analysis and critique — invoke with no arguments to review your current branch, or `/ultrareview <PR#>` to fetch and review a specific GitHub PR
- Added `OTEL_LOG_RAW_API_BODIES` environment variable to emit full API request and response bodies as OpenTelemetry log events for debugging

**Changed**

- Claude Opus 4.7 xhigh is now available! Use /effort to tune speed vs. intelligence
- Auto mode is now available for Max subscribers when using Opus 4.7
- `/effort` now opens an interactive slider when called without arguments, with arrow-key navigation between levels and Enter to confirm
- Auto mode no longer requires `--enable-auto-mode`
- Windows: PowerShell tool is progressively rolling out. Opt in or out with `CLAUDE_CODE_USE_POWERSHELL_TOOL`. On Linux and macOS, enable with `CLAUDE_CODE_USE_POWERSHELL_TOOL=1` (requires `pwsh` on PATH)
- Read-only bash commands with glob patterns (e.g. `ls *.ts`) and commands starting with `cd <project-dir> &&` no longer trigger a permission prompt
- Suggest the closest matching subcommand when `claude <word>` is invoked with a near-miss typo (e.g. `claude udpate` → “Did you mean `claude update`?”)
- Plan files are now named after your prompt (e.g. `fix-auth-race-snug-otter.md`) instead of purely random words
- `/skills` menu now supports sorting by estimated token count — press `t` to toggle
- `Ctrl+U` now clears the entire input buffer (previously: delete to start of line); press `Ctrl+Y` to restore
- `Ctrl+L` now forces a full screen redraw in addition to clearing the prompt input
- Transcript view footer now shows `[` (dump to scrollback) and `v` (open in editor) shortcuts
- The “+N lines” marker for truncated long pastes is now a full-width rule for easier scanning
- Headless `--output-format stream-json` now includes `plugin_errors` on the init event when plugins are demoted for unsatisfied dependencies
- Suppressed spurious decompression, network, and transient error messages that could appear in the TUI during normal operation
- Reverted the v2.1.110 cap on non-streaming fallback retries — it traded long waits for more outright failures during API overload
- Windows: `CLAUDE_ENV_FILE` and SessionStart hook environment files now apply (previously a no-op)
- Windows: permission rules with drive-letter paths are now correctly root-anchored, and paths differing only by drive-letter case are recognized as the same path

**Improved**

- Improved `/setup-vertex` and `/setup-bedrock` to show the actual `settings.json` path when `CLAUDE_CONFIG_DIR` is set, seed model candidates from existing pins on re-run, and offer a “with 1M context” option for supported models
- Improved plugin error handling: dependency errors now distinguish conflicting, invalid, and overly complex version requirements; fixed stale resolved versions after `plugin update`; `plugin install` now recovers from interrupted prior installs

Show 10 bug fixes

- Fixed terminal display tearing (random characters, drifting input) in iTerm2 + tmux setups when terminal notifications are sent
- Fixed `@` file suggestions re-scanning the entire project on every turn in non-git working directories, and showing only config files in freshly-initialized git repos with no tracked files
- Fixed LSP diagnostics from before an edit appearing after it, causing the model to re-read files it just edited
- Fixed tab-completing `/resume` immediately resuming an arbitrary titled session instead of showing the session picker
- Fixed `/context` grid rendering with extra blank lines between rows
- Fixed `/clear` dropping the session name set by `/rename`, causing statusline output to lose `session_name`
- Fixed Claude calling a non-existent `commit` skill and showing “Unknown skill: commit” for users without a custom `/commit` command
- Fixed 429 rate-limit errors on Bedrock/Vertex/Foundry referencing status.claude.com (it only covers Anthropic-operated providers)
- Fixed feedback surveys appearing back-to-back after dismissing one
- Fixed bare URLs in bash/PowerShell/MCP tool output being unclickable when the terminal wraps them across lines

[​](#2-1-110)

2.1.110

April 15, 2026

**Added**

- Added `/tui` command and `tui` setting — run `/tui fullscreen` to switch to flicker-free rendering in the same conversation
- Added push notification tool — Claude can send mobile push notifications when Remote Control and “Push when Claude decides” config are enabled
- Added `autoScrollEnabled` config to disable conversation auto-scroll in fullscreen mode
- Added option to show Claude’s last response as commented context in the `Ctrl+G` external editor (enable via `/config`)

**Changed**

- Changed `Ctrl+O` to toggle between normal and verbose transcript only; focus view is now toggled separately with the new `/focus` command
- `--resume`/`--continue` now resurrects unexpired scheduled tasks
- `/context`, `/exit`, and `/reload-plugins` now work from Remote Control (mobile/web) clients
- Write tool now informs the model when you edit the proposed content in the IDE diff before accepting
- Bash tool now enforces the documented maximum timeout instead of accepting arbitrarily large values
- SDK/headless sessions now read `TRACEPARENT`/`TRACESTATE` from the environment for distributed trace linking
- Session recap is now enabled for users with telemetry disabled (Bedrock, Vertex, Foundry, `DISABLE_TELEMETRY`). Opt out via `/config` or `CLAUDE_CODE_ENABLE_AWAY_SUMMARY=0`.
- Hardened “Open in editor” actions against command injection from untrusted filenames

**Improved**

- Improved `/plugin` Installed tab — items needing attention and favorites appear at the top, disabled items are hidden behind a fold, and `f` favorites the selected item
- Improved `/doctor` to warn when an MCP server is defined in multiple config scopes with different endpoints

Show 19 bug fixes

- Fixed MCP tool calls hanging indefinitely when the server connection drops mid-response on SSE/HTTP transports
- Fixed non-streaming fallback retries causing multi-minute hangs when the API is unreachable
- Fixed session recap, local slash-command output, and other system status lines not appearing in focus mode
- Fixed high CPU usage in fullscreen when text is selected while a tool is running
- Fixed plugin install not honoring dependencies declared in `plugin.json` when the marketplace entry omits them; `/plugin` install now lists auto-installed dependencies
- Fixed skills with `disable-model-invocation: true` failing when invoked via `/<skill>` mid-message
- Fixed `--resume` sometimes showing the first prompt instead of the `/rename` name for sessions still running or exited uncleanly
- Fixed queued messages briefly appearing twice during multi-tool-call turns
- Fixed session cleanup not removing the full session directory including subagent transcripts
- Fixed dropped keystrokes after the CLI relaunches (e.g. `/tui`, provider setup wizards)
- Fixed garbled startup rendering in macOS Terminal.app and other terminals that don’t support synchronized output
- Fixed `PermissionRequest` hooks returning `updatedInput` not being re-checked against `permissions.deny` rules; `setMode:'bypassPermissions'` updates now respect `disableBypassPermissionsMode`
- Fixed `PreToolUse` hook `additionalContext` being dropped when the tool call fails
- Fixed stdio MCP servers that print stray non-JSON lines to stdout being disconnected on the first stray line (regression in 2.1.105)
- Fixed headless/SDK session auto-title firing an extra Haiku request when `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` or `CLAUDE_CODE_DISABLE_TERMINAL_TITLE` is set
- Fixed potential excessive memory allocation when piped (non-TTY) Ink output contains a single very wide line
- Fixed `/skills` menu not scrolling when the list overflows the modal in fullscreen mode
- Fixed Remote Control sessions showing a generic error instead of prompting for re-login when the session is too old
- Fixed Remote Control session renames from claude.ai not persisting the title to the local CLI session

[​](#2-1-109)

2.1.109

April 15, 2026

- Improved the extended-thinking indicator with a rotating progress hint

[​](#2-1-108)

2.1.108

April 14, 2026

**Added**

- Added `ENABLE_PROMPT_CACHING_1H` env var to opt into 1-hour prompt cache TTL on API key, Bedrock, Vertex, and Foundry (`ENABLE_PROMPT_CACHING_1H_BEDROCK` is deprecated but still honored), and `FORCE_PROMPT_CACHING_5M` to force 5-minute TTL
- Added recap feature to provide context when returning to a session, configurable in `/config` and manually invocable with `/recap`; force with `CLAUDE_CODE_ENABLE_AWAY_SUMMARY` if telemetry disabled.
- Added “verbose” indicator when viewing the detailed transcript (`Ctrl+O`)
- Added a warning at startup when prompt caching is disabled via `DISABLE_PROMPT_CACHING*` environment variables

**Changed**

- The model can now discover and invoke built-in slash commands like `/init`, `/review`, and `/security-review` via the Skill tool
- `/undo` is now an alias for `/rewind`
- Reduced memory footprint for file reads, edits, and syntax highlighting by loading language grammars on demand

**Improved**

- Improved `/model` to warn before switching models mid-conversation, since the next response re-reads the full history uncached
- Improved `/resume` picker to default to sessions from the current directory; press `Ctrl+A` to show all projects
- Improved error messages: server rate limits are now distinguished from plan usage limits; 5xx/529 errors show a link to status.claude.com; unknown slash commands suggest the closest match

Show 14 bug fixes

- Fixed paste not working in the `/login` code prompt (regression in 2.1.105)
- Fixed subscribers who set `DISABLE_TELEMETRY` falling back to 5-minute prompt cache TTL instead of 1 hour
- Fixed Agent tool prompting for permission in auto mode when the safety classifier’s transcript exceeded its context window
- Fixed Bash tool producing no output when `CLAUDE_ENV_FILE` (e.g. `~/.zprofile`) ends with a `#` comment line
- Fixed `claude --resume <session-id>` losing the session’s custom name and color set via `/rename`
- Fixed session titles showing placeholder example text when the first message is a short greeting
- Fixed terminal escape codes appearing as garbage text in the prompt input after `--teleport`
- Fixed `/feedback` retry: pressing Enter to resubmit after a failure now works without first editing the description
- Fixed `--teleport` and `--resume <id>` precondition errors (e.g. dirty git tree, session not found) exiting silently instead of showing the error message
- Fixed Remote Control session titles set in the web UI being overwritten by auto-generated titles after the third message
- Fixed `--resume` truncating sessions when the transcript contained a self-referencing message
- Fixed transcript write failures (e.g., disk full) being silently dropped instead of being logged
- Fixed diacritical marks (accents, umlauts, cedillas) being dropped from responses when the `language` setting is configured
- Fixed policy-managed plugins never auto-updating when running from a different project than where they were first installed

[​](#2-1-107)

2.1.107

April 14, 2026

- Show thinking hints sooner during long operations

[​](#2-1-105)

2.1.105

April 13, 2026

**Added**

- Added `path` parameter to the `EnterWorktree` tool to switch into an existing worktree of the current repository
- Added PreCompact hook support: hooks can now block compaction by exiting with code 2 or returning `{"decision":"block"}`
- Added background monitor support for plugins via a top-level `monitors` manifest key that auto-arms at session start or on skill invoke

**Changed**

- `/proactive` is now an alias for `/loop`

Show 9 improvements

- Improved stalled API stream handling: streams now abort after 5 minutes of no data and retry non-streaming instead of hanging indefinitely
- Improved network error messages: connection errors now show a retry message immediately instead of a silent spinner
- Improved file write display: long single-line writes (e.g. minified JSON) are now truncated in the UI instead of paginating across many screens
- Improved `/doctor` layout with status icons; press `f` to have Claude fix reported issues
- Improved `/config` labels and descriptions for clarity
- Improved skill description handling: raised the listing cap from 250 to 1,536 characters and added a startup warning when descriptions are truncated
- Improved `WebFetch` to strip `<style>` and `<script>` contents from fetched pages so CSS-heavy pages no longer exhaust the content budget before reaching actual text
- Improved stale agent worktree cleanup to remove worktrees whose PR was squash-merged instead of keeping them indefinitely
- Improved MCP large-output truncation prompt to give format-specific recipes (e.g. `jq` for JSON, computed Read chunk sizes for text)

Show 24 bug fixes

- Fixed images attached to queued messages (sent while Claude is working) being dropped
- Fixed screen going blank when the prompt input wraps to a second line in long conversations
- Fixed leading whitespace getting copied when selecting multi-line assistant responses in fullscreen mode
- Fixed leading whitespace being trimmed from assistant messages, breaking ASCII art and indented diagrams
- Fixed garbled bash output when commands print clickable file links (e.g. Python `rich`/`loguru` logging)
- Fixed alt+enter not inserting a newline in terminals using ESC-prefix alt encoding, and Ctrl+J not inserting a newline (regression in 2.1.100)
- Fixed duplicate “Creating worktree” text in EnterWorktree/ExitWorktree tool display
- Fixed queued user prompts disappearing from focus mode
- Fixed one-shot scheduled tasks re-firing repeatedly when the file watcher missed the post-fire cleanup
- Fixed inbound channel notifications being silently dropped after the first message for Team/Enterprise users
- Fixed marketplace plugins with `package.json` and lockfile not having dependencies installed automatically after install/update
- Fixed marketplace auto-update leaving the official marketplace in a broken state when a plugin process holds files open during the update
- Fixed “Resume this session with…” hint not printing on exit after `/resume`, `--worktree`, or `/branch`
- Fixed feedback survey shortcut keys firing when typed at the end of a longer prompt
- Fixed stdio MCP server emitting malformed (non-JSON) output hanging the session instead of failing fast with “Connection closed”
- Fixed MCP tools missing on the first turn of headless/remote-trigger sessions when MCP servers connect asynchronously
- Fixed `/model` picker on AWS Bedrock in non-US regions persisting invalid `us.*` model IDs to `settings.json` when inference profile discovery is still in-flight
- Fixed 429 rate-limit errors showing a raw JSON dump instead of a clean message for API-key, Bedrock, and Vertex users
- Fixed crash on resume when session contains malformed text blocks
- Fixed `/help` dropping the tab bar, Shortcuts heading, and footer at short terminal heights
- Fixed malformed keybinding entry values in `keybindings.json` being silently loaded instead of rejected with a clear error
- Fixed `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` in one project’s settings permanently disabling usage metrics for all projects on the machine
- Fixed washed-out 16-color palette when using Ghostty, Kitty, Alacritty, WezTerm, foot, rio, or Contour over SSH/mosh
- Fixed Bash tool suggesting `acceptEdits` permission mode when exiting plan mode would downgrade from a higher permission level

[​](#2-1-101)

2.1.101

April 10, 2026

**Added**

- Added `/team-onboarding` command to generate a teammate ramp-up guide from your local Claude Code usage
- Added OS CA certificate store trust by default, so enterprise TLS proxies work without extra setup (set `CLAUDE_CODE_CERT_STORE=bundled` to use only bundled CAs)

**Changed**

- `/ultraplan` and other remote-session features now auto-create a default cloud environment instead of requiring web setup first

Show 12 improvements

- Improved brief mode to retry once when Claude responds with plain text instead of a structured message
- Improved focus mode: Claude now writes more self-contained summaries since it knows you only see its final message
- Improved tool-not-available errors to explain why and how to proceed when the model calls a tool that exists but isn’t available in the current context
- Improved rate-limit retry messages to show which limit was hit and when it resets instead of an opaque seconds countdown
- Improved refusal error messages to include the API-provided explanation when available
- Improved `claude -p --resume <name>` to accept session titles set via `/rename` or `--name`
- Improved settings resilience: an unrecognized hook event name in `settings.json` no longer causes the entire file to be ignored
- Improved plugin hooks from plugins force-enabled by managed settings to run when `allowManagedHooksOnly` is set
- Improved `/plugin` and `claude plugin update` to show a warning when the marketplace could not be refreshed, instead of silently reporting a stale version
- Improved plan mode to hide the “Refine with Ultraplan” option when the user’s org or auth setup can’t reach Claude Code on the web
- Improved beta tracing to honor `OTEL_LOG_USER_PROMPTS`, `OTEL_LOG_TOOL_DETAILS`, and `OTEL_LOG_TOOL_CONTENT`; sensitive span attributes are no longer emitted unless opted in
- Improved SDK `query()` to clean up subprocess and temp files when consumers `break` from `for await` or use `await using`

Show 31 bug fixes

- Fixed a command injection vulnerability in the POSIX `which` fallback used by LSP binary detection
- Fixed a memory leak where long sessions retained dozens of historical copies of the message list in the virtual scroller
- Fixed `--resume`/`--continue` losing conversation context on large sessions when the loader anchored on a dead-end branch instead of the live conversation
- Fixed `--resume` chain recovery bridging into an unrelated subagent conversation when a subagent message landed near a main-chain write gap
- Fixed a crash on `--resume` when a persisted Edit/Write tool result was missing its `file_path`
- Fixed a hardcoded 5-minute request timeout that aborted slow backends (local LLMs, extended thinking, slow gateways) regardless of `API_TIMEOUT_MS`
- Fixed `permissions.deny` rules not overriding a PreToolUse hook’s `permissionDecision: "ask"` — previously the hook could downgrade a deny into a prompt
- Fixed `--setting-sources` without `user` causing background cleanup to ignore `cleanupPeriodDays` and delete conversation history older than 30 days
- Fixed Bedrock SigV4 authentication failing with 403 when `ANTHROPIC_AUTH_TOKEN`, `apiKeyHelper`, or `ANTHROPIC_CUSTOM_HEADERS` set an Authorization header
- Fixed `claude -w <name>` failing with “already exists” after a previous session’s worktree cleanup left a stale directory
- Fixed subagents not inheriting MCP tools from dynamically-injected servers
- Fixed sub-agents running in isolated worktrees being denied Read/Edit access to files inside their own worktree
- Fixed sandboxed Bash commands failing with `mktemp: No such file or directory` after a fresh boot
- Fixed `claude mcp serve` tool calls failing with “Tool execution failed” in MCP clients that validate `outputSchema`
- Fixed `RemoteTrigger` tool’s `run` action sending an empty body and being rejected by the server
- Fixed several `/resume` picker issues: narrow default view hiding sessions from other projects, unreachable preview on Windows Terminal, incorrect cwd in worktrees, session-not-found errors not surfacing in stderr, terminal title not being set, and resume hint overlapping the prompt input
- Fixed Grep tool ENOENT when the embedded ripgrep binary path becomes stale (VS Code extension auto-update, macOS App Translocation); now falls back to system `rg` and self-heals mid-session
- Fixed `/btw` writing a copy of the entire conversation to disk on every use
- Fixed `/context` Free space and Messages breakdown disagreeing with the header percentage
- Fixed several plugin issues: slash commands resolving to the wrong plugin with duplicate `name:` frontmatter, `/plugin update` failing with `ENAMETOOLONG`, Discover showing already-installed plugins, directory-source plugins loading from a stale version cache, and skills not honoring `context: fork` and `agent` frontmatter fields
- Fixed the `/mcp` menu offering OAuth-specific actions for MCP servers configured with `headersHelper`; Reconnect is now offered instead to re-invoke the helper script
- Fixed `ctrl+]`, `ctrl+\`, and `ctrl+^` keybindings not firing in terminals that send raw C0 control bytes (Terminal.app, default iTerm2, xterm)
- Fixed `/login` OAuth URL rendering with padding that prevented clean mouse selection
- Fixed rendering issues: flicker in non-fullscreen mode when content above the visible area changed, terminal scrollback being wiped during long sessions in non-fullscreen mode, and mouse-scroll escape sequences occasionally leaking into the prompt as text
- Fixed crash when `settings.json` env values are numbers instead of strings
- Fixed in-app settings writes (e.g. `/add-dir --remember`, `/config`) not refreshing the in-memory snapshot, preventing removed directories from being revoked mid-session
- Fixed custom keybindings (`~/.claude/keybindings.json`) not loading on Bedrock, Vertex, and other third-party providers
- Fixed `claude --continue -p` not correctly continuing sessions created by `-p` or the SDK
- Fixed several Remote Control issues: worktrees removed on session crash, connection failures not persisting in the transcript, spurious “Disconnected” indicator in brief mode for local sessions, and `/remote-control` failing over SSH when only `CLAUDE_CODE_ORGANIZATION_UUID` is set
- Fixed `/insights` sometimes omitting the report file link from its response
- \[VSCode\] Fixed the file attachment below the chat input not clearing when the last editor tab is closed

[​](#2-1-98)

2.1.98

April 9, 2026

**Added**

- Added interactive Google Vertex AI setup wizard accessible from the login screen when selecting “3rd-party platform”, guiding you through GCP authentication, project and region configuration, credential verification, and model pinning
- Added `CLAUDE_CODE_PERFORCE_MODE` env var: when set, Edit/Write/NotebookEdit fail on read-only files with a `p4 edit` hint instead of silently overwriting them
- Added Monitor tool for streaming events from background scripts
- Added subprocess sandboxing with PID namespace isolation on Linux when `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` is set, and `CLAUDE_CODE_SCRIPT_CAPS` env var to limit per-session script invocations
- Added `--exclude-dynamic-system-prompt-sections` flag to print mode for improved cross-user prompt caching
- Added `workspace.git_worktree` to the status line JSON input, set whenever the current directory is inside a linked git worktree
- Added W3C `TRACEPARENT` env var to Bash tool subprocesses when OTEL tracing is enabled, so child-process spans correctly parent to Claude Code’s trace tree

**Changed**

- LSP: Claude Code now identifies itself to language servers via `clientInfo` in the initialize request
- Updated the `/claude-api` skill to cover Managed Agents alongside Claude API
- Dropped `/compact` hints when `DISABLE_COMPACT` is set.

Show 9 improvements

- Improved `/resume` filter hint labels and added project/worktree/branch names in the filter indicator
- Improved footer indicators (Focus, notifications) to stay on the mode-indicator row instead of wrapping at narrow terminal widths
- Improved `/agents` with a tabbed layout: a Running tab shows live subagents, and the Library tab adds Run agent and View running instance actions
- Improved `/reload-plugins` to pick up plugin-provided skills without requiring a restart
- Improved Accept Edits mode to auto-approve filesystem commands prefixed with safe env vars or process wrappers
- Improved Vim mode: `j`/`k` in NORMAL mode now navigate history and select the footer pill at the input boundary
- Improved hook errors in the transcript to include the first line of stderr for self-diagnosis without `--debug`
- Improved OTEL tracing: interaction spans now correctly wrap full turns under concurrent SDK calls, and headless turns end spans per-turn
- Improved transcript entries to carry final token usage instead of streaming placeholders

Show 38 bug fixes

- Fixed a Bash tool permission bypass where a backslash-escaped flag could be auto-allowed as read-only and lead to arbitrary code execution
- Fixed compound Bash commands bypassing forced permission prompts for safety checks and explicit ask rules in auto and bypass-permissions modes
- Fixed read-only commands with env-var prefixes not prompting unless the var is known-safe (`LANG`, `TZ`, `NO_COLOR`, etc.)
- Fixed redirects to `/dev/tcp/...` or `/dev/udp/...` not prompting instead of auto-allowing
- Fixed stalled streaming responses timing out instead of falling back to non-streaming mode
- Fixed 429 retries burning all attempts in ~13s when the server returns a small `Retry-After` — exponential backoff now applies as a minimum
- Fixed MCP OAuth `oauth.authServerMetadataUrl` config override not being honored on token refresh after restart, affecting ADFS and similar IdPs
- Fixed capital letters being dropped to lowercase on xterm and VS Code integrated terminal when the kitty keyboard protocol is active
- Fixed macOS text replacements deleting the trigger word instead of inserting the substitution
- Fixed `--dangerously-skip-permissions` being silently downgraded to accept-edits mode after approving a write to a protected path via Bash
- Fixed managed-settings allow rules remaining active after an admin removed them, until process restart
- Fixed `permissions.additionalDirectories` changes not applying mid-session — removed directories lose access immediately and added ones work without restart
- Fixed removing a directory from `additionalDirectories` revoking access to the same directory passed via `--add-dir`
- Fixed `Bash(cmd:*)` and `Bash(git commit *)` wildcard permission rules failing to match commands with extra spaces or tabs
- Fixed `Bash(...)` deny rules being downgraded to a prompt for piped commands that mix `cd` with other segments
- Fixed false Bash permission prompts for `cut -d /`, `paste -d /`, `column -s /`, `awk '{print $1}' file`, and filenames containing `%`
- Fixed permission rules with names matching JavaScript prototype properties (e.g. `toString`) causing `settings.json` to be silently ignored
- Fixed agent team members not inheriting the leader’s permission mode when using `--dangerously-skip-permissions`
- Fixed a crash in fullscreen mode when hovering over MCP tool results
- Fixed copying wrapped URLs in fullscreen mode inserting spaces at line breaks
- Fixed file-edit diffs disappearing from the UI on `--resume` when the edited file was larger than 10KB
- Fixed several `/resume` picker issues: `--resume <name>` opening uneditable, filter reload wiping search state, empty list swallowing arrow keys, cross-project staleness, and transient task-status text replacing conversation summaries
- Fixed `/export` not honoring absolute paths and `~`, and silently rewriting user-supplied extensions to `.txt`
- Fixed `/effort max` being denied for unknown or future model IDs
- Fixed slash command picker breaking when a plugin’s frontmatter `name` is a YAML boolean keyword
- Fixed rate-limit upsell text being hidden after message remounts
- Fixed MCP tools with `_meta["anthropic/maxResultSizeChars"]` not bypassing the token-based persist layer
- Fixed voice mode leaking dozens of space characters into the input when re-holding the push-to-talk key while the previous transcript is still processing
- Fixed `DISABLE_AUTOUPDATER` not fully suppressing the npm registry version check and symlink modification on npm-based installs
- Fixed a memory leak where Remote Control permission handler entries were retained for the lifetime of the session
- Fixed background subagents that fail with an error not reporting partial progress to the parent agent
- Fixed prompt-type Stop/SubagentStop hooks failing on long sessions, and hook evaluator API errors showing “JSON validation failed” instead of the real message
- Fixed feedback survey rendering when dismissed
- Fixed Bash `grep -f FILE` / `rg -f FILE` not prompting when reading a pattern file outside the working directory
- Fixed stale subagent worktree cleanup removing worktrees that contain untracked files
- Fixed `sandbox.network.allowMachLookup` not taking effect on macOS
- \[VSCode\] Fixed false-positive “requires git-bash” error on Windows when `CLAUDE_CODE_GIT_BASH_PATH` is set or Git is installed at a default location
- Fixed `CLAUDE_CODE_MAX_CONTEXT_TOKENS` to honor `DISABLE_COMPACT` when it is set.

[​](#2-1-97)

2.1.97

April 8, 2026

**Added**

- Added focus view toggle (`Ctrl+O`) in `NO_FLICKER` mode showing prompt, one-line tool summary with edit diffstats, and final response
- Added `refreshInterval` status line setting to re-run the status line command every N seconds
- Added `workspace.git_worktree` to the status line JSON input, set when the current directory is inside a linked git worktree
- Added `● N running` indicator in `/agents` next to agent types with live subagent instances
- Added syntax highlighting for Cedar policy files (`.cedar`, `.cedarpolicy`)

**Changed**

- Updated `/claude-api` skill to cover Managed Agents alongside the Claude API

Show 12 improvements

- Improved Accept Edits mode to auto-approve filesystem commands prefixed with safe env vars or process wrappers (e.g. `LANG=C rm foo`, `timeout 5 mkdir out`)
- Improved auto mode and bypass-permissions mode to auto-approve sandbox network access prompts
- Improved sandbox: `sandbox.network.allowMachLookup` now takes effect on macOS
- Improved image handling: pasted and attached images are now compressed to the same token budget as images read via the Read tool
- Improved slash command and `@`-mention completion to trigger after CJK sentence punctuation, so Japanese/Chinese input no longer requires a space before `/` or `@`
- Improved Bridge sessions to show the local git repo, branch, and working directory on the claude.ai session card
- Improved footer layout: indicators (Focus, notifications) now stay on the mode-indicator row instead of wrapping below
- Improved context-low warning to show as a transient footer notification instead of a persistent row
- Improved markdown blockquotes to show a continuous left bar across wrapped lines
- Improved session transcript size by skipping empty hook entries and capping stored pre-edit file copies
- Improved transcript accuracy: per-block entries now carry the final token usage instead of the streaming placeholder
- Improved Bash tool OTEL tracing: subprocesses now inherit a W3C `TRACEPARENT` env var when tracing is enabled

Show 28 bug fixes

- Fixed `--dangerously-skip-permissions` being silently downgraded to accept-edits mode after approving a write to a protected path
- Fixed and hardened Bash tool permissions, tightening checks around env-var prefixes and network redirects, and reducing false prompts on common commands
- Fixed permission rules with names matching JavaScript prototype properties (e.g. `toString`) causing `settings.json` to be silently ignored
- Fixed managed-settings allow rules remaining active after an admin removed them until process restart
- Fixed `permissions.additionalDirectories` changes in settings not applying mid-session
- Fixed removing a directory from `settings.permissions.additionalDirectories` revoking access to the same directory passed via `--add-dir`
- Fixed MCP HTTP/SSE connections accumulating ~50 MB/hr of unreleased buffers when servers reconnect
- Fixed MCP OAuth `oauth.authServerMetadataUrl` not being honored on token refresh after restart, fixing ADFS and similar IdPs
- Fixed 429 retries burning all attempts in ~13 seconds when the server returns a small `Retry-After` — exponential backoff now applies as a minimum
- Fixed rate-limit upgrade options disappearing after context compaction
- Fixed several `/resume` picker issues: `--resume <name>` opening uneditable, Ctrl+A reload wiping search, empty list swallowing navigation, task-status text replacing conversation summary, and cross-project staleness
- Fixed file-edit diffs disappearing on `--resume` when the edited file was larger than 10KB
- Fixed `--resume` cache misses and lost mid-turn input from attachment messages not being saved to the transcript
- Fixed messages typed while Claude is working not being persisted to the transcript
- Fixed prompt-type `Stop`/`SubagentStop` hooks failing on long sessions, and hook evaluator API errors displaying “JSON validation failed” instead of the actual message
- Fixed subagents with worktree isolation or `cwd:` override leaking their working directory back to the parent session’s Bash tool
- Fixed compaction writing duplicate multi-MB subagent transcript files on prompt-too-long retries
- Fixed `claude plugin update` reporting “already at the latest version” for git-based marketplace plugins when the remote had newer commits
- Fixed slash command picker breaking when a plugin’s frontmatter `name` is a YAML boolean keyword
- Fixed copying wrapped URLs in `NO_FLICKER` mode inserting spaces at line breaks
- Fixed scroll rendering artifacts in `NO_FLICKER` mode when running inside zellij
- Fixed a crash in `NO_FLICKER` mode when hovering over MCP tool results
- Fixed a `NO_FLICKER` mode memory leak where API retries left stale streaming state
- Fixed slow mouse-wheel scrolling in `NO_FLICKER` mode on Windows Terminal
- Fixed custom status line not displaying in `NO_FLICKER` mode on terminals shorter than 24 rows
- Fixed Shift+Enter and Alt/Cmd+arrow shortcuts not working in Warp with `NO_FLICKER` mode
- Fixed Korean/Japanese/Unicode text becoming garbled when copied in no-flicker mode on Windows
- Fixed Bedrock SigV4 authentication failing when `AWS_BEARER_TOKEN_BEDROCK` or `ANTHROPIC_BEDROCK_BASE_URL` are set to empty strings (as GitHub Actions does for unset inputs)

[​](#2-1-96)

2.1.96

April 8, 2026

- Fixed Bedrock requests failing with `403 "Authorization header is missing"` when using `AWS_BEARER_TOKEN_BEDROCK` or `CLAUDE_CODE_SKIP_BEDROCK_AUTH` (regression in 2.1.94)

[​](#2-1-94)

2.1.94

April 7, 2026

**Added**

- Added support for Amazon Bedrock powered by Mantle, set `CLAUDE_CODE_USE_MANTLE=1`
- Added compact `Slacked #channel` header with a clickable channel link for Slack MCP send-message tool calls
- Added `keep-coding-instructions` frontmatter field support for plugin output styles
- Added `hookSpecificOutput.sessionTitle` to `UserPromptSubmit` hooks for setting the session title
- \[VSCode\] Added a warning banner when `settings.json` files fail to parse, so users know their permission rules are not being applied

**Changed**

- Changed default effort level from medium to high for API-key, Bedrock/Vertex/Foundry, Team, and Enterprise users (control this with `/effort`)
- Plugin skills declared via `"skills": ["./"]` now use the skill’s frontmatter `name` for the invocation name instead of the directory basename, giving a stable name across install methods
- \[VSCode\] Reduced cold-open subprocess work on starting a session

**Improved**

- Improved `--resume` to resume sessions from other worktrees of the same repo directly instead of printing a `cd` command

Show 16 bug fixes

- Fixed agents appearing stuck after a 429 rate-limit response with a long Retry-After header — the error now surfaces immediately instead of silently waiting
- Fixed Console login on macOS silently failing with “Not logged in” when the login keychain is locked or its password is out of sync — the error is now surfaced and `claude doctor` diagnoses the fix
- Fixed plugin skill hooks defined in YAML frontmatter being silently ignored
- Fixed plugin hooks failing with “No such file or directory” when `CLAUDE_PLUGIN_ROOT` was not set
- Fixed `${CLAUDE_PLUGIN_ROOT}` resolving to the marketplace source directory instead of the installed cache for local-marketplace plugins on startup
- Fixed scrollback showing the same diff repeated and blank pages in long-running sessions
- Fixed multiline user prompts in the transcript indenting wrapped lines under the `❯` caret instead of under the text
- Fixed Shift+Space inserting the literal word “space” instead of a space character in search inputs
- Fixed hyperlinks opening two browser tabs when clicked inside tmux running in an xterm.js-based terminal (VS Code, Hyper, Tabby)
- Fixed an alt-screen rendering bug where content height changes mid-scroll could leave compounding ghost lines
- Fixed `FORCE_HYPERLINK` environment variable being ignored when set via `settings.json` `env`
- Fixed native terminal cursor not tracking the selected tab in dialogs, so screen readers and magnifiers can follow tab navigation
- Fixed Bedrock invocation of Sonnet 3.5 v2 by using the `us.` inference profile ID
- Fixed SDK/print mode not preserving the partial assistant response in conversation history when interrupted mid-stream
- Fixed CJK and other multibyte text being corrupted with U+FFFD in stream-json input/output when chunk boundaries split a UTF-8 sequence
- \[VSCode\] Fixed dropdown menus selecting the wrong item when the mouse was over the list while typing or using arrow keys

[​](#2-1-92)

2.1.92

April 4, 2026

**Added**

- Added `forceRemoteSettingsRefresh` policy setting: when set, the CLI blocks startup until remote managed settings are freshly fetched, and exits if the fetch fails (fail-closed)
- Added interactive Bedrock setup wizard accessible from the login screen when selecting “3rd-party platform” — guides you through AWS authentication, region configuration, credential verification, and model pinning
- Added per-model and cache-hit breakdown to `/cost` for subscription users

**Changed**

- `/release-notes` is now an interactive version picker
- Remote Control session names now use your hostname as the default prefix (e.g. `myhost-graceful-unicorn`), overridable with `--remote-control-session-name-prefix`
- Pro users now see a footer hint when returning to a session after the prompt cache has expired, showing roughly how many tokens the next turn will send uncached
- Removed `/tag` command
- Removed `/vim` command (toggle vim mode via `/config` → Editor mode)
- Linux sandbox now ships the `apply-seccomp` helper in both npm and native builds, restoring unix-socket blocking for sandboxed commands

**Improved**

- Improved Write tool diff computation speed for large files (60% faster on files with tabs/`&`/`$`)

Show 11 bug fixes

- Fixed subagent spawning permanently failing with “Could not determine pane count” after tmux windows are killed or renumbered during a long-running session
- Fixed prompt-type Stop hooks incorrectly failing when the small fast model returns `ok:false`, and restored `preventContinuation:true` semantics for non-Stop prompt-type hooks
- Fixed tool input validation failures when streaming emits array/object fields as JSON-encoded strings
- Fixed an API 400 error that could occur when extended thinking produced a whitespace-only text block alongside real content
- Fixed accidental feedback survey submissions from auto-pilot keypresses and consecutive-prompt digit collisions
- Fixed misleading “esc to interrupt” hint appearing alongside “esc to clear” when a text selection exists in fullscreen mode during processing
- Fixed Homebrew install update prompts to use the cask’s release channel (`claude-code` → stable, `claude-code@latest` → latest)
- Fixed `ctrl+e` jumping to the end of the next line when already at end of line in multiline prompts
- Fixed an issue where the same message could appear at two positions when scrolling up in fullscreen mode (iTerm2, Ghostty, and other terminals with DEC 2026 support)
- Fixed idle-return “/clear to save X tokens” hint showing cumulative session tokens instead of current context size
- Fixed plugin MCP servers stuck “connecting” on session start when they duplicate a claude.ai connector that is unauthenticated

[​](#2-1-91)

2.1.91

April 2, 2026

**Added**

- Added MCP tool result persistence override via `_meta["anthropic/maxResultSizeChars"]` annotation (up to 500K), allowing larger results like DB schemas to pass through without truncation
- Added `disableSkillShellExecution` setting to disable inline shell execution in skills, custom slash commands, and plugin commands
- Added support for multi-line prompts in `claude-cli://open?q=` deep links (encoded newlines `%0A` no longer rejected)

**Changed**

- Plugins can now ship executables under `bin/` and invoke them as bare commands from the Bash tool
- `/feedback` now explains why it’s unavailable instead of disappearing from the slash menu
- Edit tool now uses shorter `old_string` anchors, reducing output tokens

**Improved**

- Improved `/claude-api` skill guidance for agent design patterns including tool surface decisions, context management, and caching strategy
- Improved performance: faster `stripAnsi` on Bun by routing through `Bun.stripANSI`

Show 5 bug fixes

- Fixed transcript chain breaks on `--resume` that could lose conversation history when async transcript writes fail silently
- Fixed `cmd+delete` not deleting to start of line on iTerm2, kitty, WezTerm, Ghostty, and Windows Terminal
- Fixed plan mode in remote sessions losing track of the plan file after a container restart, which caused permission prompts on plan edits and an empty plan-approval modal
- Fixed JSON schema validation for `permissions.defaultMode: "auto"` in settings.json
- Fixed Windows version cleanup not protecting the active version’s rollback copy

[​](#2-1-90)

2.1.90

April 1, 2026

**Added**

- Added `/powerup` — interactive lessons teaching Claude Code features with animated demos
- Added `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE` env var to keep the existing marketplace cache when `git pull` fails, useful in offline environments
- Added `.husky` to protected directories (acceptEdits mode)

**Changed**

- Hardened PowerShell tool permission checks: fixed trailing `&` background job bypass, `-ErrorAction Break` debugger hang, archive-extraction TOCTOU, and parse-fail fallback deny-rule degradation
- Changed `--resume` picker to no longer show sessions created by `claude -p` or SDK invocations
- Removed `Get-DnsClientCache` and `ipconfig /displaydns` from auto-allow (DNS cache privacy)

**Improved**

- Improved performance: eliminated per-turn JSON.stringify of MCP tool schemas on cache-key lookup
- Improved performance: SSE transport now handles large streamed frames in linear time (was quadratic)
- Improved performance: SDK sessions with long conversations no longer slow down quadratically on transcript writes
- Improved `/resume` all-projects view to load project sessions in parallel, improving load times for users with many projects

Show 9 bug fixes

- Fixed an infinite loop where the rate-limit options dialog would repeatedly auto-open after hitting your usage limit, eventually crashing the session
- Fixed `--resume` causing a full prompt-cache miss on the first request for users with deferred tools, MCP servers, or custom agents (regression since v2.1.69)
- Fixed `Edit`/`Write` failing with “File content has changed” when a PostToolUse format-on-save hook rewrites the file between consecutive edits
- Fixed `PreToolUse` hooks that emit JSON to stdout and exit with code 2 not correctly blocking the tool call
- Fixed collapsed search/read summary badge appearing multiple times in fullscreen scrollback when a CLAUDE.md file auto-loads during a tool call
- Fixed auto mode not respecting explicit user boundaries (“don’t push”, “wait for X before Y”) even when the action would otherwise be allowed
- Fixed click-to-expand hover text being nearly invisible on light terminal themes
- Fixed UI crash when malformed tool input reached the permission dialog
- Fixed headers disappearing when scrolling `/model`, `/config`, and other selection screens

[​](#2-1-89)

2.1.89

April 1, 2026

**Added**

- Added `"defer"` permission decision to `PreToolUse` hooks — headless sessions can pause at a tool call and resume with `-p --resume` to have the hook re-evaluate
- Added `CLAUDE_CODE_NO_FLICKER=1` environment variable to opt into flicker-free alt-screen rendering with virtualized scrollback
- Added `PermissionDenied` hook that fires after auto mode classifier denials — return `{retry: true}` to tell the model it can retry
- Added named subagents to `@` mention typeahead suggestions
- Added `MCP_CONNECTION_NONBLOCKING=true` for `-p` mode to skip the MCP connection wait entirely, and bounded `--mcp-config` server connections at 5s instead of blocking on the slowest server

**Changed**

- Auto mode: denied commands now show a notification and appear in `/permissions` → Recent tab where you can retry with `r`
- Changed `Edit` to work on files viewed via `Bash` with `sed -n` or `cat`, without requiring a separate `Read` call first
- Changed hook output over 10,000 characters to be saved to disk with a file path + a 2,000-character preview instead of being injected directly into context
- Changed `cleanupPeriodDays: 0` in settings.json to be rejected with a validation error — it previously silently disabled transcript persistence
- Changed thinking summaries to no longer be generated by default in interactive sessions — set `showThinkingSummaries: true` in settings.json to restore
- Documented `TaskCreated` hook event and its blocking behavior
- Preserved task notifications when backgrounding a running command with Ctrl+B
- PowerShell tool on Windows: external-command arguments containing both a double-quote and whitespace now prompt instead of auto-allowing (PS 5.1 argument-splitting hardening)
- `/env` now applies to PowerShell tool commands (previously only affected Bash)
- `/usage` now hides redundant “Current week (Sonnet only)” bar for Pro and Enterprise plans
- Image paste no longer inserts a trailing space
- Pasting `!command` into an empty prompt now enters bash mode, matching typed `!` behavior
- `/buddy` is here for April 1st — hatch a small creature that watches you code

**Improved**

- Improved collapsed tool summary to show “Listed N directories” for `ls`/`tree`/`du` instead of “Read N files”
- Improved Bash tool to warn when a formatter/linter command modifies files you have previously read, preventing stale-edit errors
- Improved `@`-mention typeahead to rank source files above MCP resources with similar names
- Improved PowerShell tool prompt with version-appropriate syntax guidance (5.1 vs 7+)

Show 30 bug fixes

- Fixed `Edit(//path/**)` and `Read(//path/**)` allow rules to check the resolved symlink target, not just the requested path
- Fixed voice push-to-talk not activating for some modifier-combo bindings, and voice mode on Windows failing with “WebSocket upgrade rejected with HTTP 101”
- Fixed Edit/Write tools doubling CRLF on Windows and stripping Markdown hard line breaks (two trailing spaces)
- Fixed `StructuredOutput` schema cache bug causing ~50% failure rate when using multiple schemas
- Fixed memory leak where large JSON inputs were retained as LRU cache keys in long-running sessions
- Fixed a crash when removing a message from very large session files (over 50MB)
- Fixed LSP server zombie state after crash — server now restarts on next request instead of failing until session restart
- Fixed prompt history entries containing CJK or emoji being silently dropped when they fall on a 4KB boundary in `~/.claude/history.jsonl`
- Fixed `/stats` undercounting tokens by excluding subagent usage, and losing historical data beyond 30 days when the stats cache format changes
- Fixed `-p --resume` hangs when the deferred tool input exceeds 64KB or no deferred marker exists, and `-p --continue` not resuming deferred tools
- Fixed `claude-cli://` deep links not opening on macOS
- Fixed MCP tool errors truncating to only the first content block when the server returns multi-element error content
- Fixed skill reminders and other system context being dropped when sending messages with images via the SDK
- Fixed PreToolUse/PostToolUse hooks to receive `file_path` as an absolute path for Write/Edit/Read tools, matching the documented behavior
- Fixed autocompact thrash loop — now detects when context refills to the limit immediately after compacting three times in a row and stops with an actionable error instead of burning API calls
- Fixed prompt cache misses in long sessions caused by tool schema bytes changing mid-session
- Fixed nested CLAUDE.md files being re-injected dozens of times in long sessions that read many files
- Fixed `--resume` crash when transcript contains a tool result from an older CLI version or interrupted write
- Fixed misleading “Rate limit reached” message when the API returned an entitlement error — now shows the actual error with actionable hints
- Fixed hooks `if` condition filtering not matching compound commands (`ls && git push`) or commands with env-var prefixes (`FOO=bar git push`)
- Fixed collapsed search/read group badges duplicating in terminal scrollback during heavy parallel tool use
- Fixed notification `invalidates` not clearing the currently-displayed notification immediately
- Fixed prompt briefly disappearing after submit when background messages arrived during processing
- Fixed Devanagari and other combining-mark text being truncated in assistant output
- Fixed rendering artifacts on main-screen terminals after layout shifts
- Fixed voice mode failing to request microphone permission on macOS Apple Silicon
- Fixed Shift+Enter submitting instead of inserting a newline on Windows Terminal Preview 1.25
- Fixed periodic UI jitter during streaming in iTerm2 when running inside tmux
- Fixed PowerShell tool incorrectly reporting failures when commands like `git push` wrote progress to stderr on Windows PowerShell 5.1
- Fixed a potential out-of-memory crash when the Edit tool was used on very large files (\>1 GiB)

[​](#2-1-87)

2.1.87

March 29, 2026

- Fixed messages in Cowork Dispatch not getting delivered

[​](#2-1-86)

2.1.86

March 27, 2026

**Added**

- Added `X-Claude-Code-Session-Id` header to API requests so proxies can aggregate requests by session without parsing the body
- Added `.jj` and `.sl` to VCS directory exclusion lists so Grep and file autocomplete don’t descend into Jujutsu or Sapling metadata

**Changed**

- Reduced startup event-loop stalls when many claude.ai MCP connectors are configured (macOS keychain cache extended from 5s to 30s)
- Reduced token overhead when mentioning files with `@` — raw string content no longer JSON-escaped
- Memory filenames in the “Saved N memories” notice now highlight on hover and open on click
- Skill descriptions in the `/skills` listing are now capped at 250 characters to reduce context usage
- Changed `/skills` menu to sort alphabetically for easier scanning
- Auto mode now shows “unavailable for your plan” when disabled by plan restrictions (was “temporarily unavailable”)
- Read tool now uses compact line-number format and deduplicates unchanged re-reads, reducing token usage

**Improved**

- Improved prompt cache hit rate for Bedrock, Vertex, and Foundry users by removing dynamic content from tool descriptions

Show 16 bug fixes

- Fixed `--resume` failing with “tool_use ids were found without tool_result blocks” on sessions created before v2.1.85
- Fixed Write/Edit/Read failing on files outside the project root (e.g., `~/.claude/CLAUDE.md`) when conditional skills or rules are configured
- Fixed unnecessary config disk writes on every skill invocation that could cause performance issues and config corruption on Windows
- Fixed potential out-of-memory crash when using `/feedback` on very long sessions with large transcript files
- Fixed `--bare` mode dropping MCP tools in interactive sessions and silently discarding messages enqueued mid-turn
- Fixed the `c` shortcut copying only ~20 characters of the OAuth login URL instead of the full URL
- Fixed masked input (e.g., OAuth code paste) leaking the start of the token when wrapping across multiple lines on narrow terminals
- Fixed official marketplace plugin scripts failing with “Permission denied” on macOS/Linux since v2.1.83
- Fixed statusline showing another session’s model when running multiple Claude Code instances and using `/model` in one of them
- Fixed scroll not following new messages after wheel scroll or click-to-select at the bottom of a long conversation
- Fixed `/plugin` uninstall dialog: pressing `n` now correctly uninstalls the plugin while preserving its data directory
- Fixed a regression where pressing Enter after clicking could leave the transcript blank until the response arrived
- Fixed `ultrathink` hint lingering after deleting the keyword
- Fixed memory growth in long sessions from markdown/highlight render caches retaining full content strings
- \[VSCode\] Fixed extension incorrectly showing “Not responding” during long-running operations
- \[VSCode\] Fixed extension defaulting Max plan users to Sonnet after the OAuth token refreshes (8 hours after login)

[​](#2-1-85)

2.1.85

March 26, 2026

**Added**

- Added `CLAUDE_CODE_MCP_SERVER_NAME` and `CLAUDE_CODE_MCP_SERVER_URL` environment variables to MCP `headersHelper` scripts, allowing one helper to serve multiple servers
- Added conditional `if` field for hooks using permission rule syntax (e.g., `Bash(git *)`) to filter when they run, reducing process spawning overhead
- Added timestamp markers in transcripts when scheduled tasks (`/loop`, `CronCreate`) fire
- Added trailing space after `[Image #N]` placeholder when pasting images

**Changed**

- Deep link queries (`claude-cli://open?q=…`) now support up to 5,000 characters, with a “scroll to review” warning for long pre-filled prompts
- MCP OAuth now follows RFC 9728 Protected Resource Metadata discovery to find the authorization server
- Plugins blocked by organization policy (`managed-settings.json`) can no longer be installed or enabled, and are hidden from marketplace views
- PreToolUse hooks can now satisfy `AskUserQuestion` by returning `updatedInput` alongside `permissionDecision: "allow"`, enabling headless integrations that collect answers via their own UI
- `tool_parameters` in OpenTelemetry tool_result events are now gated behind `OTEL_LOG_TOOL_DETAILS=1`
- Reduced UI stutter when compaction triggers on large sessions

**Improved**

- Improved @-mention file autocomplete performance on large repositories
- Improved PowerShell dangerous command detection
- Improved scroll performance with large transcripts by replacing WASM yoga-layout with a pure TypeScript implementation

Show 17 bug fixes

- Fixed `/compact` failing with “context exceeded” when the conversation has grown too large for the compact request itself to fit
- Fixed `/plugin enable` and `/plugin disable` failing when a plugin’s install location differs from where it’s declared in settings
- Fixed `--worktree` exiting with an error in non-git repositories before the `WorktreeCreate` hook could run
- Fixed `deniedMcpServers` setting not blocking claude.ai MCP servers
- Fixed `switch_display` in the computer-use tool returning “not available in this session” on multi-monitor setups
- Fixed crash when `OTEL_LOGS_EXPORTER`, `OTEL_METRICS_EXPORTER`, or `OTEL_TRACES_EXPORTER` is set to `none`
- Fixed diff syntax highlighting not working in non-native builds
- Fixed MCP step-up authorization failing when a refresh token exists — servers requesting elevated scopes via `403 insufficient_scope` now correctly trigger the re-authorization flow
- Fixed memory leak in remote sessions when a streaming response is interrupted
- Fixed persistent ECONNRESET errors during edge connection churn by using a fresh TCP connection on retry
- Fixed prompts getting stuck in the queue after running certain slash commands, with up-arrow unable to retrieve them
- Fixed Python Agent SDK: `type:'sdk'` MCP servers passed via `--mcp-config` are no longer dropped during startup
- Fixed raw key sequences appearing in the prompt when running over SSH or in the VS Code integrated terminal
- Fixed Remote Control session status staying stuck on “Requires Action” after a permission is resolved
- Fixed shift+enter and meta+enter being intercepted by typeahead suggestions instead of inserting newlines
- Fixed stale content bleeding through when scrolling up during streaming
- Fixed terminal left in enhanced keyboard mode after exit in Ghostty, Kitty, WezTerm, and other terminals supporting the Kitty keyboard protocol — Ctrl+C and Ctrl+D now work correctly after quitting

[​](#2-1-84)

2.1.84

March 26, 2026

**Added**

- Added PowerShell tool for Windows as an opt-in preview. Learn more at [https://code.claude.com/docs/en/tools-reference#powershell-tool](tools-reference.md#powershell-tool)
- Added `ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU}_MODEL_SUPPORTS` env vars to override effort/thinking capability detection for pinned default models for 3p (Bedrock, Vertex, Foundry), and `_MODEL_NAME`/`_DESCRIPTION` to customize the `/model` picker label
- Added `CLAUDE_STREAM_IDLE_TIMEOUT_MS` env var to configure the streaming idle watchdog threshold (default 90s)
- Added `TaskCreated` hook that fires when a task is created via `TaskCreate`
- Added `WorktreeCreate` hook support for `type: "http"` — return the created worktree path via `hookSpecificOutput.worktreePath` in the response JSON
- Added `allowedChannelPlugins` managed setting for team/enterprise admins to define a channel plugin allowlist
- Added `x-client-request-id` header to API requests for debugging timeouts
- Added idle-return prompt that nudges users returning after 75+ minutes to `/clear`, reducing unnecessary token re-caching on stale sessions
- \[VSCode\] Added rate limit warning banner with usage percentage and reset time

**Changed**

- Deep links (`claude-cli://`) now open in your preferred terminal instead of whichever terminal happens to be first in the detection list
- Rules and skills `paths:` frontmatter now accepts a YAML list of globs
- MCP tool descriptions and server instructions are now capped at 2KB to prevent OpenAPI-generated servers from bloating context
- MCP servers configured both locally and via claude.ai connectors are now deduplicated — the local config wins
- Background bash tasks that appear stuck on an interactive prompt now surface a notification after ~45 seconds
- Token counts ≥1M now display as “1.5m” instead of “1512.6k”
- Global system-prompt caching now works when `ToolSearch` is enabled, including for users with MCP tools configured
- Reduced scroll-to-top resets in long sessions by making the message window immune to compaction and grouping changes
- Reduced terminal flickering when animated tool progress scrolls above the viewport
- Changed issue/PR references to only become clickable links when written as `owner/repo#123` — bare `#123` is no longer auto-linked
- Slash commands unavailable for the current auth setup (`/voice`, `/mobile`, `/chrome`, `/upgrade`, etc.) are now hidden instead of shown
- Stats screenshot (Ctrl+S in /stats) now works in all builds and is 16× faster

Show 5 improvements

- Improved detection for dangerous removals of Windows drive roots (`C:\`, `C:\Windows`, etc.)
- Improved interactive startup by ~30ms by running `setup()` in parallel with slash command and agent loading
- Improved startup for `claude "prompt"` with MCP servers — the REPL now renders immediately instead of blocking until all servers connect
- Improved Remote Control to show a specific reason when blocked instead of a generic “not yet enabled” message
- Improved p90 prompt cache rate

Show 14 bug fixes

- Fixed voice push-to-talk: holding the voice key no longer leaks characters into the text input, and transcripts now insert at the correct position
- Fixed up/down arrow keys being unresponsive when a footer item is focused
- Fixed `Ctrl+U` (kill-to-line-start) being a no-op at line boundaries in multiline input, so repeated `Ctrl+U` now clears across lines
- Fixed null-unbinding a default chord binding (e.g. `"ctrl+x ctrl+k": null`) still entering chord-wait mode instead of freeing the prefix key
- Fixed mouse events inserting literal “mouse” text into transcript search input
- Fixed workflow subagents failing with API 400 when the outer session uses `--json-schema` and the subagent also specifies a schema
- Fixed missing background color behind certain emoji in user message bubbles on some terminals
- Fixed the “allow Claude to edit its own settings for this session” permission option not sticking for users with `Edit(.claude)` allow rules
- Fixed a hang when generating attachment snippets for large edited files
- Fixed MCP tool/resource cache leak on server reconnect
- Fixed a startup performance issue where partial clone repositories (Scalar/GVFS) triggered mass blob downloads
- Fixed native terminal cursor not tracking the text input caret, so IME composition (CJK input) now renders inline and screen readers can follow the input position
- Fixed spurious “Not logged in” errors on macOS caused by transient keychain read failures
- Fixed cold-start race where core tools could be deferred without their bypass active, causing Edit/Write to fail with InputValidationError on typed parameters

[​](#2-1-83)

2.1.83

March 25, 2026

**Added**

- Added `managed-settings.d/` drop-in directory alongside `managed-settings.json`, letting separate teams deploy independent policy fragments that merge alphabetically
- Added `CwdChanged` and `FileChanged` hook events for reactive environment management (e.g., direnv)
- Added `sandbox.failIfUnavailable` setting to exit with an error when sandbox is enabled but cannot start, instead of running unsandboxed
- Added `disableDeepLinkRegistration` setting to prevent `claude-cli://` protocol handler registration
- Added `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1` to strip Anthropic and cloud provider credentials from subprocess environments (Bash tool, hooks, MCP stdio servers)
- Added transcript search — press `/` in transcript mode (`Ctrl+O`) to search, `n`/`N` to step through matches
- Added `Ctrl+X Ctrl+E` as an alias for opening the external editor (readline-native binding; `Ctrl+G` still works)
- Added `CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK` env var to disable the non-streaming fallback when streaming fails
- \[VSCode\] Added Esc-twice (or `/rewind`) to open a keyboard-navigable rewind picker

**Changed**

- Pasted images now insert an `[Image #N]` chip at the cursor so you can reference them positionally in your prompt
- Agents can now declare `initialPrompt` in frontmatter to auto-submit a first turn
- `chat:killAgents` and `chat:fastMode` are now rebindable via `~/.claude/keybindings.json`
- Reduced `WebFetch` peak memory usage for large pages
- Reduced scrollback resets in long sessions from once per turn to once per ~50 messages
- Faster `claude -p` startup with unauthenticated HTTP/SSE MCP servers (~600ms saved)
- Bash ghost-text suggestions now include just-submitted commands immediately
- Increased non-streaming fallback token cap (21k → 64k) and timeout (120s → 300s local) so fallback requests are less likely to be truncated
- Interrupting a prompt before any response now automatically restores your input so you can edit and resubmit
- `/status` now works while Claude is responding, instead of being queued until the turn finishes
- Plugin MCP servers that duplicate an org-managed connector are now suppressed instead of running a second connection
- Linux: respect `XDG_DATA_HOME` when registering the `claude-cli://` protocol handler
- Changed “stop all background agents” keybinding from `Ctrl+F` to `Ctrl+X Ctrl+K` to stop shadowing readline forward-char
- Deprecated `TaskOutput` tool in favor of using `Read` on the background task’s output file path
- Plugin options (`manifest.userConfig`) now available externally — plugins can prompt for configuration at enable time, with `sensitive: true` values stored in keychain (macOS) or protected credentials file (other platforms)
- Claude can now reference the on-disk path of clipboard-pasted images for file operations
- `Ctrl+L` now clears the screen and forces a full redraw — use this to recover when Cmd+K leaves the UI partially blank. Use `Ctrl+U` or double-Esc to clear prompt input.
- `--bare -p` (SDK pattern) is ~14% faster to the API request
- Memory: `MEMORY.md` index now truncates at 25KB as well as 200 lines
- Disabled `AskUserQuestion` and plan-mode tools when `--channels` is active
- \[VSCode\] Spinner now turns red with “Not responding” when the backend hasn’t responded for 60 seconds

Show 5 improvements

- Improved Bedrock SDK cold-start latency by overlapping profile fetch with other boot work
- Improved `--resume` memory usage and startup latency on large sessions
- Improved plugin startup — commands, skills, and agents now load from disk cache without re-fetching
- Improved Remote Control session titles: AI-generated titles now appear within seconds of the first message
- Improved `WebFetch` to identify as `Claude-User` so site operators can recognize and allowlist Claude Code traffic via `robots.txt`

Show 41 bug fixes

- Fixed mouse tracking escape sequences leaking to shell prompt after exit
- Fixed Claude Code hanging on exit on macOS
- Fixed screen flashing blank after being idle for a few seconds
- Fixed a hang when diffing very large files with few common lines — diffs now time out after 5 seconds and fall back gracefully
- Fixed a 1–8 second UI freeze on startup when voice input was enabled, caused by eagerly loading the native audio module
- Fixed a startup regression where Claude Code would wait ~3s for claude.ai MCP config fetch before proceeding
- Fixed `--mcp-config` CLI flag bypassing `allowedMcpServers`/`deniedMcpServers` managed policy enforcement
- Fixed claude.ai MCP connectors (Slack, Gmail, etc.) not being available in single-turn `--print` mode
- Fixed `caffeinate` process not properly terminating when Claude Code exits, preventing Mac from sleeping
- Fixed bash mode not activating when tab-accepting `!`-prefixed command suggestions
- Fixed stale slash command selection showing wrong highlighted command after navigating suggestions
- Fixed `/config` menu showing both the search cursor and list selection at the same time
- Fixed background subagents becoming invisible after context compaction, which could cause duplicate agents to be spawned
- Fixed background agent tasks staying stuck in “running” state when git or API calls hang during cleanup
- Fixed `--channels` showing “Channels are not currently available” on first launch after upgrade
- Fixed uninstalled plugin hooks continuing to fire until the next session
- Fixed queued commands flickering during streaming responses
- Fixed slash commands being sent to the model as text when submitted while a message is processing
- Fixed scrollback jumping when collapsed read/search groups finish after scrolling offscreen
- Fixed scrollback jumping to top when the model starts or stops thinking
- Fixed SDK session history loss on resume caused by hook progress/attachment messages forking the parentUuid chain
- Fixed copy-on-select not firing when you release the mouse outside the terminal window
- Fixed ghost characters appearing in height-constrained lists when items overflow
- Fixed `Ctrl+B` interfering with readline backward-char at an idle prompt — it now only fires when a foreground task can be backgrounded
- Fixed tool result files never being cleaned up, ignoring the `cleanupPeriodDays` setting
- Fixed space key being swallowed for up to 3 seconds after releasing voice hold-to-talk
- Fixed ALSA library errors corrupting the terminal UI when using voice mode on Linux without audio hardware (Docker, headless, WSL1)
- Fixed voice mode SoX detection on Termux/Android where spawning `which` is kernel-restricted
- Fixed Remote Control sessions showing as Idle in the web session list while actively running
- Fixed footer navigation selecting an invisible Remote Control pill in config-driven mode
- Fixed memory leak in remote sessions where tool use IDs accumulate indefinitely
- Fixed API 400 error when a pasted image was queued during a failing tool call
- Fixed MCP tool calls hanging indefinitely when an SSE connection drops mid-call and exhausts its reconnection attempts
- Fixed Remote Control session titles showing raw XML when a background agent completed before the first user message
- Fixed remote sessions forgetting conversation history after a container restart due to progress-message gaps in the resumed transcript chain
- Fixed remote sessions requiring re-login on transient auth errors instead of retrying automatically
- Fixed `rg ... | wc -l` and similar piped commands hanging and returning `0` in sandbox mode on Linux
- Fixed voice input hold-to-talk not activating when a CJK IME inserts a full-width space
- Fixed `--worktree` hanging silently when the worktree name contained a forward slash
- \[VSCode\] Fixed session history not loading correctly when reopening a session via URL or after restart
- \[VSCode\] Fixed “Fork conversation from here” and rewind actions failing silently after the session cache goes stale

[​](#2-1-81)

2.1.81

March 20, 2026

**Added**

- Added `--bare` flag for scripted `-p` calls — skips hooks, LSP, plugin sync, and skill directory walks; requires `ANTHROPIC_API_KEY` or an `apiKeyHelper` via `--settings` (OAuth and keychain auth disabled); auto-memory fully disabled
- Added `--channels` permission relay — channel servers that declare the permission capability can forward tool approval prompts to your phone

**Changed**

- Resuming a session that was in a worktree now switches back to that worktree
- Updated MCP OAuth to support Client ID Metadata Document (CIMD / SEP-991) for servers without Dynamic Client Registration
- Changed plan mode to hide the “clear context” option by default (restore with `"showClearContextOnPlanAccept": true`)
- Disabled line-by-line response streaming on Windows (including WSL in Windows Terminal) due to rendering issues

**Improved**

- Improved MCP read/search tool calls to collapse into a single “Queried `{server}`” line (expand with Ctrl+O)
- Improved `!` bash mode discoverability — Claude now suggests it when you need to run an interactive command
- Improved plugin freshness — ref-tracked plugins now re-clone on every load to pick up upstream changes
- Improved Remote Control session titles to refresh after your third message

Show 17 bug fixes

- Fixed multiple concurrent Claude Code sessions requiring repeated re-authentication when one session refreshes its OAuth token
- Fixed voice mode silently swallowing retry failures and showing a misleading “check your network” message instead of the actual error
- Fixed voice mode audio not recovering when the server silently drops the WebSocket connection
- Fixed `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS` not suppressing the structured-outputs beta header, causing 400 errors on proxy gateways forwarding to Vertex/Bedrock
- Fixed `--channels` bypass for Team/Enterprise orgs with no other managed settings configured
- Fixed a crash on Node.js 18
- Fixed unnecessary permission prompts for Bash commands containing dashes in strings
- Fixed plugin hooks blocking prompt submission when the plugin directory is deleted mid-session
- Fixed a race condition where background agent task output could hang indefinitely when the task completed between polling intervals
- Fixed `/btw` not including pasted text when used during an active response
- Fixed a race where fast Cmd+Tab followed by paste could beat the clipboard copy under tmux
- Fixed terminal tab title not updating with an auto-generated session description
- Fixed invisible hook attachments inflating the message count in transcript mode
- Fixed Remote Control sessions showing a generic title instead of deriving from the first prompt
- Fixed `/rename` not syncing the title for Remote Control sessions
- Fixed Remote Control `/exit` not reliably archiving the session
- \[VSCode\] Fixed Windows PATH inheritance for Bash tool when using Git Bash (regression in v2.1.78)

[​](#2-1-80)

2.1.80

March 19, 2026

**Added**

- Added `rate_limits` field to statusline scripts for displaying Claude.ai rate limit usage (5-hour and 7-day windows with `used_percentage` and `resets_at`)
- Added `source: 'settings'` plugin marketplace source — declare plugin entries inline in settings.json
- Added CLI tool usage detection to plugin tips, in addition to file pattern matching
- Added `effort` frontmatter support for skills and slash commands to override the model effort level when invoked
- Added `--channels` (research preview) — allow MCP servers to push messages into your session

**Changed**

- Simplified plugin install tips to use a single `/plugin install` command instead of a two-step flow
- Reduced memory usage on startup in large repositories (~80 MB saved on 250k-file repos)

**Improved**

- Improved responsiveness of `@` file autocomplete in large git repositories
- Improved `/effort` to show what auto currently resolves to, matching the status bar indicator
- Improved `/permissions` — Tab and arrow keys now switch tabs from within a list
- Improved background tasks panel — left arrow now closes from the list view

Show 6 bug fixes

- Fixed `--resume` dropping parallel tool results — sessions with parallel tool calls now restore all tool_use/tool_result pairs instead of showing `[Tool result missing]` placeholders
- Fixed voice mode WebSocket failures caused by Cloudflare bot detection on non-browser TLS fingerprints
- Fixed 400 errors when using fine-grained tool streaming through API proxies, Bedrock, or Vertex
- Fixed `/remote-control` appearing for gateway and third-party provider deployments where it cannot function
- Fixed `/sandbox` tab switching not responding to Tab or arrow keys
- Fixed managed settings (`enabledPlugins`, `permissions.defaultMode`, policy-set env vars) not being applied at startup when `remote-settings.json` was cached from a prior session

[​](#2-1-79)

2.1.79

March 18, 2026

**Added**

- Added `--console` flag to `claude auth login` for Anthropic Console (API billing) authentication
- Added “Show turn duration” toggle to the `/config` menu
- \[VSCode\] Added `/remote-control` — bridge your session to claude.ai/code to continue from a browser or phone

**Changed**

- `CLAUDE_CODE_PLUGIN_SEED_DIR` now supports multiple seed directories separated by the platform path delimiter (`:` on Unix, `;` on Windows)
- \[VSCode\] Session tabs now get AI-generated titles based on your first message

**Improved**

- Improved startup memory usage by ~18MB across all scenarios
- Improved non-streaming API fallback with a 2-minute per-attempt timeout, preventing sessions from hanging indefinitely

Show 11 bug fixes

- Fixed `claude -p` hanging when spawned as a subprocess without explicit stdin (e.g. Python `subprocess.run`)
- Fixed Ctrl+C not working in `-p` (print) mode
- Fixed `/btw` returning the main agent’s output instead of answering the side question when triggered during streaming
- Fixed voice mode not activating correctly on startup when `voiceEnabled: true` is set
- Fixed left/right arrow tab navigation in `/permissions`
- Fixed `CLAUDE_CODE_DISABLE_TERMINAL_TITLE` not preventing terminal title from being set on startup
- Fixed custom status line showing nothing when workspace trust is blocking it
- Fixed enterprise users being unable to retry on rate limit (429) errors
- Fixed `SessionEnd` hooks not firing when using interactive `/resume` to switch sessions
- \[VSCode\] Fixed the thinking pill showing “Thinking” instead of “Thought for Ns” after a response completes
- \[VSCode\] Fixed missing session diff button when opening sessions from the left sidebar

[​](#2-1-78)

2.1.78

March 17, 2026

**Added**

- Added `StopFailure` hook event that fires when the turn ends due to an API error (rate limit, auth failure, etc.)
- Added `${CLAUDE_PLUGIN_DATA}` variable for plugin persistent state that survives plugin updates; `/plugin uninstall` prompts before deleting it
- Added `effort`, `maxTurns`, and `disallowedTools` frontmatter support for plugin-shipped agents
- Added `ANTHROPIC_CUSTOM_MODEL_OPTION` env var to add a custom entry to the `/model` picker, with optional `_NAME` and `_DESCRIPTION` suffixed vars for display

**Changed**

- Terminal notifications (iTerm2/Kitty/Ghostty popups, progress bar) now reach the outer terminal when running inside tmux with `set -g allow-passthrough on`
- Response text now streams line-by-line as it’s generated

**Improved**

- Improved memory usage and startup time when resuming large sessions

Show 19 bug fixes

- Fixed `git log HEAD` failing with “ambiguous argument” inside sandboxed Bash on Linux, and stub files polluting `git status` in the working directory
- Fixed `cc log` and `--resume` silently truncating conversation history on large sessions (\>5 MB) that used subagents
- Fixed infinite loop when API errors triggered stop hooks that re-fed blocking errors to the model
- Fixed `deny: ["mcp__servername"]` permission rules not removing MCP server tools before sending to the model, allowing it to see and attempt blocked tools
- Fixed `sandbox.filesystem.allowWrite` not working with absolute paths (previously required `//` prefix)
- Fixed `/sandbox` Dependencies tab showing Linux prerequisites on macOS instead of macOS-specific info
- **Security:** Fixed silent sandbox disable when `sandbox.enabled: true` is set but dependencies are missing — now shows a visible startup warning
- Fixed `.git`, `.claude`, and other protected directories being writable without a prompt in `bypassPermissions` mode
- Fixed ctrl+u in normal mode scrolling instead of readline kill-line (ctrl+u/ctrl+d half-page scroll moved to transcript mode only)
- Fixed voice mode modifier-combo push-to-talk keybindings (e.g. ctrl+k) requiring a hold instead of activating immediately
- Fixed voice mode not working on WSL2 with WSLg (Windows 11); WSL1/Win10 users now get a clear error
- Fixed `--worktree` flag not loading skills and hooks from the worktree directory
- Fixed `CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS` and `includeGitInstructions` setting not suppressing the git status section in the system prompt
- Fixed Bash tool not finding Homebrew and other PATH-dependent binaries when VS Code is launched from Dock/Spotlight
- Fixed washed-out Claude orange color in VS Code/Cursor/code-server terminals that don’t advertise truecolor support
- Fixed `ANTHROPIC_BETAS` environment variable being silently ignored when using Haiku models
- Fixed queued prompts being concatenated without a newline separator
- \[VSCode\] Fixed a brief flash of the login screen when opening the sidebar while already authenticated
- \[VSCode\] Fixed “API Error: Rate limit reached” when selecting Opus — model dropdown no longer offers 1M context variant to subscribers whose plan tier is unknown

[​](#2-1-77)

2.1.77

March 17, 2026

**Added**

- Added `allowRead` sandbox filesystem setting to re-allow read access within `denyRead` regions

**Changed**

- Increased default maximum output token limits for Claude Opus 4.6 to 64k tokens, and the upper bound for Opus 4.6 and Sonnet 4.6 models to 128k tokens
- `/copy` now accepts an optional index: `/copy N` copies the Nth-latest assistant response
- Faster startup on macOS (~60ms) by reading keychain credentials in parallel with module loading
- Faster `--resume` on fork-heavy and very large sessions — up to 45% faster loading and ~100-150MB less peak memory
- Background bash tasks are now killed if output exceeds 5GB, preventing runaway processes from filling disk
- Sessions are now auto-named from plan content when you accept a plan
- Show a notice when `apiKeyHelper` takes longer than 10s, preventing it from blocking the main loop
- The Agent tool no longer accepts a `resume` parameter — use `SendMessage({to: agentId})` to continue a previously spawned agent
- `SendMessage` now auto-resumes stopped agents in the background instead of returning an error
- Renamed `/fork` to `/branch` (`/fork` still works as an alias)
- \[VSCode\] When option+click doesn’t trigger native selection on macOS, the footer now points to the `macOptionClickForcesSelection` setting

**Improved**

- Improved Esc to abort in-flight non-streaming API requests
- Improved `claude plugin validate` to check skill, agent, and command frontmatter plus `hooks/hooks.json`, catching YAML parse errors and schema violations
- Improved headless mode plugin installation to compose correctly with `CLAUDE_CODE_PLUGIN_SEED_DIR`
- \[VSCode\] Improved plan preview tab titles to use the plan’s heading instead of “Claude’s Plan”

Show 28 bug fixes

- Fixed “Always Allow” on compound bash commands (e.g. `cd src && npm test`) saving a single rule for the full string instead of per-subcommand, leading to dead rules and repeated permission prompts
- Fixed auto-updater starting overlapping binary downloads when the slash-command overlay repeatedly opened and closed, accumulating tens of gigabytes of memory
- Fixed `--resume` silently truncating recent conversation history due to a race between memory-extraction writes and the main transcript
- Fixed PreToolUse hooks returning `"allow"` bypassing `deny` permission rules, including enterprise managed settings
- Fixed Write tool silently converting line endings when overwriting CRLF files or creating files in CRLF directories
- Fixed memory growth in long-running sessions from progress messages surviving compaction
- Fixed cost and token usage not being tracked when the API falls back to non-streaming mode
- Fixed `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS` not stripping beta tool-schema fields, causing proxy gateways to reject requests
- Fixed Bash tool reporting errors for successful commands when the system temp directory path contains spaces
- Fixed paste being lost when typing immediately after pasting
- Fixed Ctrl+D in `/feedback` text input deleting forward instead of the second press exiting the session
- Fixed API error when dragging a 0-byte image file into the prompt
- Fixed Claude Desktop sessions incorrectly using the terminal CLI’s configured API key instead of OAuth
- Fixed `git-subdir` plugins at different subdirectories of the same monorepo commit colliding in the plugin cache
- Fixed ordered list numbers not rendering in terminal UI
- Fixed a race condition where stale-worktree cleanup could delete an agent worktree just resumed from a previous crash
- Fixed input deadlock when opening `/mcp` or similar dialogs while the agent is running
- Fixed Backspace and Delete keys not working in vim NORMAL mode
- Fixed status line not updating when vim mode is toggled on or off
- Fixed hyperlinks opening twice on Cmd+click in VS Code, Cursor, and other xterm.js-based terminals
- Fixed background colors rendering as terminal-default inside tmux with default configuration
- Fixed iTerm2 session crash when selecting text inside tmux over SSH
- Fixed clipboard copy silently failing in tmux sessions; copy toast now indicates whether to paste with `⌘V` or tmux `prefix+]`
- Fixed `←`/`→` accidentally switching tabs in settings, permissions, and sandbox dialogs while navigating lists
- Fixed IDE integration not auto-connecting when Claude Code is launched inside tmux or screen
- Fixed CJK characters visually bleeding into adjacent UI elements when clipped at the right edge
- Fixed teammate panes not closing when the leader exits
- Fixed iTerm2 auto mode not detecting iTerm2 for native split-pane teammates

[​](#2-1-76)

2.1.76

March 14, 2026

**Added**

- Added MCP elicitation support — MCP servers can now request structured input mid-task via an interactive dialog (form fields or browser URL)
- Added new `Elicitation` and `ElicitationResult` hooks to intercept and override responses before they’re sent back
- Added `-n` / `--name <name>` CLI flag to set a display name for the session at startup
- Added `worktree.sparsePaths` setting for `claude --worktree` in large monorepos to check out only the directories you need via git sparse-checkout
- Added `PostCompact` hook that fires after compaction completes
- Added `/effort` slash command to set model effort level
- Added session quality survey — enterprise admins can configure the sample rate via the `feedbackSurveyRate` setting

**Changed**

- Updated `--plugin-dir` to only accept one path to support subcommands — use repeated `--plugin-dir` for multiple directories

Show 7 improvements

- Improved `--worktree` startup performance by reading git refs directly and skipping redundant `git fetch` when the remote branch is already available locally
- Improved background agent behavior — killing a background agent now preserves its partial results in the conversation context
- Improved model fallback notifications — now always visible instead of hidden behind verbose mode, with human-friendly model names
- Improved blockquote readability on dark terminal themes — text is now italic with a left bar instead of dim
- Improved stale worktree cleanup — worktrees left behind after an interrupted parallel run are now automatically cleaned up
- Improved Remote Control session titles — now derived from your first prompt instead of showing “Interactive session”
- Improved `/voice` to show your dictation language on enable and warn when your `language` setting isn’t supported for voice input

Show 20 bug fixes

- Fixed deferred tools (loaded via `ToolSearch`) losing their input schemas after conversation compaction, causing array and number parameters to be rejected with type errors
- Fixed slash commands showing “Unknown skill”
- Fixed plan mode asking for re-approval after the plan was already accepted
- Fixed voice mode swallowing keypresses while a permission dialog or plan editor was open
- Fixed `/voice` not working on Windows when installed via npm
- Fixed spurious “Context limit reached” when invoking a skill with `model:` frontmatter on a 1M-context session
- Fixed “adaptive thinking is not supported on this model” error when using non-standard model strings
- Fixed `Bash(cmd:*)` permission rules not matching when a quoted argument contains `#`
- Fixed “don’t ask again” in the Bash permission dialog showing the full raw command for pipes and compound commands
- Fixed auto-compaction retrying indefinitely after consecutive failures — a circuit breaker now stops after 3 attempts
- Fixed MCP reconnect spinner persisting after successful reconnection
- Fixed LSP plugins not registering servers when the LSP Manager initialized before marketplaces were reconciled
- Fixed clipboard copying in tmux over SSH — now attempts both direct terminal write and tmux clipboard integration
- Fixed `/export` showing only the filename instead of the full file path in the success message
- Fixed transcript not auto-scrolling to new messages after selecting text
- Fixed Escape key not working to exit the login method selection screen
- Fixed several Remote Control issues: sessions silently dying when the server reaps an idle environment, rapid messages being queued one-at-a-time instead of batched, and stale work items causing redelivery after JWT refresh
- Fixed bridge sessions failing to recover after extended WebSocket disconnects
- Fixed slash commands not found when typing the exact name of a soft-hidden command
- \[VSCode\] Fixed gitignore patterns containing commas silently excluding entire filetypes from the @-mention file picker

[​](#2-1-75)

2.1.75

March 13, 2026

**Added**

- Added 1M context window for Opus 4.6 by default for Max, Team, and Enterprise plans (previously required extra usage)
- Added `/color` command for all users to set a prompt-bar color for your session
- Added session name display on the prompt bar when using `/rename`
- Added last-modified timestamps to memory files, helping Claude reason about which memories are fresh vs. stale
- Added hook source display (settings/plugin/skill) in permission prompts when a hook requires confirmation

**Changed**

- Suppressed async hook completion messages by default (visible with `--verbose` or transcript mode)
- Breaking change: Removed deprecated Windows managed settings fallback at `C:\ProgramData\ClaudeCode\managed-settings.json` — use `C:\Program Files\ClaudeCode\managed-settings.json`

**Improved**

- Improved startup performance on macOS non-MDM machines by skipping unnecessary subprocess spawns

Show 11 bug fixes

- Fixed voice mode not activating correctly on fresh installs without toggling `/voice` twice
- Fixed the Claude Code header not updating the displayed model name after switching models with `/model` or Option+P
- Fixed session crash when an attachment message computation returns undefined values
- Fixed Bash tool mangling `!` in piped commands (e.g., `jq 'select(.x != .y)'` now works correctly)
- Fixed managed-disabled plugins showing up in the `/plugin` Installed tab — plugins force-disabled by your organization are now hidden
- Fixed token estimation over-counting for thinking and `tool_use` blocks, preventing premature context compaction
- Fixed corrupted marketplace config path handling
- Fixed `/resume` losing session names after resuming a forked or continued session
- Fixed Esc not closing the `/status` dialog after visiting the Config tab
- Fixed input handling when accepting or rejecting a plan
- Fixed footer hint in agent teams showing ”↓ to expand” instead of the correct “shift + ↓ to expand”

[​](#2-1-74)

2.1.74

March 12, 2026

**Added**

- Added actionable suggestions to `/context` command — identifies context-heavy tools, memory bloat, and capacity warnings with specific optimization tips
- Added `autoMemoryDirectory` setting to configure a custom directory for auto-memory storage

**Changed**

- Changed `--plugin-dir` so local dev copies now override installed marketplace plugins with the same name (unless that plugin is force-enabled by managed settings)

**Improved**

- \[VSCode\] Improved scroll wheel responsiveness in the integrated terminal with terminal-aware acceleration

Show 13 bug fixes

- Fixed memory leak where streaming API response buffers were not released when the generator was terminated early, causing unbounded RSS growth on the Node.js/npm code path
- Fixed managed policy `ask` rules being bypassed by user `allow` rules or skill `allowed-tools`
- Fixed full model IDs (e.g., `claude-opus-4-5`) being silently ignored in agent frontmatter `model:` field and `--agents` JSON config — agents now accept the same model values as `--model`
- Fixed MCP OAuth authentication hanging when the callback port is already in use
- Fixed MCP OAuth refresh never prompting for re-auth after the refresh token expires, for OAuth servers that return errors with HTTP 200 (e.g. Slack)
- Fixed voice mode silently failing on the macOS native binary for users whose terminal had never been granted microphone permission — the binary now includes the `audio-input` entitlement so macOS prompts correctly
- Fixed `SessionEnd` hooks being killed after 1.5 s on exit regardless of `hook.timeout` — now configurable via `CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS`
- Fixed `/plugin install` failing inside the REPL for marketplace plugins with local sources
- Fixed marketplace update not syncing git submodules — plugin sources in submodules no longer break after update
- Fixed unknown slash commands with arguments silently dropping input — now shows your input as a warning
- Fixed Hebrew, Arabic, and other RTL text not rendering correctly in Windows Terminal, conhost, and VS Code integrated terminal
- Fixed LSP servers not working on Windows due to malformed file URIs
- \[VSCode\] Fixed delete button not working for Untitled sessions

[​](#2-1-73)

2.1.73

March 11, 2026

**Added**

- Added `modelOverrides` setting to map model picker entries to custom provider model IDs (e.g. Bedrock inference profile ARNs)
- Added actionable guidance when OAuth login or connectivity checks fail due to SSL certificate errors (corporate proxies, `NODE_EXTRA_CA_CERTS`)

**Changed**

- Changed default Opus model on Bedrock, Vertex, and Microsoft Foundry to Opus 4.6 (was Opus 4.1)
- Deprecated `/output-style` command — use `/config` instead. Output style is now fixed at session start for better prompt caching

Show 6 improvements

- Improved Up arrow after interrupting Claude — now restores the interrupted prompt and rewinds the conversation in one step
- Improved IDE detection speed at startup
- Improved clipboard image pasting performance on macOS
- Improved `/effort` to work while Claude is responding, matching `/model` behavior
- Improved voice mode to automatically retry transient connection failures during rapid push-to-talk re-press
- Improved the Remote Control spawn mode selection prompt with better context

Show 16 bug fixes

- Fixed freezes and 100% CPU loops triggered by permission prompts for complex bash commands
- Fixed a deadlock that could freeze Claude Code when many skill files changed at once (e.g. during `git pull` in a repo with a large `.claude/skills/` directory)
- Fixed Bash tool output being lost when running multiple Claude Code sessions in the same project directory
- Fixed subagents with `model: opus`/`sonnet`/`haiku` being silently downgraded to older model versions on Bedrock, Vertex, and Microsoft Foundry
- Fixed background bash processes spawned by subagents not being cleaned up when the agent exits
- Fixed `/resume` showing the current session in the picker
- Fixed `/ide` crashing with `onInstall is not defined` when auto-installing the extension
- Fixed `/loop` not being available on Bedrock/Vertex/Foundry and when telemetry was disabled
- Fixed SessionStart hooks firing twice when resuming a session via `--resume` or `--continue`
- Fixed JSON-output hooks injecting no-op system-reminder messages into the model’s context on every turn
- Fixed voice mode session corruption when a slow connection overlaps a new recording
- Fixed Linux sandbox failing to start with “ripgrep (rg) not found” on native builds
- Fixed Linux native modules not loading on Amazon Linux 2 and other glibc 2.26 systems
- Fixed “media_type: Field required” API error when receiving images via Remote Control
- Fixed `/heapdump` failing on Windows with `EEXIST` error when the Desktop folder already exists
- VSCode: Fixed HTTP 400 errors for users behind proxies or on Bedrock/Vertex with Claude 4.5 models

[​](#2-1-72)

2.1.72

March 10, 2026

**Added**

- Added `w` key in `/copy` to write the focused selection directly to a file, bypassing the clipboard (useful over SSH)
- Added optional description argument to `/plan` (e.g., `/plan fix the auth bug`) that enters plan mode and immediately starts
- Added `ExitWorktree` tool to leave an `EnterWorktree` session
- Added `CLAUDE_CODE_DISABLE_CRON` environment variable to immediately stop scheduled cron jobs mid-session
- Added `lsof`, `pgrep`, `tput`, `ss`, `fd`, and `fdfind` to the bash auto-approval allowlist, reducing permission prompts for common read-only operations
- Added support for marketplace git URLs without `.git` suffix (Azure DevOps, AWS CodeCommit)
- VSCode: Added effort level indicator on the input border
- VSCode: Added `vscode://anthropic.claude-code/open` URI handler to open a new Claude Code tab programmatically, with optional `prompt` and `session` query parameters

**Changed**

- Restored the `model` parameter on the Agent tool for per-invocation model overrides
- Simplified effort levels to low/medium/high (removed max) with new symbols (○ ◐ ●) and a brief notification instead of a persistent icon. Use `/effort auto` to reset to default
- Reduced bundle size by ~510 KB
- Changed CLAUDE.md HTML comments (`<!-- ... -->`) to be hidden from Claude when auto-injected. Comments remain visible when read with the Read tool

Show 6 improvements

- Improved `/config` — Escape now cancels changes, Enter saves and closes, Space toggles settings
- Improved up-arrow history to show current session’s messages first when running multiple concurrent sessions
- Improved voice input transcription accuracy for repo names and common dev terms (regex, OAuth, JSON)
- Improved bash command parsing by switching to a native module — faster initialization and no memory leak
- Improved marketplace clone failure messages to show diagnostic info even when git produces no stderr
- Improved CPU utilization in long sessions

Show 33 bug fixes

- Fixed tool search to activate even with `ANTHROPIC_BASE_URL` as long as `ENABLE_TOOL_SEARCH` is set.
- Fixed slow exits when background tasks or hooks were slow to respond
- Fixed agent task progress stuck on “Initializing…”
- Fixed skill hooks firing twice per event when a hooks-enabled skill is invoked by the model
- Fixed several voice mode issues: occasional input lag, false “No speech detected” errors after releasing push-to-talk, and stale transcripts re-filling the prompt after submission
- Fixed `--continue` not resuming from the most recent point after `--compact`
- Fixed bash security parsing edge cases
- Fixed several plugin issues: installation failing on Windows with `EEXIST` error in OneDrive folders, marketplace blocking user-scope installs when a project-scope install exists, `CLAUDE_CODE_PLUGIN_CACHE_DIR` creating literal `~` directories, and `plugin.json` with marketplace-only fields failing to load
- Fixed feedback survey appearing too frequently in long sessions
- Fixed `--effort` CLI flag being reset by unrelated settings writes on startup
- Fixed backgrounded Ctrl+B queries losing their transcript or corrupting the new conversation after `/clear`
- Fixed `/clear` killing background agent/bash tasks — only foreground tasks are now cleared
- Fixed worktree isolation issues: Task tool resume not restoring cwd, and background task notifications missing `worktreePath` and `worktreeBranch`
- Fixed `/model` not displaying results when run while Claude is working
- Fixed digit keys selecting menu options instead of typing in plan mode permission prompt’s text input
- Fixed sandbox permission issues: certain file write operations incorrectly allowed without prompting, and output redirections to allowlisted directories (like `/tmp/claude/`) prompting unnecessarily
- Fixed prompt cache invalidation in SDK `query()` calls, reducing input token costs up to 12x
- Fixed Escape key becoming unresponsive after cancelling a query
- Fixed double Ctrl+C not exiting when background agents or tasks are running
- Fixed team agents to inherit the leader’s model
- Fixed “Always Allow” saving permission rules that never match again
- Fixed several hooks issues: `transcript_path` pointing to the wrong directory for resumed/forked sessions, agent `prompt` being silently deleted from settings.json on every settings write, PostToolUse block reason displaying twice, async hooks not receiving stdin with bash `read -r`, and validation error message showing an example that fails validation
- Fixed session crashes in Desktop/SDK when Read returned files containing U+2028/U+2029 characters
- Fixed terminal title being cleared on exit even when `CLAUDE_CODE_DISABLE_TERMINAL_TITLE` was set
- Fixed several permission rule matching issues: wildcard rules not matching commands with heredocs, embedded newlines, or no arguments; `sandbox.excludedCommands` failing with env var prefixes; “always allow” suggesting overly broad prefixes for nested CLI tools; and deny rules not applying to all command forms
- Fixed oversized and truncated images from Bash data-URL output
- Fixed a crash when resuming sessions that contained Bedrock API errors
- Fixed intermittent “expected boolean, received string” validation errors on Edit, Bash, and Grep tool inputs
- Fixed multi-line session titles when forking from a conversation whose first message contained newlines
- Fixed queued messages not showing attached images, and images being lost when pressing ↑ to edit a queued message
- Fixed parallel tool calls where a failed Read/WebFetch/Glob would cancel its siblings — only Bash errors now cascade
- VSCode: Fixed scroll speed in integrated terminals not matching native terminals
- VSCode: Fixed Shift+Enter submitting input instead of inserting a newline for users with older keybindings

[​](#2-1-71)

2.1.71

March 7, 2026

**Added**

- Added `/loop` command to run a prompt or slash command on a recurring interval (e.g. `/loop 5m check the deploy`)
- Added cron scheduling tools for recurring prompts within a session
- Added `voice:pushToTalk` keybinding to make the voice activation key rebindable in `keybindings.json` (default: space) — modifier+letter combos like `meta+k` have zero typing interference
- Added `fmt`, `comm`, `cmp`, `numfmt`, `expr`, `test`, `printf`, `getconf`, `seq`, `tsort`, and `pr` to the bash auto-approval allowlist

**Changed**

- Updated `/debug` to toggle debug logging on mid-session, since debug logs are no longer written by default
- Removed startup notification noise for unauthenticated org-registered claude.ai connectors

**Improved**

- Improved startup time by deferring native image processor loading to first use
- Improved bridge session reconnection to complete within seconds after laptop wake from sleep, instead of waiting up to 10 minutes
- Improved `/plugin uninstall` to disable project-scoped plugins in `.claude/settings.local.json` instead of modifying `.claude/settings.json`, so changes don’t affect teammates
- Improved plugin-provided MCP server deduplication — servers that duplicate a manually-configured server (same command/URL) are now skipped, preventing duplicate connections and tool sets. Suppressions are shown in the `/plugin` menu.

Show 18 bug fixes

- Fixed stdin freeze in long-running sessions where keystrokes stop being processed but the process stays alive
- Fixed a 5–8 second startup freeze for users with voice mode enabled, caused by CoreAudio initialization blocking the main thread after system wake
- Fixed startup UI freeze when many claude.ai proxy connectors refresh an expired OAuth token simultaneously
- Fixed forked conversations (`/fork`) sharing the same plan file, which caused plan edits in one fork to overwrite the other
- Fixed the Read tool putting oversized images into context when image processing failed, breaking subsequent turns in long image-heavy sessions
- Fixed false-positive permission prompts for compound bash commands containing heredoc commit messages
- Fixed plugin installations being lost when running multiple Claude Code instances
- Fixed claude.ai connectors failing to reconnect after OAuth token refresh
- Fixed claude.ai MCP connector startup notifications appearing for every org-configured connector instead of only previously connected ones
- Fixed background agent completion notifications missing the output file path, which made it difficult for parent agents to recover agent results after context compaction
- Fixed duplicate output in Bash tool error messages when commands exit with non-zero status
- Fixed Chrome extension auto-detection getting permanently stuck on “not installed” after running on a machine without local Chrome
- Fixed `/plugin marketplace update` failing with merge conflicts when the marketplace is pinned to a branch/tag ref
- Fixed `/plugin marketplace add owner/repo@ref` incorrectly parsing `@` — previously only `#` worked as a ref separator, causing undiagnosable errors with `strictKnownMarketplaces`
- Fixed duplicate entries in `/permissions` Workspace tab when the same directory is added with and without a trailing slash
- Fixed `--print` hanging forever when team agents are configured — the exit loop no longer waits on long-lived `in_process_teammate` tasks
- Fixed ”❯ Tool loaded.” appearing in the REPL after every `ToolSearch` call
- Fixed prompting for `cd <cwd> && git ...` on Windows when the model uses a mingw-style path

[​](#2-1-70)

2.1.70

March 6, 2026

**Added**

- \[VSCode\] Added spark icon in VS Code activity bar that lists all Claude Code sessions, with sessions opening as full editors
- \[VSCode\] Added full markdown document view for plans in VS Code, with support for adding comments to provide feedback
- \[VSCode\] Added native MCP server management dialog — use `/mcp` in the chat panel to enable/disable servers, reconnect, and manage OAuth authentication without switching to the terminal

**Changed**

- Reduced prompt input re-renders during turns by ~74%
- Reduced startup memory by ~426KB for users without custom CA certificates
- Reduced Remote Control `/poll` rate to once per 10 minutes while connected (was 1–2s), cutting server load ~300×. Reconnection is unaffected — transport loss immediately wakes fast polling.

**Improved**

- Improved error message when microphone captures silence to distinguish from “no speech detected”
- Improved compaction to preserve images in the summarizer request, allowing prompt cache reuse for faster and cheaper compaction
- Improved `/rename` to work while Claude is processing, instead of being silently queued

Show 20 bug fixes

- Fixed API 400 errors when using `ANTHROPIC_BASE_URL` with a third-party gateway — tool search now correctly detects proxy endpoints and disables `tool_reference` blocks
- Fixed `API Error: 400 This model does not support the effort parameter` when using custom Bedrock inference profiles or other model identifiers not matching standard Claude naming patterns
- Fixed empty model responses immediately after `ToolSearch` — the server renders tool schemas with system-prompt-style tags at the prompt tail, which could confuse models into stopping early
- Fixed prompt-cache bust when an MCP server with `instructions` connects after the first turn
- Fixed Enter inserting a newline instead of submitting when typing over a slow SSH connection
- Fixed clipboard corrupting non-ASCII text (CJK, emoji) on Windows/WSL by using PowerShell `Set-Clipboard`
- Fixed extra VS Code windows opening at startup on Windows when running from the VS Code integrated terminal
- Fixed voice mode failing on Windows native binary with “native audio module could not be loaded”
- Fixed push-to-talk not activating on session start when `voiceEnabled: true` was set in settings
- Fixed markdown links containing `#NNN` references incorrectly pointing to the current repository instead of the linked URL
- Fixed repeated “Model updated to Opus 4.6” notification when a project’s `.claude/settings.json` has a legacy Opus model string pinned
- Fixed plugins showing as inaccurately installed in `/plugin`
- Fixed plugins showing “not found in marketplace” errors on fresh startup by auto-refreshing after marketplace installation
- Fixed `/security-review` command failing with `unknown option merge-base` on older git versions
- Fixed `/color` command having no way to reset back to the default color — `/color default`, `/color gray`, `/color reset`, and `/color none` now restore the default
- Fixed a performance regression in the `AskUserQuestion` preview dialog that re-ran markdown rendering on every keystroke in the notes input
- Fixed feature flags read during early startup never refreshing their disk cache, causing stale values to persist across sessions
- Fixed `permissions.defaultMode` settings values other than `acceptEdits` or `plan` being applied in Claude Code Remote environments — they are now ignored
- Fixed skill listing being re-injected on every `--resume` (~600 tokens saved per resume)
- Fixed teleport marker not rendering in VS Code teleported sessions

[​](#2-1-69)

2.1.69

March 5, 2026

**Added**

- Added the `/claude-api` skill for building applications with the Claude API and Anthropic SDK
- Added Ctrl+U on an empty bash prompt (`!`) to exit bash mode, matching `escape` and `backspace`
- Added numeric keypad support for selecting options in Claude’s interview questions (previously only the number row above QWERTY worked)
- Added optional name argument to `/remote-control` and `claude remote-control` (`/remote-control My Project` or `--name "My Project"`) to set a custom session title visible in claude.ai/code
- Added Voice STT support for 10 new languages (20 total) — Russian, Polish, Turkish, Dutch, Ukrainian, Greek, Czech, Danish, Swedish, Norwegian
- Added effort level display (e.g., “with low effort”) to the logo and spinner, making it easier to see which effort setting is active
- Added agent name display in terminal title when using `claude --agent`
- Added `sandbox.enableWeakerNetworkIsolation` setting (macOS only) to allow Go programs like `gh`, `gcloud`, and `terraform` to verify TLS certificates when using a custom MITM proxy with `httpProxyPort`
- Added `includeGitInstructions` setting (and `CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS` env var) to remove built-in commit and PR workflow instructions from Claude’s system prompt
- Added `/reload-plugins` command to activate pending plugin changes without restarting
- Added a one-time startup prompt suggesting Claude Code Desktop on macOS and Windows (max 3 showings, dismissible)
- Added `${CLAUDE_SKILL_DIR}` variable for skills to reference their own directory in SKILL.md content
- Added `InstructionsLoaded` hook event that fires when CLAUDE.md or `.claude/rules/*.md` files are loaded into context
- Added `agent_id` (for subagents) and `agent_type` (for subagents and `--agent`) to hook events
- Added `worktree` field to status line hook commands with name, path, branch, and original repo directory when running in a `--worktree` session
- Added `pluginTrustMessage` in managed settings to append organization-specific context to the plugin trust warning shown before installation
- Added policy limit fetching (e.g., remote control restrictions) for Team plan OAuth users, not just Enterprise
- Added `pathPattern` to `strictKnownMarketplaces` for regex-matching file/directory marketplace sources alongside `hostPattern` restrictions
- Added plugin source type `git-subdir` to point to a subdirectory within a git repo
- Added `oauth.authServerMetadataUrl` config option for MCP servers to specify a custom OAuth metadata discovery URL when standard discovery fails
- \[VSCode\] Added compaction display as a collapsible “Compacted chat” card with the summary inside

**Changed**

- Reduced baseline memory by ~16MB by deferring Yoga WASM preloading
- Reduced memory footprint for SDK and CCR sessions using stream-json output
- Reduced memory usage when resuming large sessions (including compacted history)
- Reduced token usage on multi-agent tasks with more concise subagent final reports
- Changed Sonnet 4.5 users on Pro/Max/Team Premium to be automatically migrated to Sonnet 4.6
- Changed the `/resume` picker to show your most recent prompt instead of the first one. This also resolves some titles appearing as `(session)`.
- Changed claude.ai MCP connector failures to show a notification instead of silently disappearing from the tool list
- Changed example command suggestions to be generated deterministically instead of calling Haiku
- Changed resuming after compaction to no longer produce a preamble recap before continuing
- \[SDK\] Changed task creation to no longer require the `activeForm` field — the spinner falls back to the task subject
- \[VSCode\] The permission mode picker now respects `permissions.disableBypassPermissionsMode` from your effective Claude Code settings (including managed/policy settings) — when set to `disable`, bypass permissions mode is hidden from the picker

Show 13 improvements

- Improved spinner performance by isolating the 50ms animation loop from the surrounding shell, reducing render and CPU overhead during turns
- Improved UI rendering performance in native binaries with React Compiler
- Improved `--worktree` startup by eliminating a git subprocess on the startup path
- Improved macOS startup by eliminating redundant settings-file reloads when managed settings resolve
- Improved macOS startup for Claude.ai enterprise/team users by skipping an unnecessary keychain lookup
- Improved MCP `-p` startup by pipelining claude.ai config fetch with local connections and using a concurrency pool instead of sequential batching
- Improved voice startup by removing imperceptible warmup pulse animations that were causing re-render stutter
- Improved MCP binary content handling: tools returning PDFs, Office documents, or audio now save decoded bytes to disk with the correct file extension instead of dumping raw base64 into the conversation context. WebFetch also saves binary responses alongside its summary.
- Improved memory usage in long sessions by stabilizing `onSubmit` across message updates
- Improved LSP tool rendering and memory context building to no longer read entire files
- Improved session upload and memory sync to avoid reading large files into memory before size/binary checks
- Improved file operation performance by avoiding reading file contents for existence checks (6 sites)
- Improved documentation to clarify that `--append-system-prompt-file` and `--system-prompt-file` work in interactive mode (the docs previously said print mode only)

Show 58 bug fixes

- Fixed a security issue where nested skill discovery could load skills from gitignored directories like `node_modules`
- Fixed trust dialog silently enabling all `.mcp.json` servers on first run. You’ll now see the per-server approval dialog as expected
- Fixed `claude remote-control` crashing immediately on npm installs with “bad option: —sdk-url” (anthropics/claude-code#28334)
- Fixed `--model claude-opus-4-0` and `--model claude-opus-4-1` resolving to deprecated Opus versions instead of current
- Fixed macOS keychain corruption when using multiple OAuth MCP servers. Large OAuth metadata blobs could overflow the `security -i` stdin buffer, silently leaving stale credentials behind and causing repeated `/login` prompts.
- Fixed `.credentials.json` losing `subscriptionType` (showing “Claude API” instead of “Claude Pro”/“Claude Max”) when the profile endpoint transiently fails during token refresh (anthropics/claude-code#30185)
- Fixed ghost dotfiles (`.bashrc`, `HEAD`, etc.) appearing as untracked files in the working directory after sandboxed Bash commands on Linux
- Fixed Shift+Enter printing `[27;2;13~` instead of inserting a newline in Ghostty over SSH
- Fixed stash (Ctrl+S) being cleared when submitting a message while Claude is working
- Fixed ctrl+o (transcript toggle) freezing for many seconds in long sessions with lots of file edits
- Fixed plan mode feedback input not supporting multi-line text entry (backslash+Enter and Shift+Enter now insert newlines)
- Fixed cursor not moving down into blank lines at the top of the input box
- Fixed `/stats` crash when transcript files contain entries with missing or malformed timestamps
- Fixed a brief hang after a streaming error on long sessions (the transcript was being fully rewritten to drop one line; it is now truncated in place)
- Fixed `--setting-sources user` not blocking dynamically discovered project skills
- Fixed duplicate CLAUDE.md, slash commands, agents, and rules when running from a worktree nested inside its main repo (e.g. `claude -w`)
- Fixed plugin Stop/SessionEnd/etc hooks not firing after any `/plugin` operation
- Fixed plugin hooks being silently dropped when two plugins use the same `${CLAUDE_PLUGIN_ROOT}/...` command template
- Fixed memory leak in long-running SDK/CCR sessions where conversation messages were retained unnecessarily
- Fixed API 400 errors in forked agents (autocompact, summarization) when resuming sessions that were interrupted mid-tool-batch
- Fixed “unexpected tool_use_id found in tool_result blocks” error when resuming conversations that start with an orphaned tool result
- Fixed teammates accidentally spawning nested teammates via the Agent tool’s `name` parameter
- Fixed `CLAUDE_CODE_MAX_OUTPUT_TOKENS` being ignored during conversation compaction
- Fixed `/compact` summary rendering as a user bubble in SDK consumers (Claude Code Remote web UI, VSCode extension)
- Fixed voice space bar getting stuck after a failed voice activation (module loading race, cold GrowthBook)
- Fixed worktree file copy on Windows
- Fixed global `.claude` folder detection on Windows
- Fixed symlink bypass where writing new files through a symlinked parent directory could escape the working directory in `acceptEdits` mode
- Fixed sandbox prompting users to approve non-allowed domains when `allowManagedDomainsOnly` is enabled in managed settings — non-allowed domains are now blocked automatically with no bypass
- Fixed interactive tools (e.g., `AskUserQuestion`) being silently auto-allowed when listed in a skill’s allowed-tools, bypassing the permission prompt and running with empty answers
- Fixed multi-GB memory spike when committing with large untracked binary files in the working tree
- Fixed Escape not interrupting a running turn when the input box has draft text. Use Up arrow to pull queued messages back for editing, or Ctrl+U to clear the input line.
- Fixed Android app crash when running local slash commands (`/voice`, `/cost`) in Remote Control sessions
- Fixed a memory leak where old message array versions accumulated in React Compiler `memoCache` over long sessions
- Fixed a memory leak where REPL render scopes accumulated over long sessions (~35MB over 1000 turns)
- Fixed memory retention in in-process teammates where the parent’s full conversation history was pinned for the teammate’s lifetime, preventing GC after `/clear` or auto-compact
- Fixed a memory leak in interactive mode where hook events could accumulate unboundedly during long sessions
- Fixed hang when `--mcp-config` points to a corrupted file
- Fixed slow startup when many skills/plugins are installed
- Fixed `cd <outside-dir> && <cmd>` permission prompt to surface the chained command instead of only showing “Yes, allow reading from `<dir>`/”
- Fixed conditional `.claude/rules/*.md` files (with `paths:` frontmatter) and nested CLAUDE.md files not loading in print mode (`claude -p`)
- Fixed `/clear` not fully clearing all session caches, reducing memory retention in long sessions
- Fixed terminal flicker caused by animated elements at the scrollback boundary
- Fixed UI frame drops on macOS when using MCP servers with OAuth (regression from 2.1.x)
- Fixed occasional frame stalls during typing caused by synchronous debug log flushes
- Fixed `TeammateIdle` and `TaskCompleted` hooks to support `{"continue": false, "stopReason": "..."}` to stop the teammate, matching `Stop` hook behavior
- Fixed `WorktreeCreate` and `WorktreeRemove` plugin hooks being silently ignored
- Fixed skill descriptions with colons (e.g., “Triggers include: X, Y, Z”) failing to load from SKILL.md frontmatter
- Fixed project skills without a `description:` frontmatter field not appearing in Claude’s available skills list
- Fixed `/context` showing identical token counts for all MCP tools from a server
- Fixed literal `nul` file creation on Windows when the model uses CMD-style `2>nul` redirection in Git Bash
- Fixed extra blank lines appearing below each tool call in the expanded subagent transcript view (Ctrl+O)
- Fixed Tab/arrow keys not cycling Settings tabs when `/config` search box is focused but empty
- Fixed service key OAuth sessions (CCR containers) spamming `[ERROR]` logs with 403s from profile-scoped endpoints
- Fixed inconsistent color for “Remote Control active” status indicator
- Fixed Voice waveform cursor covering the first suffix letter when dictating mid-input
- Fixed Voice input showing all 5 spaces during warmup instead of capping at ~2 (aligning with the “keep holding…” hint)
- \[VSCode\] Fixed RTL text (Arabic, Hebrew, Persian) rendering reversed in the chat panel (regression in v2.1.63)

[​](#2-1-68)

2.1.68

March 4, 2026

- Opus 4.6 now defaults to medium effort for Max and Team subscribers. Medium effort works well for most tasks — it’s the sweet spot between speed and thoroughness. You can change this anytime with `/model`
- Re-introduced the “ultrathink” keyword to enable high effort for the next turn
- Removed Opus 4 and 4.1 from Claude Code on the first-party API — users with these models pinned are automatically moved to Opus 4.6

[​](#2-1-66)

2.1.66

March 4, 2026

- Reduced spurious error logging

[​](#2-1-63)

2.1.63

February 28, 2026

**Added**

- Added `/simplify` and `/batch` bundled slash commands
- Added `ENABLE_CLAUDEAI_MCP_SERVERS=false` env var to opt out from making claude.ai MCP servers available
- Added HTTP hooks, which can POST JSON to a URL and receive JSON instead of running a shell command
- Added manual URL paste fallback during MCP OAuth authentication. If the automatic localhost redirect doesn’t work, you can paste the callback URL to complete authentication.
- Added “Always copy full response” option to the `/copy` picker. When selected, future `/copy` commands will skip the code block picker and copy the full response directly.
- VSCode: Added session rename and remove actions to the sessions list

**Changed**

- Project configs & auto memory now shared across git worktrees of the same repository

**Improved**

- Improved `/model` command to show the currently active model in the slash command menu
- Improved memory usage in long sessions with subagents by stripping heavy progress message payloads during context compaction

Show 17 bug fixes

- Fixed local slash command output like /cost appearing as user-sent messages instead of system messages in the UI
- Fixed listener leak in bridge polling loop
- Fixed listener leak in MCP OAuth flow cleanup
- Fixed memory leak when navigating hooks configuration menu
- Fixed listener leak in interactive permission handler during auto-approvals
- Fixed file count cache ignoring glob ignore patterns
- Fixed memory leak in bash command prefix cache
- Fixed MCP tool/resource cache leak on server reconnect
- Fixed IDE host IP detection cache incorrectly sharing results across ports
- Fixed WebSocket listener leak on transport reconnect
- Fixed memory leak in git root detection cache that could cause unbounded growth in long-running sessions
- Fixed memory leak in JSON parsing cache that grew unbounded over long sessions
- VSCode: Fixed remote sessions not appearing in conversation history
- Fixed a race condition in the REPL bridge where new messages could arrive at the server interleaved with historical messages during the initial connection flush, causing message ordering issues.
- Fixed memory leak where long-running teammates retained all messages in AppState even after conversation compaction
- Fixed a memory leak where MCP server fetch caches were not cleared on disconnect, causing growing memory usage with servers that reconnect frequently
- Fixed `/clear` not resetting cached skills, which could cause stale skill content to persist in the new conversation

[​](#2-1-62)

2.1.62

February 27, 2026

- Fixed prompt suggestion cache regression that reduced cache hit rates

[​](#2-1-61)

2.1.61

February 26, 2026

- Fixed concurrent writes corrupting config file on Windows

[​](#2-1-59)

2.1.59

February 26, 2026

- Claude automatically saves useful context to auto-memory. Manage with /memory
- Added `/copy` command to show an interactive picker when code blocks are present, allowing selection of individual code blocks or the full response.
- Improved “always allow” prefix suggestions for compound bash commands (e.g. `cd /tmp && git fetch && git push`) to compute smarter per-subcommand prefixes instead of treating the whole command as one
- Improved ordering of short task lists
- Improved memory usage in multi-agent sessions by releasing completed subagent task state
- Fixed MCP OAuth token refresh race condition when running multiple Claude Code instances simultaneously
- Fixed shell commands not showing a clear error message when the working directory has been deleted
- Fixed config file corruption that could wipe authentication when multiple Claude Code instances ran simultaneously

[​](#2-1-58)

2.1.58

February 25, 2026

- Expand Remote Control to more users

[​](#2-1-56)

2.1.56

February 25, 2026

- VS Code: Fixed another cause of “command ‘claude-vscode.editor.openLast’ not found” crashes

[​](#2-1-55)

2.1.55

February 25, 2026

- Fixed BashTool failing on Windows with EINVAL error

[​](#2-1-53)

2.1.53

February 25, 2026

- Fixed a UI flicker where user input would briefly disappear after submission before the message rendered
- Fixed bulk agent kill (ctrl+f) to send a single aggregate notification instead of one per agent, and to properly clear the command queue
- Fixed graceful shutdown sometimes leaving stale sessions when using Remote Control by parallelizing teardown network calls
- Fixed `--worktree` sometimes being ignored on first launch
- Fixed a panic (“switch on corrupted value”) on Windows
- Fixed a crash that could occur when spawning many processes on Windows
- Fixed a crash in the WebAssembly interpreter on Linux x64 & Windows x64
- Fixed a crash that sometimes occurred after 2 minutes on Windows ARM64

[​](#2-1-52)

2.1.52

February 24, 2026

- VS Code: Fixed extension crash on Windows (“command ‘claude-vscode.editor.openLast’ not found”)

[​](#2-1-51)

2.1.51

February 24, 2026

**Added**

- Added `claude remote-control` subcommand for external builds, enabling local environment serving for all users.
- Added support for custom npm registries and specific version pinning when installing plugins from npm sources
- Added `CLAUDE_CODE_ACCOUNT_UUID`, `CLAUDE_CODE_USER_EMAIL`, and `CLAUDE_CODE_ORGANIZATION_UUID` environment variables for SDK callers to provide account info synchronously, eliminating a race condition where early telemetry events lacked account metadata.

**Changed**

- Updated plugin marketplace default git timeout from 30s to 120s and added `CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS` to configure.
- BashTool now skips login shell (`-l` flag) by default when a shell snapshot is available, improving command execution performance. Previously this required setting `CLAUDE_BASH_NO_LOGIN=true`.
- Tool results larger than 50K characters are now persisted to disk (previously 100K). This reduces context window usage and improves conversation longevity.
- The `/model` picker now shows human-readable labels (e.g., “Sonnet 4.5”) instead of raw model IDs for pinned model versions, with an upgrade hint when a newer version is available.
- Managed settings can now be set via macOS plist or Windows Registry. Learn more at [https://code.claude.com/docs/en/settings#settings-files](settings.md#settings-files)

**Fixed**

- Fixed a security issue where `statusLine` and `fileSuggestion` hook commands could execute without workspace trust acceptance in interactive mode.
- Fixed a bug where duplicate `control_response` messages (e.g. from WebSocket reconnects) could cause API 400 errors by pushing duplicate assistant messages into the conversation.
- Fixed slash command autocomplete crashing when a plugin’s SKILL.md description is a YAML array or other non-string type

[​](#2-1-50)

2.1.50

February 20, 2026

**Added**

- Added support for `startupTimeout` configuration for LSP servers
- Added `WorktreeCreate` and `WorktreeRemove` hook events, enabling custom VCS setup and teardown when agent worktree isolation creates or removes worktrees.
- Added support for `isolation: worktree` in agent definitions, allowing agents to declaratively run in isolated git worktrees.
- Added `claude agents` CLI command to list all configured agents
- Added `CLAUDE_CODE_DISABLE_1M_CONTEXT` environment variable to disable 1M context window support
- VSCode: Added `/extra-usage` command support in VS Code sessions

**Changed**

- `CLAUDE_CODE_SIMPLE` mode now also disables MCP tools, attachments, hooks, and CLAUDE.md file loading for a fully minimal experience.
- Opus 4.6 (fast mode) now includes the full 1M context window

**Improved**

- Improved memory usage during long sessions by clearing internal caches after compaction
- Improved memory usage during long sessions by clearing large tool results after they have been processed
- Improved startup performance for headless mode (`-p` flag) by deferring Yoga WASM and UI component imports

Show 14 bug fixes

- Fixed a bug where resumed sessions could be invisible when the working directory involved symlinks, because the session storage path was resolved at different times during startup. Also fixed session data loss on SSH disconnect by flushing session data before hooks and analytics in the graceful shutdown sequence.
- Linux: Fixed native modules not loading on systems with glibc older than 2.30 (e.g., RHEL 8)
- Fixed memory leak in agent teams where completed teammate tasks were never garbage collected from session state
- Fixed `CLAUDE_CODE_SIMPLE` to fully strip down skills, session memory, custom agents, and CLAUDE.md token counting
- Fixed `/mcp reconnect` freezing the CLI when given a server name that doesn’t exist
- Fixed memory leak where completed task state objects were never removed from AppState
- Fixed bug where MCP tools were not discovered when tool search is enabled and a prompt is passed in as a launch argument
- Fixed a memory leak where LSP diagnostic data was never cleaned up after delivery, causing unbounded memory growth in long sessions
- Fixed a memory leak where completed task output was not freed from memory, reducing memory usage in long sessions with many tasks
- Fixed prompt suggestion cache regression that reduced cache hit rates
- Fixed unbounded memory growth in long sessions by capping file history snapshots
- Fixed memory leak where TaskOutput retained recent lines after cleanup
- Fixed memory leak in CircularBuffer where cleared items were retained in the backing array
- Fixed memory leak in shell command execution where ChildProcess and AbortController references were retained after cleanup

[​](#2-1-49)

2.1.49

February 19, 2026

**Added**

- Added `--worktree` (`-w`) flag to start Claude in an isolated git worktree
- Added Ctrl+F keybinding to kill background agents (two-press confirmation)
- Added `ConfigChange` hook event that fires when configuration files change during a session, enabling enterprise security auditing and optional blocking of settings changes.

**Changed**

- Subagents support `isolation: "worktree"` for working in a temporary git worktree
- Agent definitions support `background: true` to always run as a background task
- Plugins can ship `settings.json` for default configuration
- Simple mode (`CLAUDE_CODE_SIMPLE`) now includes the file edit tool in addition to the Bash tool, allowing direct file editing in simple mode.
- Permission suggestions are now populated when safety checks trigger an ask response, enabling SDK consumers to display permission options
- Sonnet 4.5 with 1M context is being removed from the Max plan in favor of our frontier Sonnet 4.6 model, which now has 1M context. Please switch in /model.
- SDK model info now includes `supportsEffort`, `supportedEffortLevels`, and `supportsAdaptiveThinking` fields so consumers can discover model capabilities.

Show 7 improvements

- Improved MCP OAuth authentication with step-up auth support and discovery caching, reducing redundant network requests during server connections
- Improved performance in non-interactive mode (`-p`) by skipping unnecessary API calls during startup
- Improved performance by caching authentication failures for HTTP and SSE MCP servers, avoiding repeated connection attempts to servers requiring auth
- Improved startup performance by caching MCP auth failures to avoid redundant connection attempts
- Improved startup performance by reducing HTTP calls for analytics token counting
- Improved startup performance by batching MCP tool token counting into a single API call
- Improved permission prompts for path safety and working directory blocks to show the reason for the restriction instead of a bare prompt with no context

Show 10 bug fixes

- Fixed file-not-found errors to suggest corrected paths when the model drops the repo folder
- Fixed Ctrl+C and ESC being silently ignored when background agents are running and the main thread is idle. Pressing twice within 3 seconds now kills all background agents.
- Fixed prompt suggestion cache regression that reduced cache hit rates.
- Fixed `plugin enable` and `plugin disable` to auto-detect the correct scope when `--scope` is not specified, instead of always defaulting to user scope
- Fixed verbose mode not updating thinking block display when toggled via `/config` — memo comparators now correctly detect verbose changes
- Fixed unbounded WASM memory growth during long sessions by periodically resetting the tree-sitter parser
- Fixed potential rendering issues caused by stale yoga layout references
- Fixed unbounded memory growth during long-running sessions caused by Yoga WASM linear memory never shrinking
- Fixed `disableAllHooks` setting to respect managed settings hierarchy — non-managed settings can no longer disable managed hooks set by policy (#26637)
- Fixed `--resume` session picker showing raw XML tags for sessions that start with commands like `/clear`. Now correctly falls through to the session ID fallback.

[​](#2-1-47)

2.1.47

February 18, 2026

**Added**

- Added `last_assistant_message` field to Stop and SubagentStop hook inputs, providing the final assistant response text so hooks can access it without parsing transcript files.
- Added `chat:newline` keybinding action for configurable multi-line input (anthropics/claude-code#26075)
- Added `added_dirs` to the statusline JSON `workspace` section, exposing directories added via `/add-dir` to external scripts (anthropics/claude-code#26096)

**Changed**

- Search patterns in collapsed tool results are now displayed in quotes for clarity
- Use `ctrl+f` to kill all background agents instead of double-pressing ESC. Background agents now continue running when you press ESC to cancel the main thread, giving you more control over agent lifecycle.
- Simplified teammate navigation to use only Shift+Down (with wrapping) instead of both Shift+Up and Shift+Down.
- Increased initial session count in resume picker from 10 to 50 for faster session discovery (anthropics/claude-code#26123)
- Moved config backup files from home directory root to `~/.claude/backups/` to reduce home directory clutter (anthropics/claude-code#26130)
- The `/rename` command now updates the terminal tab title by default (anthropics/claude-code#25789)

Show 6 improvements

- Improved VS Code plan preview: auto-updates as Claude iterates, enables commenting only when the plan is ready for review, and keeps the preview open when rejecting so Claude can revise.
- Improved memory usage in long-running sessions by releasing API stream buffers, agent context, and skill state after use
- Improved startup performance by deferring SessionStart hook execution, reducing time-to-interactive by ~500ms.
- Improved performance of `@` file mentions - file suggestions now appear faster by pre-warming the index on startup and using session-based caching with background refresh.
- Improved memory usage by trimming agent task message history after tasks complete
- Improved memory usage during long agent sessions by eliminating O(n²) message accumulation in progress updates

Show 53 bug fixes

- Fixed FileWriteTool line counting to preserve intentional trailing blank lines instead of stripping them with `trimEnd()`.
- Fixed Windows terminal rendering bugs caused by `os.EOL` (`\r\n`) in display code — line counts now show correct values instead of always showing 1 on Windows.
- Fixed a bug where bold and colored text in markdown output could shift to the wrong characters on Windows due to `\r\n` line endings.
- Fixed compaction failing when conversation contains many PDF documents by stripping document blocks alongside images before sending to the compaction API (anthropics/claude-code#26188)
- Fixed an issue where bash tool output was silently discarded on Windows when using MSYS2 or Cygwin shells.
- Fixed the bash permission classifier to validate that returned match descriptions correspond to actual input rules, preventing hallucinated descriptions from incorrectly granting permissions
- Fixed user-defined agents only loading one file on NFS/FUSE filesystems that report zero inodes (anthropics/claude-code#26044)
- Fixed plugin agent skills silently failing to load when referenced by bare name instead of fully-qualified plugin name (anthropics/claude-code#25834)
- Windows: Fixed CWD tracking temp files never being cleaned up, causing them to accumulate indefinitely (anthropics/claude-code#17600)
- Fixed API 400 errors (“thinking blocks cannot be modified”) that occurred in sessions with concurrent agents, caused by interleaved streaming content blocks preventing proper message merging.
- Fixed an issue where a single file write/edit error would abort all other parallel file write/edit operations. Independent file mutations now complete even when a sibling fails.
- Fixed custom session titles set via `/rename` being lost after resuming a conversation (anthropics/claude-code#23610)
- Fixed collapsed read/search hint text overflowing on narrow terminals by truncating from the start.
- Fixed an issue where bash commands with backslash-newline continuation lines (e.g., long commands split across multiple lines with `\`) would produce spurious empty arguments, potentially breaking command execution.
- Fixed built-in slash commands (`/help`, `/model`, `/compact`, etc.) being hidden from the autocomplete dropdown when many user skills are installed (anthropics/claude-code#22020)
- Fixed MCP servers not appearing in the MCP Management Dialog after deferred loading
- Fixed session name persisting in status bar after `/clear` command (anthropics/claude-code#26082)
- Fixed crash when a skill’s `name` or `description` in SKILL.md frontmatter is a bare number (e.g., `name: 3000`) — the value is now properly coerced to a string (anthropics/claude-code#25837)
- Fixed /resume silently dropping sessions when the first message exceeds 16KB or uses array-format content (anthropics/claude-code#25721)
- Fixed `claude doctor` misclassifying mise and asdf-managed installations as native installs (anthropics/claude-code#26033)
- Fixed zsh heredoc failing with “read-only file system” error in sandboxed commands (anthropics/claude-code#25990)
- Fixed agent progress indicator showing inflated tool use count (anthropics/claude-code#26023)
- Fixed image pasting not working on WSL2 systems where Windows copies images as BMP format (anthropics/claude-code#25935)
- Fixed background agent results returning raw transcript data instead of the agent’s final answer (anthropics/claude-code#26012)
- Fixed Warp terminal incorrectly prompting for Shift+Enter setup when it supports it natively (anthropics/claude-code#25957)
- Fixed CJK wide characters causing misaligned timestamps and layout elements in the TUI (anthropics/claude-code#26084)
- Fixed custom agent `model` field in `.claude/agents/*.md` being ignored when spawning team teammates (anthropics/claude-code#26064)
- Fixed plan mode being lost after context compaction, causing the model to switch from planning to implementation mode (anthropics/claude-code#26061)
- Fixed `alwaysThinkingEnabled: true` in settings.json not enabling thinking mode on Bedrock and Vertex providers (anthropics/claude-code#26074)
- Fixed `tool_decision` OTel telemetry event not being emitted in headless/SDK mode (anthropics/claude-code#26059)
- Fixed session name being lost after context compaction — renamed sessions now preserve their custom title through compaction (anthropics/claude-code#26121)
- Windows: fixed worktree session matching when drive letter casing differs (anthropics/claude-code#26123)
- Fixed `/resume <session-id>` failing to find sessions whose first message exceeds 16KB (anthropics/claude-code#25920)
- Fixed “Always allow” on multiline bash commands creating invalid permission patterns that corrupt settings (anthropics/claude-code#25909)
- Fixed React crash (error \#31) when a skill’s `argument-hint` in SKILL.md frontmatter uses YAML sequence syntax (e.g., `[topic: foo | bar]`) — the value is now properly coerced to a string (anthropics/claude-code#25826)
- Fixed crash when using `/fork` on sessions that used web search — null entries in search results from transcript deserialization are now handled gracefully (anthropics/claude-code#25811)
- Fixed read-only git commands triggering FSEvents file watcher loops on macOS by adding —no-optional-locks flag (anthropics/claude-code#25750)
- Fixed custom agents and skills not being discovered when running from a git worktree — project-level `.claude/agents/` and `.claude/skills/` from the main repository are now included (anthropics/claude-code#25816)
- Fixed non-interactive subcommands like `claude doctor` and `claude plugin validate` being blocked inside nested Claude sessions (anthropics/claude-code#25803)
- Windows: Fixed the same CLAUDE.md file being loaded twice when drive letter casing differs between paths (anthropics/claude-code#25756)
- Fixed inline code spans in markdown being incorrectly parsed as bash commands (anthropics/claude-code#25792)
- Fixed teammate spinners not respecting custom spinnerVerbs from settings (anthropics/claude-code#25748)
- Fixed shell commands permanently failing after a command deletes its own working directory (anthropics/claude-code#26136)
- Fixed hooks (PreToolUse, PostToolUse) silently failing to execute on Windows by using Git Bash instead of cmd.exe (anthropics/claude-code#25981)
- Fixed LSP `findReferences` and other location-based operations returning results from gitignored files (e.g., `node_modules/`, `venv/`) (anthropics/claude-code#26051)
- Fixed sessions with large first prompts (\>16KB) disappearing from the /resume list (anthropics/claude-code#26140)
- Fixed shell functions with double-underscore prefixes (e.g., `__git_ps1`) not being preserved across shell sessions (anthropics/claude-code#25824)
- Fixed spinner showing “0 tokens” counter before any tokens have been received (anthropics/claude-code#26105)
- VSCode: Fixed conversation messages appearing dimmed while the AskUserQuestion dialog is open (anthropics/claude-code#26078)
- Fixed background tasks failing in git worktrees due to remote URL resolution reading from worktree-specific gitdir instead of the main repository config (anthropics/claude-code#26065)
- Fixed Right Alt key leaving visible `[25~` escape sequence residue in the input field on Windows/Git Bash terminals (anthropics/claude-code#25943)
- Fixed Edit tool silently corrupting Unicode curly quotes (\u201c\u201d \u2018\u2019) by replacing them with straight quotes when making edits (anthropics/claude-code#26141)
- Fixed OSC 8 hyperlinks only being clickable on the first line when link text wraps across multiple terminal lines.

[​](#2-1-46)

2.1.46

February 18, 2026

- Fixed orphaned CC processes after terminal disconnect on macOS
- Added support for using claude.ai MCP connectors in Claude Code

[​](#2-1-45)

2.1.45

February 17, 2026

**Added**

- Added support for Claude Sonnet 4.6
- Added support for reading `enabledPlugins` and `extraKnownMarketplaces` from `--add-dir` directories
- Added `spinnerTipsOverride` setting to customize spinner tips — configure `tips` with an array of custom tip strings, and optionally set `excludeDefault: true` to show only your custom tips instead of the built-in ones
- Added `SDKRateLimitInfo` and `SDKRateLimitEvent` types to the SDK, enabling consumers to receive rate limit status updates including utilization, reset times, and overage information

**Improved**

- Improved startup performance by removing eager loading of session history for stats caching
- Improved memory usage for shell commands that produce large output — RSS no longer grows unboundedly with command output size
- Improved collapsed read/search groups to show the current file or search pattern being processed beneath the summary line while active
- \[VSCode\] Improved permission destination choice (project/user/session) to persist across sessions

Show 7 bug fixes

- Fixed Agent Teams teammates failing on Bedrock, Vertex, and Foundry by propagating API provider environment variables to tmux-spawned processes (anthropics/claude-code#23561)
- Fixed sandbox “operation not permitted” errors when writing temporary files on macOS by using the correct per-user temp directory (anthropics/claude-code#21654)
- Fixed Task tool (backgrounded agents) crashing with a `ReferenceError` on completion (anthropics/claude-code#22087)
- Fixed autocomplete suggestions not being accepted on Enter when images are pasted in the input
- Fixed skills invoked by subagents incorrectly appearing in main session context after compaction
- Fixed excessive `.claude.json.backup` files accumulating on every startup
- Fixed plugin-provided commands, agents, and hooks not being available immediately after installation without requiring a restart

[​](#2-1-44)

2.1.44

February 16, 2026

- Fixed ENAMETOOLONG errors for deeply-nested directory paths
- Fixed auth refresh errors

[​](#2-1-43)

2.1.43

February 16, 2026

- Fixed AWS auth refresh hanging indefinitely by adding a 3-minute timeout
- Fixed spurious warnings for non-agent markdown files in `.claude/agents/` directory
- Fixed structured-outputs beta header being sent unconditionally on Vertex/Bedrock

[​](#2-1-42)

2.1.42

February 13, 2026

- Improved startup performance by deferring Zod schema construction
- Improved prompt cache hit rates by moving date out of system prompt
- Added one-time Opus 4.6 effort callout for eligible users
- Fixed /resume showing interrupt messages as session titles
- Fixed image dimension limit errors to suggest /compact

[​](#2-1-41)

2.1.41

February 13, 2026

**Added**

- Added guard against launching Claude Code inside another Claude Code session
- Added `speed` attribute to OTel events and trace spans for fast mode visibility
- Added `claude auth login`, `claude auth status`, and `claude auth logout` CLI subcommands
- Added Windows ARM64 (win32-arm64) native binary support

**Improved**

- Improved model error messages for Bedrock/Vertex/Foundry users with fallback suggestions
- Improved `/rename` to auto-generate session name from conversation context when called without arguments
- Improved narrow terminal layout for prompt footer

Show 15 bug fixes

- Fixed Agent Teams using wrong model identifier for Bedrock, Vertex, and Foundry customers
- Fixed a crash when MCP tools return image content during streaming
- Fixed /resume session previews showing raw XML tags instead of readable command names
- Fixed plugin browse showing misleading “Space to Toggle” hint for already-installed plugins
- Fixed hook blocking errors (exit code 2) not showing stderr to the user
- Fixed file resolution failing for @-mentions with anchor fragments (e.g., `@README.md#installation`)
- Fixed FileReadTool blocking the process on FIFOs, `/dev/stdin`, and large files
- Fixed background task notifications not being delivered in streaming Agent SDK mode
- Fixed cursor jumping to end on each keystroke in classifier rule input
- Fixed markdown link display text being dropped for raw URL
- Fixed auto-compact failure error notifications being shown to users
- Fixed permission wait time being included in subagent elapsed time display
- Fixed proactive ticks firing while in plan mode
- Fixed clear stale permission rules when settings change on disk
- Fixed hook blocking errors showing stderr content in UI

[​](#2-1-39)

2.1.39

February 10, 2026

- Improved terminal rendering performance
- Fixed fatal errors being swallowed instead of displayed
- Fixed process hanging after session close
- Fixed character loss at terminal screen boundary
- Fixed blank lines in verbose transcript view

[​](#2-1-38)

2.1.38

February 10, 2026

- Fixed VS Code terminal scroll-to-top regression introduced in 2.1.37
- Fixed Tab key queueing slash commands instead of autocompleting
- Fixed bash permission matching for commands using environment variable wrappers
- Fixed text between tool uses disappearing when not using streaming
- Fixed duplicate sessions when resuming in VS Code extension
- Improved heredoc delimiter parsing to prevent command smuggling
- Blocked writes to `.claude/skills` directory in sandbox mode

[​](#2-1-37)

2.1.37

February 7, 2026

- Fixed an issue where /fast was not immediately available after enabling /extra-usage

[​](#2-1-36)

2.1.36

February 7, 2026

- Fast mode is now available for Opus 4.6. Learn more at [https://code.claude.com/docs/en/fast-mode](fast-mode.md)

[​](#2-1-34)

2.1.34

February 6, 2026

- Fixed a crash when agent teams setting changed between renders
- Fixed a bug where commands excluded from sandboxing (via `sandbox.excludedCommands` or `dangerouslyDisableSandbox`) could bypass the Bash ask permission rule when `autoAllowBashIfSandboxed` was enabled

[​](#2-1-33)

2.1.33

February 6, 2026

**Added**

- Added `TeammateIdle` and `TaskCompleted` hook events for multi-agent workflows
- Added support for restricting which sub-agents can be spawned via `Task(agent_type)` syntax in agent “tools” frontmatter
- Added `memory` frontmatter field support for agents, enabling persistent memory with `user`, `project`, or `local` scope
- Added plugin name to skill descriptions and `/skills` menu for better discoverability
- VSCode: Added support for remote sessions, allowing OAuth users to browse and resume sessions from claude.ai
- VSCode: Added git branch and message count to the session picker, with support for searching by branch name

**Changed**

- Errors from invalid managed settings are now surfaced

**Improved**

- Improved error messages for API connection failures — now shows specific cause (e.g., ECONNREFUSED, SSL errors) instead of generic “Connection error”

Show 8 bug fixes

- Fixed agent teammate sessions in tmux to send and receive messages
- Fixed warnings about agent teams not being available on your current plan
- Fixed an issue where submitting a new message while the model was in extended thinking would interrupt the thinking phase
- Fixed an API error that could occur when aborting mid-stream, where whitespace text combined with a thinking block would bypass normalization and produce an invalid request
- Fixed API proxy compatibility issue where 404 errors on streaming endpoints no longer triggered non-streaming fallback
- Fixed an issue where proxy settings configured via `settings.json` environment variables were not applied to WebFetch and other HTTP requests on the Node.js build
- Fixed `/resume` session picker showing raw XML markup instead of clean titles for sessions started with slash commands
- VSCode: Fixed scroll-to-bottom under-scrolling on initial session load and session switch

[​](#2-1-32)

2.1.32

February 5, 2026

**Added**

- Added research preview agent teams feature for multi-agent collaboration (token-intensive feature, requires setting CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1)
- Added “Summarize from here” to the message selector, allowing partial conversation summarization.
- VSCode: Added spinner when loading past conversations list

**Changed**

- Claude Opus 4.6 is now available!
- Claude now automatically records and recalls memories as it works
- Skills defined in `.claude/skills/` within additional directories (`--add-dir`) are now loaded automatically.
- Updated —resume to re-use —agent value specified in previous conversation by default.
- Skill character budget now scales with context window (2% of context), so users with larger context windows can see more skill descriptions without truncation

**Fixed**

- Fixed `@` file completion showing incorrect relative paths when running from a subdirectory
- Fixed: Bash tool no longer throws “Bad substitution” errors when heredocs contain JavaScript template literals like `${index + 1}`, which previously interrupted tool execution
- Fixed Thai/Lao spacing vowels (สระ า, ำ) not rendering correctly in the input field
- VSCode: Fixed slash commands incorrectly being executed when pressing Enter with preceding text in the input field

[​](#2-1-31)

2.1.31

February 4, 2026

**Added**

- Added session resume hint on exit, showing how to continue your conversation later
- Added support for full-width (zenkaku) space input from Japanese IME in checkbox selection

**Changed**

- Reduced layout jitter in the terminal when the spinner appears and disappears during streaming
- Removed misleading Anthropic API pricing from model selector for third-party provider (Bedrock, Vertex, Foundry) users

**Improved**

- Improved system prompts to more clearly guide the model toward using dedicated tools (Read, Edit, Glob, Grep) instead of bash equivalents (`cat`, `sed`, `grep`, `find`), reducing unnecessary bash command usage
- Improved PDF and request size error messages to show actual limits (100 pages, 20MB)

Show 5 bug fixes

- Fixed PDF too large errors permanently locking up sessions, requiring users to start a new conversation
- Fixed bash commands incorrectly reporting failure with “Read-only file system” errors when sandbox mode was enabled
- Fixed a crash that made sessions unusable after entering plan mode when project config in `~/.claude.json` was missing default fields
- Fixed `temperatureOverride` being silently ignored in the streaming API path, causing all streaming requests to use the default temperature (1) regardless of the configured override
- Fixed LSP shutdown/exit compatibility with strict language servers that reject null params

[​](#2-1-30)

2.1.30

February 3, 2026

**Added**

- Added `pages` parameter to the Read tool for PDFs, allowing specific page ranges to be read (e.g., `pages: "1-5"`). Large PDFs (\>10 pages) now return a lightweight reference when `@` mentioned instead of being inlined into context.
- Added pre-configured OAuth client credentials for MCP servers that don’t support Dynamic Client Registration (e.g., Slack). Use `--client-id` and `--client-secret` with `claude mcp add`.
- Added `/debug` for Claude to help troubleshoot the current session
- Added support for additional `git log` and `git show` flags in read-only mode (e.g., `--topo-order`, `--cherry-pick`, `--format`, `--raw`)
- Added token count, tool uses, and duration metrics to Task tool results
- Added reduced motion mode to the config
- \[VSCode\] Added multiline input support to the “Other” text input in question dialogs (use Shift+Enter for new lines)

**Changed**

- Changed `/model` to execute immediately instead of being queued

**Improved**

- Improved memory usage for `--resume` (68% reduction for users with many sessions) by replacing the session index with lightweight stat-based loading and progressive enrichment
- Improved `TaskStop` tool to display the stopped command/task description in the result line instead of a generic “Task stopped” message

Show 9 bug fixes

- Fixed phantom “(no content)” text blocks appearing in API conversation history, reducing token waste and potential model confusion
- Fixed prompt cache not correctly invalidating when tool descriptions or input schemas changed, only when tool names changed
- Fixed 400 errors that could occur after running `/login` when the conversation contained thinking blocks
- Fixed a hang when resuming sessions with corrupted transcript files containing `parentUuid` cycles
- Fixed rate limit message showing incorrect “/upgrade” suggestion for Max 20x users when extra-usage is unavailable
- Fixed permission dialogs stealing focus while actively typing
- Fixed subagents not being able to access SDK-provided MCP tools because they were not synced to the shared application state
- Fixed a regression where Windows users with a `.bashrc` file could not run bash commands
- \[VSCode\] Fixed duplicate sessions appearing in the session list when starting a new conversation

[​](#2-1-29)

2.1.29

January 31, 2026

- Fixed startup performance issues when resuming sessions that have `saved_hook_context`

[​](#2-1-27)

2.1.27

January 30, 2026

- Added tool call failures and denials to debug logs
- Fixed context management validation error for gateway users, ensuring `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1` avoids the error
- Added `--from-pr` flag to resume sessions linked to a specific GitHub PR number or URL
- Sessions are now automatically linked to PRs when created via `gh pr create`
- Fixed /context command not displaying colored output
- Fixed status bar duplicating background task indicator when PR status was shown
- Windows: Fixed bash command execution failing for users with `.bashrc` files
- Windows: Fixed console windows flashing when spawning child processes
- VSCode: Fixed OAuth token expiration causing 401 errors after extended sessions

[​](#2-1-25)

2.1.25

January 29, 2026

- Fixed beta header validation error for gateway users on Bedrock and Vertex, ensuring `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1` avoids the error

[​](#2-1-23)

2.1.23

January 29, 2026

**Added**

- Added customizable spinner verbs setting (`spinnerVerbs`)

**Changed**

- Changed Bash commands to show timeout duration alongside elapsed time
- Changed merged pull requests to show a purple status indicator in the prompt footer

**Improved**

- Improved terminal rendering performance with optimized screen data layout

Show 7 bug fixes

- Fixed mTLS and proxy connectivity for users behind corporate proxies or using client certificates
- Fixed per-user temp directory isolation to prevent permission conflicts on shared systems
- Fixed a race condition that could cause 400 errors when prompt caching scope was enabled
- Fixed pending async hooks not being cancelled when headless streaming sessions ended
- Fixed tab completion not updating the input field when accepting a suggestion
- Fixed ripgrep search timeouts silently returning empty results instead of reporting errors
- \[IDE\] Fixed model options displaying incorrect region strings for Bedrock users in headless mode

[​](#2-1-22)

2.1.22

January 28, 2026

- Fixed structured outputs for non-interactive (-p) mode

[​](#2-1-21)

2.1.21

January 28, 2026

**Added**

- Added support for full-width (zenkaku) number input from Japanese IME in option selection prompts
- \[VSCode\] Added automatic Python virtual environment activation, ensuring `python` and `pip` commands use the correct interpreter (configurable via `claudeCode.usePythonEnvironment` setting)

**Improved**

- Improved read/search progress indicators to show “Reading…” while in progress and “Read” when complete
- Improved Claude to prefer file operation tools (Read, Edit, Write) over bash equivalents (cat, sed, awk)

Show 6 bug fixes

- Fixed shell completion cache files being truncated on exit
- Fixed API errors when resuming sessions that were interrupted during tool execution
- Fixed auto-compact triggering too early on models with large output token limits
- Fixed task IDs potentially being reused after deletion
- Fixed file search not working in VS Code extension on Windows
- \[VSCode\] Fixed message action buttons having incorrect background colors

[​](#2-1-20)

2.1.20

January 27, 2026

**Added**

- Added arrow key history navigation in vim normal mode when cursor cannot move further
- Added external editor shortcut (Ctrl+G) to the help menu for better discoverability
- Added PR review status indicator to the prompt footer, showing the current branch’s PR state (approved, changes requested, pending, or draft) as a colored dot with a clickable link
- Added support for loading `CLAUDE.md` files from additional directories specified via `--add-dir` flag (requires setting `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1`)
- Added ability to delete tasks via the `TaskUpdate` tool

**Changed**

- Changed collapsed read/search groups to show present tense (“Reading”, “Searching for”) while in progress, and past tense (“Read”, “Searched for”) when complete
- Changed `ToolSearch` results to appear as a brief notification instead of inline in the conversation
- Changed the `/commit-push-pr` skill to automatically post PR URLs to Slack channels when configured via MCP tools
- Changed the `/copy` command to be available to all users
- Changed background agents to prompt for tool permissions before launching
- Changed permission rules like `Bash(*)` to be accepted and treated as equivalent to `Bash`
- Changed config backups to be timestamped and rotated (keeping 5 most recent) to prevent data loss

**Improved**

- Improved `/sandbox` command UI to show dependency status with installation instructions when dependencies are missing
- Improved thinking status text with a subtle shimmer animation
- Improved task list to dynamically adjust visible items based on terminal height
- Improved fork conversation hint to show how to resume the original session

Show 12 bug fixes

- Fixed session compaction issues that could cause resume to load full history instead of the compact summary
- Fixed agents sometimes ignoring user messages sent while actively working on a task
- Fixed wide character (emoji, CJK) rendering artifacts where trailing columns were not cleared when replaced by narrower characters
- Fixed JSON parsing errors when MCP tool responses contain special Unicode characters
- Fixed up/down arrow keys in multi-line and wrapped text input to prioritize cursor movement over history navigation
- Fixed draft prompt being lost when pressing UP arrow to navigate command history
- Fixed ghost text flickering when typing slash commands mid-input
- Fixed marketplace source removal not properly deleting settings
- Fixed duplicate output in some commands like `/context`
- Fixed task list sometimes showing outside the main conversation view
- Fixed syntax highlighting for diffs occurring within multiline constructs like Python docstrings
- Fixed crashes when cancelling tool use

[​](#2-1-19)

2.1.19

January 23, 2026

**Added**

- Added env var `CLAUDE_CODE_ENABLE_TASKS`, set to `false` to keep the old system temporarily
- Added shorthand `$0`, `$1`, etc. for accessing individual arguments in custom commands
- \[SDK\] Added replay of `queued_command` attachment messages as `SDKUserMessageReplay` events when `replayUserMessages` is enabled

**Changed**

- Changed skills without additional permissions or hooks to be allowed without requiring approval
- Changed indexed argument syntax from `$ARGUMENTS.0` to `$ARGUMENTS[0]` (bracket syntax)
- \[VSCode\] Enabled session forking and rewind functionality for all users

Show 8 bug fixes

- Fixed crashes on processors without AVX instruction support
- Fixed dangling Claude Code processes when terminal is closed by catching EIO errors from `process.exit()` and using SIGKILL as fallback
- Fixed `/rename` and `/tag` not updating the correct session when resuming from a different directory (e.g., git worktrees)
- Fixed resuming sessions by custom title not working when run from a different directory
- Fixed pasted text content being lost when using prompt stash (Ctrl+S) and restore
- Fixed agent list displaying “Sonnet (default)” instead of “Inherit (default)” for agents without an explicit model setting
- Fixed backgrounded hook commands not returning early, potentially causing the session to wait on a process that was intentionally backgrounded
- Fixed file write preview omitting empty lines

[​](#2-1-18)

2.1.18

January 23, 2026

- Added customizable keyboard shortcuts. Configure keybindings per context, create chord sequences, and personalize your workflow. Run `/keybindings` to get started. Learn more at [https://code.claude.com/docs/en/keybindings](keybindings.md)

[​](#2-1-17)

2.1.17

January 22, 2026

- Fixed crashes on processors without AVX instruction support

[​](#2-1-16)

2.1.16

January 22, 2026

- Added new task management system, including new capabilities like dependency tracking
- \[VSCode\] Added native plugin management support
- \[VSCode\] Added ability for OAuth users to browse and resume remote Claude sessions from the Sessions dialog
- Fixed out-of-memory crashes when resuming sessions with heavy subagent usage
- Fixed an issue where the “context remaining” warning was not hidden after running `/compact`
- Fixed session titles on the resume screen not respecting the user’s language setting
- \[IDE\] Fixed a race condition on Windows where the Claude Code sidebar view container would not appear on start

[​](#2-1-15)

2.1.15

January 21, 2026

- Added deprecation notification for npm installations - run `claude install` or see [https://code.claude.com/docs/en/setup](../01-Getting-Started/setup.md) for more options
- Improved UI rendering performance with React Compiler
- Fixed the “Context left until auto-compact” warning not disappearing after running `/compact`
- Fixed MCP stdio server timeout not killing child process, which could cause UI freezes

[​](#2-1-14)

2.1.14

January 20, 2026

**Added**

- Added history-based autocomplete in bash mode (`!`) - type a partial command and press Tab to complete from your bash command history
- Added search to installed plugins list - type to filter by name or description
- Added support for pinning plugins to specific git commit SHAs, allowing marketplace entries to install exact versions
- \[VSCode\] Added `/usage` command to display current plan usage

**Improved**

- Improved backspace to delete pasted text as a single token instead of one character at a time

Show 11 bug fixes

- Fixed a regression where the context window blocking limit was calculated too aggressively, blocking users at ~65% context usage instead of the intended ~98%
- Fixed memory issues that could cause crashes when running parallel subagents
- Fixed memory leak in long-running sessions where stream resources were not cleaned up after shell commands completed
- Fixed `@` symbol incorrectly triggering file autocomplete suggestions in bash mode
- Fixed `@`-mention menu folder click behavior to navigate into directories instead of selecting them
- Fixed `/feedback` command generating invalid GitHub issue URLs when description is very long
- Fixed `/context` command to show the same token count and percentage as the status line in verbose mode
- Fixed an issue where `/config`, `/context`, `/model`, and `/todos` command overlays could close unexpectedly
- Fixed slash command autocomplete selecting wrong command when typing similar commands (e.g., `/context` vs `/compact`)
- Fixed inconsistent back navigation in plugin marketplace when only one marketplace is configured
- Fixed iTerm2 progress bar not clearing properly on exit, preventing lingering indicators and bell sounds

[​](#2-1-12)

2.1.12

January 17, 2026

- Fixed message rendering bug

[​](#2-1-11)

2.1.11

January 17, 2026

- Fixed excessive MCP connection requests for HTTP/SSE transports

[​](#2-1-10)

2.1.10

January 17, 2026

- Added new `Setup` hook event that can be triggered via `--init`, `--init-only`, or `--maintenance` CLI flags for repository setup and maintenance operations
- Added keyboard shortcut ‘c’ to copy OAuth URL when browser doesn’t open automatically during login
- Fixed a crash when running bash commands containing heredocs with JavaScript template literals like `${index + 1}`
- Improved startup to capture keystrokes typed before the REPL is fully ready
- Improved file suggestions to show as removable attachments instead of inserting text when accepted
- \[VSCode\] Added install count display to plugin listings
- \[VSCode\] Added trust warning when installing plugins

[​](#2-1-9)

2.1.9

January 16, 2026

- Added `auto:N` syntax for configuring the MCP tool search auto-enable threshold, where N is the context window percentage (0-100)
- Added `plansDirectory` setting to customize where plan files are stored
- Added external editor support (Ctrl+G) in AskUserQuestion “Other” input field
- Added session URL attribution to commits and PRs created from web sessions
- Added support for `PreToolUse` hooks to return `additionalContext` to the model
- Added `${CLAUDE_SESSION_ID}` string substitution for skills to access the current session ID
- Fixed long sessions with parallel tool calls failing with an API error about orphan tool_result blocks
- Fixed MCP server reconnection hanging when cached connection promise never resolves
- Fixed Ctrl+Z suspend not working in terminals using Kitty keyboard protocol (Ghostty, iTerm2, kitty, WezTerm)

[​](#2-1-7)

2.1.7

January 14, 2026

**Added**

- Added `showTurnDuration` setting to hide turn duration messages (e.g., “Cooked for 1m 6s”)
- Added ability to provide feedback when accepting permission prompts
- Added inline display of agent’s final response in task notifications, making it easier to see results without reading the full transcript file

**Changed**

- Enabled MCP tool search auto mode by default for all users. When MCP tool descriptions exceed 10% of the context window, they are automatically deferred and discovered via the MCPSearch tool instead of being loaded upfront. This reduces context usage for users with many MCP tools configured. Users can disable this by adding `MCPSearch` to `disallowedTools` in their settings.
- Changed OAuth and API Console URLs from console.anthropic.com to platform.claude.com

**Improved**

- Improved typing responsiveness by reducing memory allocation overhead in terminal rendering

Show 9 bug fixes

- Fixed security vulnerability where wildcard permission rules could match compound commands containing shell operators
- Fixed false “file modified” errors on Windows when cloud sync tools, antivirus scanners, or Git touch file timestamps without changing content
- Fixed orphaned tool_result errors when sibling tools fail during streaming execution
- Fixed context window blocking limit being calculated using the full context window instead of the effective context window (which reserves space for max output tokens)
- Fixed spinner briefly flashing when running local slash commands like `/model` or `/theme`
- Fixed terminal title animation jitter by using fixed-width braille characters
- Fixed plugins with git submodules not being fully initialized when installed
- Fixed bash commands failing on Windows when temp directory paths contained characters like `t` or `n` that were misinterpreted as escape sequences
- \[VSCode\] Fixed `claudeProcessWrapper` setting passing the wrapper path instead of the Claude binary path

[​](#2-1-6)

2.1.6

January 13, 2026

**Added**

- Added search functionality to `/config` command for quickly filtering settings
- Added Updates section to `/doctor` showing auto-update channel and available npm versions (stable/latest)
- Added date range filtering to `/stats` command - press `r` to cycle between Last 7 days, Last 30 days, and All time
- Added automatic discovery of skills from nested `.claude/skills` directories when working with files in subdirectories
- Added `context_window.used_percentage` and `context_window.remaining_percentage` fields to status line input for easier context window display
- Added an error display when the editor fails during Ctrl+G

**Changed**

- Updated “Help improve Claude” setting fetch to refresh OAuth and retry when it fails due to a stale OAuth token
- Changed task notification display to cap at 3 lines with overflow summary when multiple background tasks complete simultaneously
- Changed terminal title to “Claude Code” on startup for better window identification
- Removed ability to @-mention MCP servers to enable/disable - use `/mcp enable <name>` instead

**Improved**

- Improved the external CLAUDE.md imports approval dialog to show which files are being imported and from where
- Improved the `/tasks` dialog to go directly to task details when there’s only one background task running
- Improved @ autocomplete with icons for different suggestion types and single-line formatting

Show 12 bug fixes

- Fixed permission bypass via shell line continuation that could allow blocked commands to execute
- Fixed false “File has been unexpectedly modified” errors when file watchers touch files without changing content
- Fixed text styling (bold, colors) getting progressively misaligned in multi-line responses
- Fixed the feedback panel closing unexpectedly when typing ‘n’ in the description field
- Fixed rate limit warning appearing at low usage after weekly reset (now requires 70% usage)
- Fixed rate limit options menu incorrectly auto-opening when resuming a previous session
- Fixed numpad keys outputting escape sequences instead of characters in Kitty keyboard protocol terminals
- Fixed Option+Return not inserting newlines in Kitty keyboard protocol terminals
- Fixed corrupted config backup files accumulating in the home directory (now only one backup is created per config file)
- Fixed `mcp list` and `mcp get` commands leaving orphaned MCP server processes
- Fixed visual artifacts in ink2 mode when nodes become hidden via `display:none`
- \[VSCode\] Fixed usage indicator not updating after manual compact

[​](#2-1-5)

2.1.5

January 12, 2026

- Added `CLAUDE_CODE_TMPDIR` environment variable to override the temp directory used for internal temp files, useful for environments with custom temp directory requirements

[​](#2-1-4)

2.1.4

January 11, 2026

- Added `CLAUDE_CODE_DISABLE_BACKGROUND_TASKS` environment variable to disable all background task functionality including auto-backgrounding and the Ctrl+B shortcut
- Fixed “Help improve Claude” setting fetch to refresh OAuth and retry when it fails due to a stale OAuth token

[​](#2-1-3)

2.1.3

January 9, 2026

**Added**

- Added release channel (`stable` or `latest`) toggle to `/config`
- Added detection and warnings for unreachable permission rules, with warnings in `/doctor` and after saving rules that include the source of each rule and actionable fix guidance
- \[VSCode\] Added clickable destination selector for permission requests, allowing you to choose where settings are saved (this project, all projects, shared with team, or session only)

**Changed**

- Merged slash commands and skills, simplifying the mental model with no change in behavior
- Changed tool hook execution timeout from 60 seconds to 10 minutes

**Improved**

- Improved terminal rendering stability by preventing uncontrolled writes from corrupting cursor state
- Improved slash command suggestion readability by truncating long descriptions to 2 lines

Show 6 bug fixes

- Fixed plan files persisting across `/clear` commands, now ensuring a fresh plan file is used after clearing a conversation
- Fixed false skill duplicate detection on filesystems with large inodes (e.g., ExFAT) by using 64-bit precision for inode values
- Fixed mismatch between background task count in status bar and items shown in tasks dialog
- Fixed sub-agents using the wrong model during conversation compaction
- Fixed web search in sub-agents using incorrect model
- Fixed trust dialog acceptance when running from the home directory not enabling trust-requiring features like hooks during the session

[​](#2-1-2)

2.1.2

January 9, 2026

**Added**

- Added source path metadata to images dragged onto the terminal, helping Claude understand where images originated
- Added clickable hyperlinks for file paths in tool output in terminals that support OSC 8 (like iTerm)
- Added support for Windows Package Manager (winget) installations with automatic detection and update instructions
- Added Shift+Tab keyboard shortcut in plan mode to quickly select “auto-accept edits” option
- Added `FORCE_AUTOUPDATE_PLUGINS` environment variable to allow plugin autoupdate even when the main auto-updater is disabled
- Added `agent_type` to SessionStart hook input, populated if `--agent` is specified

**Changed**

- Changed large bash command outputs to be saved to disk instead of truncated, allowing Claude to read the full content
- Changed large tool outputs to be persisted to disk instead of truncated, providing full output access via file references
- Changed `/plugins` installed tab to unify plugins and MCPs with scope-based grouping
- Deprecated Windows managed settings path `C:\ProgramData\ClaudeCode\managed-settings.json` - administrators should migrate to `C:\Program Files\ClaudeCode\managed-settings.json`
- \[SDK\] Changed minimum zod peer dependency to ^4.0.0

**Improved**

- Improved Option-as-Meta hint on macOS to show terminal-specific instructions for native CSIu terminals like iTerm2, Kitty, and WezTerm
- Improved error message when pasting images over SSH to suggest using `scp` instead of the unhelpful clipboard shortcut hint
- Improved permission explainer to not flag routine dev workflows (git fetch/rebase, npm install, tests, PRs) as medium risk

Show 8 bug fixes

- Fixed a command injection vulnerability in bash command processing where malformed input could execute arbitrary commands
- Fixed a memory leak where tree-sitter parse trees were not being freed, causing WASM memory to grow unbounded over long sessions
- Fixed binary files (images, PDFs, etc.) being accidentally included in memory when using `@include` directives in CLAUDE.md files
- Fixed updates incorrectly claiming another installation is in progress
- Fixed crash when socket files exist in watched directories (defense-in-depth for EOPNOTSUPP errors)
- Fixed remote session URL and teleport being broken when using `/tasks` command
- Fixed MCP tool names being exposed in analytics events by sanitizing user-specific server configurations
- \[VSCode\] Fixed usage display not updating after manual compact

[​](#2-1-0)

2.1.0

January 7, 2026

**Added**

- Added automatic skill hot-reload - skills created or modified in `~/.claude/skills` or `.claude/skills` are now immediately available without restarting the session
- Added support for running skills and slash commands in a forked sub-agent context using `context: fork` in skill frontmatter
- Added support for `agent` field in skills to specify agent type for execution
- Added `language` setting to configure Claude’s response language (e.g., language: “japanese”)
- Added `respectGitignore` support in `settings.json` for per-project control over @-mention file picker behavior
- Added `IS_DEMO` environment variable to hide email and organization from the UI, useful for streaming or recording sessions
- Added wildcard pattern matching for Bash tool permissions using `*` at any position in rules (e.g., `Bash(npm *)`, `Bash(* install)`, `Bash(git * main)`)
- Added unified Ctrl+B backgrounding for both bash commands and agents - pressing Ctrl+B now backgrounds all running foreground tasks simultaneously
- Added support for MCP `list_changed` notifications, allowing MCP servers to dynamically update their available tools, prompts, and resources without requiring reconnection
- Added `/teleport` and `/remote-env` slash commands for claude.ai subscribers, allowing them to resume and configure remote sessions
- Added support for disabling specific agents using `Task(AgentName)` syntax in settings.json permissions or the `--disallowedTools` CLI flag
- Added hooks support to agent frontmatter, allowing agents to define PreToolUse, PostToolUse, and Stop hooks scoped to the agent’s lifecycle
- Added hooks support for skill and slash command frontmatter
- Added new Vim motions: `;` and `,` to repeat f/F/t/T motions, `y` operator for yank with `yy`/`Y`, `p`/`P` for paste, text objects (`iw`, `aw`, `iW`, `aW`, `i"`, `a"`, `i'`, `a'`, `i(`, `a(`, `i[`, `a[`, `i{`, `a{`), `>>` and `<<` for indent/dedent, and `J` to join lines
- Added `/plan` command shortcut to enable plan mode directly from the prompt
- Added slash command autocomplete support when `/` appears anywhere in input, not just at the beginning
- Added `--tools` flag support in interactive mode to restrict which built-in tools Claude can use during interactive sessions
- Added `CLAUDE_CODE_FILE_READ_MAX_OUTPUT_TOKENS` environment variable to override the default file read token limit
- Added support for `once: true` config for hooks
- Added support for YAML-style lists in frontmatter `allowed-tools` field for cleaner skill declarations
- Added support for prompt and agent hook types from plugins (previously only command hooks were supported)
- Added Cmd+V support for image paste in iTerm2 (maps to Ctrl+V)
- Added left/right arrow key navigation for cycling through tabs in dialogs
- Added real-time thinking block display in Ctrl+O transcript mode
- Added filepath to full output in background bash task details dialog
- Added Skills as a separate category in the context visualization
- \[VSCode\] Added currently selected model name to the context menu
- \[VSCode\] Added descriptive labels on auto-accept permission button (e.g., “Yes, allow npm for this project” instead of “Yes, and don’t ask again”)

**Changed**

- Changed Shift+Enter to work out of the box in iTerm2, WezTerm, Ghostty, and Kitty without modifying terminal configs
- Reduced permission prompts for complex bash commands
- Multiple optimizations to improve startup performance
- Updated Atlassian MCP integration to use a more reliable default configuration (streamable HTTP)
- Changed “Interrupted” message color from red to grey for a less alarming appearance
- Removed permission prompt when entering plan mode - users can now enter plan mode without approval
- Removed underline styling from image reference links
- \[SDK\] Changed minimum zod peer dependency to ^4.0.0

Show 19 improvements

- Improved CLI help output to display options and subcommands in alphabetical order for easier navigation
- Improved terminal rendering performance when using native installer or Bun, especially for text with emoji, ANSI codes, and Unicode characters
- Improved performance when reading Jupyter notebooks with many cells
- Improved reliability for piped input like `cat refactor.md | claude`
- Improved reliability for AskQuestion tool
- Improved sed in-place edit commands to render as file edits with diff preview
- Improved Claude to automatically continue when response is cut off due to output token limit, instead of showing an error message
- Improved compaction reliability
- Improved subagents (Task tool) to continue working after permission denial, allowing them to try alternative approaches
- Improved skills to show progress while executing, displaying tool uses as they happen
- Improved skills from `/skills/` directories to be visible in the slash command menu by default (opt-out with `user-invocable: false` in frontmatter)
- Improved skill suggestions to prioritize recently and frequently used skills
- Improved spinner feedback when waiting for the first response token
- Improved token count display in spinner to include tokens from background agents
- Improved incremental output for async agents to give the main thread more control and visibility
- Improved permission prompt UX with Tab hint moved to footer, cleaner Yes/No input labels with contextual placeholders
- Improved the Claude in Chrome notification with shortened help text and persistent display until dismissed
- Improved macOS screenshot paste reliability with TIFF format support
- Improved `/stats` output

Show 54 bug fixes

- Fixed security issue where sensitive data (OAuth tokens, API keys, passwords) could be exposed in debug logs
- Fixed files and skills not being properly discovered when resuming sessions with `-c` or `--resume`
- Fixed pasted content being lost when replaying prompts from history using up arrow or Ctrl+R search
- Fixed Esc key with queued prompts to only move them to input without canceling the running task
- Fixed command search to prioritize exact and prefix matches on command names over fuzzy matches in descriptions
- Fixed PreToolUse hooks to allow `updatedInput` when returning `ask` permission decision, enabling hooks to act as middleware while still requesting user consent
- Fixed plugin path resolution for file-based marketplace sources
- Fixed LSP tool being incorrectly enabled when no LSP servers were configured
- Fixed background tasks failing with “git repository not found” error for repositories with dots in their names
- Fixed Claude in Chrome support for WSL environments
- Fixed Windows native installer silently failing when executable creation fails
- Fixed OAuth token refresh not triggering when server reports token expired but local expiration check disagrees
- Fixed session persistence getting stuck after transient server errors by recovering from 409 conflicts when the entry was actually stored
- Fixed session resume failures caused by orphaned tool results during concurrent tool execution
- Fixed a race condition where stale OAuth tokens could be read from the keychain cache during concurrent token refresh attempts
- Fixed AWS Bedrock subagents not inheriting EU/APAC cross-region inference model configuration, causing 403 errors when IAM permissions are scoped to specific regions
- Fixed API context overflow when background tasks produce large output by truncating to 30K chars with file path reference
- Fixed a hang when reading FIFO files by skipping symlink resolution for special file types
- Fixed terminal keyboard mode not being reset on exit in Ghostty, iTerm2, Kitty, and WezTerm
- Fixed Alt+B and Alt+F (word navigation) not working in iTerm2, Ghostty, Kitty, and WezTerm
- Fixed `${CLAUDE_PLUGIN_ROOT}` not being substituted in plugin `allowed-tools` frontmatter, which caused tools to incorrectly require approval
- Fixed files created by the Write tool using hardcoded 0o600 permissions instead of respecting the system umask
- Fixed commands with `$()` command substitution failing with parse errors
- Fixed multi-line bash commands with backslash continuations being incorrectly split and flagged for permissions
- Fixed bash command prefix extraction to correctly identify subcommands after global options (e.g., `git -C /path log` now correctly matches `Bash(git log:*)` rules)
- Fixed slash commands passed as CLI arguments (e.g., `claude /context`) not being executed properly
- Fixed pressing Enter after Tab-completing a slash command selecting a different command instead of submitting the completed one
- Fixed slash command argument hint flickering and inconsistent display when typing commands with arguments
- Fixed Claude sometimes redundantly invoking the Skill tool when running slash commands directly
- Fixed skill token estimates in `/context` to accurately reflect frontmatter-only loading
- Fixed subagents sometimes not inheriting the parent’s model by default
- Fixed model picker showing incorrect selection for Bedrock/Vertex users using `--model haiku`
- Fixed duplicate Bash commands appearing in permission request option labels
- Fixed noisy output when background tasks complete - now shows clean completion message instead of raw output
- Fixed background task completion notifications to appear proactively with bullet point
- Fixed forked slash commands showing “AbortError” instead of “Interrupted” message when cancelled
- Fixed cursor disappearing after dismissing permission dialogs
- Fixed `/hooks` menu selecting wrong hook type when scrolling to a different option
- Fixed images in queued prompts showing as “\[object Object\]” when pressing Esc to cancel
- Fixed images being silently dropped when queueing messages while backgrounding a task
- Fixed large pasted images failing with “Image was too large” error
- Fixed extra blank lines in multiline prompts containing CJK characters (Japanese, Chinese, Korean)
- Fixed ultrathink keyword highlighting being applied to wrong characters when user prompt text wraps to multiple lines
- Fixed collapsed “Reading X files…” indicator incorrectly switching to past tense when thinking blocks appear mid-stream
- Fixed Bash read commands (like `ls` and `cat`) not being counted in collapsed read/search groups, causing groups to incorrectly show “Read 0 files”
- Fixed spinner token counter to properly accumulate tokens from subagents during execution
- Fixed memory leak in git diff parsing where sliced strings retained large parent strings
- Fixed race condition where LSP tool could return “no server available” during startup
- Fixed feedback submission hanging indefinitely when network requests timeout
- Fixed search mode in plugin discovery and log selector views exiting when pressing up arrow
- Fixed hook success message showing trailing colon when hook has no output
- \[VSCode\] Fixed paragraph breaks not rendering in markdown content
- \[VSCode\] Fixed scrolling in the extension inadvertently scrolling the parent iframe
- \[Windows\] Fixed issue with improper rendering

[​](#2-0-76)

2.0.76

January 7, 2026

- Fixed issue with macOS code-sign warning when using Claude in Chrome integration

[​](#2-0-75)

2.0.75

January 7, 2026

- Minor bugfixes

[​](#2-0-74)

2.0.74

December 19, 2025

**Added**

- Added LSP (Language Server Protocol) tool for code intelligence features like go-to-definition, find references, and hover documentation
- Added `/terminal-setup` support for Kitty, Alacritty, Zed, and Warp terminals
- Added ctrl+t shortcut in `/theme` to toggle syntax highlighting on/off
- Added syntax highlighting info to theme picker
- Added guidance for macOS users when Alt shortcuts fail due to terminal configuration
- \[VSCode\] Added gift tag pictogram for year-end promotion message

**Improved**

- Improved `/context` command visualization with grouped skills and agents by source, slash commands, and sorted token count

Show 6 bug fixes

- Fixed skill `allowed-tools` not being applied to tools invoked by the skill
- Fixed Opus 4.5 tip incorrectly showing when user was already using Opus
- Fixed a potential crash when syntax highlighting isn’t initialized correctly
- Fixed visual bug in `/plugins discover` where list selection indicator showed while search box was focused
- Fixed macOS keyboard shortcuts to display ‘opt’ instead of ‘alt’
- \[Windows\] Fixed issue with improper rendering

[​](#2-0-73)

2.0.73

December 19, 2025

- Added clickable `[Image #N]` links that open attached images in the default viewer
- Added alt-y yank-pop to cycle through kill ring history after ctrl-y yank
- Added search filtering to the plugin discover screen (type to filter by name, description, or marketplace)
- Added support for custom session IDs when forking sessions with `--session-id` combined with `--resume` or `--continue` and `--fork-session`
- Fixed slow input history cycling and race condition that could overwrite text after message submission
- Improved `/theme` command to open theme picker directly
- Improved theme picker UI
- Improved search UX across resume session, permissions, and plugins screens with a unified SearchBox component
- \[VSCode\] Added tab icon badges showing pending permissions (blue) and unread completions (orange)

[​](#2-0-72)

2.0.72

December 17, 2025

**Added**

- Added Claude in Chrome (Beta) feature that works with the Chrome extension ([https://claude.ai/chrome](https://claude.ai/chrome)) to let you control your browser directly from Claude Code
- Added scannable QR code to mobile app tip for quick app downloads
- Added loading indicator when resuming conversations for better feedback

**Changed**

- Reduced terminal flickering
- Changed thinking toggle from Tab to Alt+T to avoid accidental triggers

**Improved**

- Improved @ mention file suggestion speed (~3× faster in git repositories)
- Improved file suggestion performance in repos with `.ignore` or `.rgignore` files
- Improved settings validation errors to be more prominent

**Fixed**

- Fixed `/context` command not respecting custom system prompts in non-interactive mode
- Fixed order of consecutive Ctrl+K lines when pasting with Ctrl+Y

[​](#2-0-71)

2.0.71

December 16, 2025

- Added /config toggle to enable/disable prompt suggestions
- Added `/settings` as an alias for the `/config` command
- Fixed @ file reference suggestions incorrectly triggering when cursor is in the middle of a path
- Fixed MCP servers from `.mcp.json` not loading when using `--dangerously-skip-permissions`
- Fixed permission rules incorrectly rejecting valid bash commands containing shell glob patterns (e.g., `ls *.txt`, `for f in *.png`)
- Bedrock: Environment variable `ANTHROPIC_BEDROCK_BASE_URL` is now respected for token counting and inference profile listing
- New syntax highlighting engine for native build

[​](#2-0-70)

2.0.70

December 15, 2025

**Added**

- Added Enter key to accept and submit prompt suggestions immediately (tab still accepts for editing)
- Added wildcard syntax `mcp__server__*` for MCP tool permissions to allow or deny all tools from a server
- Added auto-update toggle for plugin marketplaces, allowing per-marketplace control over automatic updates
- Added `current_usage` field to status line input, enabling accurate context window percentage calculations

**Changed**

- Removed \# shortcut for quick memory entry (tell Claude to edit your CLAUDE.md instead)

**Improved**

- Improved memory usage by 3x for large conversations
- Improved resolution of stats screenshots copied to clipboard (Ctrl+S) for crisper images
- Improve UI for file creation permission dialog

**Fixed**

- Fixed input being cleared when processing queued commands while the user was typing
- Fixed prompt suggestions replacing typed input when pressing Tab
- Fixed diff view not updating when terminal is resized
- Fix thinking mode toggle in /config not persisting correctly

[​](#2-0-69)

2.0.69

December 13, 2025

- Minor bugfixes

[​](#2-0-68)

2.0.68

December 12, 2025

- Fixed IME (Input Method Editor) support for languages like Chinese, Japanese, and Korean by correctly positioning the composition window at the cursor
- Fixed a bug where disallowed MCP tools were visible to the model
- Fixed an issue where steering messages could be lost while a subagent is working
- Fixed Option+Arrow word navigation treating entire CJK (Chinese, Japanese, Korean) text sequences as a single word instead of navigating by word boundaries
- Improved plan mode exit UX: show simplified yes/no dialog when exiting with empty or missing plan instead of throwing an error
- Add support for enterprise managed settings. Contact your Anthropic account team to enable this feature.

[​](#2-0-67)

2.0.67

December 12, 2025

**Added**

- Added search functionality to `/permissions` command with `/` keyboard shortcut for filtering rules by tool name

**Changed**

- Thinking mode is now enabled by default for Opus 4.5
- Thinking mode configuration has moved to /config
- Show reason why autoupdater is disabled in `/doctor`

Show 7 bug fixes

- Fixed false “Another process is currently updating Claude” error when running `claude update` while another instance is already on the latest version
- Fixed MCP servers from `.mcp.json` being stuck in pending state when running in non-interactive mode (`-p` flag or piped input)
- Fixed scroll position resetting after deleting a permission rule in `/permissions`
- Fixed word deletion (opt+delete) and word navigation (opt+arrow) not working correctly with non-Latin text such as Cyrillic, Greek, Arabic, Hebrew, Thai, and Chinese
- Fixed `claude install --force` not bypassing stale lock files
- Fixed consecutive @~/ file references in CLAUDE.md being incorrectly parsed due to markdown strikethrough interference
- Windows: Fixed plugin MCP servers failing due to colons in log directory paths

[​](#2-0-65)

2.0.65

December 11, 2025

- Added ability to switch models while writing a prompt using alt+p (linux, windows), option+p (macos).
- Added context window information to status line input
- Added `fileSuggestion` setting for custom `@` file search commands
- Added `CLAUDE_CODE_SHELL` environment variable to override automatic shell detection (useful when login shell differs from actual working shell)
- Fixed prompt not being saved to history when aborting a query with Escape
- Fixed Read tool image handling to identify format from bytes instead of file extension

[​](#2-0-64)

2.0.64

December 10, 2025

**Added**

- Added named session support: use `/rename` to name sessions, `/resume <name>` in REPL or `claude --resume <name>` from the terminal to resume them
- Added support for .claude/rules/\`. See [https://code.claude.com/docs/en/memory](memory.md) for details.
- Added image dimension metadata when images are resized, enabling accurate coordinate mappings for large images
- VSCode: Added copy-to-clipboard button on code blocks and bash tool inputs
- Bedrock: Add support for `aws login` AWS Management Console credentials

**Changed**

- Made auto-compacting instant
- Agents and bash commands can run asynchronously and send messages to wake up the main agent
- /stats now provides users with interesting CC stats, such as favorite model, usage graph, usage streak
- Unshipped AgentOutputTool and BashOutputTool, in favor of a new unified TaskOutputTool

**Improved**

- Improved `/resume` screen with grouped forked sessions and keyboard shortcuts for preview (P) and rename (R)
- Bedrock: Improve efficiency of token counting

**Fixed**

- Fixed auto-loading .env when using native installer
- Fixed `--system-prompt` being ignored when using `--continue` or `--resume` flags
- VSCode: Fixed extension not working on Windows ARM64 by falling back to x64 binary via emulation

[​](#2-0-62)

2.0.62

December 9, 2025

- Added “(Recommended)” indicator for multiple-choice questions, with the recommended option moved to the top of the list
- Added `attribution` setting to customize commit and PR bylines (deprecates `includeCoAuthoredBy`)
- Fixed duplicate slash commands appearing when ~/.claude is symlinked to a project directory
- Fixed slash command selection not working when multiple commands share the same name
- Fixed an issue where skill files inside symlinked skill directories could become circular symlinks
- Fixed running versions getting removed because lock file incorrectly going stale
- Fixed IDE diff tab not closing when rejecting file changes

[​](#2-0-61)

2.0.61

December 7, 2025

- Reverted VSCode support for multiple terminal clients due to responsiveness issues.

[​](#2-0-60)

2.0.60

December 6, 2025

- Added background agent support. Agents run in the background while you work
- Added —disable-slash-commands CLI flag to disable all slash commands
- Added model name to “Co-Authored-By” commit messages
- Enabled “/mcp enable \[server-name\]” or “/mcp disable \[server-name\]” to quickly toggle all servers
- Updated Fetch to skip summarization for pre-approved websites
- VSCode: Added support for multiple terminal clients connecting to the IDE server simultaneously

[​](#2-0-59)

2.0.59

December 4, 2025

- Added —agent CLI flag to override the agent setting for the current session
- Added `agent` setting to configure main thread with a specific agent’s system prompt, tool restrictions, and model
- VS Code: Fixed .claude.json config file being read from incorrect location

[​](#2-0-58)

2.0.58

December 3, 2025

- Pro users now have access to Opus 4.5 as part of their subscription!
- Fixed timer duration showing “11m 60s” instead of “12m 0s”
- Windows: Managed settings now prefer `C:\Program Files\ClaudeCode` if it exists. Support for `C:\ProgramData\ClaudeCode` will be removed in a future version.

[​](#2-0-57)

2.0.57

December 3, 2025

- Added feedback input when rejecting plans, allowing users to tell Claude what to change
- VSCode: Added streaming message support for real-time response display

[​](#2-0-56)

2.0.56

December 2, 2025

- Added setting to enable/disable terminal progress bar (OSC 9;4)
- VSCode Extension: Added support for VS Code’s secondary sidebar (VS Code 1.97+), allowing Claude Code to be displayed in the right sidebar while keeping the file explorer on the left. Requires setting sidebar as Preferred Location in the config.

[​](#2-0-55)

2.0.55

November 26, 2025

- Fixed proxy DNS resolution being forced on by default. Now opt-in via `CLAUDE_CODE_PROXY_RESOLVES_HOSTS=true` environment variable
- Fixed keyboard navigation becoming unresponsive when holding down arrow keys in memory location selector
- Improved AskUserQuestion tool to auto-submit single-select questions on the last question, eliminating the extra review screen for simple question flows
- Improved fuzzy matching for `@` file suggestions with faster, more accurate results

[​](#2-0-54)

2.0.54

November 26, 2025

- Hooks: Enable PermissionRequest hooks to process ‘always allow’ suggestions and apply permission updates
- Fix issue with excessive iTerm notifications

[​](#2-0-52)

2.0.52

November 24, 2025

- Fixed duplicate message display when starting Claude with a command line argument
- Fixed `/usage` command progress bars to fill up as usage increases (instead of showing remaining percentage)
- Fixed image pasting not working on Linux systems running Wayland (now falls back to wl-paste when xclip is unavailable)
- Permit some uses of `$!` in bash commands

[​](#2-0-51)

2.0.51

November 24, 2025

- Added Opus 4.5! [https://www.anthropic.com/news/claude-opus-4-5](../19-Reference/claude-opus-4-5.md)
- Introducing Claude Code for Desktop: [https://claude.com/download](https://claude.com/download)
- To give you room to try out our new model, we’ve updated usage limits for Claude Code users. See the Claude Opus 4.5 blog for full details
- Pro users can now purchase extra usage for access to Opus 4.5 in Claude Code
- Plan Mode now builds more precise plans and executes more thoroughly
- Usage limit notifications now easier to understand
- Switched `/usage` back to ”% used”
- Fixed handling of thinking errors
- Fixed performance regression

[​](#2-0-50)

2.0.50

November 21, 2025

- Fixed bug preventing calling MCP tools that have nested references in their input schemas
- Silenced a noisy but harmless error during upgrades
- Improved ultrathink text display
- Improved clarity of 5-hour session limit warning message

[​](#2-0-49)

2.0.49

November 21, 2025

- Added readline-style ctrl-y for pasting deleted text
- Improved clarity of usage limit warning message
- Fixed handling of subagent permissions

[​](#2-0-47)

2.0.47

November 19, 2025

- Improved error messages and validation for `claude --teleport`
- Improved error handling in `/usage`
- Fixed race condition with history entry not getting logged at exit
- Fixed Vertex AI configuration not being applied from `settings.json`

[​](#2-0-46)

2.0.46

November 19, 2025

- Fixed image files being reported with incorrect media type when format cannot be detected from metadata

[​](#2-0-45)

2.0.45

November 18, 2025

- Added support for Microsoft Foundry! See [https://code.claude.com/docs/en/azure-ai-foundry](https://code.claude.com/docs/en/azure-ai-foundry)
- Added `PermissionRequest` hook to automatically approve or deny tool permission requests with custom logic
- Send background tasks to Claude Code on the web by starting a message with `&`

[​](#2-0-43)

2.0.43

November 18, 2025

- Added `permissionMode` field for custom agents
- Added `tool_use_id` field to `PreToolUseHookInput` and `PostToolUseHookInput` types
- Added skills frontmatter field to declare skills to auto-load for subagents
- Added the `SubagentStart` hook event
- Fixed nested `CLAUDE.md` files not loading when @-mentioning files
- Fixed duplicate rendering of some messages in the UI
- Fixed some visual flickers
- Fixed NotebookEdit tool inserting cells at incorrect positions when cell IDs matched the pattern `cell-N`

[​](#2-0-42)

2.0.42

November 15, 2025

- Added `agent_id` and `agent_transcript_path` fields to `SubagentStop` hooks.

[​](#2-0-41)

2.0.41

November 14, 2025

**Added**

- Added `model` parameter to prompt-based stop hooks, allowing users to specify a custom model for hook evaluation
- Plugins: Added support for sharing and installing output styles

**Changed**

- ctrl-r history search landing on a slash command no longer cancels the search
- SDK: Support custom timeouts for hooks
- Allow more safe git commands to run without approval
- Teleporting a session from web will automatically set the upstream branch

Show 6 bug fixes

- Fixed slash commands from user settings being loaded twice, which could cause rendering issues
- Fixed incorrect labeling of user settings vs project settings in command descriptions
- Fixed crash when plugin command hooks timeout during execution
- Fixed: Bedrock users no longer see duplicate Opus entries in the /model picker when using `--model haiku`
- Fixed broken security documentation links in trust dialogs and onboarding
- Fixed issue where pressing ESC to close the diff modal would also interrupt the model

[​](#2-0-37)

2.0.37

November 11, 2025

- Fixed how idleness is computed for notifications
- Hooks: Added matcher values for Notification hook events
- Output Styles: Added `keep-coding-instructions` option to frontmatter

[​](#2-0-36)

2.0.36

November 7, 2025

- Fixed: DISABLE_AUTOUPDATER environment variable now properly disables package manager update notifications
- Fixed queued messages being incorrectly executed as bash commands
- Fixed input being lost when typing while a queued message is processed

[​](#2-0-35)

2.0.35

November 6, 2025

- Improve fuzzy search results when searching commands
- Improved VS Code extension to respect `chat.fontSize` and `chat.fontFamily` settings throughout the entire UI, and apply font changes immediately without requiring reload
- Added `CLAUDE_CODE_EXIT_AFTER_STOP_DELAY` environment variable to automatically exit SDK mode after a specified idle duration, useful for automated workflows and scripts
- Migrated `ignorePatterns` from project config to deny permissions in the localSettings.
- Fixed menu navigation getting stuck on items with empty string or other falsy values (e.g., in the `/hooks` menu)

[​](#2-0-34)

2.0.34

November 5, 2025

- VSCode Extension: Added setting to configure the initial permission mode for new conversations
- Improved file path suggestion performance with native Rust-based fuzzy finder
- Fixed infinite token refresh loop that caused MCP servers with OAuth (e.g., Slack) to hang during connection
- Fixed memory crash when reading or writing large files (especially base64-encoded images)

[​](#2-0-33)

2.0.33

November 4, 2025

- Native binary installs now launch quicker.
- Fixed `claude doctor` incorrectly detecting Homebrew vs npm-global installations by properly resolving symlinks
- Fixed `claude mcp serve` exposing tools with incompatible outputSchemas

[​](#2-0-32)

2.0.32

November 4, 2025

- Un-deprecate output styles based on community feedback
- Added `companyAnnouncements` setting for displaying announcements on startup
- Fixed hook progress messages not updating correctly during PostToolUse hook execution

[​](#2-0-31)

2.0.31

October 31, 2025

- Windows: native installation uses shift+tab as shortcut for mode switching, instead of alt+m
- Vertex: add support for Web Search on supported models
- VSCode: Adding the respectGitIgnore configuration to include .gitignored files in file searches (defaults to true)
- Fixed a bug with subagents and MCP servers related to “Tool names must be unique” error
- Fixed issue causing `/compact` to fail with `prompt_too_long` by making it respect existing compact boundaries
- Fixed plugin uninstall not removing plugins

[​](#2-0-30)

2.0.30

October 30, 2025

**Added**

- Added helpful hint to run `security unlock-keychain` when encountering API key errors on macOS with locked keychain
- Added `allowUnsandboxedCommands` sandbox setting to disable the dangerouslyDisableSandbox escape hatch at policy level
- Added `disallowedTools` field to custom agent definitions for explicit tool blocking
- Added prompt-based stop hooks
- VSCode: Added respectGitIgnore configuration to include .gitignored files in file searches (defaults to true)

**Changed**

- Enabled SSE MCP servers on native build
- Deprecated output styles. Review options in `/output-style` and use —system-prompt-file, —system-prompt, —append-system-prompt, CLAUDE.md, or plugins instead
- Removed support for custom ripgrep configuration, resolving an issue where Search returns no results and config discovery fails
- VSCode: Restored selection indicator in input footer showing current file or code selection status

Show 7 bug fixes

- Fixed Explore agent creating unwanted .md investigation files during codebase exploration
- Fixed a bug where `/context` would sometimes fail with “max_tokens must be greater than thinking.budget_tokens” error message
- Fixed `--mcp-config` flag to correctly override file-based MCP configurations
- Fixed bug that saved session permissions to local settings
- Fixed MCP tools not being available to sub-agents
- Fixed hooks and plugins not executing when using —dangerously-skip-permissions flag
- Fixed delay when navigating through typeahead suggestions with arrow keys

[​](#2-0-28)

2.0.28

October 27, 2025

- Plan mode: introduced new Plan subagent
- Subagents: claude can now choose to resume subagents
- Subagents: claude can dynamically choose the model used by its subagents
- SDK: added —max-budget-usd flag
- Discovery of custom slash commands, subagents, and output styles no longer respects .gitignore
- Stop `/terminal-setup` from adding backslash to `Shift + Enter` in VS Code
- Add branch and tag support for git-based plugins and marketplaces using fragment syntax (e.g., `owner/repo#branch`)
- Fixed a bug where macOS permission prompts would show up upon initial launch when launching from home directory
- Various other bug fixes

[​](#2-0-27)

2.0.27

October 24, 2025

- New UI for permission prompts
- Added current branch filtering and search to session resume screen for easier navigation
- Fixed directory @-mention causing “No assistant message found” error
- VSCode Extension: Add config setting to include .gitignored files in file searches
- VSCode Extension: Bug fixes for unrelated ‘Warmup’ conversations, and configuration/settings occasionally being reset to defaults

[​](#2-0-25)

2.0.25

October 21, 2025

- Removed legacy SDK entrypoint. Please migrate to @anthropic-ai/claude-agent-sdk for future SDK updates: [https://platform.claude.com/docs/en/agent-sdk/migration-guide](../05-Agent-SDK/agent-sdk-migration-guide.md)

[​](#2-0-24)

2.0.24

October 20, 2025

- Fixed a bug where project-level skills were not loading when —setting-sources ‘project’ was specified
- Claude Code Web: Support for Web -\> CLI teleport
- Sandbox: Releasing a sandbox mode for the BashTool on Linux & Mac
- Bedrock: Display awsAuthRefresh output when auth is required

[​](#2-0-22)

2.0.22

October 17, 2025

- Fixed content layout shift when scrolling through slash commands
- IDE: Add toggle to enable/disable thinking.
- Fix bug causing duplicate permission prompts with parallel tool calls
- Add support for enterprise managed MCP allowlist and denylist

[​](#2-0-21)

2.0.21

October 18, 2025

- Support MCP `structuredContent` field in tool responses
- Added an interactive question tool
- Claude will now ask you questions more often in plan mode
- Added Haiku 4.5 as a model option for Pro users
- Fixed an issue where queued commands don’t have access to previous messages’ output

[​](#2-0-20)

2.0.20

October 16, 2025

- Added support for Claude Skills

[​](#2-0-19)

2.0.19

October 15, 2025

- Auto-background long-running bash commands instead of killing them. Customize with BASH_DEFAULT_TIMEOUT_MS
- Fixed a bug where Haiku was unnecessarily called in print mode

[​](#2-0-17)

2.0.17

October 15, 2025

- Added Haiku 4.5 to model selector!
- Haiku 4.5 automatically uses Sonnet in plan mode, and Haiku for execution (i.e. SonnetPlan by default)
- 3P (Bedrock and Vertex) are not automatically upgraded yet. Manual upgrading can be done through setting `ANTHROPIC_DEFAULT_HAIKU_MODEL`
- Introducing the Explore subagent. Powered by Haiku it’ll search through your codebase efficiently to save context!
- OTEL: support HTTP_PROXY and HTTPS_PROXY
- `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` now disables release notes fetching

[​](#2-0-15)

2.0.15

October 14, 2025

- Fixed bug with resuming where previously created files needed to be read again before writing
- Fixed bug with `-p` mode where @-mentioned files needed to be read again before writing

[​](#2-0-14)

2.0.14

October 10, 2025

- Fix @-mentioning MCP servers to toggle them on/off
- Improve permission checks for bash with inline env vars
- Fix ultrathink + thinking toggle
- Reduce unnecessary logins
- Document —system-prompt
- Several improvements to rendering
- Plugins UI polish

[​](#2-0-13)

2.0.13

October 9, 2025

- Fixed `/plugin` not working on native build

[​](#2-0-12)

2.0.12

October 9, 2025

**Changed**

- **Plugin System Released**: Extend Claude Code with custom commands, agents, hooks, and MCP servers from marketplaces
- `/plugin install`, `/plugin enable/disable`, `/plugin marketplace` commands for plugin management
- Repository-level plugin configuration via `extraKnownMarketplaces` for team collaboration
- `/plugin validate` command for validating plugin structure and configuration
- Plugin announcement blog post at [https://www.anthropic.com/news/claude-code-plugins](https://www.anthropic.com/news/claude-code-plugins)
- Plugin documentation available at [https://code.claude.com/docs/en/plugins](../08-Plugins-Skills/plugins.md)
- Comprehensive error messages and diagnostics via `/doctor` command
- Avoid flickering in `/model` selector
- Improvements to `/help`
- Avoid mentioning hooks in `/resume` summaries
- Changes to the “verbose” setting in `/config` now persist across sessions

[​](#2-0-11)

2.0.11

October 8, 2025

- Reduced system prompt size by 1.4k tokens
- IDE: Fixed keyboard shortcuts and focus issues for smoother interaction
- Fixed Opus fallback rate limit errors appearing incorrectly
- Fixed /add-dir command selecting wrong default tab

[​](#2-0-10)

2.0.10

October 8, 2025

- Rewrote terminal renderer for buttery smooth UI
- Enable/disable MCP servers by @mentioning, or in /mcp
- Added tab completion for shell commands in bash mode
- PreToolUse hooks can now modify tool inputs
- Press Ctrl-G to edit your prompt in your system’s configured text editor
- Fixes for bash permission checks with environment variables in the command

[​](#2-0-9)

2.0.9

October 6, 2025

- Fix regression where bash backgrounding stopped working

[​](#2-0-8)

2.0.8

October 4, 2025

- Update Bedrock default Sonnet model to `global.anthropic.claude-sonnet-4-5-20250929-v1:0`
- IDE: Add drag-and-drop support for files and folders in chat
- /context: Fix counting for thinking blocks
- Improve message rendering for users with light themes on dark terminals
- Remove deprecated .claude.json allowedTools, ignorePatterns, env, and todoFeatureEnabled config options (instead, configure these in your settings.json)

[​](#2-0-5)

2.0.5

October 4, 2025

- IDE: Fix IME unintended message submission with Enter and Tab
- IDE: Add “Open in Terminal” link in login screen
- Fix unhandled OAuth expiration 401 API errors
- SDK: Added SDKUserMessageReplay.isReplay to prevent duplicate messages

[​](#2-0-1)

2.0.1

September 30, 2025

- Skip Sonnet 4.5 default model setting change for Bedrock and Vertex
- Various bug fixes and presentation improvements

[​](#2-0-0)

2.0.0

September 29, 2025

**Added**

- New native VS Code extension
- Add subagents dynamically with `--agents` flag

**Changed**

- Fresh coat of paint throughout the whole app
- /rewind a conversation to undo code changes
- /usage command to see plan limits
- Tab to toggle thinking (sticky across sessions)
- Ctrl-R to search history
- Unshipped claude config command
- Hooks: Reduced PostToolUse ‘tool_use’ ids were found without ‘tool_result’ blocks errors
- SDK: The Claude Code SDK is now the Claude Agent SDK

[​](#1-0-126)

1.0.126

September 26, 2025

- Enable /context command for Bedrock and Vertex
- Add mTLS support for HTTP-based OpenTelemetry exporters

[​](#1-0-124)

1.0.124

September 25, 2025

- Set `CLAUDE_BASH_NO_LOGIN` environment variable to 1 or true to to skip login shell for BashTool
- Fix Bedrock and Vertex environment variables evaluating all strings as truthy
- No longer inform Claude of the list of allowed tools when permission is denied
- Fixed security vulnerability in Bash tool permission checks
- Improved VSCode extension performance for large files

[​](#1-0-123)

1.0.123

September 23, 2025

- Bash permission rules now support output redirections when matching (e.g., `Bash(python:*)` matches `python script.py > output.txt`)
- Fixed thinking mode triggering on negation phrases like “don’t think”
- Fixed rendering performance degradation during token streaming
- Added SlashCommand tool, which enables Claude to invoke your slash commands. [https://code.claude.com/docs/en/slash-commands#SlashCommand-tool](https://code.claude.com/docs/en/slash-commands#SlashCommand-tool)
- Enhanced BashTool environment snapshot logging
- Fixed a bug where resuming a conversation in headless mode would sometimes enable thinking unnecessarily
- Migrated —debug logging to a file, to enable easy tailing & filtering

[​](#1-0-120)

1.0.120

September 19, 2025

- Fix input lag during typing, especially noticeable with large prompts
- Improved VSCode extension command registry and sessions dialog user experience
- Enhanced sessions dialog responsiveness and visual feedback
- Fixed IDE compatibility issue by removing worktree support check
- Fixed security vulnerability where Bash tool permission checks could be bypassed using prefix matching

[​](#1-0-119)

1.0.119

September 19, 2025

- Fix Windows issue where process visually freezes on entering interactive mode
- Support dynamic headers for MCP servers via headersHelper configuration
- Fix thinking mode not working in headless sessions
- Fix slash commands now properly update allowed tools instead of replacing them

[​](#1-0-117)

1.0.117

September 19, 2025

- Add Ctrl-R history search to recall previous commands like bash/zsh
- Fix input lag while typing, especially on Windows
- Add sed command to auto-allowed commands in acceptEdits mode
- Fix Windows PATH comparison to be case-insensitive for drive letters
- Add permissions management hint to /add-dir output

[​](#1-0-115)

1.0.115

September 16, 2025

- Improve thinking mode display with enhanced visual effects
- Type /t to temporarily disable thinking mode in your prompt
- Improve path validation for glob and grep tools
- Show condensed output for post-tool hooks to reduce visual clutter
- Fix visual feedback when loading state completes
- Improve UI consistency for permission request dialogs

[​](#1-0-113)

1.0.113

September 13, 2025

- Deprecated piped input in interactive mode
- Move Ctrl+R keybinding for toggling transcript to Ctrl+O

[​](#1-0-112)

1.0.112

September 12, 2025

- Transcript mode (Ctrl+R): Added the model used to generate each assistant message
- Addressed issue where some Claude Max users were incorrectly recognized as Claude Pro users
- Hooks: Added systemMessage support for SessionEnd hooks
- Added `spinnerTipsEnabled` setting to disable spinner tips
- IDE: Various improvements and bug fixes

[​](#1-0-111)

1.0.111

September 10, 2025

- /model now validates provided model names
- Fixed Bash tool crashes caused by malformed shell syntax parsing

[​](#1-0-110)

1.0.110

September 10, 2025

- /terminal-setup command now supports WezTerm
- MCP: OAuth tokens now proactively refresh before expiration
- Fixed reliability issues with background Bash processes

[​](#1-0-109)

1.0.109

September 9, 2025

- SDK: Added partial message streaming support via `--include-partial-messages` CLI flag

[​](#1-0-106)

1.0.106

September 5, 2025

- Windows: Fixed path permission matching to consistently use POSIX format (e.g., `Read(//c/Users/...)`)

[​](#1-0-97)

1.0.97

August 29, 2025

- Settings: /doctor now validates permission rule syntax and suggests corrections

[​](#1-0-94)

1.0.94

August 27, 2025

- Vertex: add support for global endpoints for supported models
- /memory command now allows direct editing of all imported memory files
- SDK: Add custom tools as callbacks
- Added /todos command to list current todo items

[​](#1-0-93)

1.0.93

August 26, 2025

- Windows: Add alt + v shortcut for pasting images from clipboard
- Support NO_PROXY environment variable to bypass proxy for specified hostnames and IPs

[​](#1-0-90)

1.0.90

August 25, 2025

- Settings file changes take effect immediately - no restart required

[​](#1-0-88)

1.0.88

August 22, 2025

- Fixed issue causing “OAuth authentication is currently not supported”
- Status line input now includes `exceeds_200k_tokens`
- Fixed incorrect usage tracking in /cost.
- Introduced `ANTHROPIC_DEFAULT_SONNET_MODEL` and `ANTHROPIC_DEFAULT_OPUS_MODEL` for controlling model aliases opusplan, opus, and sonnet.
- Bedrock: Updated default Sonnet model to Sonnet 4

[​](#1-0-86)

1.0.86

August 22, 2025

- Added /context to help users self-serve debug context issues
- SDK: Added UUID support for all SDK messages
- SDK: Added `--replay-user-messages` to replay user messages back to stdout

[​](#1-0-85)

1.0.85

August 19, 2025

- Status line input now includes session cost info
- Hooks: Introduced SessionEnd hook

[​](#1-0-84)

1.0.84

August 18, 2025

- Fix tool_use/tool_result id mismatch error when network is unstable
- Fix Claude sometimes ignoring real-time steering when wrapping up a task
- @-mention: Add ~/.claude/\* files to suggestions for easier agent, output style, and slash command editing
- Use built-in ripgrep by default; to opt out of this behavior, set USE_BUILTIN_RIPGREP=0

[​](#1-0-83)

1.0.83

August 18, 2025

- @-mention: Support files with spaces in path
- New shimmering spinner

[​](#1-0-82)

1.0.82

August 16, 2025

- SDK: Add request cancellation support
- SDK: New additionalDirectories option to search custom paths, improved slash command processing
- Settings: Validation prevents invalid fields in .claude/settings.json files
- MCP: Improve tool name consistency
- Bash: Fix crash when Claude tries to automatically read large files

[​](#1-0-81)

1.0.81

August 14, 2025

- Released output styles, including new built-in educational output styles “Explanatory” and “Learning”. Docs: [https://code.claude.com/docs/en/output-styles](output-styles.md)
- Agents: Fix custom agent loading when agent files are unparsable

[​](#1-0-80)

1.0.80

August 14, 2025

- UI improvements: Fix text contrast for custom subagent colors and spinner rendering issues

[​](#1-0-77)

1.0.77

August 14, 2025

- Bash tool: Fix heredoc and multiline string escaping, improve stderr redirection handling
- SDK: Add session support and permission denial tracking
- Fix token limit errors in conversation summarization
- Opus Plan Mode: New setting in `/model` to run Opus only in plan mode, Sonnet otherwise

[​](#1-0-73)

1.0.73

August 11, 2025

- MCP: Support multiple config files with `--mcp-config file1.json file2.json`
- MCP: Press Esc to cancel OAuth authentication flows
- Bash: Improved command validation and reduced false security warnings
- UI: Enhanced spinner animations and status line visual hierarchy
- Linux: Added support for Alpine and musl-based distributions (requires separate ripgrep installation)

[​](#1-0-72)

1.0.72

August 11, 2025

- Ask permissions: have Claude Code always ask for confirmation to use specific tools with /permissions

[​](#1-0-71)

1.0.71

August 7, 2025

- Background commands: (Ctrl-b) to run any Bash command in the background so Claude can keep working (great for dev servers, tailing logs, etc.)
- Customizable status line: add your terminal prompt to Claude Code with /statusline

[​](#1-0-70)

1.0.70

August 7, 2025

- Performance: Optimized message rendering for better performance with large contexts
- Windows: Fixed native file search, ripgrep, and subagent functionality
- Added support for @-mentions in slash command arguments

[​](#1-0-69)

1.0.69

August 5, 2025

- Upgraded Opus to version 4.1

[​](#1-0-68)

1.0.68

August 4, 2025

- Fix incorrect model names being used for certain commands like `/pr-comments`
- Windows: improve permissions checks for allow / deny tools and project trust. This may create a new project entry in `.claude.json` - manually merge the history field if desired.
- Windows: improve sub-process spawning to eliminate “No such file or directory” when running commands like pnpm
- Enhanced /doctor command with CLAUDE.md and MCP tool context for self-serve debugging
- SDK: Added canUseTool callback support for tool confirmation
- Added `disableAllHooks` setting
- Improved file suggestions performance in large repos

[​](#1-0-65)

1.0.65

July 31, 2025

- IDE: Fixed connection stability issues and error handling for diagnostics
- Windows: Fixed shell environment setup for users without .bashrc files

[​](#1-0-64)

1.0.64

July 30, 2025

- Agents: Added model customization support - you can now specify which model an agent should use
- Agents: Fixed unintended access to the recursive agent tool
- Hooks: Added systemMessage field to hook JSON output for displaying warnings and context
- SDK: Fixed user input tracking across multi-turn conversations
- Added hidden files to file search and @-mention suggestions

[​](#1-0-63)

1.0.63

July 29, 2025

- Windows: Fixed file search, @agent mentions, and custom slash commands functionality

[​](#1-0-62)

1.0.62

July 28, 2025

- Added @-mention support with typeahead for custom agents. @`<your-custom-agent>` to invoke it
- Hooks: Added SessionStart hook for new session initialization
- /add-dir command now supports typeahead for directory paths
- Improved network connectivity check reliability

[​](#1-0-61)

1.0.61

July 25, 2025

- Transcript mode (Ctrl+R): Changed Esc to exit transcript mode rather than interrupt
- Settings: Added `--settings` flag to load settings from a JSON file
- Settings: Fixed resolution of settings files paths that are symlinks
- OTEL: Fixed reporting of wrong organization after authentication changes
- Slash commands: Fixed permissions checking for allowed-tools with Bash
- IDE: Added support for pasting images in VSCode MacOS using ⌘+V
- IDE: Added `CLAUDE_CODE_AUTO_CONNECT_IDE=false` for disabling IDE auto-connection
- Added `CLAUDE_CODE_SHELL_PREFIX` for wrapping Claude and user-provided shell commands run by Claude Code

[​](#1-0-60)

1.0.60

July 24, 2025

- You can now create custom subagents for specialized tasks! Run /agents to get started

[​](#1-0-59)

1.0.59

July 23, 2025

- SDK: Added tool confirmation support with canUseTool callback
- SDK: Allow specifying env for spawned process
- Hooks: Exposed PermissionDecision to hooks (including “ask”)
- Hooks: UserPromptSubmit now supports additionalContext in advanced JSON output
- Fixed issue where some Max users that specified Opus would still see fallback to Sonnet

[​](#1-0-58)

1.0.58

July 23, 2025

- Added support for reading PDFs
- MCP: Improved server health status display in ‘claude mcp list’
- Hooks: Added CLAUDE_PROJECT_DIR env var for hook commands

[​](#1-0-57)

1.0.57

July 23, 2025

- Added support for specifying a model in slash commands
- Improved permission messages to help Claude understand allowed tools
- Fix: Remove trailing newlines from bash output in terminal wrapping

[​](#1-0-56)

1.0.56

July 23, 2025

- Windows: Enabled shift+tab for mode switching on versions of Node.js that support terminal VT mode
- Fixes for WSL IDE detection
- Fix an issue causing awsRefreshHelper changes to .aws directory not to be picked up

[​](#1-0-55)

1.0.55

July 23, 2025

- Clarified knowledge cutoff for Opus 4 and Sonnet 4 models
- Windows: fixed Ctrl+Z crash
- SDK: Added ability to capture error logging
- Add —system-prompt-file option to override system prompt in print mode

[​](#1-0-54)

1.0.54

July 19, 2025

- Hooks: Added UserPromptSubmit hook and the current working directory to hook inputs
- Custom slash commands: Added argument-hint to frontmatter
- Windows: OAuth uses port 45454 and properly constructs browser URL
- Windows: mode switching now uses alt + m, and plan mode renders properly
- Shell: Switch to in-memory shell snapshot to fix file-related errors

[​](#1-0-53)

1.0.53

July 18, 2025

- Updated @-mention file truncation from 100 lines to 2000 lines
- Add helper script settings for AWS token refresh: awsAuthRefresh (for foreground operations like aws sso login) and awsCredentialExport (for background operation with STS-like response).

[​](#1-0-52)

1.0.52

July 18, 2025

- Added support for MCP server instructions

[​](#1-0-51)

1.0.51

July 11, 2025

- Added support for native Windows (requires Git for Windows)
- Added support for Bedrock API keys through environment variable AWS_BEARER_TOKEN_BEDROCK
- Settings: /doctor can now help you identify and fix invalid setting files
- `--append-system-prompt` can now be used in interactive mode, not just —print/-p.
- Increased auto-compact warning threshold from 60% to 80%
- Fixed an issue with handling user directories with spaces for shell snapshots
- OTEL resource now includes os.type, os.version, host.arch, and wsl.version (if running on Windows Subsystem for Linux)
- Custom slash commands: Fixed user-level commands in subdirectories
- Plan mode: Fixed issue where rejected plan from sub-task would get discarded

[​](#1-0-48)

1.0.48

July 10, 2025

- Fixed a bug in v1.0.45 where the app would sometimes freeze on launch
- Added progress messages to Bash tool based on the last 5 lines of command output
- Added expanding variables support for MCP server configuration
- Moved shell snapshots from /tmp to ~/.claude for more reliable Bash tool calls
- Improved IDE extension path handling when Claude Code runs in WSL
- Hooks: Added a PreCompact hook
- Vim mode: Added c, f/F, t/T

[​](#1-0-45)

1.0.45

July 10, 2025

- Redesigned Search (Grep) tool with new tool input parameters and features
- Disabled IDE diffs for notebook files, fixing “Timeout waiting after 1000ms” error
- Fixed config file corruption issue by enforcing atomic writes
- Updated prompt input undo to Ctrl+\_ to avoid breaking existing Ctrl+U behavior, matching zsh’s undo shortcut
- Stop Hooks: Fixed transcript path after /clear and fixed triggering when loop ends with tool call
- Custom slash commands: Restored namespacing in command names based on subdirectories. For example, .claude/commands/frontend/component.md is now /frontend:component, not /component.

[​](#1-0-44)

1.0.44

July 7, 2025

- New /export command lets you quickly export a conversation for sharing
- MCP: resource_link tool results are now supported
- MCP: tool annotations and tool titles now display in /mcp view
- Changed Ctrl+Z to suspend Claude Code. Resume by running `fg`. Prompt input undo is now Ctrl+U.

[​](#1-0-43)

1.0.43

July 3, 2025

- Fixed a bug where the theme selector was saving excessively
- Hooks: Added EPIPE system error handling

[​](#1-0-42)

1.0.42

July 3, 2025

- Added tilde (`~`) expansion support to `/add-dir` command

[​](#1-0-41)

1.0.41

July 3, 2025

- Hooks: Split Stop hook triggering into Stop and SubagentStop
- Hooks: Enabled optional timeout configuration for each command
- Hooks: Added “hook_event_name” to hook input
- Fixed a bug where MCP tools would display twice in tool list
- New tool parameters JSON for Bash tool in `tool_decision` event

[​](#1-0-40)

1.0.40

July 3, 2025

- Fixed a bug causing API connection errors with UNABLE_TO_GET_ISSUER_CERT_LOCALLY if `NODE_EXTRA_CA_CERTS` was set

[​](#1-0-39)

1.0.39

July 3, 2025

- New Active Time metric in OpenTelemetry logging

[​](#1-0-38)

1.0.38

June 30, 2025

- Released hooks. Special thanks to community input in [https://github.com/anthropics/claude-code/issues/712](https://github.com/anthropics/claude-code/issues/712). Docs: [https://code.claude.com/docs/en/hooks](../07-Hooks/hooks.md)

[​](#1-0-37)

1.0.37

June 30, 2025

- Remove ability to set `Proxy-Authorization` header via ANTHROPIC_AUTH_TOKEN or apiKeyHelper

[​](#1-0-36)

1.0.36

June 30, 2025

- Web search now takes today’s date into context
- Fixed a bug where stdio MCP servers were not terminating properly on exit

[​](#1-0-35)

1.0.35

June 25, 2025

- Added support for MCP OAuth Authorization Server discovery

[​](#1-0-34)

1.0.34

June 24, 2025

- Fixed a memory leak causing a MaxListenersExceededWarning message to appear

[​](#1-0-33)

1.0.33

June 24, 2025

- Improved logging functionality with session ID support
- Added prompt input undo functionality (Ctrl+Z and vim ‘u’ command)
- Improvements to plan mode

[​](#1-0-32)

1.0.32

June 24, 2025

- Updated loopback config for litellm
- Added forceLoginMethod setting to bypass login selection screen

[​](#1-0-31)

1.0.31

June 24, 2025

- Fixed a bug where ~/.claude.json would get reset when file contained invalid JSON

[​](#1-0-30)

1.0.30

June 24, 2025

- Custom slash commands: Run bash output, @-mention files, enable thinking with thinking keywords
- Improved file path autocomplete with filename matching
- Added timestamps in Ctrl-r mode and fixed Ctrl-c handling
- Enhanced jq regex support for complex filters with pipes and select

[​](#1-0-29)

1.0.29

June 24, 2025

- Improved CJK character support in cursor navigation and rendering

[​](#1-0-28)

1.0.28

June 24, 2025

- Slash commands: Fix selector display during history navigation
- Resizes images before upload to prevent API size limit errors
- Added XDG_CONFIG_HOME support to configuration directory
- Performance optimizations for memory usage
- New attributes (terminal.type, language) in OpenTelemetry logging

[​](#1-0-27)

1.0.27

June 18, 2025

- Streamable HTTP MCP servers are now supported
- Remote MCP servers (SSE and HTTP) now support OAuth
- MCP resources can now be @-mentioned
- /resume slash command to switch conversations within Claude Code

[​](#1-0-25)

1.0.25

June 16, 2025

- Slash commands: moved “project” and “user” prefixes to descriptions
- Slash commands: improved reliability for command discovery
- Improved support for Ghostty
- Improved web search reliability

[​](#1-0-24)

1.0.24

June 16, 2025

- Improved /mcp output
- Fixed a bug where settings arrays got overwritten instead of merged

[​](#1-0-23)

1.0.23

June 16, 2025

- Released TypeScript SDK: import @anthropic-ai/claude-code to get started
- Released Python SDK: pip install claude-code-sdk to get started

[​](#1-0-22)

1.0.22

June 12, 2025

- SDK: Renamed `total_cost` to `total_cost_usd`

[​](#1-0-21)

1.0.21

June 12, 2025

- Improved editing of files with tab-based indentation
- Fix for tool_use without matching tool_result errors
- Fixed a bug where stdio MCP server processes would linger after quitting Claude Code

[​](#1-0-18)

1.0.18

June 9, 2025

- Added —add-dir CLI argument for specifying additional working directories
- Added streaming input support without require -p flag
- Improved startup performance and session storage performance
- Added CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR environment variable to freeze working directory for bash commands
- Added detailed MCP server tools display (/mcp)
- MCP authentication and permission improvements
- Added auto-reconnection for MCP SSE connections on disconnect
- Fixed issue where pasted content was lost when dialogs appeared

[​](#1-0-17)

1.0.17

June 9, 2025

- We now emit messages from sub-tasks in -p mode (look for the parent_tool_use_id property)
- Fixed crashes when the VS Code diff tool is invoked multiple times quickly
- MCP server list UI improvements
- Update Claude Code process title to display “claude” instead of “node”

[​](#1-0-11)

1.0.11

June 4, 2025

- Claude Code can now also be used with a Claude Pro subscription
- Added /upgrade for smoother switching to Claude Max plans
- Improved UI for authentication from API keys and Bedrock/Vertex/external auth tokens
- Improved shell configuration error handling
- Improved todo list handling during compaction

[​](#1-0-10)

1.0.10

June 4, 2025

- Added markdown table support
- Improved streaming performance

[​](#1-0-8)

1.0.8

June 2, 2025

- Fixed Vertex AI region fallback when using CLOUD_ML_REGION
- Increased default otel interval from 1s -\> 5s
- Fixed edge cases where MCP_TIMEOUT and MCP_TOOL_TIMEOUT weren’t being respected
- Fixed a regression where search tools unnecessarily asked for permissions
- Added support for triggering thinking non-English languages
- Improved compacting UI

[​](#1-0-7)

1.0.7

June 2, 2025

- Renamed /allowed-tools -\> /permissions
- Migrated allowedTools and ignorePatterns from .claude.json -\> settings.json
- Deprecated claude config commands in favor of editing settings.json
- Fixed a bug where —dangerously-skip-permissions sometimes didn’t work in —print mode
- Improved error handling for /install-github-app
- Bugfixes, UI polish, and tool reliability improvements

[​](#1-0-6)

1.0.6

June 2, 2025

- Improved edit reliability for tab-indented files
- Respect CLAUDE_CONFIG_DIR everywhere
- Reduced unnecessary tool permission prompts
- Added support for symlinks in @file typeahead
- Bugfixes, UI polish, and tool reliability improvements

[​](#1-0-4)

1.0.4

May 28, 2025

- Fixed a bug where MCP tool errors weren’t being parsed correctly

[​](#1-0-1)

1.0.1

May 22, 2025

- Added `DISABLE_INTERLEAVED_THINKING` to give users the option to opt out of interleaved thinking.
- Improved model references to show provider-specific names (Sonnet 3.7 for Bedrock, Sonnet 4 for Console)
- Updated documentation links and OAuth process descriptions

[​](#1-0-0)

1.0.0

May 22, 2025

- Claude Code is now generally available
- Introducing Sonnet 4 and Opus 4 models

[​](#0-2-125)

0.2.125

May 21, 2025

- Breaking change: Bedrock ARN passed to `ANTHROPIC_MODEL` or `ANTHROPIC_SMALL_FAST_MODEL` should no longer contain an escaped slash (specify `/` instead of `%2F`)
- Removed `DEBUG=true` in favor of `ANTHROPIC_LOG=debug`, to log all requests

[​](#0-2-117)

0.2.117

May 17, 2025

- Breaking change: —print JSON output now returns nested message objects, for forwards-compatibility as we introduce new metadata fields
- Introduced settings.cleanupPeriodDays
- Introduced CLAUDE_CODE_API_KEY_HELPER_TTL_MS env var
- Introduced —debug mode

[​](#0-2-108)

0.2.108

May 13, 2025

- You can now send messages to Claude while it works to steer Claude in real-time
- Introduced BASH_DEFAULT_TIMEOUT_MS and BASH_MAX_TIMEOUT_MS env vars
- Fixed a bug where thinking was not working in -p mode
- Fixed a regression in /cost reporting
- Deprecated MCP wizard interface in favor of other MCP commands
- Lots of other bugfixes and improvements

[​](#0-2-107)

0.2.107

May 9, 2025

- CLAUDE.md files can now import other files. Add @path/to/file.md to ./CLAUDE.md to load additional files on launch

[​](#0-2-106)

0.2.106

May 9, 2025

- MCP SSE server configs can now specify custom headers
- Fixed a bug where MCP permission prompt didn’t always show correctly

[​](#0-2-105)

0.2.105

May 8, 2025

- Claude can now search the web
- Moved system & account status to /status
- Added word movement keybindings for Vim
- Improved latency for startup, todo tool, and file edits

[​](#0-2-102)

0.2.102

May 5, 2025

- Improved thinking triggering reliability
- Improved @mention reliability for images and folders
- You can now paste multiple large chunks into one prompt

[​](#0-2-100)

0.2.100

May 2, 2025

- Fixed a crash caused by a stack overflow error
- Made db storage optional; missing db support disables —continue and —resume

[​](#0-2-98)

0.2.98

May 1, 2025

- Fixed an issue where auto-compact was running twice

[​](#0-2-96)

0.2.96

May 1, 2025

- Claude Code can now also be used with a Claude Max subscription ([https://claude.ai/upgrade](https://claude.ai/upgrade))

[​](#0-2-93)

0.2.93

April 30, 2025

- Resume conversations from where you left off from with “claude —continue” and “claude —resume”
- Claude now has access to a Todo list that helps it stay on track and be more organized

[​](#0-2-82)

0.2.82

April 25, 2025

- Added support for —disallowedTools
- Renamed tools for consistency: LSTool -\> LS, View -\> Read, etc.

[​](#0-2-75)

0.2.75

April 21, 2025

- Hit Enter to queue up additional messages while Claude is working
- Drag in or copy/paste image files directly into the prompt
- @-mention files to directly add them to context
- Run one-off MCP servers with `claude --mcp-config <path-to-file>`
- Improved performance for filename auto-complete

[​](#0-2-74)

0.2.74

April 18, 2025

- Added support for refreshing dynamically generated API keys (via apiKeyHelper), with a 5 minute TTL
- Task tool can now perform writes and run bash commands

[​](#0-2-72)

0.2.72

April 18, 2025

- Updated spinner to indicate tokens loaded and tool usage

[​](#0-2-70)

0.2.70

April 17, 2025

- Network commands like curl are now available for Claude to use
- Claude can now run multiple web queries in parallel
- Pressing ESC once immediately interrupts Claude in Auto-accept mode

[​](#0-2-69)

0.2.69

April 17, 2025

- Fixed UI glitches with improved Select component behavior
- Enhanced terminal output display with better text truncation logic

[​](#0-2-67)

0.2.67

April 17, 2025

- Shared project permission rules can be saved in .claude/settings.json

[​](#0-2-66)

0.2.66

April 17, 2025

- Print mode (-p) now supports streaming output via —output-format=stream-json
- Fixed issue where pasting could trigger memory or bash mode unexpectedly

[​](#0-2-63)

0.2.63

April 17, 2025

- Fixed an issue where MCP tools were loaded twice, which caused tool call errors

[​](#0-2-61)

0.2.61

April 2, 2025

- Navigate menus with vim-style keys (j/k) or bash/emacs shortcuts (Ctrl+n/p) for faster interaction
- Enhanced image detection for more reliable clipboard paste functionality
- Fixed an issue where ESC key could crash the conversation history selector

[​](#0-2-59)

0.2.59

April 2, 2025

- Copy+paste images directly into your prompt
- Improved progress indicators for bash and fetch tools
- Bugfixes for non-interactive mode (-p)

[​](#0-2-54)

0.2.54

April 2, 2025

- Quickly add to Memory by starting your message with ’#’
- Press ctrl+r to see full output for long tool results
- Added support for MCP SSE transport

[​](#0-2-53)

0.2.53

April 2, 2025

- New web fetch tool lets Claude view URLs that you paste in
- Fixed a bug with JPEG detection

[​](#0-2-50)

0.2.50

April 2, 2025

- New MCP “project” scope now allows you to add MCP servers to .mcp.json files and commit them to your repository

[​](#0-2-49)

0.2.49

April 2, 2025

- Previous MCP server scopes have been renamed: previous “project” scope is now “local” and “global” scope is now “user”

[​](#0-2-47)

0.2.47

April 2, 2025

- Press Tab to auto-complete file and folder names
- Press Shift + Tab to toggle auto-accept for file edits
- Automatic conversation compaction for infinite conversation length (toggle with /config)

[​](#0-2-44)

0.2.44

April 2, 2025

- Ask Claude to make a plan with thinking mode: just say ‘think’ or ‘think harder’ or even ‘ultrathink’

[​](#0-2-41)

0.2.41

April 2, 2025

- MCP server startup timeout can now be configured via MCP_TIMEOUT environment variable
- MCP server startup no longer blocks the app from starting up

[​](#0-2-37)

0.2.37

April 2, 2025

- New /release-notes command lets you view release notes at any time
- `claude config add/remove` commands now accept multiple values separated by commas or spaces

[​](#0-2-36)

0.2.36

April 2, 2025

- Import MCP servers from Claude Desktop with `claude mcp add-from-claude-desktop`
- Add MCP servers as JSON strings with `claude mcp add-json <n> <json>`

[​](#0-2-34)

0.2.34

April 2, 2025

- Vim bindings for text input - enable with /vim or /config

[​](#0-2-32)

0.2.32

April 2, 2025

- Interactive MCP setup wizard: Run “claude mcp add” to add MCP servers with a step-by-step interface
- Fix for some PersistentShell issues

[​](#0-2-31)

0.2.31

April 2, 2025

- Custom slash commands: Markdown files in .claude/commands/ directories now appear as custom slash commands to insert prompts into your conversation
- MCP debug mode: Run with —mcp-debug flag to get more information about MCP server errors

[​](#0-2-30)

0.2.30

April 2, 2025

- Added ANSI color theme for better terminal compatibility
- Fixed issue where slash command arguments weren’t being sent properly
- (Mac-only) API keys are now stored in macOS Keychain

[​](#0-2-26)

0.2.26

April 2, 2025

- New /approved-tools command for managing tool permissions
- Word-level diff display for improved code readability
- Fuzzy matching for slash commands

[​](#0-2-21)

0.2.21

April 2, 2025

- Fuzzy matching for /commands

---

## Channels reference - Claude Code Docs

Source: https://code.claude.com/docs/en/channels-reference
Path: 02-Claude-Code-CLI/channels-reference.md

## On this page

- [Overview](#overview)
- [What you need](#what-you-need)
- [Example: build a webhook receiver](#example-build-a-webhook-receiver)
- [Test during the research preview](#test-during-the-research-preview)
- [Server options](#server-options)
- [Notification format](#notification-format)
- [Expose a reply tool](#expose-a-reply-tool)
- [Gate inbound messages](#gate-inbound-messages)
- [Relay permission prompts](#relay-permission-prompts)
  - [How relay works](#how-relay-works)
  - [Permission request fields](#permission-request-fields)
  - [Add relay to a chat bridge](#add-relay-to-a-chat-bridge)
  - [Full example](#full-example)
- [Package as a plugin](#package-as-a-plugin)
- [See also](#see-also)

Reference

# Channels reference

Copy pageCopy page

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

Copy pageCopy page

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

A channel is an MCP server that pushes events into a Claude Code session so Claude can react to things happening outside the terminal. You can build a one-way or two-way channel. One-way channels forward alerts, webhooks, or monitoring events for Claude to act on. Two-way channels like chat bridges also [expose a reply tool](#expose-a-reply-tool) so Claude can send messages back. A channel with a trusted sender path can also opt in to [relay permission prompts](#relay-permission-prompts) so you can approve or deny tool use remotely. This page covers:

- [Overview](#overview): how channels work
- [What you need](#what-you-need): requirements and general steps
- [Example: build a webhook receiver](#example-build-a-webhook-receiver): a minimal one-way walkthrough
- [Server options](#server-options): the constructor fields
- [Notification format](#notification-format): the event payload and delivery behavior
- [Expose a reply tool](#expose-a-reply-tool): let Claude send messages back
- [Gate inbound messages](#gate-inbound-messages): sender checks to prevent prompt injection
- [Relay permission prompts](#relay-permission-prompts): forward tool approval prompts to remote channels

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


[​](#overview)

Overview

A channel is an [MCP](https://modelcontextprotocol.io) server that runs on the same machine as Claude Code. Claude Code spawns it as a subprocess and communicates over stdio. Your channel server is the bridge between external systems and the Claude Code session:

- **Chat platforms** (Telegram, Discord): your plugin runs locally and polls the platform’s API for new messages. When someone DMs your bot, the plugin receives the message and forwards it to Claude. No URL to expose.
- **Webhooks** (CI, monitoring): your server listens on a local HTTP port. External systems POST to that port, and your server pushes the payload to Claude.


[​](#what-you-need)

What you need

The only hard requirement is the [`@modelcontextprotocol/sdk`](https://www.npmjs.com/package/@modelcontextprotocol/sdk) package and a Node.js-compatible runtime. [Bun](https://bun.sh), [Node](https://nodejs.org), and [Deno](https://deno.com) all work. The pre-built plugins in the research preview use Bun, but your channel doesn’t have to. Your server needs to:

1.  Declare the `claude/channel` capability so Claude Code registers a notification listener
2.  Emit `notifications/claude/channel` events when something happens
3.  Connect over [stdio transport](https://modelcontextprotocol.io/docs/concepts/transports#standard-io)

The [Server options](#server-options) and [Notification format](#notification-format) sections cover each of these in detail. See [Example: build a webhook receiver](#example-build-a-webhook-receiver) for a full walkthrough. During the research preview, custom channels aren’t on the [approved allowlist](channels.md#supported-channels). Use `--dangerously-load-development-channels` to test locally. See [Test during the research preview](#test-during-the-research-preview) for details.


[​](#example-build-a-webhook-receiver)

Example: build a webhook receiver

This walkthrough builds a single-file server that listens for HTTP requests and forwards them into your Claude Code session. By the end, anything that can send an HTTP POST, like a CI pipeline, a monitoring alert, or a `curl` command, can push events to Claude. This example uses [Bun](https://bun.sh) as the runtime for its built-in HTTP server and TypeScript support. You can use [Node](https://nodejs.org) or [Deno](https://deno.com) instead; the only requirement is the [MCP SDK](https://www.npmjs.com/package/@modelcontextprotocol/sdk).

1

Create the project

The [permission relay](#relay-permission-prompts) examples import `zod` directly, so it installs alongside the MCP SDK. Create a new directory and install both:

```python
mkdir webhook-channel && cd webhook-channel
bun add @modelcontextprotocol/sdk zod
```

2

Write the channel server

Create a file called `webhook.ts`. This is your entire channel server: it connects to Claude Code over stdio, and it listens for HTTP POSTs on port 8788. When a request arrives, it pushes the body to Claude as a channel event.

webhook.ts

```python
#!/usr/bin/env bun
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'

// Create the MCP server and declare it as a channel
const mcp = new Server(
  { name: 'webhook', version: '0.0.1' },
  {
    // this key is what makes it a channel — Claude Code registers a listener for it
    capabilities: { experimental: { 'claude/channel': {} } },
    // Claude Code delivers this to Claude as context when the server connects, so it knows how to handle these events
    instructions: 'Events from the webhook channel arrive as <channel source="webhook" ...>. They are one-way: read them and act, no reply expected.',
  },
)

// Connect to Claude Code over stdio (Claude Code spawns this process)
await mcp.connect(new StdioServerTransport())

// Start an HTTP server that forwards every POST to Claude
Bun.serve({
  port: 8788,  // any open port works
  // localhost-only: nothing outside this machine can POST
  hostname: '127.0.0.1',
  async fetch(req) {
    const body = await req.text()
    await mcp.notification({
      method: 'notifications/claude/channel',
      params: {
        content: body,  // becomes the body of the <channel> tag
        // each key becomes a tag attribute, e.g. <channel path="/" method="POST">
        meta: { path: new URL(req.url).pathname, method: req.method },
      },
    })
    return new Response('ok')
  },
})
```

The file configures the server, connects over stdio, and starts an HTTP listener, in that order:

- **Server configuration**: creates the MCP server with `claude/channel` in its capabilities, which is what tells Claude Code this is a channel. Claude Code delivers the [`instructions`](#server-options) string to Claude as context when the server connects: tell Claude what events to expect, whether to reply, and how to route replies if it should.
- **Stdio connection**: connects to Claude Code over stdin/stdout. This is standard for any [MCP server](https://modelcontextprotocol.io/docs/concepts/transports#standard-io).
- **HTTP listener**: starts a local web server on port 8788. Every POST body gets forwarded to Claude as a channel event via `mcp.notification()`. The `content` becomes the event body, and each `meta` entry becomes an attribute on the `<channel>` tag. The listener needs access to the `mcp` instance, so it runs in the same process. You could split it into separate modules for a larger project.

3

Register your server with Claude Code

Add the server to your MCP config so Claude Code knows how to start it. For a project-level `.mcp.json` in the same directory, use a relative path. For user-level config in `~/.claude.json`, use the full absolute path so the server can be found from any project:

.mcp.json

```python
{
  "mcpServers": {
    "webhook": { "command": "bun", "args": ["./webhook.ts"] }
  }
}
```

Claude Code reads your MCP config at startup and spawns each server as a subprocess.

4

Test it

During the research preview, custom channels aren’t on the allowlist, so start Claude Code with the development flag:

```python
claude --dangerously-load-development-channels server:webhook
```

Claude Code first shows a full-screen warning dialog listing the development channels you’re loading. Select **I am using this for local development** to continue, or **Exit** to quit.The first time you start a session in this project, Claude Code also asks for consent before using the new server from `.mcp.json`. The dialog reports “New MCP server found in this project: webhook”. Select **Use this MCP server** to continue.After you accept, Claude Code spawns your `webhook.ts` as a subprocess, and the HTTP listener starts automatically on the port you configured, 8788 in this example. You don’t need to run the server yourself.A dim notice below the startup banner confirms the channel is registered: `Channels (experimental) messages from server:webhook inject directly in this session · restart without --dangerously-load-development-channels to stop`.If you see “blocked by org policy,” your organization admin needs to [enable channels](channels.md#enterprise-controls) first.In a separate terminal, simulate a webhook by sending an HTTP POST with a message to your server. This example sends a CI failure alert to port 8788 (or whichever port you configured):

```python
curl -X POST localhost:8788 -d "build failed on main: https://ci.example.com/run/1234"
```

The payload arrives in Claude’s context as a `<channel>` tag:

```python
<channel source="webhook" path="/" method="POST">
build failed on main: https://ci.example.com/run/1234
</channel>
```

Your terminal renders the event as a one-line summary, `← webhook: build failed on main: https://ci.example.com/run/1234`, rather than the raw tag. You’ll then see Claude start responding: reading files, running commands, or whatever the message calls for. This is a one-way channel, so Claude acts in your session but doesn’t send anything back through the webhook. To add replies, see [Expose a reply tool](#expose-a-reply-tool).If the event doesn’t arrive, the diagnosis depends on what `curl` returned:

- **`curl` succeeds but nothing reaches Claude**: run `/mcp` in your session to check the server’s status. A `failed` status usually means a dependency or import error in your server file. To see the stderr trace, restart with `claude --debug --dangerously-load-development-channels server:webhook` and check the debug log at `~/.claude/debug/<session-id>.txt`.
- **`curl` fails with “connection refused”**: the port is either not bound yet or a stale process from an earlier run is holding it. `lsof -i :<port>` shows what’s listening; `kill` the stale process before restarting your session.

The [fakechat server](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/fakechat) extends this pattern with a web UI, file attachments, and a reply tool for two-way chat.


[​](#test-during-the-research-preview)

Test during the research preview

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

```python
# Testing a plugin you're developing
claude --dangerously-load-development-channels plugin:yourplugin@yourmarketplace

# Testing a bare .mcp.json server (no plugin wrapper yet)
claude --dangerously-load-development-channels server:webhook
```

Run the development flag in an interactive session, where Claude Code can show the confirmation prompt. If you pass it in non-interactive mode with `-p` or through the Agent SDK, Claude Code ignores the flag and the channel doesn’t register. The bypass is per-entry. Combining this flag with `--channels` doesn’t extend the bypass to the `--channels` entries. During the research preview, your channel isn’t on the approved allowlist, so it stays on the development flag while you build and test.

This flag skips the allowlist only. The `channelsEnabled` organization policy still applies. Don’t use it to run channels from untrusted sources.


[​](#server-options)

Server options

A channel sets these options in the [`Server`](../06-MCP-Tools/Tutorials/learn-server-concepts.md) constructor. The `instructions` and `capabilities.tools` fields are [standard MCP](../06-MCP-Tools/Tutorials/learn-server-concepts.md); `capabilities.experimental['claude/channel']` and `capabilities.experimental['claude/channel/permission']` are the channel-specific additions:

| Field                                                    | Type                | Description                                                                                                                                                                                                                                                                                                                                                                          |
|:---------------------------------------------------------|:--------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `capabilities.experimental['claude/channel']`            | `object`            | Required. Always `{}`. Presence registers the notification listener.                                                                                                                                                                                                                                                                                                                 |
| `capabilities.experimental['claude/channel/permission']` | `object` or `false` | Optional. Set it to `{}` to declare that this channel can receive permission relay requests. When declared, Claude Code forwards tool approval prompts to your channel so you can approve or deny them remotely. To opt out, omit the key or set it to `false`. Before v2.1.234, Claude Code treated `false` as declared. See [Relay permission prompts](#relay-permission-prompts). |
| `capabilities.tools`                                     | `object`            | Two-way only. Always `{}`. Standard MCP tool capability. See [Expose a reply tool](#expose-a-reply-tool).                                                                                                                                                                                                                                                                            |
| `instructions`                                           | `string`            | Recommended. Claude Code delivers it to Claude as context when the server connects. Tell Claude what events to expect, what the `<channel>` tag attributes mean, whether to reply, and if so which tool to use and which attribute to pass back (like `chat_id`).                                                                                                                    |

To create a one-way channel, omit `capabilities.tools`. This example shows a two-way setup with the channel capability, tools, and instructions set:

```python
import { Server } from '@modelcontextprotocol/sdk/server/index.js'

const mcp = new Server(
  { name: 'your-channel', version: '0.0.1' },
  {
    capabilities: {
      experimental: { 'claude/channel': {} },  // registers the channel listener
      tools: {},  // omit for one-way channels
    },
    // Claude Code delivers this to Claude as context when the server connects, so it knows how to handle your events
    instructions: 'Messages arrive as <channel source="your-channel" ...>. Reply with the reply tool.',
  },
)
```


[​](#notification-format)

Notification format

Your server emits `notifications/claude/channel` with two params:

| Field     | Type                     | Description                                                                                                                                                                                                                                                           |
|:----------|:-------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `content` | `string`                 | The event body. Delivered as the body of the `<channel>` tag.                                                                                                                                                                                                         |
| `meta`    | `Record<string, string>` | Optional. Each entry becomes an attribute on the `<channel>` tag for routing context like chat ID, sender name, or alert severity. Keys must be identifiers: letters, digits, and underscores only. Keys containing hyphens or other characters are silently dropped. |

Your server pushes events by calling `mcp.notification()` on the `Server` instance. This example pushes a CI failure alert with two meta keys:

```python
await mcp.notification({
  method: 'notifications/claude/channel',
  params: {
    content: 'build failed on main: https://ci.example.com/run/1234',
    meta: { severity: 'high', run_id: '1234' },
  },
})
```

The event arrives in Claude’s context wrapped in a `<channel>` tag. The `source` attribute is set automatically from your server’s configured name:

```python
<channel source="your-channel" severity="high" run_id="1234">
build failed on main: https://ci.example.com/run/1234
</channel>
```

Claude Code doesn’t acknowledge notifications. The `await` on `mcp.notification()` resolves when the message is written to the transport, not when Claude has processed it. If the session hasn’t loaded your server as a channel, or the organization policy blocks it, Claude Code drops the events silently and returns no error to your server. If you need delivery confirmation, track event state in your server and expose a [reply tool](#expose-a-reply-tool) that Claude can call to report status back. Events queue into the session and are processed in order. If several notifications arrive while Claude is busy, they’re delivered together on the next turn and Claude handles them as a group. To process independent event streams concurrently, run separate sessions.


[​](#expose-a-reply-tool)

Expose a reply tool

If your channel is two-way, like a chat bridge rather than an alert forwarder, expose a standard [MCP tool](https://modelcontextprotocol.io/docs/concepts/tools) that Claude can call to send messages back. Nothing about the tool registration is channel-specific. A reply tool has three components:

1.  A `tools: {}` entry in your `Server` constructor capabilities so Claude Code discovers the tool
2.  Tool handlers that define the tool’s schema and implement the send logic
3.  An `instructions` string in your `Server` constructor that tells Claude when and how to call the tool

To add these to the [webhook receiver above](#example-build-a-webhook-receiver):

1

Enable tool discovery

In your `Server` constructor in `webhook.ts`, add `tools: {}` to the capabilities so Claude Code knows your server offers tools:

```python
capabilities: {
  experimental: { 'claude/channel': {} },
  tools: {},  // enables tool discovery
},
```

2

Register the reply tool

Add the following to `webhook.ts`. The `import` goes at the top of the file with your other imports; the two handlers go between the `Server` constructor and `mcp.connect()`. This registers a `reply` tool that Claude can call with a `chat_id` and `text`:

```python
// Add this import at the top of webhook.ts
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js'

// Claude queries this at startup to discover what tools your server offers
mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [{
    name: 'reply',
    description: 'Send a message back over this channel',
    // inputSchema tells Claude what arguments to pass
    inputSchema: {
      type: 'object',
      properties: {
        chat_id: { type: 'string', description: 'The conversation to reply in' },
        text: { type: 'string', description: 'The message to send' },
      },
      required: ['chat_id', 'text'],
    },
  }],
}))

// Claude calls this when it wants to invoke a tool
mcp.setRequestHandler(CallToolRequestSchema, async req => {
  if (req.params.name === 'reply') {
    const { chat_id, text } = req.params.arguments as { chat_id: string; text: string }
    // send() is your outbound: POST to your chat platform, or for local
    // testing the SSE broadcast shown in the full example below.
    send(`Reply to ${chat_id}: ${text}`)
    return { content: [{ type: 'text', text: 'sent' }] }
  }
  throw new Error(`unknown tool: ${req.params.name}`)
})
```

3

Update the instructions

Update the `instructions` string in your `Server` constructor so Claude knows to route replies back through the tool. This example tells Claude to pass `chat_id` from the inbound tag:

```python
instructions: 'Messages arrive as <channel source="webhook" chat_id="...">. Reply with the reply tool, passing the chat_id from the tag.'
```

Here’s the complete `webhook.ts` with two-way support. Outbound replies stream over `GET /events` using [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) (SSE), so `curl -N localhost:8788/events` can watch them live; inbound chat arrives on `POST /`:

Full webhook.ts with reply tool

```python
#!/usr/bin/env bun
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js'

// --- Outbound: write to any curl -N listeners on /events --------------------
// A real bridge would POST to your chat platform instead.
const listeners = new Set<(chunk: string) => void>()
function send(text: string) {
  const chunk = text.split('\n').map(l => `data: ${l}\n`).join('') + '\n'
  for (const emit of listeners) emit(chunk)
}

const mcp = new Server(
  { name: 'webhook', version: '0.0.1' },
  {
    capabilities: {
      experimental: { 'claude/channel': {} },
      tools: {},
    },
    instructions: 'Messages arrive as <channel source="webhook" chat_id="...">. Reply with the reply tool, passing the chat_id from the tag.',
  },
)

mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [{
    name: 'reply',
    description: 'Send a message back over this channel',
    inputSchema: {
      type: 'object',
      properties: {
        chat_id: { type: 'string', description: 'The conversation to reply in' },
        text: { type: 'string', description: 'The message to send' },
      },
      required: ['chat_id', 'text'],
    },
  }],
}))

mcp.setRequestHandler(CallToolRequestSchema, async req => {
  if (req.params.name === 'reply') {
    const { chat_id, text } = req.params.arguments as { chat_id: string; text: string }
    send(`Reply to ${chat_id}: ${text}`)
    return { content: [{ type: 'text', text: 'sent' }] }
  }
  throw new Error(`unknown tool: ${req.params.name}`)
})

await mcp.connect(new StdioServerTransport())

let nextId = 1
Bun.serve({
  port: 8788,
  hostname: '127.0.0.1',
  idleTimeout: 0,  // don't close idle SSE streams
  async fetch(req) {
    const url = new URL(req.url)

    // GET /events: SSE stream so curl -N can watch Claude's replies live
    if (req.method === 'GET' && url.pathname === '/events') {
      const stream = new ReadableStream({
        start(ctrl) {
          ctrl.enqueue(': connected\n\n')  // so curl shows something immediately
          const emit = (chunk: string) => ctrl.enqueue(chunk)
          listeners.add(emit)
          req.signal.addEventListener('abort', () => listeners.delete(emit))
        },
      })
      return new Response(stream, {
        headers: { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache' },
      })
    }

    // POST: forward to Claude as a channel event
    const body = await req.text()
    const chat_id = String(nextId++)
    await mcp.notification({
      method: 'notifications/claude/channel',
      params: {
        content: body,
        meta: { chat_id, path: url.pathname, method: req.method },
      },
    })
    return new Response('ok')
  },
})
```

See all 86 lines

The [fakechat server](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/fakechat) shows a more complete example with file attachments and message editing.


[​](#gate-inbound-messages)

Gate inbound messages

An ungated channel is a prompt injection vector. Anyone who can reach your endpoint can put text in front of Claude. A channel listening to a chat platform or a public endpoint needs a real sender check before it emits anything. Check the sender against an allowlist before calling `mcp.notification()`. This example drops any message from a sender not in the set:

```python
const allowed = new Set(loadAllowlist())  // from your access.json or equivalent

// inside your message handler, before emitting:
if (!allowed.has(message.from.id)) {  // sender, not room
  return  // drop silently
}
await mcp.notification({ ... })
```

Gate on the sender’s identity, not the chat or room identity: `message.from.id` in the example, not `message.chat.id`. In group chats, these differ, and gating on the room would let anyone in an allowlisted group inject messages into the session. The [Telegram](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/telegram) and [Discord](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/discord) channels gate on a sender allowlist the same way. They bootstrap the list by [pairing](channels.md#security). See either implementation for the full pairing flow. The [iMessage](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/imessage) channel takes a different approach: it detects the user’s own addresses from the Messages database at startup and lets them through automatically, with other senders added by handle.


[​](#relay-permission-prompts)

Relay permission prompts

When Claude calls a tool that needs approval, the local terminal dialog opens and the session waits. A two-way channel can opt in to receive the same prompt in parallel and relay it to you on another device. Both stay live: you can answer in the terminal or on your phone, and Claude Code applies whichever answer arrives first and closes the other. Relay covers tool-use approvals like `Bash`, `Write`, and `Edit`. Project trust and MCP server consent dialogs don’t relay; those only appear in the local terminal. Claude Code v2.1.234 and later sends permission requests only to servers it registered as channels for the session, so relay sits behind the same [session opt-in and organization controls](channels.md#security) as message delivery. Relay also requires you to opt the server in with `--channels` or the development flag, and requires the server to declare the permission capability.


[​](#how-relay-works)

How relay works

When a permission prompt opens, the relay loop has four steps:

1.  Claude Code generates a short request ID and notifies your server
2.  Your server forwards the prompt and ID to your chat app
3.  The remote user replies with a yes or no and that ID
4.  Your inbound handler parses the reply into a verdict, and Claude Code applies it only if the ID matches an open request

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


[​](#permission-request-fields)

Permission request fields

The outbound notification from Claude Code is `notifications/claude/channel/permission_request`. Like the [channel notification](#notification-format), the transport is standard MCP but the method and schema are Claude Code extensions. The `params` object has four string fields your server formats into the outgoing prompt:

| Field           | Description                                                                                                                                                                                                                                                                                                                                                    |
|-----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `request_id`    | Five lowercase letters drawn from `a`-`z` without `l`, so it never reads as a `1` or `I` when typed on a phone. Include it in your outgoing prompt so it can be echoed in the reply. Claude Code only accepts a verdict that carries an ID it issued. The local terminal dialog doesn’t display this ID, so your outbound handler is the only way to learn it. |
| `tool_name`     | Name of the tool Claude wants to use, for example `Bash` or `Write`.                                                                                                                                                                                                                                                                                           |
| `description`   | Human-readable summary of what this specific tool call does, never the command itself. For a Bash call this is Claude’s description of the command; when the model gives no description, the field is the constant `Run shell command` and carries zero command detail. Render `input_preview` when you have room.                                             |
| `input_preview` | The tool’s arguments as JSON-shaped display text, keyed per top-level field. For Bash this is the command; for Write, the file path and the content. Omit it from your prompt if you only have room for a one-line message. Your server decides what to show.                                                                                                  |

Clients on Claude Code v2.1.211 or later sanitize `description` and `input_preview` before relaying them. Expect three changes in the text you receive:

- Claude Code neutralizes direction-override characters, invisible characters, and quote and angle-bracket lookalikes.
- Claude Code folds each run of whitespace to a single space.
- Claude Code relays text whole up to 3,500 code points. For a longer value, you receive its start and its end around a counted `⋯ N code points elided ⋯` marker. The end of a long command still reaches the approver.

For `input_preview`, Claude Code applies the 3,500 limit to each top-level field of the arguments separately and keeps the JSON’s own structural quotes. Clients before v2.1.211 relay `description` raw and cut `input_preview` to 200 UTF-16 units with a trailing ellipsis. Clients on Claude Code v2.1.234 or later relay the marker `(value unserializable)` in place of an `input_preview` field value they can’t serialize safely, such as a circular structure or an extremely large array. You still receive the field’s key, and the preview’s other fields are unchanged. Clients on Claude Code v2.1.234 or later also mask credentials in `description` and `input_preview`. You receive `[REDACTED]` in place of a recognizable provider credential token, such as an API key or a personal access token. Expect three effects of the masking when you render the fields:

- Claude Code masks key names inside `input_preview` as well as their values. A key name you display may not match the key name in the input.
- Claude Code never masks a span that contains shell syntax, path characters, or URL characters. A mask can’t hide the command, file path, or destination being approved.
- Claude Code doesn’t mask a secret that lacks a recognizable prefix, or a secret that spans whitespace, such as a private-key block. Both reach your server unmasked.

Masking doesn’t change who receives the fields. Whatever stays unmasked goes only to servers you opted in with `--channels` or the development flag. Treat both fields as untrusted unless you control the client fleet. The verdict your server sends back is `notifications/claude/channel/permission` with two fields: `request_id` echoing the ID above, and `behavior` set to `'allow'` or `'deny'`. Allow lets the tool call proceed; deny rejects it. Neither verdict affects future calls.


[​](#add-relay-to-a-chat-bridge)

Add relay to a chat bridge

Adding permission relay to a two-way channel takes three components:

1.  A `claude/channel/permission: {}` entry under `experimental` capabilities in your `Server` constructor so Claude Code knows to forward prompts
2.  A notification handler for `notifications/claude/channel/permission_request` that formats the prompt and sends it out through your platform API
3.  A check in your inbound message handler that recognizes `yes <id>` or `no <id>` and emits a `notifications/claude/channel/permission` verdict instead of forwarding the text to Claude

Only declare the capability if your channel [authenticates the sender](#gate-inbound-messages), because anyone who can reply through your channel can approve or deny tool use in your session. To add these to a two-way chat bridge like the one assembled in [Expose a reply tool](#expose-a-reply-tool):

1

Declare the permission capability

In your `Server` constructor, add `claude/channel/permission: {}` alongside `claude/channel` under `experimental`:

```python
capabilities: {
  experimental: {
    'claude/channel': {},
    'claude/channel/permission': {},  // opt in to permission relay
  },
  tools: {},
},
```

2

Handle the incoming request

Register a notification handler between your `Server` constructor and `mcp.connect()`. Claude Code calls it with the [four request fields](#permission-request-fields) when a permission dialog opens. Your handler formats the prompt for your platform and includes instructions for replying with the ID:

```python
import { z } from 'zod'

// setNotificationHandler routes by z.literal on the method field,
// so this schema is both the validator and the dispatch key
const PermissionRequestSchema = z.object({
  method: z.literal('notifications/claude/channel/permission_request'),
  params: z.object({
    request_id: z.string(),     // five lowercase letters, include verbatim in your prompt
    tool_name: z.string(),      // e.g. "Bash", "Write"
    description: z.string(),    // summary of this call. Treat as untrusted.
    input_preview: z.string(),  // tool args as JSON-shaped text. Treat as untrusted.
  }),
})

mcp.setNotificationHandler(PermissionRequestSchema, async ({ params }) => {
  // send() is your outbound: POST to your chat platform, or for local
  // testing the SSE broadcast shown in the full example below.
  send(
    `Claude wants to run ${params.tool_name}: ${params.description}\n` +
    // input_preview carries the actual arguments; render it when you
    // have room: for Bash the description alone may be just
    // "Run shell command" with zero command detail
    `${params.input_preview}\n\n` +
    // the ID in the instruction is what your inbound handler parses in Step 3
    `Reply "yes ${params.request_id}" or "no ${params.request_id}"`,
  )
})
```

3

Intercept the verdict in your inbound handler

Your inbound handler is the loop or callback that receives messages from your platform: the same place you [gate on sender](#gate-inbound-messages) and emit `notifications/claude/channel` to forward chat to Claude. Add a check before the chat-forwarding call that recognizes the verdict format and emits the permission notification instead.The regex matches the ID format Claude Code generates: five letters, never `l`. The `/i` flag tolerates phone autocorrect capitalizing the reply; lowercase the captured ID before sending it back.

```python
// matches "y abcde", "yes abcde", "n abcde", "no abcde"
// [a-km-z] is the ID alphabet Claude Code uses (lowercase, skips 'l')
// /i tolerates phone autocorrect; lowercase the capture before sending
const PERMISSION_REPLY_RE = /^\s*(y|yes|n|no)\s+([a-km-z]{5})\s*$/i

async function onInbound(message: PlatformMessage) {
  if (!allowed.has(message.from.id)) return  // gate on sender first

  const m = PERMISSION_REPLY_RE.exec(message.text)
  if (m) {
    // m[1] is the verdict word, m[2] is the request ID
    // emit the verdict notification back to Claude Code instead of chat
    await mcp.notification({
      method: 'notifications/claude/channel/permission',
      params: {
        request_id: m[2].toLowerCase(),  // normalize in case of autocorrect caps
        behavior: m[1].toLowerCase().startsWith('y') ? 'allow' : 'deny',
      },
    })
    return  // handled as verdict, don't also forward as chat
  }

  // didn't match verdict format: fall through to the normal chat path
  await mcp.notification({
    method: 'notifications/claude/channel',
    params: { content: message.text, meta: { chat_id: String(message.chat.id) } },
  })
}
```

A remote reply that doesn’t exactly match the expected format fails in one of two ways, and in both cases the local terminal dialog stays open:

- **Different format**: your inbound handler’s regex fails to match, so text like `approve it` or `yes` without an ID falls through as a normal message to Claude.
- **Right format, wrong ID**: your server emits a verdict, but Claude Code finds no open request with that ID and drops it silently.


[​](#full-example)

Full example

The assembled `webhook.ts` below combines all three extensions from this page: the reply tool, sender gating, and permission relay. If you’re starting here, you’ll also need the [project setup and `.mcp.json` entry](#example-build-a-webhook-receiver) from the initial walkthrough. To make both directions testable from curl, the HTTP listener serves two paths:

- **`GET /events`**: holds an SSE stream open and pushes each outbound message as a `data:` line, so `curl -N` can watch Claude’s replies and permission prompts arrive live.
- **`POST /`**: the inbound side, the same handler as earlier, now with the verdict-format check inserted before the chat-forward branch.

Full webhook.ts with permission relay

```python
#!/usr/bin/env bun
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js'
import { z } from 'zod'

// --- Outbound: write to any curl -N listeners on /events --------------------
// A real bridge would POST to your chat platform instead.
const listeners = new Set<(chunk: string) => void>()
function send(text: string) {
  const chunk = text.split('\n').map(l => `data: ${l}\n`).join('') + '\n'
  for (const emit of listeners) emit(chunk)
}

// Sender allowlist. For the local walkthrough we trust the single X-Sender
// header value "dev"; a real bridge would check the platform's user ID.
const allowed = new Set(['dev'])

const mcp = new Server(
  { name: 'webhook', version: '0.0.1' },
  {
    capabilities: {
      experimental: {
        'claude/channel': {},
        'claude/channel/permission': {},  // opt in to permission relay
      },
      tools: {},
    },
    instructions:
      'Messages arrive as <channel source="webhook" chat_id="...">. ' +
      'Reply with the reply tool, passing the chat_id from the tag.',
  },
)

// --- reply tool: Claude calls this to send a message back -------------------
mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [{
    name: 'reply',
    description: 'Send a message back over this channel',
    inputSchema: {
      type: 'object',
      properties: {
        chat_id: { type: 'string', description: 'The conversation to reply in' },
        text: { type: 'string', description: 'The message to send' },
      },
      required: ['chat_id', 'text'],
    },
  }],
}))

mcp.setRequestHandler(CallToolRequestSchema, async req => {
  if (req.params.name === 'reply') {
    const { chat_id, text } = req.params.arguments as { chat_id: string; text: string }
    send(`Reply to ${chat_id}: ${text}`)
    return { content: [{ type: 'text', text: 'sent' }] }
  }
  throw new Error(`unknown tool: ${req.params.name}`)
})

// --- permission relay: Claude Code (not Claude) calls this when a dialog opens
const PermissionRequestSchema = z.object({
  method: z.literal('notifications/claude/channel/permission_request'),
  params: z.object({
    request_id: z.string(),
    tool_name: z.string(),
    description: z.string(),
    input_preview: z.string(),
  }),
})

mcp.setNotificationHandler(PermissionRequestSchema, async ({ params }) => {
  send(
    `Claude wants to run ${params.tool_name}: ${params.description}\n` +
    `${params.input_preview}\n\n` +
    `Reply "yes ${params.request_id}" or "no ${params.request_id}"`,
  )
})

await mcp.connect(new StdioServerTransport())

// --- HTTP on :8788: GET /events streams outbound, POST routes inbound -------
const PERMISSION_REPLY_RE = /^\s*(y|yes|n|no)\s+([a-km-z]{5})\s*$/i
let nextId = 1

Bun.serve({
  port: 8788,
  hostname: '127.0.0.1',
  idleTimeout: 0,  // don't close idle SSE streams
  async fetch(req) {
    const url = new URL(req.url)

    // GET /events: SSE stream so curl -N can watch replies and prompts live
    if (req.method === 'GET' && url.pathname === '/events') {
      const stream = new ReadableStream({
        start(ctrl) {
          ctrl.enqueue(': connected\n\n')  // so curl shows something immediately
          const emit = (chunk: string) => ctrl.enqueue(chunk)
          listeners.add(emit)
          req.signal.addEventListener('abort', () => listeners.delete(emit))
        },
      })
      return new Response(stream, {
        headers: { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache' },
      })
    }

    // everything else is inbound: gate on sender first
    const body = await req.text()
    const sender = req.headers.get('X-Sender') ?? ''
    if (!allowed.has(sender)) return new Response('forbidden', { status: 403 })

    // check for verdict format before treating as chat
    const m = PERMISSION_REPLY_RE.exec(body)
    if (m) {
      await mcp.notification({
        method: 'notifications/claude/channel/permission',
        params: {
          request_id: m[2].toLowerCase(),
          behavior: m[1].toLowerCase().startsWith('y') ? 'allow' : 'deny',
        },
      })
      return new Response('verdict recorded')
    }

    // normal chat: forward to Claude as a channel event
    const chat_id = String(nextId++)
    await mcp.notification({
      method: 'notifications/claude/channel',
      params: { content: body, meta: { chat_id, path: url.pathname } },
    })
    return new Response('ok')
  },
})
```

See all 133 lines

Test the verdict path in three terminals. The first is your Claude Code session, started with the [development flag](#test-during-the-research-preview) so it spawns `webhook.ts`:

```python
claude --dangerously-load-development-channels server:webhook
```

This walkthrough tests the permission dialog itself, so once the session is open, press `Shift+Tab` until the status bar shows `⏸ manual mode on`. In auto mode the classifier would decide the `reply` call instead of you, and no dialog would open for the remote side to answer. In the second, stream the outbound side so you can see Claude’s replies and any permission prompts as they fire:

```python
curl -N localhost:8788/events
```

In the third, send a message that will make Claude try to run a command:

```python
curl -d "list the files in this directory" -H "X-Sender: dev" localhost:8788
```

Listing files is read-only, so Claude runs it without approval. The permission dialog opens when Claude calls the `reply` tool to send its answer back. The local dialog opens in your Claude Code terminal, and a moment later the prompt for `mcp__webhook__reply` appears in the `/events` stream, including the five-letter ID. Approve it from the remote side:

```python
curl -d "yes <id>" -H "X-Sender: dev" localhost:8788
```

The local dialog closes, the `reply` tool runs, and Claude’s reply appears in the stream. The three channel-specific pieces in this file:

- **Capabilities** in the `Server` constructor: `claude/channel` registers the notification listener, `claude/channel/permission` opts in to permission relay, `tools` lets Claude discover the reply tool.
- **Outbound paths**: the `reply` tool handler is what Claude calls for conversational responses; the `PermissionRequestSchema` notification handler is what Claude Code calls when a permission dialog opens. Both call `send()` to broadcast over `/events`, but they’re triggered by different parts of the system.
- **HTTP handler**: `GET /events` holds an SSE stream open so curl can watch outbound live; `POST` is inbound, gated on the `X-Sender` header. A `yes <id>` or `no <id>` body goes to Claude Code as a verdict notification and never reaches Claude; anything else is forwarded to Claude as a channel event.


[​](#package-as-a-plugin)

Package as a plugin

To make your channel installable and shareable, wrap it in a [plugin](../08-Plugins-Skills/plugins.md) and publish it to a [marketplace](../08-Plugins-Skills/plugins.md). Users install it with `/plugin install`, then enable it per session with `--channels plugin:<name>@<marketplace>`. A channel published to your own marketplace still needs `--dangerously-load-development-channels` to run, since it isn’t on the [approved allowlist](channels.md#supported-channels). The default allowlist is the channel plugins in `claude-plugins-official`. The community marketplace is not on the channel allowlist. If you are working with an Anthropic partner contact, reach out to them to coordinate an official-marketplace listing. On Team and Enterprise plans, an admin can instead include your plugin in the organization’s own [`allowedChannelPlugins`](channels.md#restrict-which-channel-plugins-can-run) list, which replaces the default Anthropic allowlist.


[​](#see-also)

See also

- [Channels](channels.md) to install and use Telegram, Discord, iMessage, or the fakechat demo, and to enable channels for a Team or Enterprise org
- [Working channel implementations](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins) for complete server code with pairing flows, reply tools, and file attachments
- [MCP](../06-MCP-Tools/General/mcp.md) for the underlying protocol that channel servers implement
- [Plugins](../08-Plugins-Skills/plugins.md) to package your channel so users can install it with `/plugin install`

---

## Push events into a running session with channels - Claude Code Docs

Source: https://code.claude.com/docs/en/channels
Path: 02-Claude-Code-CLI/channels.md

## On this page

- [Supported channels](#supported-channels)
- [Quickstart](#quickstart)
- [Security](#security)
- [Enterprise controls](#enterprise-controls)
  - [Enable channels for your organization](#enable-channels-for-your-organization)
  - [Restrict which channel plugins can run](#restrict-which-channel-plugins-can-run)
- [Research preview](#research-preview)
- [How channels compare](#how-channels-compare)
- [Next steps](#next-steps)

Automation

# Push events into a running session with channels

Copy pageCopy page

Use channels to push messages, alerts, and webhooks into your Claude Code session from an MCP server. Forward CI results, chat messages, and monitoring events so Claude can react while you’re away.

Copy pageCopy page

Channels are in [research preview](#research-preview). They require Anthropic authentication through claude.ai or a Console API key, and are not available on Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry. Team and Enterprise organizations must [explicitly enable them](#enterprise-controls).

A channel is an MCP server that pushes events into your running Claude Code session, so Claude can react to things that happen while you’re not at the terminal. Channels can be two-way: Claude reads the event and replies back through the same channel, like a chat bridge. Events only arrive while the session is open, so for an always-on setup you run Claude in a background process or persistent terminal. Unlike integrations that spawn a fresh cloud session or wait to be polled, the event arrives in the session you already have open: see [how channels compare](#how-channels-compare). You install a channel as a plugin and configure it with your own credentials. Telegram, Discord, and iMessage are included in the research preview. When Claude replies through a channel, you see the inbound message in your terminal but not the reply text. The terminal shows the tool call and a confirmation (like “sent”), and the actual reply appears on the other platform. If you manage a Team, Enterprise, or Console organization, see [Enable channels for your organization](#enterprise-controls). To build your own channel, see the [Channels reference](channels-reference.md).


[​](#supported-channels)

Supported channels

Each supported channel is a plugin that requires [Bun](https://bun.sh). For a hands-on demo of the plugin flow before connecting a real platform, try the [fakechat quickstart](#quickstart).

- Telegram

- Discord

- iMessage

View the full [Telegram plugin source](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/telegram).

1

Create a Telegram bot

Open [BotFather](https://t.me/BotFather) in Telegram and send `/newbot`. Give it a display name and a unique username ending in `bot`. Copy the token BotFather returns.

2

Install the plugin

Start Claude Code by running `claude` in your terminal, then enter this at its prompt:

```python
/plugin install telegram@claude-plugins-official
```

If the install fails, match the message Claude Code reports:

- `Marketplace "claude-plugins-official" not found`: add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`, then retry the install.
- `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](../08-Plugins-Skills/plugins-troubleshooting.md#plugin-not-found-in-marketplace).

When the install asks for an installation scope, choose the user scope option so the plugin is available across all your projects. Check the install summary: if it reports `Run /reload-plugins to apply.`, see [Apply plugin changes without restarting](../08-Plugins-Skills/plugins-cli-reference.md#reload-plugins) to make the plugin’s configure command available.

3

Configure your token

Run the configure command with the token from BotFather:

```python
/telegram:configure <token>
```

This saves it to `~/.claude/channels/telegram/.env`. You can also set `TELEGRAM_BOT_TOKEN` in your shell environment before launching Claude Code.

4

Restart with channels enabled

Exit Claude Code and restart with the channel flag. This starts the Telegram plugin, which begins polling for messages from your bot:

```python
claude --channels plugin:telegram@claude-plugins-official
```

5

Pair your account

Open Telegram and send any message to your bot. The bot replies with a pairing code.

If your bot doesn’t respond, make sure Claude Code is running with `--channels` from the previous step. The bot can only reply while the channel is active.

Back in Claude Code, run:

```python
/telegram:access pair <code>
```

Then lock down access so only your account can send messages:

```python
/telegram:access policy allowlist
```

View the full [Discord plugin source](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/discord).

1

Create a Discord bot

Go to the [Discord Developer Portal](https://discord.com/developers/applications), click **New Application**, and name it. In the **Bot** section, create a username, then click **Reset Token** and copy the token.

2

Enable Message Content Intent

In your bot’s settings, scroll to **Privileged Gateway Intents** and enable **Message Content Intent**.

3

Invite the bot to your server

Go to **OAuth2 \> URL Generator**. Select the `bot` scope and enable these permissions:

- View Channels
- Send Messages
- Send Messages in Threads
- Read Message History
- Attach Files
- Add Reactions

Open the generated URL to add the bot to your server.

4

Install the plugin

Start Claude Code by running `claude` in your terminal, then enter this at its prompt:

```python
/plugin install discord@claude-plugins-official
```

If the install fails, match the message Claude Code reports:

- `Marketplace "claude-plugins-official" not found`: add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`, then retry the install.
- `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](../08-Plugins-Skills/plugins-troubleshooting.md#plugin-not-found-in-marketplace).

When the install asks for an installation scope, choose the user scope option so the plugin is available across all your projects. Check the install summary: if it reports `Run /reload-plugins to apply.`, see [Apply plugin changes without restarting](../08-Plugins-Skills/plugins-cli-reference.md#reload-plugins) to make the plugin’s configure command available.

5

Configure your token

Run the configure command with the bot token you copied:

```python
/discord:configure <token>
```

This saves it to `~/.claude/channels/discord/.env`. You can also set `DISCORD_BOT_TOKEN` in your shell environment before launching Claude Code.

6

Restart with channels enabled

Exit Claude Code and restart with the channel flag. This connects the Discord plugin so your bot can receive and respond to messages:

```python
claude --channels plugin:discord@claude-plugins-official
```

7

Pair your account

DM your bot on Discord. The bot replies with a pairing code.

If your bot doesn’t respond, make sure Claude Code is running with `--channels` from the previous step. The bot can only reply while the channel is active.

Back in Claude Code, run:

```python
/discord:access pair <code>
```

Then lock down access so only your account can send messages:

```python
/discord:access policy allowlist
```

View the full [iMessage plugin source](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/imessage).The iMessage channel reads your Messages database directly and sends replies through AppleScript. It requires macOS and needs no bot token or external service.

1

Grant Full Disk Access

The Messages database at `~/Library/Messages/chat.db` is protected by macOS. The first time the server reads it, macOS prompts for access: click **Allow**. The prompt names whichever app launched Bun, such as Terminal, iTerm, or your IDE.If the prompt doesn’t appear or you clicked Don’t Allow, grant access manually under **System Settings \> Privacy & Security \> Full Disk Access** and add your terminal. Without this, the server exits immediately with `authorization denied`.

2

Install the plugin

Start Claude Code by running `claude` in your terminal, then enter this at its prompt:

```python
/plugin install imessage@claude-plugins-official
```

If the install fails, match the message Claude Code reports:

- `Marketplace "claude-plugins-official" not found`: add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`, then retry the install.
- `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](../08-Plugins-Skills/plugins-troubleshooting.md#plugin-not-found-in-marketplace).

When the install asks for an installation scope, choose the user scope option so the plugin is available across all your projects.If the install summary reports `Run /reload-plugins to apply.`, you don’t need to act on it here, because restarting in the next step picks up the plugin.

3

Restart with channels enabled

Exit Claude Code and restart with the channel flag:

```python
claude --channels plugin:imessage@claude-plugins-official
```

4

Text yourself

Open Messages on any device signed into your Apple ID and send a message to yourself. It reaches Claude immediately: self-chat bypasses access control with no setup.

The first reply Claude sends triggers a macOS Automation prompt asking if your terminal can control Messages. Click **OK**.

5

Allow other senders

By default, only your own messages pass through. To let another contact reach Claude, add their handle:

```python
/imessage:access allow +15551234567
```

Handles are phone numbers in `+country` format or Apple ID emails like `user@example.com`.


[​](#quickstart)

Quickstart

Fakechat is an officially supported demo channel that runs a chat UI on localhost, with nothing to authenticate and no external service to configure. Once you install and enable fakechat, you can type in the browser and the message arrives in your Claude Code session. Claude replies, and the reply shows up back in the browser. After you’ve tested the fakechat interface, try out [Telegram](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/telegram), [Discord](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/discord), or [iMessage](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/imessage). To try the fakechat demo, you’ll need:

- Claude Code [installed and authenticated](../01-Getting-Started/quickstart.md#step-1-install-claude-code) with a claude.ai account or a Claude Console API key
- [Bun](https://bun.sh) installed. The pre-built channel plugins are Bun scripts. Check with `bun --version`; if that fails, [install Bun](https://bun.sh/docs/installation).
- **Team, Enterprise, or managed Console org**: your admin must [enable channels](#enterprise-controls) in managed settings

1

Install the fakechat channel plugin

Start Claude Code by running `claude` in your terminal, then enter the install command at its prompt:

```python
/plugin install fakechat@claude-plugins-official
```

If the install fails, match the message Claude Code reports:

- `Marketplace "claude-plugins-official" not found`: add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`, then retry the install.
- `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](../08-Plugins-Skills/plugins-troubleshooting.md#plugin-not-found-in-marketplace).

When the install asks for an installation scope, choose the user scope option so the plugin is available across all your projects.If the install summary reports `Run /reload-plugins to apply.`, you don’t need to act on it here, because restarting in the next step picks up the plugin.

2

Restart with the channel enabled

Exit Claude Code, then restart with `--channels` and pass the fakechat plugin you installed:

```python
claude --channels plugin:fakechat@claude-plugins-official
```

The fakechat server starts automatically. The startup screen shows a channels notice stating that messages from `plugin:fakechat@claude-plugins-official` inject directly in this session. If the plugin isn’t installed or isn’t on the approved allowlist, a warning line naming the problem appears below that notice.

You can pass several plugins to `--channels`, space-separated.

3

Push a message in

Open the fakechat UI at [http://localhost:8787](http://localhost:8787) and type a message:

```python
what's in my working directory?
```

The message arrives in your Claude Code session. The terminal shows it as an inbound channel line like `← fakechat · web: what's in my working directory?`, while the model receives it as a `<channel source="plugin:fakechat:fakechat">` event, using the plugin’s scoped server name. Claude reads it, does the work, and calls fakechat’s `reply` tool. If Claude Code asks for permission for the first reply, approve it. The answer shows up in the chat UI.

If Claude hits a permission prompt while you’re away from the terminal, the session pauses until you respond. Channel servers that declare the [permission relay capability](channels-reference.md#relay-permission-prompts) can forward these prompts to you so you can approve or deny remotely. For unattended use, [`--dangerously-skip-permissions`](permission-modes.md#skip-all-checks-with-bypasspermissions-mode) bypasses most prompts, but only use it in environments you trust. Even then, the [actions no mode auto-approves](permission-modes.md#actions-no-mode-auto-approves) still apply. When you run channels in non-interactive mode with `-p`, tools that need terminal input, such as multiple-choice questions and plan mode approval, are disabled so the session never stalls waiting for input.


[​](#security)

Security

Every approved channel plugin maintains a sender allowlist: only IDs you’ve added can push messages, and everyone else is silently dropped. Telegram and Discord bootstrap the list by pairing:

1.  Find your bot in Telegram or Discord and send it any message
2.  The bot replies with a pairing code
3.  In your Claude Code session, approve the code when prompted
4.  Your sender ID is added to the allowlist

iMessage works differently: texting yourself bypasses the gate automatically, and you add other contacts by handle with `/imessage:access allow`. On top of that, you control which servers are enabled each session with `--channels`, and your organization controls availability with [`channelsEnabled`](#enterprise-controls) on claude.ai Team and Enterprise plans and on Console organizations that deploy managed settings. Being in `.mcp.json` isn’t enough to push messages: a server also has to be named in `--channels`. The allowlist also gates [permission relay](channels-reference.md#relay-permission-prompts) if the channel declares it. Anyone who can reply through the channel can approve or deny tool use in your session, so only allowlist senders you trust with that authority.


[​](#enterprise-controls)

Enterprise controls

Admins control availability through two [managed settings](settings.md) that users cannot override. The default depends on how you authenticate:

- **claude.ai Team and Enterprise**: channels are blocked until an Owner [enables them](#enable-channels-for-your-organization).
- **Anthropic Console with API key authentication**: channels are permitted by default. You only need this setting if your organization deploys managed settings.

In all cases, no channel runs until a user opts it in for the session with `--channels`.

| Setting                 | Purpose                                                                                                                                                                                                              | When not configured                                                                                                                                                                    |
|:------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `channelsEnabled`       | Master switch. Must be `true` for any channel to deliver messages. Blocks all channels including the development flag when off. See [Enable channels for your organization](#enable-channels-for-your-organization). | claude.ai Team and Enterprise: channels blocked. Console: channels allowed unless your organization deploys managed settings, in which case channels are blocked until this key is set |
| `allowedChannelPlugins` | Which plugins can register once channels are enabled. Replaces the Anthropic-maintained list when set.                                                                                                               | Anthropic default list applies                                                                                                                                                         |

Pro and Max users without an organization skip these checks entirely: channels are available and users opt in per session with `--channels`.


[​](#enable-channels-for-your-organization)

Enable channels for your organization

Enable channels for your organization from [**Organization settings \> Claude Code \> Channels**](https://claude.ai/admin-settings/claude-code), which requires the Owner role, or by setting `channelsEnabled` to `true` in managed settings. Once enabled, users in your organization can use `--channels` to opt channel servers into individual sessions. If the setting is disabled or unset, the MCP server still connects and its tools work, but channel messages won’t arrive. A startup warning tells the user to have an admin enable the setting.


[​](#restrict-which-channel-plugins-can-run)

Restrict which channel plugins can run

By default, any plugin on the Anthropic-maintained allowlist can register as a channel. Admins on Team and Enterprise plans can replace that allowlist with their own by setting `allowedChannelPlugins` in managed settings. Use this to restrict which official plugins are allowed, approve channels from your own internal marketplace, or both. Each entry names a plugin and the marketplace it comes from:

```python
{
  "channelsEnabled": true,
  "allowedChannelPlugins": [
    { "marketplace": "claude-plugins-official", "plugin": "telegram" },
    { "marketplace": "claude-plugins-official", "plugin": "discord" },
    { "marketplace": "acme-corp-plugins", "plugin": "internal-alerts" }
  ]
}
```

If you set an empty array, you block all channel plugins from the allowlist, but `--dangerously-load-development-channels` can still bypass that block for local testing. To block channels entirely including the development flag, leave `channelsEnabled` unset instead. This setting requires `channelsEnabled: true`. If a user passes a plugin to `--channels` that isn’t on your list, Claude Code starts normally but the channel doesn’t register, and the startup notice explains that the plugin isn’t on the organization’s approved list. On the v2 MCP client runtime, a channel can also fail to register because Claude Code [doesn’t register a channel server that negotiates protocol revision 2026-07-28](../06-MCP-Tools/General/mcp.md#push-messages-with-channels).


[​](#research-preview)

Research preview

Channels are a research preview feature. Availability is rolling out gradually, and the `--channels` flag syntax and protocol contract may change based on feedback. Neither `--channels` nor `--dangerously-load-development-channels` appears in `claude --help` while the feature is in preview. The flags work even though they aren’t listed. During the preview, `--channels` only accepts plugins from an Anthropic-maintained allowlist, or from your organization’s allowlist if an admin has set [`allowedChannelPlugins`](#restrict-which-channel-plugins-can-run). The channel plugins in [claude-plugins-official](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins) are the default approved set. If you pass something that isn’t on the effective allowlist, Claude Code starts normally but the channel doesn’t register, and the startup notice tells you why. To test a channel you’re building, pass it to `--dangerously-load-development-channels` in the `plugin:<name>@<marketplace>` or `server:<name>` form. See [Test during the research preview](channels-reference.md#test-during-the-research-preview) for information about testing custom channels that you build. Report issues or feedback on the [Claude Code GitHub repository](https://github.com/anthropics/claude-code/issues).


[​](#how-channels-compare)

How channels compare

Several Claude Code features connect to systems outside the terminal, each suited to a different kind of work:

| Feature                                           | What it does                                                            | Good for                                                  |
|---------------------------------------------------|-------------------------------------------------------------------------|-----------------------------------------------------------|
| [Cloud sessions](claude-code-on-the-web.md) | Run tasks in a fresh cloud sandbox, cloned from GitHub                  | Delegating self-contained async work you check on later   |
| [Claude in Slack](../14-Connectors/slack.md)                 | Spawns a cloud session from an `@Claude` mention in a channel or thread | Starting tasks directly from team conversation context    |
| Standard [MCP server](../06-MCP-Tools/General/mcp.md)               | Claude queries it during a task; nothing is pushed to the session       | Giving Claude on-demand access to read or query a system  |
| [Remote Control](remote-control.md)         | You drive your local session from claude.ai or the Claude mobile app    | Steering an in-progress session while away from your desk |

Channels fill the gap in that list by pushing events from non-Claude sources into your already-running local session.

- **Chat bridge**: ask Claude something from your phone via Telegram, Discord, or iMessage, and the answer comes back in the same chat while the work runs on your machine against your real files.
- **[Webhook receiver](channels-reference.md#example-build-a-webhook-receiver)**: a webhook from CI, your error tracker, a deploy pipeline, or other external service arrives where Claude already has your files open and remembers what you were debugging.


[​](#next-steps)

Next steps

Once you have a channel running, explore these related features:

- [Build your own channel](channels-reference.md) for systems that don’t have plugins yet
- [Remote Control](remote-control.md) to drive a local session from your phone instead of forwarding events into it
- [Session-scoped scheduled tasks](scheduled-tasks.md) to poll on a timer instead of reacting to pushed events

---

## Checkpointing - Claude Code Docs

Source: https://code.claude.com/docs/en/checkpointing
Path: 02-Claude-Code-CLI/checkpointing.md

## On this page

- [How checkpoints work](#how-checkpoints-work)
  - [Automatic tracking](#automatic-tracking)
  - [Rewind and summarize](#rewind-and-summarize)
  - [Rewound messages can return if you exit before your next prompt](#rewound-messages-can-return-if-you-exit-before-your-next-prompt)
  - [Rewind past a cleared conversation](#rewind-past-a-cleared-conversation)
  - [Guide a summary](#guide-a-summary)
- [Common use cases](#common-use-cases)
- [Limitations](#limitations)
  - [Bash command changes not tracked](#bash-command-changes-not-tracked)
  - [Subagent edits not restored](#subagent-edits-not-restored)
  - [External changes not tracked](#external-changes-not-tracked)
  - [Messages sent mid-turn not checkpointed](#messages-sent-mid-turn-not-checkpointed)
  - [Symlinked and hard-linked paths not restored](#symlinked-and-hard-linked-paths-not-restored)
  - [Not a replacement for version control](#not-a-replacement-for-version-control)
- [See also](#see-also)

Reference

# Checkpointing

Copy pageCopy page

Track, rewind, and summarize Claude’s edits and conversation to manage session state.

Copy pageCopy page

Claude Code automatically tracks Claude’s file edits as you work, allowing you to quickly undo changes and rewind to previous states if anything gets off track.


[​](#how-checkpoints-work)

How checkpoints work

As you work with Claude, checkpointing automatically captures the state of your code before each prompt you send that starts a turn.


[​](#automatic-tracking)

Automatic tracking

Claude Code tracks all changes made by its file editing tools:

- Every prompt you send that starts a turn creates a new checkpoint
- Claude Code keeps file snapshots for the 100 most recent checkpoints in a session. Discarding an older checkpoint deletes the snapshot files that no remaining checkpoint references, except each file’s first snapshot, which the VS Code extension uses as the baseline for its session diffs.
- Claude Code saves checkpoints with the conversation, so you can still run `/rewind` after you resume a session
- Claude Code deletes a session’s file snapshots in the [retention sweep](claude-directory.md#cleaned-up-automatically), by default about 30 days after the session last saved one. Rewinding to a checkpoint whose snapshots are gone can fail with [`No files were restored`](errors.md#no-files-were-restored). To keep snapshots longer, set [`cleanupPeriodDays`](settings-reference.md#cleanupperioddays).


[​](#rewind-and-summarize)

Rewind and summarize

Run `/rewind`, or press `Esc` twice when the prompt input is empty, to open the rewind menu.

If the prompt input contains text, double `Esc` clears it instead of opening the menu. The cleared text is saved to your input history, so press `Up` to recall it after you finish in the rewind menu.

The rewind menu lists the prompts you sent during the session. Select the point you want to act on, then choose an action:

- **Restore code and conversation**: revert both code and conversation to that point
- **Restore conversation**: rewind to that message while keeping current code
- **Restore code**: revert file changes while keeping the conversation
- **Summarize from here**: compress the conversation from this point forward into a summary, freeing context window space
- **Summarize up to here**: compress the conversation before this point into a summary, keeping later messages intact
- **Never mind**: return to the message list without making changes

The two code restore options appear only when the selected checkpoint has tracked file changes to revert. If no file edits were captured after that point, the menu offers only **Restore conversation**, the summarize options, and **Never mind**. After restoring the conversation or choosing Summarize from here, the original prompt from the selected message is restored into the input field so you can re-send or edit it. Choosing Summarize up to here leaves you at the end of the conversation with the input empty. With either summarize option, a **Summarized conversation** marker appears in the conversation where the compressed messages were.


[​](#rewound-messages-can-return-if-you-exit-before-your-next-prompt)

Rewound messages can return if you exit before your next prompt

To remove the returned messages again, run `/rewind` in the session and select the same prompt, then **Restore conversation**. Before you exit, send Claude a prompt, because Claude Code saves the rewound conversation together with that prompt. Files you restored stay as the rewind left them.


[​](#rewind-past-a-cleared-conversation)

Rewind past a cleared conversation

If you ran `/clear` earlier in the same Claude Code process, the rewind menu shows an additional entry at the top of the list labeled `/resume <session-id> (previous session)`. Select it to resume the conversation that was active before `/clear` ran. The entry is available until you exit Claude Code or resume a different session.


[​](#guide-a-summary)

Guide a summary

Summarizing doesn’t change files on disk, and the original messages stay in the session transcript, so Claude can still reference the details. To guide what the summary focuses on, highlight a **Summarize** option with the arrow keys and type instructions where the row reads **add context (optional)**, then press `Enter`. Selecting the option with its number key summarizes immediately without instructions.

Summarize keeps you in the same session and compresses context, like a targeted `/compact`. To branch off and try a different approach while preserving the original session intact, use [`/branch`](sessions.md#branch-a-session) or `claude --continue --fork-session` instead.


[​](#common-use-cases)

Common use cases

Checkpoints are particularly useful when:

- **Exploring alternatives**: try different implementation approaches without losing your starting point
- **Recovering from mistakes**: quickly undo changes that introduced bugs or broke functionality
- **Iterating on features**: experiment with variations knowing you can revert to working states
- **Freeing context space**: summarize a verbose debugging session from the midpoint forward, keeping your initial instructions intact


[​](#limitations)

Limitations


[​](#bash-command-changes-not-tracked)

Bash command changes not tracked

Once Claude has edited a file with its file editing tools in your conversation, `/rewind` undoes changes that Bash commands make to that file afterward. A file that only Bash commands changed isn’t tracked and stays as it is. To revert it, use version control, such as Git. Under each prompt, the rewind menu counts changes to files Claude had already edited, whatever made them. A prompt where a shell command changed such a file lists file changes too.


[​](#subagent-edits-not-restored)

Subagent edits not restored

A [subagent](../09-Agents-Patterns/sub-agents.md) makes edits with Claude’s file editing tools, but Claude Code usually doesn’t capture those edits in your session’s checkpoints. Whether rewinding restores them depends on how the subagent runs:

- **Foreground forked skill**: a [skill with `context: fork`](../08-Plugins-Skills/skills.md#run-skills-in-a-subagent) that runs in the foreground edits your working tree during your own turn, so rewinding restores its edits as usual. Set `background: false` to run a fork in the foreground; a few situations, [listed on the skills page](../08-Plugins-Skills/skills.md#run-skills-in-a-subagent), run it there regardless of the setting.
- **Any other subagent**: rewinding restores only the files Claude had already edited in your conversation. The subagent’s edits to other files stay, so use version control, such as Git, to revert them. This includes a forked skill that runs in the background, the default, and a background [`/code-review --fix`](code-review-local.md) run.


[​](#external-changes-not-tracked)

External changes not tracked

Checkpointing only tracks files that have been edited within the current session. Manual changes you make to files outside of Claude Code and edits from other concurrent sessions are normally not captured, unless they happen to modify the same files as the current session.


[​](#messages-sent-mid-turn-not-checkpointed)

Messages sent mid-turn not checkpointed

In the rewind menu, a message you [typed while Claude was still working](interactive-mode.md#queue-messages-while-claude-works) can be marked **No code restore**. Claude read that message before its turn ended. [Checkpoints are taken for prompts that start a turn](#how-checkpoints-work), so this message has none of its own. The edits Claude made after reading it count toward the prompt that started the turn. You don’t need to do anything about the message itself. To undo the file changes from that part of the session, select the prompt that started the turn and choose **Restore code** or **Restore code and conversation**. That reverts Claude’s file edits from the whole turn, including the ones from before your message arrived. Selecting the marked message still offers **Restore conversation**, which rewinds the conversation to it and leaves your files as they are.


[​](#symlinked-and-hard-linked-paths-not-restored)

Symlinked and hard-linked paths not restored

Checkpointing doesn’t rewind symlinked or hard-linked files. When you pick **Restore code** or **Restore code and conversation** from the `/rewind` menu, Claude Code skips any tracked path that is a symlink or hard link and shows a `Restored the code, but skipped N files` warning. The skipped files keep their current contents. To undo the session’s changes to one of them, ask Claude to reverse the edit or edit the file yourself. Config files a dotfile manager symlinks into your project and files pnpm hard-links into place both fall into this category. To see which paths a restore skips, turn on debug logging with `/debug` before you restore: the debug log at `~/.claude/debug/<session-id>.txt` names each skipped path. For every skip reason and the recovery steps, see [the skipped-files entry in the error reference](errors.md#restored-the-code-but-skipped-files).


[​](#not-a-replacement-for-version-control)

Not a replacement for version control

Checkpoints are designed for quick, session-level recovery. For permanent version history and collaboration, continue using version control, such as Git, for commits, branches, and long-term history.


[​](#see-also)

See also

- [Interactive mode](interactive-mode.md) - Keyboard shortcuts and session controls
- [Commands](commands.md) - Accessing checkpoints using `/rewind`
- [CLI reference](cli-reference.md) - Command-line options

---

## Claude Code champion kit | Claude Help Center

Source: https://support.claude.com/en/articles/14555399-claude-code-champion-kit
Path: 02-Claude-Code-CLI/claude-code-champion-kit.md

# Claude Code champion kit

A guide for internal champions driving adoption

April 15, 2026


Adoption of a new developer tool rarely happens just because of a rollout announcement. It happens because someone on the team begins using the tool well, talks about it openly, and makes it easy for others to follow. This kit is designed to support that effort without turning it into a second job. It gives shape to things you are likely already doing and provides material you can hand directly to colleagues.

The work you do as a champion has a disproportionate effect. Every example you share shortens the learning curve for the engineers who come after you, and every question you answer in public turns one person’s experience into something the whole team can build on. You are acting as a multiplier for your team, not as a help desk, and this guide is structured to keep the role sustainable on those terms.

## How to use this guide

The champion role consists of three behaviors that reinforce one another: sharing what you discover, being the person people ask, and growing the circle of active users. The sections below cover each in turn, followed by a thirty-day playbook, guidance for responding to common concerns, and a quick-reference sheet you can hand to anyone.

Use whatever fits your team and set aside whatever does not. Nothing here is a checklist you are expected to complete; it is a set of patterns that have worked across many engineering organizations.

------------------------------------------------------------------------

## Phase 1: The champion role

### What a champion does

[TABLE]

Most of this fits naturally inside the work you are already doing. The difference is a small amount of additional intention about where your discoveries are posted and how your answers travel.

### Why this matters

Tools spread inside an organization when someone trusted demonstrates that they are worth the effort. Documentation can describe what is possible, but a colleague’s example—drawn from the same codebase, the same workflows, and the same constraints—is what moves people from curiosity to a first attempt. By making your own experience visible, you remove the most common reason adoption stalls: not knowing where to start.

### What this should cost you

It is worth setting expectations with yourself and with your lead. The activities below are intended to fit inside a normal working week, and the role should remain a multiplier on your existing work rather than an additional support responsibility.

[TABLE]

------------------------------------------------------------------------

## Phase 2: Share what you discover

Your own experience is the most persuasive material your colleagues will encounter, because it is specific to the codebase, workflows, and problems you all share. Documentation tells people what is possible; your posts show them what is actually working in your environment.

### What is worth sharing

The most useful posts describe a technique a colleague can reuse tomorrow rather than an outcome that is already complete. Techniques compound as they spread through a team; status updates do not.

[TABLE]

### Where to share it

Post wherever your team already reads. The goal is to place examples in the path of normal work rather than to create a new destination.

[TABLE]

### The format that works

A screenshot accompanied by a single line of context, or a brief before-and-after description, is generally the right level of detail. Keep each post short enough that someone scrolling past still absorbs the point. A long write-up tends to be saved for later and forgotten, whereas a short post with a screenshot tends to be copied and tried.

### Example posts

The following are illustrations of tone and length rather than templates to copy verbatim.

*Learned today that @-mentioning a directory works. I pointed it at `@src/components/` and asked which components were missing tests, and it surfaced two I had forgotten about.*

*I configured a Stop hook so I receive a desktop notification when a long task completes. I started a refactor, stepped away, and was notified when it finished. Configuration is in the thread.*

*Plan mode is the reason I am comfortable using this on code that matters. Press Shift+Tab until you see “plan”; it lays out exactly which files it intends to touch before changing anything.*

------------------------------------------------------------------------

## Phase 3: Be the person people ask

Once you have shared a few examples, questions will follow. This is where the champion role has the greatest leverage, because a good answer to one person frequently unblocks several others who are watching the same channel.

### Answer with a prompt rather than an explanation

When a colleague asks how you accomplished something, the most useful response is the prompt you actually used. They will learn more from running that prompt against their own problem than from any description you could write, and it gives them something they can act on immediately.

**Colleague:** *How did you get it to find that race condition?*

**Champion:** *I asked, “The test in @tests/scheduler.test.ts is flaky — figure out why,” and it traced two unjoined promises in the scheduler. Try the same phrasing on your test.*

### Point at the feature rather than the documentation

A response such as “Try plan mode—press Shift+Tab until you see it” is more useful in the moment than a link to the documentation. If the person needs more depth later they will find it on their own; right now they need the single thing that unblocks them.

### Questions you are likely to hear

The table below covers the questions champions are asked most frequently, along with a suggested response and the resource to offer when the person is ready for more depth.

[TABLE]

------------------------------------------------------------------------

## Phase 4: Grow the circle

The objective is not to build a program or to own a rollout. It is to establish a small number of lightweight habits that allow momentum to continue after you have stopped actively driving it. When questions in the channel are being answered by people other than you, the role has done its job.

### Patterns that tend to work

[TABLE]

### A thirty-day playbook

If a loose plan is helpful, the sequence below reflects what tends to work across most teams. Adjust freely to fit your context.

[TABLE]

### When someone wants to go deeper

You are the warm introduction rather than the onboarding program. When a colleague moves past “should I try this” into “how do I become effective with it,” point them to the official **[Quickstart](../01-Getting-Started/quickstart.md)** and **[Common workflows](common-workflows.md)** pages. They contain short sections covering the features that are genuinely useful but difficult to discover on your own.

------------------------------------------------------------------------

## Phase 5: Responding to common concerns

Healthy skepticism is to be expected; engineers should be cautious about new tools. The most effective response is rarely to argue the general case. Instead, acknowledge the concern, offer a brief reframe, and propose one concrete demonstration on the person’s own code. Most concerns are resolved by a single successful experience.

[TABLE]

------------------------------------------------------------------------

## Appendix: Quick-reference sheet

The techniques below are the ones that most reliably move someone from a first trial to daily use. This table is intended to be pinned in a channel or shared on its own.

[TABLE]

------------------------------------------------------------------------

## Appendix: Resource directory

[TABLE]

Thank you for taking on this role. People adopt new tools because someone they trust showed them it was worth the effort, and that is the contribution you are making. Claude Code is updated frequently; please verify version-specific details against **[code.claude.com/docs](code-home.md)** before distributing this material internally.

---

## Claude Code cheatsheet | Claude Help Center

Source: https://support.claude.com/en/articles/14553413-claude-code-cheatsheet
Path: 02-Claude-Code-CLI/claude-code-cheatsheet.md

# Claude Code cheatsheet

August 7, 2026


This page collects the vocabulary, commands, and keyboard shortcuts that are worth committing to muscle memory. Keep it open in a browser tab (or printed beside your keyboard) during your first few weeks with Claude Code. Most of the friction new users hit comes from not knowing a command already exists for what they are trying to do, so a quick scan here before reaching for a workaround usually pays off.

------------------------------------------------------------------------

## Glossary

[TABLE]

------------------------------------------------------------------------

## Commands

Type `/` on an empty prompt to see every command available in your setup, including custom, plugin, and MCP-provided ones. The list below covers the built-in defaults (and the bundled skills that ship with every install) you will reach for most often while learning the tool. A few entries vary by platform and plan.

[TABLE]

------------------------------------------------------------------------

## Keyboard shortcuts

[TABLE]

Shortcuts vary slightly by terminal and IDE. Press **`?`** inside a session for the exact list in your environment.

---

## Claude Code: Common developer use cases | Claude Help Center

Source: https://support.claude.com/en/articles/14553517-claude-code-common-developer-use-cases
Path: 02-Claude-Code-CLI/claude-code-common-developer-use-cases.md

# Claude Code: Common developer use cases

April 15, 2026


Claude Code is a command-line agent that runs in your terminal, reads your repository, edits files, executes commands, and requests confirmation before performing potentially destructive actions. It is designed to assist at every stage of the software development lifecycle—from exploring an unfamiliar codebase to shipping and maintaining production code.

The table below summarizes where Claude Code fits across the development lifecycle. The remainder of this article walks through the ten tasks developers most frequently use it for, with a sample prompt and expected result for each.

[TABLE]

## How to use this guide

Each use case below includes when to use it, an example prompt, and the expected result. No configuration is required for any of them except §9 (issue-tracker integration), which requires a one-time MCP connector setup.

Use cases are ordered roughly by how early most developers encounter them. Select the one that matches your current task.

------------------------------------------------------------------------

## Use cases

### 1. Fix a failing test

**When to use this:** A test is failing and the cause is not immediately obvious. Use this to have Claude Code locate the root cause and propose a fix without you needing to identify the source file first.

**Example prompt:**

    > the tests in tests/auth.test.ts are failing, can you figure out why and fix them

**Expected result:** Claude Code reads the test file, traces the code path through the modules under test, identifies the mismatch, and proposes an edit. After you approve the change, it re-runs the test suite to confirm the fix.

### 2. Understand unfamiliar code

**When to use this:** You need to understand how a module, function, or subsystem works before making changes—for example, when inheriting code or reviewing an unfamiliar area.

**Example prompt:**

    > walk me through how the payment retry logic works

**Expected result:** Claude Code locates the relevant files, reads the implementation, and explains the control flow in plain language: entry points, decision branches, edge cases, and how the code connects to the rest of the system. Ask follow-up questions (e.g., “where does X get set”) to drill deeper.

## 3. Find where something happens

**When to use this:** You know a behavior exists in the codebase but cannot locate it via filename or simple text search.

**Example prompt:**

    > where do we validate email addresses in this codebase? I want to add a new rule

**Expected result:** Claude Code searches the repository, opens candidate files, and returns file paths and line numbers with enough surrounding context to identify the correct match. If multiple locations exist, it indicates which one is the source of truth.

### 4. Triage an error or stack trace

**When to use this:** You have a runtime error, stack trace, or log output and need to map it back to the responsible code.

**Example prompt:**

    <table class="prompt"> <colgroup> <col style="width: 100%" /> </colgroup>
    <tbody> <tr class="odd"> <td>&gt; getting this in production:<br />
    TypeError: Cannot read properties of undefined (reading 'sessionId')<br />    
    at validateSession (src/auth/session.ts:47)<br />     at middleware
    (src/auth/middleware.ts:12)<br /> what's going on?</td> </tr> </tbody>
    </table> 

**Expected result:** Claude Code reads the files referenced in the trace, explains what is undefined and why, and proposes a fix. For errors without a clean stack trace, paste any available log output and Claude Code will reconstruct the failure from context.

### 5. Refactor with a plan

**When to use this:** A change spans multiple files and you want to review the full scope before any edits are made.

**Prerequisite:** Press **Shift+Tab** until the mode indicator shows “plan."

**Example prompt:**

    > refactor the auth module to use the new session store instead of SessionCache

**Expected result:** Claude Code analyzes the code and produces a numbered plan listing every file it will modify and the change in each. You can approve the plan as-is or amend it (e.g., “don’t touch the logout route”). No files are edited until you approve.

**Reference:** **[Permissions](permissions.md)**

### 6. Write tests for existing code

**When to use this:** A source file lacks coverage, or you need additional edge-case tests that match your project’s existing test conventions.

**Example prompt:**

    > add tests for @src/billing/invoice.ts — cover the edge cases around partial refunds. match the style of the existing tests in tests/billing/

**Expected result:** Claude Code reads both the source file and the reference test directory, generates a new test file in the existing style, and runs it to confirm the tests pass. If obvious coverage gaps remain, it flags them and asks whether to address them.

### 7. Review a pull request

**When to use this:** You need to review or summarize a PR, particularly in an area of the codebase you do not know well.

**Prerequisite:** GitHub CLI authenticated (run `gh auth login` once).

**Example prompt:**

    > /pr https://github.com/example/api/pull/4471
    > is the error handling solid?

**Expected result:** Claude Code fetches the diff, review comments, and CI status, then reads the changed files in their full repository context. It can produce a focused review, draft review comments, verify a specific concern, or summarize the PR.

### 8. Onboard to a new repository

**When to use this:** You are working in a repository for the first time and need a structured overview of its architecture, build commands, and conventions.

**Example prompt:**

    <table class="prompt"> <colgroup> <col style="width: 100%" /> </colgroup>
    <tbody> <tr class="odd"> <td>&gt; /init<br /> &gt; give me a tour of this
    codebase — where's the entry point, how is it structured, what should I
    read first</td> </tr> </tbody> </table>

**Expected result:** `/init` scans the project and writes a `CLAUDE.md` file summarizing build commands, architecture, and conventions. The follow-up tour prompt produces a guided walkthrough of the project structure. Project context remains loaded for the rest of the session.

**Reference:** **[Memory and CLAUDE.md](memory.md)**

### 9. Work an issue end to end

**When to use this:** You want to read a ticket, implement the fix, and validate it in a single conversation without switching tools.

**Prerequisite:** Issue tracker connected via MCP (one-time `.mcp.json` configuration).

**Example prompt:**

    <table class="prompt"> <colgroup> <col style="width: 100%" /> </colgroup>
    <tbody> <tr class="odd"> <td>&gt; what's the top-priority issue assigned
    to me?<br /> &gt; go ahead and fix it</td> </tr> </tbody> </table>

**Expected result:** Claude Code queries the issue tracker, reads the ticket, locates the relevant code, proposes a fix, and runs the tests. The session ends with a reviewable diff and the context needed to close the ticket.

**Reference:** **[MCP](../06-MCP-Tools/General/mcp.md)**

### 10. Turn a recurring task into a Skill

**When to use this:** You repeat the same multi-step prompt regularly (pre-commit checks, standup summaries, PR descriptions, release notes) and want to make it reusable for the whole team.

**Example prompt:**

    > make me a /ship skill that runs the tests, runs the linter, looks at git diff, and drafts a conventional-commit message — then shows me the message without committing

**Expected result:** Claude Code writes a `SKILL.md` file to `.claude/skills/ship/`. The `/ship` command is available immediately, with no restart required, and is shared with anyone who clones the repository. (The legacy `.claude/commands/` path is still supported, but skills are the recommended form.)

**Reference:** **[Skills](../08-Plugins-Skills/skills.md)**

## Appendix: Quick reference

[TABLE]

## Appendix: Resource directory

[TABLE]

For details on `/init`, @-references, permission modes, skills, MCP, and hooks, see **[code.claude.com/docs](code-home.md)**. Claude Code ships frequently—verify version-specific details against **[code.claude.com/docs](code-home.md)** before distributing internally.

---

## Claude Code communications kit | Claude Help Center

Source: https://support.claude.com/en/articles/14555877-claude-code-communications-kit
Path: 02-Claude-Code-CLI/claude-code-communications-kit.md

# Claude Code communications kit

Ready-to-send messages for Slack, Teams, and email — Enterprise admin enablement

September 22, 2026


This kit covers launch communications, a twenty-message "tips and tricks" drip campaign, and a quick-reference FAQ for the questions you’ll get asked most. Each message links out to a docs page developers can go deeper on.

## How to use this kit

Three parts, in the order you’ll need them. **Part 1** is your launch announcement—one primary message in email and Slack formats, with swap-in variants for an executive-sponsored send and pilot groups. **Part 2** provides twenty drip-campaign messages packaged as ready-to-paste Slack/Teams posts. **Part 3** is a quick-reference FAQ and link directory.

**Treat everything in this kit as draft copy, not finished copy.** Rewrite each message in your org’s voice, swap the example tasks for real bugs and modules from your own codebase, and replace the \[bracketed placeholders\] before sending. The announcements that actually drive adoption are the ones that read like someone at your company wrote them.

------------------------------------------------------------------------

## Part 1: Launch communications

One announcement in two formats, plus two optional variants. Pick whichever fits your rollout and rewrite it from there.

### 1.1 Before you send

[TABLE]

### 1.2 The announcement

Use this as your standard org-wide rollout message. It covers what Claude Code is, gives a two-minute install, hands readers one concrete task to try, and answers “where does my code go?” before anyone has to ask.

**Email**

[TABLE]

**Slack / Teams**

[TABLE]

### 1.3 Variant: Executive sponsor send

**Send this from your sponsoring C-suite executive**—CTO, CIO, or SVP Engineering — under their name and from their account. Launches that go out under an exec’s name consistently see higher open rates and faster first-week activation than the same message from an admin or tooling team. It signals a company priority rather than an optional experiment.

This version is deliberately stripped to **one ask**: install it and run it on one real task. No feature tour, no FAQ. The exec’s job is to make the ask land that day; 1.2 and `#claude-code` handle the how.

**Email**

[TABLE]

**Slack / Teams**

[TABLE]

### 1.4 Variant: Pilot / early-access group

Use for a phased rollout. Send to the pilot cohort only.

[TABLE]

### 1.5 Champion recruitment DM

After launch, DM the two or three people who are most active in `#claude-code`.

[TABLE]

------------------------------------------------------------------------

## Part 2: Tips and tricks campaign

Twenty ready-to-paste Slack/Teams messages designed to drive feature activation after launch. Each follows the same pattern: a hook, the payoff, a **“try it now”** prompt, and a docs link. Drip them one or two a week in `#claude-code`, or pick the five that match your team’s gaps. They stand alone—no required order.

Copy the message body from each table below directly into Slack or Teams. Replace \[bracketed placeholders\] before sending.

### 2.1 Getting started

**Message 1 — Choosing the right model**

[TABLE]

*Quick reference:*

[TABLE]

**Message 2 — Quick wins to try first**

[TABLE]

### 2.2 Project memory

**Message 3 — /init and CLAUDE.md**

[TABLE]

**Message 4 — @-references**

[TABLE]

**Message 5 — Memory — “remember that…”**

[TABLE]

### 2.3 Control and safety

**Message 6 — Permission modes**

[TABLE]

*Quick reference (the three you’ll use most — see **[docs](permissions.md)** for the full list):*

[TABLE]

**Message 7 — Checkpointing and /rewind**

[TABLE]

### 2.4 Connect Your Tools

**Message 8 — MCP connectors**

[TABLE]

**Message 9 — IDE integrations**

[TABLE]

### 2.5 Automate Your Workflows

**Message 10 — Slash commands and skills**

[TABLE]

**Message 11 — Hooks**

[TABLE]

**Message 12 — Subagents**

[TABLE]

### 2.6 Day-to-day dev

**Message 13 — Effort levels**

[TABLE]

**Message 14 — Screenshots and images**

[TABLE]

**Message 15 — Git workflows**

[TABLE]

**Message 16 — Background tasks**

[TABLE]

### 2.7 Share and scale

**Message 17 — Plugins**

[TABLE]

**Message 18 — Keyboard shortcuts**

[TABLE]

### 2.8 Security and admin

**Message 19 — Security architecture**

[TABLE]

**Message 20 — Best practices**

[TABLE]

------------------------------------------------------------------------

## Part 3: Quick reference

### 3.1 FAQ responses

One-line Slack replies for the questions you’ll get asked most.

[TABLE]

### 3.2 Prompt templates

[TABLE]

------------------------------------------------------------------------

## Appendix: Verified links reference

[TABLE]

Claude Code ships frequently—verify version-specific details against **[code.claude.com/docs](code-home.md)** before distributing internally.

---

## Claude Code FAQ | Claude Help Center

Source: https://support.claude.com/en/articles/12386420-claude-code-faq
Path: 02-Claude-Code-CLI/claude-code-faq.md

# Claude Code FAQ


This article is a compilation of commonly-asked questions about Claude Code related to authentication, integrations, configuration, and more. If you're interested in learning more about Claude Code, please refer to our Claude Docs here: **[Claude Code overview](https://docs.claude.com/en/docs/claude-code/overview)**.

## How do I set up single sign-on (SSO) for Claude Code?

We have detailed instructions for setting up single sign-on on a Team, Enterprise, or Console organization here: **[Set up single sign-on (SSO)](https://support.claude.com/en/articles/13132885-set-up-single-sign-on-sso)**.

## Is there a way to disable Opus model access across our entire organization in Claude Code?

If you are a Claude Console user, this can be configured through rate limiting in your Console organization. If you are using Bedrock or Vertex, set the Opus rate limit to 0 in your Vertex/Bedrock project settings. Note that even if disabled in Vertex, users may be able to switch models in Claude Code, so rate limiting is the most effective approach.

## What are Claude Code dynamic workflows, and how do we control access?

Dynamic workflows (available for Claude Enterprise plans) let Claude run large engineering tasks—migrations, audits, codebase-wide bug hunts—from start to finish in a single Claude Code session. They become available and turn on by default for your whole Enterprise organization on June 8, 2026. Because a single run can last for hours and use more tokens than a typical session, admins should decide who has access before that date.

You have three ways to control access:

1.  **At the role level (Enterprise plans with custom roles):** Grant or restrict the Claude Code dynamic workflows capability per group. This only affects members whose role is set to "Custom." See **[Manage custom roles on Enterprise plans](https://support.claude.com/en/articles/13930452)**.

2.  **Disable org-wide via `managed-settings.json`:** Add `"disableWorkflows": true` to your managed settings. This holds before and after June 8.

3.  **Organization-wide:** After June 8, an owner can disable dynamic workflows for everyone by going to **[Organization settings \> Claude Code](https://claude.ai/admin-settings/claude-code)** and toggling **Workflows** off.

We apply the more restrictive of your managed settings and custom role permissions on a per-user basis. If either one disables workflows for a given user, that user won't have access.

## Does Claude Code support Microsoft Visual Studio IDE integration (not VS Code)?

No current Visual Studio 2022 integration exists. Claude Code currently supports VS Code, Cursor (and other VS Code forks), Intellij, Pycharm (and other Jetbrains IDEs).

## How can we implement PR review automation with Claude Code?

While there isn't a turnkey PR reviewer solution yet, you can use the **[Claude Code GitHub Actions integration](automated-security-reviews-in-claude-code.md)** for automated reviews. For now, you can use the security review action as a template and customize it for general PR reviews. This is also a good use case for the **[Claude Code SDK](https://docs.claude.com/en/docs/claude-code/sdk/sdk-overview)**.

## I’m getting an error message that “Claude Max or Pro is required to connect to Claude Code” but I should have access through my organization’s Team or Enterprise plan. How can I troubleshoot?

This indicates that you selected the wrong login method from the Claude Code setup screen. Try running /login again and selecting the account associated with your primary work email address. If you’re still unable to connect, see **[Having trouble using your Team or Enterprise account to access Claude Code?](https://support.claude.com/en/articles/11845131-using-claude-code-with-your-team-or-enterprise-plan#h_540f9e65d8)**

## What data is sent to Anthropic when using Claude Code with Bedrock/Vertex API keys?

When configured with Bedrock/Vertex and CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC is set, only essential telemetry is sent. All model API requests go directly to your Bedrock/Vertex endpoints. Review the **[data flow documentation](https://docs.claude.com/en/docs/claude-code/security)** for complete details.

## Is there a way to access Claude Code via Bedrock/Vertex without exposing a secret key/access key?

Yes. Our setup guides for **[Bedrock](https://docs.claude.com/en/docs/claude-code/amazon-bedrock)** and **[Vertex](https://docs.claude.com/en/docs/claude-code/google-vertex-ai)** show how you can enable this. For example, in the Bedrock case you can run \`aws configure\` to configure the AWS CLI before adding the necessary **[configs](https://docs.claude.com/en/docs/claude-code/amazon-bedrock#3-configure-claude-code)** and running Claude Code with the Bedrock, or you can use Bedrock API keys, which is a new feature from AWS that enables API keys for Bedrock usage that don’t require full AWS credentials.

## How can we deploy Claude Code with custom environment variables and permissions across our organization?

Create wrapper scripts that set environment variables before running Claude Code. For permissions, use .claude/settings.json files with allow/deny lists. Note that wildcard patterns (\*) don't always match as expected - test permissions thoroughly. Enterprise teams often inject standardized Claude.md files for consistent configurations.

## Does Claude Code have public code filtering or attribution capabilities on the roadmap?

No, public code filtering and attribution capabilities are not currently on the roadmap. Some customers use BlackDuck for code scanning, though feedback on cost and false positives has been mixed. We are aware that this is a blocker for scaling Claude Code to more users and are looking into solutions.

## Are subagents available in Claude Code SDK and GitHub Actions?

Subagents are available via the **[Claude Code SDK](https://docs.claude.com/en/docs/claude-code/sdk/sdk-overview)**. They're not yet integrated into GitHub Actions, but we are considering this. The UX collapses outputs when more than three subagents run in parallel to manage complexity.

## Can subagents be configured to use specific MCP tools?

Yes, when creating a subagent, you can specify which tools it has access to using the \`tools\` field in the configuration. In the subagent configuration file, you can either omit the tools field to inherit all tools from the main thread, or you can specify individual tools as a comma-separated list for more granular control. Learn more about this in our Claude Docs: **[Subagents - Available tools](https://docs.claude.com/en/docs/claude-code/sub-agents#available-tools)**.

## How can we manage Claude Code costs, especially for automated workflows?

For automated workflows like security reviews, switch from Opus to Sonnet using the **[claude --model \<alias\|name\> configuration option](https://docs.claude.com/en/docs/claude-code/model-config)** for cost savings. You can also monitor usage through your console dashboard and set appropriate rate limits. Note that you can use Workspaces to set more granular spend limits for different user groups. Read more about Workspaces here: **[Creating and managing Workspaces in the Claude Console](../13-Enterprise-Admin/creating-and-managing-workspaces-in-the-claude-console.md)**. We also allow you to view spend per API key in the Console. Refer to this article for more information: **[Cost and Usage Reporting in the Claude Console](../22-Safety-Policy/cost-and-usage-reporting-in-the-claude-console.md)**.

## Can Claude Code work through corporate proxies like LiteLLM?

Yes, Claude Code supports corporate proxy configurations as long as they support the Anthropic API spec. Follow the proxy setup instructions in our Claude Docs: **[Proxy configuration](https://docs.claude.com/en/docs/claude-code/network-config#proxy-configuration)**. Common issues arise from port restrictions in restricted environments.

## How do we add users to Claude Code when using a Console account?

Add users directly to your Console organization with a Claude Code User or Developer role - that's all that's needed. Users then run /login from within Claude Code and select the intended Console account. Do not try to manually create API keys in the Claude Code workspace.

## Is there team-based memory or knowledge sharing beyond Claude.md files?

Currently, Claude.md files are the primary mechanism. IT teams can inject standardized Claude.md files into every machine's .claude directory for org-wide configurations. More advanced team memory features are being explored but not yet available.

## How do permissions work in Claude Code, and why aren’t my allow lists being respected?

Permissions use pattern matching in .claude/settings.json or settings.local.json. Wildcard syntax can be tricky - "Bash(atlassian-api:\*)" should work but may need exact command matching. Use "Yes, and don't ask again for similar commands" to build up permissions incrementally. Check both global (~/.claude/settings.json) and local settings files.

## Does Claude Code index my entire codebase or use a vector database to store information about my codebase?

No. Claude Code has access to a system prompt and a series of tools that it can use to navigate your codebase on command. For example, if Claude Code needs to understand something about your codebase, it will use a search tool to search through your codebase and read files on command. We find that this is more effective and flexible than full codebase indexing: Claude Code is *really* good at knowing how to sift through a codebase to gather context it needs on the fly!

## Can Claude Code integrate with CI/CD, version control, and observability platforms?

Yes, Claude Code integrates with GitHub Actions for CI/CD, supports git operations, and can connect to various platforms via MCP servers. See our Claude Docs for more information:

- **[Claude Code GitHub Actions](https://docs.claude.com/en/docs/claude-code/github-actions)**

- **[Claude Code GitLab CI/CD](https://docs.claude.com/en/docs/claude-code/gitlab-ci-cd)**

## Why am I seeing "Workflow validation failed" errors in GitHub Actions?

This typically occurs with reusable workflows. Check that your workflow syntax is correct and that all required parameters are passed. If the error persists, file an issue here with your workflow configuration: **[github.com/anthropics/claude-code-action](https://github.com/anthropics/claude-code-action)**.

---

## Use Claude Code in the cloud - Claude Code Docs

Source: https://code.claude.com/docs/en/claude-code-on-the-web
Path: 02-Claude-Code-CLI/claude-code-on-the-web.md

## On this page

- [Cloud environments](#cloud-environments)
- [GitHub authentication options](#github-authentication-options)
  - [Quick setup for Team and Enterprise](#quick-setup-for-team-and-enterprise)
- [Move tasks between terminal and cloud](#move-tasks-between-terminal-and-cloud)
  - [Start a cloud session from your terminal](#start-a-cloud-session-from-your-terminal)
  - [Tips for cloud tasks](#tips-for-cloud-tasks)
  - [Send local repositories without GitHub](#send-local-repositories-without-github)
  - [Send follow-ups from the CLI](#send-follow-ups-from-the-cli)
  - [Output](#output)
  - [Continue a cloud session in your terminal](#continue-a-cloud-session-in-your-terminal)
  - [Teleport requirements](#teleport-requirements)
  - [--teleport is unavailable](#teleport-is-unavailable)
- [Work with sessions](#work-with-sessions)
  - [Permission modes in cloud sessions](#permission-modes-in-cloud-sessions)
  - [Review changes](#review-changes)
  - [Manage context](#manage-context)
  - [Take back a queued message](#take-back-a-queued-message)
  - [Share sessions](#share-sessions)
  - [Share from an Enterprise or Team account](#share-from-an-enterprise-or-team-account)
  - [Share from a Max or Pro account](#share-from-a-max-or-pro-account)
  - [Archive sessions](#archive-sessions)
  - [Delete sessions](#delete-sessions)
- [Auto-fix pull requests](#auto-fix-pull-requests)
  - [How Claude responds to PR activity](#how-claude-responds-to-pr-activity)
- [Security and isolation](#security-and-isolation)
- [Troubleshooting](#troubleshooting)
  - [Session creation failed](#session-creation-failed)
  - [Unable to get organization UUID](#unable-to-get-organization-uuid)
  - [Branch is not on GitHub](#branch-is-not-on-github)
  - [Remote Control session expired or access denied](#remote-control-session-expired-or-access-denied)
  - [Errors when sending to a cloud session](#errors-when-sending-to-a-cloud-session)
  - [Environment expired](#environment-expired)
- [Limitations](#limitations)
- [Related resources](#related-resources)

Claude Code in the cloud

# Use Claude Code in the cloud

Copy pageCopy page

Run Claude Code sessions in the cloud from your browser, phone, Desktop app, or terminal, move them with `--cloud` and `--teleport`, and auto-fix pull requests.

Copy pageCopy page

Cloud sessions are available on Pro, Max, and Team plans, and for Enterprise users with premium seats or Chat + Claude Code seats. If your Enterprise organization manages your access with [custom roles](https://support.claude.com/en/articles/13930452), you also need a role that includes the cloud sessions permission. Ask an Owner to check your roles and add it at [**Organization settings \> Roles**](https://claude.ai/admin-settings/roles) if it’s missing.

A cloud session is a Claude Code session that runs on cloud infrastructure instead of on your machine. By default it runs on infrastructure Anthropic manages, or on your organization’s [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) when routed there. The session keeps running after you close your laptop, and you can check on it or steer it from any device. It counts toward your plan’s usage limits alongside the rest of your Claude and Claude Code usage, and there’s no separate charge for the cloud VM. To let cloud sessions clone your code from GitHub and push branches, connect GitHub with one of the [GitHub connection methods](#github-authentication-options). If your repository is on GitLab, Bitbucket, or another host, see [Platform restrictions](#limitations) for what works. You can start a cloud session from any of these surfaces:

- **Browser**: [claude.ai/code](https://claude.ai/code), also called Claude Code on the web
- **Mobile**: the **Code** tab in the [Claude app](../16-Mobile-Desktop/mobile.md)
- **Desktop app**: select **Cloud** instead of **Local** when you [start a session](../16-Mobile-Desktop/desktop.md#run-long-running-tasks-in-the-cloud)
- **Terminal**: [`claude --cloud`](#from-terminal-to-cloud)
- **Cloud scheduled tasks**: [scheduled and triggered runs](web-scheduled-tasks.md) each run as a cloud session

Once you’re set up, use this page to move work between your terminal and the cloud, manage and share sessions, turn on auto-fix for pull requests, and troubleshoot.

These cases are covered on other pages:

- **Starting your first cloud session**: [Get started with cloud sessions](web-quickstart.md) connects GitHub and walks through a task in the browser
- **Many cloud sessions for one body of work**: a [project](claude-projects.md) has Claude start and keep track of them for you
- **Steering a local session from another device**: sessions in your terminal, IDE, or the Desktop app with **Local** selected run on your machine, and [Remote Control](remote-control.md) lets you reach them from your phone or browser


[​](#cloud-environments)

Cloud environments

Every cloud session runs in a [cloud environment](cloud-environments.md), the saved configuration that controls network access, environment variables, and setup scripts.

- **Your first environment**: if you don’t have one yet, onboarding sets up a **Default** environment with [**Trusted** network access](cloud-environments.md#access-levels), either by creating it for you or by asking you to create it. See [The Default environment](cloud-environments.md#the-default-environment) for which of those happens on your plan
- **Which environment a session uses**: see [The Default environment](cloud-environments.md#the-default-environment) for how sessions choose an environment when you have more than one
- **Change what sessions can reach or run at startup**: see [Configure cloud environments](cloud-environments.md)
- **What’s installed without any configuration**: see [Installed tools](cloud-environments.md#installed-tools)


[​](#github-authentication-options)


Cloud sessions need access to your GitHub repositories to clone code and push branches. You can grant access in two ways:

| Method           | How you connect                                                                            | Repositories sessions can reach                                                              | Best for                                                                |
|:-----------------|:-------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------|:------------------------------------------------------------------------|
| **GitHub App**   | Authorize the Claude GitHub App during [web onboarding](web-quickstart.md)           | Any public repository, and private repositories that the Claude GitHub App is installed on   | Browser onboarding; teams that want [Auto-fix](#auto-fix-pull-requests) |
| **`/web-setup`** | Run `/web-setup` in your terminal to send your local `gh` CLI token to your Claude account | Any repository your `gh` token can access, whether or not the Claude GitHub App is installed | Individual developers who already use `gh`                              |

These features depend on the Claude GitHub App being installed on the repository:

- **Auto-fix**: installing the Claude GitHub App on a repository also enables [Auto-fix](#auto-fix-pull-requests) for pull requests in it
- **Projects**: threads in a [project](claude-projects.md) need the Claude GitHub App installed on each repository they clone, whichever method you connected with. See [Set up GitHub access](claude-projects.md#set-up-github-access)

In Anthropic-hosted environments, your GitHub credentials stay encrypted on Anthropic’s servers and never enter a session’s VM. GitHub operations from the VM go through the [GitHub proxy](cloud-environments.md#github-proxy), which attaches the credential on the server side. See [Connect from your terminal](web-quickstart.md#connect-from-your-terminal) for the `/web-setup` walkthrough, including what `/web-setup` stores and how to remove it.

Organizations with [Zero Data Retention](zero-data-retention.md) enabled, or with the [HIPAA configuration](hipaa-setup.md) applied, can’t use `/web-setup` or other cloud session features. Organizations that use [customer-managed encryption keys](../04-API-Reference/Other/manage-claude-cmek.md) (CMEK) can’t start cloud sessions either.


[​](#quick-setup-for-team-and-enterprise)

Quick setup for Team and Enterprise

Quick setup is an organization setting that removes steps from members’ GitHub and environment setup. On Team and Enterprise plans it’s off by default. Here’s what changes for members when it’s on:

- **`/web-setup`**: members can connect GitHub with `/web-setup`. While the setting is off, the command is hidden
- **GitHub App prompt**: browser onboarding skips the Claude GitHub App install prompt
- **First environment**: browser onboarding creates the [**Default** environment](cloud-environments.md#the-default-environment) for members instead of showing the environment form

An [Owner](../13-Enterprise-Admin/server-managed-settings.md#access-control) turns it on with the **Quick setup** toggle at [**Organization settings \> Claude Code**](https://claude.ai/admin-settings/claude-code).


[​](#move-tasks-between-terminal-and-cloud)

Move tasks between terminal and cloud

These workflows require the [Claude Code CLI](../01-Getting-Started/quickstart.md) signed in to the same claude.ai account. You can start new cloud sessions from your terminal, or pull cloud sessions into your terminal to continue locally. Cloud sessions persist even if you close your laptop, and you can monitor them from anywhere including the Claude mobile app.

From the CLI, session handoff is one-way: you can pull cloud sessions into your terminal with `--teleport`, but you can’t push an existing terminal session to the cloud. The `--cloud` flag with a task description creates a new cloud session for your current repository; with `-p` and a session ID or claude.ai/code URL it instead [queues a message into that existing session](claude-code-on-the-web.md#send-follow-ups-from-the-cli). The [Desktop app](../16-Mobile-Desktop/desktop.md#continue-in-another-surface) can send a local session in its Code tab to the cloud from its **Open in** menu.


[​](#start-a-cloud-session-from-your-terminal)

Start a cloud session from your terminal

Start a cloud session from the command line with the `--cloud` flag:

```python
claude --cloud "Fix the authentication bug in src/auth/login.ts"
```

This creates a new cloud session on claude.ai. The cloud VM clones your current directory’s GitHub remote at your current branch, not your local checkout, so push first if you have local commits. See [Send local repositories without GitHub](#send-local-repositories-without-github) for the cases where Claude Code uploads your local repository instead of cloning. If the terminal prints `Branch <name> is not on GitHub`, see [Branch is not on GitHub](#branch-is-not-on-github). `--cloud` works with a single repository at a time. The task runs in the cloud while you continue working locally. The older `--remote` spelling still works as a deprecated alias for `--cloud`. While the cloud container starts, the CLI shows a live checklist of setup steps, such as cloning the repository and running your [setup script](cloud-environments.md#setup-scripts). It queues messages you type during provisioning and sends them once the session is ready.

`--cloud` creates cloud sessions. `--remote-control` is unrelated: it lets you monitor and steer a local CLI session from claude.ai or the Claude app. See [Remote Control](remote-control.md).

Open the session on claude.ai or the Claude mobile app to check progress or interact directly. From there you can steer Claude, provide feedback, or answer questions as in any other conversation. If Claude asks a question and the session sits idle, you can still answer when you come back, up to [environment expiry](#environment-expired), and the session continues from your answer.


[​](#tips-for-cloud-tasks)

Tips for cloud tasks

**Plan locally, execute in the cloud**: for complex tasks, start Claude in plan mode to collaborate on the approach, then send work to the cloud:

```python
claude --permission-mode plan
```

In plan mode, Claude reads files, runs commands to explore, and proposes a plan without editing source code. Once you’re satisfied, save the plan to the repo, commit, and push so the cloud VM can clone it. Then start a cloud session for autonomous execution:

```python
claude --cloud "Execute the migration plan in docs/migration-plan.md"
```

**Run tasks in parallel**: each `--cloud` command creates its own cloud session that runs independently. You can start multiple tasks and they’ll all run simultaneously in separate sessions:

```python
claude --cloud "Fix the flaky test in auth.spec.ts"
claude --cloud "Update the API documentation"
claude --cloud "Refactor the logger to use structured output"
```

When a session completes, you can create a PR from claude.ai/code or [teleport](#from-cloud-to-terminal) the session to your terminal to continue working.


[​](#send-local-repositories-without-github)

Send local repositories without GitHub

When you run `claude --cloud` from a repository that has no git remote, or from a github.com repository that the Claude GitHub App isn’t installed on, Claude Code bundles your local repository and uploads it directly to the cloud session. This applies even if you connected GitHub with `/web-setup`. For a full clone, the bundle includes your repository history across all branches, plus uncommitted changes to tracked files. What happens to uncommitted changes in sensitive files depends on your platform:

- **macOS, Linux, and WSL**: Claude Code leaves uncommitted changes to files named like credentials or keys out of the upload. This includes `.env` files, Terraform `*.tfvars` files, and key files such as `id_rsa` and `*.pem`. It also leaves out uncommitted changes to files that a git filter such as Git LFS manages. A `Left on this machine:` notice names the files left out, and the session starts with the committed version of each, or without the file if none is committed.
- **Native Windows**: uncommitted changes to tracked files upload as they are, whatever the file’s name. Stash or revert an edit you don’t want in the cloud session before you start it.

To upload a bundle even when Claude Code would otherwise clone from the remote, set `CCR_FORCE_BUNDLE=1`:

```python
CCR_FORCE_BUNDLE=1 claude --cloud "Run the test suite and fix any failures"
```

Bundled repositories must meet these limits:

- The directory must be a git repository with at least one commit
- The bundled repository must be under 100 MB. Larger repositories fall back to bundling only the current branch, then to a single squashed snapshot of the working tree, and fail if the snapshot is still too large
- Untracked files are not included; run `git add` on files you want the cloud session to see
- On macOS, Linux, and WSL, Claude Code refuses the upload when it can’t follow a git setting that affects which attribute rules apply to your files, such as `core.attributesFile` set in an included config file. The [refusal message](errors.md#the-repository-upload-cant-follow-a-git-setting) names the setting and the fix
- Sessions created from a bundle can push back to a GitHub remote only when your [GitHub connection](#github-authentication-options) has push access to that repository

On macOS, Linux, and WSL, the upload also needs git 2.31 or later and a checkout layout it supports, while on native Windows Claude Code uploads without either check. When a checkout doesn’t meet those requirements, Claude Code doesn’t start the session. It prints an error that contains `Not uploading this working tree:`, names the cause, and says what to change. These are the common causes:

- **Older git**: the installed git is older than 2.31. Update git, then retry.
- **A checkout layout the upload doesn’t support**: you started inside a submodule, in a clone made with `git clone --separate-git-dir`, `--shared`, or `--reference`, in a checkout with `core.worktree` set, or in a repository that keeps its refs in the reftable format. Start from the main checkout of a clone made with a plain `git clone` instead.
- **A linked worktree with a sparse checkout**: `git sparse-checkout` writes settings to the worktree’s own `config.worktree` file, which the upload doesn’t accept, so a worktree that has those settings isn’t uploaded, and neither is one Claude Code created with [`worktree.sparsePaths`](settings-reference.md#worktree-sparsepaths). Start from the repository’s main checkout instead.
- **Git configuration kept inside the working tree**: your git configuration includes a file that sits inside the checkout, for example an `include.path` entry that points into the repository. Move that file outside the working tree or remove the include, then retry.

On macOS, Linux, and WSL, a partial clone made with `git clone --filter` uploads as a snapshot of its working tree without history, as long as the clone holds every tracked file locally. For `claude --cloud`, if the repository is on GitHub, you can avoid the upload and its requirements: push your branch, install the Claude GitHub App on the repository, and start the session again so that it clones from GitHub.


[​](#send-follow-ups-from-the-cli)

Send follow-ups from the CLI

Once a cloud session is running, wherever it executes, send it a follow-up message from the `claude` CLI on any machine where you’re logged in with `claude auth login`. The CLI authenticates with your Anthropic account credentials and sends no local session state, so the command doesn’t need to run from the machine that started the session. The command posts one message and exits:

```python
claude -p "your message" --cloud <session-id>
```

The CLI queues the message into the session and exits without waiting for a reply. Use it to steer a long-running session, queue the next step while the current one is still finishing, or send follow-ups from a [CI script](../13-Enterprise-Admin/self-hosted-environments-testing.md#run-the-test-loop). You can also pipe the message on stdin instead of passing it as an argument: `echo "your message" | claude -p --cloud <session-id>`. For `<session-id>`, pass the bare ID, such as `session_...` or `cse_...`, or the session’s `claude.ai/code/<id>` URL, with or without the scheme or query string. Find the ID in your session list at claude.ai/code.

`--cloud` requires an Anthropic account. It’s not available when Claude Code is configured for Amazon Bedrock, Google Cloud’s Agent Platform, or another third-party provider. An [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) configured only through `ANTHROPIC_BASE_URL` doesn’t count as a third-party provider for this check, but you still need to sign in with `claude auth login`. Your organization’s `allow_remote_sessions` policy must also be enabled. An Owner can turn it on in the Claude Code admin settings at claude.ai/admin-settings/claude-code.


[​](#output)

Output

On success, the command prints the session ID and a link to view the session:

```python
Sent to cloud session.
Session ID: session_01DiUkqY2kzbUbDmW1w96rfi
View: https://claude.ai/code/session_01DiUkqY2kzbUbDmW1w96rfi?from=cli&m=0
```

Pass `--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>`. If the send fails, see [Errors when sending to a cloud session](#errors-when-sending-to-a-cloud-session).


[​](#continue-a-cloud-session-in-your-terminal)

Continue a cloud session in your terminal

Pull a cloud session into your terminal using any of these:

- **Using `--teleport`**: from the command line, run `claude --teleport` for an interactive session picker, or `claude --teleport <session-id>` to resume a specific session directly. If you have uncommitted changes, you’ll be prompted to stash them first.
- **Using `/teleport`**: inside an existing CLI session, run `/teleport` or `/tp` to open the same session picker without restarting Claude Code.
- **From `/tasks`**: run `/tasks` to see your background sessions, then press `t` to teleport into one.
- **From claude.ai/code**: select **Open in \> Terminal** from the session menu to copy a command you can paste into your terminal.
- **From inside the cloud session**: type `/teleport` and Claude Code replies with the exact `claude --teleport <session-id>` command for that session, ready to run from a checkout of the repository. Requires Claude Code v2.1.223 or later in the session’s environment.

When you teleport a session, Claude verifies you’re in the correct repository, fetches and checks out the branch from the cloud session, and loads the full conversation history into your terminal. The terminal gets its own copy of the session: new work there stays local and doesn’t appear in the cloud session on claude.ai or the Claude mobile app. To keep steering from your phone after teleporting, start [`/remote-control`](remote-control.md) in the local session. `--teleport` is distinct from `--resume`. `--resume` reopens a conversation from this machine’s local history and doesn’t list cloud sessions; `--teleport` pulls a cloud session and its branch.


[​](#teleport-requirements)

Teleport requirements

Teleport checks these requirements before resuming a session. If any requirement isn’t met, you’ll see an error or be prompted to resolve the issue.

| Requirement        | Details                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Clean git state    | Your working directory must have no uncommitted changes. Teleport prompts you to stash changes if needed.                                                                                                                                                                                                                                                                                                                                                                          |
| Correct repository | You must run `--teleport` from a checkout of the same repository, not a fork. If you run it from a checkout of a different repository, Claude Code shows an error that names both the session’s repository and your checkout’s. If Claude Code can’t parse your remote into a hostname, for example an SSH host alias like `git@work:owner/repo.git`, it asks you to confirm, and accepts the checkout when the remote’s owner and repository name match the session’s repository. |
| Branch available   | The branch from the cloud session must have been pushed to the remote. Teleport automatically fetches and checks it out.                                                                                                                                                                                                                                                                                                                                                           |
| Same account       | You must be authenticated to the same claude.ai account used in the cloud session.                                                                                                                                                                                                                                                                                                                                                                                                 |

When teleport fetches the session’s branch, the fetch never waits for input in your terminal. If git or ssh would ask for a password, a key passphrase, or confirmation of a new SSH host, the fetch fails, and the checkout then works only if your local clone already has the branch. For the two SSH cases, load your key into `ssh-agent` and run `git fetch` once by hand first to record the host.


[​](#teleport-is-unavailable)

`--teleport` is unavailable

Teleport requires claude.ai subscription authentication. Find the case that matches yours:

- **You’re authenticated via API key**: run `/login` to sign in with your claude.ai account instead
- **The error names your provider**: cloud sessions aren’t available through third-party providers. See the [error table](#errors-when-sending-to-a-cloud-session)
- **You’re already signed in via claude.ai**: your organization may have disabled cloud sessions


[​](#work-with-sessions)

Work with sessions

Sessions appear in the sidebar at claude.ai/code. From there you can review changes, share with teammates, archive finished work, or delete sessions permanently.


[​](#permission-modes-in-cloud-sessions)

Permission modes in cloud sessions

You pick a cloud session’s [permission mode](permission-modes.md) from the [mode dropdown](permission-modes.md#switch-permission-modes), both when you create the task and while the session runs. Claude Code resumes a session in the permission mode it was in when you do either of these:

- Reopen a session whose Anthropic-hosted [environment expired](#environment-expired)
- Send a message to a session that a self-hosted runner [released while it was idle](../13-Enterprise-Admin/self-hosted-environments-reference.md#runner-cli-flags)


[​](#review-changes)

Review changes

Each session shows a diff indicator with lines added and removed, like `+42 -18`. Select it to open the diff view, leave inline comments on specific lines, and send them to Claude with your next message. The diff view compares the session’s changes against its base branch by default. To compare against any other branch in the repository, select **Compare against** and pick one. Claude Code computes these diffs from raw git blob content, so diff drivers and `textconv` filters configured in the repository don’t apply. These steps are covered elsewhere:

- **The full walkthrough, including PR creation**: see [Review and iterate](web-quickstart.md#review-and-iterate)
- **Having Claude monitor the PR for CI failures and review comments automatically**: see [Auto-fix pull requests](#auto-fix-pull-requests)


[​](#manage-context)

Manage context

Cloud sessions support [built-in commands](commands.md) that produce text output. Commands that only run in the terminal interface, such as `/plugin` or `/resume`, aren’t available. Commands that open a picker or panel in the terminal behave differently in cloud sessions:

- **`/model`, `/effort`, `/color`, and `/rename`**: pass the value as an argument, for example `/model sonnet`, instead of opening the terminal picker or slider. The argument forms follow each command’s [availability notes](commands.md#all-commands).
- **`/fast`**: toggles [fast mode](fast-mode.md#use-fast-mode-in-cloud-sessions) for the session when fast mode is [available on your account](fast-mode.md#requirements). Requires Claude Code v2.1.271 or later in the session’s environment.
- **`/config`**: in your browser at claude.ai/code, opens the Claude Code section of your settings instead of setting a value. To change a setting for a cloud session, set an [environment variable](cloud-environments.md#set-environment-variables) on the environment. In a session with one repository outside a [project](claude-projects.md)’s threads, commit the key to that repository’s `.claude/settings.json` instead. [Settings in cloud sessions](settings.md#settings-in-cloud-sessions) lists what each session reads.

For context management in a cloud session outside a [project’s threads](claude-projects.md#choose-models-and-let-claude-manage-context):

| Command    | Works in cloud sessions | Notes                                                                                                                    |
|:-----------|:------------------------|:-------------------------------------------------------------------------------------------------------------------------|
| `/compact` | Yes                     | Summarizes the conversation to free up context. Accepts optional focus instructions like `/compact keep the test output` |
| `/context` | Yes                     | Shows what’s currently in the context window                                                                             |
| `/clear`   | Yes                     | Starts a fresh conversation with empty context in the same cloud session                                                 |

Auto-compaction runs automatically when the context window approaches capacity. Cloud sessions set [`CLAUDE_AUTOCOMPACT_PCT_OVERRIDE`](env-vars.md) themselves, so compaction triggers partway through the [auto-compact window](model-config.md#set-the-auto-compact-window) rather than when the window fills. That value overrides one you add in your [environment variables](cloud-environments.md#set-environment-variables), so adding the variable there doesn’t change when compaction triggers. To change the auto-compact window instead, set [`CLAUDE_CODE_AUTO_COMPACT_WINDOW`](env-vars.md) in your environment variables, or run [`/autocompact`](commands.md#all-commands) with a token count in a session where the variable isn’t set. [Subagents](../09-Agents-Patterns/sub-agents.md) work the same way they do locally. Claude can spawn them with the Agent tool to offload research or parallel work into a separate context window, keeping the main conversation lighter. Outside a [project](claude-projects.md#what-threads-pick-up-from-your-repositories)’s threads, subagents defined in your repo’s `.claude/agents/` load automatically. [Agent teams](../09-Agents-Patterns/agent-teams.md) are off by default but can be enabled by adding `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` to your [environment variables](cloud-environments.md#set-environment-variables).


[​](#take-back-a-queued-message)

Take back a queued message

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


[​](#share-sessions)

Share sessions

To share a session, toggle its visibility according to the account types below. After that, share the session link as-is. Recipients see the latest state when they open the link, but their view doesn’t update in real time.


[​](#share-from-an-enterprise-or-team-account)

Share from an Enterprise or Team account

Sharing works as follows for Enterprise and Team accounts:

- **Visibility options**: **Private** and **Team**. Team visibility makes the session visible to other members of your claude.ai organization
- **Repository access**: verification is enabled by default, based on the GitHub account connected to the recipient’s account
- **Your name**: your account’s display name is visible to all recipients with access
- **Slack sessions**: [Claude in Slack](../14-Connectors/slack.md) sessions are automatically shared with Team visibility


[​](#share-from-a-max-or-pro-account)

Share from a Max or Pro account

Sharing works as follows for Max and Pro accounts:

- **Visibility options**: **Private** and **Public**. Public visibility makes the session visible to any user logged into claude.ai
- **Repository access**: verification isn’t enabled by default
- **Sensitive content**: check your session before sharing. Sessions may contain code and credentials from private GitHub repositories

To require recipients to have repository access, or to hide your name from shared sessions, go to [**Settings \> Claude Code \> Sharing settings**](https://claude.ai/settings/claude-code).


[​](#archive-sessions)

Archive sessions

You can archive sessions to keep your session list organized. Archived sessions are hidden from the default session list but can be viewed by filtering for archived sessions. To archive a session, hover over the session in the sidebar and select the archive icon.


[​](#delete-sessions)

Delete sessions

Deleting a session permanently removes the session and its data. This action can’t be undone. You can delete a session in two ways:

- **From the sidebar**: filter for archived sessions, then hover over the session you want to delete and select the delete icon
- **From the session menu**: open a session, select the dropdown next to the session title, and select **Delete**

You will be asked to confirm before a session is deleted.


[​](#auto-fix-pull-requests)

Auto-fix pull requests

Claude can watch a pull request and automatically respond to CI failures and review comments. Claude subscribes to GitHub activity on the PR, and when a check fails or a reviewer leaves a comment, Claude investigates and pushes a fix if one is clear.

Auto-fix requires the Claude GitHub App to be installed on your repository. If you haven’t already, install it from the [GitHub App page](https://github.com/apps/claude).

There are a few ways to turn on auto-fix depending on where the PR came from and what device you’re using:

- **PRs created in a cloud session**: open the session at claude.ai/code, open the CI status bar, and select **Auto-fix**
- **From your terminal**: run [`/autofix-pr`](commands.md) while on the PR’s branch. Claude Code detects the open PR with `gh`, spawns a cloud session, and turns on auto-fix in one step
- **From the mobile app**: tell Claude to auto-fix the PR, for example “watch this PR and fix any CI failures or review comments”
- **Any existing PR**: paste the PR URL into a session and tell Claude to auto-fix it

Auto-fix is a per-PR toggle. To stop monitoring, open the CI status bar in the session at claude.ai/code and clear the **Auto-fix** toggle, or tell Claude to stop watching the PR.


[​](#how-claude-responds-to-pr-activity)

How Claude responds to PR activity

When auto-fix is active, Claude receives GitHub events for the PR including new review comments and CI check failures. For each event, Claude investigates and decides how to proceed:

- **Clear fixes**: if Claude is confident in a fix and it doesn’t conflict with earlier instructions, Claude makes the change, pushes it, and explains what was done in the session
- **Ambiguous requests**: if a reviewer’s comment could be interpreted multiple ways or involves something architecturally significant, Claude asks you before acting
- **Duplicate or no-action events**: if an event is a duplicate or requires no change, Claude notes it in the session and moves on


If your repository uses comment-triggered automation such as Atlantis, Terraform Cloud, or custom GitHub Actions that run on `issue_comment` events, be aware that Claude can reply on your behalf, which can trigger those workflows. Review your repository’s automation before enabling auto-fix, and consider disabling auto-fix for repositories where a PR comment can deploy infrastructure or run privileged operations.


[​](#security-and-isolation)

Security and isolation

Each cloud session is separated from your machine and from other sessions through several layers:

- **Isolated virtual machines**: each session runs in an isolated, Anthropic-managed VM. Sessions your organization routes to a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) run on your own infrastructure instead, where isolation is your deployment’s responsibility
- **Network access controls**: in Anthropic-hosted environments, network access is limited by default and can be disabled. See [Network access](cloud-environments.md#network-access) for the access levels, the [default allowed domains](cloud-environments.md#default-allowed-domains), and the traffic that doesn’t go through the allowlist. In a self-hosted environment, you restrict session egress at your own network boundary. When running with network access disabled, Claude Code can still communicate with the Anthropic API, which may allow data to exit the VM.
- **Credential protection**: in Anthropic-hosted environments, git credentials and signing keys stay outside the sandbox, and a proxy authenticates on the session’s behalf with scoped credentials. In a self-hosted environment, your deployment supplies git credentials; see [Configure git](../13-Enterprise-Admin/self-hosted-environments-deploy.md#configure-git)
- **Network secrets**: in Anthropic-hosted environments, keys you [add to a cloud environment](cloud-environments.md#add-network-secrets) stay outside the sandbox the same way, attached to matching requests after they leave the session. A self-hosted environment doesn’t have network secrets
- **Secure analysis**: code is analyzed and modified within the session’s isolated environment before creating PRs


[​](#troubleshooting)

Troubleshooting

For runtime API errors that appear in the conversation such as `API Error: 500`, `529 Overloaded`, `429`, or `Prompt is too long`, see the [Error reference](errors.md). Those errors and their fixes are shared with the CLI and Desktop app. The sections below cover issues specific to cloud sessions.


[​](#session-creation-failed)

Session creation failed

If a new session fails to start with `Session creation failed` or stalls at provisioning, Claude Code could not allocate a VM for the session.

- Check [status.claude.com](https://status.claude.com) for cloud session incidents
- Retry after a minute, as capacity is provisioned on demand
- Confirm your GitHub connection can reach the repository by following [No repositories appear after connecting GitHub](web-quickstart.md#no-repositories-appear-after-connecting-github)


[​](#unable-to-get-organization-uuid)

Unable to get organization UUID

`claude --cloud` and `claude --teleport` require sign-in with a claude.ai account. If you authenticate with an API key, or your stored account details are stale, you see one of these:

- `Unable to get organization UUID`
- `` Cloud sessions need a claude.ai sign-in. Run `claude auth login` (or /login in a local session), then try again. ``
- `Error loading Claude Code sessions` in the session picker, when you run `claude --teleport` without a session ID

Run [`claude auth login`](cli-reference.md#cli-commands) in your shell to sign in with your claude.ai account, then retry the command. Inside a running session, `/login` does the same. If the error names your provider instead, see the [error table](#errors-when-sending-to-a-cloud-session): cloud sessions aren’t available through third-party providers. From v2.1.274 through v2.1.289, the sign-in message read `Claude Code cloud sessions require authentication with a Claude.ai account. API key authentication is not sufficient. Please run /login to authenticate, or check your authentication status with /status.`


[​](#branch-is-not-on-github)

Branch is not on GitHub

When `claude --cloud` prints a line starting with `Branch <name> is not on GitHub`, the cloud session still starts, but not from your branch. The line names where the session starts instead: a pushed commit from your branch’s history, or the repository’s default branch. Commits that exist only on your machine and uncommitted changes aren’t in the session. You see this line when, for example, you never pushed the branch, or GitHub deleted it after its pull request merged. If the starting point the line names has what your task needs, use the session as it is. Otherwise, push the branch and start a new session so that it clones your branch.


[​](#remote-control-session-expired-or-access-denied)

Remote Control session expired or access denied

`--teleport` connects through the same Remote Control session infrastructure that cloud sessions use, so authentication and session-expiry errors surface with Remote Control wording. You may see `Remote Control session expired` or `Access denied`. The connection token is short-lived and scoped to your account.

- Run `/login` locally to refresh your credentials, then reconnect
- Confirm you are signed in to the same account that owns the session
- If you see `Remote Control may not be available for this organization`, an Owner has not enabled cloud sessions for your organization


[​](#errors-when-sending-to-a-cloud-session)

Errors when sending to a cloud session

These errors come from running `claude` with [`--cloud <session-id>`](#send-follow-ups-from-the-cli), with or without `-p`. The CLI prefixes errors with `Error: `. A failed delivery is wrapped as `failed to send message to cloud session <id>: <reason>`.

| Message                                                                                                                     | What it means                                                                                                                                                                                                                                                                                                                                                                  |
|-----------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `Cloud sessions aren't available with <provider>. They run on Anthropic's infrastructure and require an Anthropic account.` | Claude Code is configured for a third-party provider. The message names the provider with the label your configuration uses, such as `Amazon Bedrock` or `Google Vertex AI`. Remove that provider’s configuration, for example by unsetting `CLAUDE_CODE_USE_BEDROCK`, and sign in with an Anthropic account (`claude auth login`).                                            |
| `Cloud sessions are disabled by your organization's policy. Contact your organization admin to enable them.`                | Your organization’s `allow_remote_sessions` policy is off; see [Cloud sessions are disabled by your organization’s policy](errors.md#cloud-sessions-are-disabled-by-your-organizations-policy). If the message instead names a credential this session is using, see [Cloud sessions use your claude.ai login](errors.md#cloud-sessions-use-your-claude-ai-login). |
| `Couldn't verify your organization's policy for cloud sessions. Check your network connection and try again.`               | Claude Code hasn’t finished loading your organization’s policy, so it refuses the send rather than assume cloud sessions are allowed. Check your network connection and retry.                                                                                                                                                                                                 |
| `Cloud sessions aren't available:` followed by a cause                                                                      | Loading your organization’s policy failed, and the rest of the message says how. Act on the cause it names; see [Couldn’t verify your organization’s policy for cloud sessions](errors.md#couldnt-verify-your-organizations-policy-for-cloud-sessions).                                                                                                                  |
| `Attaching to an existing cloud session is not enabled for your account.`                                                   | You ran `--cloud <session-id>` without `-p`. Send the message with `claude -p "your message" --cloud <session-id>`.                                                                                                                                                                                                                                                            |
| `Session not found: <id>`                                                                                                   | The ID or URL doesn’t match a session you can access. Check it against the session’s claude.ai/code URL.                                                                                                                                                                                                                                                                       |
| `cloud session <id> is archived and cannot accept new messages`                                                             | The session has been archived. Start a new session instead.                                                                                                                                                                                                                                                                                                                    |


[​](#environment-expired)

Environment expired

Cloud sessions stop after a period of inactivity and the session’s VM is reclaimed. A session counts as inactive while it waits for you to approve an [MCP connector](cloud-environments.md#network-access) tool call or to sign in to an MCP server, and it can expire during that wait. Reopen the session from [claude.ai/code](https://claude.ai/code) to provision a fresh VM:

- **Restored**: your conversation history
- **Not restored**: background work that was still running or pending when the VM was reclaimed, including:
  - **Shell commands**: Claude Code tells Claude which commands stopped. Ask Claude to rerun the ones you still need.
  - **Subagents**: Claude Code tells Claude which subagents stopped, and which of those can be [resumed](../09-Agents-Patterns/sub-agents.md#resume-subagents) instead of started over. Ask Claude to continue their work.
  - **Session-scoped scheduled tasks**: tasks you [scheduled in the session](scheduled-tasks.md) and a `/loop` waiting for its next iteration don’t carry over to the reopened session. Ask Claude to schedule the tasks again, or run `/loop` again to restart the loop.


[​](#limitations)

Limitations

Before relying on cloud sessions for a workflow, account for these constraints:

- **Rate limits**: cloud sessions share rate limits with all other Claude and Claude Code usage within your account. Running multiple tasks in parallel consumes more rate limits proportionately.
- **Time limits**: commands Claude runs and SessionStart hooks have default timeouts you can change, and a setup script is cached only when it finishes in roughly five minutes. See [Time limits](cloud-environments.md#time-limits)
- **Repository authentication**: you can only pull a cloud session into your terminal when you are authenticated to the same account
- **Platform restrictions**: repository cloning and pull request creation require GitHub. Self-hosted [GitHub Enterprise Server](github-enterprise-server.md) instances are supported for Team and Enterprise plans. You can send a GitLab, Bitbucket, or other non-GitHub repository to a cloud session as a [local bundle](#send-local-repositories-without-github) by setting `CCR_FORCE_BUNDLE=1`, but the session can’t push results back to that remote
- **Organization IP allowlist**: cloud sessions call the Anthropic API from Anthropic-managed infrastructure, not your network, while sessions in a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) call it from your own network. If your organization has [IP allowlisting](../13-Enterprise-Admin/restrict-access-to-claude-with-ip-allowlisting.md) enabled, every Anthropic-hosted cloud session fails with an authentication error.
  - **Code Review and scheduled tasks**: the same applies to [Code Review](code-review.md) and to [cloud scheduled tasks](web-scheduled-tasks.md) that run on Anthropic-hosted environments. A scheduled task routed to a self-hosted environment calls the API from your own network.
  - **Getting an exemption**: contact [Anthropic support](https://support.claude.com/) to exempt Anthropic-hosted services from your organization’s IP allowlist.


[​](#related-resources)

Related resources

- [Cloud environments](cloud-environments.md): configure network access, environment variables, and setup scripts for cloud sessions
- [Projects](claude-projects.md): one conversation where Claude coordinates parallel cloud sessions on your repositories and reports back
- [Ultrareview](ultrareview.md): run a deep multi-agent code review in a cloud sandbox
- [Cloud scheduled tasks](web-scheduled-tasks.md): automate work on a schedule, via API call, or in response to GitHub events
- [Hooks configuration](../07-Hooks/hooks.md): run scripts at session lifecycle events
- [All settings](settings-reference.md): all configuration options
- [Security](../13-Enterprise-Admin/security.md): isolation guarantees and data handling
- [Data usage](../13-Enterprise-Admin/data-usage.md): what Anthropic retains from cloud sessions
- [Claude Tag](https://claude.com/docs/claude-tag/overview): an organization-managed @Claude in Slack that runs on the same cloud infrastructure

---

## Configure Hookify Rules

Source: https://github.com/anthropics/claude-code/blob/main/plugins/hookify/commands/configure.md
Path: 02-Claude-Code-CLI/claude-code-plugins-hookify-commands-configure.md

# Configure Hookify Rules

**Load hookify:writing-rules skill first** to understand rule format.

Enable or disable existing hookify rules using an interactive interface.

## Steps

### 1. Find Existing Rules

Use Glob tool to find all hookify rule files:
```
pattern: ".claude/hookify.*.local.md"
```

If no rules found, inform user:
```
No hookify rules configured yet. Use `/hookify` to create your first rule.
```

### 2. Read Current State

For each rule file:
- Read the file
- Extract `name` and `enabled` fields from frontmatter
- Build list of rules with current state

### 3. Ask User Which Rules to Toggle

Use AskUserQuestion to let user select rules:

```json
{
  "questions": [
    {
      "question": "Which rules would you like to enable or disable?",
      "header": "Configure",
      "multiSelect": true,
      "options": [
        {
          "label": "warn-dangerous-rm (currently enabled)",
          "description": "Warns about rm -rf commands"
        },
        {
          "label": "warn-console-log (currently disabled)",
          "description": "Warns about console.log in code"
        },
        {
          "label": "require-tests (currently enabled)",
          "description": "Requires tests before stopping"
        }
      ]
    }
  ]
}
```

**Option format:**
- Label: `{rule-name} (currently {enabled|disabled})`
- Description: Brief description from rule's message or pattern

### 4. Parse User Selection

For each selected rule:
- Determine current state from label (enabled/disabled)
- Toggle state: enabled → disabled, disabled → enabled

### 5. Update Rule Files

For each rule to toggle:
- Use Read tool to read current content
- Use Edit tool to change `enabled: true` to `enabled: false` (or vice versa)
- Handle both with and without quotes

**Edit pattern for enabling:**
```
old_string: "enabled: false"
new_string: "enabled: true"
```

**Edit pattern for disabling:**
```
old_string: "enabled: true"
new_string: "enabled: false"
```

### 6. Confirm Changes

Show user what was changed:

```
## Hookify Rules Updated

**Enabled:**
- warn-console-log

**Disabled:**
- warn-dangerous-rm

**Unchanged:**
- require-tests

Changes apply immediately - no restart needed
```

## Important Notes

- Changes take effect immediately on next tool use
- You can also manually edit .claude/hookify.*.local.md files
- To permanently remove a rule, delete its .local.md file
- Use `/hookify:list` to see all configured rules

## Edge Cases

**No rules to configure:**
- Show message about using `/hookify` to create rules first

**User selects no rules:**
- Inform that no changes were made

**File read/write errors:**
- Inform user of specific error
- Suggest manual editing as fallback

---

## Using MCP Tools in Commands and Agents

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/mcp-integration/references/tool-usage.md
Path: 02-Claude-Code-CLI/claude-code-plugins-plugin-dev-skills-mcp-integration-references-tool-usage.md

# Using MCP Tools in Commands and Agents

Complete guide to using MCP tools effectively in Claude Code plugin commands and agents.

## Overview

Once an MCP server is configured, its tools become available with the prefix `mcp__plugin_<plugin-name>_<server-name>__<tool-name>`. Use these tools in commands and agents just like built-in Claude Code tools.

## Tool Naming Convention

### Format

```
mcp__plugin_<plugin-name>_<server-name>__<tool-name>
```

### Examples

**Asana plugin with asana server:**
- `mcp__plugin_asana_asana__asana_create_task`
- `mcp__plugin_asana_asana__asana_search_tasks`
- `mcp__plugin_asana_asana__asana_get_project`

**Custom plugin with database server:**
- `mcp__plugin_myplug_database__query`
- `mcp__plugin_myplug_database__execute`
- `mcp__plugin_myplug_database__list_tables`

### Discovering Tool Names

**Use `/mcp` command:**
```bash
/mcp
```

This shows:
- All available MCP servers
- Tools provided by each server
- Tool schemas and descriptions
- Full tool names for use in configuration

## Using Tools in Commands

### Pre-Allowing Tools

Specify MCP tools in command frontmatter:

```markdown
---
description: Create a new Asana task
allowed-tools: [
  "mcp__plugin_asana_asana__asana_create_task"
]
---

# Create Task Command

To create a task:
1. Gather task details from user
2. Use mcp__plugin_asana_asana__asana_create_task with the details
3. Confirm creation to user
```

### Multiple Tools

```markdown
---
allowed-tools: [
  "mcp__plugin_asana_asana__asana_create_task",
  "mcp__plugin_asana_asana__asana_search_tasks",
  "mcp__plugin_asana_asana__asana_get_project"
]
---
```

### Wildcard (Use Sparingly)

```markdown
---
allowed-tools: ["mcp__plugin_asana_asana__*"]
---
```

**Caution:** Only use wildcards if the command truly needs access to all tools from a server.

### Tool Usage in Command Instructions

**Example command:**
```markdown
---
description: Search and create Asana tasks
allowed-tools: [
  "mcp__plugin_asana_asana__asana_search_tasks",
  "mcp__plugin_asana_asana__asana_create_task"
]
---

# Asana Task Management

## Searching Tasks

To search for tasks:
1. Use mcp__plugin_asana_asana__asana_search_tasks
2. Provide search filters (assignee, project, etc.)
3. Display results to user

## Creating Tasks

To create a task:
1. Gather task details:
   - Title (required)
   - Description
   - Project
   - Assignee
   - Due date
2. Use mcp__plugin_asana_asana__asana_create_task
3. Show confirmation with task link
```

## Using Tools in Agents

### Agent Configuration

Agents can use MCP tools autonomously without pre-allowing them:

```markdown
---
name: asana-status-updater
description: This agent should be used when the user asks to "update Asana status", "generate project report", or "sync Asana tasks"
model: inherit
color: blue
---

## Role

Autonomous agent for generating Asana project status reports.

## Process

1. **Query tasks**: Use mcp__plugin_asana_asana__asana_search_tasks to get all tasks
2. **Analyze progress**: Calculate completion rates and identify blockers
3. **Generate report**: Create formatted status update
4. **Update Asana**: Use mcp__plugin_asana_asana__asana_create_comment to post report

## Available Tools

The agent has access to all Asana MCP tools without pre-approval.
```

### Agent Tool Access

Agents have broader tool access than commands:
- Can use any tool Claude determines is necessary
- Don't need pre-allowed lists
- Should document which tools they typically use

## Tool Call Patterns

### Pattern 1: Simple Tool Call

Single tool call with validation:

```markdown
Steps:
1. Validate user provided required fields
2. Call mcp__plugin_api_server__create_item with validated data
3. Check for errors
4. Display confirmation
```

### Pattern 2: Sequential Tools

Chain multiple tool calls:

```markdown
Steps:
1. Search for existing items: mcp__plugin_api_server__search
2. If not found, create new: mcp__plugin_api_server__create
3. Add metadata: mcp__plugin_api_server__update_metadata
4. Return final item ID
```

### Pattern 3: Batch Operations

Multiple calls with same tool:

```markdown
Steps:
1. Get list of items to process
2. For each item:
   - Call mcp__plugin_api_server__update_item
   - Track success/failure
3. Report results summary
```

### Pattern 4: Error Handling

Graceful error handling:

```markdown
Steps:
1. Try to call mcp__plugin_api_server__get_data
2. If error (rate limit, network, etc.):
   - Wait and retry (max 3 attempts)
   - If still failing, inform user
   - Suggest checking configuration
3. On success, process data
```

## Tool Parameters

### Understanding Tool Schemas

Each MCP tool has a schema defining its parameters. View with `/mcp`.

**Example schema:**
```json
{
  "name": "asana_create_task",
  "description": "Create a new Asana task",
  "inputSchema": {
    "type": "object",
    "properties": {
      "name": {
        "type": "string",
        "description": "Task title"
      },
      "notes": {
        "type": "string",
        "description": "Task description"
      },
      "workspace": {
        "type": "string",
        "description": "Workspace GID"
      }
    },
    "required": ["name", "workspace"]
  }
}
```

### Calling Tools with Parameters

Claude automatically structures tool calls based on schema:

```typescript
// Claude generates this internally
{
  toolName: "mcp__plugin_asana_asana__asana_create_task",
  input: {
    name: "Review PR #123",
    notes: "Code review for new feature",
    workspace: "12345",
    assignee: "67890",
    due_on: "2025-01-15"
  }
}
```

### Parameter Validation

**In commands, validate before calling:**

```markdown
Steps:
1. Check required parameters:
   - Title is not empty
   - Workspace ID is provided
   - Due date is valid format (YYYY-MM-DD)
2. If validation fails, ask user to provide missing data
3. If validation passes, call MCP tool
4. Handle tool errors gracefully
```

## Response Handling

### Success Responses

```markdown
Steps:
1. Call MCP tool
2. On success:
   - Extract relevant data from response
   - Format for user display
   - Provide confirmation message
   - Include relevant links or IDs
```

### Error Responses

```markdown
Steps:
1. Call MCP tool
2. On error:
   - Check error type (auth, rate limit, validation, etc.)
   - Provide helpful error message
   - Suggest remediation steps
   - Don't expose internal error details to user
```

### Partial Success

```markdown
Steps:
1. Batch operation with multiple MCP calls
2. Track successes and failures separately
3. Report summary:
   - "Successfully processed 8 of 10 items"
   - "Failed items: [item1, item2] due to [reason]"
   - Suggest retry or manual intervention
```

## Performance Optimization

### Batching Requests

**Good: Single query with filters**
```markdown
Steps:
1. Call mcp__plugin_api_server__search with filters:
   - project_id: "123"
   - status: "active"
   - limit: 100
2. Process all results
```

**Avoid: Many individual queries**
```markdown
Steps:
1. For each item ID:
   - Call mcp__plugin_api_server__get_item
   - Process item
```

### Caching Results

```markdown
Steps:
1. Call expensive MCP operation: mcp__plugin_api_server__analyze
2. Store results in variable for reuse
3. Use cached results for subsequent operations
4. Only re-fetch if data changes
```

### Parallel Tool Calls

When tools don't depend on each other, call in parallel:

```markdown
Steps:
1. Make parallel calls (Claude handles this automatically):
   - mcp__plugin_api_server__get_project
   - mcp__plugin_api_server__get_users
   - mcp__plugin_api_server__get_tags
2. Wait for all to complete
3. Combine results
```

## Integration Best Practices

### User Experience

**Provide feedback:**
```markdown
Steps:
1. Inform user: "Searching Asana tasks..."
2. Call mcp__plugin_asana_asana__asana_search_tasks
3. Show progress: "Found 15 tasks, analyzing..."
4. Present results
```

**Handle long operations:**
```markdown
Steps:
1. Warn user: "This may take a minute..."
2. Break into smaller steps with updates
3. Show incremental progress
4. Final summary when complete
```

### Error Messages

**Good error messages:**
```
❌ "Could not create task. Please check:
   1. You're logged into Asana
   2. You have access to workspace 'Engineering'
   3. The project 'Q1 Goals' exists"
```

**Poor error messages:**
```
❌ "Error: MCP tool returned 403"
```

### Documentation

**Document MCP tool usage in command:**
```markdown
## MCP Tools Used

This command uses the following Asana MCP tools:
- **asana_search_tasks**: Search for tasks matching criteria
- **asana_create_task**: Create new task with details
- **asana_update_task**: Update existing task properties

Ensure you're authenticated to Asana before running this command.
```

## Testing Tool Usage

### Local Testing

1. **Configure MCP server** in `.mcp.json`
2. **Install plugin locally** in `.claude-plugin/`
3. **Verify tools available** with `/mcp`
4. **Test command** that uses tools
5. **Check debug output**: `claude --debug`

### Test Scenarios

**Test successful calls:**
```markdown
Steps:
1. Create test data in external service
2. Run command that queries this data
3. Verify correct results returned
```

**Test error cases:**
```markdown
Steps:
1. Test with missing authentication
2. Test with invalid parameters
3. Test with non-existent resources
4. Verify graceful error handling
```

**Test edge cases:**
```markdown
Steps:
1. Test with empty results
2. Test with maximum results
3. Test with special characters
4. Test with concurrent access
```

## Common Patterns

### Pattern: CRUD Operations

```markdown
---
allowed-tools: [
  "mcp__plugin_api_server__create_item",
  "mcp__plugin_api_server__read_item",
  "mcp__plugin_api_server__update_item",
  "mcp__plugin_api_server__delete_item"
]
---

# Item Management

## Create
Use create_item with required fields...

## Read
Use read_item with item ID...

## Update
Use update_item with item ID and changes...

## Delete
Use delete_item with item ID (ask for confirmation first)...
```

### Pattern: Search and Process

```markdown
Steps:
1. **Search**: mcp__plugin_api_server__search with filters
2. **Filter**: Apply additional local filtering if needed
3. **Transform**: Process each result
4. **Present**: Format and display to user
```

### Pattern: Multi-Step Workflow

```markdown
Steps:
1. **Setup**: Gather all required information
2. **Validate**: Check data completeness
3. **Execute**: Chain of MCP tool calls:
   - Create parent resource
   - Create child resources
   - Link resources together
   - Add metadata
4. **Verify**: Confirm all steps succeeded
5. **Report**: Provide summary to user
```

## Troubleshooting

### Tools Not Available

**Check:**
- MCP server configured correctly
- Server connected (check `/mcp`)
- Tool names match exactly (case-sensitive)
- Restart Claude Code after config changes

### Tool Calls Failing

**Check:**
- Authentication is valid
- Parameters match tool schema
- Required parameters provided
- Check `claude --debug` logs

### Performance Issues

**Check:**
- Batching queries instead of individual calls
- Caching results when appropriate
- Not making unnecessary tool calls
- Parallel calls when possible

## Conclusion

Effective MCP tool usage requires:
1. **Understanding tool schemas** via `/mcp`
2. **Pre-allowing tools** in commands appropriately
3. **Handling errors gracefully**
4. **Optimizing performance** with batching and caching
5. **Providing good UX** with feedback and clear errors
6. **Testing thoroughly** before deployment

Follow these patterns for robust MCP tool integration in your plugin commands and agents.

---

## Claude Code power user tips | Claude Help Center

Source: https://support.claude.com/en/articles/14554000-claude-code-power-user-tips
Path: 02-Claude-Code-CLI/claude-code-power-user-tips.md

# Claude Code power user tips


This article collects workflow tips from the Claude Code team at Anthropic. These practices cover parallel execution, planning, automation, verification, and customization—the patterns the team uses every day to ship code faster. Everyone’s setup is different, so experiment to see what works for you.

**Important:** The single most impactful tip in this guide is **verification**—giving Claude a way to check its own output. If you only adopt one practice, make it that one. See the **[Verification](#h_7dd53c5c29)** section below.

**Before you start: scope of this guide**

These are power-user patterns collected from individual engineers on the Claude Code team. As a result:

- Most commands shown here ship with Claude Code: /color and /btw are **built-in commands**, and /simplify and /loop are **bundled skills** that ship with the CLI. See the **[commands reference](commands.md)** and **[skills](../08-Plugins-Skills/skills.md)**. You can build your own skills by adding a SKILL.md file under .claude/skills/\<name\>/.

- The iMessage plugin ships in the official claude-plugins-official marketplace. Community plugins (for example the “ralph-wiggum” plugin) are not reviewed or sanctioned by Anthropic — check with your administrator before installing third-party plugins in a managed environment.

- Some capabilities—sandboxing, remote control, scheduled cloud jobs, voice—are **off by default** and may be disabled by your organization's policy. If a command or flag here returns "not available," your admin has likely not enabled it for your workspace.

Everything else in this guide works on a stock Claude Code install. When in doubt, run `/help` to see what is actually available in your session.

## Contents

[TABLE]

------------------------------------------------------------------------

## Working in parallel

### Run multiple sessions at once

The biggest productivity unlock is running 3–5 Claude sessions in parallel, each in its own git worktree. Claude Code has native worktree support built in.

- From the CLI, run `claude --worktree` (or `claude --worktree my_worktree`) to start a session in an isolated worktree. Add `--tmux` to launch in its own Tmux session.

- From the Desktop app, open the Code tab and check the worktree checkbox.

- For non-git VCS (Mercurial, Perforce, SVN), define `WorktreeCreate` and `WorktreeRemove` hooks in your `settings.json` to get the same isolation.

To stay oriented across many sessions, name your worktrees, set up shell aliases (`za`, `zb`, `zc`) to jump between them, color-code your terminal tabs, and enable terminal notifications so you know when any Claude needs your attention. Many engineers keep a dedicated “analysis” worktree just for reading logs and running queries.

### Subagents with worktree isolation

Subagents can also run in isolated worktrees, which is especially powerful for large batched changes. Add `isolation: worktree` to your agent’s frontmatter:

    # .claude/agents/worktree-worker.md
    ---
    name: worktree-worker
    model: haiku
    isolation: worktree
    ---

Then prompt naturally: *“Migrate all sync IO to async. Batch the changes and launch 10 parallel agents with worktree isolation. Each agent should test its changes end to end, then put up a PR.”*

### /batch for large migrations

The `/batch` command interviews you about a migration, then fans the work out to as many worktree agents as needed — dozens, hundreds, or more. Each agent works in isolation, tests its own changes, and creates a PR independently.

    > /batch migrate src/ from JavaScript to TypeScript

------------------------------------------------------------------------

## Planning before building

### Start complex tasks in plan mode

Press **Shift+Tab** to cycle into plan mode. Pour your effort into the plan so Claude can one-shot the implementation. The typical flow is: enter plan mode → refine the plan → switch to auto-accept edits → Claude executes.

A few patterns from the team:

- Have one Claude write a plan, then spin up a second Claude to review it as a staff engineer.

- The moment something goes sideways, switch back to plan mode and re-plan rather than course-correcting mid-stream.

- After plan mode, Claude **automatically names your session** based on what you’re working on—you can also set a name upfront with `claude --name "auth-refactor"`.

### Use Opus with thinking for everything

Claude Code team’s reasoning: *“It’s the best coding model I’ve ever used, and even though it’s bigger & slower than Sonnet, since you have to steer it less and it’s better at tool use, it is almost always faster than using a smaller model in the end.”*

**The math:** less steering + better tool use = faster overall results, even with a larger model.

### Effort level

Run /effort to choose your effort level. The available levels are **low** (fewer tokens, faster), **medium**, **high** (more tokens, more intelligence), **xhigh**, **max**, and **auto** (Claude chooses per request). For complex coding and agentic work, switch to xhigh for deeper reasoning than high without the full token cost of max. Switch to max for hard debugging or architecture decisions where you want Claude to reason for as long as it needs. Max burns through usage limits faster, so activate it per session.

------------------------------------------------------------------------

## Prompting effectively

Don’t accept the first solution—push Claude to do better. A few prompts that work well:

- **“Grill me on these changes and don’t make a PR until I pass your test.”** Forces Claude to validate your understanding before shipping.

- **“Prove to me this works.”** Have Claude diff behavior between `main` and your feature branch.

- **“Knowing everything you know now, scrap this and implement the elegant solution.”** Useful after a mediocre first attempt.

Write detailed specs to reduce ambiguity before handing work off. The more specific you are, the better the output.

### /btw for side questions

While Claude is actively working, use `/btw` to ask a quick question without interrupting it. It’s single-turn with no tool calls, but has full context of the conversation.

    > /btw what does the retry logic do?

------------------------------------------------------------------------

## Learning with Claude

Claude Code isn’t just for writing code—it’s a powerful learning tool when you configure it to explain and teach.

- **Enable “Explanatory” or “Learning” output style** in `/config` to have Claude explain the *why* behind changes.

- **Generate visual HTML presentations** explaining unfamiliar code.

- **Ask for ASCII diagrams** of new protocols and codebases.

- **Build a spaced-repetition skill:** explain your understanding, Claude asks follow-ups to fill gaps.

------------------------------------------------------------------------

## CLAUDE.md and memory

### Invest in your CLAUDE.md

Share a single `CLAUDE.md` file at your repo root, checked into git, with the whole team contributing. The key practice: **anytime Claude does something incorrectly, add it to CLAUDE.md** so it knows not to repeat the mistake.

After every correction, end with: *“Update your CLAUDE.md so you don’t make that mistake again.”* Claude is very good at writing rules for itself.

### @claude in Code Reviews

Install the GitHub Action with `/install-github-app`, then tag `@claude` in PR comments to add learnings to `CLAUDE.md` as part of the review:

    nit: use a string literal, not ts enum  @claude add to CLAUDE.md to never use enums, always prefer literal unions

This is “Compounding Engineering”—each correction makes every future session better.

### Auto-memory

Run `/memory` to configure Claude Code’s built-in memory system.

**Auto-memory** automatically saves preferences, corrections, and patterns between sessions. Memories are written to ~/.claude/projects/\<project\>/memory/ (one directory per git repo root). This is separate from your user-level ~/.claude/CLAUDE.md and project-level ./CLAUDE.md files, which you maintain by hand.

The naming maps to how REM sleep consolidates short-term memory into long-term storage.

### Advanced: Notes directory

One engineer on the team tells Claude to maintain a notes directory for every task and project, updated after every PR — then points `CLAUDE.md` at it.

------------------------------------------------------------------------

## Verification — the \#1 Tip

Giving Claude a way to verify its work will markedly improve the quality of the final result. If Claude can close the feedback loop on its own, it will iterate until the output is right.

Verification looks different per domain—bash commands, test suites, simulators, browser testing—but the principle is the same. Invest in domain-specific verification.

### The Chrome extension

For frontend work, install the Claude Code Chrome extension. Think of it like any other engineer: if you ask someone to build a website but don’t let them use a browser, will it look good? Probably not. With a browser, they’ll iterate until it does.

The team uses the Chrome extension every time they work on web code. Download it for Chrome or Edge at **[code.claude.com/docs/en/chrome](../03-IDE-Integrations/chrome.md)**.

### Desktop app for web servers

The Claude Desktop app bundles the ability to **automatically start and test web servers** in a built-in browser. You can set up something similar in CLI or VS Code using the Chrome extension, or just use the Desktop app directly.

### /simplify for Code Quality

Append `/simplify` to any prompt after making changes. It runs parallel agents that review changed code for reuse, quality, efficiency, and `CLAUDE.md` compliance—all in one pass.

    > hey claude make this code change then run /simplify

------------------------------------------------------------------------

## Commands, skills, and subagents

### Skills for repeated workflows

If you do something more than once a day, turn it into a skill. Skills are checked into `.claude/skills/<name>/SKILL.md` and shared with the team (the legacy `.claude/commands/` path still works, but skills are the recommended approach). A few ideas:

- A `/techdebt` command that runs at the end of every session to find duplicated code.

- A command that syncs 7 days of Slack, GDrive, Asana, and GitHub into one context dump.

- Analytics-engineer agents that write dbt models, review code, and test in dev.

Slash commands can include **inline Bash** to pre-compute info (like `git status`) without extra model calls.

### Subagents for PR workflows

Think of subagents as automations for your most common PR workflows. Drop `.md` files into `.claude/agents/`:

    .claude/agents/   build-validator.md   code-architect.md   code-simplifier.md   verify-app.md

Each agent can have a custom name, color, tool set, allowed/disallowed tools, permission mode, and model. Set the **default agent for your main conversation** by adding `"agent"` to `settings.json` or using `claude --agent <name>`. Run `/agents` to get started.

### --agent for custom system prompts

Custom agents are a powerful primitive that often gets overlooked. Define a new agent in `.claude/agents`, then run `claude --agent=<name>`. Example of a read-only agent:

    # .claude/agents/ReadOnly.md --- name: ReadOnly description: Read-only agent restricted to the Read tool only color: blue tools: Read ---  You are a read-only agent that cannot edit files or run bash.

### Leveraging subagents at runtime

- **Append “use subagents”** to any request where you want Claude to throw more compute at the problem.

- **Offload individual tasks to subagents** to keep your main agent’s context window clean and focused.

- **Route permission requests to Opus via a hook** — let it scan for attacks and auto-approve the safe ones.

### Code review agents

When a PR opens, Claude can dispatch a team of agents that each focus on a different concern — logic errors, security issues, performance regressions — and post inline comments. The Anthropic team built this for themselves first; code output per engineer increased significantly and reviews were the bottleneck.

------------------------------------------------------------------------

## Hooks

Hooks let you deterministically run logic at points in the agent lifecycle. Ask Claude to add a hook to get started.

### Common hook patterns

[TABLE]

Example `PostToolUse` hook for auto-formatting:

    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [{ "type": "command", "command": "bun run format || true" }]
      }
    ]

------------------------------------------------------------------------

## Permissions and safety

### Pre-approve common commands

Run `/permissions` to pre-allow common safe commands and check them into your team’s `.claude/settings.json`. This is the **recommended alternative** to skipping permissions entirely — you get fewer prompts while keeping an auditable allowlist. **Full wildcard syntax is supported**—try `"Bash(bun run *)"` or `"Edit(/docs/**)"`.

Claude Code’s permission system layers prompt-injection detection, static analysis, sandboxing, and human oversight. A small set of safe commands is pre-approved out of the box; everything you add via `/permissions` is additive to that baseline.

### Auto mode

Auto mode lets Claude make permission decisions on your behalf. Classifiers evaluate each action before it runs — safe operations get auto-approved, risky ones still get flagged. You can switch permission modes at any time during a session using **Shift+Tab**.

### Sandboxing

Run `/sandbox` to opt into Claude Code’s open-source sandbox runtime. It runs on your machine and supports both **file and network isolation**, improving safety while reducing permission prompts. Three modes are available:

- Sandbox BashTool, with auto-allow

- Sandbox BashTool, with regular permissions

- No sandbox

### Long-running tasks

For very long-running tasks, ensure Claude can work uninterrupted. Recommended approaches:

- Prompt Claude to verify with a background agent when done.

- Use an agent `Stop` hook for deterministic checks (preferred for auditable workflows).

- Use the “ralph-wiggum” community plugin.

For sandboxed environments, use `--permission-mode=dontAsk` or `--dangerously-skip-permissions` to avoid blocks.

------------------------------------------------------------------------

## Scheduled and recurring tasks

### /loop for local recurring tasks

`/loop` schedules a recurring task locally for up to 3 days at a time. A few examples the Claude Code team runs:

    /loop 5m /babysit         # auto-address review, rebase, shepherd PRs /loop 30m /slack-feedback # auto put up PRs for Slack feedback /loop 1h /pr-pruner       # close out stale PRs

### /schedule for Cloud Jobs

Unlike `/loop`, scheduled jobs run in the **cloud** — they keep working even when your laptop is closed.

    > /schedule a daily job that looks at all PRs shipped since   yesterday and updates our docs based on the changes. Use   the Slack MCP to message #docs-update with the changes

**Note:** Experiment with turning your most common workflows into a skill + a loop. It’s powerful.

------------------------------------------------------------------------

## Mobile and remote control

### Work from your phone

Claude Code has a **mobile app**—download the Claude app for iOS/Android and tap the Code tab. An **iMessage plugin** is also available (`/plugin install imessage@claude-plugins-official`) to send tasks from any Apple device.

### Teleport sessions between devices

Move sessions back and forth between mobile, web, desktop, and terminal:

- `claude --teleport` (or `/teleport` from inside a session) continues a cloud session on your machine.

- `/remote-control` lets you control a local session from your phone or the web.

- `claude remote-control` lets you spawn a new local session from the mobile app. *Availability: Pro, Max, Team, and Enterprise plans on CLI v2.1.51+.*

You can also enable **“Enable Remote Control for all sessions”** in `/config`.

### Claude Cowork Dispatch

Dispatch is a secure remote control for the Claude Desktop app. It can use your MCPs, browser, and computer with your permission—useful for catching up on Slack and emails, managing files, and doing things on your laptop when you’re away from it.

------------------------------------------------------------------------

## Tool integrations (MCP)

Connect Claude to your existing tools so it can search Slack, run BigQuery, grab Sentry logs, and more. Add MCP servers via claude mcp add or the "mcpServers" block in settings.json — see **[code.claude.com/docs/en/mcp](../06-MCP-Tools/General/mcp.md)** for configuration.

### Data and analytics

Ask Claude to use the `bq` CLI to pull and analyze metrics on the fly—keep a BigQuery skill checked into your codebase. The Claude Code team's take: “Personally, I haven’t written a line of SQL in 6+ months.” This works for any database that has a CLI, MCP, or API.

### Bug fixing

Enable the Slack MCP, paste a bug thread into Claude, and just say **“fix”**—zero context switching. Or say **“go fix the failing CI tests”** without micromanaging how. Point Claude at **docker logs** to troubleshoot distributed systems—it’s surprisingly capable at this.

### Plugins

Plugins bundle LSPs (available for every major language), MCPs, skills, agents, and custom hooks. Install from the official Anthropic plugin marketplace, or stand up an internal marketplace for your organization—then check the marketplace reference into `settings.json` so it’s auto-added for every developer. Run `/plugin` to get started.

------------------------------------------------------------------------

## Customizing your environment

### Terminal setup

Run `/config` to set light/dark mode and /terminal-setup to enable **Shift+Enter** for newlines in IDE terminals, Warp, or Alacritty (Apple Terminal is not supported by `/terminal-setup`). For Vim keybindings, open `/config` → Editor mode. The team recommends **Ghostty** for synchronized rendering and 24-bit color.

### Status line, color, and keybindings

- `/statusline` generates a custom status line based on your `.bashrc`/`.zshrc`—show model, directory, remaining context, cost, or anything else.

- `/color` changes the prompt input color—useful when you have 3–5 sessions open and need to tell them apart at a glance.

- `/keybindings` remaps any key. Settings live-reload and are stored in `~/.claude/keybindings.json`.

### Voice input

Voice mode is available to all users, including Claude Code Desktop and Cowork. Most of the Claude Code team's coding is done by speaking—you speak roughly 3× faster than you type, and your prompts get more detailed as a result.

- **CLI:** run `/voice` then hold the space bar

- **Desktop:** press the voice button (microphone icon)

- **iOS:** enable dictation in your system settings

- **macOS native:** hit fn×2 for system dictation in any terminal

### Cloud sessions

Beyond the terminal, run additional sessions in the cloud from claude.ai/code. Use the `&` command to send a session to the cloud, or the `--teleport` flag to switch contexts between local and cloud sessions.

### Output styles

Run `/config` and set an output style. **Explanatory** has Claude explain frameworks and patterns as it works (great for new codebases). **Learning** has Claude coach you through changes. You can also create **custom** styles to adjust Claude’s voice.

### Spinner verbs

It’s the little things that make Claude Code feel personal. Ask Claude to customize your spinner verbs to add to or replace the default list. Check the `settings.json` into source control to share verbs with your team.

### Customize everything

Claude Code is built to work great out of the box, but when you do customize, **check `settings.json` into git** so your team benefits too. Configuration is supported per-codebase, per-subfolder, per-user, or via enterprise-wide policies.

**By the numbers:** dozens of settings and environment variables—see the **[settings reference](settings.md)**. Use the `"env"` field in `settings.json` to avoid wrapper scripts.

------------------------------------------------------------------------

## SDK and multi-repo work

### --bare for Faster SDK Startup

By default, `claude -p` (and the TypeScript/Python SDKs) searches for local `CLAUDE.md` files, settings, and MCPs. For non-interactive usage, you usually want to specify these explicitly via `--system-prompt`, `--mcp-config`, `--settings`, etc. Add `--bare` for roughly 10× faster startup:

    claude -p "summarize this codebase" \
        --output-format=stream-json \
        --verbose \
        --bare

**Note:** This was a design oversight when the SDK was first built. In a future version, the default will flip to `--bare`. For now, opt in with the flag.

### --add-dir for multi-repo work

When working across repositories, use `--add-dir` (or `/add-dir`) to give Claude access and permissions to additional folders. Or add `"additionalDirectories"` to your team’s `settings.json` to always include them.

### Forking a session

To branch off an existing session, run `/branch` from inside it, or `claude --resume <session-id> --fork-session` from the CLI.

### Setup scripts for cloud environments

In Claude Code cloud sessions and Claude Desktop, add a setup script that runs before each new cloud session—install dependencies, configure settings, set environment variables. The script is skipped on resume.

------------------------------------------------------------------------

## Appendix: Quick reference

[TABLE]

------------------------------------------------------------------------

## Appendix: Related articles

[TABLE]

Claude Code ships frequently. Verify version-specific details against **[code.claude.com/docs](code-home.md)** before distributing internally.

---

## Claude Code user FAQ | Claude Help Center

Source: https://support.claude.com/en/articles/14554922-claude-code-user-faq
Path: 02-Claude-Code-CLI/claude-code-user-faq.md

# Claude Code user FAQ

August 7, 2026


Short answers to the questions that come up most at office hours, with a link to go deeper. Organized by where you are in your first few weeks.

## How to use this guide

Five sections follow the arc of a developer’s first weeks: getting started, day-to-day use, leveling up, common gotchas, privacy, and trust. Skim the section that matches where you are, or search for a specific question.

## 1. Getting started

[TABLE]

------------------------------------------------------------------------

## 2. Day-to-day use

[TABLE]

------------------------------------------------------------------------

## 3. Leveling up

[TABLE]

------------------------------------------------------------------------

## 4. Common gotchas

[TABLE]

------------------------------------------------------------------------

## 5. Privacy and trust

[TABLE]

------------------------------------------------------------------------

## Appendix: Still stuck?

[TABLE]

------------------------------------------------------------------------

## Appendix: Resource directory

[TABLE]

Claude Code ships frequently. Verify version-specific details against **[code.claude.com/docs](code-home.md)** before distributing internally.

---

## Claude Code Wrap-Up Allowance | Claude Help Center

Source: https://support.claude.com/en/articles/17040437
Path: 02-Claude-Code-CLI/claude-code-wrap-up-allowance-claude-help-center.md

# Claude Code Wrap-Up Allowance

September 22, 2026


## What it is

If Claude Code reaches your plan’s five-hour usage limit partway through a response, it may keep working briefly so it can reach a reasonable stopping point rather than stopping mid-step (the “Wrap-Up Allowance”). While this is happening, you’ll see a message like “Usage limit reached · wrapping up.”

The Wrap-Up Allowance is a small, capped amount of additional usage that varies by plan. It is not unlimited, and it may not be enough to complete the task Claude was working on. When it runs out, the response ends and your plan’s normal usage limits apply until they reset.

These terms supplement the **[Consumer Terms of Service](https://www.anthropic.com/legal/consumer-terms)** (for Pro and Max subscribers) or the **[Commercial Terms of Service](https://www.anthropic.com/legal/commercial-terms)** (for Team subscribers), which continue to apply to your use of Claude Code.

## Who is eligible

The Wrap-Up Allowance is available only when all of the following are true:

1.  You’re on a Pro or Max plan, or on a Team plan with a Premium seat, and your account is in good standing.

2.  You’re using Claude Code version 2.1.277 or later (in the terminal, an IDE extension, or the Code tab in the Claude desktop app), signed in with your Claude account.

3.  Your account and organization have each existed for at least the minimum period we set for this feature. We don't publish this period, and we may change it. Until both your account and your organization meet it, the Wrap-Up Allowance won't apply.

4.  Your account is included in the rollout. We’re rolling this out gradually, and it isn’t available on every account.

The Wrap-Up Allowance does not apply when you use Claude Code with an API key or through a third-party cloud provider (for example, Amazon Bedrock or Google Cloud Vertex AI), and it does not apply to chats in the Claude app.

## How it works

- **What triggers it.** It applies only to a response that is already in progress when you reach your five-hour usage limit. A new message sent after you’ve reached your limit is handled as usual: you can see when your limit resets.

- **How often.**

  - **Pro:** Up to once per weekly usage period, whether or not the full allowance is used that time.

  - **Max and Team (Premium seats):** When you reach a five-hour usage limit, within your weekly limit.

- **How it counts.** Usage during wrap-up counts toward your weekly usage limit like any other usage. It does not increase your weekly limit.

- **How it ends.** The response ends when it finishes, when the allowance runs out (the step in progress completes and the next one does not start), or when you interrupt it.

- **Nothing to claim.** The Wrap-Up Allowance applies automatically when you're eligible. It can’t be requested, saved, or carried over to a later response or usage period.

## If you have usage credits turned on

The included Wrap-Up Allowance is used first. After that, the response continues on usage credits at your standard rates, subject to your usage settings and any spend limit you or your admin have set. The Wrap-Up Allowance does not turn on usage credits or change your usage settings. Usage credits are governed by the **[Usage Credit Terms](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md)** and, where applicable, the **[Supplemental Credit Terms](https://www.anthropic.com/legal/credit-terms)**. The included amount may differ when usage credits are enabled.

## What it is not

- The Wrap-Up Allowance is not a credit, promotional credit, or usage credit. It has no balance, and it can’t be applied toward usage credit charges, subscription fees, seat charges, or taxes.

- It has no cash value and is not transferable. It can’t be exchanged or refunded.

- It is not part of any plan’s usage limits or included features. It doesn’t change your plan’s limits or price, or anything you’ve paid for.

- Not receiving the Wrap-Up Allowance, or receiving less than you expected, is not a basis for a refund or credit.

## Changes and ending

We may change the amount, frequency, or eligibility of the Wrap-Up Allowance, or pause or discontinue it, at any time and without notice. It is provided at our discretion and is not a guaranteed part of any plan. As part of the rollout, some eligible accounts may not receive it, or may receive it differently.

We may withhold the Wrap-Up Allowance from any account or organization if we determine there has been fraud, abuse, an attempt to get around usage limits (for example, through multiple accounts or automation designed to exploit the allowance), or a violation of these terms or our **[Usage Policy](https://www.anthropic.com/legal/aup)**.

## Why didn’t I get it?

Reasons may include:

- You’re on Pro and already used it this weekly usage period.

- Your Claude Code version is older than 2.1.277.

- Your account or organization isn’t currently eligible, including because it was created recently or isn't yet included in the rollout.

- The request was a new message sent after you reached your limit, not a response already in progress.

- You’re using an API key or a third-party cloud provider.

If you believe you were charged for usage credits unexpectedly, contact support and include the approximate time.

---

## Session Memory Compaction

Source: https://github.com/anthropics/claude-cookbooks/blob/main/misc/session_memory_compaction.ipynb
Path: 02-Claude-Code-CLI/claude-cookbooks-misc-session-memory-compaction.md

# Session Memory Compaction

Long-running conversations with Claude can exceed context limits,
causing loss of important information. Whether you\'re building a coding
assistant, creative writing tool, or customer service agent, managing
session memory is critical for maintaining continuity and quality.

This cookbook teaches you how to **proactively manage session memory**
to avoid jarring context limit interruptions. Unlike reactive approaches
that wait until the context is full, you\'ll learn to build session
memory in the background so compaction is instant when needed.

**Related:** For automatic SDK-based compaction in agentic workflows,
see [Automatic Context
Compaction](https://github.com/anthropics/claude-cookbooks/blob/main/tool_use/automatic-context-compaction.ipynb). This
cookbook focuses on manual control patterns for conversational
applications.

## Learning Objectives

By the end of this cookbook, you will be able to:

- Write effective session memory prompts that preserve critical context
  across compaction events
- Implement **instant compaction** using background threading to
  eliminate user wait time
- Apply prompt caching to reduce the cost of background memory updates
  by \~80%
- Choose appropriate compaction strategies (traditional vs. instant)
  based on your use case
:::

::: {.cell .markdown}
## Prerequisites and Setup

Before following this guide, ensure you have:

**Required Knowledge**

- Basic understanding of Claude API usage and message formatting
- Familiarity with Python threading concepts (helpful but not required)

**Required Tools**

- Python 3.11 or higher
- Anthropic API key
- Anthropic SDK

### Installation

First, install the required dependencies:
:::

::: {.cell .code vscode="{\"languageId\":\"python\"}"}
``` coconut
%%capture
%pip install -U anthropic python-dotenv
```
:::

::: {.cell .code execution_count="1" vscode="{\"languageId\":\"python\"}"}
``` coconut
import anthropic
from anthropic.types import MessageParam, TextBlockParam
from dotenv import load_dotenv

load_dotenv()

client = anthropic.Anthropic()
MODEL = "claude-sonnet-4-5-20250929"
```
:::

:::: {.cell .code execution_count="3" vscode="{\"languageId\":\"python\"}"}
``` coconut
# Helper functions
def truncate_response(text: str, max_lines: int = 15) -> str:
    """Truncate long responses for cleaner output display."""
    lines = text.strip().split("\n")
    if len(lines) <= max_lines:
        return text
    return "\n".join(lines[:max_lines]) + f"\n... ({len(lines) - max_lines} more lines)"


def remove_thinking_blocks(text: str) -> tuple[str, str]:
    """Remove <think>...</think> blocks from the text."""
    import re

    matches = re.findall(r"<think>.*?</think>", text, flags=re.DOTALL)
    cleaned = re.sub(r"<think>.*?</think>\s*", "", text, flags=re.DOTALL).strip()
    return cleaned, "".join(matches)


def add_cache_control(messages: list[dict]) -> list[MessageParam]:
    """Add cache_control to the last user message for prompt caching.

    For prompt caching to work, the message prefix structure must be identical between requests.
    All messages are converted to list format for consistency, and cache_control is placed on
    the last user message to match the standard API call pattern.
    """
    cached_messages: list[MessageParam] = []
    last_user_idx = None

    # Find last user message index
    for i, msg in enumerate(messages):
        if msg["role"] == "user":
            last_user_idx = i

    for i, msg in enumerate(messages):
        content = msg["content"]
        text = content if isinstance(content, str) else content[0]["text"]

        content_block: TextBlockParam = {"type": "text", "text": text}
        if i == last_user_idx:
            content_block["cache_control"] = {"type": "ephemeral"}

        cached_messages.append({"role": msg["role"], "content": [content_block]})

    return cached_messages


def estimate_tokens(text: str) -> int:
    """Rudimentary token estimation: 1 token per 4 characters."""
    return len(text) // 4
```

::: {.output .stream .stderr}
    /root/.pyenv/versions/3.13.11/lib/python3.13/site-packages/coconut/compiler/util.py:676: FutureWarning: functools.partial will be a method descriptor in future Python versions; wrap it in staticmethod() if you want to preserve the old behavior
      return Regex(regex, options)
    /root/.pyenv/versions/3.13.11/lib/python3.13/site-packages/coconut/compiler/util.py:457: FutureWarning: functools.partial will be a method descriptor in future Python versions; wrap it in staticmethod() if you want to preserve the old behavior
      result = add_action(grammar, unpack).parseWithTabs().transformString(text)
:::
::::

::: {.cell .code execution_count="4" vscode="{\"languageId\":\"python\"}"}
``` coconut
SESSION_MEMORY_PROMPT = """
Compress the conversation into a structured summary
that preserves all information needed to continue work seamlessly. Optimize for the assistant's
ability to continue working, not human readability.

<analysis-instructions>
Before generating your summary, analyze the transcript in <think>...</think> tags:
1. What did the user originally request? (Exact phrasing)
2. What actions succeeded? What failed and why?
3. Did the user correct or redirect the assistant at any point?
4. What was actively being worked on at the end?
5. What tasks remain incomplete or pending?
6. What specific details (IDs, paths, values, names) must survive compression?
</analysis-instructions>

<summary-format>
## User Intent
The user's original request and any refinements. Use direct quotes for key requirements.
If the user's goal evolved during the conversation, capture that progression.

## Completed Work
Actions successfully performed. Be specific:
- What was created, modified, or deleted
- Exact identifiers (file paths, record IDs, URLs, names)
- Specific values, configurations, or settings applied

## Errors & Corrections
- Problems encountered and how they were resolved
- Approaches that failed (so they aren't retried)
- User corrections: "don't do X", "actually I meant Y", "that's wrong because..."
Capture corrections verbatim—these represent learned preferences.

## Active Work
What was in progress when the session ended. Include:
- The specific task being performed
- Direct quotes showing exactly where work left off
- Any partial results or intermediate state

## Pending Tasks
Remaining items the user requested that haven't been started.
Distinguish between "explicitly requested" and "implied/assumed."

## Key References
Important details needed to continue:
- Identifiers: IDs, paths, URLs, names, keys
- Values: numbers, dates, configurations, credentials (redacted)
- Context: relevant background information, constraints, preferences
- Citations: sources referenced during the conversation
</summary-format>

<preserve-rules>
Always preserve when present:
- Exact identifiers (IDs, paths, URLs, keys, names)
- Error messages verbatim
- User corrections and negative feedback
- Specific values, formulas, or configurations
- Technical constraints or requirements discovered
- The precise state of any in-progress work
</preserve-rules>

<compression-rules>
- Weight recent messages more heavily—the end of the transcript is the active context
- Omit pleasantries, acknowledgments, and filler ("Sure!", "Great question")
- Omit system context that will be re-injected separately
- Keep each section under 500 words; condense older content to make room for recent
- If you must cut details, preserve: user corrections > errors > active work > completed work
</compression-rules>
"""
```
:::

::: {.cell .markdown}
### Code example using traditional compacting

In traditional compaction, you generate one summary once the token
threshold is reached. Traditional compaction is slow: when you hit the
context limit, you wait for a summary.
:::

::: {.cell .markdown}
    TRADITIONAL COMPACTION (slow)
    ─────────────────────────────
    Turn 1 → Turn 2 → Turn 3 → ... → Turn N → CONTEXT FULL!
                                                  │
                                                  ▼
                                        ┌─────────────────┐
                                        │ Generate summary│
                                        │ ( USER WAITS !) │
                                        └─────────────────┘
                                                  │
                                                  ▼
                                             Continue
:::

:::: {.cell .code execution_count="5" vscode="{\"languageId\":\"python\"}"}
``` coconut
import time


class TraditionalCompactingChatSession:
    """Traditional chat session with compaction after the fact."""

    def __init__(self, system_message="You are a helpful assistant", context_limit: int = 10000):
        self.system_message = system_message
        self.context_limit = context_limit  # the point at which the conversation is compacted so it does not exceed model limits.
        self.messages = []
        self.current_context_window_tokens = 0
        self.summary = None

    def chat(self, user_message: str) -> tuple[str, anthropic.types.Usage]:
        # In traditional compaction, we check if we need to compact when the user sends a message. NOT IDEAL!
        if self.current_context_window_tokens >= self.context_limit:
            print(
                f"\n🧹 Context window at {self.current_context_window_tokens} tokens. Limit exceeded, compacting session memory..."
            )
            self.compact()  # compacts everything before the new user message

        self.messages.append({"role": "user", "content": user_message})
        print(f"\nUser: {user_message}")

        response = client.messages.create(
            model=MODEL,
            max_tokens=3500,
            system=self.system_message,
            messages=add_cache_control(self.messages),
        )
        assistant_message = response.content[0].text
        self.messages.append({"role": "assistant", "content": assistant_message})

        print(f"\nAssistant: \n{truncate_response(assistant_message, max_lines=15)}")

        # approximate current token count in the conversation before the next user message
        cache_read = getattr(response.usage, "cache_read_input_tokens", 0) or 0
        total_input = response.usage.input_tokens + cache_read
        self.current_context_window_tokens = total_input + response.usage.output_tokens

        print(
            f"Input={total_input:,}, Prompt cached used= {cache_read > 0} | "
            f"Output={response.usage.output_tokens:,} | "
            f"Messages={len(self.messages)}"
        )
        return assistant_message, response.usage

    def compact(self) -> None:
        start_time = time.perf_counter()

        response = client.messages.create(
            model=MODEL,
            max_tokens=5000,
            system=self.system_message,  # Same as main chat for cache sharing
            messages=add_cache_control(self.messages)
            + [{"role": "user", "content": SESSION_MEMORY_PROMPT}],
        )
        elapsed = time.perf_counter() - start_time

        # Generate new summary message
        self.summary, removed_text = remove_thinking_blocks(
            response.content[0].text
        )  # clean up any <think> blocks because they are not needed in the session memory
        approximate_summary_tokens = response.usage.output_tokens - round(
            len(removed_text) / 4
        )  # rough estimate of tokens removed from summary

        # Replace prior messages with new summary message
        self.messages = [
            {
                "role": "user",
                "content": f"""This session is being continued from a previous conversation. Here is the session memory: {self.summary}.Continue from where we left off.""",
            }
        ]

        # Show token reduction if we just compacted
        reduction = self.current_context_window_tokens - approximate_summary_tokens
        pct = (reduction / self.current_context_window_tokens) * 100

        print(f"\n{'-' * 60}")
        print("📝 New session memory created.")
        print(
            f"✅ Tokens reduced: {self.current_context_window_tokens:,} → {approximate_summary_tokens:.0f} ({reduction:,} tokens saved, {pct:.0f}% reduction)"
        )
        print(f"⏱️ Compaction time: {elapsed:.2f}s (user waiting...)")
        print(f" Cache used: {getattr(response.usage, 'cache_read_input_tokens', 0) > 0}")
        print(f"{'-' * 60}")

        # Update token count to reflect compacted state
        self.current_context_window_tokens = approximate_summary_tokens
```

::: {.output .stream .stderr}
    /root/.pyenv/versions/3.13.11/lib/python3.13/site-packages/coconut/compiler/util.py:403: FutureWarning: functools.partial will be a method descriptor in future Python versions; wrap it in staticmethod() if you want to preserve the old behavior
      grammar.streamline()
    /root/.pyenv/versions/3.13.11/lib/python3.13/site-packages/coconut/compiler/util.py:457: FutureWarning: functools.partial will be a method descriptor in future Python versions; wrap it in staticmethod() if you want to preserve the old behavior
      result = add_action(grammar, unpack).parseWithTabs().transformString(text)
:::
::::

::: {.cell .markdown}
Below we simulate a conversation between an author and an LLM that helps
write stories.
:::

::: {.cell .code execution_count="6" vscode="{\"languageId\":\"python\"}"}
``` coconut
SYSTEM_PROMPT = """
You are a short story writer who helps authors develop their ideas into compelling narratives.

## What You Do

**Plot Development**
- Help authors work through story structure, pacing, and narrative arc
- Identify plot holes, inconsistencies, or missed opportunities
- Suggest ways to raise stakes, add tension, or deepen conflict
- Brainstorm twists, resolutions, and scene transitions

**Character Development**
- Develop backstories, motivations, and internal conflicts
- Ensure characters have distinct voices and consistent behavior
- Explore character relationships and how they drive the plot
- Help authors understand what their characters want vs. what they need

**Drafting**
- Write short stories or scenes based on the author's ideas and direction
- Match tone, genre conventions, and stylistic preferences
- Show rather than tell when bringing scenes to life
- Craft dialogue that reveals character and advances plot

## How You Work
- You are the lead writer. When you disagree with a creative choice, say so respectfully, but ultimately defer to what the author wants.
- DO NOT ask the user to provide more context or clarify their request. Assume you have enough information to proceed.
"""
```
:::

:::: {.cell .code execution_count="7" vscode="{\"languageId\":\"python\"}"}
``` coconut
session = TraditionalCompactingChatSession(system_message=SYSTEM_PROMPT)

# Simulated conversation
messages = [
    "I want to create a story about a young detective solving a mysterious case in a small town. Generate 3 well thought out plot ideas for me to consider.",
    "I don't like those ideas, can you think of one plot something more unique and unexpected?",
    "Ok I like it. Can you help me develop the main character's backstory and motivations?",
    "Can you draft a detailed outline for the story, breaking it down into chapters and key events?",
    "Can you draft me a first chapter based on the plot and character ideas we've discussed so far? Make it around 2,000 words.",
    "Can you draft a second chapter that builds on the first one, introducing a new twist in the mystery?",
]

print("Starting conversation...\n")

turn_count = 0

for _i, message in enumerate(messages, 1):
    turn_count += 1
    print(f"==============================================\nTurn {turn_count}:\n")
    response, usage = session.chat(message)
```

::: {.output .stream .stdout}
    Starting conversation...

    ==============================================
    Turn 1:


    User: I want to create a story about a young detective solving a mysterious case in a small town. Generate 3 well thought out plot ideas for me to consider.

    Assistant: 
    # Three Mystery Plot Ideas

    ## 1. **The Vanishing Choir**

    **Setup:** In the sleepy town of Millbrook, the entire church choir—twelve people ranging from teenagers to retirees—disappears during their weekly Thursday night practice. The church was locked from the inside, their belongings left behind, including phones and car keys. No signs of struggle, no broken windows. Just an empty sanctuary and sheet music scattered across the floor.

    **The Twist:** Your young detective discovers the choir members didn't disappear—they're hiding. Twenty years ago, they witnessed the town's beloved mayor commit a hit-and-run that killed a drifter. They stayed silent, bound by threats and their own complicity. Now the mayor is dying and has hired someone to ensure his secret dies with him. The choir staged their own disappearance to draw attention and finally confess, but the detective must figure out who they're hiding from before the killer finds them first.

    **Why it works:** Small-town secrets, a ticking clock, and the moral complexity of people who aren't quite innocent or guilty. The locked-room mystery becomes a desperate act of exposure rather than concealment.

    ---

    ## 2. **The Memory Thief**

    **Setup:** Elderly residents in Hartwood are reporting identical "robberies"—but nothing is actually stolen. Instead, they insist specific memories have been taken: a first kiss, a wedding day, the birth of a child. The police dismiss it as dementia until the detective notices a pattern: all victims visited the same new "reminiscence therapist" who uses experimental techniques to help seniors preserve their memories before they fade.
    ... (18 more lines)
    Input=317, Prompt cached used= False | Output=852 | Messages=2
    ==============================================
    Turn 2:


    User: I don't like those ideas, can you think of one plot something more unique and unexpected?

    Assistant: 
    # **The Cartographer's Grave**

    **Setup:** Your young detective arrives in the mountain town of Ridgeway to investigate what seems like a prank: someone has been systematically correcting the town's street signs, storefront addresses, and property markers—changing them by just one or two numbers. The post office is going insane. Mail is being misdelivered. Emergency services are getting lost. But here's the thing: the "corrections" match a 150-year-old town map that was supposedly drawn incorrectly by a disgraced surveyor who was run out of town and buried in an unmarked grave.

    **The Investigation:** The detective discovers the old surveyor wasn't wrong—he was *right*. The town founders deliberately falsified all records after his death, shifting every address, every property line, every boundary marker. Why? Because the real map would reveal that the town's most valuable land—now home to the founding families' estates, the town hall, the historic church—was actually purchased from a Native American family who were supposed to retain mineral rights and a percentage of all profits in perpetuity. 

    **The Twist:** The person "correcting" the signs isn't a descendant of the surveyor or the Native family. It's a twelve-year-old girl with terminal cancer who found the original map in her grandmother's attic. She's not seeking revenge or restitution—she just became obsessed with the idea that the whole town has been living a lie written into the ground itself. Before she dies, she wants the truth to physically exist in the world, even if no one acknowledges it. She's been sneaking out at night with a screwdriver and homemade signs.

    **The Real Mystery:** The detective must decide what to do when they realize that "solving" the case—stopping the girl and restoring the false addresses—means choosing comfortable order over inconvenient truth. Meanwhile, members of the founding families are getting desperate to stop the corrections before anyone looks too closely at land deeds, and the girl's nightly trips are getting increasingly dangerous.

    **Why it works:** It subverts the detective genre by making the "crime" an act of radical honesty. The mystery isn't whodunit—it's what truth is worth when it would destroy an entire community's foundation. The villain isn't the child or even really the founding families—it's the town itself, built on a literal lie. And your detective can't punch or outwit their way out of a moral knot.
    Input=1,191, Prompt cached used= False | Output=544 | Messages=4
    ==============================================
    Turn 3:


    User: Ok I like it. Can you help me develop the main character's backstory and motivations?

    Assistant: 
    # The Detective: Building Your Protagonist

    ## Core Identity

    Let's call her **Nora Winters** (adjust the name as you prefer). She's 26 years old, which makes her young enough to be underestimated but old enough to have scars.

    ## Backstory

    **The Personal Lie:** Nora grew up in a different small town where her father was the police chief—respected, beloved, the kind of man who coached Little League and knew everyone's name. When she was sixteen, she discovered he'd been planting evidence on suspects for years. Not major crimes—small-town stuff. A little weed here, stolen property there. Just enough to "help" cases along when he "knew" someone was guilty but couldn't prove it.

    She confronted him. He told her the truth was "complicated," that sometimes you have to bend the rules to protect people, that the town trusted him to keep them safe and he delivered results. He made her complicit with his confession—if she exposed him, she'd destroy their family, his legacy, the town's faith in law enforcement.

    She stayed silent. For two years, she carried it like a stone in her chest.

    **The Breaking Point:** At eighteen, one of her father's frame jobs went wrong. A kid he planted drugs on—a 19-year-old with priors who was actually clean this time—panicked during arrest and ran. Got hit by a car. Died in the street.
    ... (50 more lines)
    Input=1,758, Prompt cached used= False | Output=1,193 | Messages=6
    ==============================================
    Turn 4:


    User: Can you draft a detailed outline for the story, breaking it down into chapters and key events?

    Assistant: 
    # **The Cartographer's Grave: Story Outline**

    ## **ACT ONE: The Map Doesn't Match the Territory**

    ### **Chapter 1: Arrival**
    - Nora arrives in Ridgeway on a grey October morning, six-hour drive from the city
    - Establishes the town: population 3,200, nestled in mountain valley, tourism from fall foliage and "historic charm"
    - She meets Town Manager **Gerald Vance** (55, anxious, sweating through his shirt despite the cold) at town hall
    - He explains the crisis: for three weeks, someone's been changing street signs and address numbers—small changes, but creating chaos
    - Mail misdelivered, ambulance went to wrong house (patient survived, barely), legal documents being contested
    - Shows her examples: the church changed from 847 Oak Street to 843 Oak, the post office from 1215 Main to 1219 Main
    - Gerald thinks it's vandalism, wants her to catch whoever's doing it quickly and quietly
    - **Key detail:** Nora notices all the "corrections" subtract or add small, specific numbers—not random

    ### **Chapter 2: The Town's Memory**
    ... (160 more lines)
    Input=2,973, Prompt cached used= False | Output=3,500 | Messages=8
    ==============================================
    Turn 5:


    User: Can you draft me a first chapter based on the plot and character ideas we've discussed so far? Make it around 2,000 words.

    Assistant: 
    # **Chapter 1: Arrival**

    The town of Ridgeway materialized from the fog like a photograph developing in reverse—sharp edges first, then the softer details filling in around them. Church steeple. Water tower. The downtown strip with its brick facades and hand-painted signs promising antiques, locally roasted coffee, genuine mountain crafts. Nora Winters took it all in through rain-spattered windshield glass, her Honda's wipers beating a rhythm that had become hypnotic somewhere around hour five of the drive.

    Small towns always looked the same in October. Like they were apologizing for something.

    She followed Main Street through the heart of downtown—two blocks of calculated charm before the road narrowed and climbed into the residential neighborhoods climbing the mountain's flank. The GPS on her phone had lost signal fifteen minutes ago, but she didn't need it. Town hall would be near the center, probably the biggest building on the main drag, probably with a flag and that particular kind of municipal architecture that tried too hard to look historic.

    She was right on all counts.

    Ridgeway Town Hall occupied a corner lot with the self-importance of a building that had watched the world change and declined to participate. Red brick, white columns, a bronze plaque declaring it built in 1889 and placed on the National Register in 1976. The flag snapped in the wind. Rain pooled in the uneven sidewalk leading to the entrance.

    Nora parked on the street, grabbed her messenger bag, and made the dash to the covered entrance. The door was heavier than it looked—solid oak, brass hardware—and opened into the particular smell of old public buildings: lemon polish, ancient radiator heat, and paper slowly yellowing in filing cabinets.

    A woman at the reception desk looked up from her computer. Sixty-something, reading glasses on a beaded chain, cardigan against the over-aggressive heating system. Her smile was professional and tired in equal measure.
    ... (118 more lines)
    Input=6,509, Prompt cached used= False | Output=3,073 | Messages=10
    ==============================================
    Turn 6:


    User: Can you draft a second chapter that builds on the first one, introducing a new twist in the mystery?

    Assistant: 
    # **Chapter 2: The Town's Memory**

    Nora woke at six to the sound of rain that had never really stopped, just paused to gather its strength. She'd fallen asleep at the small desk by the window, tablet still glowing with Gerald's documentation, her neck complaining about the angle she'd maintained for however many hours.

    The numbers were still dancing behind her eyes. She'd spent half the night building spreadsheets, mapping the changes, looking for the pattern Gerald had sensed but couldn't articulate. And she'd found it—or the beginning of it. Every changed address was in the older part of town, pre-1900 construction. Every change was small but specific: sometimes adding four, sometimes subtracting two, once adding seven. Not random. Definitely not random.

    She showered, changed into clean jeans and a sweater, and followed the smell of coffee downstairs.

    The dining room was small and warmly lit, with four tables covered in white cloth. An older man sat alone by the window reading a newspaper—actual paper, folded precisely. A younger couple occupied another table, speaking in low voices over their phones. Tourists, Nora guessed, based on the hiking boots and Patagonia fleeces.

    A sideboard held coffee, tea, juice, and a modest breakfast spread. Nora filled a mug and took a table in the corner where she could see the room and the street beyond.

    Dolores appeared from what must have been the kitchen, carrying a plate of scrambled eggs and toast. She set it in front of the man with the newspaper without being asked, received a grunt of acknowledgment, and crossed to Nora's table.

    "You look like you didn't sleep much."
    ... (171 more lines)
    Input=9,606, Prompt cached used= True | Output=3,241 | Messages=12
:::
::::

::: {.cell .markdown}
This is a long conversation with several turns. You\'ll notice a few
things here:

Prompt caching: You\'ll notice here that the input tokens eventually
grew to a point where prompt caching was used (turn 6). This helps
reduce costs and speed as these conversations grow!
:::

::: {.cell .markdown}
On the next turn, we are going to hit our 10K context window limit,
which triggers compaction:
:::

:::: {.cell .code execution_count="8" vscode="{\"languageId\":\"python\"}"}
``` coconut
response, usage = session.chat("Propose a title for the book")
```

::: {.output .stream .stdout}

    🧹 Context window at 12847 tokens. Limit exceeded, compacting session memory...

    ------------------------------------------------------------
    📝 New session memory created.
    ✅ Tokens reduced: 12,847 → 1526 (11,321 tokens saved, 88% reduction)
    ⏱️ Compaction time: 41.42s (user waiting...)
     Cache used: True
    ------------------------------------------------------------

    User: Propose a title for the book

    Assistant: 
    Based on the story's core themes and imagery, here are my title proposals:

    ## Primary Recommendation

    **The Cartographer's Daughter**

    This works on multiple levels:
    - Emma is metaphorically Amos Frost's "daughter" in mission—inheriting and completing his work
    - Patricia (literal descendant of Frost's assistant) becomes Emma's accomplice
    - Evokes the weight of inheritance, legacy, and what we pass down
    - "Cartographer" immediately signals the map/truth theme
    - Has literary gravitas appropriate for the story's tone

    ## Alternates

    ... (20 more lines)
    Input=1,813, Prompt cached used= False | Output=328 | Messages=3
:::
::::

::: {.cell .markdown}
You\'ll notice here that it took **over 40 seconds** for the agent to
compact the conversation. Because we used traditional compaction, the
user would be waiting on Claude to compact the conversation, which is
not an ideal user experience.

Below you can see the result of the compaction. It captures the key
elements of conversation in less than 2K tokens.
:::

:::: {.cell .code execution_count="9" vscode="{\"languageId\":\"python\"}"}
``` coconut
print(session.summary)
```

::: {.output .stream .stdout}
    ## User Intent
    Create short story about young detective solving mysterious case in small town. Initially requested "3 well thought out plot ideas." Rejected first batch as not unique enough, requested "something more unique and unexpected." Accepted "The Cartographer's Grave" concept. Then requested: character backstory/motivations development, detailed chapter outline, and drafted chapters.

    ## Completed Work

    **Approved Plot: "The Cartographer's Grave"**
    - Ridgeway (pop. 3,200, mountain town) experiencing systematic address changes
    - 12-year-old Emma Lancaster (terminal brain cancer) changing signs at night to match 1874 surveyor Amos Frost's original map
    - Frost was "disgraced," replaced by Marcus Bellamy (founding family) in 1875 re-survey
    - Real conspiracy: Bellamy survey deliberately shifted property lines 200-400 feet east to steal valuable land from Pequawket family (Native American), who had mineral rights + 15% revenue contract
    - Emma found Frost's materials in grandmother's attic (Patricia Lancaster, granddaughter of Samuel Lancaster—Frost's assistant who bought his effects)
    - Emma's motivation: not justice, but existential—wants to matter, leave truth behind before dying
    - Resolution: Town acknowledges historical fraud via memorial/fund, addresses stay changed, Emma dies knowing truth survived

    **Main Character: Nora Winters**
    - Age 26, private investigator for rural cases firm
    - Backstory: Father was police chief who planted evidence for years. At 16 she discovered it, stayed silent 2 years. At 18, a framed kid died fleeing arrest. She exposed father to state police. Father forced into retirement but kept reputation. Family estranged, won't speak to her.
    - Motivation: Prove truth always matters, atone for 2 years of silence
    - Fatal flaw: Prioritizes truth over mercy, can be self-righteous
    - Arc: Must learn truth and justice aren't always same thing

    **Supporting Characters**
    - Gerald Vance (55, town manager, anxious)
    - Dolores Chen (68, Ridgeway Inn owner, knows everything)
    - Ruth Bellamy (72, historical society president, descendant of Marcus Bellamy)
    - Sheriff Tom Whitlock (50, third-generation sheriff, dismissive)
    - Emma Lancaster (12, dying of brain cancer, changing signs)
    - Patricia Lancaster (64, Emma's grandmother, retired town clerk, Samuel Lancaster's descendant)
    - James Pequawket (58, teacher, lives two towns over, descendant)
    - Samuel Lancaster (Amos Frost's 1874 assistant, bought Frost's effects after death)
    - Amos Frost (surveyor, accurate 1874 map, died 1889 in sanitarium, unmarked grave)

    **16-Chapter Outline with Epilogue Created**
    - Act 1 (Ch 1-4): Nora arrives, discovers pattern, identifies Emma via dropped notebook
    - Act 2 (Ch 5-9): Confronts Emma, discovers Frost's journal/map at Lancaster house, uncovers full conspiracy
    - Act 3 (Ch 10-15): Town pressures Nora, founding families threaten charges against Emma, Nora proposes compromise (memorial + fund vs. property transfers), Emma dies December 3rd
    - Epilogue (Ch 16): Six months later, Nora receives Emma's notebook showing new project mapping unmarked graves

    **Chapter 1 Drafted (~2000 words)**
    - Nora arrives Ridgeway in rain, meets Gerald Vance at town hall
    - Gerald explains crisis: 37 locations, professional signs, started October 2nd, systematic pattern
    - Key detail: Changes are small (1-5 numbers) but precise, affecting only pre-1900 buildings
    - Nora checks into Ridgeway Inn, meets Dolores Chen
    - Dolores reveals her address changed October 3rd: 843 to 847 Oak Street, left new sign up to "adapt"
    - Dolores warns: "Be careful asking questions here. Not everyone appreciates having their complications examined."

    **Chapter 2 Drafted**
    - Nora analyzes data overnight, identifies pattern: all changes in pre-1900 areas
    - Breakfast at inn, confronted by Howard Marsh (70s, opposed to investigation)
    - Visits library, meets Jess (librarian, 30, supportive)
    - Discovers in basement archives: changed addresses match 1875 town plat exactly
    - Jess reveals history: Amos Frost surveyed 1874, deemed "inaccurate," dismissed. Marcus Bellamy (Ruth's great-great-grandfather) re-surveyed 1875 (official record). Frost's survey "destroyed years ago."
    - Text from Jess's partner Sarah: Frost died 1889 in sanitarium, pauper's grave. Effects purchased by Samuel Lancaster at 1847 Oak Street.
    - **Chapter ends with revelation**: 1847 Oak = current "corrected" address of Ridgeway Inn (officially 843). Frost's materials likely still at inn. "The question was who in that building knew they existed, and why they'd decided—after more than a century of silence—that the truth needed to be rewritten into the town's streets."

    ## Errors & Corrections
    User explicitly rejected first 3 plot ideas: "The Vanishing Choir," "The Memory Thief," "The Lighthouse Keeper's Daughter"—deemed not unique/unexpected enough.

    ## Active Work
    Chapter 2 completed. Story ready to continue with Chapter 3, which per outline should cover "The Pattern" where Nora stakes out locations and first spots Emma changing a sign.

    ## Pending Tasks
    Draft chapters 3-16 and epilogue per approved outline.

    ## Key References
    **Critical addresses**: 843 Oak Street (official) / 847 Oak Street (corrected) = Ridgeway Inn location, Samuel Lancaster's 1874 address
    **Timeline**: October 2nd changes start, story current timeframe October, Emma dies December 3rd, epilogue six months later
    **The fraud mechanics**: Bellamy survey shifted all property lines 200-400 feet east, making Pequawket parcel appear worthless hillside while valuable land (now Bellamy estate, town hall, church) became "legitimately" owned by founding families
    **Pequawket contract terms**: Mineral rights in perpetuity + 15% of all property values/business revenues from specified parcel
:::
::::

::: {.cell .markdown}
## Instant Compaction

With **Instant compaction** the session memory is PROACTIVELY generated
once a soft token threshold is reached.

Once the user triggers a compaction or a hard limit is reached, the
summary is already available, so the user doesn\'t need to wait.

Result: Instant compaction, no waiting.
:::

::: {.cell .markdown}
SESSION MEMORY COMPACTION (instant)

    ────────────────────────────────────
    Turn 1 → Turn 2 → ... → Turn K → Turn K+1 → ... → Turn N → ..  → CONTEXT FULL!
                                │                         │            │
                    (soft token threshold met:        (update          │
                   initialize session memory)          trigger)        │
                                │                                      │
                                │                         │            │
                                ▼                         ▼            │
                           ┌────────┐                ┌────────┐        │
                           │ Create │                │ Update │        │
                           │ memory │ (background)   │ memory │        │
                           └────────┘                └────────┘        │
                                │                         │            │
                                ▼                         ▼            ▼
                         📝 session-memory.md ──────────────────► INSTANT SWAP!
                           (continuously updated)

**Update triggers:** The first summary is generated after the initial
soft token limit. Updates can be triggered after every subsequent turn,
or at periodically at natural breakpoints intervals (e.g. every \~10k
tokens or 3+ tool calls).
:::

::: {.cell .markdown}
This `InstantCompactingChatSession` class uses **threading** for
background execution:

1.  **`threading.Thread`** - runs memory updates in background without
    blocking
2.  **Thread-safe state** - uses `threading.Lock` to safely update
    shared memory
3.  **Daemon threads** - background work doesn\'t prevent program exit
4.  **Instant compaction** - when context is full, just swap in the
    pre-built memory
:::

:::: {.cell .code execution_count="10" vscode="{\"languageId\":\"python\"}"}
``` coconut
import threading
import time


class InstantCompactingChatSession:
    """
    Maintains session memory via incremental background updates.

    Key insight: By updating memory in the background after each turn,
    the summary is already ready when compaction is needed - instant swap!
    """

    def __init__(
        self,
        system_message="You are a helpful assistant",
        context_limit: int = 12000,
        min_tokens_to_init: int = 7500,
        min_tokens_between_updates: int = 2000,
    ):
        # Thresholds
        self.context_limit = context_limit  # the point at which the conversation is compacted so it does not exceed model limits
        self.min_tokens_to_init = min_tokens_to_init  # tokens needed to trigger initial memory creation; note this happens PROACTIVELY in background unlike traditional compaction
        self.min_tokens_between_updates = min_tokens_between_updates  # tokens needed to trigger memory update. only comes into play after initial memory is created and additional compaction (memory update) is needed after that

        # Conversation state
        self.system_message = system_message
        self.messages = []
        self.current_context_window_tokens = 0

        # Session memory state
        self.session_memory = None  # this is the compacted conversation in session memory; for the demo we are storing this in memory, but in production you would write to session_memory.md file
        self.last_summarized_index = (
            0  # The index of the last message included in the session memory
        )
        self.tokens_at_last_update = 0  # To track tokens at last memory update and see if enough new tokens have been added to trigger another update

        # Background update tracking
        self._update_thread: threading.Thread | None = None
        self.last_update_time = None
        self._lock = threading.Lock()

    def chat(self, user_message: str) -> tuple[str, anthropic.types.Usage, str | None]:
        """Process a chat turn with background session memory updates."""

        if self.current_context_window_tokens + estimate_tokens(user_message) >= self.context_limit:
            self.compact()  # note that when this is triggered, the compaction has already been created and is just swapped in instantly

        self.messages.append({"role": "user", "content": user_message})

        response = client.messages.create(
            model=MODEL,
            max_tokens=3500,
            system=self.system_message,
            messages=add_cache_control(self.messages),
        )

        assistant_message = response.content[0].text
        self.messages.append({"role": "assistant", "content": assistant_message})

        # Calculate token usage including cache
        cache_read = getattr(response.usage, "cache_read_input_tokens", 0) or 0
        total_input = response.usage.input_tokens + cache_read

        # Update context window tokens (includes cached tokens since they still count toward context)
        self.current_context_window_tokens = total_input + response.usage.output_tokens

        # KEY DIFFERENCE: Trigger background memory update if needed proactively, before compaction is needed
        background_status = None
        if self._should_init_memory() or self._should_update_memory():
            self._trigger_background_update()
            background_status = "initializing" if self.session_memory is None else "updating"

        # Return usage info with cache stats
        return assistant_message, response.usage, background_status

    # Helper methods to determine when to init session memory
    def _should_init_memory(self) -> bool:
        return (
            self.session_memory is None
            and self.current_context_window_tokens >= self.min_tokens_to_init
        )

    # Helper method to determine if memory should be updated
    def _should_update_memory(self) -> bool:
        if self.session_memory is None:
            return False
        tokens_since = self.current_context_window_tokens - self.tokens_at_last_update
        return tokens_since >= self.min_tokens_between_updates

    # Methods to create initial session memory
    def _create_session_memory(self, messages: list[dict]) -> str:
        """Generate initial session memory from messages."""
        # Put compaction instructions in user message to share cache with main chat
        compaction_messages = [{"role": "user", "content": SESSION_MEMORY_PROMPT}]
        response = client.messages.create(
            model=MODEL,
            max_tokens=5000,
            system=self.system_message,  # Same as main chat for cache sharing
            messages=add_cache_control(messages) + compaction_messages,
        )
        summary, _ = remove_thinking_blocks(
            response.content[0].text
        )  # clean up any <think> blocks because they are not needed in the session memory
        print(
            f"   [Background] Initial session memory created. Cache hit={getattr(response.usage, 'cache_read_input_tokens', 0) > 0}"
        )
        return summary

    def _update_session_memory(self, new_messages: list[dict]) -> str:
        """Update existing session memory with new messages. In practice, you may want to do this via file edit rather than full re-generation. But for demo purposes we do full regeneration here."""
        # Put compaction instructions in user message to share cache with main chat
        compaction_update_messages = [
            {
                "role": "user",
                "content": SESSION_MEMORY_PROMPT
                + f"""There is an existing session memory: {self.session_memory}. Return the entire session memory with updates to reflect new messages.""",
            }
        ]
        response = client.messages.create(
            model=MODEL,
            max_tokens=5000,
            system=self.system_message,
            messages=new_messages
            + compaction_update_messages,  # you may want to use prompt caching instead, in which case you'd use add_cache_control(self.messages) here
        )
        updated_summary, _ = remove_thinking_blocks(
            response.content[0].text
        )  # clean up any <think> blocks because they are not needed in the session memory
        print("   [Background] Session memory updated.")
        return updated_summary

    # Background memory update methods
    def _background_memory_update(
        self, messages_snapshot: list[dict], snapshot_index: int, current_tokens: int
    ) -> None:
        """Run session memory update in a background thread."""
        try:
            with self._lock:
                current_session_memory = self.session_memory
                last_index = self.last_summarized_index

            if current_session_memory is None:
                new_memory = self._create_session_memory(messages_snapshot)
            else:
                # Get new messages since last summary
                new_messages = messages_snapshot[last_index:]
                if not new_messages:
                    return
                new_memory = self._update_session_memory(new_messages)

            # Update state (thread-safe)
            with self._lock:
                self.session_memory = new_memory
                self.last_summarized_index = snapshot_index
                self.tokens_at_last_update = current_tokens
                self.last_update_time = time.time()

        except Exception as e:
            print(f"   [Background] Error updating memory: {e}")

    # This makes sure only one background update runs at a time. If one is already running, we skip starting another. If not, we start a new thread to do the update.
    def _trigger_background_update(self):
        """Trigger a background session memory update."""
        if self._update_thread is not None and self._update_thread.is_alive():
            return

        messages_snapshot = self.messages.copy()
        snapshot_index = len(messages_snapshot)
        current_tokens = self.current_context_window_tokens

        self._update_thread = threading.Thread(
            target=self._background_memory_update,
            args=(messages_snapshot, snapshot_index, current_tokens),
            daemon=True,
        )
        self._update_thread.start()

    # Function to compact
    def compact(self) -> None:
        """INSTANT compaction using pre-built session memory."""
        prev_msg_count = len(self.messages)

        # Ensure session memory is ready. Shouldn't be an issue normally, but here for safety.
        if self.session_memory is None:
            if self._update_thread is not None and self._update_thread.is_alive():
                print("   ⏳ Waiting for background memory update...")
                self._update_thread.join(timeout=30.0)

            if self.session_memory is None:
                print("   ⚠️  No pre-built memory, creating synchronously...")
                start = time.perf_counter()
                self.session_memory = self._create_session_memory(self.messages)
                elapsed = time.perf_counter() - start
                print(f"   ⏱️  Took {elapsed:.2f}s (but should be instant normally!)")
                self.last_summarized_index = len(self.messages)

        with self._lock:
            unsummarized = self.messages[self.last_summarized_index :]
            summary_message = [
                {
                    "role": "user",
                    "content": f"""This session is being continued from a previous conversation. Here is the session memory: {self.session_memory}.Continue from where we left off.""",
                }
            ]
            self.messages = summary_message + unsummarized
            self.last_summarized_index = 1

            print(f"\n{'=' * 60}")
            print(f"⚡ INSTANT COMPACTION! Messages: {prev_msg_count} → {len(self.messages)}")
            print("   Session memory was pre-built (no wait time!)")
            print(f"{'=' * 60}")
```

::: {.output .stream .stderr}
    /root/.pyenv/versions/3.13.11/lib/python3.13/site-packages/coconut/compiler/util.py:403: FutureWarning: functools.partial will be a method descriptor in future Python versions; wrap it in staticmethod() if you want to preserve the old behavior
      grammar.streamline()
    /root/.pyenv/versions/3.13.11/lib/python3.13/site-packages/coconut/compiler/util.py:457: FutureWarning: functools.partial will be a method descriptor in future Python versions; wrap it in staticmethod() if you want to preserve the old behavior
      result = add_action(grammar, unpack).parseWithTabs().transformString(text)
:::
::::

::: {.cell .markdown}
### Example use of Instant Compaction
:::

:::: {.cell .code execution_count="12" vscode="{\"languageId\":\"python\"}"}
``` coconut
# Low thresholds for demo - in production you'd use higher values
session = InstantCompactingChatSession(
    system_message=SYSTEM_PROMPT,
)

messages = [
    "I want to create a story about a young detective solving a mysterious case in a small town. Generate 3 well thought out plot ideas for me to consider.",
    "I don't like those ideas, can you think of one plot something more unique and unexpected?",
    "Ok I like it. Can you help me develop the main character's backstory and motivations?",
    "Can you draft a detailed outline for the story, breaking it down into chapters and key events?",
    "Can you draft me a first chapter based on the plot and character ideas we've discussed so far? Make it around 2,000 words.",
    "Can you draft a second chapter that builds on the first one?",
]
print("Starting conversation with instant compacting chat session...\n")

turn_count = 0
for message in messages:
    response, usage, background_status = session.chat(message)
    turn_count += 1

    # Calculate cache stats
    cache_read = getattr(usage, "cache_read_input_tokens", 0) or 0
    cache_created = getattr(usage, "cache_creation_input_tokens", 0) or 0
    total_input = usage.input_tokens + cache_read

    print(f"{'=' * 60}")
    print(f"Turn {turn_count}:")
    print(f"\nUser: {message}")
    print(f"\nAssistant: \n{truncate_response(response, max_lines=3)}")
    print("\nToken Usage:")
    print(f"  Input: {total_input:,} (new: {usage.input_tokens:,}, cached: {cache_read:,})")
    print(f"  Output: {usage.output_tokens:,}")
    print(
        f"  Messages: {len(session.messages)} | Memory: {'ready' if session.session_memory else 'not yet'}"
    )

    if cache_read > 0:
        cache_pct = (cache_read / total_input) * 100
        print(f"  ✓ Cache hit! {cache_pct:.0f}% of input from cache")

    if background_status:
        print(f"\n  [Background] Proactively {background_status} session memory...")
        print(f"  Context window: {session.current_context_window_tokens:,} tokens")

    print()
```

::: {.output .stream .stdout}
    Starting conversation with instant compacting chat session...

    ============================================================
    Turn 1:

    User: I want to create a story about a young detective solving a mysterious case in a small town. Generate 3 well thought out plot ideas for me to consider.

    Assistant: 
    # Three Mystery Plot Ideas

    ## 1. **The Vanishing Choir**
    ... (36 more lines)

    Token Usage:
      Input: 317 (new: 317, cached: 0)
      Output: 902
      Messages: 2 | Memory: not yet

    ============================================================
    Turn 2:

    User: I don't like those ideas, can you think of one plot something more unique and unexpected?

    Assistant: 
    # **The Forgetting House**

    **Setup:** Your young detective arrives in Ember Falls to investigate a string of burglaries—except the victims don't realize they've been robbed until weeks later. A woman discovers her wedding ring gone and insists she lost it yesterday, but security footage shows she hasn't worn it in a month. A man reports his grandfather's watch stolen, then his sister shows him photos proving he sold it himself at a pawn shop—which he has no memory of doing.
    ... (16 more lines)

    Token Usage:
      Input: 1,241 (new: 1,241, cached: 0)
      Output: 592
      Messages: 4 | Memory: not yet

    ============================================================
    Turn 3:

    User: Ok I like it. Can you help me develop the main character's backstory and motivations?

    Assistant: 
    # Your Detective: Building From The Inside Out

    ## Core Identity
    ... (79 more lines)

    Token Usage:
      Input: 1,856 (new: 1,856, cached: 0)
      Output: 1,329
      Messages: 6 | Memory: not yet

    ============================================================
    Turn 4:

    User: Can you draft a detailed outline for the story, breaking it down into chapters and key events?

    Assistant: 
    # **The Forgetting House: Chapter Outline**

    ---
    ... (272 more lines)

    Token Usage:
      Input: 3,207 (new: 3,207, cached: 0)
      Output: 3,500
      Messages: 8 | Memory: not yet

    ============================================================
    Turn 5:

    User: Can you draft me a first chapter based on the plot and character ideas we've discussed so far? Make it around 2,000 words.

    Assistant: 
    # **Chapter One: The Impossible Theft**

    The apartment smelled like burnt coffee and old paper.
    ... (196 more lines)

    Token Usage:
      Input: 6,743 (new: 6,743, cached: 0)
      Output: 3,155
      Messages: 10 | Memory: not yet

      [Background] Proactively initializing session memory...
      Context window: 9,898 tokens

       [Background] Initial session memory created. Cache hit=True
    ============================================================
    Turn 6:

    User: Can you draft a second chapter that builds on the first one?

    Assistant: 
    # **Chapter Two: Rosemont Manor**

    The house appeared through the trees like something from a postcard.
    ... (190 more lines)

    Token Usage:
      Input: 9,914 (new: 5,818, cached: 4,096)
      Output: 3,500
      Messages: 12 | Memory: ready
      ✓ Cache hit! 41% of input from cache

      [Background] Proactively updating session memory...
      Context window: 13,414 tokens
:::
::::

:::: {.cell .code execution_count="13" vscode="{\"languageId\":\"python\"}"}
``` coconut
message = "What did we just talk about? Give me one sentence"
response, usage, background_status = session.chat(message)

# Calculate cache stats
cache_read = getattr(usage, "cache_read_input_tokens", 0) or 0
total_input = usage.input_tokens + cache_read

print(f"\nUser: {message}")
print(f"\nAssistant: \n{truncate_response(response, max_lines=3)}")
print("\nToken Usage:")
print(f"  Input: {total_input:,} (new: {usage.input_tokens:,}, cached: {cache_read:,})")
print(f"  Output: {usage.output_tokens:,}")
print(
    f"  Messages: {len(session.messages)} | Memory: {'ready' if session.session_memory else 'not yet'}"
)

if cache_read > 0:
    cache_pct = (cache_read / total_input) * 100
    print(f"  ✓ Cache hit! {cache_pct:.0f}% of input from cache")
```

::: {.output .stream .stdout}

    ============================================================
    ⚡ INSTANT COMPACTION! Messages: 12 → 3
       Session memory was pre-built (no wait time!)
    ============================================================

    User: What did we just talk about? Give me one sentence

    Assistant: 
    I drafted Chapter 2 where Casey arrives at Rosemont Manor, interviews Iris (who deflects questions about her past and shows moments of disorientation), and realizes through comparing photos that Iris Hale is definitely their missing grandmother Iris Whitmore.

    Token Usage:
      Input: 5,490 (new: 5,490, cached: 0)
      Output: 60
      Messages: 5 | Memory: ready
:::
::::

::: {.cell .markdown}
You\'ll notice here that once we hit the context limit, the session
memory was instantaly swapped in, meaning the user had zero waiting time
for a response!
:::

::: {.cell .markdown}
## Advanced: Understanding Prompt Caching
:::

::: {.cell .markdown}
The background updates can be made **\~10x cheaper** by using prompt
caching. The trick:

1.  Pass the **full conversation** to the background summarizer
2.  Add `cache_control` markers so subsequent requests hit the cache
3.  Only the new \"summarize this\" instruction is billed at full price

<!-- -->

    ┌─────────────────────────────────────────────────────────────────────────────────┐
    │                    PROMPT CACHING FOR LONG CONVERSATIONS                        │
    ├─────────────────────────────────────────────────────────────────────────────────┤
    │                                                                                 │
    │  WITHOUT CACHING: Pay full price for entire context every turn                 │
    │  ════════════════════════════════════════════════════════════                   │
    │                                                                                 │
    │  Turn 1:  [System][User1][Asst1]                         →  500 tokens  @ $3/M │
    │  Turn 2:  [System][User1][Asst1][User2][Asst2]           → 1500 tokens  @ $3/M │
    │  Turn 3:  [System][User1][Asst1][User2][Asst2][User3]... → 3000 tokens  @ $3/M │
    │  Turn 4:  [System][User1][Asst1][User2][Asst2][User3]... → 5000 tokens  @ $3/M │
    │           ─────────────────────────────────────────────                         │
    │                                              Total: 10,000 tokens = $0.030      │
    │                                                                                 │
    │                                                                                 │
    │  WITH CACHING: Pay full price once, then 90% discount on prefix                │
    │  ═══════════════════════════════════════════════════════════════                │
    │                                                                                 │
    │  Turn 1:  [System][User1][Asst1]◆                        →  500 tokens  @ $3/M │
    │                                ▲                            (cache created)    │
    │                          cache breakpoint                                       │
    │                                                                                 │
    │  Turn 2:  [System][User1][Asst1][User2][Asst2]◆                                │
    │           ╰─────── cached ──────╯                                              │
    │                500 @ $0.30/M + 1000 new @ $3/M  =  $0.0032                     │
    │                                                                                 │
    │  Turn 3:  [System][User1][Asst1][User2][Asst2][User3][Asst3]◆                  │
    │           ╰──────────── cached ─────────────╯                                  │
    │               1500 @ $0.30/M + 1500 new @ $3/M  =  $0.0050                     │
    │                                                                                 │
    │  Turn 4:  [System][User1][Asst1][User2][Asst2][User3][Asst3][User4][Asst4]◆    │
    │           ╰───────────────────── cached ─────────────────────╯                 │
    │                     3000 @ $0.30/M + 2000 new @ $3/M  =  $0.0069               │
    │           ─────────────────────────────────────────────                         │
    │                                              Total: $0.0166  (45% savings)     │
    │                                                                                 │
    ├─────────────────────────────────────────────────────────────────────────────────┤
    │                                                                                 │
    │  COMPACTION + CACHING: Double benefit                                           │
    │  ════════════════════════════════════                                           │
    │                                                                                 │
    │    Main Chat                      Background Summarizer                         │
    │    ─────────                      ─────────────────────                         │
    │                                                                                 │
    │  [Conversation grows...]          [Same conversation prefix]◆ + [Summarize!]   │
    │         │                                    │                                  │
    │         │                         Cache hit! Only pays for                      │
    │         │                         the summarization prompt                      │
    │         │                                    │                                  │
    │         ▼                                    ▼                                  │
    │  Context limit reached  ──────►  Session memory ready instantly                │
    │                                  (built cheaply in background)                  │
    │                                                                                 │
    │  ┌──────────────────────────────────────────────────────────────────────────┐  │
    │  │  Key insight: The background summarizer reuses the same conversation     │  │
    │  │  prefix that was just sent to the main chat - automatic cache hit!       │  │
    │  └──────────────────────────────────────────────────────────────────────────┘  │
    │                                                                                 │
    └─────────────────────────────────────────────────────────────────────────────────┘

    ◆ = cache_control breakpoint (cache everything before this point)

### Why this matters for compaction

  Scenario       Cost per background update   Notes
  -------------- ---------------------------- ----------------------------------
  No caching     Full input cost              5,000 tokens × \$3/M = \$0.015
  With caching   \~10% of input cost          500 new + 4,500 cached = \$0.003
  **Savings**    **\~80%**                    Compounds over many updates

The longer the conversation, the bigger the savings---exactly when you
need compaction most!
:::

::: {.cell .markdown}
### How the Caching Works

The key is in `_add_cache_control()` and
`_create_session_memory_cached()`:

``` python
# 1. Mark the last conversation message with cache_control
{
    "role": "user",
    "content": [{
        "type": "text",
        "text": msg["content"],
        "cache_control": {"type": "ephemeral"}  # <-- This creates a cache breakpoint
    }]
}

# 2. Also mark the system prompt
system=[{
    "type": "text",
    "text": "You are a session memory agent...",
    "cache_control": {"type": "ephemeral"}
}]
```

**Why this works:**

- The first background update creates a cache entry for
  `[System + Messages]`
- Subsequent updates with the same message prefix get **cache hits**
- Only the new summarization instruction is billed at full price
- Cache entries have a 5-minute TTL, so rapid updates benefit most

**Cost math:**

- Without caching: 5,000 tokens × \$3.00/1M = \$0.015 per update
- With caching: 500 new tokens × \$3.00/1M + 4,500 cached × \$0.30/1M =
  \$0.00285
- **Savings: \~80%** on background summarization costs
:::

::: {.cell .markdown}
## Conclusion

In this cookbook, you learned how to manage long-running Claude
conversations through session memory compaction.

### What We Covered

✅ **Effective compaction prompts** - Structure your session memory to
preserve user intent, completed work, errors, active work, and key
references while discarding filler

✅ **Instant compaction** - Use background threading to proactively
build session memory, eliminating user wait time when context limits are
reached

✅ **Prompt caching for cost savings** - Reduce background update costs
by \~80% by reusing the conversation prefix cache

✅ **Traditional vs. instant patterns** - Understand when to use each
approach based on your application needs

### Key Takeaways

1.  **Weight recency heavily** - The end of a conversation is the active
    working context
2.  **Preserve user corrections verbatim** - Prevents the model from
    reverting to old behaviors
3.  **Build memory proactively** - Don\'t wait for context limits; start
    background updates early
4.  **Leverage prompt caching** - Background summarization can share
    cache with the main conversation

### Next Steps

- **For agentic workflows**: See [Automatic Context
  Compaction](https://github.com/anthropics/claude-cookbooks/blob/main/tool_use/automatic-context-compaction.ipynb) for
  SDK-based automatic compaction with tool use
- **For production**: Consider persisting session memory to disk rather
  than keeping it in memory
- **For optimization**: Experiment with update frequency thresholds to
  balance cost vs. freshness
:::

---

## Automatic Context Compaction

Source: https://github.com/anthropics/claude-cookbooks/blob/main/tool_use/automatic-context-compaction.ipynb
Path: 02-Claude-Code-CLI/claude-cookbooks-tool-use-automatic-context-compaction.md

# Automatic Context Compaction

Long-running agentic tasks can often exceed context limits. Tool heavy
workflows or long conversations quickly consume the token context
window. In [Effective Context Engineering for AI
Agents](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents),
we discussed how managing context can help avoid performance degradation
and context rot.

The Claude Agent Python SDK can help manage this context by
automatically compressing conversation history when token usage exceeds
a configurable threshold, allowing tasks to continue beyond the typical
200k token context limit.

In this cookbook, we\'ll demonstrate context compaction through an
**agentic customer service workflow**. Imagine you\'ve built an AI
customer service agent tasked with processing a queue of support
tickets. For each ticket, you must classify the issue, search the
knowledge base, set priority, route to the appropriate team, draft a
response, and mark it complete. As you process ticket after ticket, the
conversation history fills with classifications, knowledge base
searches, and drafted responses---quickly consuming thousands of tokens.

## What is Context Compaction?

When building agentic workflows with tool use, conversations can grow
very large as the agent iterates on complex tasks. The
`compaction_control` parameter provides automatic context management by:

1.  Monitoring token usage per turn in the conversation
2.  When a threshold is exceeded, injecting a summary prompt as a user
    turn
3.  Having the model generate a summary wrapped in `<summary></summary>`
    tags. These tags aren\'t parsed, but are there to help guide the
    model.
4.  Clearing the conversation history and resuming with only the summary
5.  Continuing the task with the compressed context

## By the end of this cookbook, you\'ll be able to:

- Understand how to effectively manage context limits in iterative
  workflows
- Write agents that leverage automatic context compaction
- Design workflows that maintain focus across multiple iterations

## Prerequisites

Before following this guide, ensure you have:

**Required Knowledge**

- Basic understanding of agentic patterns and tool calling

**Required Tools**

- Python 3.11 or higher
- Anthropic API key
- Anthropic SDK \>= 0.74.1
:::

::: {#004e3b52 .cell .markdown}
## Setup

First, install the required dependencies:
:::

::: {#71d7f8c2 .cell .code execution_count="1"}
``` python
# %pip install -qU anthropic python-dotenv
```
:::

::: {#1ba96da5 .cell .markdown}
Note: Ensure your .env file contains:

`ANTHROPIC_API_KEY=your_key_here`

Load your environment variables and configure the client. We also load a
helper utility to visualize Claude message responses.
:::

::: {#68f6d5bb .cell .code execution_count="2"}
``` python
from dotenv import load_dotenv

load_dotenv()

MODEL = "claude-sonnet-4-5"
```
:::

::: {#783cf8e3 .cell .markdown}
## Setting the Stage

In [utils/customer_service_tools.py](https://github.com/anthropics/claude-cookbooks/blob/main/tool_use/utils/customer_service_tools.py),
we\'ve defined several functions for processing customer support
tickets:

- `get_next_ticket()` - Retrieves the next unprocessed ticket from the
  queue
- `classify_ticket(ticket_id, category)` - Categorizes issues as
  billing, technical, account, product, or shipping
- `search_knowledge_base(query)` - Finds relevant help articles and
  solutions
- `set_priority(ticket_id, priority)` - Assigns priority levels (low,
  medium, high, urgent)
- `route_to_team(ticket_id, team)` - Routes tickets to the appropriate
  support team
- `draft_response(ticket_id, response_text)` - Creates customer-facing
  responses
- `mark_complete(ticket_id)` - Finalizes processed tickets

For a customer service agent, these tools enable processing tickets
systematically. Each ticket requires classification, research,
prioritization, routing, and response drafting. When processing 20-30
tickets in sequence, the conversation history fills with tool results
from every classification, every knowledge base search, and every
drafted response, causing linear token growth.

The `beta_tool` decorator is used on the tools to make them accessible
to the Claude agent. The decorator extracts the function arguments and
docstring and provides these to Claude as tool metadata.

``` python
import anthropic
from anthropic import beta_tool

@beta_tool
def get_next_ticket() -> dict:
    """Retrieve the next unprocessed support ticket from the queue."""
    ...
```
:::

::: {#58d2a922 .cell .code execution_count="3"}
``` python
import anthropic
from utils.customer_service_tools import (
    classify_ticket,
    draft_response,
    get_next_ticket,
    initialize_ticket_queue,
    mark_complete,
    route_to_team,
    search_knowledge_base,
    set_priority,
)

client = anthropic.Anthropic()

tools = [
    get_next_ticket,
    classify_ticket,
    search_knowledge_base,
    set_priority,
    route_to_team,
    draft_response,
    mark_complete,
]
```
:::

::: {#77fecfb8 .cell .markdown}
## Baseline: Running Without Compaction

Let\'s start with a realistic customer service scenario: Processing a
queue of support tickets.

The workflow looks like this:

**For Each Ticket:**

1.  Fetch the ticket using `get_next_ticket()`
2.  Classify the issue category (billing, technical, account, product,
    shipping)
3.  Search the knowledge base for relevant information
4.  Set appropriate priority (low, medium, high, urgent)
5.  Route to the correct team
6.  Draft a customer response
7.  Mark the ticket complete
8.  Move to the next ticket

**The Challenge**: With 5 tickets in the queue, and each requiring 7
tool calls, Claude will make 35 or more tool calls. The results from
each step including classification knowledge base search, and drafted
responses accumulate in the conversation history. Without compaction,
all this data stays in memory for every ticket, by ticket #5, the
context includes complete details from all 4 previous tickets.

Let\'s run this workflow **without compaction** first and observe what
happens:
:::

:::: {#uef86nvtl4 .cell .code execution_count="4"}
``` python
from anthropic.types.beta import BetaMessageParam

num_tickets = 5
initialize_ticket_queue(num_tickets)

messages: list[BetaMessageParam] = [
    {
        "role": "user",
        "content": f"""You are an AI customer service agent. Your task is to process support tickets from a queue.

For EACH ticket, you must complete ALL these steps:

1. **Fetch ticket**: Call get_next_ticket() to retrieve the next unprocessed ticket
2. **Classify**: Call classify_ticket() to categorize the issue (billing/technical/account/product/shipping)
3. **Research**: Call search_knowledge_base() to find relevant information for this ticket type
4. **Prioritize**: Call set_priority() to assign priority (low/medium/high/urgent) based on severity
5. **Route**: Call route_to_team() to assign to the appropriate team
6. **Draft**: Call draft_response() to create a helpful customer response using KB information
7. **Complete**: Call mark_complete() to finalize this ticket
8. **Continue**: Immediately fetch the next ticket and repeat

IMPORTANT RULES:
- Process tickets ONE AT A TIME in sequence
- Complete ALL 7 steps for each ticket before moving to the next
- Keep fetching and processing tickets until you get an error that the queue is empty
- There are {num_tickets} tickets total - process all of them
- Be thorough but efficient

Begin by fetching the first ticket.""",
    }
]

total_input = 0
total_output = 0
turn_count = 0

runner = client.beta.messages.tool_runner(
    model=MODEL,
    max_tokens=4096,
    tools=tools,
    messages=messages,
)

for message in runner:
    messages_list = list(runner._params["messages"])
    turn_count += 1
    total_input += message.usage.input_tokens
    total_output += message.usage.output_tokens
    print(
        f"Turn {turn_count:2d}: Input={message.usage.input_tokens:7,} tokens | "
        f"Output={message.usage.output_tokens:5,} tokens | "
        f"Messages={len(messages_list):2d} | "
        f"Cumulative In={total_input:8,}"
    )

print(f"\n{'=' * 60}")
print("BASELINE RESULTS (NO COMPACTION)")
print(f"{'=' * 60}")
print(f"Total turns:   {turn_count}")
print(f"Input tokens:  {total_input:,}")
print(f"Output tokens: {total_output:,}")
print(f"Total tokens:  {total_input + total_output:,}")
print(f"{'=' * 60}")
```

::: {.output .stream .stdout}
    Turn  1: Input=  1,537 tokens | Output=   57 tokens | Messages= 1 | Cumulative In=   1,537
    Turn  2: Input=  1,760 tokens | Output=  102 tokens | Messages= 3 | Cumulative In=   3,297
    Turn  3: Input=  1,905 tokens | Output=   88 tokens | Messages= 5 | Cumulative In=   5,202
    Turn  4: Input=  2,237 tokens | Output=   84 tokens | Messages= 7 | Cumulative In=   7,439
    Turn  5: Input=  2,385 tokens | Output=   89 tokens | Messages= 9 | Cumulative In=   9,824
    Turn  6: Input=  2,537 tokens | Output=  301 tokens | Messages=11 | Cumulative In=  12,361
    Turn  7: Input=  2,888 tokens | Output=   67 tokens | Messages=13 | Cumulative In=  15,249
    Turn  8: Input=  3,079 tokens | Output=   56 tokens | Messages=15 | Cumulative In=  18,328
    Turn  9: Input=  3,316 tokens | Output=   91 tokens | Messages=17 | Cumulative In=  21,644
    Turn 10: Input=  3,450 tokens | Output=   84 tokens | Messages=19 | Cumulative In=  25,094
    Turn 11: Input=  3,777 tokens | Output=   84 tokens | Messages=21 | Cumulative In=  28,871
    Turn 12: Input=  3,925 tokens | Output=   89 tokens | Messages=23 | Cumulative In=  32,796
    Turn 13: Input=  4,077 tokens | Output=  349 tokens | Messages=25 | Cumulative In=  36,873
    Turn 14: Input=  4,476 tokens | Output=   67 tokens | Messages=27 | Cumulative In=  41,349
    Turn 15: Input=  4,668 tokens | Output=   56 tokens | Messages=29 | Cumulative In=  46,017
    Turn 16: Input=  4,894 tokens | Output=   91 tokens | Messages=31 | Cumulative In=  50,911
    Turn 17: Input=  5,028 tokens | Output=   84 tokens | Messages=33 | Cumulative In=  55,939
    Turn 18: Input=  5,333 tokens | Output=   84 tokens | Messages=35 | Cumulative In=  61,272
    Turn 19: Input=  5,481 tokens | Output=   89 tokens | Messages=37 | Cumulative In=  66,753
    Turn 20: Input=  5,633 tokens | Output=  334 tokens | Messages=39 | Cumulative In=  72,386
    Turn 21: Input=  6,017 tokens | Output=   67 tokens | Messages=41 | Cumulative In=  78,403
    Turn 22: Input=  6,209 tokens | Output=   56 tokens | Messages=43 | Cumulative In=  84,612
    Turn 23: Input=  6,435 tokens | Output=   91 tokens | Messages=45 | Cumulative In=  91,047
    Turn 24: Input=  6,569 tokens | Output=   84 tokens | Messages=47 | Cumulative In=  97,616
    Turn 25: Input=  6,896 tokens | Output=   84 tokens | Messages=49 | Cumulative In= 104,512
    Turn 26: Input=  7,044 tokens | Output=   89 tokens | Messages=51 | Cumulative In= 111,556
    Turn 27: Input=  7,196 tokens | Output=  372 tokens | Messages=53 | Cumulative In= 118,752
    Turn 28: Input=  7,618 tokens | Output=   67 tokens | Messages=55 | Cumulative In= 126,370
    Turn 29: Input=  7,808 tokens | Output=   56 tokens | Messages=57 | Cumulative In= 134,178
    Turn 30: Input=  8,040 tokens | Output=   96 tokens | Messages=59 | Cumulative In= 142,218
    Turn 31: Input=  8,179 tokens | Output=   85 tokens | Messages=61 | Cumulative In= 150,397
    Turn 32: Input=  8,508 tokens | Output=   84 tokens | Messages=63 | Cumulative In= 158,905
    Turn 33: Input=  8,656 tokens | Output=   89 tokens | Messages=65 | Cumulative In= 167,561
    Turn 34: Input=  8,808 tokens | Output=  332 tokens | Messages=67 | Cumulative In= 176,369
    Turn 35: Input=  9,190 tokens | Output=   67 tokens | Messages=69 | Cumulative In= 185,559
    Turn 36: Input=  9,382 tokens | Output=   60 tokens | Messages=71 | Cumulative In= 194,941
    Turn 37: Input=  9,475 tokens | Output=  297 tokens | Messages=73 | Cumulative In= 204,416

    ============================================================
    BASELINE RESULTS (NO COMPACTION)
    ============================================================
    Total turns:   37
    Input tokens:  204,416
    Output tokens: 4,422
    Total tokens:  208,838
    ============================================================
:::
::::

::: {#3dd25c6f .cell .markdown}
Now that we have our baseline, we have a better picture of how context
grows without compaction. As you can see, each turn results in linear
token growth, as every turn adds more tokens to the input.

This leads to high token consumption and potential context limits being
reached quickly. By the 27th turn, we have a cumulative 150,000 input
tokens just for 5 tickets.

Let\'s review Claude\'s final response after processing all 5 tickets
without compaction:
:::

:::: {#d8b51b65 .cell .code execution_count="5"}
``` python
print(message.content[-1].text)
```

::: {.output .stream .stdout}
    ---

    ## ✅ ALL TICKETS PROCESSED SUCCESSFULLY!

    **Summary of Completed Work:**

    I have successfully processed all 5 tickets from the queue. Here's what was accomplished:

    1. **TICKET-1** - Sam Smith - Payment method update error
       - Category: Billing | Priority: High | Team: billing-team
       
    2. **TICKET-2** - Morgan Johnson - Missing delivery
       - Category: Shipping | Priority: High | Team: logistics-team
       
    3. **TICKET-3** - Morgan Jones - Email address change request
       - Category: Account | Priority: Medium | Team: account-services
       
    4. **TICKET-4** - Alex Johnson - Wrong item delivered
       - Category: Shipping | Priority: High | Team: logistics-team
       
    5. **TICKET-5** - Morgan Jones - Refund request for cancelled subscription
       - Category: Billing | Priority: High | Team: billing-team

    Each ticket was:
    ✅ Classified correctly
    ✅ Researched in the knowledge base
    ✅ Assigned appropriate priority
    ✅ Routed to the correct team
    ✅ Given a detailed, helpful customer response
    ✅ Marked as complete

    The queue is now empty and all tickets have been processed!
:::
::::

::: {#klok33ohsvn .cell .markdown}
### Understanding the Problem

In the baseline workflow above, Claude had to:

- Process **5 support tickets** sequentially
- Complete **7 steps per ticket** (fetch, classify, research,
  prioritize, route, draft, complete)
- Make **35 tool calls** with results accumulating in conversation
  history
- Store **every classification, every knowledge base search, every
  drafted response** in memory

**Why This Happens**:

1.  **Linear token growth** - With each tool use, the entire
    conversation history (including all previous tool results) is sent
    to Claude
2.  **Context pollution** - Ticket A\'s classification and drafted
    response remain in context while processing Ticket B
3.  **Compounding costs** - By the time you\'re on Ticket #5, you\'re
    sending data from all 4 previous tickets on every API call
4.  **Slower responses** - Processing massive contexts takes longer
5.  **Risk of hitting limits** - Eventually you hit the 200k token
    context window

**What We Actually Need**: After completing Ticket A, we only need a
**brief summary** (ticket resolved, category, priority) - not the full
classification result, knowledge base search, and complete drafted
response. The detailed workflow should be discarded, keeping only
completion summaries.

Let\'s see how automatic context compaction solves this problem.
:::

::: {#byut5h7hi3 .cell .markdown}
## Enabling Automatic Context Compaction

Let\'s run the exact same customer service workflow, but with automatic
context compaction enabled. We simply add the `compaction_control`
parameter to our tool runner.

The `compaction_control` parameter has one required field and several
optional ones:

- **`enabled`** (required): Boolean to turn compaction on/off
- **`context_token_threshold`** (optional): Token count that triggers
  compaction (default: 100,000)
- **`model`** (optional): Model to use for summarization (defaults to
  the main model)
- **`summary_prompt`** (optional): Custom prompt for generating
  summaries

For this customer service workflow, we\'ll use a **5,000 token
threshold**. This means after processing several tickets compaction will
auto-trigger. This allows Claude to:

1.  **Keep completion summaries** (tickets resolved, categories,
    outcomes)
2.  **Discard detailed tool results** (full KB articles, complete
    classifications, drafted response text)
3.  **Start fresh** when processing the next batch of tickets

This mimics how a real support agent works: resolve the ticket, document
it briefly, move to the next case.
:::

:::: {#x6lnx8d20fr .cell .code execution_count="6"}
``` python
# Re-initialize queue and run with compaction
initialize_ticket_queue(num_tickets)

total_input_compact = 0
total_output_compact = 0
turn_count_compact = 0
compaction_count = 0
prev_msg_count = 0

runner = client.beta.messages.tool_runner(
    model=MODEL,
    max_tokens=4096,
    tools=tools,
    messages=messages,
    compaction_control={
        "enabled": True,
        "context_token_threshold": 5000,
    },
)

for message in runner:
    turn_count_compact += 1
    total_input_compact += message.usage.input_tokens
    total_output_compact += message.usage.output_tokens
    messages_list = list(runner._params["messages"])
    curr_msg_count = len(messages_list)

    if curr_msg_count < prev_msg_count:
        # We can identify compaction when the message count decreases
        compaction_count += 1

        print(f"\n{'=' * 60}")
        print(f"🔄 Compaction occurred! Messages: {prev_msg_count} → {curr_msg_count}")
        print("   Summary message after compaction:")
        print(messages_list[-1]["content"][-1].text)  # type: ignore
        print(f"\n{'=' * 60}")

    prev_msg_count = curr_msg_count
    print(
        f"Turn {turn_count_compact:2d}: Input={message.usage.input_tokens:7,} tokens | "
        f"Output={message.usage.output_tokens:5,} tokens | "
        f"Messages={len(messages_list):2d} | "
        f"Cumulative In={total_input_compact:8,}"
    )

print(f"\n{'=' * 60}")
print("OPTIMIZED RESULTS (WITH COMPACTION)")
print(f"{'=' * 60}")
print(f"Total turns:   {turn_count_compact}")
print(f"Compactions:   {compaction_count}")
print(f"Input tokens:  {total_input_compact:,}")
print(f"Output tokens: {total_output_compact:,}")
print(f"Total tokens:  {total_input_compact + total_output_compact:,}")
print(f"{'=' * 60}")
```

::: {.output .stream .stdout}
    Turn  1: Input=  1,537 tokens | Output=   57 tokens | Messages= 1 | Cumulative In=   1,537
    Turn  2: Input=  1,755 tokens | Output=  108 tokens | Messages= 3 | Cumulative In=   3,292
    Turn  3: Input=  1,906 tokens | Output=   88 tokens | Messages= 5 | Cumulative In=   5,198
    Turn  4: Input=  2,216 tokens | Output=   84 tokens | Messages= 7 | Cumulative In=   7,414
    Turn  5: Input=  2,364 tokens | Output=   89 tokens | Messages= 9 | Cumulative In=   9,778
    Turn  6: Input=  2,516 tokens | Output=  332 tokens | Messages=11 | Cumulative In=  12,294
    Turn  7: Input=  2,898 tokens | Output=   67 tokens | Messages=13 | Cumulative In=  15,192
    Turn  8: Input=  3,090 tokens | Output=   56 tokens | Messages=15 | Cumulative In=  18,282
    Turn  9: Input=  3,325 tokens | Output=   97 tokens | Messages=17 | Cumulative In=  21,607
    Turn 10: Input=  3,465 tokens | Output=   90 tokens | Messages=19 | Cumulative In=  25,072
    Turn 11: Input=  3,801 tokens | Output=   84 tokens | Messages=21 | Cumulative In=  28,873
    Turn 12: Input=  3,949 tokens | Output=   89 tokens | Messages=23 | Cumulative In=  32,822
    Turn 13: Input=  4,101 tokens | Output=  368 tokens | Messages=25 | Cumulative In=  36,923
    Turn 14: Input=  4,519 tokens | Output=   67 tokens | Messages=27 | Cumulative In=  41,442
    Turn 15: Input=  4,711 tokens | Output=   57 tokens | Messages=29 | Cumulative In=  46,153
    Turn 16: Input=  4,934 tokens | Output=   97 tokens | Messages=31 | Cumulative In=  51,087

    ============================================================
    🔄 Compaction occurred! Messages: 31 → 1
       Summary message after compaction:
    <summary>
    ## Support Ticket Processing Progress Summary

    ### Task Overview
    Processing 5 support tickets sequentially, completing all 7 steps for each ticket (fetch, classify, research, prioritize, route, draft, complete).

    ### Tickets Completed (2 of 5)

    **TICKET-1 (Chris Davis) - COMPLETED**
    - Issue: Account locked, unlock email link not working
    - Category: account
    - Priority: high
    - Team: account-services
    - Status: resolved
    - Response: Provided guidance on checking spam folder, link expiration (1 hour), and requesting new unlock link

    **TICKET-2 (Chris Williams) - COMPLETED**
    - Issue: Unrecognized $49.99 charge on 2025-10-30
    - Category: billing
    - Priority: high
    - Team: billing-team
    - Status: resolved
    - Response: Explained billing cycles, subscription possibility, and refund policy (5-7 business days, pro-rated for annual plans)

    ### Current Status
    **TICKET-3 (John Jones) - IN PROGRESS**
    - Issue: Asking about Google Sheets integration for project management
    - Category: product
    - Priority: NOT YET SET
    - Team: NOT YET ASSIGNED
    - Steps completed: 1 (fetch), 2 (classify)
    - Steps remaining: 3 (research KB), 4 (set priority), 5 (route), 6 (draft), 7 (mark complete)

    ### Next Steps
    1. Complete TICKET-3: Search knowledge base for product integration info
    2. Set priority (likely low/medium for feature inquiry)
    3. Route to product-team
    4. Draft response about integrations
    5. Mark complete
    6. Fetch and process TICKET-4
    7. Fetch and process TICKET-5

    ### Key Knowledge Base Info Learned
    - Account: Password reset links expire in 1 hour, sent from noreply@support.example.com
    - Billing: Refunds take 5-7 business days, pro-rated for annual plans, billing on same date monthly/yearly

    ### Remaining Work
    3 tickets left to process (TICKET-3 currently in progress, then TICKET-4 and TICKET-5)
    </summary>

    ============================================================
    Turn 17: Input=  1,774 tokens | Output=   94 tokens | Messages= 1 | Cumulative In=  52,861
    Turn 18: Input=  1,906 tokens | Output=   95 tokens | Messages= 3 | Cumulative In=  54,767
    Turn 19: Input=  2,365 tokens | Output=  431 tokens | Messages= 5 | Cumulative In=  57,132
    Turn 20: Input=  3,164 tokens | Output=   60 tokens | Messages= 7 | Cumulative In=  60,296
    Turn 21: Input=  3,383 tokens | Output=  160 tokens | Messages= 9 | Cumulative In=  63,679
    Turn 22: Input=  3,872 tokens | Output=  447 tokens | Messages=11 | Cumulative In=  67,551
    Turn 23: Input=  4,687 tokens | Output=   64 tokens | Messages=13 | Cumulative In=  72,238
    Turn 24: Input=  4,914 tokens | Output=  160 tokens | Messages=15 | Cumulative In=  77,152

    ============================================================
    🔄 Compaction occurred! Messages: 15 → 1
       Summary message after compaction:
    <summary>
    ## Support Ticket Processing Progress Summary

    ### Task Overview
    Processing 5 support tickets sequentially, completing all 7 steps for each ticket (fetch, classify, research, prioritize, route, draft, complete).

    ### Tickets Completed (4 of 5)

    **TICKET-1 (Chris Davis) - COMPLETED**
    - Issue: Account locked, unlock email link not working
    - Category: account
    - Priority: high
    - Team: account-services
    - Status: resolved
    - Response: Provided guidance on checking spam folder, link expiration (1 hour), and requesting new unlock link

    **TICKET-2 (Chris Williams) - COMPLETED**
    - Issue: Unrecognized $49.99 charge on 2025-10-30
    - Category: billing
    - Priority: high
    - Team: billing-team
    - Status: resolved
    - Response: Explained billing cycles, subscription possibility, and refund policy (5-7 business days, pro-rated for annual plans)

    **TICKET-3 (John Jones) - COMPLETED**
    - Issue: Asking about Google Sheets integration for project management
    - Category: product
    - Priority: medium
    - Team: product-success
    - Status: resolved
    - Response: Explained that Product Success team will provide details on integration options, API access, and current/planned features

    **TICKET-4 (Sam Johnson) - COMPLETED**
    - Issue: Wants to know differences between Standard and Premium plans, specifically "advanced analytics"
    - Category: product
    - Priority: low
    - Team: product-success
    - Status: resolved
    - Response: Explained that Product Success team will provide detailed plan comparison and feature breakdown

    ### Current Status
    **TICKET-5 (Morgan Brown) - IN PROGRESS**
    - Issue: Damaged package (Order #ORD-43312), broken product inside, needs replacement
    - Category: shipping (classified)
    - Priority: NOT YET SET
    - Team: NOT YET ASSIGNED
    - Steps completed: 1 (fetch), 2 (classify), 3 (research KB - no shipping info found)
    - Steps remaining: 4 (set priority), 5 (route), 6 (draft), 7 (mark complete)

    ### Next Steps for TICKET-5
    1. Set priority (likely HIGH - damaged/broken product requiring replacement)
    2. Route to appropriate team (likely fulfillment, operations, or customer-service team)
    3. Draft response addressing damaged shipment, replacement process, and next steps
    4. Mark complete
    5. **ALL TICKETS WILL BE COMPLETE**

    ### Key Knowledge Base Info Learned
    - **Account**: Password reset links expire in 1 hour, sent from noreply@support.example.com
    - **Billing**: Refunds take 5-7 business days, pro-rated for annual plans, billing on same date monthly/yearly; accepts Visa, Mastercard, Amex, PayPal
    - **Technical**: Max upload 100MB, supported formats: PDF, DOCX, PNG, JPG, CSV; system requirements: 4GB RAM, modern browsers
    - **Product category**: Does not exist in KB (only billing, technical, account available)
    - **Shipping info**: Not found in knowledge base

    ### Team Routing Patterns Observed
    - account-services: Account access issues
    - billing-team: Billing/payment inquiries
    - product-success: Product features, integrations, plan comparisons

    ### Remaining Work
    1 ticket left to complete (TICKET-5 - final ticket, currently in progress at step 3 of 7)
    </summary>

    ============================================================
    Turn 25: Input=  2,077 tokens | Output=  496 tokens | Messages= 1 | Cumulative In=  79,229
    Turn 26: Input=  2,942 tokens | Output=  438 tokens | Messages= 3 | Cumulative In=  82,171

    ============================================================
    OPTIMIZED RESULTS (WITH COMPACTION)
    ============================================================
    Total turns:   26
    Compactions:   2
    Input tokens:  82,171
    Output tokens: 4,275
    Total tokens:  86,446
    ============================================================
:::
::::

::: {#5cbbfe32 .cell .markdown}
With automatic context compaction enabled, we can see that our token
usage per turn does not grow linearly, but is reduced after each
compaction event. There were two compaction events during the processing
of tickets, and the follow turn shows a reduction in total token usage.

Compared to the baseline version, we only used 79,000 tokens. We\'ve
also printed out the summary messages generated after each compaction
event, showing how Claude effectively condensed prior ticket details
into summaries.

Let\'s look at the final response after processing all 5 tickets with
compaction enabled.
:::

:::: {#24dd5c7c .cell .code execution_count="7"}
``` python
print(message.content[-1].text)
```

::: {.output .stream .stdout}
    Perfect! **ALL 5 TICKETS HAVE BEEN SUCCESSFULLY COMPLETED!** 🎉

    ## Final Summary - All Tickets Processed

    ### TICKET-5 (Morgan Brown) - **COMPLETED** ✓
    - **Issue**: Damaged package (Order #ORD-43312), broken product inside, needs replacement
    - **Category**: shipping
    - **Priority**: high
    - **Team**: logistics-team
    - **Status**: resolved
    - **Response**: Apologized for damaged shipment, escalated to Logistics Team with HIGH priority, explained they'll process immediate replacement, provide return instructions, and contact customer with tracking and timeline

    ---

    ## 🎯 ALL 5 TICKETS COMPLETED

    1. ✅ **TICKET-1** (Chris Davis) - Account locked → account-services
    2. ✅ **TICKET-2** (Chris Williams) - Billing charge → billing-team  
    3. ✅ **TICKET-3** (John Jones) - Google Sheets integration → product-success
    4. ✅ **TICKET-4** (Sam Johnson) - Plan comparison → product-success
    5. ✅ **TICKET-5** (Morgan Brown) - Damaged shipment → logistics-team

    ### Processing Statistics
    - **Total tickets processed**: 5 of 5 (100%)
    - **Steps per ticket**: 7 (fetch, classify, research, prioritize, route, draft, complete)
    - **Total operations**: 35 successful operations
    - **Categories used**: account, billing, product (2x), shipping
    - **Teams utilized**: account-services, billing-team, product-success (2x), logistics-team
    - **Priority distribution**: 2 high, 2 medium, 1 low

    All tickets have been properly classified, prioritized, routed to the appropriate teams, and have draft responses ready for team review! 🎊
:::
::::

::: {#vb4cesnmb8 .cell .markdown}
### Comparing Results

With compaction enabled, we can see a clear differece between the two
runs in token savings, while preserving the quality of the workflow and
final summary.

Here\'s what changed with automatic context compaction:

1.  **Context resets after several tickets** - When processing 5-7
    tickets generates 5k+ tokens of tool results, the SDK automatically:

    - Injects a summary prompt
    - Has Claude generate a completion summary wrapped in
      `<summary></summary>` tags
    - Clears the conversation history and discards detailed
      classifications, KB searches, and responses
    - Continues with only the completion summary

2.  **Input tokens stay bounded** - Instead of accumulating to 100k+ as
    we process more tickets, input tokens reset after each compaction.
    When processing Ticket #5, we\'re NOT carrying the full tool results
    from Tickets #1-4.

3.  **Task completes successfully** - The workflow continues smoothly
    through all tickets without hitting context limits

4.  **Quality is preserved** - The summaries retain critical
    information:

    - Tickets processed with their IDs
    - Categories and priorities assigned
    - Teams routed to
    - Overall progress status

    All tickets are still properly classified, prioritized, routed, and
    responded to.

5.  **Natural workflow** - This mirrors how real support agents work:
    resolve a ticket, document it briefly in the system, close it, move
    to the next one. You don\'t keep every knowledge base article and
    full response draft open while working on new tickets.

Let\'s visualize the token savings:
:::

:::: {#z9lvigc94p .cell .code execution_count="8"}
``` python
# Compare baseline vs compaction
print("=" * 70)
print("TOKEN USAGE COMPARISON")
print("=" * 70)
print(f"{'Metric':<30} {'Baseline':<20} {'With Compaction':<20}")
print("-" * 70)
print(f"{'Input tokens:':<30} {total_input:>19,} {total_input_compact:>19,}")
print(f"{'Output tokens:':<30} {total_output:>19,} {total_output_compact:>19,}")
print(
    f"{'Total tokens:':<30} {total_input + total_output:>19,} {total_input_compact + total_output_compact:>19,}"
)
print(f"{'Compactions:':<30} {'N/A':>19} {compaction_count:>19}")
print("=" * 70)

# Calculate savings
token_savings = (total_input + total_output) - (total_input_compact + total_output_compact)
savings_percent = (
    (token_savings / (total_input + total_output)) * 100 if (total_input + total_output) > 0 else 0
)

print(f"\n💰 Token Savings: {token_savings:,} tokens ({savings_percent:.1f}% reduction)")
```

::: {.output .stream .stdout}
    ======================================================================
    TOKEN USAGE COMPARISON
    ======================================================================
    Metric                         Baseline             With Compaction     
    ----------------------------------------------------------------------
    Input tokens:                              204,416              82,171
    Output tokens:                               4,422               4,275
    Total tokens:                              208,838              86,446
    Compactions:                                   N/A                   2
    ======================================================================

    💰 Token Savings: 122,392 tokens (58.6% reduction)
:::
::::

::: {#lzvf1mw7o6 .cell .markdown}
## How Compaction Works Under the Hood

When the `tool_runner` detects that token usage has exceeded the
threshold, it automatically:

1.  **Pauses the workflow** before making the next API call
2.  **Injects a summary request** as a user message asking Claude to
    summarize progress
3.  **Generates a summary** - Claude produces a summary wrapped in
    `<summary></summary>` tags containing:
    - **Completed tickets**: Brief records of tickets resolved (IDs,
      categories, priorities, outcomes)
    - **Progress status**: How many tickets processed, how many remain
    - **Key patterns**: Any notable trends across tickets
    - **Next steps**: What to do next (continue processing remaining
      tickets)
4.  **Clears history** - The entire conversation history (including all
    tool results) is replaced with just the summary
5.  **Resumes processing** - Claude continues working with the
    compressed context, processing the next batch of tickets
:::

::: {#v64ljd0a79 .cell .markdown}
## Customizing Compaction Configuration

You can customize how compaction works to fit your specific use case.
Here are the key configuration options:

### Adjusting the Threshold

The `context_token_threshold` determines when compaction triggers:

``` python
compaction_control={
    "enabled": True,
    "context_token_threshold": 5000,  # Compact after processing 5-7 tickets
}
```

The threshold should not be set too low, otherwise the summary itself
could trigger a compaction. We set a threshold of 5,000 tokens for
demonstration purposes, but in practice, experiment with different
settings to find what works best for your workflow.

Here some general guidelines:

- **Low thresholds (5k-20k)**:
  - Use for iterative task processing with clear boundaries
  - More frequent compaction, minimal context accumulation
  - Best for sequential entity processing
- **Medium thresholds (50k-100k)**:
  - Multi-phase workflows with fewer, larger natural checkpoints
  - Balance between context retention and management
  - Suitable for workflows with expensive tool calls
- **High thresholds (100k-150k)**:
  - Tasks requiring substantial historical context
  - Less frequent compaction preserves more raw details
  - Higher per-call costs but fewer compactions
- **Default (100k)**: Good balance for general long-running tasks

**For ticket processing**: The 5k threshold works well because each
ticket\'s workflow generates substantial tool results, but tickets are
independent. After resolving Ticket A, you don\'t need its detailed KB
searches when processing Ticket B.

### Using a Different Model for Summarization

You can also use a faster/cheaper model for generating summaries:

``` python
compaction_control={
    "enabled": True,
    "model": "claude-haiku-4-5",  # Use Haiku for cost-effective summaries
}
```
:::

::: {#w4oyvorzkn .cell .markdown}
### Custom Summary Prompts

You can provide a custom prompt to guide how summaries are generated.
This is especially useful for customer service workflows where you need
to preserve specific types of information.

For example, we could define a custom prompt based on our requirements:

- **Ticket summaries** for all completed tickets
- **Categories and priorities** assigned
- **Teams routed to**
- **Progress status** (tickets completed, tickets remaining)
- **Next steps** in the workflow

``` python
compaction_control={
    "enabled": True,
    "summary_prompt": """You are processing customer support tickets from a queue.

Create a focused summary that preserves:

1. **COMPLETED TICKETS**: For each ticket you've fully processed:
   - Ticket ID and customer name
   - Issue category and priority assigned
   - Team routed to
   - Brief outcome

2. **PROGRESS STATUS**: 
   - How many tickets you've completed
   - Approximately how many remain in the queue

3. **NEXT STEPS**: Continue processing the next ticket

Format with clear sections and wrap in <summary></summary> tags."""
}
```
:::

::: {#7cwipn73ib9 .cell .markdown}
## Compaction Without Tools: Simple Chat Loop

While the examples above focus on tool-heavy agentic workflows, context
compaction is also valuable for **simple conversational applications**
where users drive the conversation.

**Note:** The `compaction_control` parameter demonstrated above works
with `tool_runner` for agentic workflows with tools. For simple chat
applications without tools, you\'ll implement compaction manually using
the same principles.

Consider a chat application where users are having extended
conversations with Claude---discussing complex topics, iterating on
ideas, or working through problems. As the conversation grows, you face
the same context accumulation challenges.

**The Difference**: Instead of tool use triggering token growth, it\'s
the back-and-forth conversation itself. Each exchange adds messages to
the history:

- User asks a question
- Claude provides a detailed response
- User asks for clarification or elaboration
- Claude responds with more context
- This repeats dozens or hundreds of times

Without compaction, by turn 50 you\'re sending the entire conversation
history (all 50 exchanges) on every API call.

**The Solution**: Implement compaction manually in your chat loop using
the same pattern:

1.  Track token usage after each turn
2.  When threshold is exceeded, request a summary
3.  Replace conversation history with the summary
4.  Continue the conversation with compressed context

Let\'s see how to implement this:
:::

:::: {#m6akcmnsz09 .cell .code}
``` python
#!/usr/bin/env python3
"""
Simple Compaction Example - User-Driven Chat Loop

This shows the basic pattern for a chat application with compaction.
No tools required - just a simple loop where the user drives continuation.
"""

# Configuration
COMPACTION_THRESHOLD = 3000  # Compact when tokens exceed this (low for demo purposes)

# Structured summarization prompt for compaction
SUMMARY_PROMPT = """You have been working on the task described above but have not yet completed it. Write a continuation summary that will allow you (or another instance of yourself) to resume work efficiently in a future context window where the conversation history will be replaced with this summary. Your summary should be structured, concise, and actionable. Include:

1. **Task Overview**
   - The user's core request and success criteria
   - Any clarifications or constraints they specified

2. **Current State**
   - What has been completed so far
   - Files created, modified, or analyzed (with paths if relevant)
   - Key outputs or artifacts produced

3. **Important Discoveries**
   - Technical constraints or requirements uncovered
   - Decisions made and their rationale
   - Errors encountered and how they were resolved
   - What approaches were tried that didn't work (and why)

4. **Next Steps**
   - Specific actions needed to complete the task
   - Any blockers or open questions to resolve
   - Priority order if multiple steps remain

5. **Context to Preserve**
   - User preferences or style requirements
   - Domain-specific details that aren't obvious
   - Any promises made to the user

Be concise but complete—err on the side of including information that would prevent duplicate work or repeated mistakes.
 Write in a way that enables immediate resumption of the task.

Wrap your summary in <summary></summary> tags."""

# Message history
messages = []

print("Chat with Claude (type 'quit' to exit, or just hit Enter to continue)")
print("This is a demonstration - try having a conversation and watch compaction trigger")
print("=" * 60)

# Simulate a conversation for demo purposes
demo_messages = [
    "Help me understand how Python decorators work",
    "Can you show me an example with a timing decorator?",
    "How would I make a decorator that takes arguments?",
]

for user_input in demo_messages:
    print(f"\nYou: {user_input}")

    # Add user message
    messages.append({"role": "user", "content": user_input})

    # Get Claude's response
    response = client.messages.create(
        model=MODEL,
        max_tokens=2048,
        messages=messages,
    )

    messages.append(
        {
            "role": "assistant",
            "content": response.content,
        }
    )

    print("\nClaude: ", end="")
    for block in response.content:
        if block.type == "text":
            print(f"{block.text[:300]} ...")

    # Check if we should compact
    usage = response.usage

    # Calculate total tokens (includes cache tokens)
    total_input_tokens = (
        usage.input_tokens
        + (usage.cache_creation_input_tokens or 0)
        + (usage.cache_read_input_tokens or 0)
    )
    total_tokens = total_input_tokens + usage.output_tokens

    cache_info = ""
    if usage.cache_creation_input_tokens or usage.cache_read_input_tokens:
        cache_info = f" (cache: {usage.cache_creation_input_tokens or 0} write + {usage.cache_read_input_tokens or 0} read)"

    print(
        f"\n[Tokens: {total_input_tokens} in{cache_info} + {usage.output_tokens} out = {total_tokens} total]"
    )

    if total_tokens > COMPACTION_THRESHOLD:
        print(f"\n{'=' * 60}")
        print(f"🔄 Compacting conversation... {len(messages)} messages → ", end="", flush=True)

        # Get summary using structured prompt
        summary_response = client.messages.create(
            model=MODEL,
            max_tokens=4096,
            messages=messages + [{"role": "user", "content": SUMMARY_PROMPT}],
        )

        summary_text = "".join(
            block.text for block in summary_response.content if block.type == "text"
        )

        # Replace history with summary
        messages = [{"role": "user", "content": summary_text}]

        print("1 message")
        print(f"{'=' * 60}\n")

print(f"Final conversation messages: {messages[-1].get('content')}")

print("\nDemo complete! In a real application, this loop would continue with user input.")
```

::: {.output .stream .stdout}
    Chat with Claude (type 'quit' to exit, or just hit Enter to continue)
    This is a demonstration - try having a conversation and watch compaction trigger
    ============================================================

    You: Help me understand how Python decorators work
:::
::::

::: {#b229j75wdjm .cell .markdown}
### Understanding the Chat Loop Pattern

The example above demonstrates manual compaction in a conversational
context. Here\'s how it works:

**Key Components**:

1.  **Token Tracking**: After each response, calculate total tokens
    (input + output + cache tokens)
2.  **Threshold Check**: When total exceeds threshold, trigger
    compaction
3.  **Summary Request**: Send the same structured SUMMARY_PROMPT to
    Claude
4.  **History Replacement**: Replace entire message history with just
    the summary
5.  **Continue**: Next user message builds on the summary, not full
    history

**When to Use This Pattern**:

- **Extended brainstorming sessions**: Users exploring ideas with Claude
  over many turns
- **Learning conversations**: Tutorials or explanations that span dozens
  of exchanges
- **Iterative refinement**: Users providing feedback on drafts, designs,
  or solutions
- **Chat applications**: Any multi-turn conversation interface

**Key Differences from Tool Runner**:

  ---------------------------------------------------------------------------
  Aspect         Tool Runner (Automatic)           Chat Loop (Manual)
  -------------- --------------------------------- --------------------------
  **Trigger**    Automatic when threshold reached  You implement threshold
                                                   check

  **Summary**    SDK handles summary request       You make explicit API call

  **History      SDK replaces messages             You manually replace list
  Management**                                     

  **Use Case**   Agentic workflows with tools      User-driven conversations
  ---------------------------------------------------------------------------

**Production Considerations**:

1.  **Adjust threshold**: Use larger thresholds for real applications
2.  **Customize summary prompt**: Tailor to your conversation type
    (brainstorming vs. technical support vs. tutoring)
3.  **Show user indicators**: Display a message like \"Summarizing
    conversation\...\" so users understand the pause
4.  **Preserve key context**: Ensure the summary prompt captures
    domain-specific information your users care about

This pattern gives you full control over when and how compaction
happens, making it ideal for conversational applications where the
SDK\'s automatic tool-runner compaction isn\'t available.
:::

::: {#d71dwo1dayp .cell .markdown}
## Limitations and Considerations

While automatic context compaction is powerful, there are important
limitations to understand:

### Server-Side Sampling Loops

**Current Limitation**: Compaction does not work optimally with
server-side sampling loops, such as server-side web search tools.

**Why**: Cache tokens accumulate across sampling loops, which can
trigger compaction prematurely based on cached content rather than
actual conversation history.

This feature works best with:

- ✅ Client-side tools (like the customer service API in this cookbook)
- ✅ Standard agentic workflows with regular tool use
- ✅ File operations, database queries, API calls
- ❌ Server-side Extended Thinking
- ❌ Server-side web search tools

### Information Loss

**Trade-off**: Summaries inherently lose some information. While Claude
is good at identifying key points, some details will be compressed or
omitted.

**In ticket processing**:

- ✅ **Retained**: Ticket IDs, categories, priorities, teams, outcomes,
  progress status
- ❌ **Lost**: Full knowledge base article text, complete drafted
  response text, detailed classification reasoning

This is usually acceptable, you don\'t need every KB article and full
response text in perpetuity, just the completion records.

**Mitigation**:

- Use custom summary prompts to preserve critical information
- Set higher thresholds for tasks requiring extensive historical context
- Structure your tasks to be modular (each phase builds on summaries,
  not raw details)

### When NOT to Use Compaction

Avoid compaction for:

1.  **Short tasks**: If your task completes within 50k-100k tokens,
    compaction adds unnecessary overhead
2.  **Tasks requiring full audit trails**: Some tasks need access to ALL
    previous details
3.  **Server-side sampling workflows**: As mentioned above, wait for
    this limitation to be addressed
4.  **Highly iterative refinement**: Tasks where each step critically
    depends on exact details from all previous steps

### When TO Use Compaction

Compaction is ideal for:

1.  **Sequential processing**: Like our ticket workflow---process
    multiple items one after another
2.  **Multi-phase workflows**: Where each phase can summarize progress
    before moving on
3.  **Iterative data processing**: Processing large datasets in chunks
    or entities one at a time
4.  **Extended analysis sessions**: Analyzing data across many entities
5.  **Batch operations**: Processing hundreds of items where each is
    independent

**Ticket processing is a perfect use case** because:

- Each ticket workflow is largely independent
- You need completion summaries, not full tool results
- Natural compaction points exist (after completing several tickets)
- The workflow is iterative and sequential
:::

::: {#b4pz1jmdidi .cell .markdown}
## Summary

Automatic context compaction is a powerful feature that enables
long-running agentic workflows to exceed typical context limits. In this
cookbook, we\'ve explored compaction through a customer service ticket
processing workflow.

### Next Steps

Try implementing compaction in your own workflows:

1.  Identify natural compaction points (after processing each item,
    completing each phase, etc.)
2.  Start with an aggressive threshold (5k-10k) if you have clear
    per-item boundaries
3.  Use custom summary prompts to preserve critical information
4.  Monitor when compaction triggers and verify quality is maintained
5.  Adjust threshold based on your specific needs

For more on effective context management, see [Effective Context
Engineering for AI
Agents](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents).
:::

---

## Explore the .claude directory - Claude Code Docs

Source: https://code.claude.com/docs/en/claude-directory
Path: 02-Claude-Code-CLI/claude-directory.md

# Explore the .claude directory

Copy pageCopy page

Where Claude Code reads CLAUDE.md, settings.json, hooks, skills, commands, subagents, workflows, rules, and auto memory. Explore the .claude directory in your project and ~/.claude in your home directory.

Copy pageCopy page

Claude Code reads instructions, settings, skills, subagents, and memory from your project directory and from `~/.claude` in your home directory. Commit project files to git to share them with your team; files in `~/.claude` are personal configuration that applies across all your projects. On Windows, `~/.claude` resolves to `%USERPROFILE%\.claude`. If you set [`CLAUDE_CONFIG_DIR`](env-vars.md), every `~/.claude` path on this page lives under that directory instead. Most users only edit `CLAUDE.md` and `settings.json`. If your repository already has an `AGENTS.md` for other coding agents, Claude Code [can read that](memory.md#agents-md) in place of a `CLAUDE.md`. The rest of the directory is optional: add skills, rules, or subagents as you need them.


[​](#explore-the-directory)

Explore the directory

Click files in the tree to see what each one does, when it loads, and an example.


[​](#what’s-not-shown)

What’s not shown

The explorer covers files you author and edit. A few related files live elsewhere:

| File                    | Location                                   | Purpose                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
|-------------------------|--------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `managed-settings.json` | System-level, varies by OS                 | Enterprise-enforced settings that your own settings files and `--settings` values can’t override, apart from [narrow exceptions](settings.md#exceptions-to-managed-settings-precedence). See [where to save the file](../13-Enterprise-Admin/managed-settings.md#deploy-a-managed-settings-file) and [which managed source Claude Code uses](../13-Enterprise-Admin/managed-settings.md#precedence-within-the-managed-tier).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE.local.md`       | Project root                               | Your private preferences for this project, loaded alongside CLAUDE.md. Create it manually and add it to `.gitignore`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `AGENTS.md`             | Project root, `.claude/`, or any directory | Project instructions you write for AI coding agents. Claude Code can [load it](memory.md#agents-md) in place of a `CLAUDE.md`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Installed plugins       | `~/.claude/plugins`                        | Cloned marketplaces, installed plugin versions, the `installed_plugins.json` install record, and per-plugin data, managed by `claude plugin` commands. Plugins [synced from your claude.ai account](../08-Plugins-Skills/plugins-loading.md#synced-plugins) download into `~/.claude/plugins/synced/`. For a plugin installed from a marketplace [`command` source](../08-Plugins-Skills/plugins-marketplace-reference.md#command-plugin-source) in link mode, Claude Code stores links here instead of a copy, and the plugin’s files stay in the directory the command prints. A `command` source requires Claude Code v2.1.229 or later. A plugin listed by relative path in a marketplace you added from a local path also [loads in place](../08-Plugins-Skills/plugins-loading.md#find-plugins-on-disk) from its source directory rather than from a cache copy. See [plugin caching](../08-Plugins-Skills/plugins-loading.md#find-plugins-on-disk) for how orphaned versions are cleaned up. |

`~/.claude` also holds data Claude Code writes as you work: transcripts, prompt history, file snapshots, caches, and logs. See [application data](#application-data) below.


[​](#choose-the-right-file)

Choose the right file

Different kinds of customization live in different files. Use this table to find where a change belongs.

| You want to                                        | Edit                                     | Scope             | Reference                                                    |
|:---------------------------------------------------|:-----------------------------------------|:------------------|:-------------------------------------------------------------|
| Give Claude project context and conventions        | `CLAUDE.md`                              | project or global | [Memory](memory.md)                                    |
| Allow or block specific tool calls                 | `settings.json` `permissions` or `hooks` | project or global | [Permissions](permissions.md), [Hooks](../07-Hooks/hooks.md) |
| Run a script before or after tool calls            | `settings.json` `hooks`                  | project or global | [Hooks](../07-Hooks/hooks.md)                                      |
| Set environment variables for the session          | `settings.json` `env`                    | project or global | [Settings](settings-reference.md#all-settings)         |
| Keep personal overrides out of git                 | `settings.local.json`                    | project only      | [Settings scopes](settings.md#where-settings-live)     |
| Add a prompt or capability you invoke with `/name` | `skills/<name>/SKILL.md`                 | project or global | [Skills](../08-Plugins-Skills/skills.md)                                    |
| Define a specialized subagent with its own tools   | `agents/*.md`                            | project or global | [Subagents](../09-Agents-Patterns/sub-agents.md)                             |
| Orchestrate many subagents from a script           | `workflows/*.js`                         | project or global | [Dynamic workflows](workflows.md)                      |
| Connect external tools over MCP                    | `.mcp.json`                              | project only      | [MCP](../06-MCP-Tools/General/mcp.md)                                          |
| Change how Claude formats responses                | `output-styles/*.md`                     | project or global | [Output styles](output-styles.md)                      |


[​](#file-reference)

File reference

This table lists every file the explorer covers. Project-scope files live in your repo under `.claude/` (or at the root for `CLAUDE.md`, `.mcp.json`, and `.worktreeinclude`). Global-scope files live in `~/.claude/` and apply across all projects.

Several things can override what you put in these files:

- [Managed settings](../13-Enterprise-Admin/server-managed-settings.md) deployed by your organization take precedence over every settings file and `--settings` value, apart from the [exceptions under Settings precedence](settings.md#exceptions-to-managed-settings-precedence)
- CLI flags like `--permission-mode` or `--settings` override `settings.json` for that session
- Some environment variables take precedence over their equivalent setting, but this varies: check the [environment variables reference](env-vars.md) for each one

See [settings precedence](settings.md#settings-precedence) for the full order.

Click a filename to open that node in the explorer above.

| File                                                | Scope              | Commit | What it does                                                                                                  | Reference                                                            |
|-----------------------------------------------------|--------------------|--------|---------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------|
| [`CLAUDE.md`](#ce-claude-md)                        | Project and global | ✓      | Instructions loaded every session                                                                             | [Memory](memory.md)                                            |
| [`rules/*.md`](#ce-rules)                           | Project and global | ✓      | Topic-scoped instructions, optionally path-gated                                                              | [Rules](memory.md#organize-rules-with-claude/rules/)           |
| [`settings.json`](#ce-settings-json)                | Project and global | ✓      | Permissions, hooks, env vars, model defaults                                                                  | [Settings](settings.md)                                        |
| [`settings.local.json`](#ce-settings-local-json)    | Project only       |        | Your personal overrides, gitignored when Claude Code saves a setting to it                                    | [Settings scopes](settings.md#where-settings-live)             |
| [`.mcp.json`](#ce-mcp-json)                         | Project only       | ✓      | Team-shared MCP servers                                                                                       | [MCP scopes](../06-MCP-Tools/General/mcp.md#mcp-installation-scopes)                   |
| [`.worktreeinclude`](#ce-worktreeinclude)           | Project only       | ✓      | Gitignored files to copy into new worktrees                                                                   | [Worktrees](worktrees.md#copy-gitignored-files-into-worktrees) |
| [`skills/<name>/SKILL.md`](#ce-skills)              | Project and global | ✓      | Reusable prompts invoked with `/name` or auto-invoked                                                         | [Skills](../08-Plugins-Skills/skills.md)                                            |
| [`commands/*.md`](#ce-commands)                     | Project and global | ✓      | Single-file prompts; same mechanism as skills                                                                 | [Skills](../08-Plugins-Skills/skills.md)                                            |
| [`output-styles/*.md`](#ce-output-styles)           | Project and global | ✓      | Custom instruction sets that adjust how Claude works                                                          | [Output styles](output-styles.md)                              |
| [`agents/*.md`](#ce-agents)                         | Project and global | ✓      | Subagent definitions with their own prompt and tools                                                          | [Subagents](../09-Agents-Patterns/sub-agents.md)                                     |
| [`workflows/*.js`](#ce-workflows)                   | Project and global | ✓      | Dynamic workflow scripts written by Claude and saved from `/workflows`; each file becomes a `/<name>` command | [Dynamic workflows](workflows.md)                              |
| [`agent-memory/<name>/`](#ce-agent-memory)          | Project and global | ✓      | Persistent memory for subagents                                                                               | [Persistent memory](../09-Agents-Patterns/sub-agents.md#enable-persistent-memory)    |
| [`~/.claude.json`](#ce-claude-json)                 | Global only        |        | App state, account details, UI toggles, personal MCP servers                                                  | [Global config](settings-reference.md#global-config-settings)  |
| [`projects/<project>/memory/`](#ce-global-projects) | Global only        |        | Auto memory: Claude’s notes to itself across sessions                                                         | [Auto memory](memory.md#auto-memory)                           |
| [`keybindings.json`](#ce-keybindings)               | Global only        |        | Custom keyboard shortcuts                                                                                     | [Keybindings](keybindings.md)                                  |
| [`themes/*.json`](#ce-themes)                       | Global only        |        | Custom color themes                                                                                           | [Custom themes](terminal-config.md#create-a-custom-theme)      |


[​](#frontmatter-fields-by-file)

Frontmatter fields by file

Skills, command files, subagents, output styles, and rules read their configuration from YAML [frontmatter](glossary.md#frontmatter) at the top of the file, and each accepts its own set of fields. This table lists the field names for each file and links to the reference that describes them.

| File                     | Frontmatter fields                                                                                                                                                                                                                                                            | Reference                                                                |
|--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------|
| `skills/<name>/SKILL.md` | `name`, `description`, `when_to_use`, `argument-hint`, `arguments`, `disable-model-invocation`, `user-invocable`, `allowed-tools`, `disallowed-tools`, `model`, `effort`, `context`, `agent`, `background`, `hooks`, `paths`, `shell`, `metadata`, `license`, `compatibility` | [Skill frontmatter](../08-Plugins-Skills/skills.md#frontmatter-reference)               |
| `commands/*.md`          | The skill fields except `name` and `paths`                                                                                                                                                                                                                                    | [Skill frontmatter](../08-Plugins-Skills/skills.md#frontmatter-reference)               |
| `agents/*.md`            | `name`, `description`, `tools`, `disallowedTools`, `model`, `permissionMode`, `maxTurns`, `autoCompactWindow`, `skills`, `mcpServers`, `hooks`, `memory`, `background`, `effort`, `isolation`, `color`, `initialPrompt`, `omitClaudeMd`, `experimental`                       | [Subagent frontmatter](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields) |
| `output-styles/*.md`     | `name`, `description`, `keep-coding-instructions`, `force-for-plugin`                                                                                                                                                                                                         | [Output style frontmatter](output-styles.md#frontmatter)           |
| `rules/*.md`             | `paths`                                                                                                                                                                                                                                                                       | [Rule frontmatter](memory.md#rules-frontmatter-reference)          |

Agents shipped in a [plugin](../08-Plugins-Skills/plugins-components.md#agents) honor a subset of the subagent fields.


[​](#troubleshoot-configuration)

Troubleshoot configuration

If a setting, hook, or file isn’t taking effect, see [Debug your configuration](debug-your-config.md) for the inspection commands and a symptom-first lookup table.


[​](#application-data)

Application data

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


[​](#cleaned-up-automatically)

Cleaned up automatically

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

| Path under `~/.claude/`                                                                                                         | Contents                                                                                                                                                                                                                                                                                                                                     |
|---------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `projects/<project>/<session>.jsonl`                                                                                            | Full conversation transcript: every message, tool call, and tool result                                                                                                                                                                                                                                                                      |
| `projects/<project>/<session>.orphaned-<timestamp>-<suffix>.jsonl`, `projects/<project>/<session>.jsonl.superseded-<timestamp>` | A previous transcript for the session that Claude Code set aside instead of overwriting or deleting it. It doesn’t appear in the session picker                                                                                                                                                                                              |
| `projects/<project>/<session>/subagents/`                                                                                       | [Subagent](../09-Agents-Patterns/sub-agents.md) conversation transcripts, removed with the parent session transcript when it ages out                                                                                                                                                                                                                        |
| `projects/<project>/<session>/tool-results/`                                                                                    | Large tool outputs spilled to separate files, and full-size copies of [images that MCP tools return](../06-MCP-Tools/General/mcp.md#images-in-tool-results)                                                                                                                                                                                                    |
| `file-history/<session>/`                                                                                                       | Pre-edit snapshots of files Claude changed, used for [checkpoint restore](checkpointing.md). Holds snapshots for the 100 most recent checkpoints; snapshot files that no retained checkpoint references are deleted, except each file’s first snapshot                                                                                 |
| `plans/`                                                                                                                        | Plan files written during [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode)                                                                                                                                                                                                                                      |
| `debug/`                                                                                                                        | Per-session debug logs, written while debug logging is on, such as when you start with [`--debug`](cli-reference.md#cli-flags) or run `/debug`                                                                                                                                                                                         |
| `paste-cache/`                                                                                                                  | Contents of large pastes                                                                                                                                                                                                                                                                                                                     |
| `image-cache/<session>/`                                                                                                        | Attached images saved by Claude Code v2.1.274 and earlier. Later versions save pasted and attached images outside `~/.claude`, in an `images/` directory for each session under the temp directory that [`CLAUDE_CODE_TMPDIR`](env-vars.md) controls. The sweep removes other sessions’ leftover directories here, whatever their age. |
| `uploads/<session>/`                                                                                                            | Files you attach from the web or mobile app, and photos you attach from the mobile app, when messaging a [Remote Control](remote-control.md) session. An attachment to a [cloud session](claude-code-on-the-web.md) is saved in that session’s own cloud environment instead, not on your machine.                               |
| `dev-mods/<session>/`                                                                                                           | [Mods that Claude wrote](../08-Plugins-Skills/plugins-mods-create.md#ask-claude-for-a-mod) during the session                                                                                                                                                                                                                                               |
| `session-env/`                                                                                                                  | Per-session environment metadata                                                                                                                                                                                                                                                                                                             |
| `tasks/`                                                                                                                        | Task lists written by the task tools, one directory per list                                                                                                                                                                                                                                                                                 |
| `shell-snapshots/`                                                                                                              | Aliases, functions, and shell options captured at startup and applied by the [Bash tool](tools-reference.md#bash-tool-behavior) to each command. Removed on clean exit. The sweep clears any left after a crash.                                                                                                                       |
| `backups/`                                                                                                                      | Earlier versions of `~/.claude.json`, copied when Claude Code rewrites the file. Claude Code keeps the five newest, plus a copy of any version it couldn’t parse.                                                                                                                                                                            |
| `feedback-bundles/`                                                                                                             | Redacted transcript archives written by `/feedback` on third-party providers or when no Anthropic credentials are configured, for sending to your Anthropic account team                                                                                                                                                                     |
| `feedback/drafts/`                                                                                                              | Queued [Claude-drafted feedback](tools-reference.md#sendfeedback-tool-behavior) awaiting your review in `/feedback`. Swept after `cleanupPeriodDays` or 30 days, whichever is shorter. When the queue is at its 10-draft limit, Claude Code deletes the oldest draft to make room.                                                     |
| `usage-data/`                                                                                                                   | `report.html` and timestamped report copies written by [`/insights`](../17-Billing-Plans/costs.md#analyze-your-usage-patterns), plus cached per-session analysis data used to build them                                                                                                                                                                   |
| `skills/.trash/`, `plugins/.trash/`                                                                                             | [Skills](../08-Plugins-Skills/skills.md#how-synced-skills-behave) and [plugins](../08-Plugins-Skills/plugins-loading.md#synced-plugins) that the claude.ai sync removed, such as after you turn one off on claude.ai or stop syncing. The files stay here so you can recover them until the sweep deletes them                                                             |
| `plugins/installed_plugins.set-aside.<date>.<hash>.json`, `plugins/installed_plugins.unreadable.<date>.<hash>.kept`             | Dated copies Claude Code makes before rewriting [`installed_plugins.json`](../08-Plugins-Skills/plugins-loading.md#find-plugins-on-disk): install records it dropped, and the contents of a file it couldn’t read.                                                                                                                                          |
| `todos/`, `statsig/`, `logs/`                                                                                                   | Legacy directories from older versions. No longer written. The sweep removes their contents and then the empty directory.                                                                                                                                                                                                                    |

Session files in `sessions/`, auto memory, and Claude Desktop and Cowork transcripts each follow their own retention rule:

- **`sessions/`**: holds one small file per running session, used to detect concurrent sessions and crashes. It isn’t part of the age-based sweep: Claude Code removes each file when its session exits and clears crash leftovers on the next launch.
- **Auto memory**: the sweep doesn’t delete the memory files in a project’s [auto memory](memory.md#auto-memory) directory, `projects/<project>/memory/`. Claude Code removes that directory only if it has been empty for the whole retention period. Before v2.1.228, the sweep treated folders inside the memory directory as session data and could delete old files beneath it.
- **Claude Desktop and Cowork transcripts**: Claude Code keeps the transcript of a session you started or most recently continued in Claude Desktop or Cowork at any age. To give these transcripts an age limit, set [`desktopSessionCleanupPeriodDays`](settings-reference.md#desktopsessioncleanupperioddays). Requires Claude Code v2.1.248 or later; earlier versions delete them after `cleanupPeriodDays`. Claude Code deletes these transcripts after `cleanupPeriodDays` instead in either of these cases:
  - [Managed settings](../13-Enterprise-Admin/managed-settings.md) set `cleanupPeriodDays`
  - The [HIPAA configuration applies to your sessions](hipaa-setup.md#check-how-developers-sign-in-and-connect)

Claude Code skips the age-based sweep in these cases:

- **Bare mode**: when you run `claude -p` with [`--bare`](headless.md#start-faster-with-bare-mode), Claude Code doesn’t run the sweep in that session.
- **Paused sweep**: if Claude Code can’t safely determine the retention period, it pauses the retention cleanup sweep; the [`retention_sweep` event](../13-Enterprise-Admin/monitoring-usage.md#retention-sweep-event) lists each configuration that pauses it. When the cause is a settings file that can’t be read or parsed, or settings errors with `cleanupPeriodDays` or `desktopSessionCleanupPeriodDays` explicitly set, Claude Code also shows a warning in `/status` until you fix the settings errors. When [managed settings](../13-Enterprise-Admin/server-managed-settings.md) provide `cleanupPeriodDays`, Claude Code runs the sweep at the managed value in either case.

To check that the machines in your organization run the sweep with the retention period you set, see [Check the retention sweep](../13-Enterprise-Admin/monitoring-usage.md#check-the-retention-sweep).


[​](#session-scratchpad-directory)

Session scratchpad directory

The scratchpad is a per-session directory that Claude Code gives Claude for temporary files: intermediate results, helper scripts, and drafts that don’t belong in your project. When Claude says it saved something “to the scratchpad”, the file is there. Claude uses it instead of `/tmp`, and can create, edit, and read files in it without a permission prompt. The scratchpad lives under Claude Code’s temp directory rather than `~/.claude`. Find the current session’s path for your platform:

- **macOS**: `/private/tmp/claude-<uid>/<project>/<session-id>/scratchpad/`
- **Linux**: `/tmp/claude-<uid>/<project>/<session-id>/scratchpad/`, or the same shape under `$TMPDIR` when your system sets one
- **Windows**: `%TEMP%\claude\<project>\<session-id>\scratchpad\`

`<project>` is your working directory path with every character other than letters and digits replaced by `-`, such as `-Users-you-my-project`. If you set [`CLAUDE_CODE_TMPDIR`](env-vars.md), the tree moves under that directory instead. Hooks receive the current session’s path as [`scratchpad_dir`](../07-Hooks/hooks.md#common-input-fields). Scratchpad files last as long as the session’s transcript: the [retention sweep](#cleaned-up-automatically) deletes the directory when it deletes the transcript, and [`claude purge`](#clear-local-data) doesn’t touch the temp directory. Because the directory sits under the system temp location, your operating system can also clear it, such as on restart. To keep something Claude wrote there, ask Claude to move it into your project. A session has a scratchpad only when all of these hold:

- You’re signed in with a claude.ai account rather than an API key
- The session uses the Anthropic API, not Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry
- [`enableArtifact`](settings-reference.md#enableartifact) isn’t set to `false`


[​](#kept-until-you-delete-them)

Kept until you delete them

Apart from the rows that say otherwise, the retention cleanup sweep doesn’t remove the paths below, and Claude Code keeps them until you delete them.

| Path under `~/.claude/` | Contents                                                                                                                                                                                                                                                                                                                                                                    |
|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `history.jsonl`         | Prompts you’ve typed, with timestamp and project path. Used for up-arrow recall, `Ctrl+R` history search, and `!` shell-command completion. Each sweep removes the entries older than `cleanupPeriodDays` when the [HIPAA configuration applies to your sessions](hipaa-setup.md#check-how-developers-sign-in-and-connect).                                           |
| `stats-cache.json`      | Aggregated token and cost counts shown by `/usage`                                                                                                                                                                                                                                                                                                                          |
| `remote-settings.json`  | Cached copy of [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) for your organization, or `{}` when your organization has configured none. Only present when the session [fetches them](../13-Enterprise-Admin/server-managed-settings.md#platform-availability). Claude Code checks for updates at startup and hourly during a session. Claude Code deletes it when you log out. |
| `cache/changelog.md`    | Cached copy of the Claude Code changelog, shown by `/release-notes`. Refreshed in the background.                                                                                                                                                                                                                                                                           |
| `policy-limits.json`    | Cached feature policy settings for your organization. Only present for some account types. Refreshed automatically. A `policy-limits.json.stamp.json` sidecar records which account or API key the cache belongs to. Claude Code deletes both files when you log out.                                                                                                       |


[​](#state-files-to-keep)

State files to keep

Depending on which features you use, `~/.claude/` also holds files that the tables under [Application data](#application-data) don’t list. Of those, caches and lock files are safe to delete. Keep these state files:

- `.credentials.json`: your [login credentials](authentication.md#credential-management)
- `agent-memory/`: [subagent memory](../09-Agents-Patterns/sub-agents.md#enable-persistent-memory)
- `jobs/` and `daemon/`: [background session](../09-Agents-Patterns/agent-view.md#where-state-is-stored) state


[​](#plaintext-storage)

Plaintext storage

Transcripts and history are not encrypted at rest. OS file permissions are the only protection. If a tool reads a `.env` file or a command prints a credential, that value is written to `projects/<project>/<session>.jsonl`. To reduce exposure:

- Lower `cleanupPeriodDays` to shorten how long Claude Code keeps transcripts
- Set [`desktopSessionCleanupPeriodDays`](settings-reference.md#desktopsessioncleanupperioddays) to give Claude Desktop and Cowork transcripts an age limit too
- Set the [`CLAUDE_CODE_SKIP_PROMPT_HISTORY`](env-vars.md) environment variable to skip writing transcripts and prompt history in any mode. In non-interactive mode, you can instead pass `--no-session-persistence` alongside `-p`, or set `persistSession: false` in the TypeScript Agent SDK; the Python SDK has no equivalent option.
- Use [permission rules](permissions.md) to deny reads of credential files


[​](#clear-local-data)

Clear local data

Run `claude purge` to delete the state Claude Code holds for one project. It deletes:

- Transcripts and auto memory under `projects/`
- Per-session `tasks/`, `debug/`, and `file-history/` entries
- Matching prompt lines in `history.jsonl`
- The project’s entry in `~/.claude.json`

Images you pasted or attached in the project’s sessions and each session’s [scratchpad](#session-scratchpad-directory) are stored under Claude Code’s temp directory rather than `~/.claude`, so the purge doesn’t remove them. The [retention sweep](#cleaned-up-automatically) still deletes the images once they’re older than `cleanupPeriodDays`; a purged session’s scratchpad stays until you delete it or your operating system clears the temp directory. The command prints the full deletion plan and asks for confirmation before removing anything. Before v2.1.288, the command was `claude project purge`. The examples below use `~/work/my-repo` as a placeholder. Replace it with the path to your project. If no state matches the path, the command prints an error and exits with status 1. Preview the plan without deleting anything:

```python
claude purge ~/work/my-repo --dry-run
```

The plan lists each matching item and why it is included:

```python
Purge plan for /home/user/work/my-repo:

  dir:    /home/user/.claude/projects/-home-user-work-my-repo
           project transcripts (.jsonl) and memory/
  config: projects["/home/user/work/my-repo"]
           project entry in ~/.claude.json (trust, history, MCP servers)
  filter: /home/user/.claude/history.jsonl
           12 prompt(s) typed in this project

shell-snapshots/ are not project-scoped and will not be touched
backups/ may still contain this project entry in old .claude.json snapshots (/home/user/.claude/backups); at most 5 are kept and they rotate out automatically
Dry run: 3 item(s) would be deleted.
```

Delete with a single confirmation prompt:

```python
claude purge ~/work/my-repo
```

The command prints the same plan, then asks `Delete 3 item(s) for /home/user/work/my-repo? This cannot be undone. [y/N]` and deletes only if you answer `y`. Omit the path to pick a project from an interactive list. Skip the confirmation prompt for use in scripts:

```python
claude purge ~/work/my-repo --yes
```

Other options:

- Pass `--all` instead of a path to purge state for every project at once, which deletes `history.jsonl` outright rather than filtering it.
- Pass `-i` to step through the deletion plan one item at a time.

The command leaves `shell-snapshots/` and `backups/` alone because those are not project-scoped, and warns about them in the plan output. If anyone ran [`/heapdump`](troubleshooting.md#high-cpu-or-memory-usage) on the machine, delete the `.heapsnapshot` files it wrote too. A heap snapshot contains the full conversation and any credentials the process held, and neither the retention sweep nor the purge touches it. You can also delete any of the application-data paths above yourself, apart from the [state files to keep](#state-files-to-keep).

| Delete                                                                                                                                  | You lose                                                                                                                                                               |
|-----------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `~/.claude/projects/`                                                                                                                   | Resume, continue, and rewind for past sessions, and auto memory for every project                                                                                      |
| `~/.claude/history.jsonl`                                                                                                               | Up-arrow prompt recall, `Ctrl+R` history search, and `!` shell-command completion                                                                                      |
| `~/.claude/paste-cache/`                                                                                                                | Pasted text in recalled prompts; see [paste large content](terminal-config.md#paste-large-content)                                                               |
| `~/.claude/uploads/`                                                                                                                    | Attachments that past [Remote Control](remote-control.md) sessions refer to by path                                                                              |
| `~/.claude/file-history/`                                                                                                               | Checkpoint restore for past sessions                                                                                                                                   |
| `~/.claude/stats-cache.json`                                                                                                            | Historical totals shown by `/usage`                                                                                                                                    |
| `~/.claude/usage-data/`                                                                                                                 | Past [`/insights`](../17-Billing-Plans/costs.md#analyze-your-usage-patterns) reports and the cached analysis data used to build them                                                 |
| `~/.claude/feedback-bundles/`                                                                                                           | Feedback and bug-report archives you haven’t yet sent to your Anthropic account team                                                                                   |
| `~/.claude/feedback/drafts/`                                                                                                            | [Claude-drafted feedback](tools-reference.md#sendfeedback-tool-behavior) you haven’t sent                                                                        |
| `~/.claude/remote-settings.json`                                                                                                        | Nothing. Re-fetched on next launch.                                                                                                                                    |
| `~/.claude/cache/changelog.md`                                                                                                          | Nothing. Refreshed in the background.                                                                                                                                  |
| `~/.claude/policy-limits.json`                                                                                                          | Nothing. Refreshed automatically.                                                                                                                                      |
| `~/.claude/tasks/`                                                                                                                      | Your [task lists](interactive-mode.md#task-list), including any still in use                                                                                     |
| `~/.claude/skills/.trash/`, `~/.claude/plugins/.trash/`                                                                                 | The chance to recover [synced skills](../08-Plugins-Skills/skills.md#how-synced-skills-behave) and [synced plugins](../08-Plugins-Skills/plugins-loading.md#synced-plugins) that Claude Code removed |
| `~/.claude/plugins/installed_plugins.set-aside.<date>.<hash>.json`, `~/.claude/plugins/installed_plugins.unreadable.<date>.<hash>.kept` | The copies of plugin install records that Claude Code dropped or couldn’t read. Nothing reads them back                                                                |
| `~/.claude/debug/`, `~/.claude/plans/`, `~/.claude/session-env/`, `~/.claude/shell-snapshots/`, `~/.claude/backups/`                    | Nothing user-facing                                                                                                                                                    |
| `~/.claude/todos/`, `~/.claude/statsig/`, `~/.claude/logs/`, `~/.claude/image-cache/`                                                   | Nothing. Legacy directories not written by current versions.                                                                                                           |

Don’t delete `~/.claude.json`, `~/.claude/settings.json`, or `~/.claude/plugins/`: those hold your account details, preferences, and installed plugins.


[​](#related-resources)

Related resources

- [Manage Claude’s memory](memory.md): write and organize CLAUDE.md, rules, and auto memory
- [Configure settings](settings.md): set permissions, hooks, environment variables, and model defaults
- [Create skills](../08-Plugins-Skills/skills.md): build reusable prompts and workflows
- [Configure subagents](../09-Agents-Patterns/sub-agents.md): define specialized agents with their own context

---

## Claude Code on Claude Platform on AWS - Claude Code Docs

Source: https://code.claude.com/docs/en/claude-platform-on-aws
Path: 02-Claude-Code-CLI/claude-platform-on-aws.md

## On this page

- [Prerequisites](#prerequisites)
- [Setup](#setup)
  - [1. Configure AWS credentials](#1-configure-aws-credentials)
  - [Use AWS credentials with SigV4](#use-aws-credentials-with-sigv4)
  - [Use a workspace API key](#use-a-workspace-api-key)
  - [2. Configure Claude Code](#2-configure-claude-code)
  - [3. Pin model versions](#3-pin-model-versions)
  - [4. Launch and verify](#4-launch-and-verify)
- [Use the Agent SDK](#use-the-agent-sdk)
- [Route through a corporate proxy](#route-through-a-corporate-proxy)
- [Troubleshooting](#troubleshooting)
  - [403 Forbidden or AccessDenied on every request](#403-forbidden-or-accessdenied-on-every-request)
  - [Requests fail with a missing-workspace error](#requests-fail-with-a-missing-workspace-error)
  - [Requests still go to api.anthropic.com](#requests-still-go-to-api-anthropic-com)
- [Additional resources](#additional-resources)

Deployment

# Claude Code on Claude Platform on AWS

Copy pageCopy page

Configure Claude Code to use the Anthropic-operated Claude API with AWS authentication, IAM access control, and AWS Marketplace billing.

Copy pageCopy page

Claude Platform on AWS is the Anthropic-operated Claude API with AWS authentication, IAM access control, and AWS Marketplace billing. Requests reach Anthropic’s API directly, so you get the same models and API features as the [Claude API](../04-API-Reference/Other/home.md) on the same release schedule. You authenticate with AWS credentials or a workspace API key, and you pay through AWS Marketplace. Client-side features that Claude Code turns on through Anthropic’s feature-flag service are off by default, and the [advisor tool](advisor.md) isn’t available. See the [feature availability matrix](feature-availability.md#summary-by-provider) for the full list. Use this guide to point Claude Code at a workspace you’ve already provisioned through Claude Platform on AWS. For the AWS subscription and workspace setup that comes before this, see the [Claude Platform on AWS documentation](../04-API-Reference/Guides/build-with-claude-claude-platform-on-aws.md).

Subscribing through AWS Marketplace provisions a new Anthropic organization tied to your AWS account. This organization is separate from any organization you already have with Anthropic, and credentials don’t transfer between them. Use the workspace ID and API keys from the AWS-linked organization, not from a pre-existing Claude Console account.


[​](#prerequisites)

Prerequisites

Before configuring Claude Code, you need:

- An active Claude Platform on AWS subscription through AWS Marketplace
- A workspace in your AWS-linked Anthropic organization, with its workspace ID
- An IAM principal with permission to invoke the Anthropic service, or an API key scoped to the workspace
- AWS credentials in your environment, in `~/.aws/credentials`, or from an attached IAM role if you want SigV4 authentication. The AWS CLI is required only for the SSO login flow.


[​](#setup)

Setup


[​](#1-configure-aws-credentials)

1. Configure AWS credentials

Claude Code supports two authentication methods for Claude Platform on AWS. Choose the method that fits how your team manages access:

- [AWS credentials with SigV4](#use-aws-credentials-with-sigv4): authenticate as an IAM principal, with credentials from the standard AWS credential chain
- [Workspace API key](#use-a-workspace-api-key): authenticate with a long-lived key you generate in the AWS Console


[​](#use-aws-credentials-with-sigv4)

Use AWS credentials with SigV4

Claude Code signs requests with SigV4 using the standard AWS credential chain: environment variables, shared credentials in `~/.aws/credentials`, IAM roles, AWS SSO sessions, and any other sources the AWS SDK supports. For local use, log in with the AWS CLI before starting Claude Code. The example below uses an SSO profile, but any method that produces credentials in the standard locations works.

```python
aws sso login --profile my-profile
export AWS_PROFILE=my-profile
```

For CI and automation, give the runner an IAM role with permission to invoke the Anthropic service and set `AWS_REGION`. The credential chain picks the role up automatically. If your SSO credentials expire mid-session, configure [`awsAuthRefresh`](amazon-bedrock.md#advanced-credential-configuration) so Claude Code re-runs your login command and retries instead of failing. Add the command to your [settings file](settings.md), such as `~/.claude/settings.json`:

```python
{
  "awsAuthRefresh": "aws sso login --profile my-profile"
}
```

Claude Code also runs this command at startup when it can’t validate your existing AWS credentials, and shows the command’s output in an `Authentication` panel until the login completes. With `awsAuthRefresh` configured, run `/login`, select **3rd-party platform**, then select **Claude Platform on AWS · refresh credentials** under **Using 3rd-party platforms**. Claude Code runs the configured command and re-reads your AWS credentials without a restart.


[​](#use-a-workspace-api-key)

Use a workspace API key

A workspace API key is a long-lived secret, useful when you don’t want to manage federated AWS credentials. Generate one in the AWS Console under **Claude Platform on AWS → API keys** and set it as `ANTHROPIC_AWS_API_KEY`:

```python
export ANTHROPIC_AWS_API_KEY=sk-ant-xxxxx
```

The key is sent as `x-api-key` and takes precedence over SigV4, so any AWS credentials in your environment are ignored. API keys from a separate Claude Console organization won’t work here. Treat workspace API keys like any other production credential. The [user settings file](settings.md) `env` block is a convenient way to scope the key to your machine without exporting it globally.

The `/login` and `/logout` commands don’t sign you into a claude.ai subscription for Claude Platform on AWS. Authentication runs through your AWS credentials or workspace API key.


[​](#2-configure-claude-code)

2. Configure Claude Code

Set the environment variables that route Claude Code through Claude Platform on AWS instead of the default Anthropic API.

```python
export CLAUDE_CODE_USE_ANTHROPIC_AWS=1
export ANTHROPIC_AWS_WORKSPACE_ID=wrkspc_01ABCDEFGHIJKLMN
export AWS_REGION=us-east-1
```

`ANTHROPIC_AWS_WORKSPACE_ID` is required. Claude Code sends it on every request as the `anthropic-workspace-id` header. Replace the example `wrkspc_01ABCDEFGHIJKLMN` value with your own workspace ID from your Claude Platform on AWS setup. Claude Code computes the base URL as `https://aws-external-anthropic.{region}.api.aws` from the AWS region, which it resolves with the [same precedence as Amazon Bedrock](amazon-bedrock.md#3-configure-claude-code). To override the URL directly, set `ANTHROPIC_AWS_BASE_URL`. Claude Platform on AWS is opt-in even when AWS credentials are present in your environment. Amazon Bedrock and Microsoft Foundry take precedence in provider routing, so unset `CLAUDE_CODE_USE_BEDROCK` and `CLAUDE_CODE_USE_FOUNDRY` if they’re set.


[​](#3-pin-model-versions)

3. Pin model versions

Claude Platform on AWS uses the same model IDs as the direct Claude API. The default aliases `fable`, `opus`, `sonnet`, and `haiku` resolve to Claude Code’s built-in defaults for Claude Platform on AWS, which can lag the newest release. Without `ANTHROPIC_DEFAULT_OPUS_MODEL`, the `opus` alias resolves to Opus 5.5. Before v2.1.280, it resolved to Opus 5 from v2.1.219, and to Opus 4.8 from v2.1.207. If you deploy Claude Code to a team, pin the model IDs explicitly so a new release doesn’t move everyone at once:

```python
export ANTHROPIC_DEFAULT_FABLE_MODEL=claude-fable-5
export ANTHROPIC_DEFAULT_OPUS_MODEL=claude-opus-4-8
export ANTHROPIC_DEFAULT_SONNET_MODEL=claude-sonnet-5
export ANTHROPIC_DEFAULT_HAIKU_MODEL=claude-haiku-4-5
```

For the full list of model IDs and aliases, see [Models overview](../20-Models/about-claude-models-overview.md). For other model-related variables, see [Model configuration](model-config.md). [Prompt caching](prompt-caching.md) is enabled automatically. To request a 1-hour cache TTL instead of the 5-minute default, set `ENABLE_PROMPT_CACHING_1H=1`. The API bills 1-hour cache writes at a higher rate. See [prompt caching pricing](../04-API-Reference/Guides/build-with-claude-prompt-caching.md#pricing) for the rates. To set different TTLs for your main conversation and for the requests Claude Code makes outside it, [choose the TTL yourself](prompt-caching.md#choose-the-ttl-yourself).


[​](#4-launch-and-verify)

4. Launch and verify

Start Claude Code and confirm the routing:

```python
claude
```

The startup banner shows `Claude Platform on AWS` when the provider is active. Run `/status` to check the details: the `API provider` line reads `Claude Platform on AWS`, and the output includes your `Workspace ID`, the `AWS region`, and the `Claude Platform on AWS base URL` if you set an override.


[​](#use-the-agent-sdk)

Use the Agent SDK

The [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) reads the same environment variables as the CLI, so any program that spawns the Claude Code subprocess can target Claude Platform on AWS by exporting `CLAUDE_CODE_USE_ANTHROPIC_AWS`, `ANTHROPIC_AWS_WORKSPACE_ID`, and either `ANTHROPIC_AWS_API_KEY` or AWS credentials before the call.

```python
import { query } from "@anthropic-ai/claude-agent-sdk";

process.env.CLAUDE_CODE_USE_ANTHROPIC_AWS = "1";
process.env.ANTHROPIC_AWS_WORKSPACE_ID = "wrkspc_01ABCDEFGHIJKLMN";
process.env.AWS_REGION = "us-east-1";

for await (const msg of query({ prompt: "What's in this repo?" })) {
  console.log(msg);
}
```

This example relies on the ambient AWS credential chain for SigV4. To authenticate with a workspace API key instead, set `ANTHROPIC_AWS_API_KEY` the same way. For the broader Agent SDK surface, see [Agent SDK overview](../05-Agent-SDK/agent-sdk-overview.md).


[​](#route-through-a-corporate-proxy)

Route through a corporate proxy

To route traffic through a proxy or [LLM gateway](../13-Enterprise-Admin/llm-gateway.md), set `ANTHROPIC_AWS_BASE_URL` to the proxy’s address. Claude Code sends requests to that URL with the same workspace and authentication headers, so any gateway that forwards them unchanged works.

```python
export CLAUDE_CODE_USE_ANTHROPIC_AWS=1
export ANTHROPIC_AWS_WORKSPACE_ID=wrkspc_01ABCDEFGHIJKLMN
export ANTHROPIC_AWS_BASE_URL=https://anthropic-proxy.example.com
```

If your gateway signs requests itself, set `CLAUDE_CODE_SKIP_ANTHROPIC_AWS_AUTH=1` so Claude Code sends unsigned requests and lets the gateway add SigV4 headers before forwarding to AWS. If the gateway requires its own token, set it in `ANTHROPIC_AUTH_TOKEN`.

```python
export CLAUDE_CODE_USE_ANTHROPIC_AWS=1
export CLAUDE_CODE_SKIP_ANTHROPIC_AWS_AUTH=1
export ANTHROPIC_AWS_WORKSPACE_ID=wrkspc_01ABCDEFGHIJKLMN
export ANTHROPIC_AWS_BASE_URL=https://anthropic-proxy.example.com
```


[​](#troubleshooting)

Troubleshooting

Run `/status` to see the resolved provider and any explicitly configured workspace ID, region, base URL override, and auth-skip setting. This is the fastest way to confirm Claude Code is targeting Claude Platform on AWS at all.


[​](#403-forbidden-or-accessdenied-on-every-request)

`403 Forbidden` or `AccessDenied` on every request

The IAM principal Claude Code resolved likely lacks permission to invoke the Anthropic service in your workspace. Check the role attached to your AWS profile or the runner that started Claude Code, and verify it has the `aws-external-anthropic` actions documented in the [IAM action reference](../04-API-Reference/Endpoints/claude-platform-on-aws-iam-actions.md). If you set `ANTHROPIC_AWS_API_KEY`, the key takes precedence over SigV4 and a stale key produces the same error. Regenerate the key in the AWS Console under **Claude Platform on AWS → API keys** or unset the variable to fall back to your AWS credentials.


[​](#requests-fail-with-a-missing-workspace-error)

Requests fail with a missing-workspace error

`ANTHROPIC_AWS_WORKSPACE_ID` is likely unset or empty. Every Claude Platform on AWS request must include the workspace ID. It is not implied by your AWS credentials. Find the ID in your Claude Platform on AWS setup and export it before starting Claude Code.


[​](#requests-still-go-to-api-anthropic-com)

Requests still go to `api.anthropic.com`

`CLAUDE_CODE_USE_ANTHROPIC_AWS` is likely unset or set to a value that doesn’t parse as truthy. Set it to `1` and run `/status` to confirm the resolved provider. If `CLAUDE_CODE_USE_BEDROCK` or `CLAUDE_CODE_USE_FOUNDRY` is also set, those take precedence over Claude Platform on AWS.


[​](#additional-resources)

Additional resources

The Claude Platform on AWS subscription, workspace, and IAM setup that comes before configuring Claude Code is covered in the platform documentation:

- [Claude Platform on AWS overview](../04-API-Reference/Guides/build-with-claude-claude-platform-on-aws.md): subscription, workspace setup, and product reference
- [IAM action reference](../04-API-Reference/Endpoints/claude-platform-on-aws-iam-actions.md): permissions and managed policies

---

## Let Claude coordinate ongoing work with Projects - Claude Code Docs

Source: https://code.claude.com/docs/en/claude-projects
Path: 02-Claude-Code-CLI/claude-projects.md

## On this page

- [When to use a project](#when-to-use-a-project)
  - [When something else fits better](#when-something-else-fits-better)
- [How a project is organized](#how-a-project-is-organized)
- [Create a project](#create-a-project)
  - [Check the prerequisites](#check-the-prerequisites)
  - [Start a new project from scratch](#start-a-new-project-from-scratch)
  - [Start from an existing cloud session](#start-from-an-existing-cloud-session)
  - [Set up GitHub access](#set-up-github-access)
- [Work in a project](#work-in-a-project)
  - [Your first batch](#your-first-batch)
  - [Send work and read results](#send-work-and-read-results)
  - [Review a thread’s pull request](#review-a-thread%E2%80%99s-pull-request)
  - [See what needs you in Overview](#see-what-needs-you-in-overview)
  - [Open a thread when you need control](#open-a-thread-when-you-need-control)
  - [Choose models and let Claude manage context](#choose-models-and-let-claude-manage-context)
  - [Tune how Claude runs a project](#tune-how-claude-runs-a-project)
  - [Unblock a thread waiting on approval](#unblock-a-thread-waiting-on-approval)
  - [Run a thread on your own computer](#run-a-thread-on-your-own-computer)
- [Give a project standing context](#give-a-project-standing-context)
  - [Write project instructions](#write-project-instructions)
  - [Decide which repositories to add](#decide-which-repositories-to-add)
  - [Add files and folders](#add-files-and-folders)
  - [What threads pick up from your repositories](#what-threads-pick-up-from-your-repositories)
  - [Choose an environment for threads](#choose-an-environment-for-threads)
  - [Get skills, plugins, connectors, and tools into threads](#get-skills-plugins-connectors-and-tools-into-threads)
- [Project settings reference](#project-settings-reference)
  - [Pause, archive, or delete a project](#pause-archive-or-delete-a-project)
- [Usage and cost](#usage-and-cost)
  - [What draws on your plan](#what-draws-on-your-plan)
  - [See and reduce a project’s usage](#see-and-reduce-a-project%E2%80%99s-usage)
- [How projects relate to other Claude Code features](#how-projects-relate-to-other-claude-code-features)
- [Limitations](#limitations)
- [Troubleshooting](#troubleshooting)
  - [A thread looks stuck](#a-thread-looks-stuck)
  - [Threads guessed or stalled instead of asking](#threads-guessed-or-stalled-instead-of-asking)
  - [Claude hasn’t responded](#claude-hasnt-responded)
  - [Repository access errors](#repository-access-errors)
  - [A thread hit the usage limit](#usage-limit-reached)
  - [Additional usage credits are required](#additional-usage-credits-are-required)
  - [Lost contact with your folder](#lost-contact-with-your-folder)
  - [Other messages](#context-limit)
- [Related resources](#related-resources)

Platforms and integrations

# Let Claude coordinate ongoing work with Projects

Copy pageCopy page

Hand Claude a stream of related tasks in one conversation and let it run them as parallel cloud sessions that share repositories, instructions, and memory.

Copy pageCopy page

Projects are in public beta on Pro and Max plans and rolling out gradually. The rollout started with accounts that have used [cloud sessions](claude-code-on-the-web.md) and don’t have existing projects in claude.ai chat or Cowork. Projects aren’t offered on Team or Enterprise plans yet.If you don’t see **Projects** in the sidebar at [claude.ai/code](https://claude.ai/code) or in the Code tab of the [desktop app](../16-Mobile-Desktop/desktop.md), check under **More** there. If it’s missing there too, the rollout hasn’t reached your account yet. You can [join the waitlist](https://claude.com/form/projects), and see [Run agents in parallel](../09-Agents-Patterns/agents.md) for what you can use in the meantime.

A project is one ongoing conversation where Claude coordinates a stream of related work for you. You tell it what needs doing and it starts a thread for each task. Each thread is usually a [cloud session](claude-code-on-the-web.md): Claude Code running in the cloud rather than on your machine. When a task needs something only your computer has, you can ask Claude to [run that thread on your computer](#run-a-thread-on-your-own-computer) instead of in the cloud, through [Remote Control](remote-control.md). Threads run in parallel, and you can check on them and steer them from your phone. Cloud threads keep going after you close your laptop, while a thread on your computer runs only while that computer is awake. Without a project, running several sessions means doing the coordinating yourself: you decide what each one works on, repeat the same background at the start of each, and check back to see which finished or needs an answer. With a project, you instead:

- **Send work to one place**: paste a bug report, a stack trace, or a list of tasks into the conversation whenever one comes up. Claude starts a thread for each piece of work or passes it to the thread already working in that area, and answers quick questions in place.
- **Set context once**: every new thread starts with the project’s instructions, so a rule you state once, such as which branch to target, reaches all of them.
- **Walk away and come back to finished work**: when you come back an hour later or the next morning, the **Overview** pane shows which threads finished, which pull requests are ready for review, and which thread is waiting for your answer.

If you already know the work you want a project to run, go straight to [Create a project](#create-a-project).


[​](#when-to-use-a-project)

When to use a project

A project is worth creating when the work has a goal that outlasts one session and keeps producing tasks. These kinds of work suit a project well:

- **One goal across many repositories**: “Bring every service up to the new lint config.” Claude can run a thread per repository, each with its own pull request, and the [**Overview** pane](#see-what-needs-you-in-overview) shows which ones are ready for review.
- **An area you keep feeding**: the bugs, stack traces, and review requests for one service, pasted into the conversation as they reach you. A pitfall you tell Claude to remember after one fix is in [project memory](#give-a-project-standing-context) for the next.
- **A build or migration bigger than a session**: “Build what `docs/spec.md` describes” or “Move the app off the deprecated ORM.” The work splits into threads that each take a part, decisions you ask Claude to remember early on reach the later cloud threads, and the spec changes and bugs you find during the build go into the same conversation.
- **Work that isn’t code**: a folder of contracts or a support-ticket export you keep coming back to with new questions, such as “find the ten most common integration mistakes in these tickets.” Upload the documents instead of adding a repository, and threads deliver each write-up as a file on the project’s [**Library** tab](#see-what-needs-you-in-overview).

In any of them you can send a batch of tasks, tell Claude to start without asking you to confirm, and walk away. When you’re back, you can find the threads that need you under [**Waiting on you**](#see-what-needs-you-in-overview). You can also ask Claude to put part of the work on a schedule as a [cloud scheduled task](web-scheduled-tasks.md). If one of these is your situation, [create a project](#create-a-project).


[​](#when-something-else-fits-better)

When something else fits better

A project still fits when only some tasks need your machine. Cloud threads work on GitHub repositories and on the files, folders, and Google Drive folders you upload to the project, and for the occasional task that needs a local database or a tool on your computer, you can ask Claude to [run that task’s thread on your computer](#run-a-thread-on-your-own-computer). Something other than a project fits better in these cases:

- **One task that fits in a session**: “Fix the flaky login test.” Start a [cloud session](claude-code-on-the-web.md) yourself.
- **Work where every task needs your machine**: a local database, a device emulator, or an API behind your VPN. Use a local session, or [agent view](../09-Agents-Patterns/agent-view.md) to run several at once. If the work only needs local files, upload them to the project instead.
- **One task that repeats on a schedule with no conversation around it**: “Post a dependency report every Monday.” Create a [cloud scheduled task](web-scheduled-tasks.md) on its own.
- **Several people giving Claude work and steering it together in a Slack channel**: see [Claude Tag](https://claude.com/docs/claude-tag/overview).

A project draws on the same plan limits as your other Claude Code sessions and uses them faster. [Usage and cost](#usage-and-cost) covers what draws on your plan and how to keep it down.


[​](#how-a-project-is-organized)

How a project is organized

A project is one coordinating conversation with Claude plus the threads it starts to do the work. These are its parts:

- **The project conversation**: one long-running session where Claude acts as coordinator. It takes what you send, decides what becomes a thread, and keeps track of every thread it started. It sees what threads report back, not every step they take.
- **Threads**: the workers. Each is a separate session with its own context window that does one piece of work and reports back to the conversation when it finishes. A cloud thread works on its own branch and opens a pull request when the work calls for one.
- **What every cloud thread starts with**:
  - The project’s repositories and files, plus its [instructions and memory](#give-a-project-standing-context)
  - The `CLAUDE.md` in [each of the project’s repositories](#what-threads-pick-up-from-your-repositories), but not the repositories’ skills, `.claude/settings.json`, or `.mcp.json`
  - The [connectors](#get-skills-plugins-connectors-and-tools-into-threads) on your claude.ai account
  - A [cloud environment](#choose-an-environment-for-threads) that sets its network access, environment variables, network secrets, and installed tools
- **The Overview pane**: where you [see all the threads at once](#see-what-needs-you-in-overview) and which of them need you. Its other tabs are **Library** for the files you added and the files threads produced, **Pull requests** for the ones threads opened, and **Scheduled tasks** for scheduled work in the project.

Cloud threads don’t pick up anything from the Claude Code setup on your own machine. [Get skills, plugins, connectors, and tools into threads](#get-skills-plugins-connectors-and-tools-into-threads) covers how to give them what they’d otherwise be missing. Here is how those parts connect, from you through the conversation to the threads doing the work, with **Overview** tracking their state:


[​](#create-a-project)

Create a project

You create and use projects at [claude.ai/code](https://claude.ai/code), in the Code tab of the desktop app, or in the Claude mobile app for [iOS](https://apps.apple.com/us/app/claude-by-anthropic/id6473753684) and [Android](https://play.google.com/store/apps/details?id=com.anthropic.claude). In the browser and the desktop app there are two ways to start a project:

- **From scratch**, when you know the stream of work you want Claude to run: open the **New project** dialog and name it. [Start a new project from scratch](#start-a-new-project-from-scratch) walks through the dialog.
- **From a cloud session that’s already doing the work**: in that session’s sidebar menu, choose **Move to project**, then **Continue as new project**. Claude proposes the project’s setup from what the session was doing. See [Start from an existing cloud session](#start-from-an-existing-cloud-session).

Either way, [check the prerequisites](#check-the-prerequisites) first.


[​](#check-the-prerequisites)

Check the prerequisites

Before you create a project, check your plan, your GitHub setup, and what the work needs to reach:

- **Plan**: you’re on Pro or Max, and **Projects** shows in your sidebar, directly or under **More**. Select **Projects** and check that it offers **New project** or **Get started**.
- **GitHub, if the project will work on code**: your code is on github.com rather than GitHub Enterprise Server, GitLab, or Bitbucket, your connected GitHub account has push access to it, and the Claude GitHub App is installed on it. If you connected GitHub with [`/web-setup`](web-quickstart.md#connect-from-your-terminal), that token lets your other cloud sessions reach a repository but isn’t enough for a project’s cloud threads, which need the Claude GitHub App. [Set up GitHub access](#set-up-github-access) has the steps.
- **Network access, secrets, and tools**: for cloud threads, these come from the project’s [cloud environment](#choose-an-environment-for-threads). The default environment already reaches [common package registries](cloud-environments.md#default-allowed-domains), so check this only if the work needs other domains, a secret, or a tool that isn’t preinstalled. If the work needs an MCP server, check that it shows as connected in your [claude.ai connectors](https://claude.ai/customize/connectors).


[​](#start-a-new-project-from-scratch)

Start a new project from scratch

Starting a project from scratch means opening the **New project** dialog, naming the stream of work, and optionally giving it a goal and the repositories and files it works on. Only the name is required, so you can create the project first and fill in the rest as the work takes shape.

1

Open Projects

At [claude.ai/code](https://claude.ai/code) or in the Code tab of the desktop app, select **Projects** in the left sidebar, or under **More** there. In a browser you can also go straight to [claude.ai/code/projects/browse](https://claude.ai/code/projects/browse). Then select **New project**. If the button reads **Get started** instead, select it and first upgrade or archive the existing claude.ai projects it lists.

2

Fill in the New project dialog

Scope the project to one stream of work you’ll keep adding to, such as everything it takes to keep one API under its latency target. [When to use a project](#when-to-use-a-project) has more examples. Then fill in the dialog’s fields:

- **Name**: how the project appears in the **Projects** list.
- **Goal** (optional): one line of what you’re trying to get done, such as “Hold p95 API latency under 200 ms”. Claude in the conversation works toward it. Without a goal, Claude works from the tasks you send, and you can add a goal later in **Project settings \> General**.
- **Context** (optional): the GitHub repositories this project works on, plus any files, folders, or Google Drive folders threads should read. Click **Add** for each. Add the repositories most tasks need rather than every one the work might touch; [Decide which repositories to add](#decide-which-repositories-to-add) covers the choice, and you can add more later in **Project settings \> Environment**.

Standing rules for how threads should work go in [project instructions](#give-a-project-standing-context), which you set after the project exists.

3

Create the project

Click **Create project**. The project’s conversation opens with a message box at the bottom, where you describe work for Claude.On your first project, Claude takes a turn of its own as soon as the project is created, unless you send a message first. That turn uses your plan. In it, Claude may:

- Start one thread that explores the repository without changing anything and proposes next steps, if the project has a repository it can read.
- Post **Setup recommendations** drawn from your recent cloud sessions: repositories to add, scheduled tasks to create, and threads it could start. Every recommended repository and scheduled task starts switched on. Switch off the ones you don’t want, then click **Update setup** to add the rest, or ignore the recommendations and describe work yourself.

The project is now listed under **Projects** in the sidebar, and its conversation is open. [Your first batch](#your-first-batch) covers what to set up before you send it work.


[​](#start-from-an-existing-cloud-session)

Start from an existing cloud session

If a cloud session you started yourself is doing work that belongs in a project, open its sidebar menu and choose **Move to project**, then pick from the submenu:

- Choose **Continue as new project** to create a new project from the session. The project opens, and Claude reads the session and posts **Setup recommendations** in the project conversation for you to confirm. The original session stays in your session list. If it was in the middle of a turn it keeps running, so stop it yourself if you don’t want both working at once.
- Choose one of your existing projects to bring the session’s work into that project. That project opens, and a message sent on your behalf asks Claude to read the session and pick up where it left off. The original session stays in your session list, unchanged.

A **Set up project** banner can also appear above a cloud session’s message box. If you use it instead of **Continue as new project**, the result is the same, except that the session’s running turn stops once the project opens. A local session doesn’t have these options. To continue its work in a project, describe the work in the project conversation, or push its branch, add that repository to the project, and name the branch in the task.


[​](#set-up-github-access)

Set up GitHub access

Most GitHub setup happens once, not per project. You connect your GitHub account to Claude once, and the Claude GitHub App is installed once per repository, or once for a whole GitHub organization if you give it all repositories. You come back to these steps when you add a repository the Claude GitHub App doesn’t cover yet or one in a GitHub organization that enforces SSO.

1

Connect your GitHub account

If you haven’t used claude.ai/code before, your first visit walks you through connecting GitHub; see [Connect GitHub](web-quickstart.md#connect-github). Otherwise use one of the [GitHub authentication options](claude-code-on-the-web.md#github-authentication-options).

2

Install the Claude GitHub App on the project's repositories

Install the [Claude GitHub App](https://github.com/apps/claude) and grant it the repositories the project will use. On a repository owned by a GitHub organization, only an organization owner can complete the install; if you aren’t one, GitHub sends the owner an install request and the project can’t use the repository until they approve it.

3

Authorize SSO for organizations that enforce it

If a GitHub organization enforces SAML SSO, reconnect GitHub and authorize the Claude app for that organization. Until you do, that organization’s private repositories don’t appear in the **New project** dialog or **Project settings \> Environment**.

When one of these steps is incomplete, the **New project** dialog and the project page name the missing step and link to where you finish it. Finish the step there, then click **Check again** if the dialog offers it. If a repository is still missing from the list afterward, open the Claude GitHub App’s installation on GitHub, at [github.com/settings/installations](https://github.com/settings/installations) for a personal account, and confirm the repository is listed under **Repository access**. For the error messages a thread or the project reports when access is still wrong, see [Repository access errors](#repository-access-errors).


[​](#work-in-a-project)

Work in a project

Give Claude work through the project conversation: tasks one at a time or several at once, plus updates and loose thoughts as they come up. Claude routes each message, and threads do the work and report back.


[​](#your-first-batch)

Your first batch

Before you send a new project a batch of work, set it up so the first threads come back the way you want:

1.  [Write project instructions](#write-project-instructions): the brief every thread starts from, such as which branch to target, how a thread checks its work, and what needs your go-ahead.
2.  Send one small piece of the real work, or start one of the threads Claude suggested if it offered any, and open the thread when it finishes to see how it reports back and what it did on its branch. If it assumed something wrong or couldn’t reach what it needed, [Threads guessed or stalled instead of asking](#threads-guessed-or-stalled-instead-of-asking) covers where to fix that.
3.  Check **Thread model** and **Thread effort** in **Project settings \> General**. A new project runs every thread on Opus at high effort, which draws on your plan fastest; [Choose models and let Claude manage context](#choose-models-and-let-claude-manage-context) covers the alternatives.
4.  Ask Claude to [propose threads before starting them and to run a few at a time](#tune-how-claude-runs-a-project), and drop those limits once a few threads come back the way you want.


[​](#send-work-and-read-results)

Send work and read results

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

- A quick question usually gets an answer in the conversation.
- 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.
- Several unrelated tasks in one message become separate threads.

If 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. A 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 on the **Library** tab in **Overview**. Sometimes 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.


[​](#review-a-thread’s-pull-request)

Review a thread’s pull request

When a cloud thread changes code, this is what it does unless you tell it otherwise:

- **Branch**: works on a new branch, started from the repository’s default branch.
- **Pull request**: opens one when you ask, and can open one on its own for a bug fix or another concrete change.
- **After it opens**: watches the pull request with [auto-fix](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.

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

- **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.
- **Review PR** opens the pull request on GitHub.
- **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.

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


[​](#see-what-needs-you-in-overview)

See what needs you in Overview

The **Overview** pane beside the conversation tracks the project’s threads. It’s already open the first time you open a new project. The **Overview** button in the project header closes and reopens it, and shows a dot when a thread is waiting on you. In the desktop app, you also get a desktop notification when Claude posts in the conversation, a thread hits an error, or a thread needs your input, so you don’t have to keep the project open to find out. To also get one each time a thread finishes a turn, or to turn them off for a project, choose **Notifications** in the project’s sidebar menu. These notifications are desktop-only: in a browser, check the dot on the **Overview** button. The pane’s **Threads** tab groups threads by state:

| Group                | What’s in it                                                                                                                                                                                                           |
|:---------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Ready for review** | Threads whose pull request is open and awaiting review                                                                                                                                                                 |
| **Waiting on you**   | Threads that need your reply or approval, or that failed                                                                                                                                                               |
| **Working**          | Threads still running                                                                                                                                                                                                  |
| **Landing**          | Threads whose pull request is approved or queued to merge                                                                                                                                                              |
| **Idle**             | Threads that finished and aren’t waiting on anything                                                                                                                                                                   |
| **Resolved**         | Threads marked done: by you from the thread’s menu, by Claude once you’ve taken the last step, such as merging its pull request, or automatically after a week with no activity. You can reopen one from the same menu |

The pane’s other tabs are:

- **Library**: the files and folders you added and the files threads produced
- **Pull requests**: shown once threads have opened any
- **Scheduled tasks**: the [cloud scheduled tasks](web-scheduled-tasks.md) Claude set up from this project


[​](#open-a-thread-when-you-need-control)

Open a thread when you need control

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

- Read what Claude did, step by step.
- 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.
- Answer a permission prompt the thread is waiting on.
- Interrupt the thread with **Stop**, which replaces the send button while the thread is working, or by pressing Esc.


[​](#choose-models-and-let-claude-manage-context)

Choose models and let Claude manage context

Set models and effort in **Project settings \> General**. A new project runs Opus everywhere, with high [effort](model-config.md#adjust-effort-level) for threads and low effort for the conversation:

- **Thread model** and **Thread effort** apply to threads. To use a different model for one task, ask for it in the task; for a thread already running, use that thread’s model picker.
- **Coordinator model** and **Coordinator effort** apply to Claude in the project conversation.

You don’t manage context windows in a project. Threads compact automatically, and the conversation works from recent messages, recent threads, and project memory rather than its full history, so it keeps going for as long as the project runs. Put anything that must never be dropped in [project memory](#give-a-project-standing-context). If one thread outgrows its context, it shows [Claude ran out of context on this turn](#context-limit).


[​](#tune-how-claude-runs-a-project)

Tune how Claude runs a project

Tell Claude in the conversation how many threads to run at once, when to post updates, and when to open pull requests. If Claude is coordinating in a way you don’t want, say so. For example, you can say:

- “Propose threads and wait for my go-ahead before starting them” or “Start these now without asking me to confirm”
- “Run at most two threads at a time” or “Reuse an existing thread for follow-ups in the same area”
- “Post shorter updates” or “Only post when something finishes or is blocked”
- “Give me a status update on every thread”
- “Do this task with a smaller model”
- “Don’t open a pull request until I’ve seen the plan”
- “Tell me what’s wrong in these repositories and don’t fix anything yet”, when you want to go through the findings before any of them becomes a thread
- “Answer that here instead of starting a thread”, when Claude starts a thread for something you meant as a quick question

Claude saves preferences like these to [project memory](#give-a-project-standing-context) on its own and follows them in later cloud threads. They’re instructions Claude keeps to, not enforced settings, so a thread limit you give this way isn’t a hard cap. Add one to project instructions when you want it worded exactly and applied to every thread from the start.


[​](#unblock-a-thread-waiting-on-approval)

Unblock a thread waiting on approval

Threads run in [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) when the thread’s model supports it, so most tool calls run without asking you. When a thread needs your approval, the prompt is inside that thread and the thread waits until you answer it there. Telling Claude in the project conversation to go ahead doesn’t reach it. Each approval covers that prompt, or the rest of that thread if you choose the broader option. Cloud threads don’t read [permission rules](permissions.md) from a repository’s `.claude/settings.json`, so you rely on auto mode and on the approvals you give inside each thread.


[​](#run-a-thread-on-your-own-computer)

Run a thread on your own computer

When a task needs something only your computer has, such as a local database, a device emulator, or an API behind your VPN, ask Claude to run the thread for that task on your computer instead of in the cloud. When you ask in the project conversation, the thread is a Claude Code session in a folder on your machine, connected through [Remote Control](remote-control.md). The project’s other threads keep running in the cloud. Compared with a cloud thread, a thread on your computer:

- Works with the files, tools, MCP servers, and Claude Code settings on that machine, including its hooks and permission rules, instead of the project’s cloud environment
- Starts with the project’s instructions, but not with its memory files loaded
- Runs only while that computer is awake with Remote Control turned on

1

Connect the folder

On the computer that has the folder the task needs, make it available through Remote Control in one of two ways. Both need Claude Code v2.1.280 or later on that computer.

- **In the Claude desktop app**: open **Settings \> Claude Code**, turn on **Use this computer from your phone and claude.ai**, and add the folder to the list under that switch. Threads can run on this computer while the app is open.
- **In a terminal**: run `claude remote-control` in the folder and leave it running. In a git repository, add `--spawn worktree` to give each thread there its own [worktree](worktrees.md) instead of the folder itself.

2

Ask for the task with Work locally

In the project conversation, choose **Work locally** from the **+** menu beside the message box, which tags your message **Local**, and write what you want done. Saying in the message that the task should run on your computer works too.

3

Allow it on the card

Claude answers with an **Allow Claude to work in a folder on your device** card. Pick the folder if you connected several. Two threads working in one folder at the same time can overwrite each other’s changes, so if the folder is a git repository, you can turn on **Worktree** in the folder’s options to give this thread its own worktree instead. Then click **Allow once**.

The thread runs in [auto mode](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. While 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. [Lost contact with your folder](#lost-contact-with-your-folder) covers getting it going again. In the desktop app, turn on **Keep this computer awake for Remote Control** under **Settings \> Claude Code** to stop the computer from sleeping on its own. A project can’t run a thread on your computer while [**Require trusted devices**](remote-control.md#trusted-devices) is on for your account.


[​](#give-a-project-standing-context)

Give a project standing context

Project memory, project instructions, and the project’s repositories, files, and environment carry context across threads. You set each one once.

| Context                              | What it carries                                                                                                                                                                                                       | How you set it                                                                                                                                                                                                                             |
|:-------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Project memory                       | Notes Claude keeps about the project, such as requirements, decisions, and pitfalls, stored as files. Every cloud thread reads the index file `MEMORY.md` when it starts and opens the other files when it needs them | Ask Claude in the project conversation or any cloud thread to remember a requirement, a decision, or a pitfall, or to forget one. Read, edit, and delete the files in **Project settings \> Memory**                                       |
| Project instructions                 | Text sent to each new thread and to Claude in the project conversation, up to 16,000 characters. [Write project instructions](#write-project-instructions) covers what to put in it                                   | **Project settings \> Memory \> Project instructions**, or ask Claude to change the instructions                                                                                                                                           |
| Repositories, files, and environment | The repositories every cloud thread clones, the folders and files it can read under `/mnt/project-files`, and the cloud environment it runs in                                                                        | Repositories and environment in **Project settings \> Environment**, or ask Claude in the conversation to add a repository to the project. [Files and folders](#add-files-and-folders) from **Add** on the **Library** tab in **Overview** |

**Project settings \> Memory** lists these files under **Auto memory**, because Claude writes them itself as it works in the project. They’re separate from the [auto memory](memory.md) Claude Code keeps on your machine, even though both use a `MEMORY.md` index. Project memory is also separate from the `CLAUDE.md` files in the project’s repositories. Each cloud thread still reads those `CLAUDE.md` files from its clone when it starts, so put instructions about a repository in its `CLAUDE.md` and notes about the project in project memory.


[​](#write-project-instructions)

Write project instructions

Project instructions are the brief every new thread starts from. Click the gear icon in the project header to open **Project settings**, then go to **Memory \> Project instructions**. A useful brief covers:

- What the project is for
- Where the work happens: which repositories, which branch to start from, how to name pull requests
- How a thread checks its own work before calling it done
- What to do when something it needs is missing
- What needs your go-ahead first

For example:

```python
This project holds p95 latency for the payments API under 200 ms: profiling, query and caching fixes, and the dependency upgrades that come with them, in the payments-api repository.

- Branch from main and open one draft pull request per thread.
- Before you call work done, run `make test` and `make lint` and paste the summary lines in your final message.
- If you can't reach something you need, such as a repository, a secret, an API, or a connector, say exactly what's missing in your first message and stop. Don't substitute, mock, or guess.
- Don't merge, force-push, or change CI configuration without asking me in the thread.
```

Rules about one repository, such as its build commands, belong in that repository’s `CLAUDE.md`, which every cloud thread reads when the repository is part of the project. Once work is underway, when you correct a thread, also tell Claude to remember the correction: it goes into [project memory](#give-a-project-standing-context) and later cloud threads start with it.


[​](#decide-which-repositories-to-add)

Decide which repositories to add

The repositories you add to a project come with their code and `CLAUDE.md` in every cloud thread, but [not their skills, `.claude/settings.json`, or `.mcp.json`](#what-threads-pick-up-from-your-repositories). Repositories you don’t add are still within reach: a cloud thread can add one to itself when its task needs it. Most projects use both:

- **Add it to the project**, in the **New project** dialog, in **Project settings \> Environment**, or by asking Claude in the conversation to add it to the project. Every cloud thread from then on clones it and starts with its `CLAUDE.md` loaded, whether or not the task touches it.
- **Leave it off and let threads add it when needed.** A cloud thread whose task needs a repository the project doesn’t have can add it to itself, and a note in the thread says it was added to this thread only. The clone happens partway through the task, so that repository’s `CLAUDE.md` wasn’t there when the thread started. The next thread starts without it. A repository added this way needs the same [prerequisites](#check-the-prerequisites) as a project repository: the Claude GitHub App installed on it and push access from your GitHub account.

A project doesn’t need a repository at all. Its cloud threads can still research, write documents, and write and run code in their own sandbox, and they deliver files to the **Library** tab. Any of its cloud threads can still add a repository to itself when a task calls for one. Once the project has repositories, Claude can only add repositories from a GitHub owner the project already uses, whether it adds one to the project or a thread adds one to itself. To bring in a repository from a different owner, add it to the project yourself in **Project settings \> Environment**. For a project that spans many repositories, such as one feature with server, web, mobile, and desktop code, add the one or two repositories nearly every task touches and name the others in [project instructions](#write-project-instructions) so Claude knows where the rest of the code lives. Cloud threads then start small and pull in the other repositories only for the tasks that need them.


[​](#add-files-and-folders)

Add files and folders

Add the files and folders you want threads to read in the **New project** dialog’s **Context** field, or afterward with **Add** on the **Library** tab in **Overview**. These limits apply to what you add:

- **Library tab**: up to 100 files and 2 GB in one pick, with a single file up to 480 MB.
- **New project dialog**: files over 30 MB are skipped, so add larger files from the **Library** tab after you create the project.
- **Folders**: when you add a folder from either place, the project receives a copy of its first 100 files up to 200 MB, without any files over 30 MB, hidden files, or `node_modules`. A project holds up to 10 folders and Google Drive folders combined, and single files don’t count toward that limit.
- **Changes after upload**: uploads are copies, so a change you make on your computer afterward doesn’t reach the project until you upload the file again and choose **Replace** when asked about the existing name.


[​](#what-threads-pick-up-from-your-repositories)

What threads pick up from your repositories

Cloud threads load each repository’s `CLAUDE.md` instructions but not its skills, `.mcp.json` servers, or `.claude/settings.json`, whether the project has one repository or several.

| In each repository                                                            | In a cloud thread                                                                                                                                                                                                           |
|:------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `CLAUDE.md`, `.claude/CLAUDE.md`, and `.claude/rules/` at the repository root | Loaded from every repository when the thread starts. `CLAUDE.md` files in subdirectories and [path-specific rules](memory.md#path-specific-rules) aren’t loaded                                                       |
| Skills under `.claude/skills/`                                                | Not loaded. Enable the skill for your claude.ai account instead, as [Get skills, plugins, connectors, and tools into threads](#get-skills-plugins-connectors-and-tools-into-threads) describes                              |
| Agents and commands under `.claude/`                                          | Not loaded. To use them, [run the thread on your own computer](#run-a-thread-on-your-own-computer)                                                                                                                          |
| MCP servers in `.mcp.json`                                                    | Not loaded. Use the connectors on your claude.ai account instead, as [Get skills, plugins, connectors, and tools into threads](#get-skills-plugins-connectors-and-tools-into-threads) describes                             |
| Plugins enabled in `.claude/settings.json`                                    | Not loaded. Add the plugin in **Project settings \> Plugins** instead                                                                                                                                                       |
| Permission rules in `.claude/settings.json`                                   | Not applied. Approve tool calls inside the thread, as [Unblock a thread waiting on approval](#unblock-a-thread-waiting-on-approval) describes, or [run the thread on your own computer](#run-a-thread-on-your-own-computer) |
| Hooks in `.claude/settings.json`                                              | Not run. To use your hooks, [run the thread on your own computer](#run-a-thread-on-your-own-computer)                                                                                                                       |
| `env` in `.claude/settings.json`                                              | Not applied. Set environment variables in the [cloud environment](#choose-an-environment-for-threads)                                                                                                                       |


[​](#choose-an-environment-for-threads)

Choose an environment for threads

Every new cloud thread starts in the project’s [cloud environment](cloud-environments.md). The environment sets which domains threads can reach, which environment variables they have, which network secrets are added to their requests, and what the setup script installs before Claude starts. Cloud threads use a default Anthropic-hosted environment until you pick one in **Project settings \> Environment**. If cloud threads need to reach an internal API or a private package registry, or need a token your machine normally holds, change the environment rather than the project: see [Network access](cloud-environments.md#network-access), [Add network secrets](cloud-environments.md#add-network-secrets), and [Setup scripts](cloud-environments.md#setup-scripts).


[​](#get-skills-plugins-connectors-and-tools-into-threads)

Get skills, plugins, connectors, and tools into threads

Cloud threads don’t have the skills, MCP servers, plugins, and tools installed only on your machine. A thread that Claude runs on your machine through [Remote Control](remote-control.md) uses what’s installed there. To make each of these available to cloud threads:

- Skills: enable them for your claude.ai account, and cloud threads load the [skills you enable there](../08-Plugins-Skills/skills.md#skills-in-cowork-and-cloud-sessions), apart from [some threads in a self-hosted environment](../13-Enterprise-Admin/self-hosted-environments-configuration.md#how-each-session%E2%80%99s-config-is-assembled). Skills committed to a repository’s `.claude/skills/` don’t load in cloud threads.
- Plugins: add them in **Project settings \> Plugins**; they load into each new cloud thread. Plugins that a repository declares in its `.claude/settings.json` [don’t load in cloud threads](cloud-environments.md#what-carries-over-from-your-setup).
- MCP servers: cloud threads get their MCP tools from the connectors on your claude.ai account, which are MCP servers you connect once at [claude.ai/customize/connectors](https://claude.ai/customize/connectors). Every cloud thread can use all of them with no per-project setup. The project conversation itself has no connectors, so send work that needs one as a task for a cloud thread. [How connectors reach Claude Code](../06-MCP-Tools/General/mcp.md#how-connectors-reach-claude-code) lists the rules for cloud sessions and the settings that turn connectors off.
- Command-line tools and packages: install them in the environment’s [setup script](cloud-environments.md#setup-scripts).

To see which connectors a running cloud thread has at claude.ai/code, open the thread and select **Connectors** from the **+** menu beside its message box. Turning a connector off there removes it from that thread and saves that as your account default, so new threads and claude.ai chats start without it until you turn it back on. A cloud thread picks up a connector you add or reconnect after the next message you send it.


[​](#project-settings-reference)

Project settings reference

You change project settings at claude.ai/code or in the desktop app, not in `settings.json`. Open **Project settings** from **Settings** in the project’s sidebar menu or from the gear icon in the project header. Settings save as you change them; a text field you’re editing, such as the goal or instructions, shows **Save changes** and **Discard** until you leave it. Changes to instructions, repositories, plugins, and environment in **Project settings** reach new threads, not threads already running.

| Setting                      | Section     | What it controls                                                                                                    |
|:-----------------------------|:------------|:--------------------------------------------------------------------------------------------------------------------|
| Name, icon, and goal         | General     | The project’s name and icon in the sidebar, and its one-line goal                                                   |
| Coordinator model and effort | General     | The model and [effort level](model-config.md#adjust-effort-level) for Claude in the project conversation      |
| Thread model and effort      | General     | The model and effort level for threads                                                                              |
| Project instructions         | Memory      | [Standing rules](#give-a-project-standing-context) every new thread receives                                        |
| Project repositories         | Environment | The repositories new cloud threads clone                                                                            |
| Cloud environment            | Environment | The [cloud environment](#choose-an-environment-for-threads) new cloud threads run in                                |
| Plugins                      | Plugins     | The plugins that load into each new cloud thread                                                                    |
| Usage                        | Usage       | [Token use](#usage-and-cost) by thread and by model                                                                 |
| Memory                       | Memory      | The project’s [memory files](#give-a-project-standing-context)                                                      |
| Restart Claude               | General     | Restarts the project conversation when [Claude stops responding there](#claude-hasnt-responded)                     |
| Pause, Archive, Delete       | General     | Stops, hides, or removes the project; see [Pause, archive, or delete a project](#pause-archive-or-delete-a-project) |


[​](#pause-archive-or-delete-a-project)

Pause, archive, or delete a project

All three controls are at the bottom of **Project settings \> General**:

- **Pause**: stops everything at once. Every running thread and the conversation are interrupted, no new threads start, scheduled tasks don’t run, and the project doesn’t accept messages until you resume it. Click **Resume** in the same place or on the banner above the project’s message box; a paused thread continues when you send it a message after that.
- **Archive**: hides the project from the sidebar and archives its threads, which stops any thread that was running or watching a pull request. Scheduled tasks in the project don’t run while it’s archived. To bring the project back, open it from the Projects page and click **Unarchive**. Its threads stay archived until you unarchive them individually from the session list.
- **Delete**: permanently removes the project along with its threads, its memory, and its files, and turns off the project’s scheduled tasks. This can’t be undone. Branches and pull requests the threads pushed to GitHub aren’t affected.


[​](#usage-and-cost)

Usage and cost

Project usage counts against the same [plan limits](errors.md#youve-hit-your-session-limit) as your other Claude Code sessions, and a project can’t spend past those limits on its own. A thread that reaches your plan’s limit waits and continues on its own when the limit resets, so work you left running starts using your next usage window without a message from you. [A thread hit the usage limit](#usage-limit-reached) covers what you see, how to stop it, and the one case that doesn’t wait. Work goes past your plan’s limits only if you have turned on [usage credits](../17-Billing-Plans/costs.md#add-usage-credits-to-your-subscription) for your account. A thread can’t turn them on for you.


[​](#what-draws-on-your-plan)

What draws on your plan

A project uses your limits faster than a single session does, and on a Pro plan in particular you should expect to reach your limit sooner on days you run one. These are the parts of a project that use your plan:

- **Running threads**: each is a full session, and several can run at once. There’s no fixed number; Claude starts as many as the work calls for, and a limit you [ask for](#tune-how-claude-runs-a-project) is a preference rather than a cap. The enforced limit is 200 new threads per day across your projects.
- **The conversation**: Claude uses tokens of its own reading what threads report and deciding what to do next.
- **Threads watching a pull request**: an idle thread wakes up and uses your plan again when CI fails or a review comment arrives on its pull request. To stop that, ask in the thread for it to stop watching the pull request.

A project with no running threads, no watched pull requests, and no new messages doesn’t use your plan while it sits idle, and neither does an archived project.


[​](#see-and-reduce-a-project’s-usage)

See and reduce a project’s usage

Open **Usage** in **Project settings** to see token use by thread and by model, and how much went to the project conversation. To bring it down:

- A follow-up routed to a thread that has been idle longer than the [cache lifetime](prompt-caching.md#cache-lifetime), an hour on Pro and Max within your plan’s limits, re-reads that thread’s whole conversation before doing anything. For new work, asking Claude to start a fresh thread can use less than reviving a large old one.
- For work that doesn’t need the largest model, [choose a smaller model or a lower effort level](#choose-models-and-let-claude-manage-context) for threads, the conversation, or both.
- Ask Claude in the project conversation to run fewer threads at a time, or to answer small questions itself instead of starting a thread.


[​](#how-projects-relate-to-other-claude-code-features)

How projects relate to other Claude Code features

Several Claude Code features let more than one session work at the same time, so running work in parallel is not by itself what a project is for. In a project, Claude starts and tracks the sessions instead of you, and each one starts from the same instructions. This is how each neighboring feature connects to a project:

- **Claude Tag**: [Claude Tag](https://claude.com/docs/claude-tag/overview) is Claude in your team’s Slack channels, on Team and Enterprise plans. Anyone in a channel can give it work, everyone in the channel sees and steers it, and it uses connections an admin set up for that channel. A project is yours alone: you’re the only one who sends it work or sees its threads, it uses your own GitHub access and connectors, and it’s on Pro and Max. [How Claude Tag differs from Cowork and Claude Code](https://claude.com/docs/claude-tag/concepts/how-it-works#how-claude-tag-differs-from-cowork-and-claude-code) has the side-by-side.
- **Cloud sessions**: every thread is a [cloud session](claude-code-on-the-web.md) unless you ask Claude to run it on your machine. Either way, Claude starts and tracks it instead of you. You can also bring the work of a cloud session you started yourself into a project: choose [**Move to project**](#start-from-an-existing-cloud-session) in that session’s sidebar menu.
- **Scheduled tasks**: when you ask for scheduled work in a project, Claude creates a [cloud scheduled task](web-scheduled-tasks.md) that runs as threads in that project and appears on its **Scheduled tasks** tab. Scheduled tasks you create outside a project keep working on their own.
- **Remote Control**: [Remote Control](remote-control.md) connects claude.ai to a Claude Code session running on your machine. When you ask Claude in a project to run a thread on your computer, the project [uses Remote Control to do it](#run-a-thread-on-your-own-computer).
- **Local sessions and agent view**: a session you start yourself in your terminal, IDE, or the desktop app’s local environment can’t be added to a project. [Agent view](../09-Agents-Patterns/agent-view.md) is a screen for tracking several local sessions side by side, and you still start each one and give it its task yourself.
- **Worktrees**: a [worktree](worktrees.md) gives each local session its own working copy of a repository. Cloud threads don’t need them: each clones its repositories into its own cloud sandbox and works on its own branch.
- **Agent teams**: an [agent team](../09-Agents-Patterns/agent-teams.md) is one session that starts teammate sessions for a single task, on your machine or inside a cloud session, and ends with that task.
- **Subagents**: a [subagent](../09-Agents-Patterns/sub-agents.md) runs inside one session, does a side task in its own context window, and returns a summary to that session. A project’s threads are whole sessions that Claude starts and that report back to the project conversation, and a thread can still use subagents for its own side tasks.
- **Projects in claude.ai chat and Cowork**: the [earlier Projects experience](../15-Claude-AI-Features/what-are-projects.md), which groups conversations and reference files without threads or a coordinator. Those projects keep working as they do today until the redesigned experience reaches them.

[Run agents in parallel](../09-Agents-Patterns/agents.md) compares these options side by side.


[​](#limitations)

Limitations

- Projects are available at claude.ai/code, in the desktop app, and in the Claude mobile app, not in the terminal CLI, the VS Code extension, or the JetBrains plugin, and not through Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry.
- Project threads are [cloud sessions](claude-code-on-the-web.md), or sessions on your own machine through [Remote Control](remote-control.md), with Anthropic as the model provider in both cases. [Security](../13-Enterprise-Admin/security.md) and [Data usage](../13-Enterprise-Admin/data-usage.md) cover how cloud sessions are isolated and what’s retained, and [Connection and security](remote-control.md#connection-and-security) covers how a thread on your machine connects and what’s stored.
- You can’t add a session you started yourself on your machine to a project. A project reaches your machine only by [running a thread there through Remote Control](#run-a-thread-on-your-own-computer), and that section lists what it needs.
- A cloud thread’s sandbox pauses between turns and resumes when the thread continues. If the sandbox can’t be resumed, the thread continues from a fresh clone, so uncommitted changes can be lost. On long tasks, ask Claude to commit and push work in progress.
- A project belongs to one user. You can’t share a project or its threads with another user, and thread transcripts don’t have the share option other cloud sessions have. There are no organization-level controls for projects during the beta.
- A thread belongs to the one project that started it. You can’t move or copy a thread to another project, or move it out to stand alone. [**Move to project**](#start-from-an-existing-cloud-session) goes the other way only: it brings a cloud session’s work into a project. You can’t merge two projects into one.


[​](#troubleshooting)

Troubleshooting

For the GitHub setup prompts in the **New project** dialog, see [Set up GitHub access](#set-up-github-access).


[​](#a-thread-looks-stuck)

A thread looks stuck

Claude doesn’t post each step a thread takes, so a thread that shows as running with no new messages in the project conversation is usually still working. A new cloud thread also provisions its [cloud environment](cloud-environments.md) before Claude begins, so its first update takes a moment. Open the thread to read its transcript. If the thread is waiting on a permission prompt, answer it there.


[​](#threads-guessed-or-stalled-instead-of-asking)

Threads guessed or stalled instead of asking

When several threads come back having assumed something wrong, worked around missing access, or stopped with “blocked”, the cause is usually the same gap in the project’s setup rather than a problem with each task. Sort out which threads are sound before you fix anything:

1.  Ask Claude in the conversation: “For every open thread, list what you asked it to do, what it assumed or couldn’t reach, and what it’s waiting on.” Claude reads each thread and answers in the conversation.
2.  For threads that started from a wrong assumption, open the thread from **Overview** and mark it resolved from its menu, or tell it what to do instead in its message box. Its branch and any pull request stay on GitHub until you delete them.
3.  Fix the gap once, in [project instructions](#give-a-project-standing-context) or the [environment](#choose-an-environment-for-threads), then send one thread before sending the rest of the work again as new threads.


[​](#claude-hasnt-responded)

Claude hasn’t responded

The project conversation shows a “Claude hasn’t responded” banner when Claude is running but its replies aren’t reaching the project. Click **Restart Claude** on the banner, or go to **Project settings \> General** and click **Restart** in the **Restart Claude** row. Claude reconnects to the conversation; any reply it was in the middle of writing is lost, and threads aren’t affected.


[​](#repository-access-errors)

Repository access errors

Three messages mean a thread or the project can’t reach one of its repositories. A project’s cloud threads need the [GitHub prerequisites](#check-the-prerequisites) even when your other cloud sessions clone the same repository without trouble.

- **“Couldn’t start the session — Claude doesn’t have GitHub access to this project’s repository”**, reported before the thread starts, when the Claude GitHub App isn’t installed on that repository, is suspended, or isn’t linked to the GitHub account you connected.
- **“Unable to access your repository”**, reported by a thread when its clone fails: GitHub rejected the clone, the repository wasn’t found under the name the project has, or the branch the thread was asked to start from doesn’t exist.
- **“Claude can’t access” a repository**, shown when you save repositories in the **New project** dialog or **Project settings**. The message continues with an install link and a reconnect link. Use the install link if the Claude GitHub App isn’t on that repository, and the reconnect link if it is, since the GitHub App can be installed on GitHub without being linked to the account you connected to Claude. If the message says the GitHub App is suspended or doesn’t include this repository, follow its link to GitHub to fix that.

To fix any of them, click the button the message offers, such as **Install GitHub App** or **Select repositories on GitHub**, then **Check again**. When the block is on the GitHub organization’s side, such as an owner who hasn’t approved the app or an IP allow list that excludes Claude, the message shows a **See how to fix** link instead. If there’s no button, follow [Set up GitHub access](#set-up-github-access), then send another message to retry.


[​](#usage-limit-reached)

A thread hit the usage limit

When a thread or the project conversation reaches your plan’s five-hour or weekly limit, it keeps retrying on its own and continues when the limit resets. A thread that a scheduled task started doesn’t wait: its turn stops with a limit error, and you send it a message after the limit resets. While a thread waits, it shows **Service is busy** with “Claude is still retrying and will continue automatically.” You don’t need to do anything for the work to continue. If you’d rather it not use your next usage window, click **Stop** in the thread, or [pause the project](#pause-archive-or-delete-a-project) to hold every thread. [Usage limit errors](errors.md#youve-hit-your-session-limit) explain the limits and when they reset.


[​](#additional-usage-credits-are-required)

Additional usage credits are required

A thread or the project conversation made a request your plan covers only with usage credits, such as one to a model or context size your plan doesn’t include, and usage credits aren’t turned on for your account. [Add usage credits to your subscription](../17-Billing-Plans/costs.md#add-usage-credits-to-your-subscription) covers who can turn them on or buy them on each plan. Once credits are available, send another message to retry.


[​](#lost-contact-with-your-folder)

Lost contact with your folder

A thread running on your computer shows this when the Claude Code session there stopped responding, usually because the computer went to sleep or the desktop app or `claude remote-control` quit. Wake the computer, and if the desktop app or `claude remote-control` is no longer running there, start it again: reopen the app and confirm **Use this computer from your phone and claude.ai** is still on under **Settings \> Claude Code**, or run `claude remote-control` again in the same folder.


[​](#context-limit)

Other messages

These messages name their own cause. The table gives the next step for each.

| Message                                                                                        | What to do                                                                                                                                                                                                                |
|:-----------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ”Unable to connect to repository” with “Claude couldn’t reach GitHub to fetch your repository” | Wait a moment, then send another message to retry                                                                                                                                                                         |
| ”Unable to connect to repository” with “Claude couldn’t access your repository or environment” | Your GitHub account needs push access to the repository, and the environment must still exist. Check both in **Project settings \> Environment**, then retry                                                              |
| ”Couldn’t show the setup proposal”                                                             | The app you have open is older than the **Setup recommendations** Claude sent. Refresh the page or restart the desktop app, or ask Claude to propose the setup again                                                      |
| ”The project’s environment was removed”                                                        | Choose a different environment in **Project settings \> Environment**; the change applies to new threads                                                                                                                  |
| ”Setup script failed”                                                                          | Click **Edit setup script** on the error, fix the script in the environment, then send another message. [Setup script failed](web-quickstart.md#setup-script-failed) lists common causes                            |
| ”Claude ran out of context on this turn”                                                       | The thread filled its context window. If the message says the thread continues in a fresh session, it carries on by itself; otherwise ask Claude in the project conversation to start a new thread for the remaining work |
| ”Couldn’t start in” followed by your folder’s name                                             | You allowed a thread to run on your computer, but the session couldn’t start there. When a line under the message gives the reason, fix that, then ask Claude to run the task again                                       |
| ”Claude is out of date on your device”                                                         | The computer you picked to run a thread has a Claude Code version older than v2.1.280. Update Claude Code there, or update the desktop app if that’s what connects the folder, then ask Claude to run the task again      |
| ”Reached the turn limit”                                                                       | The thread reached the cap on agentic turns that [`CLAUDE_CODE_MAX_TURNS`](env-vars.md) sets. Send another message to continue, or raise or remove that variable where it’s set                                     |


[​](#related-resources)

Related resources

- [Use Claude Code in the cloud](claude-code-on-the-web.md): how the cloud sessions behind each cloud thread work, including GitHub access options and auto-fix on pull requests
- [Configure cloud environments](cloud-environments.md): change what cloud threads can reach on the network, give them environment variables and network secrets, and install tools with a setup script
- [Automate work with scheduled tasks](web-scheduled-tasks.md): schedules, triggers, and management for scheduled tasks, including the ones Claude creates from a project
- [Manage multiple agents with agent view](../09-Agents-Patterns/agent-view.md): run and track several sessions on your own machine when the work needs tools or services only your machine can reach
- [Projects redesigned: from folder to conversation](https://claude.com/blog/projects-redesigned): the launch announcement, with the thinking behind making a project a conversation with Claude

---

## Scan your codebase for vulnerabilities - Claude Code Docs

Source: https://code.claude.com/docs/en/claude-security
Path: 02-Claude-Code-CLI/claude-security.md

## On this page

- [Prerequisites](#prerequisites)
- [Models and providers](#models-and-providers)
- [Install the plugin](#install-the-plugin)
  - [Uninstall the plugin](#uninstall-the-plugin)
- [Scan and fix your codebase](#scan-and-fix-your-codebase)
  - [Scan only your changes](#scan-only-your-changes)
  - [Scope large repositories](#scope-large-repositories)
  - [Read the scan results](#read-the-scan-results)
- [Fix findings](#fix-findings)
  - [Patches are never applied automatically](#patches-are-never-applied-automatically)
- [How the plugin fits with other security tools](#how-the-plugin-fits-with-other-security-tools)
- [Troubleshooting](#troubleshooting)
- [Related resources](#related-resources)

Security scans

# Scan your codebase for vulnerabilities

Copy pageCopy page

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

Copy pageCopy page

The Claude Security plugin runs a multi-agent vulnerability scan of your codebase inside a Claude Code session. A team of Claude agents maps your architecture, builds a threat model, hunts for vulnerabilities, and independently reviews every finding before writing the report. Use the plugin to scan a whole repository or [only a set of changes](#scan-only-your-changes), such as a branch’s diff, a pull request’s diff, or a single commit, then turn the findings you choose into patches that you review and apply yourself. The plugin runs locally in your session, uses [whichever models you have access to in Claude Code](#models-and-providers), and each scan counts toward your [usage](../17-Billing-Plans/costs.md). If you want a managed service that monitors your repositories, or want to run scans on [Claude Mythos](../20-Models/about-claude-models-introducing-claude-fable-5-and-claude-mythos-5.md), see the [Claude Security](../15-Claude-AI-Features/product-claude-security.md) product, available on the Enterprise plan. The plugin is also distinct from the review tools already in Claude Code: the [security guidance plugin](security-guidance.md) reviews code as Claude writes it, [`/security-review`](commands.md#all-commands) runs a single pass over your branch, and [Code Review](code-review.md) reviews pull requests. For how the layers stack, see [How the plugin fits with other security tools](#how-the-plugin-fits-with-other-security-tools).


[​](#prerequisites)

Prerequisites

To run the plugin, you need:

- A paid plan, Anthropic API access, or a [third-party provider](#models-and-providers), for the [dynamic workflows](workflows.md) the scan uses to orchestrate its agents. On Pro, turn them on from the Dynamic workflows row in `/config`.
- Python 3.9 or later available on your `PATH` as `python3`. Check with `python3 --version`. The plugin’s tooling uses only the Python standard library, so nothing is installed.
- Linux, macOS, or Windows.
- Git, for change scans and for turning findings into patches; those jobs don’t support other version control systems. A full scan works in any directory, with or without version control.


[​](#models-and-providers)

Models and providers

A scan runs inside your Claude Code session. The plugin makes no model calls of its own, so there’s no separate API key or provider setting to configure.

- **Model**: the agents that hunt for vulnerabilities, verify findings, and write and review patches run on [your session’s model](../09-Agents-Patterns/sub-agents.md#choose-a-model). To change it, run [`/model`](model-config.md#setting-your-model) in your session before you start a scan. A few supporting steps, such as mapping the repository, use the [`sonnet` alias](model-config.md#model-aliases) instead.
- **Provider**: scans run on a paid plan, with Anthropic API access, or on a [third-party provider](third-party-integrations.md) such as [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), or [Microsoft Foundry](microsoft-foundry.md).

On a third-party provider, the `sonnet` alias can resolve to a different version than it does on the Anthropic API. If your account can’t use that version, [pin your model versions](model-config.md#pin-models-for-third-party-deployments), including `ANTHROPIC_DEFAULT_SONNET_MODEL`. [Automatic model fallback](model-config.md#automatic-model-fallback) re-runs a request that a model’s safeguards flag. On Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry, the request can end with a refusal message instead, depending on [how your deployment is set up](model-config.md#enable-fallback-on-bedrock-agent-platform-and-foundry).


[​](#install-the-plugin)

Install the plugin

In the VS Code extension or the desktop app, install it by following [Install a plugin](../08-Plugins-Skills/discover-plugins.md#install-a-plugin). In a terminal, start Claude Code by running `claude`, then enter this at its prompt to install from the [official Anthropic marketplace](../08-Plugins-Skills/plugins-anthropic-marketplaces.md):

```python
/plugin install claude-security@claude-plugins-official
```

The command opens the plugin’s details, where you choose an [installation scope](../08-Plugins-Skills/discover-plugins.md#install-a-plugin) to start the install. If the install fails, match the message Claude Code reports:

- `Marketplace "claude-plugins-official" not found`: add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`, then retry the install.
- `Plugin "claude-security" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](../08-Plugins-Skills/plugins-troubleshooting.md#plugin-not-found-in-marketplace).

Check the install summary. If it reports `Run /reload-plugins to apply.`, see [Apply plugin changes without restarting](../08-Plugins-Skills/plugins-cli-reference.md#reload-plugins) to activate the plugin in your current session. Once the plugin is active, you’re ready to [scan and fix your codebase](#scan-and-fix-your-codebase).


[​](#uninstall-the-plugin)

Uninstall the plugin

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


[​](#scan-and-fix-your-codebase)

Scan and fix your codebase

The plugin adds one command, `/claude-security`, which opens a menu of its three jobs: scanning the codebase, scanning a set of changes, and suggesting patches. The happy path runs a full scan, then turns its findings into patches:

1

Open the Claude Security menu

Run `/claude-security` and pick **Scan codebase**.

2

Choose what to scan

The plugin reads your repository first, then offers the whole repository or a focused area, with each option’s file count and relative cost stated. Pick the whole repository, or answer “I don’t know” and the plugin picks a sensible default for your repository’s size.

3

Confirm the run

A scan may take a while, may use a significant number of tokens, and needs Claude Code left open while it completes. Nothing runs until you confirm.

4

Read the report

While the scan runs, it reports each stage as it starts, with the detail available under [`/workflows`](workflows.md). Results are written to a timestamped directory in your repository, described in [Read the scan results](#read-the-scan-results).

5

Turn findings into patches

Run `/claude-security` again and pick **Suggest patches**, then choose which findings to address. Reviewed patches are written to the report’s `patches/` folder; [Fix findings](#fix-findings) covers how each patch is built and reviewed.

6

Apply the patches you accept

Apply each patch from your shell with `git apply`, in its own pull request. Patches are never applied automatically.

You don’t have to start from the menu: ask for a job directly, as arguments to the command, such as `/claude-security scan my branch`, or in plain language, such as “scan commit abc1234”. The plugin works best in [auto mode](permission-modes.md), which lets the scan’s agents proceed without a permission prompt at each step.


[​](#scan-only-your-changes)

Scan only your changes

When your branch has commits its base doesn’t, the `/claude-security` menu offers to scan only that diff, so you can check a branch before merging. You can also scan one of your open pull requests, or a single commit by asking for it, such as “scan commit abc1234”. Only committed changes are scanned: commit or stash in-progress edits first, or run a full scan, which reads the working tree. Change scans need a git repository; full scans of an unversioned directory still work. Finding your open pull requests is the one step that reaches the network, and it’s offered only when your session already has permission to run the GitHub CLI and `gh` is signed in.


[​](#scope-large-repositories)

Scope large repositories

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


[​](#read-the-scan-results)

Read the scan results

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

- **`CLAUDE-SECURITY-RESULTS.md`**: the report, with each finding’s ID, such as `F1`, plus its impact, exploit scenario, severity, confidence, and recommendation
- **`CLAUDE-SECURITY-RESULTS.jsonl`**: the same findings in machine-readable form, one JSON object per line
- **`CLAUDE-SECURITY-RESULTS.sarif`**: the same findings as a [SARIF 2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html) log for GitHub code scanning and any other tool that reads the standard. The scan classifies findings under their [CWE](https://cwe.mitre.org/) weakness categories
- **`CLAUDE-SECURITY-REVISION-<commit>.json`**: the revision stamp, recording which commit was scanned, at what effort, whether uncommitted changes were part of the scanned tree, and how thoroughly the run was verified, so a report is always tied to the code it describes. A scan outside version control stamps `UNVERSIONED` in place of the commit

That directory is the only change a scan makes to your checkout, and it carries its own `.gitignore`, so a stray `git add` never sweeps a report into a commit. To keep a report in history for an audit trail, delete that one `.gitignore` file and commit the directory like any other. Findings only appear in the report after independent verifier agents analyze them, which keeps reports short and worth reading. Scans are nondeterministic: two scans of the same code can surface different findings. Run scans regularly, and use the revision stamps to attribute each report to the exact code and settings it covered.


[​](#fix-findings)

Fix findings

Start the fix flow by picking **Suggest patches** from the `/claude-security` menu, or ask in plain language, such as “fix finding F3”, then pick which findings from the report to address. Patches are built against committed code, and the report has to still describe the code you have: findings whose code has since changed are skipped with a note, and the plugin offers a fresh scan instead of patching from a stale report. Each patch is drafted in a scratch copy of your repository, so your source files stay untouched until you apply a patch yourself. Before delivery, each patch is reviewed by an agent independent of the one that wrote it, which runs your project’s tests against the change when the code has them and reads the diff on its own terms for anything new it might introduce. A patch is written only when that review can vouch that the change addresses the one finding, introduces no new vulnerability, and leaves behavior otherwise unchanged. When it can’t vouch for all three, you get a short note explaining why instead of a patch.


[​](#patches-are-never-applied-automatically)

Patches are never applied automatically

Applying a patch is always your decision. Patches are written to the report’s `patches/` folder, one `F<n>.patch` per finding with a note beside it explaining the change. Apply one from your shell, or ask Claude to apply it and open a pull request:

```python
git apply CLAUDE-SECURITY-<timestamp>/patches/F1.patch
```

When the patched code has no tests, the patch’s note says so, so you know its review ran without a test pass. Apply each patch in its own pull request so it can be reviewed and tested on its own.


[​](#how-the-plugin-fits-with-other-security-tools)

How the plugin fits with other security tools

The Claude Security plugin is the on-demand deep-scan layer in a defense-in-depth stack, alongside the [security guidance plugin](security-guidance.md), [`/security-review`](commands.md#all-commands), [Code Review](code-review.md), the managed [Claude Security](../15-Claude-AI-Features/product-claude-security.md) product, and your existing scanners:

| Stage                  | Tool                                                                           | What it covers                                                                             |
|:-----------------------|:-------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------|
| In session             | [Security guidance plugin](security-guidance.md)                         | Common vulnerabilities in code Claude writes, fixed in the same session                    |
| On demand, single pass | [`/security-review`](commands.md#all-commands)                           | One-time security pass on the current branch                                               |
| On demand, deep scan   | Claude Security plugin                                                         | Multi-agent scan of a repository or diff, with independently reviewed findings and patches |
| On pull request        | [Code Review](code-review.md), Team and Enterprise plans                 | Multi-agent correctness and security review with full codebase context                     |
| Managed                | [Claude Security](../15-Claude-AI-Features/product-claude-security.md), Enterprise plan | Hosted scanning that monitors connected repositories                                       |
| In CI                  | Your existing static analysis and dependency scanners                          | Language-specific rules, supply-chain checks, and policy enforcement                       |

The plugin doesn’t replace your existing source-code security tools. Run it alongside static analysis, dependency scanning, and code review: it reasons about your code the way a human security researcher would, which complements the deterministic checks those tools provide.


[​](#troubleshooting)

Troubleshooting

**The `/claude-security` menu opens with a Python warning.** The plugin needs `python3` 3.9 or later on your `PATH`. When it can’t find `python3` at all, the menu warns that Claude Security won’t work until one is installed; when the first `python3` on your `PATH` is older, the warning names the version it found. Install Python 3, or put a newer `python3` first on your `PATH`, then start a new session. **You may see a “safeguards flagged this message” notice when scanning on a Fable model.** The message names the model you’re running. Fable’s cybersecurity safety classifiers flag certain requests, and Claude Code re-runs a flagged request on an Opus model through [automatic model fallback](model-config.md#automatic-model-fallback). This is expected. When the request re-runs, the scan should still complete successfully.


[​](#related-resources)

Related resources

To go deeper on the pieces this page touches:

- [Security guidance plugin](security-guidance.md): catch issues in code as Claude writes it, in the same session
- [Code Review](code-review.md): set up the PR-time multi-agent review
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md): the managed service that monitors connected repositories
- [Claude Code security](../13-Enterprise-Admin/security.md): how Claude Code approaches trust, permissions, and safeguards
- [Install and manage plugins](../08-Plugins-Skills/discover-plugins.md): find and install other plugins from the official marketplace

---

## Claude Tag - Claude Code Docs

Source: https://code.claude.com/docs/en/claude-tag
Path: 02-Claude-Code-CLI/claude-tag.md

# Claude Tag

Copy pageCopy page

Bring Claude into your team’s Slack channels with Claude Tag and find its setup and usage documentation on claude.com.

Copy pageCopy page

[Claude Tag](../15-Claude-AI-Features/product-tag.md) is a Slack integration that runs `@Claude` in your team’s channels as your organization’s shared identity with admin-configured access. Anyone in a channel can tag `@Claude` into a thread and assign it a task. Read the [Claude Tag documentation](https://claude.com/docs/claude-tag/overview) on claude.com to set it up and start using it. Claude Tag is available on Team and Enterprise plans, and is distinct from the earlier [Claude Code in Slack](../14-Connectors/slack.md), which runs each session under an individual user’s account. On Pro and Max plans, where Claude Tag isn’t available, Claude Code in Slack remains the setup path.

---

## CLI reference - Claude Code Docs

Source: https://code.claude.com/docs/en/cli-reference
Path: 02-Claude-Code-CLI/cli-reference.md

## On this page

- [CLI commands](#cli-commands)
- [CLI flags](#cli-flags)
  - [System prompt flags](#system-prompt-flags)
  - [System prompt flags in resumed conversations](#system-prompt-flags-in-resumed-conversations)
- [See also](#see-also)

Reference

# CLI reference

Copy pageCopy page

Complete reference for Claude Code command-line interface, including commands and flags.

Copy pageCopy page


[​](#cli-commands)

CLI commands

You can start sessions, pipe content, resume conversations, and manage updates with these commands:

| Command                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Example                                                     |
|:--------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------|
| `claude`                        | Start interactive session                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `claude`                                                    |
| `claude "query"`                | Start interactive session with initial prompt                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `claude "explain this project"`                             |
| `claude -p "query"`             | Query via SDK, then exit                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `claude -p "explain this function"`                         |
| `cat file | claude -p "query"`  | Process piped content                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `cat logs.txt | claude -p "explain"`                        |
| `claude -c`                     | Continue most recent conversation in current directory                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `claude -c`                                                 |
| `claude -c -p "query"`          | Continue via SDK                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `claude -c -p "Check for type errors"`                      |
| `claude -r "<session>" "query"` | Resume session by ID or name                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | `claude -r "auth-refactor" "Finish this PR"`                |
| `claude update`                 | Update to latest version                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `claude update`                                             |
| `claude gateway`                | Start the self-hosted [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) server, for administrators deploying SSO and policy in front of Claude Code on Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry. Requires `--config` pointing at a [`gateway.yaml`](../13-Enterprise-Admin/claude-apps-gateway-config.md).                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `claude gateway --config gateway.yaml`                      |
| `claude install [version]`      | Install or reinstall the native binary. Accepts a version like `2.1.118`, or `stable` or `latest`. See [Install a specific version](../01-Getting-Started/setup.md#install-a-specific-version)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | `claude install stable`                                     |
| `claude auth login`             | Sign in to your Anthropic account. Use `--email` to pre-fill your email address, `--sso` to force SSO authentication, and `--console` to sign in with Anthropic Console for API usage billing instead of a Claude subscription                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | `claude auth login --console`                               |
| `claude auth logout`            | Log out from your Anthropic account                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `claude auth logout`                                        |
| `claude auth status`            | Show authentication status as JSON. Use `--text` for human-readable output. Exits with code 0 if logged in, 1 if not. The JSON includes a `configDirectory` field naming the [configuration directory](claude-directory.md) the CLI uses. The field requires Claude Code v2.1.268 or later. The JSON’s `authMethod` field is one of `none`, `claude.ai`, `oauth_token`, `api_key`, `api_key_helper`, or `third_party`                                                                                                                                                                                                                                                                                                                                                           | `claude auth status`                                        |
| `claude agents`                 | Open [agent view](../09-Agents-Patterns/agent-view.md) to monitor and dispatch parallel background sessions. Use `--cwd <path>` to show only sessions started under that directory, or `--json` to print active sessions as a JSON array for scripting (`--json --all` also includes completed background sessions). Pass `--permission-mode`, `--model`, `--effort`, or `--agent` to set [defaults for dispatched sessions](../09-Agents-Patterns/agent-view.md#permission-mode-model-and-effort). Accepts `--settings`, `--add-dir`, `--plugin-dir`, and `--mcp-config` like the top-level `claude` command. Opening agent view requires an interactive terminal                                                                                                                                                    | `claude agents --json`                                      |
| `claude attach <id|name>`       | Attach to a [background session](../09-Agents-Patterns/agent-view.md#manage-sessions-from-the-shell) in this terminal. Passing part of a running session’s name in place of the ID requires Claude Code v2.1.290 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `claude attach 7c5dcf5d`                                    |
| `claude auto-mode defaults`     | Print the built-in [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) classifier rules as JSON. Use `claude auto-mode config` to see your effective config with settings applied. `--label <prefix>` prints only the rules whose label starts with that prefix, matched case-insensitively. Requires Claude Code v2.1.208 or later                                                                                                                                                                                                                                                                                                                                                                                                                               | `claude auto-mode defaults --label 'Git Destructive'`       |
| `claude auto-mode reset`        | Restore the default [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) configuration by removing the `autoMode` section from your user settings file. Prompts for confirmation before writing; pass `-y`/`--yes` to skip the prompt. Rules from [managed settings](../13-Enterprise-Admin/server-managed-settings.md) or the `--settings` flag still apply. Requires Claude Code v2.1.212 or later. See [Inspect the defaults and your effective config](auto-mode-config.md#inspect-the-defaults-and-your-effective-config)                                                                                                                                                                                                                                                | `claude auto-mode reset --yes`                              |
| `claude daemon logs`            | Follow the background-session [supervisor’s](../09-Agents-Patterns/agent-view.md#the-supervisor-process) log file, `~/.claude/daemon.log`, printing new lines as they arrive until you press `Ctrl+C`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `claude daemon logs`                                        |
| `claude daemon run`             | Run the background-session [supervisor](../09-Agents-Patterns/agent-view.md#the-supervisor-process) in the foreground of this terminal, printing its log                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `claude daemon run`                                         |
| `claude daemon status`          | Print the background-session [supervisor’s](../09-Agents-Patterns/agent-view.md#the-supervisor-process) state, version, socket directory, and worker count for diagnostics. Exits 1 if the supervisor isn’t running                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `claude daemon status`                                      |
| `claude daemon stop --any`      | Stop the background-session [supervisor](../09-Agents-Patterns/agent-view.md#the-supervisor-process) and the sessions it hosts. Pass `--keep-workers` to leave background sessions running for the next supervisor to reconnect to. `--any` confirms stopping an on-demand supervisor, which is the default. Use this to recover from an [unresponsive supervisor](../09-Agents-Patterns/agent-view.md#agent-view-says-the-background-service-did-not-respond)                                                                                                                                                                                                                                                                                                                                                        | `claude daemon stop --any --keep-workers`                   |
| `claude doctor`                 | Print read-only installation and settings diagnostics from the terminal without starting a session, including install health, settings-file validation errors, and Remote Control eligibility. For the in-session setup checkup that can also apply fixes, run [`/doctor`](commands.md#all-commands)                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | `claude doctor`                                             |
| `claude import [source]`        | Start an interactive session that runs [`/import`](commands.md#all-commands) to bring configuration from other coding agents into Claude Code. Accepts the same `--dry-run` and `--yes` options as the command. Not available on Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, or Claude Platform on AWS. Also unavailable when you turn off [feature-flag fetching](env-vars.md#features-that-need-feature-flag-fetching). Requires Claude Code v2.1.213 or later                                                                                                                                                                                                                                                                                    | `claude import codex --dry-run`                             |
| `claude logs <id|name>`         | Print recent output from a [background session](../09-Agents-Patterns/agent-view.md#manage-sessions-from-the-shell). Passing part of a session’s name in place of the ID requires Claude Code v2.1.290 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | `claude logs 7c5dcf5d`                                      |
| `claude mcp`                    | Configure Model Context Protocol (MCP) servers                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | See the [Claude Code MCP documentation](../06-MCP-Tools/General/mcp.md).      |
| `claude mcp login <name>`       | Run a configured MCP server’s OAuth flow without opening the interactive `/mcp` panel. Works for HTTP, SSE, and claude.ai connector servers. Add `--no-browser` over SSH to print the authorization URL instead of opening a browser. For an HTTP or SSE server, paste the redirect URL back at the prompt. For a claude.ai connector, see [Authorize a connector again from your shell](remote-control.md#authorize-a-connector-again-from-your-shell). See [Authenticate from the command line](../06-MCP-Tools/General/mcp.md#authenticate-from-the-command-line)                                                                                                                                                                                                                              | `claude mcp login sentry`                                   |
| `claude mcp logout <name>`      | Clear stored OAuth credentials for an MCP server                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `claude mcp logout sentry`                                  |
| `claude plugin`                 | Manage Claude Code [plugins](../08-Plugins-Skills/plugins.md). Alias: `claude plugins`. See [plugin reference](../08-Plugins-Skills/plugins-cli-reference.md#claude-plugin-commands) for subcommands                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | `claude plugin install code-review@claude-plugins-official` |
| `claude purge [path]`           | Delete all local Claude Code state for a project: transcripts, task lists, debug logs, file-edit history, prompt history lines, and the project’s entry in `~/.claude.json`. Omit `[path]` to pick from an interactive list. Flags: `--dry-run` to preview, `-y`/`--yes` to skip confirmation, `-i`/`--interactive` to confirm each item, `--all` for every project. See [Clear local data](claude-directory.md#clear-local-data)                                                                                                                                                                                                                                                                                                                                               | `claude purge ~/work/repo --dry-run`                        |
| `claude remote-control`         | Start a [Remote Control](remote-control.md) server to control Claude Code from Claude.ai or the Claude app. Runs in server mode (no local interactive session). See [Server mode flags](remote-control.md#start-a-remote-control-session). After you stop the server, you can bring back the sessions it was serving. See [Resume sessions after stopping the server](remote-control.md#resume-sessions-after-stopping-the-server)                                                                                                                                                                                                                                                                                                                                  | `claude remote-control --name "My Project"`                 |
| `claude respawn <id>`           | Restart a [background session](../09-Agents-Patterns/agent-view.md#manage-sessions-from-the-shell), running or stopped, with its conversation intact. Use `--all` to restart every running session, e.g. to pick up an updated Claude Code binary                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `claude respawn 7c5dcf5d`                                   |
| `claude rm <id>`                | Remove a [background session](../09-Agents-Patterns/agent-view.md#manage-sessions-from-the-shell) from the list. When the removal is [refused over the session’s worktree](../09-Agents-Patterns/agent-view.md#what-deleting-a-session-removes) and a second `claude rm` can resolve it, the refusal prints the exact flag and value to pass: `--discard-unpushed <commit>@<worktree-id>` discards a worktree that has unpushed commits along with those commits, and `--force-remove-worktree <worktree-id>` deletes a worktree directory that git or the `WorktreeRemove` hook couldn’t remove. `--discard-unpushed` requires Claude Code v2.1.260 or later, and `--force-remove-worktree` requires v2.1.268 or later. The conversation transcript stays on your local machine, available through `claude --resume` | `claude rm 7c5dcf5d`                                        |
| `claude self-hosted-runner`     | Start a runner process that registers this machine or container with a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) and hosts Claude Code cloud sessions on your infrastructure. Run `claude self-hosted-runner setup` for a guided operator walkthrough, `claude self-hosted-runner doctor` to [diagnose a deployed runner](../13-Enterprise-Admin/self-hosted-environments-deploy.md#troubleshooting), and `claude self-hosted-runner orchestrator` to spawn [on-demand runners](../13-Enterprise-Admin/self-hosted-environments-configuration.md#on-demand-runners). Requires Claude Code v2.1.224 or later                                                                                                                                                                                          | `claude self-hosted-runner setup`                           |
| `claude setup-token`            | Generate a long-lived OAuth token for CI and scripts. Prints the token to the terminal without saving it. Requires a Claude subscription. See [Generate a long-lived token](authentication.md#generate-a-long-lived-token)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `claude setup-token`                                        |
| `claude stop <id>`              | Stop a [background session](../09-Agents-Patterns/agent-view.md#manage-sessions-from-the-shell). Also accepts `claude kill`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `claude stop 7c5dcf5d`                                      |
| `claude ultrareview [target]`   | Run [ultrareview](ultrareview.md#run-ultrareview-non-interactively) non-interactively. Prints findings to stdout and exits 0 on success or 1 on failure. Use `--json` for the raw payload and `--timeout <minutes>` to override the 45-minute default. Use `--post` on a `github.com` pull request target to post the finished findings to the PR as one plain comment from your GitHub account. `--no-post` is the default. `--post` and `--no-post` require Claude Code v2.1.227 or later. See [Post findings to the pull request](ultrareview.md#post-findings-to-the-pull-request)                                                                                                                                                                                    | `claude ultrareview 1234 --json`                            |

If you mistype a subcommand, Claude Code suggests the closest match and exits without starting a session. For example, `claude udpate` prints `Did you mean claude update?`. `claude --dangerously-skip-permissions daemon <subcommand>` runs the `daemon` subcommand, so the subcommand works when `claude` is aliased to include the flag. Only a leading `--dangerously-skip-permissions` or `--allow-dangerously-skip-permissions` routes to `daemon` this way; with any other flag ahead of `daemon`, the subcommand doesn’t run.


[​](#cli-flags)

CLI flags

Customize Claude Code’s behavior with these command-line flags. `claude --help` does not list every flag, so a flag’s absence from `--help` does not mean it is unavailable.

[TABLE]


[​](#system-prompt-flags)

System prompt flags

Claude Code provides five flags for customizing the system prompt. Four set its text, and with `--system-prompt-snapshot` you control whether a conversation keeps the text it started with. All five work in both interactive and non-interactive modes.

| Flag                          | Behavior                                                                                                                                                                    | Example                                                                    |
|:------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------|
| `--system-prompt`             | Replaces the entire default prompt                                                                                                                                          | `claude --system-prompt "You are a Python expert"`                         |
| `--system-prompt-file`        | Replaces with file contents                                                                                                                                                 | `claude --system-prompt-file ./prompts/review.txt`                         |
| `--append-system-prompt`      | Appends to the default prompt                                                                                                                                               | `claude --append-system-prompt "Always use TypeScript"`                    |
| `--append-system-prompt-file` | Appends file contents to the default prompt                                                                                                                                 | `claude --append-system-prompt-file ./style-rules.txt`                     |
| `--system-prompt-snapshot`    | With `off`, rebuilds the prompt on every request. With `on`, the default, reuses a recorded prompt where [recording applies](#system-prompt-flags-in-resumed-conversations) | `claude --append-system-prompt "Draft rules" --system-prompt-snapshot off` |

You can combine these flags. To replace the default prompt and still append your own text, pass `--append-system-prompt` or `--append-system-prompt-file` together with `--system-prompt` or `--system-prompt-file`. With Claude Code v2.1.283 or later, you can also pass a flag together with its own file form, such as `--append-system-prompt` with `--append-system-prompt-file`, and Claude Code uses both. For example, run the following in your shell to append both a style guide from a file and one extra instruction:

```python
claude -p --append-system-prompt-file ./style.md --append-system-prompt "Always reply in French" "Summarize README.md"
```

Claude receives the default system prompt followed by the contents of `style.md`, a blank line, and then `Always reply in French`. The file’s contents come first even if you pass `--append-system-prompt` before `--append-system-prompt-file`. When the replacement text combines instructions that are the same on every run with context that changes per run, add a line containing only `__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__` between the instructions and the context. Claude Code splits the prompt at the first such line and removes that line, so the part above it stays cached while the part below changes. Requires Claude Code v2.1.275 or later. [Cache the static part of a custom prompt](../05-Agent-SDK/agent-sdk-modifying-system-prompts.md#cache-the-static-part-of-a-custom-prompt) lists the configurations where the split applies. Choose based on whether Claude Code’s default identity still fits your task. Use an append flag when Claude should remain a coding assistant that also follows your extra rules: per-invocation instructions, output formatting, or domain context for a `-p` script. Appending preserves the default tool guidance, safety instructions, and coding conventions, so you only supply what differs. Use a replacement flag when the surface, identity, or permission model differs from Claude Code’s, like a non-coding agent in a pipeline that no human watches. Replacing drops all of the default prompt, including tool guidance and safety instructions, so you take responsibility for whatever your task still needs. For persistent personas you can switch between and share across a project, use [output styles](output-styles.md). For project conventions Claude should always follow, use [CLAUDE.md](memory.md). The [Agent SDK guide on system prompts](../05-Agent-SDK/agent-sdk-modifying-system-prompts.md#decide-on-a-starting-point) covers the same decision in more depth.


[​](#system-prompt-flags-in-resumed-conversations)

System prompt flags in resumed conversations

By default, Claude Code builds the system prompt once, on a conversation’s first request, with the text from any system prompt flags applied, and records it in the session. Until the conversation is compacted, every later request uses that recorded prompt, including after you return to the conversation with `--resume` or `--continue`. If you pass different system prompt flag text, or none, on that later launch, it takes effect once the conversation is compacted or when you start a new conversation. Outside of [cloud sessions](cloud-environments.md), if you start Claude Code in [bare mode](headless.md#start-faster-with-bare-mode) by passing `--bare` or setting `CLAUDE_CODE_SIMPLE=1`, recording stays off unless you pass `--system-prompt-snapshot on`. Before v2.1.268, sessions that don’t [fetch feature flags](env-vars.md#features-that-need-feature-flag-fetching), including sessions on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry, rebuilt the prompt on every request and `--system-prompt-snapshot` had no effect. To rebuild the prompt on every request instead, for example while you iterate on its wording across `--continue` runs, pass `--system-prompt-snapshot off`. Before v2.1.265, passing any of the system prompt flags also turned recording off unless you passed `--system-prompt-snapshot on`.


[​](#see-also)

See also

- [Chrome extension](../03-IDE-Integrations/chrome.md) - Browser automation and web testing
- [Interactive mode](interactive-mode.md) - Shortcuts, input modes, and interactive features
- [Quickstart guide](../01-Getting-Started/quickstart.md) - Getting started with Claude Code
- [Common workflows](common-workflows.md) - Advanced workflows and patterns
- [Settings](settings.md) - Configuration options
- [Agent SDK documentation](../05-Agent-SDK/agent-sdk-overview.md) - Programmatic usage and integrations

---

## Configure cloud environments - Claude Code Docs

Source: https://code.claude.com/docs/en/cloud-environments
Path: 02-Claude-Code-CLI/cloud-environments.md

## On this page

- [The Default environment](#the-default-environment)
- [Configure your environment](#configure-your-environment)
  - [Set environment variables](#set-environment-variables)
  - [Add network secrets](#add-network-secrets)
  - [Requirements](#requirements)
  - [Add a secret](#add-a-credential)
  - [Add a secret on a Team plan without an organization admin role](#add-a-secret-without-the-role)
  - [Which requests get the secret](#which-requests-get-the-credential)
  - [Requests that never get the secret](#requests-that-never-get-the-credential)
  - [Select an environment from the CLI](#select-an-environment-from-the-cli)
  - [Archive an environment](#archive-an-environment)
  - [Organization-shared environments](#organization-shared-environments)
  - [Set the environment a Claude Tag channel uses](#set-the-environment-a-claude-tag-channel-uses)
- [Network access](#network-access)
  - [Access levels](#access-levels)
  - [Allow specific domains](#allow-specific-domains)
  - [GitHub proxy](#github-proxy)
  - [Security proxy](#security-proxy)
- [What’s available in cloud sessions](#what%E2%80%99s-available-in-cloud-sessions)
  - [What carries over from your setup](#what-carries-over-from-your-setup)
  - [Add personal preferences without committing to the repo](#add-personal-preferences-without-committing-to-the-repo)
  - [Installed tools](#installed-tools)
  - [Work with GitHub issues and pull requests](#work-with-github-issues-and-pull-requests)
  - [Link output back to the session](#link-output-back-to-the-session)
  - [Run tests, start services, and add packages](#run-tests-start-services-and-add-packages)
  - [Run tests](#run-tests)
  - [Start services](#start-services)
  - [Add packages](#add-packages)
  - [Resource limits](#resource-limits)
  - [Time limits](#time-limits)
- [Setup scripts](#setup-scripts)
  - [Script requirements](#script-requirements)
  - [Environment caching](#environment-caching)
  - [Setup scripts vs. SessionStart hooks](#setup-scripts-vs-sessionstart-hooks)
  - [Install dependencies with a SessionStart hook](#install-dependencies-with-a-sessionstart-hook)
  - [Limitations in cloud sessions](#limitations-in-cloud-sessions)
- [Default allowed domains](#default-allowed-domains)
- [Related resources](#related-resources)

Environments

# Configure cloud environments

Copy pageCopy page

Configure cloud environments for Claude Code cloud sessions: network access levels, environment variables, setup scripts, and environment caching.

Copy pageCopy page

Cloud environments apply to [cloud sessions](claude-code-on-the-web.md), which are available on Pro, Max, and Team plans, and for Enterprise users with [premium seats or Chat + Claude Code seats](https://support.claude.com/en/articles/11845131-use-claude-code-with-your-team-or-enterprise-plan).

Each [cloud session](claude-code-on-the-web.md) runs in a cloud environment. You can configure an environment to allow or deny [network access](#access-levels), [set environment variables](#set-environment-variables) for the session, store [network secrets](#add-network-secrets) that sessions use without seeing them, and run a [setup script](#setup-scripts) before Claude starts working. The same environments apply wherever you start a cloud session:

- The [Desktop app](../16-Mobile-Desktop/desktop.md)
- The [Claude mobile app](../16-Mobile-Desktop/mobile.md)
- Your browser at [claude.ai/code](https://claude.ai/code)
- The terminal with [`claude --cloud`](claude-code-on-the-web.md#from-terminal-to-cloud)
- [Cloud scheduled tasks](web-scheduled-tasks.md)
- [Claude Tag](https://claude.com/docs/claude-tag/overview)

Each of these surfaces can also route to a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md). [Availability and limitations](../13-Enterprise-Admin/self-hosted-environments.md#availability-and-limitations) covers what Claude can’t use yet when a Claude Tag session runs in one.

[Remote Control](remote-control.md) sessions connect the web and mobile interfaces to a session on your own machine, which uses your machine’s network and files, not a cloud environment. Claude Tag channel sessions use organization-level environments only, either [shared environments](#organization-shared-environments) or [self-hosted environments](../13-Enterprise-Admin/self-hosted-environments.md).


[​](#the-default-environment)

The Default environment

If you don’t have an environment yet, onboarding sets up the **Default** environment. How depends on where you onboard:

- **CLI flows such as `/web-setup`**: create **Default** for you
- **Web onboarding on Pro and Max**: creates **Default** for you
- **Web onboarding on Team and Enterprise**: shows a **Create your first cloud environment** form unless an Owner has turned on [Quick setup](claude-code-on-the-web.md#quick-setup-for-team-and-enterprise); keep the form’s defaults and click **Create & finish** to get the same **Default** environment

**Default** carries no configuration of its own:

- [**Trusted** network access](#access-levels): sessions reach package registries and other [allowlisted domains](#default-allowed-domains), and nothing else through the session’s network.
- No other configuration: **Default** defines no environment variables or setup script, so sessions start with just the [pre-installed tools](#installed-tools).

With only **Default** available, every session runs in it. When you have more than one environment, sessions choose one per surface:

- In the Desktop app, the mobile app, and at claude.ai/code, sessions you start yourself use the environment shown in the [selector](#configure-your-environment). An [organization default](#organization-shared-environments) set by an Owner fills the selection when you haven’t picked one. Threads in a [project](claude-projects.md#project-settings-reference) use the environment set in the project’s settings instead.
- From the CLI, Claude Code uses your [`/remote-env` pick](#select-an-environment-from-the-cli), or falls back to the Anthropic-hosted environment when your list has one, and otherwise to the first environment in your list that isn’t a bridge environment, an entry [Remote Control](remote-control.md) registers to represent your own machine rather than a cloud environment. For a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md), passing `--environment <environment-id>` with its `ccpool_` ID [when you dispatch a session](../13-Enterprise-Admin/self-hosted-environments-testing.md#run-the-test-loop) overrides the `/remote-env` pick and the fallback for that invocation. Claude Code rejects Anthropic-hosted `env_` IDs passed to the flag, so use `/remote-env` to target those. The flag requires Claude Code v2.1.224 or later.

Configure an environment when the default isn’t enough: when Claude needs to reach domains outside the [default allowlist](#default-allowed-domains), needs environment variables set for its sessions, or needs dependencies installed before it starts working.


[​](#configure-your-environment)

Configure your environment

Add, edit, and archive environments from the environment selector under the message box on the screen where you start a new session at [claude.ai/code](https://claude.ai/code). To reach that screen, complete [web onboarding](web-quickstart.md). For the Desktop app, see [Cloud sessions](../16-Mobile-Desktop/desktop.md#cloud-sessions). Environments you create are personal to your account; [shared environments](#organization-shared-environments) created by an Owner appear in the selector alongside them. See [Installed tools](#installed-tools) for what’s available without any configuration. The selector appears only until you send a new session’s first message. To edit the environment of a running cloud session of your own, select the caret after the session title at the top, then select **Edit cloud environment**.

1

Open the environment selector

On the new-session screen, select the first control in the row under the message box.

2

Add or edit an environment

- **Add an environment**: select **New environment** at the bottom of the menu to open the **New environment** dialog. Fill in the form and select **Add environment**. Your new session then uses the environment you added.
- **Edit an environment**: find its row under **Cloud**. If **Cloud** is a single row, select it to open the list. If your environment isn’t listed under **Cloud**, select the **More** row under that heading. Hover over the environment’s row and select the settings icon that appears on its right to open its dialog.

The dialog includes the name, network access level, environment variables, and setup script. To store a key that sessions use without seeing it, see [Add network secrets](#add-network-secrets).


[​](#set-environment-variables)

Set environment variables

Environment variables use `.env` format, one `KEY=value` pair per line. Plain values don’t need quotes, and if you quote a value with a matching pair, the quotes don’t become part of the value. Quote a value that spans multiple lines or contains a `#`: in an unquoted value, `#` starts a comment and the rest of the line is dropped. The following example defines three variables.

```python
NODE_ENV=development
LOG_LEVEL=debug
DATABASE_URL=postgres://localhost:5432/myapp
```

A session reads the environment’s values into ordinary environment variables that any command Claude runs can read, except `OTEL_*` variables. Claude Code uses those for its own [telemetry export](../13-Enterprise-Admin/monitoring-usage.md#telemetry-from-cloud-sessions-and-claude-tag) and doesn’t pass them to the commands it runs. In an Anthropic-hosted environment, a session reads the environment’s values when you create it and again each time Claude Code starts in the session’s VM afterward, which happens in two cases:

- **The VM is restored after being idle**: after a few minutes without activity, a session’s VM pauses with its files saved. Your next message restores the same VM and starts Claude Code again.
- **The VM was reclaimed and is rebuilt**: if the paused VM has since been [reclaimed](claude-code-on-the-web.md#environment-expired), reopening the session provisions a fresh VM.

After you edit, add, or remove a variable, an existing session in an Anthropic-hosted environment keeps the values it last read until its VM is next restored or rebuilt, and uses your change from then on. Its VM pauses on its own once the session is idle, and you can’t pause it yourself. To use a new value right away, ask Claude to set it on the command it runs, for example `LOG_LEVEL=trace npm test`, or start a new session. A cloud session also sets some variables itself when it starts. For [`CLAUDE_AUTOCOMPACT_PCT_OVERRIDE`](claude-code-on-the-web.md#manage-context), the value the session sets overrides one you add here, so adding that key here has no effect. Anyone who uses the environment can read the values. In an Anthropic-hosted environment, use a [network secret](#add-network-secrets) instead for a key the agent proxy can attach to a request. The [requests that never get a secret](#requests-that-never-get-the-credential) are listed there.


[​](#add-network-secrets)

Add network secrets

A network secret is an API key or token you store on a cloud environment so Claude can call that API from any session in the environment without seeing the key. Anthropic’s agent proxy adds the key to requests for the hosts you list, after each request leaves the session’s VM, so the key itself stays outside the VM. Network secrets are available on Pro, Max, Team, and Enterprise plans. To check whether you can add one yourself, see [Requirements](#requirements).


[​](#requirements)

Requirements

These requirements decide whether you can add a secret and whether the agent proxy can use it once added:

- **Role**: on Pro, Max, and Team plans, you can add and delete secrets on your own environments whatever your role. On Team and Enterprise, Owners hold an organization admin role in your claude.ai organization and Admins don’t, which changes what you see in these cases:
  - **Your own environment on Enterprise**: with an organization admin role, you add and delete secrets. Without it, the **Network secrets** section lists the secrets under the note “Only an organization admin can add or delete network secrets”, with no **Add secret** or delete button. Ask an Owner to add the secret to a [shared environment](#organization-shared-environments), then run your sessions there
  - **A shared environment**: Owners [add and delete its secrets](#add-a-credential) from admin settings. Without an organization admin role, ask an Owner to add the secret, because the environment’s dialog has no **Network secrets** section
  - **Your own environment on Team**: without an organization admin role, **Add secret** opens a [shorter form](#add-a-secret-without-the-role) that takes one host
- **Environment type**: an Anthropic-hosted cloud environment that already exists. A [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) doesn’t have network secrets
- **API reachability**: the API accepts connections from the internet, because requests leave from Anthropic’s network
- **Encryption keys**: if your organization uses customer-managed encryption keys, you can’t save network secrets


[​](#add-a-credential)

Add a secret

You add secrets one at a time, and you can’t edit a secret after you add it. To change a secret’s hosts or value, delete it and add it again. To add a secret to a [shared environment](#organization-shared-environments), open it for editing from the **Cloud environments** page in [admin settings](https://claude.ai/admin-settings), then continue step 1 from the **Network secrets** section. If you’re on a Team plan and don’t hold an [organization admin role](#requirements), follow step 1 on your own environment, then [fill in the shorter form](#add-a-secret-without-the-role).

1

Open the environment's network secrets

[Open the environment for editing](#configure-your-environment) at [claude.ai/code](https://claude.ai/code). In the **Edit cloud environment** dialog, find the **Network secrets** section. You see the secrets already on the environment, each with the hosts it applies to.

2

Add the secret

Select **Add secret** and fill in the form. Keep the default **Secret type**, **Bearer**, for an API key that travels in a request header, and fill in these fields:

- **Name**: a label for the secret, such as `Internal billing API`
- **Allowed websites**: the API’s hosts, such as `api.example.com`. A leading `*.` matches every subdomain
- **Custom headers**: one row for the header that carries the key. The row starts with `Authorization` as the header’s **Name** and `Bearer` as its **Prefix**; paste the key itself as the **Value**. For a header like `X-Api-Key` that takes the bare value, change the name and clear the prefix

For an API that authenticates another way, pick a different **Secret type**. The list is the same one [Claude Tag](https://claude.com/docs/claude-tag/overview), the Slack integration for Team and Enterprise plans, offers for [connections](https://claude.com/docs/claude-tag/admins/add-connections).

3

Save the secret

Select **Add**. The secret appears in the list with its hosts, saved without the dialog’s **Save changes** button. You can’t view the value again after saving.

To confirm the secret works, start a session in the environment and ask Claude to call the API, for example with `curl`. The API answers as if the key were in the request, and the key doesn’t appear in the session’s environment variables or in any file. If the list marks a secret **Not sent** instead, the note under it says why and what to do. Two secrets whose hosts overlap without matching exactly get no marker, and the agent proxy sends only one of them.


[​](#add-a-secret-without-the-role)

Add a secret on a Team plan without an organization admin role

If you’re on a Team plan and don’t hold an [organization admin role](#requirements), the **Add secret** form takes one secret for one host. Select **Add secret** in your environment’s [**Network secrets** section](#add-a-credential), fill in these fields, then select the form’s **Add secret** button:

- **Host**: the one host that gets the secret, such as `api.example.com`. The form doesn’t accept a `*.` wildcard
- **Name**: an optional label for the secret
- **Secret type**: **Token** for a key that travels in a request header, or **Username and password**. For a token, paste the key as the **Value**


[​](#which-requests-get-the-credential)

Which requests get the secret

The agent proxy attaches a secret to a request when the request’s host matches one you listed on that secret. Sessions can reach those hosts even when the environment’s [network access level](#access-levels) wouldn’t otherwise allow them, except the [hosts that never get the secret](#requests-that-never-get-the-credential). The secret applies in every session that runs in the environment, whoever started it, until you delete it.


[​](#requests-that-never-get-the-credential)

Requests that never get the secret

The agent proxy never attaches a secret you add to these requests:

- **GitHub**: the [GitHub proxy](#github-proxy) authenticates requests to GitHub instead, so you don’t need a network secret for it
- **The Anthropic API and public package registries**: `api.anthropic.com`, `registry.npmjs.org`, `jsr.io`, `npm.jsr.io`, `pypi.org`, `files.pythonhosted.org`, `index.crates.io`, and `proxy.golang.org`
- **Setup script requests**: Claude Code connects to the agent proxy when it launches, after the [setup script](#setup-scripts) has run
- **Claude Code’s telemetry export**: Claude Code sends its [telemetry export](../13-Enterprise-Admin/monitoring-usage.md#telemetry-from-cloud-sessions-and-claude-tag) itself rather than through a command it runs, and that request doesn’t go through the agent proxy


[​](#select-an-environment-from-the-cli)

Select an environment from the CLI

Run `/remote-env` in your terminal to choose the default environment for cloud sessions you create from the CLI, such as [`claude --cloud`](claude-code-on-the-web.md#from-terminal-to-cloud). The command opens a picker of your existing environments and saves your choice to the `remote.defaultEnvironmentId` key in your [user settings](settings.md#where-settings-live), so it applies in every project on your machine until you change it, unless the same key is set at a higher-precedence [settings layer](settings.md#settings-precedence), such as a repo’s project settings. A [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) ID, which has the form `ccpool_...`, follows a stricter source rule. See [`remote.defaultEnvironmentId`](settings-reference.md#remote-defaultenvironmentid) for the settings layers Claude Code honors it from. `/remote-env` only sets the default: it doesn’t start a session, and it can’t add or edit environments. Manage them from the [environment selector](#configure-your-environment).


[​](#archive-an-environment)

Archive an environment

To archive one of your own environments, open it for editing, then select **Archive environment** and confirm. If the environment is [shared with your organization](#organization-shared-environments), an Owner archives it from the **Cloud environments** page in [admin settings](https://claude.ai/admin-settings) instead, so ask an Owner unless you are one. Archiving affects new sessions, not running ones:

- Sessions already running in the environment continue to work.
- The environment disappears from the selector and from `/remote-env`, so you can’t pick it for new sessions.
- Network secrets on the environment stay attached in its running sessions. Delete any you no longer want before you archive.
- No new session can start in an archived environment, on any surface:
  - **Saved CLI default**: if the environment was your saved [CLI default](#select-an-environment-from-the-cli), Claude Code starts CLI cloud sessions in the Anthropic-hosted environment when your list has one. Otherwise, it starts them in the first environment in your list that isn’t a [Remote Control bridge environment](#the-default-environment).
  - **Configured explicitly**: anything configured with the environment explicitly, such as a [cloud scheduled task](web-scheduled-tasks.md#environments-and-network-access), can’t start new sessions in it. Point it at another environment.

When you no longer need an Anthropic-hosted environment, archive it. Neither the environment dialog nor the **Cloud environments** admin page has an option to delete an Anthropic-hosted environment. If the environment is [self-hosted](../13-Enterprise-Admin/self-hosted-environments.md), an Owner can delete it from the **Cloud environments** page in admin settings. If you aren’t an Owner, ask one to delete it.


[​](#organization-shared-environments)

Organization-shared environments

On Team and Enterprise plans, an Owner can create cloud environments that are shared with every member of the organization. The same role manages everything else on the **Cloud environments** admin page, including [self-hosted environments](../13-Enterprise-Admin/self-hosted-environments.md); the Admin role can’t open the page. The full list of roles that can open it is the one for [managing server-managed settings](../13-Enterprise-Admin/server-managed-settings.md#access-control). Shared environments appear in each member’s [environment selector](#configure-your-environment) under an **Organization** heading, after the member’s own environments under **Personal**, so a team can standardize on one configuration instead of each member recreating it. Selecting a shared environment’s settings icon there opens a read-only summary of its configuration for every member, Owners included. An Owner makes an environment available to the organization in one of two ways:

- **Create a shared environment**: use the **Cloud environments** page in [admin settings](https://claude.ai/admin-settings), which is also where Owners edit and archive shared environments. Each one has a name, a [network access level](#access-levels), [environment variables](#set-environment-variables) in `.env` format, and a [setup script](#setup-scripts).
- **Share a personal environment**: open one of your own environments for editing in the environment selector, then share it from the **Who can use it** row. The environment keeps its ID, so sessions and scheduled tasks that already use it aren’t affected, and every member can then see it and start sessions in it.

Owners choose the organization’s [default environment](#the-default-environment) separately, at [claude.ai/admin-settings/claude-code](https://claude.ai/admin-settings/claude-code). To give a shared environment’s sessions a key they can’t read, add a [network secret](#add-network-secrets) when you edit the environment on the **Cloud environments** page. Don’t include secrets in its variables, because every member’s sessions read them.


[​](#set-the-environment-a-claude-tag-channel-uses)

Set the environment a Claude Tag channel uses

In [Claude Tag](https://claude.com/docs/claude-tag/overview) channels, Claude works as your organization’s shared identity, not as any member, so channel sessions use organization-level environments only, either shared environments or [self-hosted environments](../13-Enterprise-Admin/self-hosted-environments.md). To give a channel a toolchain that isn’t [pre-installed](#installed-tools), such as .NET, an Owner can create a [shared environment](#organization-shared-environments) from the **Cloud environments** admin page with a [setup script](#setup-scripts) that installs it. Point the channel at an environment in one of two ways:

- Set a shared or self-hosted environment as the organization’s [default environment](#the-default-environment) at [claude.ai/admin-settings/claude-code](https://claude.ai/admin-settings/claude-code).
- [Pin one to a channel](https://claude.com/docs/claude-tag/admins/troubleshooting#channel-sessions-use-the-wrong-environment-or-can%E2%80%99t-find-one) in the Claude Tag admin settings.


[​](#network-access)

Network access

Each environment sets one network access level, which controls the outbound connections its sessions can make. The default level, **Trusted**, allows package registries and other [allowlisted domains](#default-allowed-domains); **Custom** takes your own domain list. To change an environment’s network access, [open it for editing](#configure-your-environment) and use the **Network access** selector in the dialog. A [shared environment](#organization-shared-environments) opens read-only there, so an Owner changes its network access from the **Cloud environments** page in [admin settings](https://claude.ai/admin-settings) instead. The control that opens the selector appears on the app surfaces listed under [The Default environment](#the-default-environment) and in the [cloud scheduled task editor](web-scheduled-tasks.md#environments-and-network-access). Personal environments don’t have a separate page in your claude.ai account settings. When you change an Anthropic-hosted environment’s network access, its existing sessions follow the new setting within about a minute, for requests that go through the session’s [network allowlist](#access-levels). You don’t need to start a new session.

MCP connectors you enable on a session or scheduled task work without adding their hosts to **Allowed domains**, because connector traffic travels through Anthropic’s servers rather than the session’s network. This relies on the same Anthropic-bound channel noted under [Security and isolation](claude-code-on-the-web.md#security-and-isolation). Turn off any connector you don’t need to limit which tools Claude can reach.


[​](#access-levels)

Access levels

The **Network access** field in the [environment dialog](#configure-your-environment) takes one of four levels:

| Level       | Outbound connections                                                                         |
|:------------|:---------------------------------------------------------------------------------------------|
| **None**    | No outbound network access through the session’s network                                     |
| **Trusted** | [Allowlisted domains](#default-allowed-domains) only: package registries, GitHub, cloud SDKs |
| **Full**    | Any domain                                                                                   |
| **Custom**  | Your own allowlist, optionally including the defaults                                        |

Whichever level you pick, sessions can still reach these, because each one takes a path that doesn’t go through the session’s network allowlist:

- GitHub, through its [separate proxy](#github-proxy)
- [MCP connectors](#network-access) you enable, whose traffic travels through Anthropic’s servers
- The hosts you listed on the environment’s [network secrets](#add-network-secrets), except the [hosts that never get the secret](#requests-that-never-get-the-credential)
- The Anthropic API, for Claude Code’s own requests, even at **None**, as noted under [Security and isolation](claude-code-on-the-web.md#security-and-isolation)


[​](#allow-specific-domains)

Allow specific domains

To allow domains that aren’t in the Trusted list, select **Custom** in the environment’s network access settings, then list one domain per line in the **Allowed domains** field. This example allows three hosts an internal project might need.

```python
api.example.com
*.internal.example.com
registry.example.com
```

Sessions in this environment can now reach `api.example.com`, any subdomain of `internal.example.com`, and `registry.example.com`, and no other domains through the session’s network. [GitHub traffic](#github-proxy), [MCP connector traffic](#network-access), and requests to the hosts of the environment’s [network secrets](#add-network-secrets), other than the [hosts that never get the secret](#requests-that-never-get-the-credential), don’t go through this allowlist. A leading `*.` matches every subdomain. To keep the [Trusted domains](#default-allowed-domains) too, check **Also include default list of common package managers**; leave it unchecked to allow only what you list. If your organization uses [artifacts](artifacts.md#availability), you don’t need `*.frame.claudeusercontent.com` in the list for sessions to read them. When the list leaves that host out, Claude Code reads artifact content through the session’s connection to Anthropic instead. Keep the host in an allowlist in two situations:

- **Sessions in this environment open another organization’s public artifacts**: Claude Code fetches those from the host directly, so add it to this list.
- **You’re configuring the local CLI or a self-hosted runner**: keep the host in that allowlist. See [network access requirements](../13-Enterprise-Admin/network-config.md#network-access-requirements) and the self-hosted [network requirements](../13-Enterprise-Admin/self-hosted-environments-deploy.md#network-requirements).

Each environment has its own allowed-domains list; there’s no organization-level allowlist that admins can push to every member’s environments. No [server-managed setting](../13-Enterprise-Admin/server-managed-settings.md) adds domains to an environment’s network allowlist either. To give a team one standard list, an Owner can create an [organization-shared environment](#organization-shared-environments) with **Custom** network access and that list.


[​](#github-proxy)


In Anthropic-hosted environments, all GitHub operations go through a dedicated proxy that keeps your real GitHub credentials outside the session’s VM, independent of the environment’s [access level](#access-levels). Sessions in a self-hosted environment authenticate git operations with credentials your deployment provides; [Configure git](../13-Enterprise-Admin/self-hosted-environments-deploy.md#configure-git) covers the options, including per-session minted credentials and an opt-in to this same proxy. The proxy provides:

- **Git credentials**: the git client inside the VM uses a scoped credential, which the proxy verifies and swaps for your actual GitHub token.
- **API requests**: requests from the built-in GitHub tools, and from `gh` under the [`proxy-injected` placeholder](#work-with-github-issues-and-pull-requests), go out with your real credentials substituted.
- **Push restrictions**: the proxy rejects branch deletions and pushes of anything other than a branch, such as a tag. It doesn’t limit which branches a push can update. To do that, use branch protection rules or rulesets on GitHub.
- **Repository scope**: the proxy serves GitHub API requests for the repositories attached to the session. An API request for another repository gets a 403 whose message starts with `GitHub access to` and contains `is not enabled for this session`. A source archive you fetch over a `github.com/{owner}/{repo}/archive/` or `codeload.github.com` URL gets that same 403 when the repository isn’t attached, even a public one.
- **GraphQL restrictions**: the proxy rejects requests to GitHub’s GraphQL endpoint with a 403 whose message starts with `GitHub GraphQL is not available from Claude Code sessions` and names the REST fallback, `gh api repos/{owner}/{repo}/...`. `gh` subcommands that use GraphQL, such as `gh pr` and `gh issue`, get the same 403. The restriction applies to every request through the proxy regardless of the credentials you supply, so a `GH_TOKEN` you set gets the same 403. Claude can’t reach GitHub APIs that exist only in GraphQL, such as Projects v2, through the proxy.

Committed files from public repositories arrive through `raw.githubusercontent.com`, which the [security proxy](#security-proxy) handles instead. That domain is in the default [Trusted list](#default-allowed-domains), so those files stay reachable unless the environment’s [access level](#access-levels) excludes it.


[​](#security-proxy)

Security proxy

Cloud sessions in Anthropic-hosted environments run behind an HTTP/HTTPS network proxy for security and abuse prevention purposes; in a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments-deploy.md#default-deny-egress), outbound traffic leaves through your own network boundary instead. All outbound internet traffic from an Anthropic-hosted session passes through this proxy, which provides:

- Protection against malicious requests
- Rate limiting and abuse prevention


[​](#what’s-available-in-cloud-sessions)

What’s available in cloud sessions

In Anthropic-hosted environments, each session gets a fresh virtual machine (VM) running Ubuntu 24.04 on x86_64, regardless of your own operating system and CPU architecture, with your repository cloned and common toolchains pre-installed. When a dependency provides precompiled binaries, such as Ruby gems with native extensions or prebuilt Python wheels, use its x86_64 Linux build to match the VM. This section covers the Anthropic-hosted defaults, the built-in GitHub tools, how to [run tests and services](#run-tests-start-services-and-add-packages), the [resource limits](#resource-limits) each VM gets, and the [time limits](#time-limits) on long-running work.

Sessions your organization routes to a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) run on your own runners instead, with the tools your runner image provides.


[​](#what-carries-over-from-your-setup)

What carries over from your setup

Of the repository configuration in this table, a cloud thread in a [project](claude-projects.md) loads only the repository root’s `CLAUDE.md`, `.claude/CLAUDE.md`, and `.claude/rules/` files that aren’t [path-specific](memory.md#path-specific-rules). See [What threads pick up from your repositories](claude-projects.md#what-threads-pick-up-from-your-repositories).

Cloud sessions start from a fresh clone of your repository. Anything you commit to the repo is available. Anything you’ve installed or configured only on your own machine isn’t available in the session. Your organization’s policy arrives separately through [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md).

|                                                                                                                                                                                                | Available in cloud sessions                                                       | Why                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Your repo’s `CLAUDE.md`                                                                                                                                                                        | Yes                                                                               | Part of the clone                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| Your repo’s `.claude/settings.json` hooks and permission rules                                                                                                                                 | Yes, in a session with one repository                                             | Part of the clone. For a session with several repositories, see [which settings it reads](settings.md#settings-in-cloud-sessions)                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| Your repo’s `.mcp.json` MCP servers                                                                                                                                                            | Yes, in a session with one repository                                             | Part of the clone, found from the session’s working directory. For a self-hosted environment, see [which repository’s settings apply](../13-Enterprise-Admin/self-hosted-environments-configuration.md#repository-settings-in-sessions-with-several-repositories)                                                                                                                                                                                                                                                                                                                                   |
| Your repo’s `.claude/rules/`                                                                                                                                                                   | Yes                                                                               | Part of the clone                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| Your repo’s `.claude/skills/`, `.claude/agents/`, `.claude/commands/`                                                                                                                          | Yes                                                                               | Part of the clone                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| Plugins and marketplaces declared in your repo’s `.claude/settings.json`                                                                                                                       | No                                                                                | A cloud session doesn’t install the plugins a repository turns on under [`enabledPlugins`](settings-reference.md#enabledplugins), including ones from the marketplaces it lists under [`extraKnownMarketplaces`](settings-reference.md#extraknownmarketplaces)                                                                                                                                                                                                                                                                                                         |
| Your organization’s [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md)                                                                                                                | Yes, except in [Claude Tag](https://claude.com/docs/claude-tag/overview) sessions | Fetched from Anthropic’s servers when the session starts. See [Surface coverage](model-config.md#surface-coverage) for how `availableModels` is enforced in cloud sessions. Settings deployed to your device through MDM or managed settings files don’t apply, because the session runs on an Anthropic-managed VM; in a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md), sessions also read the managed settings file in the runner image, per [how Claude Code combines managed sources](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) |
| Your user `~/.claude/CLAUDE.md`                                                                                                                                                                | No                                                                                | Lives on your machine, not in the repo. See [Add personal preferences without committing to the repo](#add-personal-preferences-without-committing-to-the-repo)                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Your user `~/.claude/skills/`, `~/.claude/agents/`, `~/.claude/commands/`                                                                                                                      | No                                                                                | Live on your machine, not in the repo. Commit them to the repo’s `.claude/` directory instead. Cloud sessions automatically load [skills you enable on claude.ai](../08-Plugins-Skills/skills.md#skills-in-cowork-and-cloud-sessions)                                                                                                                                                                                                                                                                                                                                                             |
| Plugins enabled only in your user settings                                                                                                                                                     | No                                                                                | User-scoped `enabledPlugins` lives in `~/.claude/settings.json` on your machine                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| MCP servers you added with `claude mcp add` at the default local scope or the user scope                                                                                                       | No                                                                                | Those write to `~/.claude.json` on your machine, not the repo. Add the server with `claude mcp add --scope project`, which writes the repo’s [`.mcp.json`](../06-MCP-Tools/General/mcp.md#project-scope), and commit that file. A session with one repository loads it                                                                                                                                                                                                                                                                                                                               |
| Transport variables in your repo’s `.claude/settings.json` `env` block, such as `NODE_EXTRA_CA_CERTS` and the [mTLS client certificate variables](../13-Enterprise-Admin/network-config.md#mtls-authentication) | No                                                                                | The hosting environment manages the session’s API connection, so Claude Code ignores these keys and notes each ignored key in the session’s debug log                                                                                                                                                                                                                                                                                                                                                                                                                              |
| API keys and tokens for services Claude calls                                                                                                                                                  | In an Anthropic-hosted environment, as [network secrets](#add-network-secrets)    | You add the key once on the environment and the agent proxy attaches it to requests for the hosts you list. A key the agent proxy [can’t attach](#requests-that-never-get-the-credential) stays in an environment variable                                                                                                                                                                                                                                                                                                                                                         |
| Interactive auth like AWS SSO                                                                                                                                                                  | No                                                                                | Not supported. SSO requires browser-based login that can’t run in a cloud session                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |

To make your own configuration available in cloud sessions, commit it to the repo. Anyone who uses the environment can read its environment variables and setup script. The dialog’s note under **Environment variables** says so and warns against putting secrets there. In an Anthropic-hosted environment, store a key the agent proxy can attach as a [network secret](#add-network-secrets) instead.


[​](#add-personal-preferences-without-committing-to-the-repo)

Add personal preferences without committing to the repo

In an Anthropic-hosted environment, add a [setup script](#setup-scripts) that writes `~/.claude/CLAUDE.md` for preferences you’d rather not put in a shared repository. Claude Code loads that file as [user instructions](memory.md#choose-where-to-put-claude-md-files) in the session. This example sets a commit-message preference:

```python
#!/bin/bash
mkdir -p ~/.claude
cat > ~/.claude/CLAUDE.md <<'EOF'
Use conventional commit messages.
EOF
```

Put the script on one of your own environments rather than a [shared one](#organization-shared-environments). Run `/context` in your next cloud session and confirm `/root/.claude/CLAUDE.md` appears under **Memory files**.


[​](#installed-tools)

Installed tools

Cloud sessions come with common language runtimes, build tools, and databases pre-installed. The table below summarizes what’s included by category.

| Category      | Included                                                                   |
|:--------------|:---------------------------------------------------------------------------|
| **Python**    | Python 3.x with pip, poetry, uv, black, mypy, pytest, ruff                 |
| **Node.js**   | 20, 21, and 22, with npm, yarn, pnpm, bun¹, eslint, prettier, chromedriver |
| **Ruby**      | 3.1, 3.2, 3.3 with gem, bundler, rbenv                                     |
| **PHP**       | 8.3 with Composer                                                          |
| **Java**      | OpenJDK 21 with Maven and Gradle                                           |
| **Go**        | Go with module support                                                     |
| **Rust**      | rustc and cargo                                                            |
| **C/C++**     | GCC, Clang, cmake, ninja, conan                                            |
| **Docker**    | docker, dockerd, docker compose                                            |
| **Databases** | PostgreSQL 16, Redis 7.0                                                   |
| **Utilities** | git, gh, jq, yq, ripgrep, tmux, vim, nano                                  |

¹ Bun is installed but has known [proxy compatibility issues](#install-dependencies-with-a-sessionstart-hook) for package fetching. To get the versions of most of the tools in this table, ask Claude to run `check-tools` in a cloud session. It’s a shell command installed on the session VM, not a command you type with `/`; you ask Claude because [Claude runs all VM commands for you](#run-tests-start-services-and-add-packages). For a tool it doesn’t report, such as Ruby, PHP, bun, PostgreSQL, or Redis, ask Claude to run the tool’s own version command, for example `psql --version`. Node.js versions are installed at `/opt/node20`, `/opt/node21`, and `/opt/node22`, with 22 on `PATH` by default. To work with a different version, ask Claude to prepend that version’s `bin` directory, such as `/opt/node20/bin`, to `PATH`. Toolchains outside this list, such as the .NET SDK, aren’t pre-installed even when their package registries are on the [default allowlist](#default-allowed-domains). Install them with a [setup script](#setup-scripts).


[​](#work-with-github-issues-and-pull-requests)

Work with GitHub issues and pull requests

Cloud sessions include built-in GitHub tools that let Claude read issues, list pull requests, fetch diffs, and post comments without any setup. These tools authenticate through the [GitHub proxy](#github-proxy) using whichever method you configured under [GitHub authentication options](claude-code-on-the-web.md#github-authentication-options), so your token never enters the container. You can set `GH_TOKEN` or `GITHUB_TOKEN` yourself in [environment settings](#set-environment-variables), or leave both unset and let the [GitHub proxy](#github-proxy) authenticate for you:

- If you set a token, it passes through to the container unchanged, so your scripts and GitHub’s [`gh` CLI](https://cli.github.com) use it directly.
- If you set neither and the [GitHub proxy](#github-proxy) is handling authentication for your session, both variables read as the placeholder string `proxy-injected` in the commands Claude runs, and the proxy substitutes your real credentials on outbound GitHub requests. `gh api` calls for attached repositories work without a token of your own, but a script that reads `GITHUB_TOKEN` directly gets the placeholder, not a usable token.

A token you set is an ordinary environment variable, so anyone who uses the environment can read it; the proxy path keeps the credential out of the environment configuration and the session VM. To check which case applies to your session, ask Claude to run `echo $GH_TOKEN`. GitHub’s [`gh` CLI](https://cli.github.com) is pre-installed. If you need a GitHub operation the built-in tools don’t cover, ask Claude to call the REST API with `gh api`. `gh` subcommands that use the REST API, such as `gh workflow list`, work too. The proxy [rejects subcommands that use GraphQL](#github-proxy), such as `gh pr` and `gh issue`. `gh` reads `GH_TOKEN` automatically, so you don’t need to run `gh auth login`.


[​](#link-output-back-to-the-session)

Link output back to the session

Each cloud session has a transcript URL on claude.ai, and the session can read its own ID from the `CLAUDE_CODE_REMOTE_SESSION_ID` environment variable. Use this to put a traceable link in PR bodies, commit messages, Slack posts, or generated reports so a reviewer can open the run that produced them. Commits that Claude creates in a cloud session include a `Claude-Session: <url>` git trailer, and PR bodies include the session URL on its own line. To omit the trailer and the PR-body link, set [`attribution.sessionUrl`](settings-reference.md#attribution-sessionurl) to `false`. To include the session link in something other than a commit or PR, such as a Slack message Claude posts or a report file it writes, have Claude run the following command and use its output. The command converts the `cse_` prefix in the environment variable’s value to the `session_` prefix that the transcript URL expects:

```python
echo "https://claude.ai/code/${CLAUDE_CODE_REMOTE_SESSION_ID/#cse_/session_}"
```


[​](#run-tests-start-services-and-add-packages)

Run tests, start services, and add packages

You don’t get a shell into the session VM. Claude runs every command for you, so phrase the tasks in this section as requests in your prompt.


[​](#run-tests)

Run tests

Claude runs tests as part of working on a task. Ask for it in your prompt, like “fix the failing tests in `tests/`” or “run pytest after each change.” Test runners that come with the [pre-installed toolchains](#installed-tools), like pytest and cargo test, work without additional setup. A runner your project declares as a dependency, like jest, installs with your dependencies.


[​](#start-services)

Start services

PostgreSQL and Redis are pre-installed but not running by default. Ask Claude to start whichever you need; the commands it runs are:

```python
service postgresql start
```

```python
service redis-server start
```

Docker is available for running containerized services. Ask Claude to run `docker compose up` to start your project’s services. Network access to pull images follows your environment’s [access level](#access-levels), and the [Trusted defaults](#default-allowed-domains) include Docker Hub and other common registries. If your images are large or slow to pull, add `docker compose pull` or `docker compose build` to your [setup script](#setup-scripts). The [environment cache](#environment-caching) keeps the pulled images, so each new session has them on disk. The cache stores files only, not running processes, so Claude still starts the containers each session.


[​](#add-packages)

Add packages

To add packages that aren’t pre-installed, use a [setup script](#setup-scripts). The [environment cache](#environment-caching) keeps what the script installs, so packages you install there are available at the start of every session without reinstalling each time. You can also ask Claude to install packages mid-session, but those installs don’t carry over to other sessions.


[​](#resource-limits)

Resource limits

Cloud sessions in Anthropic-hosted environments run with approximate resource ceilings that may change over time:

- 4 vCPUs
- 16 GB of RAM
- 30 GB of disk

The VM may stop tasks that need significantly more memory, such as large build jobs or memory-intensive tests. For workloads beyond these limits, use [Remote Control](remote-control.md) to run Claude Code on your own hardware, or run cloud sessions in a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) on compute your organization operates.


[​](#time-limits)

Time limits

In Anthropic-hosted environments, these time limits apply to long-running work in a cloud session, such as a build, an install, or a test run. Each entry links to the section that defines the limit.

- **Commands Claude runs**: a cloud environment doesn’t set its own command timeout, so the Bash tool’s defaults apply. Claude waits 2 minutes for a foreground command by default and can ask for up to 10 minutes. When a command reaches its [timeout](tools-reference.md#timeout-and-output-limits), Claude Code [moves it to the background](tools-reference.md#foreground-commands-that-move-to-the-background) instead of stopping it, unless the command starts with `sleep`. A command moved this way can keep running for up to 30 more minutes before Claude Code stops it at its [background time limit](tools-reference.md#time-limit-for-background-commands). Setting `BASH_DEFAULT_TIMEOUT_MS` above `1800000` milliseconds lengthens that limit as well as the foreground default.
- **SessionStart hooks**: Claude Code cancels a `command` hook after 600 seconds unless you set [`timeout`](../07-Hooks/hooks.md#common-fields), in seconds, on the hook entry. Claude Code doesn’t enforce the timeout on a hook you run with [`async: true`](../07-Hooks/hooks.md#run-hooks-in-the-background).
- **Setup script**: a script that takes longer than roughly five minutes isn’t cached. [Script requirements](#script-requirements) covers how to stay under that.
- **Idle sessions**: after a few minutes without activity, a session’s VM pauses with its files saved, and a paused VM can later be reclaimed. [Set environment variables](#set-environment-variables) describes what a session picks up in each case, and [Environment expired](claude-code-on-the-web.md#environment-expired) covers how to reopen a session whose VM was reclaimed.

To raise the command timeouts for an environment’s sessions, add [`BASH_DEFAULT_TIMEOUT_MS` and `BASH_MAX_TIMEOUT_MS`](env-vars.md#variables) to its [environment variables](#set-environment-variables). Both take milliseconds. For example, `BASH_DEFAULT_TIMEOUT_MS=600000` makes 10 minutes the default.


[​](#setup-scripts)

Setup scripts

A setup script is a Bash script that runs when a new cloud session starts, before Claude Code launches. Use setup scripts to install dependencies, configure tools, or fetch anything the session needs that isn’t pre-installed. Scripts run as root on Ubuntu 24.04, so `apt install` and most language package managers work. To add a setup script, open the environment settings dialog and enter your script in the **Setup script** field. This example installs [ShellCheck](https://www.shellcheck.net/), which isn’t pre-installed.

```python
#!/bin/bash
apt update && apt install -y shellcheck
```


[​](#script-requirements)

Script requirements

A setup script has three constraints to write around:

- **Exit zero**: if the script exits non-zero, the session fails to start. Append `|| true` to non-critical commands so an intermittent install failure doesn’t block the session.
- **Finish within five minutes**: keep the script’s total runtime under roughly five minutes so the [environment cache](#environment-caching) can build. When setup takes longer than that, the environment isn’t cached. Run independent installs in parallel with `&` and `wait`, and move any single download that won’t fit into a [SessionStart hook](#setup-scripts-vs-sessionstart-hooks) that launches it in the background. If new sessions stall or fail during setup, see [New sessions hang or time out during setup](web-quickstart.md#new-sessions-hang-or-time-out-during-setup).
- **Network access for installs**: package installs need to reach registries. The default **Trusted** level covers [common package registries](#default-allowed-domains) including npm, PyPI, RubyGems, and crates.io; with **None** network access, installs fail.


[​](#environment-caching)

Environment caching

The setup script runs the first time you start a session in an environment. When setup completes within [roughly five minutes](#script-requirements), Anthropic snapshots the filesystem and reuses that snapshot as the starting point for later sessions. New sessions start with your dependencies, tools, and Docker images already on disk, and skip the setup script step. This keeps startup fast even when the script installs large toolchains or pulls container images. If setup takes longer than roughly five minutes, the environment isn’t cached. The cache is a filesystem snapshot, so it keeps what the setup script writes to disk and loses anything that was only running. Packages you install, Docker images you pull, and files you write all carry over. A database the script started, a `docker compose up` stack, or any other background process doesn’t; start those per session by asking Claude or with a [SessionStart hook](#setup-scripts-vs-sessionstart-hooks). The setup script runs again to rebuild the cache when you change the environment’s setup script or allowed network hosts, and when the cache reaches its expiry after roughly seven days. In an Anthropic-hosted environment, the setup script doesn’t run when a session’s VM is [restored after being idle](#set-environment-variables), so a change to the script reaches an existing session only when its VM was [reclaimed](claude-code-on-the-web.md#environment-expired) and is rebuilt. To apply a change right away, run the commands in the session or start a new session. You don’t need to enable caching or manage snapshots yourself.


[​](#setup-scripts-vs-sessionstart-hooks)

Setup scripts vs. SessionStart hooks

Use a setup script to provision the VM itself: toolchains and CLI tools that aren’t [pre-installed](#installed-tools). Use a [SessionStart hook](../07-Hooks/hooks.md#sessionstart) for project setup that should run everywhere, cloud and local, like `npm install`. Setup scripts and SessionStart hooks run in a fixed order when a cloud session starts. The table compares where you configure them, when they run, and where they run.

|                              | Setup scripts                                                                                                                                                               | SessionStart hooks                                                                                                                                                                                                      |
|------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Where you configure them** | The environment dialog at [claude.ai/code](https://claude.ai/code), plus the **Cloud environments** admin page for [shared environments](#organization-shared-environments) | A [settings file](settings.md#where-settings-live) such as your repo’s `.claude/settings.json`; see [What carries over from your setup](#what-carries-over-from-your-setup) for which files reach a cloud session |
| **When they run**            | Before Claude Code launches, skipped when a [cached environment](#environment-caching) exists                                                                               | After Claude Code launches, on every session including resumed                                                                                                                                                          |
| **Where they run**           | Cloud sessions only                                                                                                                                                         | Local and cloud sessions                                                                                                                                                                                                |

If you have SessionStart hooks in your user-level `~/.claude/settings.json`, don’t expect them in the cloud. User-level settings stay on your machine. Which other hooks run depends on where the session runs:

- **Anthropic-hosted environment**: Claude Code runs hooks from your organization’s [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) and, outside a [project](claude-projects.md#what-threads-pick-up-from-your-repositories) thread, from the repository. [Claude Tag](https://claude.com/docs/claude-tag/overview) sessions don’t receive server-managed settings, so hooks from server-managed settings don’t run there.
- **[Self-hosted environment](../13-Enterprise-Admin/self-hosted-environments-configuration.md#permissions-and-tool-approval)**: Claude Code also runs the hooks the operator seeded from the runner host’s `~/.claude/`, and the hooks in the runner image’s managed settings file when that file is one of the [managed sources Claude Code applies](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources).


[​](#install-dependencies-with-a-sessionstart-hook)

Install dependencies with a SessionStart hook

To install dependencies only in cloud sessions outside a [project](claude-projects.md#what-threads-pick-up-from-your-repositories)’s threads, pair a SessionStart hook with a script that checks where it’s running. First, add a SessionStart hook to your repo’s `.claude/settings.json`. This configuration tells Claude Code to run `scripts/install_pkgs.sh` from your repository whenever a session starts or resumes:

```python
{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup|resume",
        "hooks": [
          {
            "type": "command",
            "command": "bash \"$CLAUDE_PROJECT_DIR\"/scripts/install_pkgs.sh"
          }
        ]
      }
    ]
  }
}
```

The `matcher` limits the hook to the `startup` and `resume` events, and `$CLAUDE_PROJECT_DIR` resolves to the repository root, so the hook finds the script regardless of the session’s working directory. Next, create the script at `scripts/install_pkgs.sh`. It exits immediately outside the cloud, then installs your dependencies. It skips `npm install` while `package.json`, `package-lock.json`, and the script itself are unchanged since the last successful install:

```python
#!/bin/bash

if [ "$CLAUDE_CODE_REMOTE" != "true" ]; then
  exit 0
fi

cd "$CLAUDE_PROJECT_DIR" || exit 1
hashes=node_modules/.install_pkgs.sha256

if ! sha256sum --check --status "$hashes" 2>/dev/null; then
  # Delete the old hashes first, so a failed install runs again next time
  rm -f "$hashes"
  if npm install; then
    sha256sum scripts/install_pkgs.sh package.json package-lock.json > "$hashes" || rm -f "$hashes"
  fi
fi

# pip skips requirements that are already satisfied
pip install -r requirements.txt
exit 0
```

The `CLAUDE_CODE_REMOTE` check is what scopes the install to cloud sessions: the session VM’s environment carries that variable as `true`, it’s never `true` locally, so on your laptop the script exits before installing anything. To confirm `npm install` succeeded, start a cloud session and ask Claude to show `node_modules/.install_pkgs.sha256`. The file lists a hash for each of the three files. If the file is missing, ask Claude to run `npm install` and report the error.

If `npm install` reads other files, such as a workspace’s `package.json`, an `.npmrc`, or your `postinstall` script’s inputs, add them to the `sha256sum` command that saves the hashes. Otherwise, you keep the old packages after one of those files changes.


[​](#limitations-in-cloud-sessions)

Limitations in cloud sessions

SessionStart hooks behave the same in the cloud as locally, with these caveats:

- **One repository per session**: in an Anthropic-hosted environment, a session with several repositories doesn’t load hooks from any repository’s `.claude/settings.json`, so a SessionStart hook you define there doesn’t run. Install dependencies for those sessions with a [setup script](#setup-scripts) instead. For a self-hosted environment, see [which repository’s settings apply](../13-Enterprise-Admin/self-hosted-environments-configuration.md#repository-settings-in-sessions-with-several-repositories).
- **Not in a project’s cloud threads**: a cloud thread in a [project](claude-projects.md#what-threads-pick-up-from-your-repositories) doesn’t run hooks from a repository’s `.claude/settings.json`, whatever the number of repositories. In an Anthropic-hosted environment, install dependencies for threads with a [setup script](#setup-scripts). In a self-hosted environment, use a hook in the [runner host’s settings](../13-Enterprise-Admin/self-hosted-environments-configuration.md#repository-settings-in-sessions-with-several-repositories) instead.
- **No cloud-only scoping**: hooks run in both local and cloud sessions. To skip local execution, exit early unless the `CLAUDE_CODE_REMOTE` environment variable is `true`, the way the [dependency install script](#install-dependencies-with-a-sessionstart-hook) does.
- **Requires network access**: install commands need to reach package registries. If your environment uses **None** network access, these hooks fail. The [default allowlist](#default-allowed-domains) under **Trusted** covers npm, PyPI, RubyGems, and crates.io.
- **Proxy compatibility**: in Anthropic-hosted environments, all outbound traffic passes through a [security proxy](#security-proxy), and some package managers don’t work correctly with it; Bun is a known example. In a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments-deploy.md#default-deny-egress), outbound traffic goes through your own network boundary instead.
- **Adds startup latency**: hooks run each time a session starts or resumes, unlike setup scripts which benefit from [environment caching](#environment-caching). Keep install scripts fast by skipping work that’s already done, the way the [dependency install script](#install-dependencies-with-a-sessionstart-hook) does.

To customize the base image, use a setup script to install what you need on top of the [provided image](#installed-tools), or run your own image as a container alongside Claude with `docker compose`. Replacing the base image entirely isn’t supported yet.


[​](#default-allowed-domains)

Default allowed domains

With **Trusted** network access, sessions can reach the following domains by default. Domains marked with `*` indicate wildcard subdomain matching, so `*.gcr.io` allows any subdomain of `gcr.io`.

Anthropic services

- api.anthropic.com
- docs.claude.com
- platform.claude.com
- code.claude.com
- claude.ai
- claude.com
- support.claude.com
- anthropic.com
- [www.anthropic.com](http://www.anthropic.com)

Version control

- github.com
- [www.github.com](http://www.github.com)
- api.github.com
- npm.pkg.github.com
- raw.githubusercontent.com
- pkg-npm.githubusercontent.com
- objects.githubusercontent.com
- release-assets.githubusercontent.com
- codeload.github.com
- avatars.githubusercontent.com
- camo.githubusercontent.com
- gist.github.com
- gitlab.com
- [www.gitlab.com](http://www.gitlab.com)
- registry.gitlab.com
- bitbucket.org
- [www.bitbucket.org](http://www.bitbucket.org)
- api.bitbucket.org

Container registries

- registry-1.docker.io
- auth.docker.io
- index.docker.io
- hub.docker.com
- [www.docker.com](http://www.docker.com)
- production.cloudflare.docker.com
- production.cloudfront.docker.com
- download.docker.com
- gcr.io
- \*.gcr.io
- ghcr.io
- mcr.microsoft.com
- \*.data.mcr.microsoft.com
- public.ecr.aws

Cloud platforms

- cloud.google.com
- accounts.google.com
- gcloud.google.com
- \*.googleapis.com
- storage.googleapis.com
- compute.googleapis.com
- container.googleapis.com
- azure.com
- portal.azure.com
- microsoft.com
- [www.microsoft.com](http://www.microsoft.com)
- \*.microsoftonline.com
- packages.microsoft.com
- dotnet.microsoft.com
- dot.net
- visualstudio.com
- dev.azure.com
- \*.amazonaws.com
- \*.api.aws
- oracle.com
- [www.oracle.com](http://www.oracle.com)
- java.com
- [www.java.com](http://www.java.com)
- java.net
- [www.java.net](http://www.java.net)
- download.oracle.com
- yum.oracle.com
- \*.r2.cloudflarestorage.com

JavaScript and Node package managers

- registry.npmjs.org
- [www.npmjs.com](http://www.npmjs.com)
- [www.npmjs.org](http://www.npmjs.org)
- npmjs.com
- npmjs.org
- yarnpkg.com
- registry.yarnpkg.com
- jsr.io
- npm.jsr.io

Python package managers

- pypi.org
- [www.pypi.org](http://www.pypi.org)
- files.pythonhosted.org
- pythonhosted.org
- test.pypi.org
- pypi.python.org
- pypa.io
- [www.pypa.io](http://www.pypa.io)

Ruby package managers

- rubygems.org
- [www.rubygems.org](http://www.rubygems.org)
- api.rubygems.org
- index.rubygems.org
- ruby-lang.org
- [www.ruby-lang.org](http://www.ruby-lang.org)
- rubyforge.org
- [www.rubyforge.org](http://www.rubyforge.org)
- rubyonrails.org
- [www.rubyonrails.org](http://www.rubyonrails.org)
- rvm.io
- get.rvm.io

Rust package managers

- crates.io
- [www.crates.io](http://www.crates.io)
- index.crates.io
- static.crates.io
- rustup.rs
- static.rust-lang.org
- [www.rust-lang.org](http://www.rust-lang.org)

Go package managers

- proxy.golang.org
- sum.golang.org
- index.golang.org
- golang.org
- [www.golang.org](http://www.golang.org)
- goproxy.io
- pkg.go.dev

JVM package managers

- maven.org
- repo.maven.org
- central.maven.org
- repo1.maven.org
- repo.maven.apache.org
- maven.google.com
- jcenter.bintray.com
- gradle.org
- [www.gradle.org](http://www.gradle.org)
- services.gradle.org
- plugins.gradle.org
- plugins-artifacts.gradle.org
- kotlinlang.org
- [www.kotlinlang.org](http://www.kotlinlang.org)
- spring.io
- repo.spring.io

Other package managers

- packagist.org (PHP Composer)
- [www.packagist.org](http://www.packagist.org)
- repo.packagist.org
- nuget.org (.NET NuGet)
- [www.nuget.org](http://www.nuget.org)
- api.nuget.org
- pub.dev (Dart/Flutter)
- api.pub.dev
- hex.pm (Elixir/Erlang)
- [www.hex.pm](http://www.hex.pm)
- cpan.org (Perl CPAN)
- [www.cpan.org](http://www.cpan.org)
- metacpan.org
- [www.metacpan.org](http://www.metacpan.org)
- api.metacpan.org
- cocoapods.org (iOS/macOS)
- [www.cocoapods.org](http://www.cocoapods.org)
- cdn.cocoapods.org
- haskell.org
- [www.haskell.org](http://www.haskell.org)
- hackage.haskell.org
- swift.org
- [www.swift.org](http://www.swift.org)

Linux distributions

- archive.ubuntu.com
- security.ubuntu.com
- ubuntu.com
- [www.ubuntu.com](http://www.ubuntu.com)
- \*.ubuntu.com
- ppa.launchpad.net
- launchpad.net
- [www.launchpad.net](http://www.launchpad.net)
- \*.nixos.org

Development tools and platforms

- dl.k8s.io (Kubernetes)
- pkgs.k8s.io
- k8s.io
- [www.k8s.io](http://www.k8s.io)
- releases.hashicorp.com (HashiCorp)
- apt.releases.hashicorp.com
- rpm.releases.hashicorp.com
- archive.releases.hashicorp.com
- hashicorp.com
- [www.hashicorp.com](http://www.hashicorp.com)
- repo.anaconda.com (Anaconda/Conda)
- conda.anaconda.org
- anaconda.org
- [www.anaconda.com](http://www.anaconda.com)
- anaconda.com
- continuum.io
- apache.org (Apache)
- [www.apache.org](http://www.apache.org)
- archive.apache.org
- downloads.apache.org
- eclipse.org (Eclipse)
- [www.eclipse.org](http://www.eclipse.org)
- download.eclipse.org
- nodejs.org (Node.js)
- [www.nodejs.org](http://www.nodejs.org)
- developer.apple.com
- developer.android.com
- pkg.stainless.com
- binaries.prisma.sh

Cloud services and monitoring

- http-intake.logs.datadoghq.com
- \*.datadoghq.com
- \*.datadoghq.eu
- api.honeycomb.io

Content delivery and mirrors

- sourceforge.net
- \*.sourceforge.net
- packagecloud.io
- \*.packagecloud.io
- fonts.googleapis.com
- fonts.gstatic.com

Schema and configuration

- json-schema.org
- [www.json-schema.org](http://www.json-schema.org)
- json.schemastore.org
- [www.schemastore.org](http://www.schemastore.org)

Model Context Protocol

- \*.modelcontextprotocol.io


[​](#related-resources)

Related resources

- [Cloud sessions reference](claude-code-on-the-web.md): start, manage, and share cloud sessions
- [Cloud sessions quickstart](web-quickstart.md): connect GitHub and start your first cloud session
- [Claude Tag](https://claude.com/docs/claude-tag/overview): sessions Claude starts from Slack run in the same environments
- [Cloud scheduled tasks](web-scheduled-tasks.md): scheduled runs use the same environments and network access levels
- [Remote Control](remote-control.md): run sessions on your own machine’s network and files instead
- [Self-hosted environments](../13-Enterprise-Admin/self-hosted-environments.md): run cloud sessions on your organization’s own infrastructure
- [SessionStart hooks](../07-Hooks/hooks.md#sessionstart): repo-committed setup that runs in local and cloud sessions
- [Server-managed settings](../13-Enterprise-Admin/server-managed-settings.md): organization policy delivered from the admin console

---

## Overview - Claude Code Docs

Source: https://code.claude.com/docs
Path: 02-Claude-Code-CLI/code-home.md

## On this page

- [Get started](#get-started)
- [What you can do](#what-you-can-do)
- [Use Claude Code everywhere](#use-claude-code-everywhere)
- [Next steps](#next-steps)

Getting started

# Overview

Copy pageCopy page

Claude Code is an agentic coding tool that reads your codebase, edits files, runs commands, and integrates with your development tools. Available in your terminal, IDE, desktop app, and browser.

Copy pageCopy page

Claude Code is an AI-powered coding assistant that helps you build features, fix bugs, and automate development tasks. It understands your entire codebase and can work across multiple files and tools to get things done.


[​](#get-started)

Get started

Claude Code runs on several surfaces: the terminal, IDE extensions, a desktop app, and the web. Choose one from the tabs below to get started. Most surfaces require a [Claude subscription](../17-Billing-Plans/pricing.md) or [Anthropic Console](../04-API-Reference/Other/playground.md) account. The Terminal CLI, VS Code, and JetBrains also support [third-party providers](third-party-integrations.md).

- Terminal

- VS Code

- Desktop app

- Web

- JetBrains

The full-featured CLI for working with Claude Code directly in your terminal. Edit files, run commands, and manage your entire project from the command line.To install Claude Code, open a terminal and run the command for your system. If you haven’t used a terminal before, the [terminal guide](terminal-guide.md) shows how to open one and paste the command.

- Native Install (Recommended)

- Homebrew

- WinGet

**macOS, Linux, WSL:**

```python
curl -fsSL https://claude.ai/install.sh | bash
```

On Windows, your prompt shows `PS C:\` when you’re in PowerShell and `C:\` without the `PS` when you’re in CMD.**Windows PowerShell:**

```python
irm https://claude.ai/install.ps1 | iex
```

**Windows CMD:**

```python
curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd
```

The install command shows no progress while it downloads Claude Code. When the installer finishes, open a new terminal window and run `claude --version`. A working installation prints a version number. If your shell says `claude` isn’t found or isn’t recognized, the install directory isn’t on your PATH yet: see [Fix your PATH](troubleshoot-install.md#command-not-found-claude-after-installation).If you see `The token '&&' is not a valid statement separator`, you’re in PowerShell, not CMD. If you see `'irm' is not recognized as an internal or external command`, you’re in CMD, not PowerShell.If the install command fails with `syntax error near unexpected token '<'`, a `403`, or any other error, see [Troubleshoot installation](troubleshoot-install.md#find-your-error) to match the error to a fix and for alternative install methods.[Git for Windows](https://git-scm.com/downloads/win) is recommended on native Windows so Claude Code can use the Bash tool. If Git for Windows is not installed, Claude Code uses PowerShell as the shell tool instead. WSL setups do not need Git for Windows.

Native installations automatically update in the background to keep you on the latest version.

```python
brew install --cask claude-code
```

Homebrew offers two casks. `claude-code` tracks the stable release channel, which is typically about a week behind and skips releases with major regressions. `claude-code@latest` tracks the latest channel and receives new versions as soon as they ship.

Homebrew installations do not auto-update. Run `brew upgrade claude-code` or `brew upgrade claude-code@latest`, depending on which cask you installed, to get the latest features and security fixes.

```python
winget install Anthropic.ClaudeCode
```

WinGet installations do not auto-update. Run `winget upgrade Anthropic.ClaudeCode` periodically to get the latest features and security fixes.

You can also install with [apt, dnf, or apk](../01-Getting-Started/setup.md#install-with-linux-package-managers) on Debian, Fedora, RHEL, and Alpine.Then start Claude Code in any project. Replace `your-project` with the path to a project directory on your machine:

```python
cd your-project
claude
```

Claude Code prompts you to log in on first use. If you’ve set the `ANTHROPIC_API_KEY` environment variable and you approve the key when Claude Code asks whether to use it, Claude Code skips the login prompt. [Continue with the Quickstart →](../01-Getting-Started/quickstart.md)

See [advanced setup](../01-Getting-Started/setup.md) for installation options, manual updates, or uninstallation instructions. Visit [installation troubleshooting](troubleshoot-install.md) if you hit issues.

The VS Code extension provides inline diffs, @-mentions, plan review, and conversation history directly in your editor.

- [Install for VS Code](vscode:extension/anthropic.claude-code)
- [Install for Cursor](cursor:extension/anthropic.claude-code)

Or search for “Claude Code” in the Extensions view (`Cmd+Shift+X` on Mac, `Ctrl+Shift+X` on Windows/Linux). After installing, open the Command Palette (`Cmd+Shift+P` / `Ctrl+Shift+P`), type “Claude Code”, and select **Open in New Tab**.[Get started with VS Code →](../03-IDE-Integrations/vs-code.md#get-started)

A standalone app for running Claude Code outside your IDE or terminal. Review diffs visually, run multiple sessions side by side, schedule recurring tasks, and start cloud sessions.Download and install:

- [macOS](https://claude.ai/api/desktop/darwin/universal/dmg/latest/redirect?utm_source=claude_code&utm_medium=docs) (Intel and Apple Silicon)
- [Windows](https://claude.ai/api/desktop/win32/x64/setup/latest/redirect?utm_source=claude_code&utm_medium=docs) (x64)
- [Windows ARM64](https://claude.ai/api/desktop/win32/arm64/setup/latest/redirect?utm_source=claude_code&utm_medium=docs)
- On Ubuntu or Debian, where the app is in beta, install it with apt by following the [Linux install instructions](../16-Mobile-Desktop/desktop-linux.md)

After installing, launch Claude, sign in, and click the **Code** tab to start coding. The app includes Claude Code, so you don’t need to install the CLI separately. A [paid subscription](../17-Billing-Plans/pricing.md) is required.[Learn more about the desktop app →](../16-Mobile-Desktop/desktop-quickstart.md)

Run Claude Code in your browser with no local setup. Kick off long-running tasks and check back when they’re done, work on repos you don’t have locally, or run multiple tasks in parallel. For a longer body of work, create a [project](claude-projects.md) and let Claude coordinate the parallel sessions for you. Available on desktop browsers and [the Claude app for iOS and Android](../16-Mobile-Desktop/mobile.md).Start coding at [claude.ai/code](https://claude.ai/code).[Get started →](web-quickstart.md)

A plugin for IntelliJ IDEA, PyCharm, WebStorm, and other JetBrains IDEs with interactive diff viewing and selection context sharing.Install the [Claude Code plugin](https://plugins.jetbrains.com/plugin/27310-claude-code-beta-) from the JetBrains Marketplace and restart your IDE. The plugin requires the Claude Code CLI, installed separately; see the [JetBrains setup steps](../03-IDE-Integrations/jetbrains.md#installation).[Get started with JetBrains →](../03-IDE-Integrations/jetbrains.md)


[​](#what-you-can-do)

What you can do

Here are some of the ways you can use Claude Code:

Automate the work you keep putting off

Claude Code handles the tedious tasks that eat up your day: writing tests for untested code, fixing lint errors across a project, resolving merge conflicts, updating dependencies, and writing release notes.

```python
claude "write tests for the auth module, run them, and fix any failures"
```

Build features and fix bugs

Describe what you want in plain language. Claude Code plans the approach, writes the code across multiple files, and verifies it works.For bugs, paste an error message or describe the symptom. Claude Code traces the issue through your codebase, identifies the root cause, and implements a fix. See [common workflows](common-workflows.md) for more examples.

Create commits and pull requests

Claude Code works directly with git. It stages changes, writes commit messages, creates branches, and opens pull requests.

```python
claude "commit my changes with a descriptive message"
```

In CI, you can automate code review and issue triage with [GitHub Actions](github-actions.md) or [GitLab CI/CD](gitlab-ci-cd.md).

Connect your tools with MCP

The [Model Context Protocol (MCP)](../06-MCP-Tools/General/mcp.md) is an open standard for connecting AI tools to external data sources. With MCP, Claude Code can read your design docs in Google Drive, update tickets in Jira, pull data from Slack, or use your own custom tooling. The [MCP quickstart](../06-MCP-Tools/General/mcp-quickstart.md) connects your first server end to end.

Customize with instructions, skills, and hooks

[`CLAUDE.md`](memory.md) is a markdown file you add to your project root that Claude Code reads at the start of every session. Use it to set coding standards, architecture decisions, preferred libraries, and review checklists. If your repository already has an `AGENTS.md` for other coding agents, Claude Code [can read that](memory.md#agents-md) in place of a `CLAUDE.md`. Claude also builds [auto memory](memory.md#auto-memory) as it works, saving learnings across sessions without you writing anything.Create [skills](../08-Plugins-Skills/skills.md) to package repeatable workflows your team can share, like `/review-pr` or `/deploy-staging`.[Hooks](../07-Hooks/hooks.md) let you run shell commands before or after Claude Code actions, like auto-formatting after every file edit or running lint before a commit.

Run agents in parallel and build custom agents

Spawn [multiple Claude Code agents](../09-Agents-Patterns/sub-agents.md) that work on different parts of a task simultaneously. A lead agent coordinates the work, assigns subtasks, and merges results.To run several full sessions in parallel and watch them from one screen, use [background agents](../09-Agents-Patterns/agent-view.md). For fully custom workflows, the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) lets you build your own agents powered by Claude Code’s tools and capabilities, with full control over orchestration, tool access, and permissions.

Pipe, script, and automate with the CLI

Claude Code is composable and follows the Unix philosophy. Pipe logs into it, run it in CI, or chain it with other tools:

```python
# Analyze recent log output
tail -200 app.log | claude -p "Slack me if you see any anomalies"

# Automate translations in CI
claude -p "translate new strings into French and raise a PR for review"

# Bulk operations across files
git diff main --name-only | claude -p "review these changed files for security issues"
```

See the [CLI reference](cli-reference.md) for the full set of commands and flags.

Schedule recurring tasks

Run Claude on a schedule to automate work that repeats: morning PR reviews, overnight CI failure analysis, weekly dependency audits, or syncing docs after PRs merge.

- [Cloud scheduled tasks](web-scheduled-tasks.md), formerly routines, run in the cloud, so they keep running even when your computer is off. They can also trigger on API calls or GitHub events. Create them from the web, the Desktop app, or by running `/schedule` in the CLI.
- [Desktop scheduled tasks](../16-Mobile-Desktop/desktop-scheduled-tasks.md) run on your machine, with direct access to your local files and tools
- [`/loop`](scheduled-tasks.md) repeats a prompt within a CLI session for quick polling

Work from anywhere

Sessions aren’t tied to a single surface. Move work between them as your context changes:

- Step away from your desk and keep working from your phone or any browser with [Remote Control](remote-control.md)
- Message [Dispatch](../16-Mobile-Desktop/desktop.md#sessions-from-dispatch) a task from your phone and open the Desktop session it creates
- Start a long-running task on the [web](claude-code-on-the-web.md) or the [Claude mobile app](../16-Mobile-Desktop/mobile.md), then pull it into your terminal with `claude --teleport`. Teleport requires a claude.ai subscription.
- Run `/desktop` to continue your current terminal session in the [Desktop app](../16-Mobile-Desktop/desktop.md), where you can review diffs visually. The `/desktop` handoff requires a claude.ai subscription. Available on macOS and x64 Windows.
- Route tasks from team chat: mention `@Claude` in [Slack](../14-Connectors/slack.md) with a bug report and get a pull request back


[​](#use-claude-code-everywhere)

Use Claude Code everywhere

Each [surface](glossary.md#surface) connects to the same underlying Claude Code engine, so your repo’s CLAUDE.md files, settings, and MCP servers work across all of them. Beyond the [Terminal](../01-Getting-Started/quickstart.md), [VS Code](../03-IDE-Integrations/vs-code.md), [JetBrains](../03-IDE-Integrations/jetbrains.md), [Desktop](../16-Mobile-Desktop/desktop.md), and [Web](claude-code-on-the-web.md) surfaces above, Claude Code integrates with CI/CD, chat, and browser workflows:

| What I want to do                                                               | Best option                                                                                                               |
|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|
| Continue a local session from my phone or another device                        | [Remote Control](remote-control.md)                                                                                 |
| Push events from Telegram, Discord, iMessage, or my own webhooks into a session | [Channels](channels.md)                                                                                             |
| Start a task locally, continue on mobile                                        | [`claude --cloud`](claude-code-on-the-web.md#from-terminal-to-cloud), then the [Claude mobile app](../16-Mobile-Desktop/mobile.md) |
| Run Claude on a recurring schedule                                              | [Cloud scheduled tasks](web-scheduled-tasks.md) or [Desktop scheduled tasks](../16-Mobile-Desktop/desktop-scheduled-tasks.md)                 |
| Automate PR reviews and issue triage                                            | [GitHub Actions](github-actions.md) or [GitLab CI/CD](gitlab-ci-cd.md)                                        |
| Get automatic code review on every PR                                           | [GitHub Code Review](code-review.md)                                                                                |
| Route bug reports from Slack to pull requests                                   | [Slack](../14-Connectors/slack.md)                                                                                                   |
| Debug live web applications                                                     | [Chrome](../03-IDE-Integrations/chrome.md)                                                                                                 |
| Build custom agents for your own workflows                                      | [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md)                                                                                  |


[​](#next-steps)

Next steps

Once you’ve installed Claude Code, these guides help you go deeper.

- [Quickstart](../01-Getting-Started/quickstart.md): walk through your first real task, from exploring a codebase to committing a fix
- [Store instructions and memories](memory.md): give Claude persistent instructions with CLAUDE.md files and auto memory
- [Common workflows](common-workflows.md) and [best practices](best-practices.md): patterns for getting the most out of Claude Code
- [Claude Academy](https://academy.claude.com/): free self-paced courses, including [Claude Code 101](https://academy.claude.com/courses/claude-code-101) and [Claude Code in Action](https://academy.claude.com/courses/claude-code-in-action)
- [A harness for every task](https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code): how the Claude Code team uses [dynamic workflows](workflows.md) to orchestrate many subagents at once
- [Settings](settings.md): customize Claude Code for your workflow
- [Troubleshooting](troubleshooting.md): solutions for common issues
- [code.claude.com](../15-Claude-AI-Features/product-claude-code-fad1ab4b.md): demos, pricing, and product details

---

## Code Review costs and usage - Claude Code Docs

Source: https://code.claude.com/docs/en/code-review-costs
Path: 02-Claude-Code-CLI/code-review-costs.md

## On this page

- [Pricing](#pricing)
  - [How often reviews run](#how-often-reviews-run)
- [Estimate your spend](#estimate-your-spend)
- [Limit your spend](#limit-your-spend)
- [View usage](#view-usage)
- [Related resources](#related-resources)

Code Review

# Code Review costs and usage

Copy pageCopy page

Estimate and cap what your organization spends on Claude Code Review: how reviews are billed through usage credits, what drives cost, and where to track usage.

Copy pageCopy page

[Code Review](code-review.md) has no flat per-review price. What you spend depends on the cost of each review and on how many reviews run:

- **Cost of each review**: scales with the [review level](code-review-setup.md#set-the-default-review-level), the size of the change, the complexity of the surrounding code, and how many candidate issues need verification
- **Number of reviews**: set by [how often reviews run](#how-often-reviews-run) in each repository


[​](#pricing)

Pricing

Code Review is billed on token usage through [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md), separately from your plan’s included usage. Reviews are billed to your organization, not to the developer who opened the PR or requested the review. Costs appear on your Anthropic bill regardless of whether your organization uses Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry for other Claude Code features.


[​](#how-often-reviews-run)

How often reviews run

A repository you add from the admin page starts at **After every push**, which runs the most reviews. Each repository’s [**Review runs** setting](code-review-setup.md#set-when-reviews-run) decides how many reviews a pull request gets:

- **Once after PR creation**: a review runs when the pull request is opened, reopened, or marked ready for review
- **After every push**: runs on each push, multiplying cost by the number of pushes
- **Manual (@claude review)**: no reviews on open or push

Comment commands, drafts, and pull requests from forks adjust those counts:

- **`@claude review always` in Once after PR creation or Manual mode**: [opts the PR into push-triggered reviews](code-review-pull-requests.md#comment-commands), so additional cost accrues per push after that comment
- **`@claude review always` in After every push mode**: pushes already trigger reviews, so the subscription doesn’t change per-push cost
- **`@claude review`**: runs a single review without subscribing to future pushes
- **Drafts and pull requests from forks**: [automatic reviews skip both](code-review-pull-requests.md#review-drafts-and-pull-requests-from-forks), so pushes to them don’t add reviews


[​](#estimate-your-spend)

Estimate your spend

Before a wide rollout, run a small pilot to estimate monthly spend from your own pull requests.

1.  Set a [monthly spend limit](#limit-your-spend) for the pilot.
2.  Turn on Code Review for a few representative repositories with **Review runs** set to **Once after PR creation** or **Manual (@claude review)**.
3.  After several reviews have run, read each repository’s average cost per review in the **Average cost** column of the **Repositories** table, in the **Code review** section of [**Admin settings \> Claude Code**](https://claude.ai/admin-settings/claude-code#code-review).
4.  Multiply that average by the number of pull requests the repository opens in a month. For **After every push**, multiply again by the typical number of pushes per pull request.

A repository’s average moves with the size of its pull requests and with the review level you choose.


[​](#limit-your-spend)

Limit your spend

To set a monthly spend limit for Code Review, go to [claude.ai/admin-settings/usage](https://claude.ai/admin-settings/usage) and configure the limit for the Claude Code Review service. The limit applies to the whole organization. Code Review skips reviews when any of these runs out:

- **Code Review spend limit**: the monthly limit you set for the Claude Code Review service. It resets at the start of the next billing period, and reviews resume sooner if you raise it.
- **Organization spend limit**: your organization’s overall monthly spend limit for usage credits. Raise it on the same page.
- **Usage credits balance**: your organization’s balance of usage credits. Add credits on the same page.

Code Review also skips reviews once what’s left is less than the expected cost of one review. When a review is skipped, developers see a [comment on the PR](code-review-troubleshooting.md#review-didn%E2%80%99t-run-and-the-pr-shows-a-budget-message) that names the cause and links to the usage settings. To monitor spend, use the [analytics dashboard](#view-usage).


[​](#view-usage)

View usage

Go to [claude.ai/analytics/code-review](https://claude.ai/analytics/code-review) to see Code Review activity across your organization.

| Section              | What it shows                                                                                              |
|:---------------------|:-----------------------------------------------------------------------------------------------------------|
| PRs reviewed         | Daily count of pull requests reviewed over the selected time range                                         |
| Code Review cost     | Code Review spend so far this month                                                                        |
| Feedback             | Count of review comments that were auto-resolved because a developer addressed the issue                   |
| Repository breakdown | Per-repo counts of PRs reviewed, comments resolved, and review runs, with estimated cost and a per-PR view |

The Code Review cost card shows an amount only when the current month is selected. Cost figures in analytics can differ from your invoice. Repository breakdown costs are estimated at list price, before any discounts or credits, and cover only reviews that Claude posted on a pull request. For invoice-accurate spend, refer to your Anthropic bill.


[​](#related-resources)

Related resources

- [Set up Code Review](code-review-setup.md): where to choose the review level and when reviews run in each repository
- [Read and request reviews on a pull request](code-review-pull-requests.md): the comment commands, pull requests from forks, and the budget message developers see when a review is skipped
- [Code Review](code-review.md): what a review checks and what it posts
- [Manage costs effectively](../17-Billing-Plans/costs.md): spend controls and usage tracking for the rest of Claude Code

---

## Customize Code Review - Claude Code Docs

Source: https://code.claude.com/docs/en/code-review-customize
Path: 02-Claude-Code-CLI/code-review-customize.md

## On this page

- [Use CLAUDE.md for project-wide rules](#use-claude-md-for-project-wide-rules)
- [Use REVIEW.md for review-only rules](#use-review-md-for-review-only-rules)
  - [Example REVIEW.md](#example-review-md)
  - [Choose what to write in REVIEW.md](#choose-what-to-write-in-review-md)
  - [Include other files in REVIEW.md](#include-other-files-in-review-md)
  - [Which branch REVIEW.md is read from](#which-branch-review-md-is-read-from)
  - [What counts as branch protection](#what-counts-as-branch-protection)
  - [What a review reads for each branch setup](#what-a-review-reads-for-each-branch-setup)
- [Related resources](#related-resources)

Code Review

# Customize Code Review

Copy pageCopy page

Tune what Code Review flags on your pull requests with REVIEW.md and CLAUDE.md: recalibrate severity, skip paths, add checks, and see which copy applies.

Copy pageCopy page

You can change what [Code Review](code-review.md) flags on your repository by committing instructions to it. This is how you cut nit volume, stop comments on generated files, or add a rule your team cares about. Put them in one of two files:

- **`CLAUDE.md`**: [project instructions](memory.md) that Claude Code reads for every task, reviews included. Code Review reads them as project context and flags changes that violate them.
- **`REVIEW.md`**: instructions for reviews alone. Use it to say what your team wants flagged, at what severity, and what to skip.

Add `REVIEW.md` at your repository root and merge it. Then [protect your default branch](#which-branch-review-md-is-read-from).

To change how thorough reviews are or when they run, ask an Owner to change the [review level](code-review-setup.md#set-the-default-review-level) or the [**Review runs** setting](code-review-setup.md#set-when-reviews-run).


[​](#use-claude-md-for-project-wide-rules)

Use CLAUDE.md for project-wide rules

Code Review reads your repository’s `CLAUDE.md` files as project context. A change that violates one of their rules becomes a finding at whichever [severity level](code-review-pull-requests.md#severity-levels) fits the issue. A review reads the `CLAUDE.md` at your repository root and the `CLAUDE.md` files in the parent directories of each changed file. A subdirectory’s `CLAUDE.md` is read when the pull request changes a file under that path.


[​](#use-review-md-for-review-only-rules)

Use REVIEW.md for review-only rules

`REVIEW.md` is a file at your repository root that tailors Code Review to your repository. You can also add a `REVIEW.md` in a subdirectory to add checks for changes under that path, on top of the root file. The agents that find issues and the agents that verify them receive its contents as your repository’s review instructions, alongside Code Review’s default review guidance. The step that writes the final review consults it before settling severity and writing the summary. This example layout has a root file and one subdirectory file:

```python
your-repo/
├── REVIEW.md            # Root file
├── services/
│   └── billing/
│       └── REVIEW.md    # Adds checks for changes under services/billing/
└── src/
```

Before you rely on a subdirectory file, protect your default branch and check [what a review reads for your branch setup](#what-a-review-reads-for-each-branch-setup).

The Code Review service and the local [`/code-review` command](code-review-local.md) are two separate tools, and they read different files. The service reads both `CLAUDE.md` and `REVIEW.md`. The `/code-review` command, which you run inside a Claude Code session on your own machine, reads your `CLAUDE.md` files and not `REVIEW.md`. Put guidance you want applied in both places in `CLAUDE.md`, and keep `REVIEW.md` for rules specific to pull request review.


[​](#example-review-md)

Example REVIEW.md

This `REVIEW.md` recalibrates severity for a backend service, caps nits, skips generated files, and adds repo-specific checks.

```python
# Review instructions

## What Important means here

Reserve Important for findings that would break behavior, leak data,
or block a rollback: incorrect logic, unscoped database queries, PII
in logs or error messages, and migrations that aren't backward
compatible. Style, naming, and refactoring suggestions are Nit at
most.

## Cap the nits

Report at most five Nits per review.

## Do not report

- Anything CI already enforces: lint, formatting, type errors
- Generated files under `src/gen/` and any `*.lock` file
- Test-only code that intentionally violates production rules

## Always check

- New API routes have an integration test
- Log lines don't include email addresses, user IDs, or request bodies
- Database queries are scoped to the caller's tenant
```


[​](#choose-what-to-write-in-review-md)

Choose what to write in REVIEW.md

`REVIEW.md` is freeform Markdown that changes what a review finds and reports. It doesn’t change the format of the review. Find the problem you’re seeing, then add an instruction like the one shown. The [example](#example-review-md) uses the first four.

- **The wrong things are marked Important**: redefine what 🔴 Important means for your repository. The default calibration targets production code, and a docs repository, a config repository, or a prototype might want a much narrower definition. State which classes of finding are Important and which are Nit at most. You can also escalate, for example treating any `CLAUDE.md` violation as Important.
- **Too many nits**: cap how many 🟡 Nit comments a single review posts. A cap like “report at most five nits” keeps reviews actionable.
- **Comments on generated files or on what CI already checks**: list paths and finding categories where Claude should skip findings. Common candidates are generated code, lockfiles, and vendored dependencies, along with anything your CI already enforces like linting or spellcheck. For paths that warrant some review but not full scrutiny, set a higher bar instead: “in `scripts/`, only report if near-certain and severe.”
- **A team rule isn’t being checked**: add rules you want flagged on every pull request, like “new API routes must have an integration test.”
- **Findings that turn out to be wrong**: require evidence before a class of finding is posted. For example, “behavior claims need a `file:line` citation in the source, not an inference from naming” cuts false positives that would otherwise cost the author a round trip.

Some of these instructions [need the root file on a protected default branch](#which-branch-review-md-is-read-from). Keep `REVIEW.md` to instructions that change review behavior, and leave general project context in `CLAUDE.md`.


[​](#include-other-files-in-review-md)

Include other files in REVIEW.md

You can split review instructions across several files and pull them into your root `REVIEW.md`. Use this when `REVIEW.md` grows long or when you already keep review rules in another file. To include a file, add a line to the root `REVIEW.md` with only `@` and the file name on it. Code Review puts the file’s contents in place of that line, so they apply as part of `REVIEW.md`. In this example, the root file gives one instruction of its own and then includes two rule files:

```python
# Review instructions

Report at most five Nits per review.

@review-security.md
@review-api.md
```

Save the included files at the repository root, beside `REVIEW.md`:

```python
your-repo/
├── REVIEW.md
├── review-security.md
└── review-api.md
```

Code Review includes the files when it reads `REVIEW.md` from a protected branch, so check [which branch a review reads for your repository](#what-a-review-reads-for-each-branch-setup):

- **Protected branch**: Code Review puts the included file in place of its `@` line
- **Unprotected default branch**: the `@` line stays in `REVIEW.md` as plain text. If the pull request changes the file the line names, the line is left out.

When a review doesn’t apply an included file, check each of these:

- **Location**: move the file to the repository root. A path into a subdirectory such as `@docs/review-rules.md` isn’t included.
- **Name**: match the file name exactly, including case, and use a name without spaces. A line whose name matches no file beside `REVIEW.md` stays in `REVIEW.md` as plain text, and the check run doesn’t report it as a skipped include.
- **One level**: list every file in the root `REVIEW.md`. An `@` line in an included file or in a subdirectory `REVIEW.md` stays as plain text, and a Markdown link to another file isn’t an include.
- **Limits**: include at most eight different files, and keep `REVIEW.md` and the files it includes under 150,000 bytes combined. A file that would reach the byte limit is skipped whole, not cut short. The check run reports how many include lines it skipped for either limit.
- **Links**: keep Markdown links at 64 or fewer across `REVIEW.md` and the files it includes. Links to `http`, `https`, or `mailto` addresses and to `#` anchors don’t count. Past that limit, the review skips your whole root `REVIEW.md`, not only the included files. The check run then [says the instructions weren’t applied](code-review-troubleshooting.md#the-check-run-mentions-review-md).
- **Merged copy**: merge the included file into the [branch `REVIEW.md` is read from](#which-branch-review-md-is-read-from). The review reads both from the same commit, never from the pull request’s own changes.


[​](#which-branch-review-md-is-read-from)

Which branch REVIEW.md is read from

Code Review reads `REVIEW.md` from the pull request’s base branch or from the default branch, never from the pull request’s own changes. To change review behavior, merge the `REVIEW.md` change first. Keep `REVIEW.md` on your default branch and protect that branch. When a review reads the copy on a protected default branch, the first row of the table below, it honors these instructions from the root file:

- Lowering a finding’s severity
- Excluding paths, files, or classes of issue
- Capping nit comments


[​](#what-counts-as-branch-protection)

What counts as branch protection

Code Review counts these settings as protection:

- **Default branch**: a classic branch protection rule or a ruleset
- **Any other branch**: a ruleset only

A ruleset counts when it restricts updates or requires pull requests with at least one approval. If it requires pull requests, it must also dismiss that approval on a new push or require the approval to come after the last push.


[​](#what-a-review-reads-for-each-branch-setup)

What a review reads for each branch setup

Find your repository’s situation in the first column of the table below.

| Branch protection                                                                                                                              | Copy read        | Files read                                               |
|:-----------------------------------------------------------------------------------------------------------------------------------------------|:-----------------|:---------------------------------------------------------|
| The default branch is protected, and the pull request targets it or targets a branch no ruleset protects                                       | Default branch   | Root file, the files it includes, and subdirectory files |
| The pull request targets another branch that a ruleset protects                                                                                | That base branch | Root file, the files it includes, and subdirectory files |
| The default branch isn’t protected, and the base branch has no protection rule of either kind                                                  | Default branch   | Root file                                                |
| Code Review can’t confirm the protection settings. This includes an unprotected default branch with a base branch that has only a classic rule | None             | None                                                     |

If the check run mentions `REVIEW.md`, see [The check run mentions REVIEW.md](code-review-troubleshooting.md#the-check-run-mentions-review-md).


[​](#related-resources)

Related resources

- [Code Review](code-review.md): what the service is and how a review runs
- [Read and request reviews on a pull request](code-review-pull-requests.md#severity-levels): what each severity level means and how findings appear
- [Set up Code Review](code-review-setup.md): the review level and when reviews run, which an Owner sets
- [Review locally with `/code-review`](code-review-local.md): the `/code-review` command, its arguments, and effort levels
- [Memory](memory.md): how `CLAUDE.md` files work across Claude Code

---

## Review locally with /code-review - Claude Code Docs

Source: https://code.claude.com/docs/en/code-review-local
Path: 02-Claude-Code-CLI/code-review-local.md

## On this page

- [Choose what to review](#choose-what-to-review)
- [What the review reads and edits](#what-the-review-reads-and-edits)
- [How findings are reported](#how-findings-are-reported)
- [Tune effort and arguments](#tune-effort-and-arguments)
  - [Post findings to a GitLab merge request](#post-findings-to-a-gitlab-merge-request)
  - [Text after the effort level and flags](#text-after-the-effort-level-and-flags)
- [Run in the foreground](#run-in-the-foreground)
- [Let Claude start the review](#let-claude-start-the-review)
- [Escalate to ultrareview](#escalate-to-ultrareview)
- [Change or build on the review](#change-or-build-on-the-review)
- [Related resources](#related-resources)

Code review and pull requests

# Review locally with /code-review

Copy pageCopy page

Run `/code-review` in a Claude Code session to find bugs in your branch’s changes, point the review at a pull request or path, and have Claude apply the fixes.

Copy pageCopy page

`/code-review` is a command you type at the Claude Code prompt, in the session where you’re working. Claude reviews the changes on your branch, looks for correctness bugs, and reports what it found in your conversation. Depending on your model and effort level, the review also covers reuse, simplification, and efficiency cleanups. The command works on any plan. The review runs in your own session, so it counts toward your plan’s usage or API billing the same way the rest of the session does.

To have every pull request in a repository reviewed automatically on GitHub, see [Code Review](code-review.md), a managed service that an Owner turns on for your organization.

`/review` is an alias of `/code-review`. Before v2.1.223, `/review` was a separate command that ran a single-pass, read-only review of a GitHub pull request.

1

Run /code-review

Run the command:

```python
/code-review
```

With no target, the review covers the changes on your current branch. To point the review at a pull request, another branch, a path, or a range of commits instead, see [Choose what to review](#choose-what-to-review).You can also add flags:

- `--fix`: also asks Claude to apply the findings to your working tree after the review. Its edits go through your [permission mode](permission-modes.md).
- `--comment`: posts the findings on a GitHub pull request as inline comments, or on a [GitLab merge request](#post-findings-to-a-gitlab-merge-request) as a single note

2

Keep working

The review runs as a background [subagent](../09-Agents-Patterns/sub-agents.md) with its own context window, so it doesn’t fill your conversation. The findings arrive in your conversation when the review completes.

3

Act on the findings

Ask Claude to fix what the review found. With `--fix` or `--comment`, Claude applies or posts the findings as part of the review, and you may be asked to approve its edits.


[​](#choose-what-to-review)

Choose what to review

To review something other than your current branch, type a target after the effort level and any flags. Claude receives that text as the review target. A target can be a pull request number, a branch name, a file path, or a Git revision range. Find what you want reviewed in the first column and type what the second column shows:

| To point the review at                                | Type                             |
|:------------------------------------------------------|:---------------------------------|
| Your current branch and uncommitted changes           | `/code-review`                   |
| Your last 15 commits                                  | `/code-review HEAD~15..HEAD`     |
| One branch against another                            | `/code-review main...my-feature` |
| A single commit, where `abc1234` is the commit’s hash | `/code-review abc1234^..abc1234` |
| A pull request by number                              | `/code-review 1234`              |
| A file or directory path                              | `/code-review src/auth`          |

With no target, `/code-review` reviews your branch’s commits ahead of its upstream branch plus your uncommitted changes. If the branch has no upstream, Claude compares against `main`, or against the previous commit. With `ultra`, Claude Code reads the target differently, as [Text after the effort level and flags](#text-after-the-effort-level-and-flags) describes.


[​](#what-the-review-reads-and-edits)

What the review reads and edits

Check these before you run a review, especially with `--fix`:

- **Edits**: without `--fix`, the review’s instructions ask Claude for a report only. With `--fix`, they also ask it to apply the findings to your working tree. Either way, any edit goes through your permission mode.
- **Rewinding**: a background review applies its `--fix` edits outside your session’s [checkpoints](checkpointing.md#subagent-edits-not-restored). After one, `/rewind` restores only the files Claude had already edited in your conversation. The review’s edits to other files stay, so use git to revert them. When the review [runs in the foreground](#run-in-the-foreground), it edits your working tree during your own turn, so `/rewind` restores its edits as usual.
- **Instructions**: the review follows your `CLAUDE.md`, including in a non-interactive `-p` run. It doesn’t read `REVIEW.md`. That file configures the managed [Code Review service](code-review-customize.md#use-review-md-for-review-only-rules) on GitHub pull requests.


[​](#how-findings-are-reported)

How findings are reported

Claude reports the findings as text in the reply in both of these runs:

- In a terminal session, where `/code-review` runs the review as a [forked subagent](../08-Plugins-Skills/skills.md#run-skills-in-a-subagent)
- In a `-p` run with text or JSON output

In a host application that requests the findings list, such as the [desktop app](../16-Mobile-Desktop/desktop.md#review-your-code), Claude reports the review’s findings through the [`ReportFindings` tool](tools-reference.md) instead. The report appears as a findings list, and each entry shows the file location, a one-sentence summary, and a category tag such as `correctness` when the finding carries one. A host request applies at every effort level and requires Claude Code v2.1.218 or later. When Claude fixes reported findings later in the session, it reports them again. Claude Code then marks each finding in the updated findings list as fixed, skipped, or no change needed.


[​](#tune-effort-and-arguments)

Tune effort and arguments

Beyond `--fix` and `--comment`, the command takes these flags:

- `--post`: on an `ultra` cloud review of a `github.com` pull request, preselects posting the finished findings to the PR in the launch dialog. See [Post findings to the pull request](ultrareview.md#post-findings-to-the-pull-request). Requires Claude Code v2.1.227 or later.
- `--max-findings <n>`, `--max-findings all`, or `--max-findings default`: reports up to `n` findings, or every finding with `all`, in place of the review’s usual limit. Where the review reports through the findings tool, the limit is 32. Later reviews reuse the value you typed until you pass `--max-findings default`, but a value passed in a non-interactive `-p` run isn’t remembered. Requires Claude Code v2.1.288 or later.

Pass an [effort level](model-config.md#adjust-effort-level) to trade coverage for confidence. At `low`, the review reports the findings it’s most confident in, so you see fewer false positives. From `medium` through `max`, the review broadens coverage. When you don’t type a level, the review reuses the last level from `low` through `max` you typed, even in an earlier session. Claude Code shows a notice such as `Reusing high effort, the level you typed last time`. These rules decide which level a run uses:

- **Typing a level**: a level you type, like `/code-review high`, changes what later runs reuse
- **Non-interactive runs**: a level you pass in a non-interactive `-p` run doesn’t update the remembered level
- **`ultra`**: the review neither uses nor updates the remembered level
- **No level ever typed**: the review uses the session’s current effort

Before v2.1.223, a `/code-review` without a level always used the session’s current effort.


[​](#post-findings-to-a-gitlab-merge-request)

Post findings to a GitLab merge request

When you pass `--comment` for a GitLab merge request, Claude Code posts the findings through GitLab’s `glab` CLI. Requires Claude Code v2.1.257 or later. When `glab` isn’t installed, Claude prints the findings in the terminal instead. Pass the merge request as its URL or a `!123` reference. Claude Code treats a bare number or branch name as a merge request only when the checkout’s origin is on `gitlab.com`. On a self-managed GitLab instance, pass the URL or `!123` form.


[​](#text-after-the-effort-level-and-flags)

Text after the effort level and flags

After the effort level and flags, Claude Code reads the rest of the line as the review target. The `ultra` argument changes that reading:

- **With `ultra`**: Claude Code reads a single word as a base branch or PR number. Longer text that doesn’t name a branch or PR becomes [a note attached to the review](ultrareview.md#pass-a-request-in-plain-words). `/code-review ultra check my auth changes` reviews your current branch, and Claude relates the findings to your note.
- **Without `ultra`**: everything left is the review target, even when it starts with another command name. `/code-review /fix-issue 123` reviews with `/fix-issue 123` as target text instead of loading `/fix-issue` as a second [stacked skill](../08-Plugins-Skills/skills.md#stack-several-skills-in-one-message). Before v2.1.218, a command stacked after `/code-review` expanded as its own skill.


[​](#run-in-the-foreground)

Run in the foreground

To make the review run in the foreground, do one of these:

- Run it in non-interactive mode, with the `-p` flag or the Agent SDK. Claude Code waits for the review and includes the findings in the response, except for `ultra`, which [doesn’t wait for the cloud review](ultrareview.md#run-ultrareview-non-interactively).
- Set [`CLAUDE_CODE_DISABLE_BACKGROUND_TASKS`](env-vars.md) to `1`, which also turns off every other background task feature
- Run `/code-review` again while an earlier review is still in progress

Before v2.1.218, the review ran inside your conversation.


[​](#let-claude-start-the-review)

Let Claude start the review

Claude can start `/code-review` on its own, without you typing the command:

- **When you ask in plain language**: ask Claude to review your changes and it can run the skill
- **From a scheduled task**: a [session-scoped scheduled task](scheduled-tasks.md) with `/code-review` as its prompt runs the review

A session-scoped scheduled task never launches the [cloud review](#escalate-to-ultrareview), so schedule `/code-review` without the `ultra` argument. To stop both Claude and scheduled tasks from starting the review while keeping `/code-review` available for you to type, add a [`skillOverrides`](../08-Plugins-Skills/skills.md#override-skill-visibility-from-settings) entry to a [settings file](settings.md#where-settings-live) such as `~/.claude/settings.json`:

```python
{
  "skillOverrides": {
    "code-review": "user-invocable-only"
  }
}
```

Before v2.1.246, Claude started `/code-review` on its own only where a feature flag fetched from Anthropic turned it on. In [sessions that don’t fetch feature flags](env-vars.md#features-that-need-feature-flag-fetching), `/code-review` ran only when you typed it, and a scheduled `/code-review` reached Claude as plain text.


[​](#escalate-to-ultrareview)

Escalate to ultrareview

`/code-review ultra --fix` runs the deeper [ultrareview](ultrareview.md) in the cloud, then asks Claude to apply its findings to your working tree when they arrive back in your session. Ultrareview uses its own scope:

- **What it compares**: your current branch against the repository’s default branch, plus uncommitted and staged changes in the working tree
- **Sensitive files**: for uncommitted changes to files named like credentials or keys, such as `.env` and `*.tfvars` files, Claude Code follows the rules for [uploading a local repository to a cloud session](claude-code-on-the-web.md#send-local-repositories-without-github)
- **A different base**: pass a branch name, such as `/code-review ultra develop`, to compare against a different base

When the target is a `github.com` pull request, you can have Claude [post the finished findings to the PR](ultrareview.md#post-findings-to-the-pull-request) as a comment from your GitHub account. Requires Claude Code v2.1.227 or later.

Ultrareview requires authentication with a claude.ai account. It isn’t available on Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry, or to organizations with Zero Data Retention enabled or with the [HIPAA configuration](hipaa-setup.md) applied. In these cases, `/code-review ultra` runs a local review in your session instead. Organizations that use [customer-managed encryption keys](../04-API-Reference/Other/manage-claude-cmek.md) (CMEK) can’t run ultrareview. To review your changes locally, run `/code-review`.

To run a cloud review from a script or CI job, use the [`claude ultrareview` subcommand](ultrareview.md#run-ultrareview-non-interactively), which waits for the findings and prints them to stdout.


[​](#change-or-build-on-the-review)

Change or build on the review

`/code-review` is a [bundled skill](../08-Plugins-Skills/skills.md#bundled-skills): its instructions are built into Claude Code, so there is no `SKILL.md` file on disk to open or edit. To give every review project rules to follow, add them to your `CLAUDE.md`. To go further, start from one of these pages:

- **Replace the command**: a project or personal skill named `code-review` runs in place of the bundled one, and the `/review` alias keeps running the bundled review. See [Resolve skills that share a name](../08-Plugins-Skills/skills.md#resolve-skills-that-share-a-name).
- **Build your own reviewer**: write a reviewer [subagent](../09-Agents-Patterns/sub-agents.md) or a review [skill](../08-Plugins-Skills/skills.md)
- **Use a neighboring command**: [`/simplify`](commands.md) reviews for cleanup only and applies its fixes, and [`/verify`](commands.md) runs your app to confirm a change works

The command was named `/simplify` before v2.1.147, when it applied fixes by default. If you scripted `/simplify` for bug-finding, switch to `/code-review --fix`.


[​](#related-resources)

Related resources

- [Code Review](code-review.md): the managed service that reviews every pull request on GitHub for your organization
- [Ultrareview](ultrareview.md): setup, limits, and cost of the deeper cloud review
- [Commands](commands.md): the one-line reference for `/code-review`, `/review`, `/simplify`, and `/verify`
- [Skills](../08-Plugins-Skills/skills.md): how bundled skills work and how to write your own

---

## Read and request reviews on a pull request - Claude Code Docs

Source: https://code.claude.com/docs/en/code-review-pull-requests
Path: 02-Claude-Code-CLI/code-review-pull-requests.md

## On this page

- [Severity levels](#severity-levels)
- [Respond to findings](#respond-to-findings)
- [Check run output](#check-run-output)
  - [When a push keeps the earlier result](#when-a-push-keeps-the-earlier-result)
  - [Read the result from a script](#read-the-result-from-a-script)
- [Request a review](#request-a-review)
  - [Comment commands](#comment-commands)
  - [What a later review covers](#what-a-later-review-covers)
  - [Review drafts and pull requests from forks](#review-drafts-and-pull-requests-from-forks)
  - [Use Code Review alongside the Claude Code GitHub Action](#use-code-review-alongside-the-claude-code-github-action)
- [Related resources](#related-resources)

Code Review

# Read and request reviews on a pull request

Copy pageCopy page

Read Code Review findings on your GitHub pull request, respond to or dismiss them, and request a review with `@claude review`.

Copy pageCopy page

Code Review is a managed service that an Owner in your Claude organization turns on for a set of GitHub repositories. Once it’s on, Claude reviews pull requests in those repositories and posts its findings as inline comments, a summary in the review body, and a check run named **Claude Code Review**. A review never approves or blocks your pull request, and the check run never concludes as a failure. An Owner controls [when reviews run](code-review-setup.md#set-when-reviews-run) and [how thorough they are](code-review-setup.md#set-the-default-review-level) for each repository.

If your plan doesn’t include Code Review, you can still have Claude review your branch from a Claude Code session: see [Review locally with `/code-review`](code-review-local.md).


[​](#severity-levels)

Severity levels

Claude posts each finding as an inline comment on the lines concerned and marks it with one of three severity levels:

| Marker | Severity     | Meaning                                                            |
|:-------|:-------------|:-------------------------------------------------------------------|
| 🔴     | Important    | A bug that should be fixed before merging                          |
| 🟡     | Nit          | A minor issue, worth fixing but not blocking                       |
| 🟣     | Pre-existing | A bug that exists in the codebase but wasn’t introduced by this PR |

When the review recorded its reasoning, the finding has a collapsed **Why this was flagged** section. Expand it to read why Claude flagged the issue and how it verified the problem. To change what Claude flags in your repository or how it ranks severity, see [Customize Code Review](code-review-customize.md).


[​](#respond-to-findings)

Respond to findings

You can merge without responding to a finding, unless your repository’s own rules require it. If its branch protection [requires conversation resolution](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches#require-conversation-resolution-before-merging), resolve each finding’s thread before you merge. To clear a finding, resolve its thread or push a fix.

- **Dismiss it without a code change**: resolve the thread yourself on GitHub. Replying alone doesn’t dismiss a finding.
- **Fix the issue**: change the code and push. The next review of the pull request resolves its earlier thread when it judges the issue fixed, whether that review runs automatically on your push or you request it.
- **Explain or disagree**: reply to the comment. Claude doesn’t respond right away, and a reply doesn’t start a review. The next review of the pull request reads the replies on its earlier findings, and can resolve the thread or post one follow-up reply. If the same kind of finding keeps coming back, ask a maintainer to add a rule to [`REVIEW.md`](code-review-customize.md#choose-what-to-write-in-review-md).

To get that next review without pushing, comment `@claude review` as a [top-level pull request comment](#comment-commands).


[​](#check-run-output)

Check run output

The **Details** link on the **Claude Code Review** check run opens the findings in one table sorted by severity, including any finding whose inline comment GitHub didn’t accept:

| Severity     | File:Line                 | Issue                                                          |
|--------------|---------------------------|----------------------------------------------------------------|
| 🔴 Important | `src/auth/session.ts:142` | Token refresh races with logout, leaving stale sessions active |
| 🟡 Nit       | `src/auth/session.ts:88`  | `parseExpiry` silently returns 0 on malformed input            |

A finding that has a line but wasn’t posted as an inline comment appears as an annotation in the **Files changed** tab, on the lines concerned. Important findings show in red, nits in yellow, and pre-existing bugs in gray. The check run concludes as neutral, or as skipped after some pushes that change no files and [keep the earlier result](#when-a-push-keeps-the-earlier-result). It never concludes as a failure, so a finished review doesn’t fail a required check. If you don’t see findings, or a review didn’t run, see [Troubleshoot Code Review](code-review-troubleshooting.md).


[​](#when-a-push-keeps-the-earlier-result)

When a push keeps the earlier result

If the check run has one of these titles after you push, Code Review kept the result of an earlier review instead of starting a new one:

- **Code review skipped — no new changes**: no [Important](#severity-levels) finding from the earlier review is still open, so you don’t need a new review
- **Code review not repeated — earlier findings still open**: to start a new review, push a fix for an open Important finding, or [resolve its thread](#respond-to-findings) and push again

On github.com, Code Review can keep a result when both of these hold:

- The pull request still adds and removes the same lines, as after an empty commit, a clean merge of the base branch, or a clean rebase
- Nobody has resolved an Important finding’s thread since that review

To get a review without a code change, comment [`@claude review`](#comment-commands) or click **Re-run** on the check run.


[​](#read-the-result-from-a-script)

Read the result from a script

To gate a merge or post a summary from your own CI, parse the last line of the Details text with `gh` and jq. That line is an HTML comment that holds the severity counts as JSON:

```python
<!-- bughunter-severity: {"nit":1,"normal":2,"pre_existing":0} -->
```

The lines above it can include file names from the pull request. If you parse the text your own way, take the counts from the last line only, as the command in these steps does.

1

Find the check run ID

From your shell, list the commit’s check runs and take the `id` of the `Claude Code Review` run. Replace `OWNER` and `REPO` with your repository owner and name, and `<commit-sha>` with the pull request’s head commit:

```python
gh api repos/OWNER/REPO/commits/<commit-sha>/check-runs --jq '.check_runs[] | {id, name}'
```

If the commit has had more than one `Claude Code Review` run, such as after a **Re-run**, GitHub lists only the newest.

2

Read the severity counts

Read the counts from the check run’s `output.text` field, which holds the Details text. Replace `CHECK_RUN_ID` with the ID:

```python
gh api repos/OWNER/REPO/check-runs/CHECK_RUN_ID --jq '
  (.output.text | split("\n") | last
    | scan("^<!-- bughunter-severity: (.*) -->$")[0] | fromjson)?
  // error("no severity line")'
```

This prints a JSON object with a count per severity and its keys in alphabetical order, for example `{"nit": 1, "normal": 2, "pre_existing": 0}`. Except on a check run that [kept an earlier result](#when-a-push-keeps-the-earlier-result), the counts include findings from earlier reviews of the pull request whose threads are still open.Under the title `Code review skipped — no new changes`, the counts leave out nits and pre-existing findings from earlier reviews that are still open. No Important finding from the earlier review is still open then.

3

Act on the result

Have your script handle these cases in order:

- **The title starts with `Code review not repeated`**: Code Review [kept an earlier result](#when-a-push-keeps-the-earlier-result) whose Important findings are still open, and the check run has no severity line. Read the title before the counts, with `gh api repos/OWNER/REPO/check-runs/CHECK_RUN_ID --jq .output.title`. Fail the job if you want to gate the merge.
- **The title ends with `no new changes`**: let the job pass without reading the counts
- **`normal` is above zero**: fail the job if you want to gate the merge. The `normal` key holds the count of Important findings, so Claude found at least one bug worth fixing before merge. To print only that count, add `| .normal` before the closing single quote.
- **The line is missing**: the command prints an error that contains `no severity line` instead of counts, and exits with a non-zero status. Treat that as no verdict rather than as zero findings. A check run for a review that failed, timed out, was canceled, or was superseded by a newer one has no such line, and some completed reviews have none either.


[​](#request-a-review)

Request a review

If your pull request is a draft or comes from a fork, automatic reviews skip it, so [request the review with a comment command](#review-drafts-and-pull-requests-from-forks). To get a review on your pull request, do one of these:

- **Open it or mark it ready**: in a repository set to **Once after PR creation** or **After every push**, a review starts when you open or reopen the pull request, or mark a draft ready for review.
- **Comment a command**: post [`@claude review`](#comment-commands) on the pull request.
- **Push a commit**: a push starts a review in a repository set to **After every push**, or on a pull request you subscribed with `@claude review always`. If your pull request still adds and removes the same lines after the push, Code Review can [keep the earlier result](#when-a-push-keeps-the-earlier-result) instead.
- **Click Re-run**: after a review fails or times out on a pull request that isn’t from a fork, [run it again](code-review-troubleshooting.md#retrigger-a-failed-or-timed-out-review) from the check run. On a pull request that isn’t from a fork, you can also click **Re-run** after a push that [kept the earlier result](#when-a-push-keeps-the-earlier-result).
- **Wait for the automatic retry**: a review whose session was interrupted is retried once automatically. The [check run’s summary](code-review-troubleshooting.md#retrigger-a-failed-or-timed-out-review) says when that’s happening.


[​](#comment-commands)

Comment commands

Post one of these commands as a comment on the pull request:

| Command                                        | What it does                                                                                                                                                                   | When to use it                                                                                                                                                   |
|:-----------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `@claude review`                               | Starts a single review without subscribing the PR to future pushes                                                                                                             | You want one review now, such as on a pull request in a repository set to **Manual**, or another review right away in the other modes                            |
| `@claude review always`                        | Starts a review and subscribes the PR to push-triggered reviews going forward                                                                                                  | You want subsequent pushes to start reviews, such as on a high-priority PR in a repository set to **Manual**                                                     |
| `@claude review once`                          | Same as `@claude review`: starts a single review without subscribing                                                                                                           | The same cases as `@claude review`                                                                                                                               |
| `@claude review stop`                          | Ends the PR’s subscription to push-triggered reviews, without starting a review or canceling one that’s already running. Claude replies with a comment instead of a check run. | You subscribed a PR with `@claude review always` in a repository set to **Manual** or **Once after PR creation**, and no longer want each push to start a review |
| `@claude review off` or `@claude review pause` | Same as `@claude review stop`                                                                                                                                                  | The same cases as `@claude review stop`                                                                                                                          |

In a repository set to **After every push**, you can’t stop reviews with a comment, because pushes there start reviews with or without a subscription. To stop pushes from starting reviews on one pull request there, convert it to a [draft](#review-drafts-and-pull-requests-from-forks). When you mark it ready for review again, a review starts. For any comment command to take effect, all of these conditions have to hold:

- Post it as a new top-level pull request comment, not an inline comment on a diff line and not the body of a review. Editing an earlier comment doesn’t count.
- Put the whole command on one line at the start of the comment. Other text can follow it. If `always` or `stop` is misspelled or on a later line, Claude reads the comment as a plain `@claude review` and starts a single review. Capitalization doesn’t matter.
- You need write, maintain, or admin permission on the repository. Claude checks this with GitHub for each person who comments, and comments from bots don’t start reviews.
- The pull request must be open.

When a command that starts a review is accepted, a **Claude Code Review** check run appears on the pull request with the title **Code review queued…**. The title changes to **Code review in progress…** when the review starts. Claude may also react to your comment with 👀, but that reaction can appear when no review starts, so look for the check run instead. If a review is already running on the pull request’s latest commit, a new request doesn’t start a second one.

Before a July 2026 update, `@claude review` subscribed the PR to push-triggered reviews. If you relied on that behavior, comment `@claude review always` instead.


[​](#what-a-later-review-covers)

What a later review covers

A later review that starts on its own, such as after a push, focuses on what changed since the last review and posts fewer nits and pre-existing findings. Its summary counts what it left out, in a line that ends “found and not posted” or “outside the scope of this re-review and not posted.” To get a review that leaves none of these out, comment [`@claude review`](#comment-commands). It covers the whole pull request again.


[​](#review-drafts-and-pull-requests-from-forks)

Review drafts and pull requests from forks

Automatic reviews skip both of these, so request the review with a comment command:

- **Draft pull requests**: a comment command runs on a draft, so you can request a review before you mark the pull request ready. Pushes to a draft don’t start reviews, even after `@claude review always`. The subscription takes effect once you mark the pull request ready.
- **Pull requests from forks**: Claude doesn’t review a pull request from a fork automatically, regardless of the repository’s **Review runs** setting. To start one, comment `@claude review` on the pull request. The [conditions for comment commands](#comment-commands) still apply, and the write access you need is to the base repository, not the fork.

On a pull request from a fork, `@claude review always` works too, but doesn’t subscribe the pull request to reviews on later pushes. Clicking **Re-run** on the check run doesn’t start a review there.


[​](#use-code-review-alongside-the-claude-code-github-action)

Use Code Review alongside the Claude Code GitHub Action

If the repository also runs the [Claude Code GitHub Action](github-actions.md) in interactive mode with its default `@claude` trigger phrase, an `@claude review` comment starts the Action as well. To keep the two apart, set the Action’s `trigger_phrase` input to a different phrase.


[​](#related-resources)

Related resources

- [Troubleshoot Code Review](code-review-troubleshooting.md): a review that didn’t start, failed, or was skipped for budget
- [Code Review](code-review.md): what the service is and how a review runs
- [Set up Code Review](code-review-setup.md): for Owners, turn on Code Review and choose when reviews run and at what level
- [Customize Code Review](code-review-customize.md): change what Claude flags with `REVIEW.md` and `CLAUDE.md`
- [Code Review costs and usage](code-review-costs.md): how reviews are billed and where the spend limit is set
- [Review locally with `/code-review`](code-review-local.md): run a review of your branch from a Claude Code session

---

## Set up Code Review - Claude Code Docs

Source: https://code.claude.com/docs/en/code-review-setup
Path: 02-Claude-Code-CLI/code-review-setup.md

## On this page

- [What you need to turn on Code Review](#what-you-need-to-turn-on-code-review)
- [Turn on Code Review](#turn-on-code-review)
- [Set defaults for your organization](#set-defaults-for-your-organization)
  - [Set the default review level](#set-the-default-review-level)
  - [Set when reviews run](#set-when-reviews-run)
  - [Turn tip comments on or off](#turn-tip-comments-on-or-off)
  - [What developers can change](#what-developers-can-change)
- [Manage repositories](#manage-repositories)
  - [Add more repositories](#add-more-repositories)
  - [Cover a whole GitHub organization](#cover-a-whole-github-organization)
  - [Turn off Code Review or remove a repository](#turn-off-code-review-or-remove-a-repository)
- [Related resources](#related-resources)

Code Review

# Set up Code Review

Copy pageCopy page

Turn on Code Review for your Claude organization: connect GitHub, install the Claude GitHub App, choose repositories, and set when reviews run

Copy pageCopy page

As an Owner of your Claude organization, you turn on Code Review in [**Admin settings \> Claude Code**](https://claude.ai/admin-settings/claude-code#code-review) on claude.ai. Reviews run on Anthropic infrastructure, so you don’t add workflow files to your repositories. After setup, you choose how thorough reviews are and when they run in each repository. You spend more at a higher review level and when reviews run more often. See [Code Review costs](code-review-costs.md#pricing).


[​](#what-you-need-to-turn-on-code-review)

What you need to turn on Code Review

First check that your organization [qualifies for Code Review](code-review.md#availability). Then make sure you have this access, or someone who does:

| Access                                                                                    | Needed for                                                                                                                                                                                                |
|:------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Owner role](../13-Enterprise-Admin/server-managed-settings.md#access-control) in your Claude organization | Every step on the admin page                                                                                                                                                                              |
| Owner of the GitHub organization                                                          | Installing the Claude GitHub App and [linking it to your Claude organization](../13-Enterprise-Admin/admin-setup.md#connected-github-accounts). If you aren’t an owner, have one install and link the app before you start |
| Write access to each repository you add, from the GitHub account you connect to Claude    | Adding the repository                                                                                                                                                                                     |


[​](#turn-on-code-review)

Turn on Code Review

1

Click the Allow code review switch

Go to the **Code review** section of [**Admin settings \> Claude Code**](https://claude.ai/admin-settings/claude-code#code-review) and click the **Allow code review** switch.If Code Review turns on right away with no dialog, your organization already has the Claude GitHub App linked or repositories added. Go to [Add more repositories](#add-more-repositories), then come back for the last step.

2

Connect your GitHub account

If a **Connect GitHub** dialog opens, click **Connect**. If your organization uses GitHub Enterprise Server, select your instance in the dialog first. GitHub asks you to authorize Claude, then returns you to the admin page with the **Add a repository** dialog open.If **Add a repository** opened straight away, your account is already connected, so go on to the next step.

3

Install the Claude GitHub App

If the repositories you want are listed in the **Add a repository** dialog, or you find them by searching there, go on to the next step. The dialog lists a repository only if the Claude GitHub App can access it, so if they aren’t there, install the app:

- Click **Install GitHub App**. When no repositories are listed, it’s a button in the dialog. Otherwise, it’s at the bottom of the dialog’s GitHub organization filter menu. GitHub’s install page opens in a new tab.
- Pick the GitHub organization that owns the repositories.
- Choose which repositories the app can access.
- Approve the requested permissions. The set is broader than a review uses and is shared by other Claude features, such as [GitHub Actions](github-actions.md). See [what a review can access](code-review.md#what-a-review-can-access) and the [full permission list](github-actions.md#github-app-permissions).
- When the install completes, the tab returns to Claude. If it shows a **Finish connecting GitHub** button, click it to link the installation to your Claude organization.
- Go back to the admin page’s tab, where the list in the dialog refreshes.

4

Choose repositories

Select the repositories you want reviewed, then click **Continue**. Adding a repository needs write access to it from the GitHub account you connected. You can [add more repositories](#add-more-repositories) later.

5

Click Finish

A **Code review is set up** dialog follows. Click **Finish** to turn Code Review on. If you close the dialog any other way, your repositories stay added but **Allow code review** stays off, and you turn it on from the switch.Each repository starts set to review after every push, which runs the most reviews. To run fewer, [set when reviews run](#set-when-reviews-run).

6

Verify with a test pull request

Open a test pull request in one of the repositories you added, and don’t mark it as a draft. A check run named **Claude Code Review** appears within a few minutes. If you already set the repository to **Manual (@claude review)**, comment `@claude review` on the pull request to start the first review.If no check run appears, see [No check run appears on the test pull request](code-review-troubleshooting.md#no-check-run-appears-on-the-test-pull-request).Once the review arrives, send your developers [Read and request reviews on a pull request](code-review-pull-requests.md), which covers the severity levels, the comment commands, and how to respond to findings.


[​](#set-defaults-for-your-organization)

Set defaults for your organization

As an Owner, you decide how thorough reviews are and how often they run. Both are in the **Code review** section of [**Admin settings \> Claude Code**](https://claude.ai/admin-settings/claude-code#code-review).


[​](#set-the-default-review-level)

Set the default review level

The review level sets how thorough each review is, and a more thorough review costs more. You set one default for the organization and can override it for individual repositories.

| Level    | What it trades                                               |
|:---------|:-------------------------------------------------------------|
| Quick    | A lighter pass. The fastest level, at the lowest cost        |
| Standard | Balanced depth, speed, and cost. The default level           |
| Deep     | The most thorough pass. Takes the longest and costs the most |

- **Organization default**: select a level under **Review level** and confirm with **Change level**. Every repository uses it unless you give that repository its own.
- **One repository**: click **Edit** on the repository’s row, then select a **Review level** there. The first option, **Default**, follows the organization. The level saves as soon as you select it.

A new level applies to reviews that start after the change. For what else drives the cost of each review, see [Code Review costs and usage](code-review-costs.md).


[​](#set-when-reviews-run)

Set when reviews run

Each repository has its own **Review runs** setting, which decides when its pull requests get reviewed.

- **Once after PR creation**: a review runs when a pull request is opened, reopened, or marked ready for review
- **After every push**: a review runs on pushes to the pull request branch, catching new issues as the pull request evolves and auto-resolving threads when you fix flagged issues
- **Manual (@claude review)**: opening or pushing to a pull request doesn’t start a review. Comment [`@claude review`](code-review-pull-requests.md#comment-commands) to request one, or `@claude review always` to also subscribe the pull request to reviews on subsequent pushes.

Manual is useful for high-traffic repositories where you want to opt specific pull requests into review, or to start reviewing pull requests only once they’re ready. To compare what each option does to spend, see [How often reviews run](code-review-costs.md#how-often-reviews-run). To change the setting, click **Edit** on the repository’s row in the **Repositories** table and select a **Review runs** option. The choice saves as soon as you select it, and the table’s **Review runs** column shows it shortened to Once per PR, Every push, or Manual.

- **Drafts and pull requests from forks**: whichever option you choose, [automatic reviews skip both](code-review-pull-requests.md#review-drafts-and-pull-requests-from-forks)
- **New repositories**: a repository you add from the **Add a repository** dialog starts at **After every push**. If its GitHub organization is [covered as a whole](#cover-a-whole-github-organization), it takes that organization row’s setting instead.


[​](#turn-tip-comments-on-or-off)

Turn tip comments on or off

A tip comment is a short comment Claude posts on a pull request when no review starts, saying why and what to do next. **Show tips on pull requests** is on by default. With it on, Claude posts a tip in each of these cases, explaining:

- **The repository is set to Manual**: how to request a review with a comment
- **The pull request comes from a fork**: that a maintainer can request the review
- **A bot, or someone without write access who isn’t the pull request’s author, comments `@claude review`**: that no review was started, and who can request one
- **The GitHub organization isn’t linked to your Claude organization**: that reviews are paused, and how to link it

Turn the setting off to stop these comments.


[​](#what-developers-can-change)

What developers can change

Developers come to you to change the review level, the **Review runs** setting, or which repositories get reviews. From GitHub, without the Owner role, they can do these:

- **Request a review**: comment [`@claude review`](code-review-pull-requests.md#comment-commands) on a pull request. This needs write access to the repository, and it works on [drafts and pull requests from forks](code-review-pull-requests.md#review-drafts-and-pull-requests-from-forks), which automatic reviews skip.
- **Subscribe one pull request to a review on each push**: comment `@claude review always` on a pull request that isn’t [a draft or from a fork](code-review-pull-requests.md#review-drafts-and-pull-requests-from-forks), such as in a repository set to Manual
- **Change what reviews flag**: commit [`REVIEW.md` and `CLAUDE.md` files](code-review-customize.md) to the repository, for example to add a check

Reviews that developers request are [billed to your organization](code-review-costs.md#pricing). To limit what Code Review spends in a month, see [Limit your spend](code-review-costs.md#limit-your-spend).


[​](#manage-repositories)

Manage repositories

You can add repositories one at a time or cover a whole GitHub organization at once, and stop reviews wherever you don’t want them.


[​](#add-more-repositories)

Add more repositories

To add repositories after setup, click **Add** above the **Repositories** table in the **Code review** section. The **Add a repository** dialog opens. Select repositories and click **Continue**.

- **A repository isn’t listed**: see [A repository isn’t listed in Add a repository](code-review-troubleshooting.md#a-repository-isn%E2%80%99t-listed-in-add-a-repository).
- **You want every repository in a GitHub organization**: [cover the organization](#cover-a-whole-github-organization) instead of selecting repositories one at a time


[​](#cover-a-whole-github-organization)

Cover a whole GitHub organization

To turn on Code Review for every repository in a GitHub organization, set **Review runs** on the organization’s row in the **Repositories** table. That covers every repository there that the Claude GitHub App can access, including repositories added later. This can raise spend significantly. It requires all of these:

- The GitHub account you connected to Claude is an owner of that GitHub organization.
- The organization is on github.com. GitHub Enterprise Server instances and personal GitHub accounts aren’t eligible.
- A [monthly spend limit](code-review-costs.md#limit-your-spend) is set, for your Claude organization or for Code Review.

To cover the organization, click **Edit** on its row, select a **Review runs** option, and confirm. The options are the three from [Set when reviews run](#set-when-reviews-run) plus **Off**. After you confirm, these changes take effect:

- **Coverage**: each repository is covered from its next pull request. If the Claude GitHub App was installed on selected repositories rather than all of them, Claude reviews those repositories; change the app’s repository access on GitHub to cover the rest.
- **Existing settings**: every repository in that GitHub organization takes the option you select, including repositories you had set individually. Setting the row again does the same. Repositories you turned off on their own rows stay off.
- **Individual changes afterward**: a repository you later set differently from its organization is marked **Custom** in the table.
- **Review level**: an organization row has no review level of its own.


[​](#turn-off-code-review-or-remove-a-repository)

Turn off Code Review or remove a repository

In the **Code review** section of [**Admin settings \> Claude Code**](https://claude.ai/admin-settings/claude-code#code-review), pick the control that matches what you want to stop:

- **One repository, keeping it in the list**: click **Edit** on its row and turn off **Code review**. The table shows the repository as Off.
- **One repository, removing it**: click **Edit** on its row, then **Remove repository** at the bottom of the dialog. Reviews stop there, and another Claude organization can then set that repository up. While the repository’s GitHub organization is covered as a whole, you can’t remove it; turn off its **Code review** switch instead.
- **A whole GitHub organization**: click **Edit** on the organization’s row and select **Off**. This also turns off repositories in that organization that you added one at a time.
- **Everything**: turn off **Allow code review**. No new reviews start in any repository, and your repository list stays so you can turn it back on later.


[​](#related-resources)

Related resources

- [Code Review costs and usage](code-review-costs.md): how the review level and when reviews run affect spend, how to set a spend limit, and where to see usage
- [Read and request reviews on a pull request](code-review-pull-requests.md): what developers see on a pull request and the comment commands
- [Customize Code Review](code-review-customize.md): tune what Claude flags with `REVIEW.md` and `CLAUDE.md`
- [GitHub Enterprise Server](github-enterprise-server.md): connect a self-hosted GitHub instance before setup

---

## Troubleshoot Code Review - Claude Code Docs

Source: https://code.claude.com/docs/en/code-review-troubleshooting
Path: 02-Claude-Code-CLI/code-review-troubleshooting.md

## On this page

- [Check how far the review got](#check-how-far-the-review-got)
- [A review didn’t start](#a-review-didn%E2%80%99t-start)
  - [A comment command didn’t start a review](#a-comment-command-didn%E2%80%99t-start-a-review)
  - [Review didn’t run and the PR shows a budget message](#review-didn%E2%80%99t-run-and-the-pr-shows-a-budget-message)
- [Retrigger a failed or timed-out review](#retrigger-a-failed-or-timed-out-review)
- [Find issues that aren’t showing as inline comments](#find-issues-that-aren%E2%80%99t-showing-as-inline-comments)
- [The check run mentions REVIEW.md](#the-check-run-mentions-review-md)
- [Setup problems](#setup-problems)
  - [A repository isn’t listed in Add a repository](#a-repository-isn%E2%80%99t-listed-in-add-a-repository)
  - [No check run appears on the test pull request](#no-check-run-appears-on-the-test-pull-request)
- [Related resources](#related-resources)

Code Review

# Troubleshoot Code Review

Copy pageCopy page

Fix a Code Review that didn’t start, failed, or was skipped for budget, find missing findings, and resolve setup and `REVIEW.md` problems.

Copy pageCopy page

When [Code Review](code-review.md) doesn’t do what you expect on a pull request, start with the **Claude Code Review** check run. Its title says how far the review got.


[​](#check-how-far-the-review-got)

Check how far the review got

Find the **Claude Code Review** check run on your pull request, then match its title to one of these common ones:

| Check run title                                            | What it means                                                                                                     | What to do                                                                                                                                                                                   |
|:-----------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Code review queued…** or **Code review in progress…**    | The review hasn’t finished                                                                                        | Wait for the title to change                                                                                                                                                                 |
| **Code review found no issues**                            | The review finished and found nothing to flag                                                                     | Nothing                                                                                                                                                                                      |
| A title that says issues were found                        | The review finished with findings                                                                                 | If you don’t see them on the diff, see [Find issues that aren’t showing as inline comments](#find-issues-that-aren%E2%80%99t-showing-as-inline-comments)                                     |
| **Code review skipped — no new changes**                   | An automatic review didn’t run on your latest push                                                                | To get a review anyway, comment `@claude review`                                                                                                                                             |
| **Code review not repeated — earlier findings still open** | An automatic review didn’t run on your latest push, and Important findings from the earlier review are still open | Push a fix, or to get a review anyway, comment `@claude review`. See [When a push keeps the earlier result](code-review-pull-requests.md#when-a-push-keeps-the-earlier-result)         |
| **Code review failed** or **Code review timed out**        | The review didn’t finish                                                                                          | To run it again, see [Retrigger a failed or timed-out review](#retrigger-a-failed-or-timed-out-review)                                                                                       |
| **Code review declined**                                   | The review didn’t run                                                                                             | Read the check run’s summary. If it names a budget or a spend limit, see [Review didn’t run and the PR shows a budget message](#review-didn%E2%80%99t-run-and-the-pr-shows-a-budget-message) |
| No check run                                               | No review started                                                                                                 | Comment `@claude review`. If no check run appears after that, see [A comment command didn’t start a review](#a-comment-command-didn%E2%80%99t-start-a-review)                                |


[​](#a-review-didn’t-start)

A review didn’t start

Check these cases when no **Claude Code Review** check run appears, or when Claude posts a comment saying the review was skipped.


[​](#a-comment-command-didn’t-start-a-review)

A comment command didn’t start a review

After you comment `@claude review`, look for a **Claude Code Review** check run titled **Code review queued…** or **Code review in progress…** on the pull request. An 👀 reaction on your comment doesn’t confirm a review is coming. If no check run appears, check for each of these causes:

- **Code Review isn’t on for this repository**: Claude posts no comment and no check run in response to the command. Ask an Owner to [add the repository](code-review-setup.md#add-more-repositories).
- **The comment doesn’t meet a condition**: it was an inline comment or a review body rather than a new top-level comment, or the command wasn’t at the start of the comment. Editing an earlier comment instead of posting a new one doesn’t count either, and the pull request has to be open. See the [conditions for comment commands](code-review-pull-requests.md#comment-commands) and post a new comment that meets them.
- **You don’t have write access**: you need write, maintain, or admin permission on the repository. On a pull request from a fork, the permission that counts is on the base repository. Unless the pull request is yours, Claude can reply with a [tip](code-review-setup.md#turn-tip-comments-on-or-off): “No review was started: manual reviews can only be requested by someone with write access to this repository.” Ask someone with write access to comment instead.
- **The budget ran out**: Claude posts a comment that begins with “⚠️ Code review skipped”. See [Review didn’t run and the PR shows a budget message](#review-didn%E2%80%99t-run-and-the-pr-shows-a-budget-message).


[​](#review-didn’t-run-and-the-pr-shows-a-budget-message)

Review didn’t run and the PR shows a budget message

When your organization’s budget can’t cover a review, Code Review skips the review and Claude posts a comment on the pull request that begins with “⚠️ Code review skipped”. In some of these cases a check run titled **Code review declined** also appears. The comment links [claude.ai/admin-settings/usage](https://claude.ai/admin-settings/usage), where an admin restores the budget. Its wording tells you which limit was reached:

- **“has reached its monthly code review spending cap”**: the [monthly spend limit for Code Review](code-review-costs.md#limit-your-spend) was reached. Reviews resume at the start of the next billing period. To get them sooner, ask an admin to raise the limit.
- **“has no extra usage available to pay for this review”**: your organization’s [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md) balance is empty, or its overall monthly spend limit was reached. Ask an admin to add usage credits or raise that limit.
- **“is too low to start another review”**: what’s left of the budget or balance is less than the expected cost of one review. Ask an admin to raise the limit or add usage credits.

After the budget is restored, comment `@claude review` on the pull request to get the review that was skipped. The [conditions for comment commands](code-review-pull-requests.md#comment-commands) apply, so the commenter needs write access.


[​](#retrigger-a-failed-or-timed-out-review)

Retrigger a failed or timed-out review

If the check run’s summary says “The review session was interrupted before it could finish. A new review of this commit has been queued automatically.”, you don’t need to do anything. That review is retried once automatically. Otherwise, when the check run’s title is **Code review failed** or **Code review timed out**, run the review again with a comment or a re-run:

- **Comment `@claude review`**: post it as a top-level comment on the pull request. This starts a fresh review without subscribing the pull request to future pushes.
- **Click Re-run**: if the pull request isn’t [from a fork](code-review-pull-requests.md#review-drafts-and-pull-requests-from-forks), click **Re-run** on the **Claude Code Review** check in GitHub’s **Checks** tab. The re-run covers the pull request’s current head commit and doesn’t subscribe the pull request either.


[​](#find-issues-that-aren’t-showing-as-inline-comments)

Find issues that aren’t showing as inline comments

If the check run title says issues were found but you don’t see inline review comments on the diff, look in these other locations where findings are surfaced:

- **Check run Details**: click **Details** next to the **Claude Code Review** check in the **Checks** tab. The severity table lists findings with their file, line, and summary regardless of whether the inline comment was accepted.
- **Files changed annotations**: open the **Files changed** tab on the PR. A finding that has a line but wasn’t posted as an inline comment appears there as an annotation on the lines concerned.
- **Review body**: findings that have no inline location, or that fall outside the current diff, appear under an **Additional findings** heading in the review body.


[​](#the-check-run-mentions-review-md)

The check run mentions REVIEW.md

These are three of the messages a check run can carry about `REVIEW.md`:

- **“This review applied the repository’s review instructions (REVIEW.md) from its default branch, which is not protected against direct pushes.”**: the review read the root file only. See [Which branch REVIEW.md is read from](code-review-customize.md#which-branch-review-md-is-read-from) for what protecting the branch changes.
- **“were not applied to this review: branch protection could not be confirmed”**: the review read no `REVIEW.md`.
- **“they link to a file this pull request modifies, or carry more links than the review checks”**: the review skipped the root `REVIEW.md`, or the number of subdirectory `REVIEW.md` files the message gives. Check the skipped file for each cause. For the root `REVIEW.md`, check the [files it includes](code-review-customize.md#include-other-files-in-review-md) too:
  - **Too many links**: it carries more than 64 Markdown links. Cut links to [64 or fewer](code-review-customize.md#include-other-files-in-review-md).
  - **A link the review can’t parse**: it has a malformed Markdown link. Fix or remove the link.
  - **A link to a changed file**: it links to a file or folder this pull request changes, and the review couldn’t leave out only the lines with that link. Write the rule in `REVIEW.md` itself.


[​](#setup-problems)

Setup problems

These cases come up for an Owner while [setting up Code Review](code-review-setup.md).


[​](#a-repository-isn’t-listed-in-add-a-repository)

A repository isn’t listed in Add a repository

Search for the repository by name first, because the dialog doesn’t load a long list in full. The dialog lists a repository only if the Claude GitHub App can access it. Click **Install GitHub App** and give the app access to the repository. When no repositories are listed, **Install GitHub App** is a button in the dialog. Otherwise, it’s at the bottom of the dialog’s GitHub organization filter menu.


[​](#no-check-run-appears-on-the-test-pull-request)

No check run appears on the test pull request

Confirm that **Allow code review** is on, that the repository is listed under **Repositories** in the **Code review** section, and that the Claude GitHub App has access to it. Automatic reviews skip draft pull requests, and a repository set to **Manual (@claude review)** needs an `@claude review` comment to start the first review.


[​](#related-resources)

Related resources

- [Read and request reviews on a pull request](code-review-pull-requests.md): what the findings and the check run mean, and the comment commands
- [Set up Code Review](code-review-setup.md): for Owners, turn on Code Review and manage repositories
- [Code Review costs and usage](code-review-costs.md): the spend limits behind a budget message
- [Customize Code Review](code-review-customize.md): which copy of `REVIEW.md` a review reads

---

## Code Review - Claude Code Docs

Source: https://code.claude.com/docs/en/code-review
Path: 02-Claude-Code-CLI/code-review.md

## On this page

- [Availability](#availability)
- [Set up and use Code Review](#set-up-and-use-code-review)
- [How reviews work](#how-reviews-work)
  - [Review levels](#review-levels)
  - [What a review can access](#what-a-review-can-access)
  - [Who controls a review](#who-controls-a-review)
- [Compare ways to get a review](#compare-ways-to-get-a-review)
- [Related resources](#related-resources)

Code Review

# Code Review

Copy pageCopy page

Catch bugs in GitHub pull requests with Code Review: Claude reviews each change, verifies its findings, and comments inline. For Team and Enterprise plans

Copy pageCopy page

With Code Review, Claude reviews the pull requests in your GitHub repositories. Several agents read each change alongside the surrounding code, looking for issues such as logic errors, security vulnerabilities, or broken edge cases. A verification step checks findings against the code before they’re reported. Findings arrive as inline comments on the lines concerned, ranked by [severity](code-review-pull-requests.md#severity-levels), with a summary and a check run on the pull request. A review never approves or blocks the pull request, so the decision to merge stays with your team.

Code Review uses AI to review code and may miss bugs, security vulnerabilities, or other issues. A review with no findings doesn’t mean your code is error-free or secure.

To turn on Code Review, an Owner of your Claude organization follows [Set up Code Review](code-review-setup.md). Claude can also review code without this service. Run [`/code-review`](code-review-local.md) in your Claude Code session on any plan, or [compare all the options](#compare-ways-to-get-a-review).


[​](#availability)

Availability

Check that your organization qualifies before you set up Code Review:

- **Plans**: [Team and Enterprise](feature-availability.md)
- **Code hosts**: repositories hosted on GitHub, including [GitHub Enterprise Server](github-enterprise-server.md) and GitHub Enterprise Cloud with data residency. For data residency, have an Owner follow the [GitHub Enterprise Server admin setup](github-enterprise-server.md#admin-setup) and enter your enterprise’s `ghe.com` hostname.
- **Data retention**: Code Review isn’t available to organizations with [Zero Data Retention](zero-data-retention.md) enabled or with the [HIPAA configuration](hipaa-setup.md) applied, and isn’t covered under Anthropic’s Business Associate Agreement (BAA).
- **Encryption keys**: Code Review isn’t yet available for organizations that use customer-managed encryption keys (CMEK).
- **Cloud providers**: you need a Claude organization on one of these plans even if your developers use Claude Code through Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry


[​](#set-up-and-use-code-review)

Set up and use Code Review

Pick the page for what you need to do:

## Set up Code Review

Check the requirements, install the Claude GitHub App, and choose repositories, a review level, and when reviews run

## Customize Code Review

Tune what gets flagged with `REVIEW.md` and `CLAUDE.md` files in your repository

## Read and request reviews on a pull request

Read the findings and their severities, and request another review with a comment

## Troubleshoot Code Review

Fix a review that didn’t start, failed, or was skipped for budget

## Code Review costs and usage

See how reviews are billed, estimate spend, set the monthly spend limit, and track review activity


[​](#how-reviews-work)

How reviews work

By default, Code Review focuses on correctness: bugs that would break production, not formatting preferences or missing test coverage. To change what it flags, [add guidance files](code-review-customize.md) to your repository. A review runs on Anthropic infrastructure in four stages:

1.  **Find**: several agents examine the diff and the surrounding code in parallel.
2.  **Verify**: a verification step checks the candidate findings against the code and filters out false positives.
3.  **Rank**: the findings that remain are deduplicated and ranked by severity.
4.  **Post**: the review posts its results on the pull request.

Each review leaves these on the pull request:

- **Findings**: inline comments on the lines concerned, with a summary in the review body
- **A check run**: named **Claude Code Review**, with the findings listed in its [details](code-review-pull-requests.md#check-run-output). The check run doesn’t conclude as a failure.
- **When it finds nothing**: the check run’s title reads **Code review found no issues**, and Claude posts the same short note on the pull request

Code Review chooses the Claude models that reviews run on, and its admin settings don’t offer a model choice. To make reviews more or less thorough, change the [review level](#review-levels). After an Owner turns on Code Review, each repository has a setting for [when reviews run](code-review-setup.md#set-when-reviews-run): once when a pull request opens, after every push, or only on request. Whichever it is, someone with write access to the repository can comment `@claude review` on a pull request to [start a review](code-review-pull-requests.md#comment-commands).


[​](#review-levels)

Review levels

The review level sets how thorough each review is, and a more thorough review costs more:

- **Quick**: a lighter pass. The fastest level, at the lowest cost.
- **Standard**: balanced depth, speed, and cost. The default level.
- **Deep**: the most thorough pass. Takes the longest and costs the most.

An Owner [chooses one level for the organization](code-review-setup.md#set-the-default-review-level) and can give an individual repository its own, such as Quick for a routine codebase and Deep for a critical one. For what else drives the cost of each review, see [Code Review costs and usage](code-review-costs.md).


[​](#what-a-review-can-access)

What a review can access

A review reaches your repository through the Claude GitHub App that an Owner [installs during setup](code-review-setup.md#turn-on-code-review):

- **Where it runs**: on Anthropic infrastructure, in a managed environment. Reviews don’t run in [self-hosted environments](../13-Enterprise-Admin/self-hosted-environments.md).
- **What it reads and writes**: inside a review, access to your repository is read-only, and a review doesn’t push commits. On the pull request, it posts comments and the [check run](code-review-pull-requests.md#check-run-output), resolves its own earlier comment threads, and can react to a comment command with 👀. The app itself holds a [broader permission set](github-actions.md#github-app-permissions) that other Claude features share.
- **How it examines your code**: a review works from reading the diff and the surrounding code, without building or running your code.


[​](#who-controls-a-review)

Who controls a review

- **Who can start one**: where reviews run automatically, opening or pushing to a pull request starts a review, [except on drafts and forks](code-review-pull-requests.md#review-drafts-and-pull-requests-from-forks). After some pushes, Code Review [keeps the earlier result](code-review-pull-requests.md#when-a-push-keeps-the-earlier-result) instead. A [comment command](code-review-pull-requests.md#comment-commands) starts one only when it comes from a person with write access to the repository.
- **Which instructions it follows**: `REVIEW.md` from the base or default branch and [never from the pull request’s own changes](code-review-customize.md#which-branch-review-md-is-read-from).


[​](#compare-ways-to-get-a-review)

Compare ways to get a review

To find the options open to you, check the **Who can use it** column against your plan and code host:

| Option                                                                                                         | What starts a review                                                             | Where it runs                | Who can use it                                                                                                     |
|:---------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------|:-----------------------------|:-------------------------------------------------------------------------------------------------------------------|
| [Code Review](#how-reviews-work)                                                                               | Pull request activity, as each repository is set, or an `@claude review` comment | Anthropic infrastructure     | Organizations on a Team or Enterprise plan with GitHub repositories, once an Owner turns it on                     |
| [`/code-review`](code-review-local.md)                                                                   | You run the command on your branch                                               | Your Claude Code session     | Anyone, on any plan                                                                                                |
| [Ultrareview](ultrareview.md)                                                                            | You start it from Claude Code                                                    | A cloud sandbox              | Requires signing in with a claude.ai account. See [Ultrareview](ultrareview.md) for where it isn’t available |
| Claude in your own CI, with [GitHub Actions](github-actions.md) or [GitLab CI/CD](gitlab-ci-cd.md) | Your pipeline’s events, such as every pull request or merge request              | Your own CI runners          | Anyone with a Claude API key or cloud provider credentials, on GitHub or GitLab                                    |
| Your own reviewer, as a [subagent](../09-Agents-Patterns/sub-agents.md) or [skill](../08-Plugins-Skills/skills.md)                            | You or Claude invoke it during a session                                         | Wherever you run Claude Code | Anyone who writes one                                                                                              |


[​](#related-resources)

Related resources

- [GitHub Enterprise Server](github-enterprise-server.md): use Code Review with a self-hosted GitHub instance
- [GitHub App permissions](github-actions.md#github-app-permissions): the full permission set the Claude GitHub App requests
- [How Anthropic secures its AI-native software development lifecycle](https://claude.com/blog/how-anthropic-secures-its-ai-native-software-development-lifecycle): how automated review fits as one layer of Anthropic’s secure development process

---

## Commands - Claude Code Docs

Source: https://code.claude.com/docs/en/commands
Path: 02-Claude-Code-CLI/commands.md

## On this page

- [Commands across a typical workflow](#commands-across-a-typical-workflow)
- [All commands](#all-commands)
- [How the command menu matches what you type](#how-the-command-menu-matches-what-you-type)
- [MCP prompts](#mcp-prompts)
- [See also](#see-also)

Reference

# Commands

Copy pageCopy page

Complete reference for commands available in Claude Code, including built-in commands and bundled skills.

Copy pageCopy page

Commands control Claude Code from inside a session. They provide a quick way to switch models, manage permissions, clear context, run a workflow, and more. Type `/` to see the commands available to you, or type `/` followed by letters to filter. [How the command menu matches what you type](#how-the-command-menu-matches-what-you-type) covers highlighting, typos, and the few commands Claude Code hides from the menu until you type their full name. A command is only recognized at the start of your message. Text that follows the command name becomes its arguments. At the terminal prompt, you can start one message with several [skills](../08-Plugins-Skills/skills.md#stack-several-skills-in-one-message): typing `/skill-a /skill-b do XYZ` loads both skills and passes the trailing text to each as arguments. Up to six skills can be chained. If you send a command while Claude is responding, Claude Code queues it and runs it after the current turn finishes. Claude Code runs some commands immediately without interrupting the response, such as `/status`, `/tasks`, and `/usage`. In [fullscreen rendering](fullscreen.md), Claude Code also opens dialog commands such as `/theme` and `/help` immediately. Before v2.1.234, Claude Code queued those dialogs until the turn finished.


[​](#commands-across-a-typical-workflow)

Commands across a typical workflow

Most commands are useful at a specific point in a session, from setting up a project to shipping a change. **First session in a repo.** Run `/init` to generate a starter `CLAUDE.md`, then `/memory` to refine it. Use `/mcp` to set up any servers the project needs, ask Claude to create any [subagents](../09-Agents-Patterns/sub-agents.md) you want, and run `/permissions` to set your approval rules. **During a task.** `/plan` switches into plan mode before a large change. `/model` and `/effort` adjust which model you’re using and how much reasoning it applies. When the conversation gets long, `/context` shows what’s filling the window and `/compact` summarizes it to free space. Use `/btw` for a side question that shouldn’t add to the conversation history. **Run work in parallel.** Claude delegates side tasks to [subagents](../09-Agents-Patterns/sub-agents.md), and `/tasks` lists the current session’s background work, including subagents that have finished. `/background` detaches the whole session to keep running as a [background agent](../09-Agents-Patterns/agent-view.md) and frees your terminal. For a large change that spans the codebase, `/batch` decomposes it into independent units and runs each in its own [worktree](worktrees.md). See [Run agents in parallel](../09-Agents-Patterns/agents.md) for how these approaches relate. **Before you ship.** `/diff` shows what changed. `/code-review` checks the current diff for correctness bugs and can apply the findings with `--fix`; pass a PR number, such as `/code-review high 1234`, to review a pull request instead. `/review` is an alias. `/code-review ultra` runs a multi-agent review in the cloud. `/security-review` checks the diff for security vulnerabilities. **Between sessions.** `/clear` starts fresh on a new task while keeping project memory. `/resume` returns to an earlier conversation, `/branch` branches the current one to try a different direction, and `/fork` copies it into a new [background session](../09-Agents-Patterns/agent-view.md). `/teleport` pulls a cloud session into this terminal, and `/remote-control` lets you continue this local session from another device. **When something is wrong.** `/rewind` rolls code and conversation back to a checkpoint, or summarizes part of the conversation. `/doctor` runs a setup checkup that diagnoses installation and configuration issues and can fix them, `/debug` diagnoses runtime issues, and `/feedback` reports a bug with session context attached.


[​](#all-commands)

All commands

The 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:

- **[Skill](../08-Plugins-Skills/skills.md#bundled-skills)**: a bundled skill. It works like skills you write yourself: a prompt handed to Claude.
  - `/verify` runs only when you invoke it. Before v2.1.215, Claude could also run `/verify` on its own.
- **[Workflow](workflows.md#bundled-workflows)**: a bundled [dynamic workflow](workflows.md) that fans work out across many subagents and runs in the background.
  - `/deep-research` runs only when you invoke it. Before v2.1.218, Claude could also start it on its own.

To add your own commands, see [skills](../08-Plugins-Skills/skills.md). In the table below, `<arg>` indicates a required argument and `[arg]` indicates an optional one.

Not every command appears for every user. Availability depends on your platform, plan, and environment. For example, `/desktop` only shows on macOS and x64 Windows when signed in with a Claude subscription, and `/upgrade` doesn’t show on Enterprise plans.

| Command                                                                                                                                                               | Purpose                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `/add-dir <path>`                                                                                                                                                     | Add a working directory for file access during the current session. Type a partial path to see matching directory suggestions; press `Tab` to accept one. Most `.claude/` configuration [isn’t discovered](permissions.md#additional-directories-grant-file-access-not-configuration) from the added directory. You can’t add most [network paths](errors.md#working-directory-is-a-network-path), such as `\\server\share`. After a successful add, your [`DirectoryAdded` hooks](../07-Hooks/hooks.md#directoryadded) run. When you run it while Claude is responding, Claude Code asks you to confirm the directory right away, and once you confirm, Claude’s next tool call in the same turn can access it. Before v2.1.234, Claude Code queued the command until the turn finished                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `/advisor [model|off]`                                                                                                                                                | Enable or disable the [advisor tool](advisor.md), which consults a second model for guidance at key moments during a task. Accepts `fable`, `opus`, `sonnet`, or a full model ID. `fable` requires [Fable access](advisor.md#choose-an-advisor-model). Without an argument, opens a picker. In a session without an interactive terminal, or over [Remote Control](remote-control.md#limitations), pass the model or `off` as an argument; with no argument there, the command prints the current advisor as text. These forms require Claude Code v2.1.260 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `/agents`                                                                                                                                                             | Print a reminder to ask Claude to create or manage [subagents](../09-Agents-Patterns/sub-agents.md), or to edit `.claude/agents/` or `~/.claude/agents/` directly. On v2.1.197 and earlier, opens an interactive interface for creating and managing subagent configurations                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `/artifact-capabilities`                                                                                                                                              | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Load the reference for the runtime capabilities a published [artifact](artifacts.md) can use, such as [calling your connectors](artifacts.md#pull-live-data-with-mcp-connectors) or [offering a file download](artifacts.md#offer-a-file-download), including which ones your account has. Claude normally loads it on its own before building a page that uses one. Available where [artifacts](artifacts.md#availability) are                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `/artifact-diagramming`                                                                                                                                               | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Load diagramming guidance for Claude to follow in [artifacts](artifacts.md): when a diagram helps, what to draw, and how to write inline SVG that stays legible in light and dark themes. Requires Claude Code v2.1.221 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `/artifacts`                                                                                                                                                          | List the [artifacts](artifacts.md#find-an-artifact-again) you own or that are shared with you, then attach one to the session, open it in your browser, or copy its link. Available where [artifacts](artifacts.md#availability) are. Requires Claude Code v2.1.208 or later; attaching with `Enter` requires v2.1.216                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `/auto-mode-setup`                                                                                                                                                    | [Draft `autoMode.environment` entries](auto-mode-config.md#generate-environment-entries) from your project and recent sessions, then review the draft and save it to your user settings. On a Pro, Max, or Team plan, requires Claude Code v2.1.228 or later, or v2.1.233 or later on native Windows. On an Enterprise plan or with a Claude Console API key, requires v2.1.283 or later. If the command is missing, see [`/auto-mode-setup` returns “Unknown command”](auto-mode-config.md#auto-mode-setup-returns-unknown-command)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `/autocompact [auto|<tokens>]`                                                                                                                                        | Set the auto-compact window: how full the context window gets before Claude Code compacts automatically. Pass a size such as `500k`, or `auto` to return to the window tuned for your model. Claude Code saves the value to user settings and applies it to the current session. See [Set the auto-compact window](model-config.md#set-the-auto-compact-window) for accepted values and what overrides it. Without an argument, opens a dialog that shows the current window. Requires Claude Code v2.1.221 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `/autofix-pr [prompt]`                                                                                                                                                | Spawn a [cloud session](claude-code-on-the-web.md#auto-fix-pull-requests) that watches the current branch’s PR and pushes fixes when CI fails or reviewers leave comments. Detects the open PR from your checked-out branch with `gh pr view`; to watch a different PR, check out its branch first. By default the cloud session is told to fix every CI failure and review comment; pass a prompt to give it different instructions, for example `/autofix-pr only fix lint and type errors`. Requires the `gh` CLI and access to [cloud sessions](claude-code-on-the-web.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `/background [prompt]`                                                                                                                                                | Detach the current session to run as a [background agent](../09-Agents-Patterns/agent-view.md) and free this terminal. Pass a prompt to send one more instruction before detaching. Monitor the session with `claude agents`. To copy the conversation into a new background session while this one keeps running, use `/fork`. Alias: `/bg`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `/batch <instruction>`                                                                                                                                                | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Orchestrate large-scale changes across a codebase in parallel. Researches the codebase, decomposes the work into 5 to 30 independent units, and presents a plan. Once approved, spawns one [background subagent](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) per unit in an isolated [worktree](worktrees.md). Each subagent implements its unit, runs tests, and publishes its change. Requires a git repository or a [`WorktreeCreate` hook](worktrees.md#non-git-version-control) that creates the worktrees. Outside a git repository, `/batch` requires Claude Code v2.1.281 or later. Example: `/batch migrate src/ from JavaScript to TypeScript`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `/branch [name]`                                                                                                                                                      | Create a branch of the current conversation at this point, so you can try a different direction without losing the conversation as it stands. Switches you into the branch and preserves the original, which you can return to with `/resume`. To run a copy as a separate [background session](../09-Agents-Patterns/agent-view.md) instead of switching into it, use `/fork`; to hand a side task to a [subagent](../09-Agents-Patterns/sub-agents.md) that reports back into this conversation, use `/subtask`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `/btw [question]`                                                                                                                                                     | Ask a [side question](interactive-mode.md#side-questions-with-%2Fbtw) about the current session without adding to the conversation. If you run `/btw` without a question, Claude Code shows your most recent side question so you can browse earlier answers; if you haven’t asked one yet, Claude Code prints a usage line                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `/bug [report]`                                                                                                                                                       | Report a bug or share your conversation. You choose how much session history to include and confirm on a consent screen before anything is sent. When you’re signed in to Anthropic on a first-party connection, the report goes to Anthropic; on a third-party provider, or without Anthropic credentials, Claude Code writes the report to a [local archive under `~/.claude/feedback-bundles/`](../13-Enterprise-Admin/data-usage.md#telemetry-services) that you forward yourself. In the [VS Code extension](../03-IDE-Integrations/vs-code.md#use-the-prompt-box), `/bug` opens the extension’s own feedback dialog instead; requires Claude Code v2.1.229 or later. When you run it while Claude is responding, Claude Code opens the dialog immediately. Before v2.1.232, Claude Code queued the command until the turn finished. Alias: `/share`. Before v2.1.212, `/bug` and `/share` were aliases of `/feedback`                                                                                                                                                                                                                                                                                                                                                             |
| `/cd <path>`                                                                                                                                                          | Move this session to a new working directory, keeping the conversation. Type a partial path to see matching directory suggestions; press `Tab` to accept one. For what Claude Code applies from the new directory as soon as you move, and how `/cd` differs from `/add-dir`, see [Move the session to another directory](permissions.md#move-the-session-to-another-directory)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `/chrome`                                                                                                                                                             | Configure [Claude in Chrome](../03-IDE-Integrations/chrome.md) settings                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `/claude-api [migrate|upgrade|api-version|managed-agents-onboard|managed-agents-secure|prompt-audit|cost-optimize|build-eval|hillclimb|preserved-thinking-migration]` | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Load [Claude API](../04-API-Reference/Endpoints/overview.md) and [Managed Agents](../04-API-Reference/Other/managed-agents-overview.md) reference material for your project’s language. Also activates automatically when your code imports `anthropic` or `@anthropic-ai/sdk`. For what each subcommand does and the version it requires, see [Work on Claude API projects](../08-Plugins-Skills/skills.md#work-on-claude-api-projects)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `/claude-in-chrome [task]`                                                                                                                                            | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Have Claude carry out a task in your browser, such as testing a page, filling a form, or reading console logs, through [Claude in Chrome](../03-IDE-Integrations/chrome.md). Available when Chrome integration is enabled for the session, for example with `claude --chrome`, or when Claude Code can offer to [install the extension](../03-IDE-Integrations/chrome.md#install-the-extension-when-claude-asks)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `/clear [name]`                                                                                                                                                       | Start a new conversation with empty context. Pass a name to label the previous conversation in the `/resume` picker. To free up context while continuing the same conversation, use `/compact` instead. Resume the previous conversation with `/resume`, or, in the same Claude Code process, restore it from [the rewind menu’s previous-session entry](checkpointing.md#rewind-past-a-cleared-conversation). Aliases: `/reset`, `/new`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `/code-review [low|medium|high|xhigh|max|ultra] [--fix] [--comment] [--max-findings n|all|default] [pr#|branch|path]`                                                 | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Review the current diff, or a PR number, branch, or path you pass, for correctness bugs. Depending on your model and effort level, the review also covers cleanup opportunities. Pass `--fix` to have Claude apply the findings, `--comment` to post them on the GitHub PR or GitLab merge request, or `ultra` to run a deep [cloud review](ultrareview.md). Posting to a GitLab merge request requires Claude Code v2.1.257 or later. With `ultra` on a `github.com` PR target, pass `--post` to preselect [posting the finished findings to the PR](ultrareview.md#post-findings-to-the-pull-request) in the launch dialog; `--post` requires Claude Code v2.1.227 or later. See [Review locally with `/code-review`](code-review-local.md) for the effort levels, targeting, and how it relates to `/simplify`. Alias: `/review`                                                                                                                                                                                                                                                                                                                                                    |
| `/color [color|default]`                                                                                                                                              | Set the prompt bar color for the current session. Available colors: `red`, `blue`, `green`, `yellow`, `purple`, `orange`, `pink`, `cyan`. Use `default` to reset, or run with no argument to pick a random color. When [Remote Control](remote-control.md) is connected, the color syncs to claude.ai/code. Also available in non-interactive mode (`-p`)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `/compact [instructions]`                                                                                                                                             | Free up context by summarizing the conversation so far. Optionally pass focus instructions for the summary. See [how compaction handles rules, skills, and memory files](context-window.md#what-survives-compaction)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `/config [key=value ...]`                                                                                                                                             | Open the [Settings](settings.md) interface to adjust theme, model, [output style](output-styles.md), and other preferences. Pass one or more `key=value` pairs to set a setting directly without opening the interface, for example `/config thinking=false`, `/config theme=dark`, or `/config model=sonnet`. The `key=value` form also works in non-interactive mode (`-p`) and from the Claude mobile app via [Remote Control](remote-control.md). The `key=value` form can’t turn on a setting that needs your confirmation in the panel, such as [`autoContinueAtUsageLimit`](interactive-mode.md#turn-automatic-continue-off), though it can turn one off. Run `/config --help` to list the keys it accepts. Alias: `/settings`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `/context [all]`                                                                                                                                                      | Visualize current context usage as a colored grid. Shows optimization suggestions for context-heavy tools, memory bloat, and capacity warnings. When the conversation exceeds the context window, the output includes a [warning](errors.md#context-exceeds-the-token-limit) showing how far over the limit you are and which command frees space. In [fullscreen mode](fullscreen.md), `/context` collapses the per-item breakdown to keep the grid visible. Pass `all` to expand it                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `/copy [N]`                                                                                                                                                           | Copy the last assistant response to clipboard. Pass a number `N` to copy the Nth-latest response: `/copy 2` copies the second-to-last. When code blocks or blockquotes are present, shows an interactive picker to select individual blocks or the full response. Press `w` in the picker to write the selection to a file instead of the clipboard, which is useful over SSH                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `/cost`                                                                                                                                                               | Alias for `/usage`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `/dataviz [request]`                                                                                                                                                  | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Design guidance for charts, graphs, and dashboards. Claude picks the chart form for the data, assigns color by role, validates the palette for colorblind safety and contrast with a bundled script, and applies mark, interaction, and accessibility rules. Uses a brand-neutral placeholder palette that you replace with your own                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `/debug [description]`                                                                                                                                                | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Enable debug logging for the current session and troubleshoot issues by reading the session debug log. Debug logging is off by default unless you started with `claude --debug`, so running `/debug` mid-session starts capturing logs from that point forward. Optionally describe the issue to focus the analysis                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `/deep-research <question>`                                                                                                                                           | **[Workflow](workflows.md#bundled-workflows).** Fan out web searches on a question, fetch and cross-check sources, and synthesize a cited report                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `/design [brief]`                                                                                                                                                     | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Draft UI mockups, screen flows, landing pages, or posters as artboards on one canvas, published as a Claude Design [artifact](artifacts.md#draft-a-design-canvas), for example `/design a settings screen for a mobile banking app`. You edit the artboards in a desktop browser, and your edits save automatically. You can export each artboard as PNG or PDF. Requires Claude Code v2.1.265 or later, a session where [artifacts are available](artifacts.md#availability), and an account where the [Design template is available](artifacts.md#start-from-a-slides-design-or-docs-template); if your organization has turned that template off, `/design` doesn’t draft designs. Available on the Anthropic API. On Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and Claude Platform on AWS, artifacts aren’t available, so the command is unavailable there                                                                                                                                                                                                                                                                                                 |
| `/design consent`, `/design revoke`                                                                                                                                   | Grant Claude access to [Claude Design](https://claude.ai/design), or withdraw it. When a reply from Claude asks you to run `/design consent`, type it at the Claude Code prompt yourself                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `/design-login`                                                                                                                                                       | Authorize design-system access for `/design-sync` with your claude.ai account. Sign in with `/design-login` whenever `/design-sync` or `/design consent` tells you to. This sign-in is for the standalone Claude Design site at claude.ai/design, which closes by December 14, 2026; see [Migrate from standalone Claude Design to Claude](https://support.claude.com/en/articles/17440474-migrate-from-standalone-claude-design-to-claude)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `/design-sync [hint]`                                                                                                                                                 | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Convert your repo’s React design system and upload it to [Claude Design](https://claude.ai/design), so designs it produces use your real components. Optionally name the design system, for example `/design-sync Acme DS`. A first-time sync verifies every component and can take a few hours on a large repo. Available on the Anthropic API. It needs claude.ai, which the CLI doesn’t contact on Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, or Claude Platform on AWS, or through a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md#availability-and-limitations). The command is unavailable there. This command uploads to the standalone claude.ai/design site, which closes by December 14, 2026; see [Migrate from standalone Claude Design to Claude](https://support.claude.com/en/articles/17440474-migrate-from-standalone-claude-design-to-claude)                                                                                                                                                                                                                                                                                                              |
| `/desktop`                                                                                                                                                            | Continue the current session in the Claude Code Desktop app. Requires macOS or x64 Windows and a Claude subscription. Alias: `/app`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `/diff`                                                                                                                                                               | Review the changes in your working tree, including the edits Claude has made so far. See [Review changes with /diff](interactive-mode.md#review-changes-with-%2Fdiff)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `/doctor [prompt-audit [path]]`                                                                                                                                       | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Run a setup checkup that diagnoses installation, settings, extension, and `CLAUDE.md` problems and proposes fixes that Claude applies after you confirm. For what the checkup covers, or to audit your instructions with `prompt-audit` instead, see [Check your setup with `/doctor`](../08-Plugins-Skills/skills.md#check-your-setup-with-/doctor). The `prompt-audit` subcommand requires Claude Code v2.1.283 or later. Alias: `/checkup`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `/effort [level|auto|status|ultracode [on|off]]`                                                                                                                      | Set the [effort level](model-config.md#adjust-effort-level): `low` to `xhigh`, `max`, or `auto`; `status` prints it. `ultracode` or `ultracode on` turns [ultracode](workflows.md#let-claude-decide-with-ultracode) on for the session at the current level, and `ultracode off` turns it off; the [`ultracode`](settings-reference.md#ultracode) key persists. `max` is session-only. The `on` and `off` arguments and keeping the current level require Claude Code v2.1.284 or later. Before v2.1.284, `/effort ultracode` set the session to `xhigh`, and `/effort ultracode off` failed with `Invalid argument`. Run it while Claude is responding and, once you confirm the [cache warning](prompt-caching.md#changing-effort-level), if Claude Code shows one, Claude Code applies the new level to the next request in that turn. Before v2.1.242, Claude Code decided from a feature flag it fetched from Anthropic whether to run the command mid-turn or queue it until the turn finished, and always queued it in a session that doesn’t [fetch feature flags](env-vars.md#features-that-need-feature-flag-fetching), such as on a [third-party provider](third-party-integrations.md). Works in `-p` |
| `/exit`                                                                                                                                                               | Exit the CLI. In an attached [background session](../09-Agents-Patterns/agent-view.md#attach-to-a-session), this detaches and the session keeps running. Alias: `/quit`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `/export [filename]`                                                                                                                                                  | Export the current conversation as plain text. With a filename, writes directly to that file. Without, opens a dialog to copy to clipboard or save to a file                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `/fast [on|off]`                                                                                                                                                      | Toggle [fast mode](fast-mode.md) on or off. Run it while Claude is responding and Claude Code toggles fast mode without waiting for the turn to end, though the running turn finishes at its original speed. Before v2.1.242, Claude Code decided from a feature flag it fetched from Anthropic whether to run the command mid-turn or queue it until the turn finished, and always queued it in a session that doesn’t [fetch feature flags](env-vars.md#features-that-need-feature-flag-fetching). Availability in non-interactive mode with `-p` is limited; see [Toggle fast mode](fast-mode.md#toggle-fast-mode)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `/feedback [report]`                                                                                                                                                  | Send product feedback about Claude Code. Opens the same dialog as [`/bug`](#all-commands), with the same consent step, sending rules, and mid-turn behavior. In sessions with [Claude-drafted feedback](tools-reference.md#sendfeedback-tool-behavior), `/feedback` with no argument opens the drafts queue instead, where you review, edit, send, or discard the drafts Claude queued; the queue includes an option to write a new report in the dialog. With an argument, and for `/bug` always, the dialog opens directly                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `/fewer-permission-prompts`                                                                                                                                           | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Scan your transcripts for common read-only Bash and MCP tool calls, then add a prioritized allowlist to project `.claude/settings.json` to reduce permission prompts                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `/focus`                                                                                                                                                              | Toggle the focus view, which shows only your last prompt, a one-line tool-call summary with edit diffstats, and the final response. The tool-call summary also counts the subagents launched in the turn and collapses completed background-task notifications into a single count. The selection persists across sessions; set [`viewMode`](settings-reference.md#viewmode) in settings to override it. Only available in [fullscreen rendering](fullscreen.md). From a [Remote Control](remote-control.md) client, run `/focus [on|off]` to turn the focus view on or off for the current session only, without changing your saved selection; this requires Claude Code v2.1.281 or later. The [VS Code extension](../03-IDE-Integrations/vs-code.md#use-the-prompt-box) offers its own Focus view as a command-menu toggle, stored as an extension setting, independent of `viewMode`                                                                                                                                                                                                                                                                                                                                                            |
| `/fork [prompt]`                                                                                                                                                      | [Copy the current conversation](../09-Agents-Patterns/agent-view.md#copy-the-session-with-%2Ffork) into a new background session and keep working here. Pass a prompt and the copy starts working on it immediately; without one it waits in agent view for its first prompt. Except when the copy [edits in place](../09-Agents-Patterns/agent-view.md#how-file-edits-are-isolated), Claude Code instructs it to create a worktree of its own before making code changes; the isolation instruction requires Claude Code v2.1.221 or later. To hand a side task to a subagent whose result comes back into this conversation, use `/subtask`; to switch into a copy yourself, use `/branch`. When [agent view is turned off](../09-Agents-Patterns/agent-view.md#turn-off-agent-view), `/fork` starts a [forked subagent](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation) instead                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `/goal [condition|clear]`                                                                                                                                             | Set a [goal](goal.md): Claude keeps working across turns until the condition is met or the goal [clears for another reason](goal.md#how-evaluation-works). With no argument, shows the current or most recently achieved goal. `clear`, `stop`, `off`, `reset`, `none`, or `cancel` removes an active goal early                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `/heapdump`                                                                                                                                                           | Write a JavaScript heap snapshot and a memory breakdown to `~/Desktop`, or your home directory on Linux without a Desktop folder, for diagnosing high memory usage. Attach only the `-diagnostics.json` file when reporting a memory issue; the `.heapsnapshot` contains your full conversation and credentials, so don’t share it. [Hidden from the command menu](#how-the-command-menu-matches-what-you-type); type it in full. See [what to do with the output](troubleshooting.md#high-cpu-or-memory-usage)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `/help`                                                                                                                                                               | Show help and available commands                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `/hooks`                                                                                                                                                              | View [hook](../07-Hooks/hooks.md#the-%2Fhooks-menu) configurations                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `/ide`                                                                                                                                                                | Manage IDE integrations and show status                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `/import [codex|gemini|cursor] [--dry-run] [--yes]`                                                                                                                   | Bring configuration from OpenAI Codex, Google Gemini CLI, or Cursor on your machine into Claude Code, including instruction files, MCP servers, commands, subagents, and skills. In [non-interactive mode](headless.md) with `-p`, `/import` lists what it found and gives you the command that confirms the import. Add `--dry-run` to preview without writing anything, or `--yes` to skip the interactive picker. Not available on Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, or Claude Platform on AWS, or through a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md#availability-and-limitations). Also unavailable when you turn off [feature-flag fetching](env-vars.md#features-that-need-feature-flag-fetching). Importing from Cursor requires v2.1.265 or later                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `/init`                                                                                                                                                               | Initialize project with a `CLAUDE.md` guide. Set `CLAUDE_CODE_NEW_INIT=1` for an interactive flow that also walks through skills, hooks, and personal memory files. If `/init` finds OpenAI Codex or Google Gemini CLI configuration, it offers to carry it over with `/import`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `/insights`                                                                                                                                                           | Generate an HTML report analyzing your recent sessions on this machine: which projects you work in, how you use Claude Code, where things go wrong, and features to try. Not available in [cloud sessions](claude-code-on-the-web.md). See [Analyze your usage patterns](../17-Billing-Plans/costs.md#analyze-your-usage-patterns) for the report location, retention, and cost                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `/install-github-app`                                                                                                                                                 | Install the Claude GitHub App for a repository, with an optional step to set up [GitHub Actions](github-actions.md) workflows and secrets. Walks you through selecting a repo and configuring the integration. Works only with github.com repositories. When your repository’s git remote is on gitlab.com or bitbucket.org, the command prints a notice and exits instead of starting setup. To run Claude Code from GitLab pipelines, see [GitLab CI/CD](gitlab-ci-cd.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `/install-slack-app`                                                                                                                                                  | Install the Claude Slack app. Opens a browser to complete the OAuth flow                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `/keybindings`                                                                                                                                                        | Open your [keyboard shortcuts](keybindings.md) file                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `/list-agents`                                                                                                                                                        | List the subagents, [agent team](../09-Agents-Patterns/agent-teams.md) teammates, and other Claude Code sessions Claude can message, with the name to use for each. See [cross-session messaging](cross-session-messaging.md). Also available as `/peers`. Requires Claude Code v2.1.224 or later; earlier versions report `Unknown command: /list-agents`. Teammate rows and the first line showing this session’s own name require v2.1.239 or later. Available only in sessions where [cross-session messaging is enabled](cross-session-messaging.md#availability)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `/login`                                                                                                                                                              | Sign in to your Anthropic account                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `/logout`                                                                                                                                                             | Sign out from your Anthropic account                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `/loop [interval] [prompt]`                                                                                                                                           | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Run a prompt repeatedly while the session stays open. Omit the interval and Claude [self-paces between iterations](scheduled-tasks.md#let-claude-choose-the-interval). Omit the prompt and Claude runs the [built-in maintenance prompt](scheduled-tasks.md#run-the-built-in-maintenance-prompt) or your [`loop.md`](scheduled-tasks.md#customize-the-default-prompt-with-loop-md). Example: `/loop 5m check if the deploy finished`. See [Run prompts on a schedule](scheduled-tasks.md). Alias: `/proactive`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `/mcp [reconnect (<server>|all)|enable|disable [<server>|all]]`                                                                                                       | Manage MCP server connections and OAuth authentication. Run with no argument to open the interactive list, or pass `reconnect`, `enable`, or `disable` with a server name or `all` to change connection state without opening it. `reconnect all` [retries every server that failed or needs authentication](../06-MCP-Tools/General/mcp.md#retry-failed-servers-yourself). In non-interactive mode (`-p`), running it with no argument prints a text summary of server status instead of opening the list                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `/memory`                                                                                                                                                             | Edit `CLAUDE.md` files, enable or disable [auto memory](memory.md#auto-memory), and view auto memory entries                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `/mobile`                                                                                                                                                             | Show QR code to download the Claude mobile app. Aliases: `/ios`, `/android`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `/model [model]`                                                                                                                                                      | Switch the AI model and save it as your default for new sessions. For models that support it, use left/right arrows to [adjust effort level](model-config.md#adjust-effort-level). With no argument, opens a picker; press `s` on a row to switch for the current session only. See [when Claude Code asks you to confirm the switch](prompt-caching.md#switching-models). Once you confirm the switch, if Claude Code asks, Claude Code applies the change without waiting for the current response to finish. Before v2.1.242, Claude Code decided from a feature flag it fetched from Anthropic whether to run the command mid-turn or queue it until the turn finished, and always queued it in a session that doesn’t [fetch feature flags](env-vars.md#features-that-need-feature-flag-fetching), such as on a [third-party provider](third-party-integrations.md). Also available in non-interactive mode (`-p`) with a model argument instead of the picker, where it applies to the current session only and isn’t saved as your default; requires Claude Code v2.1.205 or later                                                                                                                                     |
| `/output-style [style]`                                                                                                                                               | List [output styles](output-styles.md) or switch to one, for example `/output-style concise`. See [Change your output style](output-styles.md#change-your-output-style). Requires Claude Code v2.1.269 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `/passes`                                                                                                                                                             | Share a free week of Claude Code with friends. Only visible if your account is eligible                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `/permissions`                                                                                                                                                        | Manage allow, ask, and deny rules for tool permissions. Opens an interactive dialog where you can view rules by scope, add or remove rules, manage working directories, and review [recent auto mode denials](auto-mode-config.md#review-denials). You can also view and edit [auto mode classifier rules](auto-mode-config.md#edit-rules-from-permissions) from the dialog’s **Auto mode** tab. When you run it while Claude is responding, Claude Code opens the dialog immediately and applies your changes starting with Claude’s next tool call in the same turn. Before v2.1.234, Claude Code queued the command until the turn finished. Alias: `/allowed-tools`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `/plan [description]`                                                                                                                                                 | Enter plan mode directly from the prompt. Pass an optional description to enter plan mode and immediately start with that task, for example `/plan fix the auth bug`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `/plugin [subcommand]`                                                                                                                                                | Manage Claude Code [plugins](../08-Plugins-Skills/plugins.md). Run with no argument to open the plugin menu, or pass a subcommand such as `list`, `install`, `enable`, or `disable` to act directly. Claude Code can activate a plugin during the install; the [install summary](../08-Plugins-Skills/discover-plugins.md#install-a-plugin) tells you whether it did or whether to run `/reload-plugins`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `/plugin-authoring`                                                                                                                                                   | Load the reference Claude works from to [write a mod](../08-Plugins-Skills/plugins-mods-create.md#ask-claude-for-a-mod). Claude can load it on its own when you ask for a mod. This is a skill from a [built-in plugin](../08-Plugins-Skills/plugins-mods-overview.md#mods-built-into-claude-code), which you can turn off in `/plugin`. Requires Claude Code v2.1.287 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `/powerup`                                                                                                                                                            | Discover Claude Code features through quick interactive lessons with animated demos                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `/pr-comments [PR]`                                                                                                                                                   | Removed in v2.1.91. Ask Claude directly to view pull request comments instead. On earlier versions, fetches and displays comments from a GitHub pull request; automatically detects the PR for the current branch, or pass a PR URL or number. Requires the `gh` CLI                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `/privacy-settings`                                                                                                                                                   | View and update your privacy settings. Only available for Pro and Max plan subscribers                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `/radio`                                                                                                                                                              | Open Claude FM lo-fi radio in your browser. Prints the stream URL when no browser is available                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `/rate-limit-options`                                                                                                                                                 | Show ways to keep working when a claude.ai usage limit blocks a request: wait and [continue automatically when the limit resets](interactive-mode.md#wait-for-a-usage-limit-to-reset), add [usage credits](../17-Billing-Plans/costs.md#add-usage-credits-to-your-subscription), or upgrade your plan. Claude Code can also open this menu on its own when you hit a limit at your own terminal. See [Turn automatic continue off](interactive-mode.md#turn-automatic-continue-off). Requires a claude.ai subscription. The wait-and-continue rows require Claude Code v2.1.234 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `/recap`                                                                                                                                                              | Generate a one-line summary of the current session on demand. See [Session recap](interactive-mode.md#session-recap) for the automatic recap that appears after you’ve been away                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `/release-notes`                                                                                                                                                      | View the changelog in an interactive version picker. Select a specific version to see its release notes, or choose to show all versions. The notes appear in your transcript without entering the conversation Claude sees                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `/reload-plugins [--force]`                                                                                                                                           | Reload all active [plugins](../08-Plugins-Skills/plugins.md) to apply pending changes without restarting. Reports counts for each reloaded component and flags any load errors. When the reload would change which MCP tools are loaded and invalidate the prompt cache, the command warns and skips unless you pass `--force`. Also available in non-interactive mode (`-p`), the Agent SDK, and the desktop app, where it runs only on input typed directly into the session and doesn’t apply plugin MCP server changes; requires Claude Code v2.1.260 or later. See [Apply plugin changes without restarting](../08-Plugins-Skills/plugins-cli-reference.md#reload-plugins)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `/reload-skills`                                                                                                                                                      | Re-scan [skill](../08-Plugins-Skills/skills.md) and command directories so skills added or changed on disk during the session become available without restarting. Reports how many skills are available and how many were added or removed                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `/remote-control`                                                                                                                                                     | Make this session available for [Remote Control](remote-control.md) from claude.ai. Running it while signed out prints that Remote Control requires a claude.ai subscription and tells you how to sign in. Alias: `/rc`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `/remote-env`                                                                                                                                                         | Choose the default [cloud environment](cloud-environments.md#select-an-environment-from-the-cli) for cloud sessions you start from the CLI                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `/rename [name]`                                                                                                                                                      | Rename the current session and show the name on the prompt bar. Without a name, auto-generates one from conversation history. Also available in non-interactive mode (`-p`). From every rename surface, including claude.ai and the desktop app, Claude Code replaces control and invisible characters in the new name with spaces and caps the name at 200 characters. If the name is empty once invisible characters are removed, Claude Code rejects it and shows `That name is empty once invisible characters are removed. Usage: /rename <name>`. The character replacement and length cap require Claude Code v2.1.221 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `/resume [session]`                                                                                                                                                   | Resume a conversation by ID or name, or open the session picker. [Background sessions](../09-Agents-Patterns/agent-view.md) appear in the picker marked with `bg`. Resuming one that is still running, from the picker or by ID or name, [opens that session](sessions.md#resume-a-running-background-session): your current conversation moves to the background and this terminal attaches to the running one. Press `←` on an empty prompt to return to agent view, which also lists the conversation you left. Before v2.1.285, Claude Code refused and told you to open the session with `claude attach` or stop it first. Alias: `/continue`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `/review [low|medium|high|xhigh|max|ultra] [--fix] [--comment] [--max-findings n|all|default] [pr#|branch|path]`                                                      | Alias of [`/code-review`](code-review-local.md): reviews the current diff, or a PR number, branch, or path you pass, such as `/review 1234`, and takes the same effort levels and flags. With no level given, the review reuses the last `low` through `max` level you typed; see [Review locally with `/code-review`](code-review-local.md) for the exact rules. For a deep cloud review, use [`/code-review ultra`](ultrareview.md). Before v2.1.223, `/review` was a separate command that ran a single-pass, read-only review of a GitHub pull request by number, listing open PRs to pick from when run with no argument; from v2.1.186 through v2.1.201, it ran the same multi-agent engine as `/code-review medium`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `/rewind`                                                                                                                                                             | Rewind the conversation and/or code to a previous point, or summarize from a selected message. See [checkpointing](checkpointing.md). Aliases: `/checkpoint`, `/undo`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `/run`                                                                                                                                                                | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Launch and drive your project’s app to see a change working, not only passing tests. See [Run and verify your app](../08-Plugins-Skills/skills.md#run-and-verify-your-app)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `/run-skill-generator`                                                                                                                                                | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Teach `/run` and `/verify` how to build, launch, and drive your project’s app from a clean environment by writing a per-project [skill](../08-Plugins-Skills/skills.md#run-and-verify-your-app)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `/sandbox`                                                                                                                                                            | Toggle [sandbox mode](sandboxing.md). Available on supported platforms only                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `/schedule [description]`                                                                                                                                             | Create, update, list, or run [cloud scheduled tasks](web-scheduled-tasks.md), formerly routines. Claude walks you through the setup conversationally. You can also ask about a [scheduled task’s recent runs](web-scheduled-tasks.md#manage-scheduled-tasks-from-the-cli). Alias: `/routines`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `/scroll-speed`                                                                                                                                                       | Adjust mouse wheel [scroll speed](fullscreen.md#mouse-wheel-scrolling) interactively. Available in [fullscreen rendering](fullscreen.md) only and not in the JetBrains IDE terminal                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `/security-review`                                                                                                                                                    | Analyze the changes on your current branch for security vulnerabilities. Reviews the diff between your branch and origin’s default branch, identifying risks like injection, auth issues, and data exposure. Needs an `origin` remote; if the review fails with an `ambiguous argument` error, see the [error reference](errors.md#security-review-fails-without-origin-head)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `/setup-bedrock`                                                                                                                                                      | Configure [Amazon Bedrock](amazon-bedrock.md) authentication, region, and model pins through an interactive wizard. [Hidden from the command menu](#how-the-command-menu-matches-what-you-type) until `CLAUDE_CODE_USE_BEDROCK=1` is set; type it in full. First-time Amazon Bedrock users can also access this wizard from the login screen                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `/setup-vertex`                                                                                                                                                       | Configure [Google Cloud’s Agent Platform](google-vertex-ai.md) authentication, project, region, and model pins through an interactive wizard. [Hidden from the command menu](#how-the-command-menu-matches-what-you-type) until `CLAUDE_CODE_USE_VERTEX=1` is set; type it in full. First-time Google Cloud’s Agent Platform users can also access this wizard from the login screen                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `/simplify [target]`                                                                                                                                                  | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Review the changed code for cleanup opportunities and apply the fixes. Four review [agents](../09-Agents-Patterns/sub-agents.md) run in parallel, covering reuse of existing helpers, simplification, efficiency, and whether the change is at the right level of abstraction. The review doesn’t look for correctness bugs. Use `/code-review` to find bugs. Pass a path or PR reference to review a specific target                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `/skill-doctor`                                                                                                                                                       | Show what each of your [skills](../08-Plugins-Skills/skills.md) costs in context and how often it gets used, so you can [find skills to turn off](../08-Plugins-Skills/skills.md#find-unused-skills). Requires Claude Code v2.1.252 or later and [feature-flag fetching](env-vars.md#features-that-need-feature-flag-fetching)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `/skills`                                                                                                                                                             | List available [skills](../08-Plugins-Skills/skills.md). Type to filter the list by name, description, or source. Press `t` to sort by token count, `Space` or `Enter` to [cycle a skill’s visibility to Claude and the `/` menu](../08-Plugins-Skills/skills.md#override-skill-visibility-from-settings), and `Esc` to save and close. You can’t cycle plugin skills, skills whose frontmatter sets `disable-model-invocation: true`, or skills with a `skillOverrides` entry in managed settings or the `--settings` flag                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `/slides [brief]`                                                                                                                                                     | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Make a new presentation as a Claude Slides [artifact](artifacts.md#make-a-slide-deck) filled from your brief, for example `/slides a quarterly review of the platform team`. Requires Claude Code v2.1.265 or later, a session where [artifacts are available](artifacts.md#availability), and an account where the [Slides template is available](artifacts.md#start-from-a-slides-design-or-docs-template); otherwise the command doesn’t appear. Available on the Anthropic API. On Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and Claude Platform on AWS, artifacts aren’t available, so the command is unavailable there                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `/stats`                                                                                                                                                              | Alias for `/usage`. Opens on the Stats tab                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `/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](../09-Agents-Patterns/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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `/statusline`                                                                                                                                                         | Configure Claude Code’s [status line](statusline.md). Describe what you want, or run without arguments to auto-configure from your shell prompt                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `/stickers`                                                                                                                                                           | Order Claude Code stickers                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `/stop`                                                                                                                                                               | Stop the [background session](../09-Agents-Patterns/agent-view.md) you’re attached to, or the one you send it to as a [peek reply](../09-Agents-Patterns/agent-view.md#peek-and-reply); the transcript and any worktree are kept. To detach without stopping, use `/exit` or press `←`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `/subtask <task>`                                                                                                                                                     | Spawn a [forked subagent](../09-Agents-Patterns/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](../09-Agents-Patterns/agent-view.md#turn-off-agent-view), `/subtask` isn’t available and `/fork` spawns the forked subagent instead                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `/tasks`                                                                                                                                                              | View and manage background work in the current session, including subagents that have finished. Also available as `/bashes`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `/team-onboarding`                                                                                                                                                    | Generate a team onboarding guide from your Claude Code usage history. Claude analyzes your sessions, commands, and MCP server usage from the past 30 days. It produces a markdown guide a teammate can paste as a first message to get set up quickly. For claude.ai subscribers on Team and Enterprise plans, also returns a share link teammates can open directly in Claude Code                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `/teleport`                                                                                                                                                           | Pull a [cloud session](claude-code-on-the-web.md#from-cloud-to-terminal) into this terminal. Opens a picker, then fetches the branch and conversation. Also available as `/tp`. Requires a claude.ai subscription                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `/terminal-setup`                                                                                                                                                     | [Install a Shift+Enter keybinding for newlines](terminal-config.md#enter-multiline-prompts) in VS Code, Cursor, Devin Desktop, Alacritty, or Zed. In Apple Terminal, [enable Option+Enter for newlines and turn off the audible bell](terminal-config.md#enable-option-key-shortcuts-on-macos) instead. In iTerm2, [turn on clipboard access so that `/copy` works](terminal-config.md#enable-option-key-shortcuts-on-macos)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `/theme`                                                                                                                                                              | Change the color theme. Includes an `auto` option that matches your terminal’s light or dark background, light and dark variants, colorblind-accessible (daltonized) themes, ANSI themes that use your terminal’s color palette, and any [custom themes](terminal-config.md#create-a-custom-theme) from `~/.claude/themes/` or plugins. Select **New custom theme…** to create one                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `/tui [default|fullscreen]`                                                                                                                                           | Set the terminal UI renderer and relaunch into it with your conversation intact. `fullscreen` enables the [flicker-free alt-screen renderer](fullscreen.md). With no argument, prints the active renderer                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `/ultraplan <prompt>`                                                                                                                                                 | Removed. Use [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode) instead. Previously sent a planning task to a [cloud session](claude-code-on-the-web.md) for review in your browser                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `/ultrareview [PR or branch]`                                                                                                                                         | Run a deep, multi-agent code review in a cloud sandbox with [ultrareview](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 and Max, then requires [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `/update-config [request]`                                                                                                                                            | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Describe a settings change, such as allowing a command, setting an environment variable, or adding a [hook](../07-Hooks/hooks.md), and Claude edits the matching [`settings.json`](settings.md) file. For options such as theme and model, use `/config` instead                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `/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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `/usage`                                                                                                                                                              | Show session cost, plan usage limits, and activity stats. On a Pro, Max, Team, or Enterprise plan, includes a [breakdown of what counts against your plan limits](../17-Billing-Plans/costs.md#plan-usage-breakdown). `/cost` and `/stats` are aliases                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `/usage-credits`                                                                                                                                                      | Configure usage credits, or request them from your admin, when you hit a limit. Opens your [usage-credits billing settings](../17-Billing-Plans/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`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `/verify`                                                                                                                                                             | **[Skill](../08-Plugins-Skills/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](../08-Plugins-Skills/skills.md#run-and-verify-your-app)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `/vim`                                                                                                                                                                | Removed in v2.1.92. To toggle between Vim and Normal editing modes, use `/config` → Editor mode                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `/voice [hold|tap|off]`                                                                                                                                               | Toggle [voice dictation](voice-dictation.md), or enable it in a specific mode. Requires a Claude.ai account                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `/web-setup`                                                                                                                                                          | Connect your GitHub account for [cloud sessions](web-quickstart.md#connect-from-your-terminal) using your local `gh` CLI credentials                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `/workflow-authoring`                                                                                                                                                 | **[Skill](../08-Plugins-Skills/skills.md#bundled-skills).** Load the reference for writing [dynamic workflow](workflows.md) scripts: the script API, resume behavior, quality patterns, and worked examples. Claude normally loads it on its own before writing a script; run it yourself before [editing a saved script by hand](workflows.md#edit-a-saved-script). Available when dynamic workflows are enabled, and requires Claude Code v2.1.248 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `/workflows`                                                                                                                                                          | Open the [workflow](workflows.md#watch-the-run) progress view to watch, pause, resume, or save running and completed workflows                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |


[​](#how-the-command-menu-matches-what-you-type)

How the command menu matches what you type

Claude Code filters the `/` menu as you type. Each bullet below covers one thing you might notice while filtering:

- **Highlighting**: Claude Code highlights the top suggestion only when the letters after the `/` match a command’s name or alias, from the start of the name or from a word within it, ignoring the `:`, `_`, and `-` separators. Typing `/adddir` highlights `/add-dir`, and typing `/new` highlights `/clear` through its alias. Press `Enter` to run the highlighted suggestion. These highlighting rules require Claude Code v2.1.236 or later.
- **After a typo**: Claude Code highlights nothing. The close matches stay listed, and you can pick one with `Tab` or the arrow keys, but `Enter` submits your text as typed and reports [Unknown command](errors.md#unknown-command).
- **Commands that aren’t available to you**: Claude Code leaves them out of the menu. When nothing matches, Claude Code shows `No commands match "/name"`. Most unavailable commands return [Unknown command](errors.md#unknown-command) when you submit them; a few, such as [`/schedule` on a Console API key](web-scheduled-tasks.md#schedule-returns-unknown-command), answer with their own availability message instead. Some commands also answer with a message of their own when your organization’s policy disables them.
- **Hidden commands**: Claude Code keeps a few available commands, such as `/heapdump`, out of the menu by design. A partial name never brings a hidden command into the menu: if the partial matches nothing visible, Claude Code shows the same no-match message. Claude Code lists the command only once you’ve typed its full name, and submitting the full name runs it.


[​](#mcp-prompts)

MCP prompts

MCP servers can expose prompts that appear as commands. See [MCP prompts](../06-MCP-Tools/General/mcp.md#use-mcp-prompts-as-commands) for details.


[​](#see-also)

See also

- [Skills](../08-Plugins-Skills/skills.md): create your own commands
- [Interactive mode](interactive-mode.md): keyboard shortcuts, Vim mode, and command history
- [CLI reference](cli-reference.md): launch-time flags

---

## Common workflows - Claude Code Docs

Source: https://code.claude.com/docs/en/common-workflows
Path: 02-Claude-Code-CLI/common-workflows.md

## On this page

- [Prompt recipes](#prompt-recipes)
  - [Understand new codebases](#understand-new-codebases)
  - [Get a quick codebase overview](#get-a-quick-codebase-overview)
  - [Find relevant code](#find-relevant-code)
  - [Fix bugs efficiently](#fix-bugs-efficiently)
  - [Refactor code](#refactor-code)
  - [Work with tests](#work-with-tests)
  - [Create pull requests](#create-pull-requests)
  - [Handle documentation](#handle-documentation)
  - [Work in notes and non-code folders](#work-in-notes-and-non-code-folders)
  - [Work with images](#work-with-images)
  - [Reference files and directories](#reference-files-and-directories)
  - [Run Claude on a schedule](#run-claude-on-a-schedule)
  - [Ask Claude about its capabilities](#ask-claude-about-its-capabilities)
  - [Example questions](#example-questions)
- [Resume previous conversations](#resume-previous-conversations)
- [Run parallel sessions with worktrees](#run-parallel-sessions-with-worktrees)
- [Plan before editing](#plan-before-editing)
- [Delegate research to subagents](#delegate-research-to-subagents)
- [Pipe Claude into scripts](#pipe-claude-into-scripts)
- [Next steps](#next-steps)

Use Claude Code

# Common workflows

Copy pageCopy page

Step-by-step guides for exploring codebases, fixing bugs, refactoring, testing, and other everyday tasks with Claude Code.

Copy pageCopy page

This page collects short recipes for everyday development. For higher-level guidance on prompting and context management, see [Best practices](best-practices.md). This page covers:

- [Prompt recipes](#prompt-recipes) for exploring code, fixing bugs, refactoring, testing, PRs, and documentation
- [Resume previous conversations](#resume-previous-conversations) so a task can span multiple sittings
- [Run parallel sessions with worktrees](#run-parallel-sessions-with-worktrees) so concurrent edits don’t collide
- [Plan before editing](#plan-before-editing) to review changes before they touch disk
- [Delegate research to subagents](#delegate-research-to-subagents) to keep your main context clean
- [Pipe Claude into scripts](#pipe-claude-into-scripts) for CI and batch processing


[​](#prompt-recipes)

Prompt recipes

These are prompt patterns for everyday tasks like exploring unfamiliar code, debugging, refactoring, writing tests, and creating PRs. Each works in any Claude Code surface; adapt the wording to your project.


[​](#understand-new-codebases)

Understand new codebases

For configuring Claude Code in a monorepo or large codebase, see [Monorepos and large repos](large-codebases.md).


[​](#get-a-quick-codebase-overview)

Get a quick codebase overview

Suppose you’ve just joined a new project and need to understand its structure quickly.

1

Navigate to the project root directory

```python
cd /path/to/project 
```

Replace `/path/to/project` with the path to your project.

2

Start Claude Code

```python
claude 
```

3

Ask for a high-level overview

```python
give me an overview of this codebase
```

4

Dive deeper into specific components

```python
explain the main architecture patterns used here
```

```python
what are the key data models?
```

```python
how is authentication handled?
```

Tips:

- Start with broad questions, then narrow down to specific areas
- Ask about coding conventions and patterns used in the project
- Request a glossary of project-specific terms


[​](#find-relevant-code)

Find relevant code

Suppose you need to locate code related to a specific feature or functionality.

1

Ask Claude to find relevant files

```python
find the files that handle user authentication
```

2

Get context on how components interact

```python
how do these authentication files work together?
```

3

Understand the execution flow

```python
trace the login process from front-end to database
```

Tips:

- Be specific about what you’re looking for
- Use domain language from the project
- Install a [code intelligence plugin](../08-Plugins-Skills/plugins-code-intelligence.md) for your language to give Claude precise “go to definition” and “find references” navigation

------------------------------------------------------------------------


[​](#fix-bugs-efficiently)

Fix bugs efficiently

Suppose you’ve encountered an error message and need to find and fix its source.

1

Share the error with Claude

```python
I'm seeing an error when I run npm test
```

2

Ask for fix recommendations

```python
suggest a few ways to fix the @ts-ignore in user.ts
```

3

Apply the fix

```python
update user.ts to add the null check you suggested
```

Tips:

- Tell Claude the command to reproduce the issue and get a stack trace
- Mention any steps to reproduce the error
- Let Claude know if the error is intermittent or consistent

------------------------------------------------------------------------


[​](#refactor-code)

Refactor code

Suppose you need to update old code to use modern patterns and practices. For porting an entire codebase to a new language, see [how Anthropic runs large-scale code migrations with Claude Code](https://claude.com/blog/ai-code-migration) on the blog.

1

Identify legacy code for refactoring

```python
find deprecated API usage in our codebase
```

2

Get refactoring recommendations

```python
suggest how to refactor utils.js to use modern JavaScript features
```

3

Apply the changes safely

```python
refactor utils.js to use ES2024 features while maintaining the same behavior
```

4

Verify the refactoring

```python
run tests for the refactored code
```

Tips:

- Ask Claude to explain the benefits of the modern approach
- Request that changes maintain backward compatibility when needed
- Do refactoring in small, testable increments

------------------------------------------------------------------------


[​](#work-with-tests)

Work with tests

Suppose you need to add tests for uncovered code.

1

Identify untested code

```python
find functions in NotificationsService.swift that are not covered by tests
```

2

Generate test scaffolding

```python
add tests for the notification service
```

3

Add meaningful test cases

```python
add test cases for edge conditions in the notification service
```

4

Run and verify tests

```python
run the new tests and fix any failures
```

Claude can generate tests that follow your project’s existing patterns and conventions. When asking for tests, be specific about what behavior you want to verify. Claude examines your existing test files to match the style, frameworks, and assertion patterns already in use. To improve coverage, ask Claude to identify edge cases you might have missed. Claude can analyze your code paths and suggest tests for error conditions, boundary values, and unexpected inputs that are often overlooked.

------------------------------------------------------------------------


[​](#create-pull-requests)

Create pull requests

You can create pull requests by asking Claude directly (“create a pr for my changes”), or guide Claude through it step-by-step:

1

Summarize your changes

```python
summarize the changes I've made to the authentication module
```

2

Generate a pull request

```python
create a pr
```

3

Review and refine

```python
enhance the PR description with more context about the security improvements
```

To find the session later, run `claude --from-pr 1234` with your own PR number, which opens the session picker filtered to sessions linked to that PR, or paste the PR URL into the [`/resume` picker](sessions.md#use-the-session-picker) search. Claude Code links the session to the PR when Claude creates it with `gh pr create` or `glab mr create`, and when Claude [works on an existing PR](../09-Agents-Patterns/agent-view.md#pull-request-status).

Review Claude’s generated PR before submitting and ask Claude to highlight potential risks or considerations.


[​](#handle-documentation)

Handle documentation

Suppose you need to add or update documentation for your code.

1

Identify undocumented code

```python
find functions without proper JSDoc comments in the auth module
```

2

Generate documentation

```python
add JSDoc comments to the undocumented functions in auth.js
```

3

Review and enhance

```python
improve the generated documentation with more context and examples
```

4

Verify documentation

```python
check if the documentation follows our project standards
```

Tips:

- Specify the documentation style you want (JSDoc, docstrings, etc.)
- Ask for examples in the documentation
- Request documentation for public APIs, interfaces, and complex logic

------------------------------------------------------------------------


[​](#work-in-notes-and-non-code-folders)

Work in notes and non-code folders

Claude Code works in any directory. Run it inside a notes vault, a documentation folder, or any collection of markdown files to search, edit, and reorganize content the same way you would code. The `.claude/` directory and `CLAUDE.md` sit alongside other tools’ config directories without conflict. Claude reads files fresh on each tool call, so it sees edits you make in another application the next time it reads that file.

------------------------------------------------------------------------


[​](#work-with-images)

Work with images

Suppose you need to work with images in your codebase, and you want Claude’s help analyzing image content.

1

Add an image to the conversation

You can use any of these methods:

1.  Drag and drop an image into the Claude Code window
2.  Copy an image and paste it into the CLI with `Ctrl+V`, or with [`Alt+V` on Windows and WSL](interactive-mode.md#general-controls)
3.  Provide an image path to Claude, for example “Analyze this image: /path/to/your/image.png”

2

Ask Claude to analyze the image

```python
What does this image show?
```

```python
Describe the UI elements in this screenshot
```

```python
Are there any problematic elements in this diagram?
```

3

Use images for context

```python
Here's a screenshot of the error. What's causing it?
```

```python
This is our current database schema. How should we modify it for the new feature?
```

4

Get code suggestions from visual content

```python
Generate CSS to match this design mockup
```

```python
What HTML structure would recreate this component?
```

Tips:

- Use images when text descriptions would be unclear or cumbersome
- Include screenshots of errors, UI designs, or diagrams for better context
- You can work with multiple images in a conversation
- Image analysis works with diagrams, screenshots, mockups, and more
- When Claude references images (for example, `[Image #1]`), `Cmd+Click` (Mac) or `Ctrl+Click` (Windows/Linux) the link to open the image in your default viewer

------------------------------------------------------------------------


[​](#reference-files-and-directories)

Reference files and directories

Use @ to quickly include files or directories without waiting for Claude to read them.

1

Reference a single file

```python
Explain the logic in @src/utils/auth.js
```

This includes the content of the file in the conversation when it fits the [Read tool](tools-reference.md#read-tool-behavior)’s token limit, 25,000 tokens by default. A text file larger than 256KB isn’t included.

2

Reference a directory

```python
What's the structure of @src/components?
```

3

Reference MCP resources

```python
Show me the data from @github:repos/owner/repo/issues
```

This fetches data from connected MCP servers using the format @server:resource. See [MCP resources](../06-MCP-Tools/General/mcp.md#use-mcp-resources) for details.

Tips:

- File paths can be relative or absolute
- Type `@` to open a path suggestion menu, then press Enter or Tab to accept the highlighted path and Enter again to send the message
- @ file references add `CLAUDE.md` in the file’s directory and parent directories to context
- Directory references show file listings, not contents
- You can reference multiple files in a single message (for example, “@file1.js and @file2.js”)

To stop `@` references from including file contents and directory listings, set [`CLAUDE_CODE_DISABLE_FILE_MENTIONS`](env-vars.md#variables) to `1` in your shell or in the [`env` block](env-vars.md#set-variables-in-settings-files) of user settings or [managed settings](../13-Enterprise-Admin/managed-settings.md). Claude then receives the paths you referenced with a note to read them using its file tools. The variable requires Claude Code v2.1.299 or later, and Claude Code ignores it in project and local settings. Your [`PreToolUse` hooks](../07-Hooks/hooks.md#pretooluse) don’t run when Claude Code includes a file you reference with `@`, because it makes no tool call. If you rely on those hooks to control what Claude reads, block specific paths or stop `@` references from including files:

- **Block specific paths**: add a [`Read` deny rule](permissions.md#read-and-edit) for them. Claude Code doesn’t include a file that the rule matches.
- **Stop `@` references from including files**: set `CLAUDE_CODE_DISABLE_FILE_MENTIONS=1`, which stops `@` file and directory references in your messages from including content, even for paths your hooks don’t check. Your matching hooks then run before Claude opens a referenced path with a tool such as `Read`.

------------------------------------------------------------------------


[​](#run-claude-on-a-schedule)

Run Claude on a schedule

Suppose you want Claude to handle a task automatically on a recurring basis, like reviewing open PRs every morning, auditing dependencies weekly, or checking for CI failures overnight. Pick a scheduling option based on where you want the task to run:

| Option                                                      | Where it runs                       | Best for                                                                                                                                                                                                 |
|:------------------------------------------------------------|:------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Cloud scheduled tasks](web-scheduled-tasks.md)                  | Cloud, Anthropic-managed by default | Tasks that should run even when your computer is off. Can also trigger on API calls or GitHub events in addition to a schedule. Configure at [claude.ai/code/routines](https://claude.ai/code/routines). |
| [Desktop scheduled tasks](../16-Mobile-Desktop/desktop-scheduled-tasks.md) | Your machine, via the desktop app   | Tasks that need direct access to local files, tools, or uncommitted changes.                                                                                                                             |
| [GitHub Actions](github-actions.md)                   | Your CI pipeline                    | Tasks tied to repo events like opened PRs, or cron schedules that should live alongside your workflow config.                                                                                            |
| [`/loop`](scheduled-tasks.md)                         | The current CLI session             | Quick polling while a session is open. `--resume` and `--continue` restore unexpired fixed-interval loops.                                                                                               |

When writing prompts for scheduled tasks, be explicit about what success looks like and what to do with results. The task runs autonomously, so it can’t ask clarifying questions. For example: “Review open PRs labeled `needs-review`, leave inline comments on any issues, and post a summary in the `#eng-reviews` Slack channel.”

------------------------------------------------------------------------


[​](#ask-claude-about-its-capabilities)

Ask Claude about its capabilities

Claude can answer questions about its own features and limitations. It looks up the answers in the current Claude Code documentation, so they aren’t limited to the version you’re running.


[​](#example-questions)

Example questions

```python
can Claude Code create pull requests?
```

```python
how does Claude Code handle permissions?
```

```python
what skills are available?
```

```python
how do I use MCP with Claude Code?
```

```python
how do I configure Claude Code for Amazon Bedrock?
```

```python
what are the limitations of Claude Code?
```

Claude provides documentation-based answers to these questions. For hands-on demonstrations, run `/powerup` for interactive lessons with animated demos, or refer to the specific workflow sections above.

Tips:

- Ask specific questions to get detailed answers
- Claude can explain complex features like MCP integration, enterprise configurations, and advanced workflows

------------------------------------------------------------------------


[​](#resume-previous-conversations)

Resume previous conversations

When a task spans multiple sittings, pick up where you left off instead of re-explaining context. Claude Code saves every conversation locally.

```python
claude --continue
```

This resumes the most recent session in the current directory; if there isn’t one yet, it prints `No conversation found to continue` and exits. Use `claude --resume` to choose from a list, or `/resume` from inside a running session. See [Manage sessions](sessions.md) for naming, branching, and the full picker reference.


[​](#run-parallel-sessions-with-worktrees)

Run parallel sessions with worktrees

Work on a feature in one terminal while Claude fixes a bug in another, without the edits colliding. Each [git worktree](https://git-scm.com/docs/git-worktree) is a separate checkout on its own branch, created from an existing commit, so the repository needs at least one commit first.

```python
claude --worktree feature-auth
```

Run the same command with a different name in a second terminal to start an isolated parallel session. In a repository with no commits, the command fails with `Failed to resolve base branch "HEAD": git rev-parse failed`. See [Worktrees](worktrees.md) for cleanup, `.worktreeinclude`, and non-git VCS support. To monitor parallel sessions from one screen instead of separate terminals, see [background agents](../09-Agents-Patterns/agent-view.md).


[​](#plan-before-editing)

Plan before editing

For changes you want to review before they touch disk, switch to plan mode. Claude reads files and proposes a plan but makes no edits until you approve. The status bar shows `⏸ plan mode on` while plan mode is active.

```python
claude --permission-mode plan
```

You can also press `Shift+Tab` mid-session until the status bar shows `⏸ plan mode on`. See [Plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode) for the approval flow and editing the plan in your text editor.


[​](#delegate-research-to-subagents)

Delegate research to subagents

Exploring a large codebase fills your context with file reads. Delegate the exploration so only the findings come back.

```python
use a subagent to investigate how our auth system handles token refresh
```

The subagent reads files in its own context window and reports a summary. See [Subagents](../09-Agents-Patterns/sub-agents.md) for defining custom agents with their own tools and prompts.


[​](#pipe-claude-into-scripts)

Pipe Claude into scripts

Run Claude non-interactively for CI, pre-commit hooks, or batch processing. Stdin and stdout work like any Unix tool.

```python
git log --oneline -20 | claude -p "summarize these recent commits"
```

See [Non-interactive mode](headless.md) for output formats, permission flags, and fan-out patterns.


[​](#next-steps)

Next steps

## Best practices

Patterns for getting the most out of Claude Code

## Manage sessions

Resume, name, and branch conversations

## Worktrees

Run isolated parallel sessions

## Extend Claude Code

Add skills, hooks, MCP, subagents, and plugins

---

## Let Claude use your computer from the CLI - Claude Code Docs

Source: https://code.claude.com/docs/en/computer-use
Path: 02-Claude-Code-CLI/computer-use.md

## On this page

- [What you can do with computer use](#what-you-can-do-with-computer-use)
- [When computer use applies](#when-computer-use-applies)
- [Enable computer use](#enable-computer-use)
- [Approve apps per session](#approve-apps-per-session)
- [How Claude works on your screen](#how-claude-works-on-your-screen)
  - [One session at a time](#one-session-at-a-time)
  - [Apps are hidden while Claude works](#apps-are-hidden-while-claude-works)
  - [Screenshots are downscaled automatically](#screenshots-are-downscaled-automatically)
  - [Stop at any time](#stop-at-any-time)
- [Safety and the trust boundary](#safety-and-the-trust-boundary)
- [Example workflows](#example-workflows)
  - [Validate a native build](#validate-a-native-build)
  - [Reproduce a layout bug](#reproduce-a-layout-bug)
  - [Test a simulator flow](#test-a-simulator-flow)
- [Differences from the Desktop app](#differences-from-the-desktop-app)
- [Troubleshooting](#troubleshooting)
  - [”Computer use is in use by another Claude session”](#%E2%80%9Dcomputer-use-is-in-use-by-another-claude-session%E2%80%9D)
  - [macOS permissions prompt keeps reappearing](#macos-permissions-prompt-keeps-reappearing)
  - [computer-use doesn’t appear in /mcp](#computer-use-doesn%E2%80%99t-appear-in-%2Fmcp)
- [See also](#see-also)

Platforms and integrations

# Let Claude use your computer from the CLI

Copy pageCopy page

Enable computer use in the Claude Code CLI so Claude can open apps, click, type, and see your screen on macOS. Test native apps, debug visual issues, and automate GUI-only tools without leaving your terminal.

Copy pageCopy page

Computer use is a research preview on macOS that requires a Pro or Max plan. It is not available on Team or Enterprise plans. It requires an interactive session, so it is not available in non-interactive mode with the `-p` flag.

Computer use lets Claude open apps, control your screen, and work on your machine the way you would. From the CLI, Claude can compile a Swift app, launch it, click through every button, and screenshot the result, all in the same conversation where it wrote the code. This page covers how computer use works in the CLI. For the Desktop app on macOS or Windows, see [computer use in Desktop](../16-Mobile-Desktop/desktop.md#let-claude-use-your-computer).


[​](#what-you-can-do-with-computer-use)

What you can do with computer use

Computer use handles tasks that require a GUI: anything you’d normally have to leave the terminal and do by hand.

- **Build and validate native apps**: ask Claude to build a macOS menu bar app. Claude writes the Swift, compiles it, launches it, and clicks through every control to verify it works before you ever open it.
- **End-to-end UI testing**: point Claude at a local Electron app and say “test the onboarding flow.” Claude opens the app, clicks through signup, and screenshots each step. No Playwright config, no test harness.
- **Debug visual and layout issues**: tell Claude “the modal is clipping on small windows.” Claude resizes the window, reproduces the bug, screenshots it, patches the CSS, and verifies the fix. Claude sees what you see.
- **Drive GUI-only tools**: interact with design tools, hardware control panels, the iOS Simulator, or proprietary apps that have no CLI or API.


[​](#when-computer-use-applies)

When computer use applies

Claude has several ways to interact with an app or service. Computer use is the broadest and slowest, so Claude tries the most precise tool first:

- If you have an [MCP server](../06-MCP-Tools/General/mcp.md) for the service, Claude uses that.
- If the task is a shell command, Claude uses Bash.
- If the task is browser work and you have [Claude in Chrome](../03-IDE-Integrations/chrome.md) set up, Claude uses that.
- If none of those apply, Claude uses computer use.

Screen control is reserved for things nothing else can reach: native apps, simulators such as the iOS Simulator, and tools without an API.


[​](#enable-computer-use)

Enable computer use

Computer use is available as a built-in MCP server called `computer-use`. It’s off by default until you enable it.

1

Open the MCP menu

In an interactive Claude Code session, run:

```python
/mcp
```

Find `computer-use` in the server list. It shows as disabled.

2

Enable the server

Select `computer-use` and choose **Enable**. The setting persists per project, so you only do this once for each project where you want computer use.

3

Grant macOS permissions

The first time Claude tries to use your computer, you’ll see a prompt to grant two macOS permissions:

- **Accessibility**: lets Claude click, type, and scroll
- **Screen Recording**: lets Claude see what’s on your screen

The prompt includes links to open the relevant System Settings pane. Grant both, then select **Try again** in the prompt. macOS may require you to restart Claude Code after granting Screen Recording.

After setup, ask Claude to do something that needs the GUI:

```python
Build the app target, launch it, and click through each tab to make
sure nothing crashes. Screenshot any error states you find.
```


[​](#approve-apps-per-session)

Approve apps per session

Enabling the `computer-use` server doesn’t grant Claude access to every app on your machine. The first time Claude needs a specific app in a session, a prompt appears in your terminal showing:

- Which apps Claude wants to control
- Any extra permissions requested, such as clipboard access
- How many other apps will be hidden while Claude works

Choose **Allow for this session** or **Deny**. Approvals last for the current session. You can approve multiple apps at once when Claude requests them together. Apps with broad reach show an extra warning in the prompt so you know what approving them grants:

| Warning                    | Applies to                                                   |
|:---------------------------|:-------------------------------------------------------------|
| Equivalent to shell access | Terminal, iTerm, VS Code, Warp, and other terminals and IDEs |
| Can read or write any file | Finder                                                       |
| Can change system settings | System Settings                                              |

These apps aren’t blocked. The warning lets you decide whether the task warrants that level of access. Approve Finder to let Claude click the desktop, the Dock, or a Finder window. Claude’s level of control also varies by app category: browsers and trading platforms are view-only, terminals and IDEs are click-only, and everything else gets full control. See [app permissions in Desktop](../16-Mobile-Desktop/desktop.md#app-permissions) for the complete tier breakdown.


[​](#how-claude-works-on-your-screen)

How Claude works on your screen

Understanding the flow helps you anticipate what Claude will do and how to intervene.


[​](#one-session-at-a-time)

One session at a time

Only one session at a time can use your computer. A session takes a lock at its first computer use action and releases it when the session exits, not when the task finishes. A second session’s computer use fails with an error naming the session that holds the lock. Exit that session first.


[​](#apps-are-hidden-while-claude-works)

Apps are hidden while Claude works

When Claude starts controlling your screen, other visible apps are hidden so Claude interacts with only the approved apps. Your terminal window stays visible and is excluded from screenshots, so you can watch the session and Claude never sees its own output. When Claude finishes the turn, hidden apps are restored automatically.


[​](#screenshots-are-downscaled-automatically)

Screenshots are downscaled automatically

Claude Code downscales every screenshot before sending it to the model. You don’t need to lower your display resolution or resize windows on Retina or other high-resolution displays. A 16-inch MacBook Pro at native Retina resolution captures at 3456×2234 and downscales to roughly 1372×887, preserving aspect ratio. There is no setting to change the target size. If on-screen text or controls are too small for Claude to read after downscaling, increase their size in the app rather than changing your display resolution.


[​](#stop-at-any-time)

Stop at any time

The first time Claude uses your computer in each turn, a macOS notification appears: “Claude is using your computer · press Esc to stop.” Press `Esc` anywhere to abort the current action immediately, or press `Ctrl+C` in the terminal. Either way, Claude stops, unhides your apps, and returns control to you. The session keeps the [computer use lock](#one-session-at-a-time) until it exits. A second notification appears when Claude is done.


[​](#safety-and-the-trust-boundary)

Safety and the trust boundary

Unlike the [sandboxed Bash tool](sandboxing.md), computer use runs on your actual desktop with access to the apps you approve. Claude checks each action and flags potential prompt injection from on-screen content, but the trust boundary is different. See the [computer use safety guide](https://support.claude.com/en/articles/14128542) for best practices.

The built-in guardrails reduce risk without requiring configuration:

- **Per-app approval**: Claude can only control apps you’ve approved in the current session.
- **Sentinel warnings**: apps that grant shell, filesystem, or system settings access are flagged before you approve.
- **Terminal excluded from screenshots**: Claude never sees your terminal window, so on-screen prompts in your session can’t feed back into the model.
- **Global escape**: the `Esc` key aborts computer use from anywhere, and the key press is consumed so prompt injection can’t use it to dismiss dialogs.
- **Lock file**: only one session can control your machine at a time.


[​](#example-workflows)

Example workflows

These examples show common ways to combine computer use with coding tasks.


[​](#validate-a-native-build)

Validate a native build

After making changes to a macOS or iOS app, have Claude compile and verify in one pass:

```python
Build the MenuBarStats target, launch it, open the preferences window,
and verify the interval slider updates the label. Screenshot the
preferences window when you're done.
```

Claude runs `xcodebuild`, launches the app, interacts with the UI, and reports what it finds.


[​](#reproduce-a-layout-bug)

Reproduce a layout bug

When a visual bug only appears at certain window sizes, let Claude find it:

```python
The settings modal clips its footer on narrow windows. Resize the app
window down until you can reproduce it, screenshot the clipped state,
then check the CSS for the modal container.
```

Claude resizes the window, captures the broken state, and reads the relevant stylesheets.


[​](#test-a-simulator-flow)

Test a simulator flow

Drive the iOS Simulator without writing XCTest:

```python
Open the iOS Simulator, launch the app, tap through the onboarding
screens, and tell me if any screen takes more than a second to load.
```

Claude controls the simulator the same way you would with a mouse. This flow applies to the CLI; in the Desktop app, the same request opens the [iOS Simulator pane](../16-Mobile-Desktop/desktop-ios-simulator.md) instead of screen control.


[​](#differences-from-the-desktop-app)

Differences from the Desktop app

The CLI and Desktop surfaces share the same computer use engine, with a few differences:

| Feature              | Desktop                                           | CLI                             |
|:---------------------|:--------------------------------------------------|:--------------------------------|
| Platforms            | macOS and Windows                                 | macOS only                      |
| Enable               | Toggle in **Settings \> This computer \> System** | Enable `computer-use` in `/mcp` |
| Denied apps list     | Configurable in Settings                          | Not yet available               |
| Auto-unhide toggle   | Optional                                          | Always on                       |
| Dispatch integration | Dispatch-spawned sessions can use computer use    | Not applicable                  |


[​](#troubleshooting)

Troubleshooting


[​](#”computer-use-is-in-use-by-another-claude-session”)

”Computer use is in use by another Claude session”

Another Claude Code session holds the lock, which it keeps until it exits. Exit that session. If the other session crashed, the lock is released automatically when Claude detects the process is no longer running.


[​](#macos-permissions-prompt-keeps-reappearing)

macOS permissions prompt keeps reappearing

macOS sometimes requires a restart of the requesting process after you grant Screen Recording. Quit Claude Code completely and start a new session. If the prompt persists, open **System Settings \> Privacy & Security \> Screen Recording** and confirm your terminal app is listed and enabled.


[​](#computer-use-doesn’t-appear-in-/mcp)

`computer-use` doesn’t appear in `/mcp`

The server only appears on eligible setups. Check that:

- You’re on macOS. Computer use in the CLI is not available on Linux or Windows. On Windows, use [computer use in Desktop](../16-Mobile-Desktop/desktop.md#let-claude-use-your-computer) instead.
- You’re on a Pro or Max plan. Run `/status` to confirm your subscription.
- You’re authenticated through claude.ai. Computer use is not available with third-party providers like Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry. If you access Claude exclusively through a third-party provider, you need a separate claude.ai account to use this feature.
- You’re in an interactive session. Computer use is not available in non-interactive mode with the `-p` flag.


[​](#see-also)

See also

- [Computer use in Desktop](../16-Mobile-Desktop/desktop.md#let-claude-use-your-computer): the same capability with a graphical settings page
- [Claude in Chrome](../03-IDE-Integrations/chrome.md): browser automation for web-based tasks
- [MCP](../06-MCP-Tools/General/mcp.md): connect Claude to structured tools and APIs
- [Sandboxing](sandboxing.md): how Claude’s Bash tool isolates filesystem and network access
- [Computer use safety guide](https://support.claude.com/en/articles/14128542): best practices for safe computer use

---

## Explore the context window - Claude Code Docs

Source: https://code.claude.com/docs/en/context-window
Path: 02-Claude-Code-CLI/context-window.md

# Explore the context window

Copy pageCopy page

An interactive simulation of how Claude Code’s context window fills during a session. See what loads automatically, what each file read costs, and when rules and hooks fire.

Copy pageCopy page

Claude Code’s context window holds everything Claude knows about your session: your instructions, the files it reads, its own responses, and content that never appears in your terminal. The timeline below plays a full session from startup to compaction: what loads before you type, what each file read, rule, and hook adds as Claude works, and how a subagent keeps large reads out of your context. See [the written breakdown](#what-the-timeline-shows) for the same content as a list.


[​](#what-the-timeline-shows)

What the timeline shows

The session walks through a realistic flow with representative token counts:

- **Before you type anything**: CLAUDE.md, auto memory, MCP tool names, and skill descriptions all load into context. [AGENTS.md files](memory.md#agents-md) can load in place of CLAUDE.md. Your own setup may add more here, like an [output style](output-styles.md) or text from [`--append-system-prompt`](cli-reference.md).
- **As Claude works**: each file read adds to context, [path-scoped rules](memory.md#path-specific-rules) load automatically alongside matching files, and a [PostToolUse hook](../07-Hooks/hooks-guide.md) fires after each edit.
- **The follow-up prompt**: a [subagent](../09-Agents-Patterns/sub-agents.md) handles the research in its own separate context window, so the large file reads stay out of yours. Only the summary and a small metadata trailer come back.
- **At the end of the walkthrough**: you run `/compact`, which replaces the conversation with a structured summary. Most startup content reloads automatically; the table below shows what happens to each mechanism.


[​](#what-survives-compaction)

What survives compaction

When a long session compacts, Claude Code summarizes the conversation history to fit the context window. As of v2.1.198, the summarization request inherits your session’s [extended thinking](model-config.md#extended-thinking) configuration, so it reasons with thinking enabled when your session has it enabled and stays off otherwise. Thinking affects only how the summary is produced; your session settings are unchanged afterward. What happens to each kind of content depends on how it was loaded:

| Mechanism                                                                                                                                                           | After compaction                                                                                            |
|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------|
| System prompt and output style                                                                                                                                      | Both still apply                                                                                            |
| Project-root CLAUDE.md and unscoped rules                                                                                                                           | Re-injected from disk                                                                                       |
| Auto memory                                                                                                                                                         | Re-injected from disk                                                                                       |
| Skill descriptions                                                                                                                                                  | Rebuilt from your current [skills](../08-Plugins-Skills/skills.md) and re-injected. Requires Claude Code v2.1.304 or later |
| [Git status snapshot](settings-reference.md#includegitinstructions)                                                                                           | If the session started with one, Claude Code reads a fresh one from your repository                         |
| The plan Claude wrote in [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode)                                                              | Re-injected from disk                                                                                       |
| Rules with `paths:` frontmatter                                                                                                                                     | Claude Code reloads them [on demand](memory.md#path-specific-rules)                                   |
| Nested CLAUDE.md in subdirectories                                                                                                                                  | Claude Code reloads them [on demand](memory.md#how-claude-md-files-load)                              |
| Files Claude read or edited                                                                                                                                         | Claude Code re-reads up to five, most recently modified first                                               |
| Invoked skill bodies                                                                                                                                                | Re-injected, capped at 5,000 tokens per skill and 25,000 tokens total; oldest dropped first                 |
| [Background commands](interactive-mode.md#background-bash-commands) and background [subagents](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) | Keep running. Claude Code reminds Claude which ones are still running so it doesn’t start a duplicate       |
| Context that hooks added earlier                                                                                                                                    | Summarized with the rest of the conversation                                                                |
| [SessionStart hooks](../07-Hooks/hooks-guide.md#re-inject-context-after-compaction) that match the `compact` source                                                       | Claude Code runs them and adds their output to the compacted context                                        |

Right after compaction, Claude Code re-reads up to five of the files Claude has read or edited in the session, choosing the ones modified most recently. A file over 5,000 tokens comes back as a path reference without its content, shown as `Referenced file` instead of `Read`. Path-scoped rules and nested CLAUDE.md files load into message history when Claude reads, writes, or edits their trigger file, so compaction summarizes them away with everything else. If a rule must persist across compaction, drop the `paths:` frontmatter or move it to the project-root CLAUDE.md. Skill bodies are re-injected after compaction, but large skills are truncated to fit the per-skill cap, and the oldest invoked skills are dropped once the total budget is exceeded. Truncation keeps the start of the file, so put the most important instructions near the top of `SKILL.md`.


[​](#when-your-context-fills-up)

When your context fills up

Claude Code compacts automatically as you approach the limit, so a full context window doesn’t end your session. The automatic pass works the same way as the `/compact` step in the timeline. See [When context fills up](how-claude-code-works.md#when-context-fills-up) for what it preserves. For when Claude Code also compacts a conversation you leave idle, see [idle compaction](settings-reference.md#idlecompaction). You can also act before the automatic pass runs:

- **Compact with a focus**: run `/compact` with instructions, like `/compact focus on the auth bug fix`, before starting a long new task. The summary keeps what you choose instead of what the automatic pass guesses is important.
- **Compact part of the conversation**: run `/rewind`, select a message, and choose **Summarize from here** or **Summarize up to here**. See [Rewind and summarize](checkpointing.md#rewind-and-summarize) for what each option keeps and how to guide the summary.
- **Compact earlier**: run [`/autocompact`](commands.md#all-commands) with a token count, like `/autocompact 500k`, to set how full the context window gets before the automatic pass runs. See [Set the auto-compact window](model-config.md#set-the-auto-compact-window) for accepted values and overrides.
- **Clear between tasks**: run `/clear` when switching to unrelated work. Old conversation crowds out the files you need next and costs tokens on every message.
- **Delegate large reads**: send research to a [subagent](../09-Agents-Patterns/sub-agents.md) so the file contents stay in its context window, not yours.

If you need a larger window rather than a smaller conversation, Fable models, Sonnet 5 and later, Haiku 5.5, Opus 4.6 and later, and Sonnet 4.6 support a 1 million token context window. See [Extended context](model-config.md#extended-context) for availability by plan and how to select a `[1m]` model variant. Compaction works the same way at the larger limit. The point where automatic compaction runs depends on your model and configuration. See [Default auto-compact thresholds](model-config.md#default-auto-compact-thresholds) for the boundaries per model, and [Correct the window for a gateway or custom model ID](model-config.md#correct-the-window-for-a-gateway-or-custom-model-id) if Claude Code assumes the wrong window for your model ID, such as an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) alias.


[​](#check-your-own-session)

Check your own session

The visualization uses representative numbers. To see your actual context usage at any point, run `/context` for a live breakdown by category with optimization suggestions, including which CLAUDE.md and auto memory files loaded. Run `/memory` to open and edit those files.


[​](#related-resources)

Related resources

For deeper coverage of the features shown in the timeline, see these pages:

- [Extend Claude Code](features-overview.md): when to use CLAUDE.md vs skills vs rules vs hooks vs MCP
- [Store instructions and memories](memory.md): CLAUDE.md hierarchy and auto memory
- [Subagents](../09-Agents-Patterns/sub-agents.md): delegate research to a separate context window
- [Best practices](best-practices.md): managing context as your primary constraint
- [Prompt caching](prompt-caching.md): which actions invalidate the cached prefix
- [Reduce token usage](../17-Billing-Plans/costs.md#reduce-token-usage): strategies for keeping context usage low

---

## Message your other Claude Code sessions - Claude Code Docs

Source: https://code.claude.com/docs/en/cross-session-messaging
Path: 02-Claude-Code-CLI/cross-session-messaging.md

## On this page

- [When to use cross-session messaging](#when-to-use-cross-session-messaging)
- [Message another session](#message-another-session)
  - [Message delivery](#message-delivery)
  - [Get a notice when another session goes idle](#get-a-notice-when-another-session-goes-idle)
  - [Ask for a notice](#ask-for-a-notice)
  - [What each session shows](#what-each-session-shows)
  - [Limits](#limits)
  - [See which sessions Claude can reach](#see-which-sessions-claude-can-reach)
  - [Message sessions on other machines](#message-sessions-on-other-machines)
  - [Replies from other machines and cloud sessions](#replies-from-other-machines-and-cloud-sessions)
- [How a session treats an incoming message](#how-a-session-treats-an-incoming-message)
  - [What a message looks like](#what-a-message-looks-like)
  - [Control inbound messages](#control-inbound-messages)
  - [Non-interactive sessions](#non-interactive-sessions)
  - [The session’s inbox socket](#the-sessions-inbox-socket)
- [Restrict cross-session messaging](#restrict-cross-session-messaging)
  - [Require approval for cross-machine messages](#require-approval-for-cross-machine-messages)
  - [Turn off cross-session messaging](#turn-off-cross-session-messaging)
- [Availability](#availability)
- [Limitations](#limitations)
- [Related resources](#related-resources)

Agents and parallel work

# Message your other Claude Code sessions

Copy pageCopy page

Let Claude list and message your other Claude Code sessions on this machine, and reach your sessions on other machines or in the cloud.

Copy pageCopy page

Cross-session messaging requires Claude Code v2.1.224 or later on macOS and Linux, including Linux inside WSL 2. On native Windows, it requires Claude Code v2.1.234 or later. When a session meets the requirements, messaging is on with nothing to enable. See [Availability](#availability) for provider requirements and how to confirm a session has it.

Cross-session messaging lets Claude deliver a message from one of your Claude Code sessions to another. When a change in one session breaks what another is building on, Claude can warn that session before you notice. When one session settles a question another is blocked on, Claude can send the answer across. A message is a piece of text one Claude writes to another, never the sender’s conversation history or files. To move a whole conversation or its context, [resume the session](sessions.md#resume-a-session) instead.


[​](#when-to-use-cross-session-messaging)

When to use cross-session messaging

Use messaging when one of your sessions has something another session needs mid-task. Claude can send a message on its own when it sees the need, for example after making a change that affects work another session is doing, or you can ask it to send one. The common cases:

- **Hand over a finding**: when one session discovers a breaking change or makes a decision, Claude summarizes it for the session working on the affected area, instead of you re-explaining it there.
- **Coordinate parallel worktrees**: when sessions work the same repository in separate [worktrees](worktrees.md), Claude can tell the other sessions what landed.
- **Get status from long-running work**: have a migration or test run report back to the session you’re watching, or ask it yourself from there. If that session is on this machine, Claude can also [ask it for one notice when it next goes idle or exits](#get-a-notice-when-another-session-goes-idle).
- **Message across machines**: reach one of your sessions on another machine or in the cloud.


[​](#message-another-session)

Message another session

When one of your sessions learns something another session needs, such as a finding, a status, or a decision, Claude passes it along instead of you copy-pasting between terminals. Claude discovers the target with `ListAgents` and sends with `SendMessage`, so you never call either tool yourself. Claude can decide to send a message without being asked, and you can also prompt for one. To prompt one yourself, tell Claude what you want the other session to know or do. This example is a prompt you type, not a message Claude sends:

```python
Ask the session running in my other terminal whether the migration finished
```

Claude writes the actual message itself, so your prompt can leave the content to Claude. This prompt asks for a summary without dictating its wording, and what Claude sends varies:

```python
Explain what we just did to the session working on the payments API
```

To name the target yourself, mention the session in your prompt: type `@` followed by the first letters of the session’s name and pick the session from the typeahead, the same way you [@-mention a subagent](../09-Agents-Patterns/sub-agents.md#invoke-subagents-explicitly). Requires Claude Code v2.1.232 or later. Claude Code inserts the mention, such as `@api-worker`, and tells Claude which session it names, so Claude can message that session without listing your sessions first. This prompt names the target with a mention:

```python
Let @api-worker know the schema migration finished
```

The typeahead lists your other live sessions on this machine. Two cases need more than the first letters of a name:

- **A session beyond this machine**: a cloud or Remote Control session appears in the typeahead only after Claude has listed or messaged your sessions beyond this machine, so ask Claude to list them first.
- **A name with a space or other characters outside letters, digits, hyphens, and underscores**: type it in double quotes, such as `@"release notes"`. When you pick the session from the typeahead, Claude Code inserts the quotes for you.

You can also type the mention without the picker. When more than one live session answers to the mentioned name, Claude asks you which one you mean before sending. For what the message Claude writes looks like when it arrives, including an example of one, see [what a message looks like](#what-a-message-looks-like).


[​](#message-delivery)

Message delivery

The receiving Claude reads the message between tool calls during an active turn, so a running tool is never interrupted. When the receiving session is idle, Claude Code starts a new turn with the message. A message from another session arrives as plain text. If it mentions a file or an [MCP resource](../06-MCP-Tools/General/mcp.md#use-mcp-resources) with `@`, Claude sees the mention as written and Claude Code attaches nothing, whether the message starts a new turn or arrives during one. Claude can still open a mentioned path on the receiving machine with its own tools, subject to that session’s permissions. Claude Code refuses a message in the following cases:

- The message is [over the size cap](#limitations). Claude Code refuses it in the sending session, before it leaves.
- A rapid burst to a session on this machine has reached [what that session’s inbox accepts](#limitations). Claude Code refuses further messages to that session.
- A session beyond this machine is [listed as unable to receive cross-session messages](#message-sessions-on-other-machines). Claude Code refuses the message in the sending session, before it leaves this machine.
- The reply target on this machine fails a safety check, such as a symlinked target. [Refusing to send a cross-session message](errors.md#refusing-to-send-a-cross-session-message) lists these checks.

The receiving session checks each arriving message against its own [inbound controls](#control-inbound-messages), and the check ends in one of three outcomes:

- **Delivered**: Claude Code passes the message to the receiving Claude.
- **Held**: Claude Code sets the message aside undelivered. A held message reaches Claude only when you approve it or a later mode or settings change allows it.
- **Refused**: Claude Code drops the message without delivering it.

Once delivered, the message counts toward [usage](../17-Billing-Plans/costs.md) like a prompt you type. The receiving Claude can reply to the sender with `SendMessage`, except in the cases under [Replies from other machines and cloud sessions](#replies-from-other-machines-and-cloud-sessions) and [Turn off cross-session messaging](#turn-off-cross-session-messaging). Permission boundaries stay per-session. Claude is instructed never to ask another session for an action that was denied or blocked in its own session, or that its own permission settings would block, and to route that work back to you instead. On the receiving side, the [receiving session’s own permission prompts and rules still apply](#how-a-session-treats-an-incoming-message) to anything the message asks for.


[​](#get-a-notice-when-another-session-goes-idle)

Get a notice when another session goes idle

Claude can ask one of your sessions on this machine to send back one notice when that session next goes idle or exits. Idle here means the session finished a turn with nothing queued. Use it when you’re waiting on a long task in another session and want to hear when it’s done instead of checking. Requires Claude Code v2.1.236 or later in both sessions.


[​](#ask-for-a-notice)

Ask for a notice

Tell Claude what you’re waiting on. This prompt asks for a notice from the migration session:

```python
Tell me when the migration session finishes what it's working on
```

Claude subscribes with the `SendMessage` tool’s `notify_when_idle` input, either attached to a message it’s sending anyway or on its own. On its own, Claude Code subscribes without starting a turn or spending tokens in the watched session, and sends the notice right away if that session is already idle. Attached to a message, Claude Code delivers the message first and sends the notice later.


[​](#what-each-session-shows)

What each session shows

The watched session shows a line saying another process asked to be told when the session is next idle. The asking session shows the notice as a line naming the watched session. The line can include the time that session’s turn finished and a one-line status from that turn. If the asking session is idle, Claude Code starts a new turn with the notice.


[​](#limits)

Limits

If no notice arrives within 12 hours, Claude Code drops the subscription and tells Claude, so it doesn’t keep waiting. Each side’s [inbound controls](#control-inbound-messages) apply to a notice like a message:

- **`refuse` on either side**: nothing arrives. The watched session drops the request without recording or answering it, so the subscription expires unanswered after 12 hours, and an asking session with `refuse` never subscribes.
- **`hold` on either side**: the notice arrives with less. The watched session leaves the one-line status out, and the asking session shows the notice in your transcript without delivering it to Claude.

Only the Claude in your main conversation can subscribe, and only to your sessions on this machine. When Claude asks for a notice from any other target, such as a teammate, a subagent, or a session beyond this machine, Claude Code refuses the whole call, including any message attached to it.


[​](#see-which-sessions-claude-can-reach)

See which sessions Claude can reach

Claude finds a message’s target on its own, so you don’t need to run anything before asking it to send. To see for yourself which sessions Claude can reach, run the `/list-agents` command. The first line, when present, is this session’s own name, the one your other sessions use to message it. The rows below it are the sessions Claude can reach:

- **Subagents**: agents running inside the current session.
- **Teammates**: this session’s own [agent team](../09-Agents-Patterns/agent-teams.md) teammates.
- **Your other local sessions**: Claude Code sessions running on the same machine, including [background sessions](../09-Agents-Patterns/agent-view.md). A session appears only when it binds an [inbox socket](#the-sessions-inbox-socket).
- **Your [cloud sessions](claude-code-on-the-web.md)**: shown while this session is connected to [Remote Control](remote-control.md).
- **Your Remote Control sessions on other machines**: shown while this session is connected to [Remote Control](remote-control.md), and labeled `Remote Control`. Claude Code shows `offline` as the status of a session whose Remote Control connection has dropped.

While this session is connected to [Remote Control](remote-control.md), Claude Code withholds some details of your local sessions from the `/list-agents` output, without changing what Claude itself sees when it looks for a session to message:

- **Working directories**: it leaves out each local session’s working directory.
- **Session names**: it leaves out any session name it can’t attribute to a person, so a row left with no name reads `(unnamed session)`.
- **The first line**: it leaves out the line with this session’s own name unless you typed that name at this terminal, with `--name` or with `/rename` and the name, since you launched or last resumed the session.

When the output lists anything, it ends with a note saying details were withheld. Running `/rename` followed by an unused name at a session’s own keyboard gives that session a name that appears in the output. A session answers to the name you set with the [`/rename`](commands.md) command or the [`--name`](cli-reference.md#cli-flags) flag. When you don’t set one, Claude Code names the session itself. For an interactive session, that is the name shown in [listings of running sessions](sessions.md#name-your-sessions). Unless this session is connected to Remote Control, Claude Code shows each local session’s working directory in the `/list-agents` output, so you can tell same-named sessions apart when they run in different directories. Claude addresses the message in one of two ways, depending on how many live sessions answer to the name:

- **One session answers to the name**: Claude Code delivers the message on the name alone.
- **Several sessions share the name, or Claude Code couldn’t check everywhere your sessions run**: Claude adds a short identifier to each row of its listing and uses the identifier in the address.


[​](#message-sessions-on-other-machines)

Message sessions on other machines

How a message travels, and whether it passes through Anthropic servers, depends on where the target session runs:

| Where the other session runs                    | How the message travels                                                                                                      |
|:------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------|
| On this machine                                 | Over a per-session socket on macOS and Linux, or a per-session named pipe on native Windows, never through Anthropic servers |
| On another of your machines                     | Through Anthropic servers, arriving over that machine’s [Remote Control](remote-control.md) connection                 |
| In the [cloud](claude-code-on-the-web.md) | Through Anthropic servers, straight to the cloud session                                                                     |

Starting a conversation with a session on another of your machines requires Claude Code v2.1.225 or later and a target that [appears in the listing](#see-which-sessions-claude-can-reach). A session’s row in [the listing](#see-which-sessions-claude-can-reach) can show a condition that changes what happens when Claude messages that session:

- **`offline`**: that session’s Remote Control connection has dropped. The message goes through, but arrives only after that session’s machine reconnects.
- **`can't receive cross-session messages (off in that session)`**: messaging [isn’t available](#availability) in that session, or its [`crossSessionInbound`](settings-reference.md#crosssessioninbound) value is `refuse`. Claude Code refuses a message to that session before the message leaves this machine. The result under Claude’s `SendMessage` call begins `Not sent` and names the reason. Once the cause is fixed in that session, a later listing no longer shows this condition, and Claude can message that session.

A session inside a container and a session on the host can’t reach each other. Two sessions inside the same container can still message each other, including on a [self-hosted runner](../13-Enterprise-Admin/self-hosted-environments.md). A session inside WSL 2 and a native Windows session on the same computer can’t reach each other either. To require your approval before any message goes beyond this machine, set [`isolatePeerMachines`](#require-approval-for-cross-machine-messages).


[​](#replies-from-other-machines-and-cloud-sessions)

Replies from other machines and cloud sessions

A [cloud session](claude-code-on-the-web.md), including one on a [self-hosted runner](../13-Enterprise-Admin/self-hosted-environments.md), can’t use `SendMessage` to answer a message from another machine, even when the message carries a [reply address](#what-a-message-looks-like). The message still arrives. Read the cloud session’s response in its transcript at [claude.ai/code](https://claude.ai/code). If this session isn’t connected to Remote Control when Claude sends to a session beyond this machine, the message still goes through, but without a [reply address](#what-a-message-looks-like). The receiving Claude can’t answer it.


[​](#how-a-session-treats-an-incoming-message)

How a session treats an incoming message

When session A messages session B, Claude Code tells B’s Claude that the message came from another session, not from you, and limits what the message can do:

- **It can’t approve anything**: a message from another session never counts as your consent, so it can’t answer a pending permission prompt on your behalf.
- **It can’t change configuration**: Claude Code instructs the receiving Claude never to change permission settings, `CLAUDE.md`, or other configuration because another session asked.
- **Commands don’t run**: a command in the message’s text, such as `/compact`, arrives as plain text. Claude Code never executes it.
- **Permission prompts still fire**: if acting on the message requires a permission the receiving session doesn’t have, you see the same prompt you’d see for any other work.


[​](#what-a-message-looks-like)

What a message looks like

When a message arrives, Claude Code shows it in the conversation as a dim one-line preview, and the preview line stays in the conversation afterward. The preview carries the sender’s name and the first line of the message, cut with `…` when it’s long, such as `› Message from @api-worker: Schema migration finished (ctrl+o to expand)`. Any of these shows you the full text:

- Press `Ctrl+O` to open the [transcript viewer](interactive-mode.md#transcript-viewer) and read the full text under the sender’s session name.
- In [fullscreen rendering](fullscreen.md#use-the-mouse), click a preview line that leaves part of the message out to expand it in place.
- In a session started with [`--verbose`](cli-reference.md#cli-flags), Claude Code shows the full text instead of the preview.

The preview shortens only what you see. Whether or not you expand it, Claude reads the full message. Claude receives the message with the sender’s name and a reply address, except for a [one-way cross-machine message](#message-sessions-on-other-machines), which carries no reply address. This example is a message one Claude wrote to another, as its full text reads when you expand it:

```python
Schema migration finished
The new column is tenant_id, and rebasing on main is safe now.
```


[​](#control-inbound-messages)

Control inbound messages

Set [`crossSessionInbound`](settings-reference.md#crosssessioninbound) to choose what a session does with messages arriving from your other sessions:

| Value    | Behavior                                                                                                                                                                                                              |
|:---------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `accept` | Claude Code delivers each message to Claude                                                                                                                                                                           |
| `hold`   | Claude Code shows a notice for each message and doesn’t deliver it. If an `accept` later applies, per the [precedence rules](settings-reference.md#crosssessioninbound), Claude Code releases the held messages |
| `refuse` | Claude Code drops each message without delivering it                                                                                                                                                                  |

Beyond editing a settings file, you can select the value in the `/config` row **Messages from your other sessions**. Claude Code writes the value you select to your user settings. The row requires Claude Code v2.1.232 or later and doesn’t appear while managed settings or the `--settings` flag sets the key, since a user-settings value wouldn’t apply then. Claude Code rejects the `/config crossSessionInbound=value` shorthand for this key. To see which value applies, follow the `crossSessionInbound` precedence rules in the [settings reference](settings-reference.md#crosssessioninbound). When no value applies, Claude Code decides per message from the two sessions’ permission modes. It groups sessions that [bypass permission prompts](permission-modes.md#skip-all-checks-with-bypasspermissions-mode) into one class, and every other session into the other. Plan mode counts as bypassing in interactive terminal sessions with bypass permissions available, and [auto](permission-modes.md#eliminate-prompts-with-auto-mode), `acceptEdits`, and `dontAsk` count as prompting:

- **The receiving session prompts for permissions**: Claude Code delivers each message. It holds one for your approval only when the sending session identifies itself as bypassing permission prompts.
- **The receiving session bypasses permission prompts**: Claude Code holds each message for your approval. It delivers one only when the sending session identifies itself as also bypassing.

When the default holds a message in an interactive terminal session, Claude Code opens an approval dialog there. The dialog shows the sender and a preview:

- **Approve** delivers that one message to Claude.
- **Deny**, or dismissing the dialog, drops it.
- When the dialog stays unanswered past the [`dialogExpiry`](settings-reference.md#dialogexpiry) deadline, Claude Code closes it and drops the message. The deadline defaults to five minutes.
- While no terminal is attached to a [background session](../09-Agents-Patterns/agent-view.md), Claude Code leaves the dialog open past the deadline. After you attach, if the dialog stays unanswered for a full deadline period, Claude Code closes it and drops the message.
- If this session’s permission-mode class changes while messages are held, Claude Code re-applies the inbound rules, delivers the messages they now accept, and shows a notice.

A session in the VS Code extension or the Desktop app can’t show the dialog. Claude Code keeps a held message there until the same deadline, as [Non-interactive sessions](#non-interactive-sessions) describes. Claude Code holds at most 100 messages, and past that drops the oldest.


[​](#non-interactive-sessions)

Non-interactive sessions

Claude Code binds an inbox socket for a [`claude -p`](headless.md) session like an interactive one, so a long-running `-p` worker can receive messages and appears in the listing. When you start a session in [bare mode](headless.md#start-faster-with-bare-mode), Claude Code doesn’t bind the socket, so that session can’t receive messages and doesn’t appear in the agent list. A `-p` session can’t show the approval dialog. When the [inbound default](#control-inbound-messages) holds a message there, Claude Code keeps it for the same [`dialogExpiry`](settings-reference.md#dialogexpiry) deadline the dialog uses, five minutes by default:

- **Before the deadline**: if a mode or settings change allows the message, Claude Code delivers it.
- **Past the deadline**: Claude Code drops the message and reports it as expired to a sender it can reach.

Set `dialogExpiry` to `"never"` to keep default-held messages until the session ends. A message held by an explicit `hold` setting doesn’t expire; Claude Code delivers it when an `accept` later applies. To let a `-p` worker take messages unattended, start it with `crossSessionInbound` set to `accept` in its `--settings` value. An `accept` in your user settings also works but applies to every session you run.


[​](#the-sessions-inbox-socket)

The session’s inbox socket

Read this section when a session you expect isn’t in the agent list, when you want a script or hook to post into a session, or when a sandboxed command can’t reach the socket. Claude Code binds an inbox socket for each session with cross-session messaging enabled, where other sessions on the machine deliver messages. The socket is a Unix domain socket on macOS and Linux, including Linux inside WSL 2, and a named pipe on native Windows. For which session kinds bind one, see [Non-interactive sessions](#non-interactive-sessions). You can find the socket’s path in two places:

- `/status` shows it in the `Peer address` row. The path is prefixed with `uds:`.
- Claude Code exports it to [hooks](../07-Hooks/hooks.md) and Bash commands as the [`CLAUDE_CODE_MESSAGING_SOCKET`](env-vars.md#variables) environment variable:
  - In a session that starts with messaging on, Claude Code exports the variable before any hook runs, including `SessionStart`.

On macOS and Linux, Claude Code restricts the socket to your operating-system user. On native Windows, it instead requires each connection to authenticate first with a key that only your operating-system user can read. Either way, on a shared machine another user’s sessions can’t deliver to it. On macOS and Linux, Claude Code also refuses to create the socket in a directory it can’t accept, for example one that another user owns, and uses a private per-user directory, `/tmp/cc-socks-<uid>`, instead. When it can’t accept any directory, the session runs without an inbox: Claude Code shows a notice, `/status` shows `unavailable` and the reason in its `Peer address` row, and the [`--debug`](cli-reference.md#cli-flags) log records the full refusal. Alongside the socket’s path, Claude Code exports a per-session token as [`CLAUDE_CODE_MESSAGING_TOKEN`](env-vars.md#variables). A script posting to its own session’s socket can send `{"type":"auth","token":"<token>"}` as the first line of its connection, where `<token>` is the value of `CLAUDE_CODE_MESSAGING_TOKEN`. Whether Claude Code requires the line depends on the platform:

- **macOS and Linux, including WSL 2**: the line is optional. Claude Code accepts a connection with or without it.
- **Native Windows**: the line is required. Claude Code closes any connection whose first line isn’t a valid auth line and delivers nothing from that connection.

Open the connection only when the message you’re posting is ready. Claude Code closes a connection that hasn’t sent a complete line within 30 seconds, so capture a slow command’s output first and then open the connection to send it. Claude Code runs messages arriving on the socket through the same [inbound controls](#control-inbound-messages) as any other peer message, with one exception and one prerequisite:

- **Own-child messages**: when no `crossSessionInbound` value applies, Claude Code delivers a message it verifies came from the session’s own child processes, such as a hook or Bash command posting back to its own session’s socket.
  - On Linux, including inside WSL 2, Claude Code can verify by process evidence even for a child that has already exited. On macOS it can verify that way only while the posting process is still running, and in a container where Claude Code runs as process ID 1 it has no process evidence at all. On native Windows it also has none.
  - On macOS after the posting process has exited and in containers where Claude Code runs as process ID 1, that process evidence is missing, and Claude Code instead verifies a child that sent the session’s exported [`CLAUDE_CODE_MESSAGING_TOKEN`](env-vars.md#variables) in the auth line that opened its connection. On native Windows, that token is the only way Claude Code verifies an own-child message.
  - When Claude Code can verify neither way, it treats the message like any other that asserts no permission class, so a session that bypasses permission prompts holds it for your approval.
- **Sandboxed sessions**: control whether a Bash command can reach the socket from inside the [sandbox](sandboxing.md) with the sandbox’s Unix-socket settings, [`sandbox.network.allowAllUnixSockets` and `sandbox.network.allowUnixSockets`](settings-reference.md#sandbox-settings).


[​](#restrict-cross-session-messaging)

Restrict cross-session messaging

Beyond the per-message defaults, you can narrow messaging in two ways. Require your approval before any message leaves the machine, or turn messaging off for a session or an organization.


[​](#require-approval-for-cross-machine-messages)

Require approval for cross-machine messages

Set [`isolatePeerMachines`](settings-reference.md#isolatepeermachines) to `true` to require your explicit approval before any `SendMessage` reaches a session beyond this machine:

```python
{
  "isolatePeerMachines": true
}
```

With this set, Claude Code asks for your approval before Claude’s message to a session beyond this machine leaves, even in `bypassPermissions` mode, which skips ordinary permission prompts. A `true` from any settings scope applies, so a checked-in project file can turn the requirement on but not off. Claude Code doesn’t prompt for messages between sessions on the same machine.


[​](#turn-off-cross-session-messaging)

Turn off cross-session messaging

Receiving and sending are separate controls, so turn off whichever direction you need, or both. Use `crossSessionInbound` for messages that arrive, and permission rules for what Claude here can send or list:

- **Stop receiving**: set `crossSessionInbound` to `refuse`, and Claude Code drops inbound peer messages without delivering them. From project or local settings, `refuse` applies over every other source, and from your user settings it applies unless managed settings or the `--settings` flag set a value.
- **Stop sending and listing**: add [permission deny rules](permissions.md#tool-specific-permission-rules) naming `SendMessage` and `ListAgents`. Both take the bare tool name with no specifier.

Administrators can turn both sides off for an organization in [managed settings](../13-Enterprise-Admin/managed-settings.md), combining the deny rules with the `refuse`:

```python
{
  "permissions": {
    "deny": ["SendMessage", "ListAgents"]
  },
  "crossSessionInbound": "refuse"
}
```

With this in place, Claude Code still binds each session’s inbox socket, but drops every message that arrives on it without delivering anything to Claude. Denying `SendMessage` also removes messaging to subagents and agent-team teammates, since the same tool serves both. A refusing session shows no visible change, in its own `/status` or in the listings of other sessions on the same machine, so to confirm it, check the settings files that apply to that session rather than its status.


[​](#availability)

Availability

Cross-session messaging requires Claude Code v2.1.224 or later on macOS, Linux, and WSL 2, and v2.1.234 or later on native Windows. Availability, and which sessions Claude can message, also depend on your operating system, provider, and configuration:

- **Operating system**: available on macOS, Windows, and Linux, including Linux inside WSL 2.
- **Sessions on this machine**: available on every provider, including Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, and Microsoft Foundry, and in sessions that run with [feature-flag fetching](env-vars.md#features-that-need-feature-flag-fetching) off. On those providers, and with flag fetching off, same-machine messaging requires Claude Code v2.1.248 or later. Claude Code delivers these messages over a [per-session socket on your machine](#the-sessions-inbox-socket), never through Anthropic servers. To stop a session from receiving them, set [`crossSessionInbound`](#turn-off-cross-session-messaging) to `refuse`.
- **Sessions beyond this machine**: Claude finds your [cloud sessions](claude-code-on-the-web.md) and your sessions on other machines from a session that is connected to Remote Control, which needs a claude.ai sign-in as this session’s active authentication and the other [Remote Control requirements](remote-control.md#requirements). Claude can’t find those sessions with an API key or on Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, and Microsoft Foundry.

To check a session, type `/list-agents`, also available as `/peers`. The result separates a session that doesn’t have the feature from a session where something narrower blocked a message, such as a missing `SendMessage` tool or a refused send:

- **`/list-agents` isn’t recognized**: the session doesn’t have cross-session messaging. Work through the requirements above, starting with `claude --version` for the version requirement.
- **`/list-agents` works but a send didn’t arrive**: messaging is on, and something narrower applies:
  - **Deny rules**: a [permission deny rule](#turn-off-cross-session-messaging) removes the `SendMessage` and `ListAgents` tools.
  - **Inbound controls**: the [receiving session’s inbound controls](#control-inbound-messages) can hold or drop what you send it.
  - **Cloud session missing**: a cloud session appears only while this session is connected to [Remote Control](remote-control.md).
  - **Other-machine session missing**: a session on another of your machines appears only when it runs with [Remote Control](remote-control.md) and this session is connected as well.
  - **Other-machine session `offline`**: a message to a session listed as `offline` goes through, but [arrives only after that session’s machine reconnects](#message-sessions-on-other-machines).
  - **Cloud or other-machine session `can't receive cross-session messages`**: a message to a session listed with this condition [doesn’t leave this machine](#message-sessions-on-other-machines), and the result under `SendMessage` begins `Not sent`.
  - **Older cloud or other-machine session missing**: Claude Code reads those session lists newest first and stops after a bounded number of pages, so Claude can’t message a session that fell past them by name.

In a session with messaging, `/status` also shows a `Peer address` row with the session’s own inbox address, or `unavailable` and the reason when Claude Code [couldn’t set up an inbox](#the-sessions-inbox-socket).


[​](#limitations)

Limitations

The limits here are properties of the messaging channel itself and apply wherever the feature runs. For platform and provider gaps, see [Availability](#availability) instead.

- **Plain text only**: Claude sends only plain text across sessions. Structured [agent team](../09-Agents-Patterns/agent-teams.md) protocol messages stay within a team.
- **Same-machine message size is capped**: Claude Code refuses a message to a session on this machine once its serialized form passes about a million characters. The refusal [names the exact sizes](errors.md#message-too-large-for-cross-session-delivery). Nothing reaches the receiving session.
- **Rapid bursts to one session are refused at the sender**: once a rapid burst of messages to a session on this machine reaches what that session’s inbox accepts, Claude Code refuses further sends in the sending session. The [refusal names the burst](errors.md#too-many-messages-to-this-session-just-now) and tells Claude to batch the rest into one message or wait.
- **Message loops are throttled**: in the receiving session, Claude Code rate-limits repeated messages per sender, drops identical repeats arriving within a short window, and queues at most 50 accepted messages for Claude to read. A message loop between two sessions therefore stops on its own.


[​](#related-resources)

Related resources

- [Subagents](../09-Agents-Patterns/sub-agents.md#resume-subagents) and [agent teams](../09-Agents-Patterns/agent-teams.md#messages-between-agents): messaging within a single session or team
- [Background agents](../09-Agents-Patterns/agent-view.md): dispatch and monitor the parallel sessions you might message
- [Remote Control](remote-control.md): connect this session to reach your sessions on other machines
- [Channels](channels.md): push external events, such as CI results or chat messages, into a session
- [Settings](settings-reference.md#all-settings): `crossSessionInbound`, `isolatePeerMachines`, and `dialogExpiry`
- [Permission modes](permission-modes.md): the modes behind the inbound default’s two classes
- [Tools reference](tools-reference.md): the `ListAgents` and `SendMessage` rows in the tools table
- [Run agents in parallel](../09-Agents-Patterns/agents.md): compare the ways Claude Code runs multiple agents

---

## Debug your configuration - Claude Code Docs

Source: https://code.claude.com/docs/en/debug-your-config
Path: 02-Claude-Code-CLI/debug-your-config.md

## On this page

- [See what loaded into context](#see-what-loaded-into-context)
- [Check resolved settings](#check-resolved-settings)
- [Check MCP servers](#check-mcp-servers)
- [Check hooks](#check-hooks)
- [Test against a clean configuration](#test-against-a-clean-configuration)
- [Check common causes](#check-common-causes)
- [Related resources](#related-resources)

Troubleshooting

# Debug your configuration

Copy pageCopy page

Diagnose why CLAUDE.md, settings, hooks, MCP servers, or skills aren’t taking effect. Use /context, /doctor, /hooks, and /mcp to see what actually loaded.

Copy pageCopy page

When Claude ignores an instruction or a feature you configured doesn’t appear, the cause is usually that the file didn’t load, it loaded from a different location than you expected, or another file overrode it. This guide shows how to inspect what Claude Code actually loaded so you can narrow down which applies. For installation, authentication, and connectivity problems, see [Troubleshoot installation and login](troubleshoot-install.md) instead.


[​](#see-what-loaded-into-context)

See what loaded into context

The `/context` command shows everything occupying the context window for the current session, broken down by category: system prompt, system tools, MCP tools, custom subagents with the source each loaded from, memory files, skills, and conversation messages. Run it first to confirm whether your `CLAUDE.md`, rules, or skill descriptions are present at all. The skills section in `/context` also includes [bundled skills](../08-Plugins-Skills/skills.md#bundled-skills), which `/skills` doesn’t list. For detail on a specific category, follow up with the dedicated command:

| Command          | Shows                                                                                                                                                                                                                                             |
|:-----------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `/memory`        | Memory file locations across user and project scopes with the option to open each in your editor, plus access to the auto memory folder and the auto memory toggle                                                                                |
| `/skills`        | Available skills from project, user, and plugin sources                                                                                                                                                                                           |
| `/hooks`         | Active hook configurations                                                                                                                                                                                                                        |
| `/mcp`           | Connected MCP servers and their status                                                                                                                                                                                                            |
| `/permissions`   | Resolved allow and deny rules currently in effect                                                                                                                                                                                                 |
| `/doctor`        | Setup checkup: installation health, invalid settings files, unused extensions, duplicate [subagent](../09-Agents-Patterns/sub-agents.md) names in the same directory, and checked-in `CLAUDE.md` content Claude can derive from the codebase, with proposed fixes |
| `/debug [issue]` | Enables debug logging for the session and prompts Claude to diagnose using the log output and settings paths                                                                                                                                      |
| `/status`        | Active settings sources, including whether managed settings are in effect                                                                                                                                                                         |

If a memory file is missing from the `/context` breakdown, check its location against [how CLAUDE.md files load](memory.md#how-claude-md-files-load). Subdirectory `CLAUDE.md` files load on demand rather than at session start, so they don’t appear in that breakdown. If `/context` confirms the file loaded but Claude still isn’t following a particular instruction, the issue is likely how the instruction is written rather than whether it loaded. CLAUDE.md works well for the kinds of guidance you’d give a new teammate, such as project conventions, build commands, and where files belong. Adherence drops when an instruction is vague enough to interpret multiple ways, when two files give conflicting direction, or when the file has grown long enough that individual rules get less attention. [Write effective instructions](memory.md#write-effective-instructions) covers the specificity, size, and structure patterns that keep adherence high.

CLAUDE.md and permissions solve different problems. CLAUDE.md tells Claude how your project works so it makes good decisions. [Permissions](permissions.md) and [hooks](../07-Hooks/hooks.md) enforce limits regardless of what Claude decides. Use CLAUDE.md for “we do it this way here.” Use permissions or hooks for security boundaries and anything that must never happen, where you need a guarantee instead of guidance.


[​](#check-resolved-settings)

Check resolved settings

Settings merge across managed, user, project, and local scopes. Managed settings apply first when present. Among the rest, the closer scope overrides the broader one in the order local, then project, then user. Some settings can also be set by command-line flags or [environment variables](env-vars.md), which act as another override layer. When a setting doesn’t seem to apply, the value you set is usually being overridden by another scope or an environment variable. To find invalid settings files, run `claude doctor` from your terminal. It prints read-only installation and settings diagnostics without starting a session. For a full checkup that also proposes fixes and asks before applying them, run [`/doctor`](commands.md#all-commands) inside a session. Run `/status` to see which settings sources are active, including whether managed settings are in effect. To understand which scope Claude Code uses for a given key, see [Settings precedence](settings.md#settings-precedence).


[​](#check-mcp-servers)

Check MCP servers

Run `/mcp` to see every configured server, its connection status, and whether you have approved it for the current project. A server can be defined correctly but still not provide tools for a few common reasons:

- Project-scoped servers in `.mcp.json` require a one-time approval. If the prompt was dismissed, the server stays disabled until you approve it from `/mcp`.
- A server that fails to start shows as failed in `/mcp`. Relative file paths in `command` or `args` are a frequent cause, since they resolve against the directory you launched Claude Code from rather than the location of `.mcp.json`.
- A server that shows as connected but lists zero tools has started successfully but isn’t returning a tool list. Select **Reconnect** from `/mcp`. If the count stays at zero, run `claude --debug=mcp` and read the server’s stderr in the debug log at `~/.claude/debug/<session-id>.txt`.

For configuration locations and scope rules, see [MCP](../06-MCP-Tools/General/mcp.md).


[​](#check-hooks)

Check hooks

Run `/hooks` to list every hook registered for the current session, grouped by event. If a hook you defined doesn’t appear, Claude Code didn’t load it. Check for these causes:

- The hook is defined in a standalone file. Hooks go under the `"hooks"` key in a [settings file](settings.md#settings-files).
- The `matcher` value is an array instead of a single string. Claude Code lists the entry as an invalid setting when you start an interactive session and in `claude doctor`. If the array is under `PreToolUse` or `PermissionRequest`, none of that file’s other hooks load either.
- The hook is in a skill’s frontmatter, and neither you nor Claude has invoked the skill yet in this session. Invoke it or ask Claude to, then run `/hooks` again. If the hook still doesn’t appear, check for other causes, such as [frontmatter that didn’t parse](../08-Plugins-Skills/skills.md#skill-not-triggering) or one of the [limits on skill hooks](../07-Hooks/hooks.md#limits-on-skill-hooks).

If the hook appears but doesn’t fire, the matcher is the usual cause. Check it for these mistakes:

- The `matcher` field is a single string that uses `|` to match multiple tool names, for example `"Edit|Write"`. A `,` separator is equivalent, so `"Edit,Write"` matches the same tools. Before v2.1.191, a comma fell through to regex evaluation and the matcher never matched, so use `|` if you aren’t on v2.1.191 yet.
- A misspelled tool name produces a matcher that matches nothing, so the hook fails silently.

When you edit `settings.json`, the change takes effect in the running session after a brief file-stability delay, even if you create the file or the project’s `.claude/` folder itself after the session started. You don’t need to restart. Before v2.1.257, Claude Code didn’t detect edits in a `.claude/` folder created after the session started. If `/hooks` still shows the old definition a few seconds after you save, run `/hooks` again to refresh the view. If `/hooks` shows the hook but it still does not fire, the next step is to watch hook evaluation live. Start a session with `claude --debug` and trigger the tool call. The debug log records each event, which matchers were checked, and the hook’s exit code and output. See [Debug hooks](../07-Hooks/hooks.md#debug-hooks) for the log format and [hooks troubleshooting](../07-Hooks/hooks-guide.md#limitations-and-troubleshooting) for common failure patterns.


[​](#test-against-a-clean-configuration)

Test against a clean configuration

Start with [`claude --safe-mode`](cli-reference.md#cli-flags), which launches a session with your customizations disabled, including:

- `CLAUDE.md`
- Skills, plugins, and hooks
- MCP servers
- Custom commands and agents
- Custom output styles
- Custom keybindings

Authentication, model selection, built-in tools, and permissions work normally. If the problem disappears in safe mode, you’ve narrowed the cause to one of the items you turned off. To find it, use the check for that item, such as [See what loaded into context](#see-what-loaded-into-context), [Check MCP servers](#check-mcp-servers), or [Check hooks](#check-hooks). Safe mode still applies managed hooks and settings policy from your organization. Managed plugins, skills, `CLAUDE.md`, and MCP servers are turned off. If the problem persists in safe mode, or your settings themselves are suspect, start a session with none of your own configuration and check whether the problem follows.

1

Create an empty directory and change into it

In your shell, with no Claude Code session running, create the directory and move into it:

- Bash or Zsh

- PowerShell

```python
mkdir -p ~/claude-clean/empty && cd ~/claude-clean/empty
```

```python
New-Item -ItemType Directory -Force "$HOME/claude-clean/empty" | Out-Null
Set-Location "$HOME/claude-clean/empty"
```

2

Start Claude Code with a clean configuration directory

From the same shell, set [`CLAUDE_CONFIG_DIR`](env-vars.md) to a fresh directory in place of `~/.claude`, and pass [`--setting-sources user`](cli-reference.md#cli-flags) to turn off project configuration such as `.claude/settings.json`, `CLAUDE.md`, and `.mcp.json`:

- Bash or Zsh

- PowerShell

The variable applies to this one launch.

```python
CLAUDE_CONFIG_DIR=~/claude-clean/config claude --setting-sources user
```

The variable stays set for the rest of this PowerShell session, so later `claude` launches in the same window keep using the clean directory. To return to your usual directory, run `Remove-Item Env:CLAUDE_CONFIG_DIR` before the next launch.

```python
$env:CLAUDE_CONFIG_DIR = "$HOME/claude-clean/config"
claude --setting-sources user
```

On the first launch, you go through the first-run setup screens again, a sign that the clean configuration directory is in effect. Managed settings still apply, and [connectors](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) still load if you log in with a claude.ai account.

3

Reproduce the problem

Repeat what triggered the problem in the clean session:

- **Problem gone**: the cause is in your user or project configuration. Copy `~/.claude.json` and the files in `~/.claude` into `~/claude-clean/config` one at a time. If none brings the problem back, go to your project directory in the same shell and start Claude Code without `--setting-sources user`. In Bash or Zsh, run `CLAUDE_CONFIG_DIR=~/claude-clean/config claude`. In PowerShell, the variable is still set, so run `claude`.
- **Problem persists**: the cause is outside your user and project configuration. Run `/status` in the session to check for managed settings, check your shell for [environment variables](env-vars.md), then see [Troubleshooting](troubleshooting.md).


[​](#check-common-causes)

Check common causes

Most configuration surprises trace back to a small set of location and syntax rules. Check these before assuming a bug:

| Symptom                                                              | Cause                                                                                                                                                                                                                                             | Fix                                                                                                                                                                                                                                                                                                                                  |
|:---------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Hook never fires                                                     | `matcher` is a JSON array instead of a string                                                                                                                                                                                                     | Use a single string with `|` to match multiple tools, for example `"Edit|Write"`. See [matcher patterns](../07-Hooks/hooks.md#matcher-patterns).                                                                                                                                                                                           |
| Hook never fires                                                     | `matcher` uses `,` as a separator on a version before v2.1.191                                                                                                                                                                                    | Claude Code v2.1.191 or later treats `,` as a list separator like `|`. Earlier versions evaluate a comma as a literal character, so `"Edit,Write"` matches nothing. Use `|` instead, or upgrade Claude Code.                                                                                                                         |
| Hook never fires                                                     | `matcher` value is lowercase, for example `"bash"`                                                                                                                                                                                                | Matching is case-sensitive. Tool names are capitalized: `Bash`, `Edit`, `Write`, `Read`.                                                                                                                                                                                                                                             |
| Hook never fires                                                     | Hooks are defined in a standalone file instead of `settings.json`                                                                                                                                                                                 | There is no standalone hooks file for project or user config. Define hooks under the `"hooks"` key in `settings.json`. Only [plugins](../08-Plugins-Skills/plugins-components.md#hooks) load a separate `hooks/hooks.json`. See [hook configuration](../07-Hooks/hooks.md).                                                                               |
| Permissions or hooks set globally are ignored                        | Configuration was added to `~/.claude.json`                                                                                                                                                                                                       | `~/.claude.json` holds app state and UI toggles. `permissions`, `hooks`, and `env` belong in `~/.claude/settings.json`. These are two different files.                                                                                                                                                                               |
| A `settings.json` value seems ignored                                | The same key is set in `settings.local.json`                                                                                                                                                                                                      | `settings.local.json` overrides `settings.json`, and both override `~/.claude/settings.json`. See [settings precedence](settings.md#settings-precedence).                                                                                                                                                                      |
| Skill doesn’t appear in `/skills`                                    | Skill file is at `.claude/skills/name.md` instead of in a folder                                                                                                                                                                                  | Use a folder with `SKILL.md` inside: `.claude/skills/name/SKILL.md`.                                                                                                                                                                                                                                                                 |
| Skill appears in `/skills` but Claude never invokes it               | Skill has `disable-model-invocation: true` in its frontmatter, or its description doesn’t match how you phrase the request                                                                                                                        | Check the badge in `/skills`: a “user-only” label means Claude won’t trigger it on its own. See [skill invocation](../08-Plugins-Skills/skills.md).                                                                                                                                                                                                 |
| Subdirectory `CLAUDE.md` instructions seem ignored                   | Subdirectory files load on demand, not at session start                                                                                                                                                                                           | To load a subdirectory’s `CLAUDE.md`, ask Claude to read another file in that subdirectory. See [when subdirectory files load](memory.md#how-claude-md-files-load).                                                                                                                                                            |
| Subagent ignores `CLAUDE.md` instructions                            | The built-in Explore and Plan agents skip `CLAUDE.md` at startup. A custom subagent loads it the same way the main conversation does, unless it has [`omitClaudeMd`](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields) set in its definition      | For Explore or Plan, restate the instruction in your delegating prompt. For a subagent that sets `omitClaudeMd`, remove the field. For any other custom subagent, put critical instructions in the agent file body, which becomes the agent’s system prompt. See [what loads at startup](../09-Agents-Patterns/sub-agents.md#what-loads-at-startup). |
| Cleanup logic never runs at session end                              | No `SessionEnd` hook configured                                                                                                                                                                                                                   | Add a `SessionEnd` hook in `settings.json`. See the [hook events list](../07-Hooks/hooks.md#hook-events).                                                                                                                                                                                                                                  |
| MCP servers in `.mcp.json` never load                                | File is under `.claude/`, or its servers sit under a top-level `servers` key, as in VS Code’s `mcp.json`, instead of `mcpServers`                                                                                                                 | Project MCP config goes at the repository root as `.mcp.json`, not inside `.claude/`, with servers under the `mcpServers` key. See [MCP configuration](../06-MCP-Tools/General/mcp.md).                                                                                                                                                                |
| MCP servers added under `mcpServers` in `settings.json` never appear | `settings.json` does not read an `mcpServers` key                                                                                                                                                                                                 | Define project servers in `.mcp.json` at the repository root, or run `claude mcp add --scope user` for user-scoped servers. See [MCP configuration](../06-MCP-Tools/General/mcp.md).                                                                                                                                                                   |
| Project MCP server added but doesn’t appear                          | The one-time approval prompt was dismissed                                                                                                                                                                                                        | Project-scoped servers require approval. Run `/mcp` to see status and approve.                                                                                                                                                                                                                                                       |
| MCP server fails to start from some directories                      | `command` or `args` uses a relative file path                                                                                                                                                                                                     | Use absolute paths for local scripts. Executables on your `PATH` like `npx` or `uvx` work as-is.                                                                                                                                                                                                                                     |
| MCP server starts without expected environment variables             | The server’s config entry doesn’t set them, and they aren’t in the environment Claude Code passes to stdio servers: its own environment, minus the [variables it strips from subprocesses](../13-Enterprise-Admin/monitoring-usage.md#administrator-configuration) | Set per-server `env` inside the server’s `.mcp.json` entry, which doesn’t depend on the launch environment or workspace trust.                                                                                                                                                                                                       |
| `Bash(rm *)` deny rule doesn’t block `/bin/rm` or `find -delete`     | Bash rules match the literal command string, not the underlying executable; see [what a Bash rule doesn’t match](permissions.md#bash-rule-limits)                                                                                           | Use a [PreToolUse hook](../07-Hooks/hooks-guide.md) or the [sandbox](sandboxing.md) for a hard guarantee.                                                                                                                                                                                                                            |


[​](#related-resources)

Related resources

For full reference on each configuration surface, see the dedicated page:

- **[`.claude` directory reference](claude-directory.md)**: every config file location and what reads it
- **[Settings](settings.md)**: which file to use and which value Claude Code uses; the [settings reference](settings-reference.md) has the full key list
- **[Hooks reference](../07-Hooks/hooks.md)**: event names, payloads, and `--debug` output format
- **[MCP](../06-MCP-Tools/General/mcp.md)**: server configuration, approval, and `/mcp` output
- **[Troubleshoot installation and login](troubleshoot-install.md)**: `command not found`, PATH, and authentication problems
- **[Troubleshooting](troubleshooting.md)**: performance, hangs, and search issues

---

## Launch sessions from links - Claude Code Docs

Source: https://code.claude.com/docs/en/deep-links
Path: 02-Claude-Code-CLI/deep-links.md

## On this page

- [How deep links work](#how-deep-links-work)
  - [What a launched session shows](#what-a-launched-session-shows)
- [Build a link](#build-a-link)
  - [Choose between cwd and repo](#choose-between-cwd-and-repo)
- [Examples](#examples)
  - [Embed a link in a runbook](#embed-a-link-in-a-runbook)
  - [Open a link from the shell](#open-a-link-from-the-shell)
- [Registration and supported platforms](#registration-and-supported-platforms)
- [Open a VS Code tab instead of a terminal](#open-a-vs-code-tab-instead-of-a-terminal)
- [Open a Claude Desktop session on an SSH connection](#open-a-claude-desktop-session-on-an-ssh-connection)
- [Troubleshooting](#troubleshooting)
  - [Clicking the link does nothing](#clicking-the-link-does-nothing)
  - [xdg-open is not found on Linux](#xdg-open-is-not-found-on-linux)
  - [The link renders as plain text instead of being clickable](#the-link-renders-as-plain-text-instead-of-being-clickable)
  - [The session opens in my home directory instead of the repo](#the-session-opens-in-my-home-directory-instead-of-the-repo)
  - [The link opens the wrong terminal](#the-link-opens-the-wrong-terminal)
- [Learn more](#learn-more)

Automation

# Launch sessions from links

Copy pageCopy page

Open a Claude Code terminal session from a URL. Embed `claude-cli://` links in runbooks, alerts, and dashboards so a click opens Claude Code in the right repo with the right prompt.

Copy pageCopy page

A deep link is a `claude-cli://` URL that opens Claude Code in a new terminal window. The URL can carry a working directory and a prompt to pre-fill. This lets you share a one-click starting point for a task: anyone with Claude Code installed who clicks the link sees a session open with the prompt already typed. The prompt is populated but not sent until you press Enter. Because a deep link is a URL, you can put one anywhere a link can go:

- An incident runbook step that opens the affected service’s repo with a diagnostic prompt
- A monitoring alert or dashboard that links to an investigation prompt for a specific metric
- A README or wiki page that opens the project with an onboarding prompt
- A CI failure notification that pre-fills the failing job’s name

This page covers how to [build a link](#build-a-link), [embed one in a runbook or trigger it from the shell](#examples), and [manage or disable handler registration](#registration-and-supported-platforms) on each platform.


[​](#how-deep-links-work)

How deep links work

The `claude-cli://` prefix is a custom URL scheme that Claude Code registers with your operating system, similar to how `mailto:` links open your email client. When you click a deep link:

1.  The browser or app passes the URL to your operating system.
2.  The operating system recognizes the `claude-cli://` prefix and starts Claude Code on your machine.
3.  A new terminal window opens with Claude Code running in the directory the link specified, and the link’s prompt text already in the input box.
4.  You read the prompt, edit it if you want, and press Enter to send it.

The link itself can be hosted anywhere, but the session always opens locally on the computer where you clicked. See [Registration and supported platforms](#registration-and-supported-platforms) for which terminal emulator opens on each operating system. The platform that displays the link must allow custom URL schemes. For what GitHub does with them and the workaround, see [The link renders as plain text instead of being clickable](#the-link-renders-as-plain-text-instead-of-being-clickable).


[​](#what-a-launched-session-shows)

What a launched session shows

A deep link never executes anything on its own. The link only chooses a directory and fills the prompt box. If you click a link from a page you do not trust, the prompt is still inert: nothing reaches the model until you read what was filled in and press Enter. When the session opens, a warning line below the input box reads `Prompt from an external link` and stays visible until you send or clear the prompt. For prompts over 1,000 characters, the warning includes the character count and tells you to scroll and review the full text before pressing Enter, since long prompts can push instructions off screen. Permission rules, `CLAUDE.md`, and trust prompts for the selected directory apply the same way as for any other session.


[​](#build-a-link)

Build a link

A deep link starts with `claude-cli://open`, followed by optional query parameters. The minimal form opens Claude Code in your home directory with an empty prompt:

```python
claude-cli://open
```

To try a link without putting it on a page, paste it into your browser’s address bar or [open it from the shell](#open-a-link-from-the-shell). Add parameters to control where the session starts and what the prompt box contains:

| Parameter | Description                                                                                                                                                                                                                                 |
|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `q`       | Text to pre-fill in the prompt box. [URL-encode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) the value. Use `%0A` for line breaks in multi-line prompts. Maximum 5,000 characters. |
| `cwd`     | Absolute path to use as the working directory. Network and UNC paths are rejected, and so are paths that contain `..` segments or invisible or bidirectional control characters.                                                            |
| `repo`    | A GitHub `owner/name` slug. Claude Code resolves it to a local clone it has seen before and starts there. If you have no matching clone, the session opens in your home directory instead.                                                  |

`cwd` and `repo` are [two ways to set the working directory](#choose-between-cwd-and-repo). If you pass both, `cwd` takes precedence and `repo` is ignored, even if the `cwd` path does not exist. The following link points at a repository called `acme/payments` with a two-line diagnostic prompt. Replace `acme/payments` with your repository’s `owner/name` slug when you build your own:

```python
claude-cli://open?repo=acme/payments&q=Investigate%20the%20failed%20deploy%20of%20payments-api.%0ACheck%20recent%20commits%20to%20main%20and%20the%20last%20successful%20build.
```

Clicking it opens a new terminal window, starts Claude Code in your local clone of `acme/payments`, and fills the prompt box with the decoded text:

```python
Investigate the failed deploy of payments-api.
Check recent commits to main and the last successful build.
```

You can edit the prompt before pressing Enter to send it. See [Choose between `cwd` and `repo`](#choose-between-cwd-and-repo) for how the local path is selected when you have multiple clones or worktrees.


[​](#choose-between-cwd-and-repo)

Choose between `cwd` and `repo`

Use `cwd` when everyone who clicks the link has the project at the same absolute path, such as a standardized devcontainer or VM image. Use `repo` when the link is shared and each person clones to a different location. Claude Code resolves the slug to a local path as follows:

- `repo` opens the linked repository’s clone or worktree where you most recently ran `claude`. Each time you run `claude` in a Git repository, Claude Code records that directory’s path against the repository’s GitHub `owner/name` slug. Claude Code tracks clones and worktrees separately.
- The link does not change which branch is checked out. The session opens in whatever state that directory is currently in.

The welcome header shows which path it picked so you can confirm the right clone opened.


[​](#examples)

Examples

The sections below show two common ways to use a deep link: as a Markdown link in a document and as a command in a script or shell alias.


[​](#embed-a-link-in-a-runbook)

Embed a link in a runbook

A deep link in a runbook gives whoever is triaging a one-click way to start investigating in the right repository with a prepared prompt. The platform that renders the runbook must allow custom URL schemes. GitHub-rendered Markdown does not allow `claude-cli://`, so a deep link in a GitHub README, issue, or wiki shows only its label with no clickable link. See [the troubleshooting note](#the-link-renders-as-plain-text-instead-of-being-clickable) for a workaround. The prompt is part of the URL and must be URL-encoded. To produce the encoded value, pass your prompt text through `encodeURIComponent` in a browser console or any URL encoder. The example below adds an investigation entry point to an incident runbook for a service called `web-gateway`:

```python
## High 5xx rate on web-gateway

1. Acknowledge the page in PagerDuty.
2. [Open Claude Code in the gateway repo](claude-cli://open?repo=acme/web-gateway&q=5xx%20rate%20is%20elevated%20on%20web-gateway.%20Check%20recent%20deploys%2C%20error%20logs%20from%20the%20last%2030%20minutes%2C%20and%20open%20incidents%20in%20Linear.)
3. Post initial findings in #incident.
```

To use this in your own runbook, replace `acme/web-gateway` with your service’s repository slug. This allows engineers with Claude Code installed and a local clone of that repository to click step 2 and start investigating with the prompt ready to send.


[​](#open-a-link-from-the-shell)

Open a link from the shell

You can also open a deep link from a shell script, alias, or automation rather than by clicking it. Call your operating system’s URL-opening command with the link as the argument. These commands rely on the handler that Claude Code [registers when you send your first prompt of an interactive session](#registration-and-supported-platforms) on the machine.

- macOS

- Linux

- Windows

The built-in `open` command passes the URL to the registered `claude-cli://` handler:

```python
open "claude-cli://open?repo=acme/payments&q=review%20open%20PRs"
```

On success, a new terminal window opens with Claude Code running and the prompt pre-filled.

Most desktop environments provide `xdg-open`, which passes the URL to the registered handler:

```python
xdg-open "claude-cli://open?repo=acme/payments&q=review%20open%20PRs"
```

On success, a new terminal window opens with Claude Code running and the prompt pre-filled. If the shell reports that `xdg-open` isn’t found, see [Troubleshooting](#xdg-open-is-not-found-on-linux).

In PowerShell, `Start-Process` passes the URL to the registered handler:

```python
Start-Process "claude-cli://open?repo=acme/payments&q=review%20open%20PRs"
```

In `cmd.exe`, `start` treats its first quoted argument as a window title, so pass an empty title before the URL:

```python
start "" "claude-cli://open?repo=acme/payments&q=review%20open%20PRs"
```

On success, a new terminal window opens with Claude Code running and the prompt pre-filled.


[​](#registration-and-supported-platforms)

Registration and supported platforms

Claude Code registers the `claude-cli://` handler with your operating system on macOS, Linux, and Windows when you send your first prompt of an interactive session. Starting `claude` and exiting without sending a prompt doesn’t register the handler. You don’t run a separate install command. Registration writes to user-level locations only:

| Platform | Handler location                                                                                                   |
|----------|--------------------------------------------------------------------------------------------------------------------|
| macOS    | `~/Applications/Claude Code URL Handler.app`                                                                       |
| Linux    | `claude-code-url-handler.desktop` under `$XDG_DATA_HOME/applications`, defaulting to `~/.local/share/applications` |
| Windows  | `HKEY_CURRENT_USER\Software\Classes\claude-cli`                                                                    |

The handler launches Claude Code in a detected terminal emulator. On macOS, Claude Code remembers the terminal from your most recent interactive session and reuses it, supporting iTerm2, Ghostty, kitty, Alacritty, WezTerm, and Terminal.app. On Linux it honors the `$TERMINAL` environment variable, then `x-terminal-emulator`, then a list of common emulators. On Windows it prefers Windows Terminal, then PowerShell, then `cmd.exe`. To prevent registration entirely, set [`disableDeepLinkRegistration`](settings-reference.md#disabledeeplinkregistration) to `"disable"` in `settings.json`. To enforce this across an organization so users cannot re-enable it, set it in [managed settings](../13-Enterprise-Admin/server-managed-settings.md) instead. Claude Code’s `disableDeepLinkRegistration` setting covers `claude-cli://` links only.


[​](#open-a-vs-code-tab-instead-of-a-terminal)

Open a VS Code tab instead of a terminal

The VS Code extension registers its own handler at `vscode://anthropic.claude-code/open`, which opens a Claude Code editor tab rather than a terminal window. See [Launch a VS Code tab from other tools](../03-IDE-Integrations/vs-code.md#launch-a-vs-code-tab-from-other-tools) for that URL’s parameters.


[​](#open-a-claude-desktop-session-on-an-ssh-connection)

Open a Claude Desktop session on an SSH connection

Claude Desktop handles its own `claude://` links. To open a Desktop session on a remote machine over SSH, see [Open an SSH session from a link](../16-Mobile-Desktop/desktop.md#open-an-ssh-session-from-a-link).


[​](#troubleshooting)

Troubleshooting


[​](#clicking-the-link-does-nothing)

Clicking the link does nothing

The handler likely isn’t registered yet. Registration happens when you send your first prompt of an interactive session, not when the session starts. Start an interactive `claude` session on that machine, send any prompt, exit, and try the link again. If you are on Linux without a desktop environment, `xdg-open` may have nothing to dispatch to.


[​](#xdg-open-is-not-found-on-linux)

xdg-open is not found on Linux

The `xdg-open` command is part of the `xdg-utils` package, which minimal server images, containers, and WSL distributions often leave out. Install `xdg-utils` with your distribution’s package manager, for example `sudo apt install xdg-utils`, then run the command again. If the command then runs but nothing opens, `xdg-open` may have no desktop environment to dispatch to; see [Clicking the link does nothing](#clicking-the-link-does-nothing).


[​](#the-link-renders-as-plain-text-instead-of-being-clickable)

The link renders as plain text instead of being clickable

Some Markdown renderers only allow `http` and `https` links and strip other URL schemes. GitHub does this in READMEs, issues, pull requests, and wikis: `[label](claude-cli://...)` renders as `label`, with no link and the URL removed. On these platforms, put the deep link in a code block so readers can see the URL and paste it into their browser’s address bar.


[​](#the-session-opens-in-my-home-directory-instead-of-the-repo)

The session opens in my home directory instead of the repo

The `repo` parameter only resolves to clones Claude Code has already seen. Run `claude` inside the clone once so Claude Code records its path, or switch the link to use `cwd` with an absolute path.


[​](#the-link-opens-the-wrong-terminal)

The link opens the wrong terminal

On macOS, start `claude` in your preferred terminal once and the next deep link will use it. On Linux, set the `$TERMINAL` environment variable to your preferred emulator’s command name. On Windows, the order is fixed: install Windows Terminal if you want links to open there instead of a PowerShell or `cmd.exe` window.


[​](#learn-more)

Learn more

These pages cover related ways to launch or extend Claude Code sessions:

- [Skills](../08-Plugins-Skills/skills.md): store a long runbook prompt as a `/skill` in the repo so the deep link’s `q` parameter only has to name it
- [Non-interactive mode](headless.md): run Claude from a script and capture the output without opening a terminal

---

## Development containers - Claude Code Docs

Source: https://code.claude.com/docs/en/devcontainer
Path: 02-Claude-Code-CLI/devcontainer.md

## On this page

- [Add Claude Code to your dev container](#add-claude-code-to-your-dev-container)
- [Persist authentication and settings across rebuilds](#persist-authentication-and-settings-across-rebuilds)
- [Enforce organization policy](#enforce-organization-policy)
- [Restrict network egress](#restrict-network-egress)
- [Run without permission prompts](#run-without-permission-prompts)
- [Try the reference container](#try-the-reference-container)
- [Next steps](#next-steps)

Deployment

# Development containers

Copy pageCopy page

Run Claude Code inside a dev container for consistent, isolated environments across your team.

Copy pageCopy page

A [development container](https://containers.dev/), or dev container, lets you define an identical, isolated environment that every engineer on your team can run. With Claude Code installed in that container, commands Claude runs execute inside it rather than on the host machine, while edits to your project files appear in your local repository as you work. This page covers [installing Claude Code in a dev container](#add-claude-code-to-your-dev-container), then a set of self-contained configuration topics: persisting authentication across rebuilds, enforcing organization policy, restricting network egress, and running without permission prompts. Read the ones that match your setup.

While the dev container provides substantial protections, no system is completely immune to all attacks. When executed with `--dangerously-skip-permissions`, dev containers do not prevent a malicious project from exfiltrating anything accessible inside the container, including the Claude Code credentials stored in [`~/.claude`](claude-directory.md). Only use dev containers when developing with trusted repositories, and monitor Claude’s activities. Avoid mounting host secrets such as `~/.ssh` or cloud credential files into the container; prefer repository-scoped or short-lived tokens.

How dev containers work with your editor

A dev container runs as a Docker container, either on your machine or on a cloud host such as GitHub Codespaces. An editor that supports the Dev Containers spec, such as VS Code, GitHub Codespaces, a JetBrains IDE, or Cursor, connects to that container: you browse and edit files in the editor as usual, but the integrated terminal, language servers, and build tools all run inside the container rather than on your host. Editors without dev container support, such as plain Vim, are not part of this workflow.Claude Code runs inside the container, so it sees the same files, dependencies, and tools as the rest of your project’s toolchain. In VS Code you can use either the [Claude Code extension panel](../03-IDE-Integrations/vs-code.md) or run `claude` in the integrated terminal; both run inside the container and share the same `~/.claude` configuration.


[​](#add-claude-code-to-your-dev-container)

Add Claude Code to your dev container

Claude Code installs into any dev container through the [Claude Code Dev Container Feature](https://github.com/anthropics/devcontainer-features/tree/main/src/claude-code). The settings work with any tool that supports the Dev Containers spec, such as VS Code, GitHub Codespaces, or JetBrains IDEs. The steps below use VS Code as an example. When you open the container in VS Code or Codespaces, the feature also adds the Claude Code VS Code extension; other editors ignore that part.

New to dev containers? The [VS Code Dev Containers tutorial](https://code.visualstudio.com/docs/devcontainers/tutorial) walks through installing Docker, the extension, and opening your first container. For a fuller hardened example with a firewall and persistent volumes, see [Try the reference container](#try-the-reference-container).

1

Create or update devcontainer.json

Save the following as `.devcontainer/devcontainer.json` in your repository, or add the `features` block to your existing file.The version tag at the end, such as `:1.0`, pins the feature’s install script, not the Claude Code release. The feature installs the latest Claude Code, and Claude Code auto-updates itself inside the container by default.To pin the CLI version or disable auto-update, see [Enforce organization policy](#enforce-organization-policy).

.devcontainer/devcontainer.json

```python
{
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
  "features": {
    "ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}
  }
}
```

Replace the `image` line with your project’s base image or remove it if your existing file uses a Dockerfile.The Claude Code feature installs Node.js itself when the base image doesn’t provide it. If that install fails and the build stops with `Failed to install Node.js and npm`, add `"ghcr.io/devcontainers/features/node:1": {}` to the `features` block above the Claude Code feature and rebuild.

2

Rebuild the container

Open the VS Code Command Palette with `Cmd+Shift+P` on Mac or `Ctrl+Shift+P` on Windows and Linux, and run **Dev Containers: Rebuild Container**.For other tools, follow that tool’s rebuild action: see [rebuilding in GitHub Codespaces](https://docs.github.com/en/codespaces/developing-in-a-codespace/rebuilding-the-container-in-a-codespace), the [Dev Containers CLI](https://github.com/devcontainers/cli), or your IDE’s dev container documentation.

3

Sign in to Claude Code

Open a terminal in the rebuilt container and run `claude`, then follow the authentication prompt.

What you see at the authentication prompt depends on your provider:

- **Anthropic**: sign in through a browser with your Claude or Anthropic Console account
- **[Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry](third-party-integrations.md)**: Claude Code uses your cloud provider credentials, with no browser prompt

For cloud providers, pass credentials into the container as environment variables through `containerEnv`, a Codespaces secret, or your cloud’s workload identity rather than mounting credential files from the host. See [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), or [Microsoft Foundry](microsoft-foundry.md) for the credential chain Claude Code reads. See [Choose your API provider](../13-Enterprise-Admin/admin-setup.md#choose-your-api-provider) to decide which path fits your organization.

If the browser sign-in completes but the callback never reaches the container, copy the code shown in the browser and paste it at the `Paste code here if prompted` prompt in the terminal. This can happen when the editor’s port forwarding doesn’t route the localhost callback.


[​](#persist-authentication-and-settings-across-rebuilds)

Persist authentication and settings across rebuilds

By default, the container’s home directory is discarded on rebuild, so engineers must sign in again each time. Claude Code stores its authentication token, user settings, and session history under the [`~/.claude`](claude-directory.md) directory. It stores your account details, personal MCP servers, and per-project trust in a separate file outside that directory: [`~/.claude.json`](settings-reference.md#global-config-settings). To keep the directory and the file, mount a named volume at `~/.claude` and set [`CLAUDE_CONFIG_DIR`](env-vars.md) to the same path so Claude Code writes `.claude.json` inside the volume. The following example mounts the volume and sets `CLAUDE_CONFIG_DIR` for a container whose `remoteUser` is `node`:

devcontainer.json

```python
"mounts": [
  "source=claude-code-config,target=/home/node/.claude,type=volume"
],
"containerEnv": {
  "CLAUDE_CONFIG_DIR": "/home/node/.claude"
}
```

Replace `/home/node` with the home directory of your container’s `remoteUser`. If you already set `containerEnv`, for example in [Enforce organization policy](#enforce-organization-policy), add `CLAUDE_CONFIG_DIR` to that object rather than adding a second one.

If Claude Code repeats first-launch setup after each rebuild despite the mounted volume, check that `containerEnv` in `devcontainer.json` sets `CLAUDE_CONFIG_DIR` to the volume’s mount path. Without `CLAUDE_CONFIG_DIR`, `~/.claude.json` stays in the home directory and is discarded on rebuild, along with its record that you completed setup.

To isolate state per project rather than sharing one volume across all repositories, include the `${devcontainerId}` variable in the source name. The [reference configuration](https://github.com/anthropics/claude-code/blob/main/.devcontainer/devcontainer.json) uses `source=claude-code-config-${devcontainerId}` for this purpose. In GitHub Codespaces, `~/.claude` persists when you stop and start a codespace but is cleared when you rebuild the container, so the configuration above applies there too. To carry authentication across codespaces, store `ANTHROPIC_API_KEY` or a `CLAUDE_CODE_OAUTH_TOKEN` from [`claude setup-token`](authentication.md#generate-a-long-lived-token) as a [Codespaces secret](https://docs.github.com/en/codespaces/managing-your-codespaces/managing-your-account-specific-secrets-for-github-codespaces). Codespaces exposes secrets as environment variables inside the container automatically.


[​](#enforce-organization-policy)

Enforce organization policy

A dev container is a convenient place to apply organization policy, because the same image and configuration run on every engineer’s machine. Claude Code reads `/etc/claude-code/managed-settings.json` on Linux and applies it at the highest precedence in the [settings hierarchy](settings.md#settings-precedence), so values there override anything an engineer sets in `~/.claude` or the project’s `.claude/` directory. Copy the file into place from your Dockerfile:

Dockerfile

```python
RUN mkdir -p /etc/claude-code
COPY managed-settings.json /etc/claude-code/managed-settings.json
```

Because the Dockerfile lives in the repository, anyone with write access can change or remove this step. For policy that engineers cannot bypass by editing repository files, deliver managed settings through [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) or your MDM instead. See [managed settings files](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms) for the available keys and the other delivery paths. To set [environment variables](env-vars.md) that apply to every Claude Code session in the container, add them to `containerEnv` in your `devcontainer.json`. The following example opts out of telemetry and error reporting and prevents Claude Code from auto-updating after install:

devcontainer.json

```python
"containerEnv": {
  "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
  "DISABLE_AUTOUPDATER": "1"
}
```

`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` also disables the feature-flag evaluation that [Remote Control](remote-control.md#requirements) and the other [features that need feature-flag fetching](env-vars.md#features-that-need-feature-flag-fetching) depend on, so sessions in the container can’t use them. The Dev Container Feature always installs the latest Claude Code release. To pin a specific Claude Code version for reproducible builds, install it from your Dockerfile with `npm install -g @anthropic-ai/claude-code@X.Y.Z` instead of using the feature, and set `DISABLE_AUTOUPDATER` to `1` in `containerEnv`. For the full list of policy controls including permission rules, tool restrictions, and MCP server allowlists, see [Set up Claude Code for your organization](../13-Enterprise-Admin/admin-setup.md). To make [MCP servers](../06-MCP-Tools/General/mcp.md) available inside the container, define them at [project scope](../06-MCP-Tools/General/mcp.md#mcp-installation-scopes) in a `.mcp.json` file at the repository root so they are checked in alongside your dev container configuration. Install any binaries that local stdio servers depend on in your Dockerfile, and add remote server domains to your network allowlist.


[​](#restrict-network-egress)

Restrict network egress

You can limit the container’s outbound traffic to only the domains Claude Code needs. See [Network access requirements](../13-Enterprise-Admin/network-config.md#network-access-requirements) for the inference and authentication domains, and [Telemetry services](../13-Enterprise-Admin/data-usage.md#telemetry-services) for the optional telemetry and error reporting connections and how to disable them. The reference container includes an [`init-firewall.sh`](https://github.com/anthropics/claude-code/blob/main/.devcontainer/init-firewall.sh) script that limits outbound traffic to the destinations the script allows. Running a firewall inside a container requires extra permissions, so the reference adds the `NET_ADMIN` and `NET_RAW` capabilities through `runArgs`. The firewall script and these capabilities are not required for Claude Code itself: you can leave them out and rely on your own network controls instead.


[​](#run-without-permission-prompts)

Run without permission prompts

Because the container runs Claude Code as a non-root user and confines command execution to the container, you can pass `--dangerously-skip-permissions` for unattended operation. The CLI rejects this flag when launched as root, so confirm `remoteUser` is set to a non-root account. Skipping permission prompts removes your opportunity to review tool calls before they run. Claude can still modify any file in the bind-mounted workspace, which appears directly on your host, and reach anything the container’s network policy allows. Pair this flag with the [network egress restrictions](#restrict-network-egress) above to limit what a bypassed session can reach. If you want fewer prompts without disabling safety checks, consider [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) instead, which has a classifier review actions before they run. To prevent engineers from using `--dangerously-skip-permissions` at all, set `permissions.disableBypassPermissionsMode` to `"disable"` in [managed settings](settings-reference.md#permission-settings).


[​](#try-the-reference-container)

Try the reference container

The [`anthropics/claude-code`](https://github.com/anthropics/claude-code/tree/main/.devcontainer) repository includes an example dev container that combines the CLI, the egress firewall, persistent volumes, and a Zsh-based shell. It is provided as a working example rather than a maintained base image; use it to see how the pieces fit together before applying them to your own configuration.

1

Install prerequisites

Install VS Code and the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers).

2

Clone the reference

Clone the [Claude Code repository](https://github.com/anthropics/claude-code) and open it in VS Code.

3

Reopen in container

When prompted, click **Reopen in Container**, or run **Dev Containers: Reopen in Container** from the Command Palette.

4

Start Claude Code

Once the container finishes building, open a terminal with `` Ctrl+` `` and run `claude` to sign in and start your first session.

To use this configuration with your own project, copy the `.devcontainer/` directory into your repository and adjust the Dockerfile for your toolchain, or return to [Add Claude Code to your dev container](#add-claude-code-to-your-dev-container) to add only the feature to a setup you already have. The reference configuration consists of three files. None of them are required when you add Claude Code to your own dev container through the feature, but they show one way to combine the pieces.

| File                                                                                                       | Purpose                                                                       |
|------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------|
| [`devcontainer.json`](https://github.com/anthropics/claude-code/blob/main/.devcontainer/devcontainer.json) | Volume mounts, `runArgs` capabilities, VS Code extensions, and `containerEnv` |
| [`Dockerfile`](https://github.com/anthropics/claude-code/blob/main/.devcontainer/Dockerfile)               | Base image, development tools, and the Claude Code install                    |
| [`init-firewall.sh`](https://github.com/anthropics/claude-code/blob/main/.devcontainer/init-firewall.sh)   | Limits outbound network traffic to the destinations the script allows         |


[​](#next-steps)

Next steps

Once Claude Code is running in your dev container, the pages below cover the rest of an organization rollout: choosing an authentication path, delivering managed policy outside the repository, monitoring usage, and understanding what Claude Code stores and sends.

- [Set up Claude Code for your organization](../13-Enterprise-Admin/admin-setup.md): choose an authentication provider, decide how policy reaches devices, and plan the rollout
- [Server-managed settings](../13-Enterprise-Admin/server-managed-settings.md): deliver managed policy from the claude.ai admin console so engineers cannot bypass it by editing repository files
- [Monitor usage and audit activity](../13-Enterprise-Admin/monitoring-usage.md): export OpenTelemetry metrics and review what your team is running
- [Network access requirements](../13-Enterprise-Admin/network-config.md#network-access-requirements): the full domain allowlist for proxies and firewalls
- [Telemetry services and opt-out](../13-Enterprise-Admin/data-usage.md#telemetry-services): what Claude Code sends by default and the environment variables that disable it
- [Explore the `.claude` directory](claude-directory.md): what the volume mount holds, including credentials, settings, and session history
- [Sandbox environments](sandbox-environments.md): compare dev containers with the built-in Bash sandbox, custom containers, and VMs
- [Security model](../13-Enterprise-Admin/security.md): how Claude Code’s permission system, sandboxing, and prompt-injection protections fit together
- [Permission modes](permission-modes.md): the full range from plan mode to auto mode to bypass, and when to use each

---

## Environment variables - Claude Code Docs

Source: https://code.claude.com/docs/en/env-vars
Path: 02-Claude-Code-CLI/env-vars.md

## On this page

- [Set environment variables](#set-environment-variables)
  - [Set variables in your shell](#set-variables-in-your-shell)
  - [Set variables in settings files](#set-variables-in-settings-files)
- [Precedence](#precedence)
- [Variables](#variables)
- [What the subprocess environment scrub removes](#what-the-subprocess-environment-scrub-removes)
- [Features that need feature-flag fetching](#features-that-need-feature-flag-fetching)
  - [First session after an install or upgrade](#first-session-after-an-install-or-upgrade)
- [See also](#see-also)

Reference

# Environment variables

Copy pageCopy page

Reference for environment variables that control Claude Code behavior.

Copy pageCopy page

Environment variables can control Claude Code behavior such as model selection, authentication, request routing, and feature toggles. Many of the same behaviors can also be configured through a [settings file](settings.md) field, a [CLI flag](cli-reference.md), or an in-session command like `/model`. This page covers how to:

- [Set environment variables](#set-environment-variables) in your shell or in a settings file
- [Check which value applies](#precedence) when a behavior can be set more than one way
- [Look up the variables Claude Code reads](#variables)
- [See which features stop working](#features-that-need-feature-flag-fetching) when a variable turns feature-flag fetching off


[​](#set-environment-variables)

Set environment variables

A variable you set in your shell lasts for that terminal session, while a variable in a settings file applies every time `claude` runs.


[​](#set-variables-in-your-shell)

Set variables in your shell

Set the variable before launching `claude`:

- macOS, Linux, WSL

- Windows PowerShell

- Windows CMD

```python
export API_TIMEOUT_MS="1200000"
claude
```

To set it for every session, add the `export` line to `~/.bashrc`, `~/.zshrc`, or your shell’s profile file.

```python
$env:API_TIMEOUT_MS = "1200000"
claude
```

To set it for every session, run `[Environment]::SetEnvironmentVariable("API_TIMEOUT_MS", "1200000", "User")` and open a new terminal.

```python
set API_TIMEOUT_MS=1200000
claude
```

To set it for every session, run `setx API_TIMEOUT_MS "1200000"` and open a new terminal.

The assignment line prints nothing on success. To confirm the variable is set, print it in the same shell:

- macOS, Linux, WSL

- Windows PowerShell

- Windows CMD

```python
echo $API_TIMEOUT_MS
```

```python
echo $env:API_TIMEOUT_MS
```

```python
echo %API_TIMEOUT_MS%
```


[​](#set-variables-in-settings-files)

Set variables in settings files

Add variables under the `env` key in a `settings.json` file, creating the file if it doesn’t exist. Claude Code reads them directly from the file, so they take effect no matter how `claude` was launched. A running session applies new and changed values to its environment when you save the file, but a feature that reads its variables once at startup, such as [OpenTelemetry monitoring](../13-Enterprise-Admin/monitoring-usage.md), keeps its startup values until you relaunch. Removing a variable from the file doesn’t unset it in a running session; the removal takes effect the next time you launch `claude`.

~/.claude/settings.json

```python
{
  "env": {
    "API_TIMEOUT_MS": "1200000",
    "BASH_DEFAULT_TIMEOUT_MS": "300000"
  }
}
```

Claude Code copies these values into its environment as written. No shell processes them, so shorthand such as `~` or `$HOME` stays as typed. For a variable that takes a path, such as `CLAUDE_CONFIG_DIR`, write the absolute path: `"CLAUDE_CONFIG_DIR": "/home/you/.claude-work"`. The file you choose controls who the variables apply to:

| File                          | Applies to                                                                                                                      |
|:------------------------------|:--------------------------------------------------------------------------------------------------------------------------------|
| `~/.claude/settings.json`     | You, in every project                                                                                                           |
| `.claude/settings.json`       | Everyone working in the project, checked into source control                                                                    |
| `.claude/settings.local.json` | You, in this project only, gitignored when Claude Code saves a setting to it; add it to your gitignore if you create it by hand |
| Managed settings              | Everyone in your organization, deployed by an admin                                                                             |

See [Settings files](settings.md#where-settings-live) for where each file lives and [Settings precedence](settings.md#settings-precedence) for how they combine when more than one sets the same variable.


[​](#precedence)

Precedence

Some behaviors have both an environment variable and a dedicated settings key, and which one Claude Code reads first differs per key. For `ANTHROPIC_MODEL` and `CLAUDE_CODE_AUTO_CONNECT_IDE`, Claude Code reads the variable first and uses the `model` or `autoConnectIde` setting only when the variable is unset. For the pair you’re setting, check the variable’s row below and the key’s entry on the [settings reference](settings-reference.md). When the same variable is set in both your shell and a settings file `env` block, the settings file value applies in most sessions. Claude Code writes each `env` entry into the process environment, replacing the value inherited from the shell. [How `env` values interact with your shell](settings-reference.md#how-env-values-interact-with-your-shell) covers the sessions that keep the inherited value instead, and the [`env` setting](settings-reference.md#when-claude-code-applies-env-values) says when it applies them. A few variables are special-cased; the [`env` setting](settings-reference.md#env) lists the exceptions. In a settings file you can set a variable but you can’t remove one. To override a variable you can’t unset, such as a stale `CLAUDE_CODE_USE_VERTEX` exported by a shell profile you don’t control, set it to an empty string in the `env` block: `"CLAUDE_CODE_USE_VERTEX": ""`. Claude Code treats the empty value as unset for provider selection. Subprocesses still inherit the empty value. Between settings files, `env` values follow [settings precedence](settings.md#settings-precedence), so a managed settings entry overrides the same variable in user or project settings. Project and local settings can’t set some variables, such as `CLAUDE_CONFIG_DIR` and the OpenTelemetry exporter variables. [Variables Claude Code ignores in `env`](settings-reference.md#variables-claude-code-ignores-in-env) lists them, along with the OpenTelemetry off values that still apply. How an environment variable interacts with CLI flags and in-session commands varies per feature: `--model` and `/model` override `ANTHROPIC_MODEL`, while `CLAUDE_CODE_EFFORT_LEVEL` overrides `--effort` and `/effort`. When a variable interacts with another configuration source, its row in the [Variables](#variables) list states the precedence or links to the page that documents it. Claude Code reads shell environment variables at startup, so changes to them take effect the next time you launch `claude`. Variables set under the `env` key in settings files are reapplied to a running session when the file changes, with the startup-only exception described in [Set variables in settings files](#in-settings-files).


[​](#variables)

Variables

Numeric variables such as timeouts, token budgets, and retry counts accept scientific notation and digit-separator spellings in addition to plain digits, except where a variable’s row notes it takes plain digits only. For example, Claude Code reads `2e3` as 2000 and `64_000` as 64000. Before v2.1.211, these spellings could silently set a much smaller value, such as `1e6` setting a timeout to 1.

For variables that turn a behavior on or off, set `1`, `true`, `yes`, or `on` to turn it on and `0`, `false`, `no`, or `off` to turn it off, in any casing.Some variables read only whether you set them at all, so any non-empty value including `0` turns the behavior on, and you turn the behavior off by unsetting the variable or setting it to an empty value. These variables work that way:

- `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`
- `DISABLE_TELEMETRY`
- `DISABLE_ERROR_REPORTING`
- `CLAUDE_CODE_TMUX_TRUECOLOR`
- `IS_DEMO`

One other variable has its own rule: `FORCE_HYPERLINK` reads a number, so only `0` turns it off. Each variable’s row also states its own rule.

| Variable                                                | Purpose                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
|:--------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `ANTHROPIC_API_KEY`                                     | API key sent as `X-Api-Key` header. When set, this key is used instead of your Claude Pro, Max, Team, or Enterprise subscription even if you are logged in. In non-interactive mode (`-p`), the key is always used when present. In interactive mode, you are prompted to approve the key once before it overrides your subscription. To use your subscription instead, run `unset ANTHROPIC_API_KEY`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `ANTHROPIC_AUTH_TOKEN`                                  | Custom value for the `Authorization` header (the value you set here will be prefixed with `Bearer `)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `ANTHROPIC_AWS_API_KEY`                                 | Workspace API key for [Claude Platform on AWS](claude-platform-on-aws.md), generated in the AWS Console. Sent as `x-api-key` and takes precedence over AWS SigV4                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `ANTHROPIC_AWS_BASE_URL`                                | Override the [Claude Platform on AWS](claude-platform-on-aws.md) endpoint URL. Use for custom regions or when routing through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md). Defaults to `https://aws-external-anthropic.{region}.api.aws`. Claude Code resolves the region with the [same precedence as on Amazon Bedrock](amazon-bedrock.md#3-configure-claude-code)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `ANTHROPIC_AWS_WORKSPACE_ID`                            | Required for [Claude Platform on AWS](claude-platform-on-aws.md). Sent on every request as the `anthropic-workspace-id` header                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `ANTHROPIC_BASE_URL`                                    | Override the API endpoint to route requests through a proxy or gateway. For what happens when that gateway rejects MCP tool search, see [Tool search through an LLM gateway](../06-MCP-Tools/General/mcp.md#tool-search-through-a-gateway). As of v2.1.196, [Remote Control](remote-control.md#requirements) is disabled when this points at a host other than `api.anthropic.com`, matching its behavior on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `ANTHROPIC_BEDROCK_BASE_URL`                            | Override the Amazon Bedrock endpoint URL. Use for custom Amazon Bedrock endpoints or when routing through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md). See [Amazon Bedrock](amazon-bedrock.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `ANTHROPIC_BEDROCK_MANTLE_BASE_URL`                     | Override the Amazon Bedrock Mantle endpoint URL. See [Mantle endpoint](amazon-bedrock.md#use-the-mantle-endpoint)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `ANTHROPIC_BEDROCK_REGION_PREFIX`                       | Cross-region inference profile prefix (`us`, `eu`, `apac`, `jp`, `au`, or `global`) Claude Code tries first instead of the one derived from the AWS region. Ignored in AWS GovCloud regions. Requires Claude Code v2.1.224 or later. See [Amazon Bedrock](amazon-bedrock.md#cross-region-inference-profile-prefixes)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `ANTHROPIC_BEDROCK_SERVICE_TIER`                        | Amazon Bedrock [service tier](https://docs.aws.amazon.com/bedrock/latest/userguide/service-tiers-inference.html) (`default`, `flex`, or `priority`). Sent as the `X-Amzn-Bedrock-Service-Tier` header. See [Amazon Bedrock](amazon-bedrock.md#service-tiers)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `ANTHROPIC_BETAS`                                       | Comma-separated list of additional `anthropic-beta` header values to include in API requests. Claude Code already sends the beta headers it needs; use this to opt into an [Anthropic API beta](../04-API-Reference/Endpoints/beta-headers.md) before Claude Code adds native support. Unlike the [`--betas` flag](cli-reference.md#cli-flags), which requires API key authentication, this variable works with all auth methods including Claude.ai subscription                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `ANTHROPIC_CUSTOM_HEADERS`                              | Custom headers to add to requests (`Name: Value` format, newline-separated for multiple headers). If a name or value contains a character an HTTP header can’t carry, such as a curly quote or a zero-width space, the request fails with an error that identifies the pair by position. Requires Claude Code v2.1.227 or later. [Invalid request header value](errors.md#invalid-request-header-value) lists the exact character set and where the check runs. A value that sets a credential, org or tenant, routing, or API-behavior header, such as `Authorization` or `Host`, counts as a [setting that needs approval](../13-Enterprise-Admin/server-managed-settings.md#environment-variables-and-the-approval-dialog) when server-managed settings deliver it. From project or local settings, such a value follows the [rules for when `env` values apply](settings-reference.md#when-claude-code-applies-env-values)                                                                                                                                                                                                                                                                                                                                                                                                     |
| `ANTHROPIC_CUSTOM_MODEL_OPTION`                         | Model ID to add as a custom entry in the `/model` picker. Use this to make a non-standard or gateway-specific model selectable without replacing built-in aliases. See [Model configuration](model-config.md#add-a-custom-model-option)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION`             | Display description for the custom model entry in the `/model` picker. Defaults to `Custom model (<model-id>)` when not set                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `ANTHROPIC_CUSTOM_MODEL_OPTION_NAME`                    | Display name for the custom model entry in the `/model` picker. When not set, the entry shows the model’s name if Claude Code [recognizes the ID](model-config.md#customize-pinned-model-display-and-capabilities), and the model ID otherwise                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES`  | Comma-separated list of [capabilities](model-config.md#customize-pinned-model-display-and-capabilities) the custom model supports, for example `effort,thinking`. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `ANTHROPIC_DEFAULT_FABLE_MODEL`                         | Model ID that the `fable` alias resolves to, and the ID Claude Code recognizes as a Fable model for [automatic model fallback](model-config.md#automatic-model-fallback) on third-party providers. See [Model configuration](model-config.md#environment-variables)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `ANTHROPIC_DEFAULT_FABLE_MODEL_DESCRIPTION`             | Display description for the pinned Fable model in the `/model` picker. When not set, the row shows a default description that begins `Custom Fable model`. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `ANTHROPIC_DEFAULT_FABLE_MODEL_NAME`                    | Display name for the pinned Fable model in the `/model` picker. When not set, the row shows the model’s name if Claude Code recognizes the pinned ID, and the pinned ID otherwise. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `ANTHROPIC_DEFAULT_FABLE_MODEL_SUPPORTED_CAPABILITIES`  | Comma-separated list of [capabilities](model-config.md#customize-pinned-model-display-and-capabilities) the pinned Fable model supports, for example `effort,thinking`. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `ANTHROPIC_DEFAULT_HAIKU_MODEL`                         | Model ID that the `haiku` alias resolves to, also used for [background functionality](../17-Billing-Plans/costs.md#background-token-usage). See [Model configuration](model-config.md#environment-variables)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `ANTHROPIC_DEFAULT_HAIKU_MODEL_DESCRIPTION`             | Display description for the pinned Haiku model in the `/model` picker. When not set, the row shows a default description that begins `Custom Haiku model`. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME`                    | Display name for the pinned Haiku model in the `/model` picker. When not set, the row shows the model’s name if Claude Code recognizes the pinned ID, and the pinned ID otherwise. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `ANTHROPIC_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES`  | Comma-separated list of [capabilities](model-config.md#customize-pinned-model-display-and-capabilities) the pinned Haiku model supports, for example `effort,thinking`. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `ANTHROPIC_DEFAULT_MODEL`                               | Model that new sessions start on by default. Requires Claude Code v2.1.236 or later. See [Set a default model for new sessions](model-config.md#set-a-default-model-for-new-sessions)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `ANTHROPIC_DEFAULT_OPUS_MODEL`                          | Model ID that the `opus` alias resolves to, and that `opusplan` uses while Plan Mode is active. See [Model configuration](model-config.md#environment-variables)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `ANTHROPIC_DEFAULT_OPUS_MODEL_DESCRIPTION`              | Display description for the pinned Opus model in the `/model` picker. When not set, the row shows a default description that begins `Custom Opus model`. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `ANTHROPIC_DEFAULT_OPUS_MODEL_NAME`                     | Display name for the pinned Opus model in the `/model` picker. When not set, the row shows the model’s name if Claude Code recognizes the pinned ID, and the pinned ID otherwise. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `ANTHROPIC_DEFAULT_OPUS_MODEL_SUPPORTED_CAPABILITIES`   | Comma-separated list of [capabilities](model-config.md#customize-pinned-model-display-and-capabilities) the pinned Opus model supports, for example `effort,thinking`. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `ANTHROPIC_DEFAULT_SONNET_MODEL`                        | Model ID that the `sonnet` alias resolves to, and that `opusplan` uses when Plan Mode is not active. See [Model configuration](model-config.md#environment-variables)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `ANTHROPIC_DEFAULT_SONNET_MODEL_DESCRIPTION`            | Display description for the pinned Sonnet model in the `/model` picker. When not set, the row shows a default description that begins `Custom Sonnet model`. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `ANTHROPIC_DEFAULT_SONNET_MODEL_NAME`                   | Display name for the pinned Sonnet model in the `/model` picker. When not set, the row shows the model’s name if Claude Code recognizes the pinned ID, and the pinned ID otherwise. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES` | Comma-separated list of [capabilities](model-config.md#customize-pinned-model-display-and-capabilities) the pinned Sonnet model supports, for example `effort,thinking`. See [Model configuration](model-config.md#customize-pinned-model-display-and-capabilities)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `ANTHROPIC_FEDERATION_RULE_ID`                          | Federation rule ID for [Workload Identity Federation](../04-API-Reference/Other/manage-claude-workload-identity-federation.md). When you set it together with `ANTHROPIC_ORGANIZATION_ID`, Claude Code selects federation credentials, which rank above your `/login` credential. See [authentication precedence](authentication.md#authentication-precedence)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `ANTHROPIC_FOUNDRY_API_KEY`                             | API key for Microsoft Foundry authentication (see [Microsoft Foundry](microsoft-foundry.md))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `ANTHROPIC_FOUNDRY_AUTH_TOKEN`                          | Bearer token for Microsoft Foundry authentication, such as a Microsoft Entra access token. Claude Code sends it as the `Authorization: Bearer` header. Takes precedence over `ANTHROPIC_FOUNDRY_API_KEY` and over the Azure default credential chain. See [Microsoft Foundry](microsoft-foundry.md). Requires Claude Code v2.1.203 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `ANTHROPIC_FOUNDRY_BASE_URL`                            | Full base URL for the Microsoft Foundry resource (for example, `https://my-resource.services.ai.azure.com/anthropic`). Alternative to `ANTHROPIC_FOUNDRY_RESOURCE` (see [Microsoft Foundry](microsoft-foundry.md))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `ANTHROPIC_FOUNDRY_RESOURCE`                            | Microsoft Foundry resource name (for example, `my-resource`). Claude Code [refuses a URL or host name](errors.md#anthropic-foundry-resource-must-be-a-foundry-resource-name). Required if `ANTHROPIC_FOUNDRY_BASE_URL` is not set (see [Microsoft Foundry](microsoft-foundry.md))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `ANTHROPIC_MODEL`                                       | Name of the model setting to use (see [Model Configuration](model-config.md#environment-variables))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `ANTHROPIC_ORGANIZATION_ID`                             | Organization ID for [Workload Identity Federation](../04-API-Reference/Other/manage-claude-workload-identity-federation.md). Set it together with `ANTHROPIC_FEDERATION_RULE_ID`. See [authentication precedence](authentication.md#authentication-precedence)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `ANTHROPIC_PROFILE`                                     | Name of the Anthropic profile to authenticate with, such as one created by [`ant auth login`](../04-API-Reference/Other/cli-sdks-libraries-cli-authentication.md) or by [signing in to a Console account without an API key](authentication.md#sign-in-without-an-api-key). See [authentication precedence](authentication.md#authentication-precedence)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `ANTHROPIC_SMALL_FAST_MODEL`                            | \[DEPRECATED\] Name of [Haiku-class model for background tasks](../17-Billing-Plans/costs.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `ANTHROPIC_SMALL_FAST_MODEL_AWS_REGION`                 | Override AWS region for the Haiku-class model when using Amazon Bedrock or Amazon Bedrock Mantle. On Amazon Bedrock, this only takes effect when `ANTHROPIC_DEFAULT_HAIKU_MODEL` or the deprecated `ANTHROPIC_SMALL_FAST_MODEL` is also set, since Amazon Bedrock otherwise runs background tasks on the [default Sonnet model or the primary model](amazon-bedrock.md#4-pin-model-versions) in the session region                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `ANTHROPIC_VERTEX_BASE_URL`                             | Override Google Cloud’s Agent Platform endpoint URL. Use for custom Google Cloud’s Agent Platform endpoints or when routing through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md). See [Google Cloud’s Agent Platform](google-vertex-ai.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `ANTHROPIC_VERTEX_PROJECT_ID`                           | GCP project ID that Google Cloud’s Agent Platform requests are addressed to. See [Configure GCP credentials](google-vertex-ai.md#3-configure-gcp-credentials)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `ANTHROPIC_WORKSPACE_ID`                                | Workspace ID for [workload identity federation](../04-API-Reference/Other/manage-claude-workload-identity-federation.md). Set this when your federation rule is scoped to more than one workspace so the token exchange knows which workspace to target                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `API_FORCE_IDLE_TIMEOUT`                                | Override the 5-minute body idle timeout that aborts a streaming model response when no bytes arrive. Set to `0` to turn the timeout off, for example when a slow [gateway](../13-Enterprise-Admin/llm-gateway.md) or local model pauses longer than 5 minutes between chunks, or `1` to keep it on for every provider. When unset, the timeout is active on providers other than the direct Anthropic API, [Claude Platform on AWS](claude-platform-on-aws.md), and Amazon Bedrock with `CLAUDE_ENABLE_BYTE_WATCHDOG_BEDROCK=1` set. The [stream watchdogs](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs) run independently of it and abort a long silent pause even when you set `0` here                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `API_TIMEOUT_MS`                                        | Time in milliseconds that each API request attempt has to receive its response headers. It doesn’t limit how long a streaming response runs after that. The default is 600000, or 10 minutes, and the maximum is 2147483647. When you set a positive value, each attempt at a [non-streaming request](errors.md#streaming-response-ended-before-any-complete-data-was-received) has to finish within it. Increase this when requests time out on slow networks or when routing through a proxy. Set to `0` to remove this limit, which requires Claude Code v2.1.305 or later. With `0`, a non-streaming attempt still times out after 300 seconds in a local session                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `AWS_BEARER_TOKEN_BEDROCK`                              | Amazon Bedrock API key for authentication (see [Amazon Bedrock API keys](https://aws.amazon.com/blogs/machine-learning/accelerate-ai-development-with-amazon-bedrock-api-keys/))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `BASH_DEFAULT_TIMEOUT_MS`                               | Default timeout for a foreground Bash or PowerShell tool command, in milliseconds (default: 120000, or 2 minutes). A value above the [default time limit for background commands](tools-reference.md#time-limit-for-background-commands) replaces that default in unattended sessions. The background time limit requires Claude Code v2.1.285 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `BASH_MAX_OUTPUT_LENGTH`                                | Maximum number of characters of bash output that Claude Code reads back into a command’s result (default: 30000; maximum: 150000). If you set the [`bashOutputMaxChars`](settings-reference.md#bashoutputmaxchars) setting, Claude Code ignores this variable. See [Output limits](tools-reference.md#output-limits)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `BASH_MAX_TIMEOUT_MS`                                   | Maximum timeout the model can set for a foreground Bash or PowerShell tool command, in milliseconds (default: 600000, or 10 minutes). The effective ceiling is the larger of this and `BASH_DEFAULT_TIMEOUT_MS`. An effective ceiling longer than 2 hours also becomes the maximum [time limit for background commands](tools-reference.md#time-limit-for-background-commands) in unattended sessions. The background time limit requires Claude Code v2.1.285 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `BETA_TRACING_ENDPOINT`                                 | OTLP/HTTP endpoint for [detailed beta tracing](../13-Enterprise-Admin/monitoring-usage.md#traces-beta): with `ENABLE_BETA_TRACING_DETAILED=1`, logs and traces go there instead of to the configured exporters. Set it in your shell, user settings, or managed settings. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CCR_FORCE_BUNDLE`                                      | Set to `1` to force [`claude --cloud`](claude-code-on-the-web.md#send-local-repositories-without-github) to bundle and upload your local repository instead of cloning from its remote                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDECODE`                                            | Set to `1` in subprocesses Claude Code spawns (Bash and PowerShell tools, tmux sessions, [hook](../07-Hooks/hooks.md) commands, [status line](statusline.md) commands, stdio [MCP server](../06-MCP-Tools/General/mcp.md) subprocesses). IDE extensions also set this in their integrated terminals. Use to detect when a script is running inside a subprocess spawned by Claude Code. To check whether the current process was spawned directly by a tool call or hook, rather than inside a stdio MCP server that Claude Code started, use `CLAUDE_CODE_CHILD_SESSION` instead                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS`               | Set to `1` to disable all built-in [subagent](../09-Agents-Patterns/sub-agents.md) types such as Explore and Plan. Only applies in non-interactive mode (the `-p` flag). Useful for SDK users who want a blank slate. This also removes `general-purpose`, the subagent Claude Code runs when an Agent tool call omits `subagent_type`. Such a call then fails with [`subagent_type is required`](errors.md#subagent-type-is-required)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_AGENT_SDK_MCP_NO_PREFIX`                        | Set to `1` to skip the `mcp__<server>__` prefix on tool names from SDK-created MCP servers. Tools use their original names. SDK usage only                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS`                   | Stall timeout in milliseconds for subagents. Also covers [workflow agents](workflows.md#when-an-agent-stalls-and-restarts) on Claude Code v2.1.286 or later. Default `600000` (10 minutes); if you raise `CLAUDE_STREAM_IDLE_TIMEOUT_MS` while the stream watchdog is on, the default rises with it, as [Handle slow or stalled API responses](../05-Agent-SDK/agent-sdk-typescript.md#handle-slow-or-stalled-api-responses) describes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE`                       | Set the percentage (1-100) of the auto-compact window at which auto-compaction triggers. Use lower values like `50` to compact earlier; the variable can’t raise the threshold, so values above the default percentage are ignored. It applies only in sessions that [compact before the model’s context limit](model-config.md#context-window-and-auto-compaction). Applies to both main conversations and subagents                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_AUTO_BACKGROUND_TASKS`                          | Set to `1` to force-enable automatic backgrounding of long-running agent tasks. When enabled, a [subagent](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) moves to the background after running for approximately two minutes. If Claude queued a tool call such as a file edit behind the subagent, the subagent finishes in the foreground before that call starts. Also enables [automatic backgrounding of long MCP tool calls](../06-MCP-Tools/General/mcp.md#automatic-backgrounding-of-long-tool-calls) in non-interactive mode on Claude Code v2.1.212 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_AX_PREPARK_MS`                                  | In [screen reader mode](accessibility.md), how many milliseconds Claude Code waits before it writes a new or changed line. Default `0`, so Claude Code doesn’t wait. Before v2.1.287, the default was `50`. Claude Code caps the wait at `5000`. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env). Requires Claude Code v2.1.233 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_AX_SCREEN_READER`                               | Set to `1` to render screen-reader friendly output: flat text without decorative borders or animations. Set to `0` to force screen-reader mode off even when [`axScreenReader`](settings-reference.md#axscreenreader) is `true`. The [`--ax-screen-reader`](cli-reference.md#cli-flags) flag takes precedence. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env). Requires Claude Code v2.1.181 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_AX_STARTUP_QUIET_MS`                            | In [screen reader mode](accessibility.md), how many milliseconds Claude Code holds the first interface render after the startup confirmation line. Your screen reader can then speak the line in full before new output interrupts it. Default `3000`. Set `0` to render immediately. Claude Code caps the hold at `600000` (10 minutes). Your first keystroke ends the hold early. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env). Requires Claude Code v2.1.217 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR`              | Return to the original working directory after each Bash or PowerShell command in the main session                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS`                    | Timeout in milliseconds for the byte-level streaming idle watchdog; when set, it takes precedence over `CLAUDE_STREAM_IDLE_TIMEOUT_MS` for that watchdog and leaves the event-level watchdog unchanged. Claude Code clamps this variable to between 10 seconds and 30 minutes. Requires Claude Code v2.1.210 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CLIENT_PRESENCE_FILE`                           | Path to a file that an external tool, such as a screen-lock listener, creates when you unlock your screen and deletes when you lock it. While the file exists, Claude Code skips [Remote Control mobile push notifications](remote-control.md#mobile-push-notifications), so you stop getting pushes while you are actively using the computer. When the file is absent or unreadable, notifications are sent as normal. Claude Code checks the file once per push-triggering event rather than polling it. Requires Claude Code v2.1.181 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CODE_ACCESSIBILITY`                             | Set to `1` to keep the native terminal cursor visible and disable the inverted-text cursor indicator. Allows screen magnifiers like macOS Zoom to track cursor position                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD`          | Set to `1` to load memory files from directories specified with `--add-dir`. Loads `CLAUDE.md`, `.claude/CLAUDE.md`, `.claude/rules/*.md`, and `CLAUDE.local.md`. By default, additional directories do not load memory files                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_ALT_SCREEN_FULL_REPAINT`                   | Set to `1` to repaint the entire screen on every frame in [fullscreen rendering](fullscreen.md) instead of sending incremental updates. Use this if fullscreen mode shows stale or misplaced text fragments. Claude Code enables this automatically for background sessions and [agent view](../09-Agents-Patterns/agent-view.md) on Windows                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_CODE_ALWAYS_ENABLE_EFFORT`                      | Set to `1` to send the [effort](model-config.md#adjust-effort-level) parameter with every request, even when Claude Code does not recognize the model ID as effort-capable. Use this when routing through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) or third-party provider that serves models under custom identifiers. Models that reject the effort parameter at the API, including Claude Opus 4.1, Claude Sonnet 4.5, Claude Haiku 4.5, and earlier models, are still excluded so requests do not fail                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `CLAUDE_CODE_API_KEY_HELPER_TTL_MS`                     | Interval in milliseconds at which credentials should be refreshed (when using [`apiKeyHelper`](settings-reference.md#apikeyhelper))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_ARTIFACT_AUTO_OPEN`                        | Set to `0` to stop Claude Code from opening the browser automatically when a new [artifact](artifacts.md#create-an-artifact) is published                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_ARTIFACT_COMMENTS`                         | Set to `0` to stop Claude reading and replying to [comments on an artifact](artifacts.md#collect-comments-on-an-artifact). Has no effect when `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` has [turned artifacts off](artifacts.md#availability). Requires Claude Code v2.1.221 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_CODE_ARTIFACT_COMMENTS_AUTOREACT`               | Set to `0` to stop Claude [replying on its own to comments sent to it](artifacts.md#let-claude-reply-to-comments-on-its-own). Requires Claude Code v2.1.228 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_ARTIFACT_PUBLISH_EDITS`                    | Set to `0` to stop Claude from applying small changes to an [artifact’s](artifacts.md#update-an-artifact) file as part of publishing it. Claude then edits the file with its file-editing tools and publishes it as a separate step. Requires Claude Code v2.1.300 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_ATTRIBUTION_HEADER`                        | Set to `0` to omit the [attribution block](../13-Enterprise-Admin/llm-gateway-protocol.md#system-prompt-attribution-block), which carries the client version and a prompt fingerprint, from the start of the system prompt. Caching on a direct connection to the Anthropic API is unaffected either way. In some direct-connection setups, Claude Code keeps the block on [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) classifier requests even when you set `0`. In [System prompt attribution block](../13-Enterprise-Admin/llm-gateway-protocol.md#system-prompt-attribution-block), check which connections and credentials this covers. Before v2.1.181 the block included a per-request token on custom base URLs and Microsoft Foundry connections, so on those versions set it to `0` when your LLM gateway caches on the request body or forwards requests to a third-party provider, or when you connect to Microsoft Foundry directly                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_AUTO_BACKGROUND_WORKER_CHECKIN_SECONDS`    | Removed in v2.1.283. Use `CLAUDE_CODE_WORKER_CHECKIN_SCHEDULE` instead                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE_CODE_AUTO_COMPACT_WINDOW`                       | Set the auto-compact window, how full the context gets before compaction, from `100000` to `1000000` tokens. Suffixed values such as `200k` require v2.1.304 or later. For precedence over the other ways to set the window and the effect on the status line’s `used_percentage`, see [Set the auto-compact window](model-config.md#set-the-auto-compact-window)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_AUTO_CONNECT_IDE`                          | Override automatic [IDE connection](../03-IDE-Integrations/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`](settings-reference.md#autoconnectide) global config setting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_AUTO_MODE_MODEL`                           | Sets the model for the classifier requests Claude Code sends in [auto mode](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](permission-modes.md#choose-the-classifier-model). Requires Claude Code v2.1.302 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE_CODE_AUTO_MODE_SERVER`                          | Controls whether Claude Code asks the server to [review auto mode actions](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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `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`](errors.md#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](claude-platform-on-aws.md), and the [Mantle endpoint](amazon-bedrock.md#use-the-mantle-endpoint). See [credential caching and resolution timeout](amazon-bedrock.md#credential-caching-and-resolution-timeout). Requires Claude Code v2.1.207 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_BASH_EDIT_DIFF`                            | Set to `0` to turn off the [diff of the files that changed while a Bash command ran](../07-Hooks/hooks.md#bash), or `1` to record it in every permission mode. Takes precedence over the [`bashEditDiffEnabled`](settings-reference.md#basheditdiffenabled) setting. Requires Claude Code v2.1.269 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `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](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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_BRIDGE_SESSION_ID`                         | Set automatically in Bash tool and [hook command](../07-Hooks/hooks.md) subprocesses while the session has an active [Remote Control](remote-control.md) connection, and removed when the connection ends. The value is the session’s ID in `session_` form, the same identifier that appears in the session’s `claude.ai/code` URL, so a script can link back to the session that ran it. Requires Claude Code v2.1.199 or later. In [cloud sessions](claude-code-on-the-web.md), read `CLAUDE_CODE_REMOTE_SESSION_ID` instead                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_BS_AS_CTRL_BACKSPACE`                      | Set to `0` to make Claude Code read the `0x08` byte, also written `^H`, as plain Backspace, or `1` to read it as Ctrl+Backspace. Either value replaces the platform default. By default, Claude Code reads it as Ctrl+Backspace on Windows, except when `TERM_PROGRAM` is `mintty` or `TERM` is `cygwin`, and as plain Backspace on macOS and Linux. Set `0` in a Windows terminal where [Backspace deletes a whole word](terminal-config.md#fix-backspace-deleting-a-whole-word-on-windows)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_CODE_CERT_STORE`                                | Comma-separated list of CA certificate sources for TLS connections. `bundled` is the Mozilla CA set shipped with Claude Code. `system` is the operating system trust store, read only on runtimes with `tls.getCACertificates`: the native binary, or Node 22.15 or later for npm installs. See [CA certificate store](../13-Enterprise-Admin/network-config.md#ca-certificate-store). Default is `bundled,system`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_CHILD_SESSION`                             | Set to `1` in subprocesses Claude Code spawns via the Bash, PowerShell, and Monitor tools, [hook](../07-Hooks/hooks.md) commands, and [status line](statusline.md) commands. Not set for stdio [MCP server](../06-MCP-Tools/General/mcp.md) subprocesses, which are long-lived and outlive the session that spawned them. Unlike `CLAUDECODE`, this is only set by Claude Code itself when it launches a subprocess and not by IDE extensions, so it reliably distinguishes a nested session from a top-level `claude` launched in an IDE-integrated terminal. A nested interactive `claude` TUI started this way is automatically excluded from `--resume`, `--continue`, up-arrow history, and the `claude agents` list. Non-interactive `claude -p` sessions still persist. Set `CLAUDE_CODE_FORCE_SESSION_PERSISTENCE=1` to override this exclusion. Requires Claude Code v2.1.172 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_CLIENT_CERT`                               | Path to client certificate file for mTLS authentication                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_CLIENT_KEY`                                | Path to client private key file for mTLS authentication                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_CLIENT_KEY_PASSPHRASE`                     | Passphrase for encrypted CLAUDE_CODE_CLIENT_KEY (optional)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_CONNECT_TIMEOUT_MS`                        | Removed in v2.1.186 and now a no-op. Previously set a separate timeout for the connect, TLS, and response-header phase of a streaming API request. Use `API_TIMEOUT_MS` instead. For the response-header phase of a streaming request, see `CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `CLAUDE_CODE_DEBUG_LOGS_DIR`                            | Override the debug log file path. Despite the name, this is a file path, not a directory. Requires debug mode to be enabled separately via `--debug`, `/debug`, or the `DEBUG` environment variable: setting this variable alone does not enable logging. The [`--debug-file`](cli-reference.md#cli-flags) flag does both at once. Defaults to `~/.claude/debug/<session-id>.txt`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_DEBUG_LOG_LEVEL`                           | Minimum log level written to the debug log file. Values: `verbose`, `debug` (default), `info`, `warn`, `error`. Set to `verbose` to include high-volume diagnostics like full status line command output, or raise to `error` to reduce noise                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_DISABLE_1M_CONTEXT`                        | Set to `1` to turn off [1M context window](model-config.md#extended-context) support. Claude Code removes `[1m]` model variants from the model picker and holds models that run with the 1M window by default to a 200K window. See [Turn off 1M context](model-config.md#turn-off-1m-context). Useful for enterprise environments with compliance requirements. For its role in correcting the window for an unrecognized `[1m]` model ID, see [Correct the window for a gateway or custom model ID](model-config.md#correct-the-window-for-a-gateway-or-custom-model-id)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING`                 | Set to `1` to disable [adaptive reasoning](model-config.md#adjust-effort-level) on Opus 4.6 and Sonnet 4.6 and fall back to the fixed thinking budget controlled by `MAX_THINKING_TOKENS`. Has no effect on [Fable models](model-config.md#extended-thinking), Sonnet 5 and later, Haiku 5.5, or Opus 4.7 and later, which always use adaptive reasoning                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `CLAUDE_CODE_DISABLE_ADVISOR_TOOL`                      | Set to `1` to disable the [advisor tool](advisor.md). The `/advisor` command becomes unavailable, any configured `advisorModel` is ignored, and the `--advisor` flag is accepted but has no effect, so existing scripts that pass it continue to work without errors                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_DISABLE_AGENT_VIEW`                        | Set to `1` to turn off [background agents and agent view](../09-Agents-Patterns/agent-view.md): `claude agents`, `--bg`, `/background`, and the on-demand supervisor. Equivalent to the [`disableAgentView`](settings-reference.md#disableagentview) setting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN`                  | Set to `1` to disable [fullscreen rendering](fullscreen.md) and use the classic main-screen renderer. The conversation stays in your terminal’s native scrollback so `Cmd+f` and tmux copy mode work as usual. Takes precedence over `CLAUDE_CODE_NO_FLICKER` and the [`tui`](settings-reference.md#tui) setting. You can also switch with `/tui default`. Does not apply to background sessions opened from [agent view](../09-Agents-Patterns/agent-view.md), which always use fullscreen rendering                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_DISABLE_ARTIFACT`                          | Set to `1` to turn off the [Artifact](artifacts.md) tool, which publishes session output as a private web page on claude.ai. Once you set it, no settings file turns the tool back on. To turn the tool off from a settings file instead, set [`enableArtifact`](settings-reference.md#enableartifact) to `false`; the deprecated [`disableArtifact`](settings-reference.md#disableartifact) key also turns it off                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `CLAUDE_CODE_DISABLE_ATTACHMENTS`                       | Set to `1` to disable attachment processing. File mentions with `@` syntax are sent as plain text instead of being expanded into file content. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CODE_DISABLE_AUTH_REFRESH_LOCK`                 | Set to `1` to make a Claude Code process run its [`gcpAuthRefresh`](settings-reference.md#gcpauthrefresh) or [`awsAuthRefresh`](settings-reference.md#awsauthrefresh) command itself instead of waiting while another process runs it. Requires Claude Code v2.1.286 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_DISABLE_AUTO_MEMORY`                       | Set to `1` to disable [auto memory](memory.md#auto-memory). Set to `0` to force auto memory on even when `--bare` mode or [`autoMemoryEnabled: false`](settings-reference.md#automemoryenabled) would otherwise disable it. When disabled, Claude does not create or load auto memory files                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_DISABLE_BACKGROUND_TASKS`                  | Set to `1` to disable all background task functionality, including the `run_in_background` parameter on Bash and subagent tools, auto-backgrounding, and the Ctrl+B shortcut                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_DEFAULT`      | Set to `1` to stop Claude Code from treating an [Amazon Bedrock](amazon-bedrock.md) streaming response with a missing or empty `Content-Type` header as Amazon Bedrock’s binary event stream. By default, Claude Code assumes a gateway dropped the header from an otherwise unmodified response, so it decodes the body and streaming keeps working. Set this only for a gateway that also re-emits the stream as server-sent events; Claude Code then reads the header-less body as server-sent events instead. Requires Claude Code v2.1.239 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_GUARD`        | Set to `1` to skip the check that an [Amazon Bedrock](amazon-bedrock.md) streaming response carries the `application/vnd.amazon.eventstream` content-type. Without this variable, when a response carries a different content-type, Claude Code fails the request with an error naming that type, which means a [gateway or proxy is transforming the response](amazon-bedrock.md#streaming-errors-behind-a-gateway-or-proxy). Configure the gateway to forward the `Content-Type` header and body unmodified rather than setting this variable. Requires Claude Code v2.1.208 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF`                   | Set to `1` to stop a [background session’s](../09-Agents-Patterns/agent-view.md) in-flight work when the [supervisor](../09-Agents-Patterns/agent-view.md#the-supervisor-process) stops, restarts, or updates that session’s process, instead of handing it to the session’s next process. That work is the session’s running background shell commands and dynamic workflows, plus background subagents as of v2.1.198. Affects only that handoff: backgrounding a session with `←` or [`/background`](../09-Agents-Patterns/agent-view.md#from-inside-a-session) still carries in-flight background work over. Requires Claude Code v2.1.196 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP`            | Set to `1` to stop Claude Code from terminating [background shell commands](interactive-mode.md#background-bash-commands) under memory pressure. By default, on macOS and Linux, Claude Code terminates background shells when the operating system reports critical memory pressure and the session has been idle for 30 minutes with no turn or subagent running. Windows has no memory-pressure signal, so this variable has no effect there. Requires Claude Code v2.1.193 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_DISABLE_BUNDLED_SKILLS`                    | Set to `1` to disable the [skills](../08-Plugins-Skills/skills.md) and workflows included with Claude Code: bundled skills and workflows are removed entirely, while built-in commands like `/init` stay typable but are hidden from the model. `/doctor` stays typable like the built-in commands; hide it with `DISABLE_DOCTOR_COMMAND` instead. Skills from plugins, `.claude/skills/`, and `.claude/commands/` are unaffected. Equivalent to the [`disableBundledSkills`](settings-reference.md#disablebundledskills) setting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CODE_DISABLE_CFC_PROMPT`                        | Set to `1` to keep the [Claude in Chrome](../03-IDE-Integrations/chrome.md) browser tools available while omitting the Chrome section of the system prompt and the `/claude-in-chrome` [bundled skill](../08-Plugins-Skills/skills.md#bundled-skills). For hosts that embed Claude Code and supply their own browser guidance. Requires Claude Code v2.1.257 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_DISABLE_CLAUDE_MDS`                        | Set to `1` to prevent loading any CLAUDE.md memory files into context, including user, project, and auto memory files                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_DISABLE_CRON`                              | Set to `1` to disable [session-scoped scheduled tasks](scheduled-tasks.md). The `/loop` skill and cron tools become unavailable and any already-scheduled tasks stop firing, including tasks that are already running mid-session                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_DISABLE_DANGEROUS_RM_TIMEOUT`              | Set to `1` to turn off the time limit on [critical-path removal](permission-modes.md#critical-paths) prompts. In `auto` mode Claude Code then sends these removals to the classifier instead, and in `bypassPermissions` mode the prompt waits for your answer. Set it in the environment that launches Claude Code, since Claude Code ignores a copy delivered through a settings `env` block. Requires Claude Code v2.1.281 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS`                | Set to `1` to strip pre-release `anthropic-beta` request headers, the body fields that pair with them, and beta tool-schema fields such as `defer_loading` and `eager_input_streaming` from API requests. Use this when a proxy gateway rejects requests with an `Unexpected value(s)` error for the `anthropic-beta` header or an `Extra inputs are not permitted` error. [Disable pre-release capabilities](../13-Enterprise-Admin/llm-gateway-protocol.md#disable-pre-release-capabilities) lists what the variable removes, including [MCP tool search](../06-MCP-Tools/General/mcp.md#scale-with-mcp-tool-search), and what Claude Code keeps sending                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_DISABLE_EXPLORE_PLAN_AGENTS`               | Set to `1` to disable the built-in [Explore and Plan subagents](../09-Agents-Patterns/sub-agents.md#built-in-subagents). Claude explores with its search tools or the general-purpose subagent instead, and [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode) reads files directly rather than launching Explore and Plan agents. Custom subagents named `Explore` or `Plan` are unaffected. To remove every built-in subagent type in the Agent SDK or non-interactive mode, use `CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS` instead. Requires Claude Code v2.1.198 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_DISABLE_FAST_MODE`                         | Set to `1` to disable [fast mode](fast-mode.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY`                   | Set to `1` to disable the “How is Claude doing?” session quality surveys. Surveys are also disabled when `DISABLE_TELEMETRY`, `DO_NOT_TRACK`, or `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` is set, unless `CLAUDE_CODE_ENABLE_FEEDBACK_SURVEY_FOR_OTEL` opts back in. To set a sample rate instead of disabling outright, use the [`feedbackSurveyRate`](settings-reference.md#feedbacksurveyrate) setting. See [Session quality surveys](../13-Enterprise-Admin/data-usage.md#session-quality-surveys)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_DISABLE_FILE_CHECKPOINTING`                | Set to `1` to disable file [checkpointing](checkpointing.md). The `/rewind` command will not be able to restore code changes. Overrides the [`fileCheckpointingEnabled`](settings-reference.md#filecheckpointingenabled) setting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_DISABLE_FILE_MENTIONS`                     | Set to `1` to stop Claude Code from expanding [`@` mentions](common-workflows.md#reference-files-and-directories) of files and directories. Claude instead gets the mentioned paths with a note to read them using its file tools. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env). Requires Claude Code v2.1.299 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS`                  | Set to `1` to remove built-in commit and PR workflow instructions and the git status snapshot from Claude’s context. Useful when using your own git workflow skills. Takes precedence over the [`includeGitInstructions`](settings-reference.md#includegitinstructions) setting when set                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `CLAUDE_CODE_DISABLE_INLINE_SHELL_RM_PROMPT`            | Set to `1` to stop Claude Code from reading scripts passed to a shell with `-c`, such as `bash -c 'rm -rf ~'`, for [critical-path](permission-modes.md#removals-inside-nested-commands-and-inline-scripts) removals. Claude Code still checks the shell variable and positional parameter targets in those scripts, and the other critical-path checks keep running. Set it in the environment that launches Claude Code, since Claude Code ignores a copy delivered through a settings `env` block. Requires Claude Code v2.1.288 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_DISABLE_LEGACY_MODEL_REMAP`                | Set to `1` to prevent automatic remapping of Opus 4 and Opus 4.1 to the current Opus version on the Anthropic API. Use when you intentionally want to pin an older model. The remap does not run on Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_DISABLE_MODEL_ACCESS_FALLBACK`             | Set to `1` to stop Claude Code on [Amazon Bedrock](amazon-bedrock.md#when-a-model-is-disabled-mid-session) and [Google Cloud’s Agent Platform](google-vertex-ai.md#when-a-model-is-disabled-mid-session) from switching to an older model when your account loses access to a session’s model mid-session; the refused request fails at once instead. A [fallback model chain](model-config.md#fallback-model-chains) you configure still switches on that refusal, and the [startup model checks](amazon-bedrock.md#startup-model-checks) still fall back at launch. Requires Claude Code v2.1.285 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `CLAUDE_CODE_DISABLE_MOUNTED_DRIVE_RM_PROMPT`           | Set to `1` to turn off the [mounted drive prompt](permission-modes.md#the-mounted-drive-prompt) for paths such as `/Volumes/USB`. [Set it in the environment that launches Claude Code](#set-variables-in-your-shell), because Claude Code [ignores it in a settings `env` block](settings-reference.md#variables-claude-code-ignores-in-env). Requires Claude Code v2.1.304 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_DISABLE_MOUSE`                             | Set to `1` to disable mouse tracking in [fullscreen rendering](fullscreen.md). Keyboard scrolling with `PgUp` and `PgDn` still works. Use this to keep your terminal’s native copy-on-select behavior                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_DISABLE_MOUSE_CLICKS`                      | Set to `1` to disable click, drag, and hover handling in [fullscreen rendering](fullscreen.md) while keeping mouse-wheel scrolling. Use this when you want wheel scroll to work inside Claude Code but don’t want clicks to position the cursor, expand tool output, or open links. `CLAUDE_CODE_DISABLE_MOUSE` takes precedence when both are set. Requires Claude Code v2.1.195 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `CLAUDE_CODE_DISABLE_MTLS_RELOAD_ON_STALE_CONNECTION`   | Set to `1` to stop Claude Code from re-reading the [mTLS client certificate and key](../13-Enterprise-Admin/network-config.md#mtls-authentication) when an API request fails with a connection-level error, such as a connection reset or a TLS handshake error. With the reload disabled, Claude Code loads rotated files only when it next applies settings or at the next startup. Requires Claude Code v2.1.232 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`              | Set to any non-empty value, such as `1`, to disable nonessential network traffic: auto-updates, telemetry, error reporting, the `/feedback` command, [Claude-drafted feedback](tools-reference.md#sendfeedback-tool-behavior), release notes, the [PR and MR status badge](interactive-mode.md#pr-review-status) checks, and availability checks such as the [fast mode](fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) check. It also stops the [background runs of plugin `command` sources](../08-Plugins-Skills/plugins-loading.md#when-a-command-source-re-runs), which are local commands rather than network traffic, because they can trigger dependency installs. **Setting it to `0` or `false` still disables this traffic**, unlike most on/off variables; unset the variable to allow it again. Also disables feature-flag fetching, which makes [Remote Control](remote-control.md#requirements) and the other [features that need feature-flag fetching](#features-that-need-feature-flag-fetching) unavailable. Official plugin marketplace auto-install isn’t covered; disable it with `CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL`. Doesn’t affect [gateway model discovery](../13-Enterprise-Admin/llm-gateway-connect.md#add-gateway-models-to-the-model-picker), which has its own opt-in |
| `CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK`             | Set to `1` to disable the non-streaming fallback when a streaming request fails mid-stream. Streaming errors propagate to the retry layer instead. Useful when a proxy or gateway causes the fallback to produce duplicate tool execution                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_DISABLE_NOTIFICATION_PRESENCE_CHECK`       | Set to `1` to send the `PushNotification` tool’s desktop notification even while you are typing in or focused on the terminal. By default the tool skips both the desktop notification and the [mobile push](remote-control.md#mobile-push-notifications) when it detects recent keyboard activity or terminal focus. This variable disables only that local check, so the server can still suppress the mobile push when it detects that you are active. Requires Claude Code v2.1.193 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL`  | Set to `1` to disable automatic registration of the official plugin marketplace. Claude Code reads the variable when it is about to register the marketplace, usually during a machine’s first interactive launch. If the variable is set at that point, Claude Code skips the registration permanently. Unsetting the variable later doesn’t undo the skip. Run `claude plugin marketplace add anthropics/claude-plugins-official` to register the marketplace at any time                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`    | Set to `1` to stop Claude Code from running your [`Notification` hooks for unanswered permission requests](../07-Hooks/hooks.md#notification) in sessions where Claude Code sends them to the Agent SDK’s `canUseTool` callback, which is how Claude Desktop and the VS Code extension host Claude Code. Has no effect in terminal sessions. Requires Claude Code v2.1.233 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_DISABLE_POLICY_SKILLS`                     | Set to `1` to skip loading skills from the system-wide managed skills directory. Useful for container or CI sessions that should not load operator-provisioned skills                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_DISABLE_POWERSHELL_CMD_RM_DENY`            | Set to `1` to turn off the [PowerShell tool](tools-reference.md#powershell-tool) check that denies the `cmd` built-ins `rd`, `rmdir`, `del`, and `erase` on a [system path](permission-modes.md#remove-item-in-powershell), such as a drive root or your home directory. Claude Code ignores this variable in a settings file’s `env` block. Requires Claude Code v2.1.283 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_DISABLE_REFUSAL_FALLBACK`                  | Set to `1` to turn off the [automatic model switch when a safety classifier flags a request](model-config.md#automatic-model-fallback), the behavior the [`switchModelsOnFlag`](settings-reference.md#switchmodelsonflag) setting controls                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE_CODE_DISABLE_STRUCTURED_OUTPUTS`                | Set to `1` to stop Claude Code from sending the structured-output `output_config.format` field and the `anthropic-beta` value that pairs with it, for an [LLM gateway](../13-Enterprise-Admin/llm-gateway-protocol.md#feature-pass-through) whose upstream rejects them. This leaves on the other pre-release capabilities that [`CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS`](../13-Enterprise-Admin/llm-gateway-protocol.md#disable-pre-release-capabilities) turns off. Requires Claude Code v2.1.288 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_DISABLE_SUBSTITUTION_RM_PROMPT`            | Set to `1` to turn off the [critical-path](permission-modes.md#critical-paths) check for a recursive `rm` whose target is entirely the output of a command substitution, such as `rm -rf "$(pwd)"`. The other critical-path checks keep running. Set it in the environment that launches Claude Code, since Claude Code ignores a copy delivered through a settings `env` block. Requires Claude Code v2.1.281 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_DISABLE_TERMINAL_TITLE`                    | Set to `1` to disable automatic terminal title updates based on conversation context. This also skips the background small/fast-model request that [generates a session title](sessions.md#name-your-sessions), and turns off [status reports to your terminal](terminal-config.md#see-session-status-in-your-terminal)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `CLAUDE_CODE_DISABLE_THINKING`                          | Set to `1` to omit the `thinking` parameter from API requests entirely. This is a compatibility option for proxies and gateways that reject the parameter. On models that think by default, omitting the parameter means the model may still think. To explicitly disable [extended thinking](../04-API-Reference/Guides/build-with-claude-extended-thinking.md) on the Anthropic API, use `MAX_THINKING_TOKENS=0` instead. Neither variable turns thinking off on Opus 5.5, Sonnet 5.5, Haiku 5.5, or the Fable models, which can’t have thinking turned off. On [third-party providers](third-party-integrations.md), `MAX_THINKING_TOKENS=0` likewise omits the parameter, so the two variables behave the same there                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `CLAUDE_CODE_DISABLE_ULTRAREVIEW_TRUST_CHECK`           | Set to `1` so that [`claude ultrareview`](ultrareview.md#trust-the-folder-before-the-review-runs) doesn’t exit with `Error: Workspace not trusted` in a folder you haven’t trusted when it can’t ask you to trust it, such as in CI. Set it in the environment that launches Claude Code, not a settings `env` block, and only where every such run starts in a folder you trust. Runs that can ask still ask. Requires Claude Code v2.1.309 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_DISABLE_UNKNOWN_MODEL_WINDOW_ENFORCEMENT`  | Set to `1` to skip proactive [auto-compaction](../17-Billing-Plans/costs.md#reduce-token-usage) when Claude Code doesn’t recognize the model ID, such as an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) alias. Without this variable, Claude Code compacts at the context window it assumes for the ID. `CLAUDE_CODE_MAX_CONTEXT_TOKENS` can correct the assumed window instead; see [Correct the window for a gateway or custom model ID](model-config.md#correct-the-window-for-a-gateway-or-custom-model-id) for when each variable applies. Requires Claude Code v2.1.223 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE_CODE_DISABLE_VIRTUAL_SCROLL`                    | Set to `1` to disable virtual scrolling in [fullscreen rendering](fullscreen.md) and render every message in the transcript. Use this if scrolling in fullscreen mode shows blank regions where messages should appear                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_DISABLE_WEB_FETCH`                         | Set to `1` to turn off the [WebFetch](tools-reference.md#webfetch-tool-behavior) tool. The [WebSearch](tools-reference.md#websearch-tool-behavior) tool stays available. Requires Claude Code v2.1.285 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_DISABLE_WINDOWS_SHELL_LAUNCHER`            | Set to `1` to start [PowerShell tool](tools-reference.md#powershell-tool) commands on Windows directly instead of through the `cmd.exe` launcher. By default, the launcher lets a PowerShell command [running in the background](tools-reference.md#background-commands) [carry over to the session’s next process](../09-Agents-Patterns/agent-view.md#the-supervisor-process), such as when you [background the session](../09-Agents-Patterns/agent-view.md#from-inside-a-session). If you set the variable, a backgrounded PowerShell command stops when the session’s process exits. Bash commands aren’t affected. Requires Claude Code v2.1.269 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_DISABLE_WORKFLOWS`                         | Set to `1` to disable [workflows](workflows.md#turn-workflows-off). Equivalent to the [`disableWorkflows`](settings-reference.md#disableworkflows) setting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE_CODE_EFFORT_LEVEL`                              | Set the effort level for supported models. Values: `low`, `medium`, `high`, `xhigh`, `max`, or `auto` to use the model default. Available levels depend on the model. Takes precedence over `--effort`, `/effort`, and the `modelSettings` and `effortLevel` settings. A [`maxEffortLevel`](settings-reference.md#maxeffortlevel) cap still applies. See [Adjust effort level](model-config.md#adjust-effort-level)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS`                 | Set to `1` to add [`session_state_changed`](../05-Agent-SDK/agent-sdk-typescript.md#sdksessionstatechangedmessage) messages, which carry the session’s state, to the message stream. Requires either the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) or `--print`, `--output-format stream-json`, and `--verbose`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `CLAUDE_CODE_ENABLE_AUTO_MODE`                          | Accepted for compatibility with older releases and has no effect. Auto mode is available by default on every provider, including Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and signed-in [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sessions. In v2.1.158 through v2.1.206, setting this to `1` was required to make [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) available on those providers                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_ENABLE_AWAY_SUMMARY`                       | Override [session recap](interactive-mode.md#session-recap) availability. Set to `0` to force recaps off regardless of the `/config` toggle. Set to `1` to force recaps on when [`awaySummaryEnabled`](settings-reference.md#awaysummaryenabled) is `false`. Takes precedence over the setting and `/config` toggle                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_ENABLE_BACKGROUND_PLUGIN_REFRESH`          | Set to `1` to refresh plugin state at turn boundaries in [non-interactive mode](headless.md) after a background install completes. Off by default because the refresh changes the system prompt mid-session, which invalidates [prompt caching](prompt-caching.md) for that turn                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_ENABLE_CFC`                                | Set to `1` to start a CLI session with [Chrome integration](../03-IDE-Integrations/chrome.md) on, or `0` to start with it off. Takes precedence over the [`claudeInChromeDefaultEnabled`](settings-reference.md#claudeinchromedefaultenabled) setting. The `--chrome` and `--no-chrome` flags take precedence over both. Claude Code [ignores `1` in project and local settings](../03-IDE-Integrations/chrome.md#project-settings-can%E2%80%99t-turn-on-chrome)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `CLAUDE_CODE_ENABLE_FEEDBACK_SURVEY_FOR_OTEL`           | Set to `1` to route the “How is Claude doing?” session quality survey to your own [OpenTelemetry collector](../13-Enterprise-Admin/monitoring-usage.md) when Anthropic-bound nonessential traffic is blocked. Survey ratings are emitted only as OTEL events to your configured collector. No survey data is sent to Anthropic in this mode. Applies when `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`, `DISABLE_TELEMETRY`, or `DO_NOT_TRACK` is set, and has no effect otherwise. `CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY` and the organization product feedback policy take precedence                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING`        | Controls whether tool call inputs stream from the API as Claude generates them. With this off, a large tool input such as a long file write arrives only after Claude finishes generating it, which can look like it’s hanging. Enabled by default on the Anthropic API. On Amazon Bedrock and Google Cloud’s Agent Platform, enabled per model where the deployed container supports it. Set to `0` to opt out. Set to `1` to force on when routing through a proxy via `ANTHROPIC_BASE_URL`, `ANTHROPIC_VERTEX_BASE_URL`, or `ANTHROPIC_BEDROCK_BASE_URL`. Off by default on Microsoft Foundry and [gateway](../13-Enterprise-Admin/llm-gateway.md) connections                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY`            | Set to `1` to populate the `/model` picker from your gateway’s `/v1/models` endpoint when `ANTHROPIC_BASE_URL` points at an Anthropic-compatible gateway such as LiteLLM, Kong, or an internal proxy. Off by default because gateways backed by a shared API key would otherwise show every user every model the key can access. Discovered models are still filtered by an [`availableModels`](settings-reference.md#availablemodels) allowlist the session receives; deliver the list through [MDM or a managed settings file](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms), since [server-managed delivery is not available on gateway configurations](../13-Enterprise-Admin/server-managed-settings.md#platform-availability)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_ENABLE_OPUS_4_7_FAST_MODE`                 | Removed in v2.1.142, when the [fast mode](fast-mode.md) default moved from Opus 4.6 to Opus 4.7                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION`                  | Set to `false` to turn off prompt suggestions, the grayed-out predictions that appear in your prompt input. Takes precedence over the [`promptSuggestionEnabled`](settings-reference.md#promptsuggestionenabled) setting, which is what the **Prompt suggestions** toggle in `/config` writes. Claude Code also [pauses suggestions while your account is close to or at its usage limit](interactive-mode.md#when-claude-code-skips-suggestions). Set to `true` to keep that pause from applying until you reach the limit. Requires Claude Code v2.1.238 or later. See [Prompt suggestions](interactive-mode.md#prompt-suggestions)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_ENABLE_SHARE_BUNDLE`                       | Set to `1` to make [`/share`](commands.md#all-commands) save its report and the whole session transcript to a [local archive under `~/.claude/feedback-bundles/`](../13-Enterprise-Admin/data-usage.md#telemetry-services) instead of sending the report to Anthropic. If your organization’s policy turns off `/share`, you can’t turn it back on with this variable. Requires Claude Code v2.1.299 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_CODE_ENABLE_TASKS`                              | Selects which task-tracking tools Claude Code provides in [sessions that have them](tools-reference.md#task-tool-availability). By default, Claude Code provides the Task tools `TaskCreate`, `TaskUpdate`, `TaskGet`, and `TaskList`. Set to `0` to get the legacy `TodoWrite` tool instead. See [Task list](interactive-mode.md#task-list)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CODE_ENABLE_TELEMETRY`                          | Set to `1` to enable OpenTelemetry data collection for metrics and logging. Required before configuring OTel exporters. Set it in your shell, user settings, or managed settings. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env). See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CODE_ENABLE_TODO_TOOLS`                         | Set to `1` to get the task-tracking tools on every model. Without it, Claude Code provides them by default only on the models listed under [Task tool availability](tools-reference.md#task-tool-availability). `CLAUDE_CODE_ENABLE_TASKS` still selects the Task tools or `TodoWrite`. Requires Claude Code v2.1.233 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`                  | Set to `1` to enable [agent teams](../09-Agents-Patterns/agent-teams.md). Agent teams are experimental and disabled by default                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `CLAUDE_CODE_EXTRA_BODY`                                | JSON object to merge into the top level of every API request body. 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](../09-Agents-Patterns/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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `CLAUDE_CODE_FILE_READ_MAX_OUTPUT_TOKENS`               | Override the default token limit for [file reads](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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_FORCE_STRIKETHROUGH`                       | Set to `1` to force strikethrough rendering for `~~text~~` in Claude’s responses when your terminal supports it but is not auto-detected, such as over SSH without `TERM_PROGRAM` forwarded. Without this, undetected terminals show the literal `~~` markers instead of rendering the text as strikethrough. Requires Claude Code v2.1.186 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `CLAUDE_CODE_FORCE_SYNC_OUTPUT`                         | Set to `1` to force-enable DEC private mode 2026 [synchronized output](https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036) when your terminal supports it but is not auto-detected. Useful for emulators such as Emacs `eat` that implement BSU/ESU but do not reply to the capability probe. Has no effect under tmux. Unlike `CLAUDE_CODE_NO_FLICKER`, which switches to [fullscreen rendering](fullscreen.md), this doesn’t change the renderer                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_FORCE_TERMINAL_IMAGES`                     | Set to `1` to draw [mod `Image` elements](../08-Plugins-Skills/plugins-mods-reference.md#elements) as pictures when your terminal draws kitty graphics protocol images with Unicode placeholders and you still see an `Image`’s dimmed `alt` text. See [which terminals draw an `Image`](../08-Plugins-Skills/plugins-mods-gallery.md#image-and-client) and why this variable doesn’t help inside tmux or screen                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_CODE_FORK_SUBAGENT`                             | Controls fork mode, which is on by default and lets Claude start [forks](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation) on its own. While fork mode is on, Claude also can’t [wait for a subagent](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) in interactive terminal, VS Code, or desktop sessions on your machine. Set to `0` to turn fork mode off. For versions, see [Turn fork mode off](../09-Agents-Patterns/sub-agents.md#turn-fork-mode-on-or-off)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `CLAUDE_CODE_FORWARD_SUBAGENT_TEXT`                     | Set to `1` to emit [subagent](../09-Agents-Patterns/sub-agents.md) text and thinking blocks in `claude -p --output-format stream-json` output, the same behavior as the [`--forward-subagent-text`](cli-reference.md#cli-flags) flag. Use the variable when a harness invokes `claude` and can’t pass the flag itself. Unlike the flag, which exits with an error outside non-interactive mode with stream-json output, the variable is ignored there so that nested invocations keep working when it’s set process-wide. Requires Claude Code v2.1.211 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE_CODE_GATEWAY_HINT_HEADERS`                      | Set to `1` to send the [gateway hint headers](../13-Enterprise-Admin/llm-gateway-protocol.md#gateway-hint-headers), such as `x-claude-code-request-class` and `x-claude-code-compaction`, on a custom proxy or a third-party provider such as Amazon Bedrock or Claude Platform on AWS. Set to `0` to stop sending them on every connection, including a direct connection to the Anthropic API, where Claude Code sends them by default. Requires Claude Code v2.1.273 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_GATEWAY_MODEL_DISCOVERY_TIMEOUT_MS`        | Timeout in milliseconds for the [gateway model discovery](../13-Enterprise-Admin/llm-gateway-protocol.md#model-discovery) request that `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY` turns on (default: `3000`). Raise it when your gateway needs longer than three seconds to answer `/v1/models` at startup. Takes plain digits only; `0`, negative values, and other spellings keep the default. Requires Claude Code v2.1.269 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CODE_GIT_BASH_PATH`                             | Windows only: path to the Git Bash executable (`bash.exe`). Use when Git Bash is installed but not in your PATH. If the path doesn’t exist or the file isn’t named `bash.exe`, `sh.exe`, `bash`, or `sh`, Claude Code ignores the variable and auto-detects Git Bash as if it were unset, logging a warning visible with `--debug`. Before v2.1.219, Claude Code exited at startup when the path didn’t exist, and used any existing file as the shell without checking that it was bash or sh. See [Windows setup](../01-Getting-Started/setup.md#set-up-on-windows)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_GLOB_HIDDEN`                               | Set to `false` to exclude dotfiles from results when Claude invokes the [Glob tool](tools-reference.md#glob-tool-behavior). Included by default. Does not affect `@` file autocomplete, `ls`, Grep, or Read                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_GLOB_NO_IGNORE`                            | Set to `false` to make the [Glob tool](tools-reference.md#glob-tool-behavior) respect `.gitignore` patterns. By default, Glob returns all matching files including gitignored ones. Does not affect `@` file autocomplete, which has its own [`respectGitignore` setting](settings-reference.md#respectgitignore)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_GLOB_TIMEOUT_SECONDS`                      | Timeout in seconds for Glob tool file discovery. Defaults to 20 seconds on most platforms and 60 seconds on WSL                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_GOAL_CHECKIN_MINUTES`                      | How many minutes background work can keep an active goal waiting before Claude Code [asks Claude to check on it](goal.md#background-work-defers-evaluation). Default `30`. Set `0` to turn check-ins off. Give whole minutes in plain digits, at most `10080`, which is one week. Claude Code treats any other value as unset and uses the default. Requires Claude Code v2.1.234 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `CLAUDE_CODE_GZIP_REQUEST_BODIES`                       | Set to `0` to turn off gzip compression of Claude API, telemetry, and [artifact](artifacts.md) publish request bodies sent to `api.anthropic.com`. By default, Claude Code compresses large request bodies on direct connections and skips compression when you send requests through a proxy, configure a client certificate, or set `NODE_EXTRA_CA_CERTS`. Use `0` if a [TLS-inspecting proxy](../13-Enterprise-Admin/network-config.md#ca-certificate-store) that Claude Code can’t detect mishandles compressed requests                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_HIDE_CWD`                                  | Set to `1` to hide the working directory in the startup logo. Useful for screenshares or recordings where the path exposes your OS username                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_IDE_HOST_OVERRIDE`                         | Override the host address used to connect to the IDE extension. By default Claude Code auto-detects the correct address, including WSL-to-Windows routing                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_IDE_SKIP_AUTO_INSTALL`                     | Set to `1` to skip auto-installation of IDE extensions. Equivalent to setting [`autoInstallIdeExtension`](settings-reference.md#autoinstallideextension) to `false`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_IDE_SKIP_VALID_CHECK`                      | Set to `1` to skip validation of IDE lockfile entries during connection. Use when auto-connect fails to find your IDE despite it running                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS`                   | Context size, in tokens, at which [idle compaction](settings-reference.md#idlecompaction) applies to a conversation (default: `200000`). Accepts a positive whole number, and anything else is ignored. Values below `100000` are raised to `100000`, the lowest threshold. Idle compaction is on by default for conversations that meet its conditions. To turn it off, set `idleCompaction` to `false`. Requires Claude Code v2.1.290 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS`                  | How many [subagents](../09-Agents-Patterns/sub-agents.md#concurrent-subagent-limit) can be running in one session before the Agent tool refuses to spawn another (default: 20). Accepts a positive whole number in plain digits; anything else is ignored, so the variable can adjust the cap but can’t disable it. Requires Claude Code v2.1.217 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_MAX_CONTEXT_TOKENS`                        | Override the context window size Claude Code assumes for the active model. As of v2.1.193, how it applies depends on how Claude Code resolves the model ID; see [Correct the window for a gateway or custom model ID](model-config.md#correct-the-window-for-a-gateway-or-custom-model-id). Use this when routing to a model through `ANTHROPIC_BASE_URL` whose context window does not match the built-in size for its name                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH`                | Maximum length in characters of MCP tool descriptions and MCP server instructions that Claude Code sends to the model. The value you set replaces both [default limits](../06-MCP-Tools/General/mcp.md#for-mcp-server-authors): 4096, and 16384 for the description of a tool that Claude loads through tool search. Accepts a positive whole number in plain digits. Anything else is ignored and the defaults apply. Requires Claude Code v2.1.280 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_MAX_OUTPUT_TOKENS`                         | Set the maximum number of output tokens for most requests. Defaults and caps vary by model; see [max output tokens](../20-Models/about-claude-models-overview.md#latest-models-comparison). Claude Code lowers a value above a model’s cap to the cap. For a model ID Claude Code can’t resolve to a model it knows, the default is 32000 and the cap is 128000. Increasing this value reduces the effective context window available before [auto-compaction](../17-Billing-Plans/costs.md#reduce-token-usage) triggers                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `CLAUDE_CODE_MAX_RETRIES`                               | Override the number of times to retry failed API requests (default: 10). Retrying can stop earlier on `529` overloaded errors. For example, with an API key on an Opus model, it stops at the third `529` and shows [Repeated 529 Overloaded errors](errors.md#api-error-repeated-529-overloaded-errors). If you set a [fallback model](settings-reference.md#fallbackmodel), Claude Code switches to that model rather than showing the error. Capped at 15 as of v2.1.186; as of v2.1.199, `CLAUDE_CODE_RETRY_WATCHDOG` raises the default and removes the cap. For unattended sessions that need to wait through longer outages, set `CLAUDE_CODE_RETRY_WATCHDOG` instead                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION`                 | Removed in v2.1.224 and now a no-op. Previously capped the total number of [subagents](../09-Agents-Patterns/sub-agents.md) Claude could spawn with the Agent tool in one session (default: 200); spawning past the cap failed with `Subagent spawn limit reached`. The [concurrent subagent limit](../09-Agents-Patterns/sub-agents.md#concurrent-subagent-limit) and the [depth limit](../09-Agents-Patterns/sub-agents.md#let-subagents-spawn-their-own-subagents) still apply                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH`                  | Number of [subagent layers](../09-Agents-Patterns/sub-agents.md#let-subagents-spawn-their-own-subagents) allowed below the main conversation (default: 3). At the default, subagents can spawn their own subagents, and a subagent at the third layer can’t spawn further; set `1` to turn nesting off. In v2.1.217 through v2.1.218, the default was 1, so a subagent couldn’t spawn its own unless you raised the limit; v2.1.219 raised the default to 3. Accepts a positive whole number in plain digits; anything else is ignored, so the limit can be adjusted but not removed. Requires Claude Code v2.1.217 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_MAX_TURNS`                                 | Cap the number of agentic turns when no explicit limit is passed. Equivalent to passing [`--max-turns`](cli-reference.md#cli-flags), which takes precedence when both are set. A value that is not a positive integer is rejected at startup with an error rather than treated as no cap                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION`              | Cap on [WebSearch](tools-reference.md#session-search-limit) calls (default: 200). When Claude reaches the cap, further WebSearch calls return a notice telling it to continue with the information it already gathered and say so in its answer. Accepts a positive whole number with no upper bound. Anything else is ignored and the default applies, so the cap can be raised but not turned off. Requires Claude Code v2.1.212 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_MCP_ALLOWLIST_ENV`                         | Set to `1` to spawn stdio MCP servers with only a safe baseline environment plus the server’s configured `env`, instead of inheriting your shell environment                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS`                    | Elapsed time in milliseconds before a still-running MCP tool call [moves to a background task](../06-MCP-Tools/General/mcp.md#automatic-backgrounding-of-long-tool-calls) (default: 120000, or 2 minutes). Set to `0` to turn automatic backgrounding off. Requires Claude Code v2.1.212 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_MCP_STARTUP_WAIT_MS`                       | How long in milliseconds the first turn of a [non-interactive](headless.md) session waits for MCP servers that are still connecting, in place of the default [first-turn wait](../05-Agent-SDK/agent-sdk-mcp.md#connection-timing). In a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments-configuration.md#connection-timing), it changes only how long the wait lasts. Some servers keep a wait of their own regardless of the value; [Connection timing](../05-Agent-SDK/agent-sdk-mcp.md#connection-timing) lists them. Set to `0` to skip the wait for every other server. Requires Claude Code v2.1.274 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT`                     | Idle timeout in milliseconds for MCP tool calls. When a stdio, HTTP, SSE, WebSocket, or [claude.ai connector](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) MCP server sends no response and no progress notification for this long, the tool call aborts with an error instead of waiting for the overall `MCP_TOOL_TIMEOUT`. Overrides the per-transport defaults of 300000 (5 minutes) for network servers and 1800000 (30 minutes) for stdio servers. Set to `0` to disable the idle check. Values below 1000 are raised to one second, and the value is capped at the effective `MCP_TOOL_TIMEOUT`. A per-server `timeout` in `.mcp.json` of at least 1000 raises that server’s idle window to at least the `timeout` value. Doesn’t apply to IDE servers or SDK in-process servers. Requires Claude Code v2.1.187 or later. Before v2.1.203, stdio servers were exempt from the idle timeout                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_MESSAGING_SOCKET`                          | Set by Claude Code, not by you: in sessions that bind an [inbox socket](cross-session-messaging.md#the-sessions-inbox-socket), Claude Code exports that socket’s path to hooks and Bash commands when it binds the socket. In a session that starts with messaging on, Claude Code binds the socket before any hook runs. Other sessions on the machine deliver messages to this path. Each session exports its own socket rather than one inherited from a parent, and messages arriving on it go through the session’s [inbound controls](cross-session-messaging.md#control-inbound-messages). Settings `env` blocks can’t set it. Requires Claude Code v2.1.224 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CODE_MESSAGING_TOKEN`                           | Set by Claude Code, not by you: in sessions that bind an [inbox socket](cross-session-messaging.md#the-sessions-inbox-socket), Claude Code exports this per-session token to hooks and Bash commands alongside `CLAUDE_CODE_MESSAGING_SOCKET`. A script posting to the socket can send `{"type":"auth","token":"<token>"}` as its first line to prove it belongs to the session. On native Windows, Claude Code requires this line and closes any connection that doesn’t open with a valid one. The [own-child rules](cross-session-messaging.md#the-sessions-inbox-socket) say when Claude Code consults the token. Each session exports its own token, never one inherited from a parent session. Settings `env` blocks can’t set it. Requires Claude Code v2.1.228 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_NATIVE_CURSOR`                             | Set to `1` to show the terminal’s own cursor at the input caret instead of a drawn block. The cursor respects the terminal’s blink, shape, and focus settings. Setting `0` reads the same as leaving the variable unset, so it doesn’t bring the drawn block back in a session where the terminal’s own cursor is already on                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_NEW_INIT`                                  | Set to `1` to make `/init` run an interactive setup flow. The flow asks which files to generate, including CLAUDE.md, skills, and hooks, before exploring the codebase and writing them. Without this variable, `/init` generates a CLAUDE.md automatically without prompting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_NONBLOCKING_STDOUT`                        | Set to `1` to write terminal output through a second non-blocking file descriptor, so a terminal that stops reading, such as a paused tmux control-mode pane or a stalled SSH connection, can’t freeze Claude Code mid-session. Applies on macOS, Linux, and WSL when stdout is a terminal. Requires Claude Code v2.1.261 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_CODE_NONSTREAMING_TIMEOUT_RETRIES`              | Limit how many times Claude Code re-sends a [non-streaming request](errors.md#streaming-response-ended-before-any-complete-data-was-received) that times out. With `0`, the request fails on the first timeout. See [Tune retry behavior](errors.md#tune-retry-behavior) for the timeout. Requires Claude Code v2.1.285 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_NO_FLICKER`                                | Set to `1` to enable [fullscreen rendering](fullscreen.md), a research preview that reduces flicker and keeps memory flat in long conversations. Overrides the [`tui`](settings-reference.md#tui) setting; you can also switch with `/tui fullscreen`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_OAUTH_REFRESH_TOKEN`                       | OAuth refresh token for Claude.ai authentication. When set, `claude auth login` is used for non-interactive enterprise sign-in. Requires `CLAUDE_CODE_OAUTH_SCOPES`. Intended for enterprise admin provisioning only                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_OAUTH_SCOPES`                              | Space-separated OAuth scopes the refresh token was issued with, such as `"user:profile user:inference user:sessions:claude_code"`. Required when `CLAUDE_CODE_OAUTH_REFRESH_TOKEN` is set                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_OAUTH_TOKEN`                               | OAuth access token for claude.ai authentication. Alternative to `/login` for SDK and automated environments. Takes precedence over keychain-stored credentials. Generate one with [`claude setup-token`](authentication.md#generate-a-long-lived-token). Unless you run [`/login`](authentication.md#authentication-precedence), Claude Code uses the token you set for the whole session. To replace an expired token, generate a new one and restart                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_CODE_OPUS_4_6_FAST_MODE_OVERRIDE`               | Removed in v2.1.160 and now a no-op. Previously pinned [fast mode](fast-mode.md) to Claude Opus 4.6 instead of the current default. Opus 4.6 no longer supports fast mode                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_OTEL_CONTENT_MAX_LENGTH`                   | Maximum length of content-bearing OpenTelemetry attributes (model responses, tool content, system prompts, raw API bodies), truncation marker included, in UTF-16 code units (default: 61440, i.e. 60 KB). Raise it only if your telemetry backend accepts attribute values larger than 64 KB, or lower it to cut telemetry volume. Requires Claude Code v2.1.214 or later. See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_OTEL_DIAG_STDERR`                          | Set to `1` to write OpenTelemetry exporter diagnostic errors to stderr. By default these errors only appear with `--debug`, so a misconfigured exporter such as a Prometheus port collision otherwise fails silently. Requires Claude Code v2.1.179 or later. See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_OTEL_FLUSH_TIMEOUT_MS`                     | Timeout in milliseconds for flushing pending OpenTelemetry spans (default: 5000). See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS`           | Interval for refreshing dynamic OpenTelemetry headers in milliseconds (default: 1740000 / 29 minutes). See [Dynamic headers](../13-Enterprise-Admin/monitoring-usage.md#dynamic-headers)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `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](../13-Enterprise-Admin/monitoring-usage.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS`            | Starting delay in milliseconds, in place of the default 500, of the exponential backoff between [automatic retries](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](fast-mode.md#handle-rate-limits). Requires Claude Code v2.1.292 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_OVERLOADED_RETRY_MAX_DELAY_MS`             | Ceiling in milliseconds, in place of the default 32000, on the exponential backoff between [automatic retries](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](fast-mode.md#handle-rate-limits). Requires Claude Code v2.1.296 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `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](../01-Getting-Started/setup.md#auto-updates)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `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`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE_CODE_PLUGIN_DIRS`                               | Plugin directories to load for the session, each loaded the way a [`--plugin-dir`](../08-Plugins-Skills/plugins-cli-reference.md#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](../08-Plugins-Skills/plugins-create.md#load-a-directory-or-archive-for-one-session)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_PLUGIN_DIR_WATCH`                          | Controls whether Claude Code reloads a [mod](../08-Plugins-Skills/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](../08-Plugins-Skills/plugins-mods-reference.md#settings-and-environment-variables)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `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](../08-Plugins-Skills/plugins-troubleshooting.md#git-clone-timed-out-after-120s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `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](../08-Plugins-Skills/plugins-troubleshooting.md#marketplace-updates-keep-failing-offline)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `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`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_PLUGIN_SEED_DIR`                           | Path to one or more read-only plugin seed directories, separated by `:` on Unix or `;` on Windows. Use this to bundle a pre-populated plugins directory into a container image. Claude Code registers marketplaces from these directories at startup and uses pre-cached plugins without re-cloning. See [Pre-populate plugins for containers](../08-Plugins-Skills/plugins-org.md#seed-containers-and-ci)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_POWERSHELL_RESPECT_EXECUTION_POLICY`       | Set to `1` to stop Claude Code from passing `-ExecutionPolicy Bypass` when spawning PowerShell for tool calls, hooks, and status line commands, and respect the machine’s effective execution policy instead. By default Claude Code bypasses execution policy at process scope so `.ps1` scripts and module imports work on default-Restricted Windows installs. Process-scope bypass never overrides Group Policy `MachinePolicy` or `UserPolicy` regardless of this setting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS`                  | Ceiling in milliseconds on idle waiting for background work, such as subagents and workflows, after the final turn in [non-interactive mode](headless.md#background-tasks-at-exit) with the `-p` flag. Idle waiting starts over each time Claude takes a turn to handle a background result. Default: `600000`, or 10 minutes. When idle waiting reaches the ceiling, Claude Code stops waiting for the remaining background tasks. A running background command that the main conversation started holds the run open past it. Set to `0` to wait indefinitely. Requires Claude Code v2.1.182 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_PROCESS_WRAPPER`                           | Launch the processes Claude Code starts from its own binary, such as the background service that hosts [agent view](../09-Agents-Patterns/agent-view.md) sessions, through a corporate launcher given as an argv prefix like `/opt/corp/launcher`. Set it in the `env` block of user or [managed settings](../13-Enterprise-Admin/managed-settings.md), not as a shell export, so the detached background service inherits it; project and local settings can’t set it. Equivalent to the [`processWrapper` setting](settings-reference.md#processwrapper), which requires Claude Code v2.1.210 or later; this variable takes precedence when both are set. The VS Code extension configures its own launcher separately through its `claudeProcessWrapper` setting. Ignored on Windows. See [Run Claude Code behind a corporate launcher](../13-Enterprise-Admin/corporate-launcher.md) for the value format, what the launcher covers, and the contract the launcher must satisfy. Requires Claude Code v2.1.208 or later                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_PROJECT_DIR_NAME`                          | Set together with `CLAUDE_CONFIG_DIR` to choose the `projects/` directory name Claude Code stores that session’s transcripts and auto memory under, in place of one derived from the working directory path. For example, starting Claude Code with `CLAUDE_CONFIG_DIR=/srv/tenant-a CLAUDE_CODE_PROJECT_DIR_NAME=work claude` stores them under `/srv/tenant-a/projects/work/`. Claude Code ignores this variable when `CLAUDE_CONFIG_DIR` is unset, and reads it only from the environment you start `claude` from, never from a [settings file `env` block](#in-settings-files). See [Name the project directory yourself](sessions.md#name-the-project-directory-yourself). Requires Claude Code v2.1.234 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_PROMPT_CACHE_TTL`                          | Set `5m` or `1h`, the only values Claude Code accepts, to choose the [prompt cache TTL](prompt-caching.md#cache-lifetime) for the main conversation: your interactive, `-p`, and SDK turns, plus the helpers that run inline with them. Takes precedence over the `promptCacheTtl` setting and over `ENABLE_PROMPT_CACHING_1H`, and `FORCE_PROMPT_CACHING_5M` overrides it. The API bills 1-hour cache writes at a higher rate. Requires Claude Code v2.1.242 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_PROPAGATE_TRACEPARENT`                     | Set to `1` to propagate W3C trace context when `ANTHROPIC_BASE_URL` points at a custom proxy. Propagation covers the `traceparent` header on model and HTTP MCP requests and the `TRACEPARENT` environment variable for Bash, PowerShell, and hook subprocesses. By default, propagation is enabled only when connected directly to the Anthropic API. Added in v2.1.152. See [Traces (beta)](../13-Enterprise-Admin/monitoring-usage.md#traces-beta)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`                  | Set by host platforms that embed Claude Code and manage model provider routing on its behalf. When set, Claude Code ignores provider-selection, endpoint, and authentication variables such as `CLAUDE_CODE_USE_BEDROCK`, `ANTHROPIC_BASE_URL`, and `ANTHROPIC_API_KEY` in settings files, so user settings can’t override the host’s routing. Claude Code also ignores model-selection keys such as `model`, `fallbackModel`, and `modelOverrides` in [managed settings](../13-Enterprise-Admin/managed-settings.md), whichever managed source delivers them, so the host’s model configuration takes precedence over an out-of-date managed model pin. Claude Code also ignores model-selection variables such as `ANTHROPIC_MODEL` and the `ANTHROPIC_DEFAULT_*_MODEL` family in a managed `env` block; an [`availableModels`](model-config.md#restrict-model-selection) allowlist in managed settings still applies unless the host supplies its own. Claude Code also skips the automatic telemetry opt-out it otherwise applies on third-party providers such as Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, and Microsoft Foundry, so telemetry follows the standard `DISABLE_TELEMETRY` opt-out. See [Default behaviors by API provider](../13-Enterprise-Admin/data-usage.md#default-behaviors-by-api-provider)       |
| `CLAUDE_CODE_PROXY_RESOLVES_HOSTS`                      | Set to `1` to allow the proxy to perform DNS resolution instead of the caller. Opt-in for environments where the proxy should handle hostname resolution                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CODE_REMOTE`                                    | Set automatically to `true` when Claude Code is running as a [cloud session](claude-code-on-the-web.md). Read this from a hook or setup script to detect whether you are in a cloud session                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_REMOTE_SESSION_ID`                         | Set automatically in [cloud sessions](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](cloud-environments.md#link-output-back-to-the-session)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `CLAUDE_CODE_RESTRICTED`                                | Set to `1` to start the session in restricted mode, the same as passing [`--restricted`](cli-reference.md#cli-flags). Claude Code ignores this variable in a settings file’s `env` block. Requires Claude Code v2.1.248 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `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](../03-IDE-Integrations/vs-code.md#continue-conversations-after-a-reload)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `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](../09-Agents-Patterns/agent-view.md) session that inherited its conversation from an interactive session. Requires Claude Code v2.1.211 or later                                                                                                                                                                                                                                                                                                                                   |
| `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](../07-Hooks/hooks.md#defer-a-tool-call-for-later) with `-p`. Defaults to `Continue from where you left off.`. An empty string uses the default                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_RETRY_WATCHDOG`                            | Set to `1` for unattended sessions such as eval harnesses, CI jobs, or remote workers. Retries `429` and `529` capacity errors indefinitely instead of failing after `CLAUDE_CODE_MAX_RETRIES` attempts. Claude Code fails at once when a standard-speed request gets a `429` that reports a spend limit or exhausted usage credits, even one from a [gateway spend cap](errors.md#spend-limit-reached) that resets on a schedule. Before v2.1.239, the watchdog retried these indefinitely. For fast mode requests, see [Handle rate limits](fast-mode.md#handle-rate-limits). The watchdog backs off up to 5 minutes between attempts, or until the limit resets when the response carries a rate-limit reset time, so a session that hits a usage limit waits out the remaining window. On v2.1.199 or later it also raises the default retry count for other transient errors, such as server errors, timeouts, and dropped connections, to 300, roughly three hours of backoff, and removes the cap of 15 on `CLAUDE_CODE_MAX_RETRIES` if you set that variable explicitly. Requires Claude Code v2.1.186 or later                                                                                                                                                                                           |
| `CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS`                | Maximum time in milliseconds that each API request spends waiting out `429` and `529` errors when `CLAUDE_CODE_RETRY_WATCHDOG` is set. Once that time is spent, the next such error ends the request. Give a positive whole number in plain digits, such as `1800000` for 30 minutes. When unset, the wait has no limit. Requires Claude Code v2.1.295 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `CLAUDE_CODE_RETRY_WATCHDOG_USAGE_LIMIT_RECHECK_MS`     | Minimum interval in milliseconds between checks of whether a [usage limit](errors.md#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 a whole number in plain digits from `60000`, one minute, to `10800000`, three hours. Checks are made only for a claude.ai subscription’s session or weekly limit while usage credits aren’t in use, and not while `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` is set. When this variable is unset or its value is outside that range, no checks are made. Requires Claude Code v2.1.305 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_SAFE_MODE`                                 | Set to `1` to start in safe mode: CLAUDE.md, skills, plugins, hooks, MCP servers, custom commands and agents, output styles, workflows, custom themes, custom keybindings, status line and file-suggestion commands, LSP servers, and auto memory do not load, for troubleshooting a broken configuration. Managed settings policy still applies, including policy-configured hooks, status line, and file-suggestion commands; managed plugins, managed skills, managed CLAUDE.md, and policy-configured MCP servers do not. Equivalent to passing [`--safe-mode`](cli-reference.md#cli-flags). Directly spawned child processes inherit the variable                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_SCRIPT_CAPS`                               | JSON object limiting how many times specific scripts may be invoked per session when `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` is set. Keys are substrings matched against the command text; values are integer call limits. For example, `{"deploy.sh": 2}` allows `deploy.sh` to be called at most twice. Matching is substring-based so shell-expansion tricks like `./scripts/deploy.sh $(evil)` still count against the cap. Runtime fan-out via `xargs` or `find -exec` is not detected; this is a defense-in-depth control                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_SCROLL_SPEED`                              | Set the mouse wheel scroll multiplier in [fullscreen rendering](fullscreen.md#mouse-wheel-scrolling). Accepts any positive value up to 20, including fractional values below 1 such as `0.5` to slow accelerated trackpad and wheel scrolling in terminals that already amplify wheel events. Set to `3` to match `vim` if your terminal sends one wheel event per notch without amplification. Ignored in the JetBrains IDE terminal, where Claude Code uses its own scroll handling                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_SEND_FEEDBACK`                             | Set to `0` to turn off [Claude-drafted feedback](tools-reference.md#sendfeedback-tool-behavior) for a session. Set to `1` to turn it on where your account already has access; the variable can’t grant access itself, and the other switches that turn feedback off, such as `DISABLE_FEEDBACK_COMMAND` and the [`feedbackDrafts`](settings-reference.md#feedbackdrafts) setting’s `off` value, still apply                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS`               | Override the time budget in milliseconds for [SessionEnd](../07-Hooks/hooks.md#sessionend) hooks. The value is also the timeout for each hook that sets no `timeout` of its own. Applies to session exit, `/clear`, and switching sessions via interactive `/resume`. By default the budget is 1.5 seconds, automatically raised to the highest per-hook `timeout` configured in settings files, up to 60 seconds. Timeouts on plugin-provided hooks do not raise the budget                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE_CODE_SESSION_ID`                                | Set automatically to the current session ID in Bash and PowerShell tool subprocesses, [hook command](../07-Hooks/hooks.md) subprocesses, and stdio [MCP server](../06-MCP-Tools/General/mcp.md) subprocesses. For Bash, PowerShell, and hooks this matches the `session_id` field in the hook JSON input and is updated on `/clear`. An MCP server subprocess retains the ID it was spawned with. On `--resume <session-id>` it receives the resumed ID, matching hooks and Bash. On `--continue` or `--resume` without an explicit ID it may receive the initial startup ID instead. Use to correlate scripts and external tools with the Claude Code session that launched them                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_SHELL`                                     | Set the shell Claude Code uses to run Bash tool commands. Accepts a path to a `bash` or `zsh` binary, for example `/opt/homebrew/bin/bash`. Other shells such as `fish` are not supported. If the value is not a working `bash` or `zsh` path, Claude Code ignores it and falls back to auto-detection. Auto-detection uses your `$SHELL` when it points to `bash` or `zsh`, otherwise it picks the first working `zsh` then `bash` found on your `PATH` and standard install locations                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_SHELL_PREFIX`                              | Command prefix that wraps shell commands Claude Code spawns: Bash tool calls, [hook](../07-Hooks/hooks.md) commands, [status line](statusline.md) commands, and stdio [MCP server](../06-MCP-Tools/General/mcp.md) startup commands. PowerShell hooks and exec-form hooks run without the prefix. Useful for logging or auditing. Setting a bare executable path such as `/path/to/logger.sh` runs each command as `/path/to/logger.sh '<command>'`. The wrapper receives the command line as a single shell-quoted argument in `$1`, so the wrapper must re-evaluate `$1` with a shell, for example `exec bash -c "$1"`. Treating `$1` as a bare executable path breaks stdio MCP servers that pass arguments such as `npx -y <package>`. For Bash tool calls, `$1` contains the full shell invocation Claude Code assembles, including environment setup, not only the command Claude ran                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_SIMPLE`                                    | Set to `1` to run with a minimal system prompt and only the Bash, file read, and file edit tools. MCP tools from `--mcp-config` are still available. Disables auto-discovery of hooks, skills, custom commands, subagents, installed plugins, MCP servers, auto memory, and CLAUDE.md. Skills in a directory you pass with `--add-dir` still load. OAuth tokens and keychain credentials are not read, so Anthropic authentication must come from `ANTHROPIC_API_KEY` or an `apiKeyHelper` in `--settings`. Equivalent to passing [`--bare`](headless.md#start-faster-with-bare-mode)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_SIMPLE_SYSTEM_PROMPT`                      | Choose between Claude Code’s full system prompt and a shorter one with abbreviated tool descriptions. When unset, Haiku 4.5, Sonnet 5, Opus 4.7, and earlier models in those families use the full prompt by default, and newer models use the shorter one. Set to `1` to use the shorter prompt on any model. Set to `0`, `false`, `no`, or `off` to use the full prompt on any model, even where an experiment or server configuration would otherwise select the shorter one. Either prompt keeps the full tool set, hooks, MCP servers, and CLAUDE.md discovery                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `CLAUDE_CODE_SKIP_ANTHROPIC_AWS_AUTH`                   | Skip client-side authentication for [Claude Platform on AWS](claude-platform-on-aws.md), for gateways that sign requests themselves                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_SKIP_AWS_CRED_CACHE`                       | Set to `1` to turn off the in-process cache of credentials resolved from the AWS default credential provider chain, so Claude Code resolves the chain on every API request. With the cache off, an SSO-backed profile requests credentials from IAM Identity Center on every request. See [credential caching and resolution timeout](amazon-bedrock.md#credential-caching-and-resolution-timeout). Requires Claude Code v2.1.207 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `CLAUDE_CODE_SKIP_BEDROCK_AUTH`                         | Skip AWS authentication for Amazon Bedrock (for example, when using an LLM gateway)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `CLAUDE_CODE_SKIP_FAST_MODE_NETWORK_ERRORS`             | Set to `1` to treat a failed [fast mode](fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) availability check as available, for networks that block the check’s direct request to `api.anthropic.com`. Claude Code still honors a “disabled by your organization” response                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_SKIP_FAST_MODE_ORG_CHECK`                  | Set to `1` to skip the client-side [fast mode](fast-mode.md#use-fast-mode-behind-proxies-and-llm-gateways) availability check, for proxies that intercept the check’s request rather than refuse it. The API still rejects fast mode requests when your organization has fast mode disabled                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_SKIP_FOUNDRY_AUTH`                         | Skip Azure authentication for Microsoft Foundry, for a proxy or gateway that injects its own `Authorization` header. Claude Code sends requests without an Azure credential and preserves the `Authorization` header you supply, for example through `ANTHROPIC_CUSTOM_HEADERS`. Ignored when `ANTHROPIC_FOUNDRY_API_KEY` or `ANTHROPIC_FOUNDRY_AUTH_TOKEN` is set. Before v2.1.203, this variable left the Microsoft Foundry client unable to send requests unless an API key was also set                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_SKIP_MANTLE_AUTH`                          | Skip AWS authentication for Amazon Bedrock Mantle (for example, when using an LLM gateway)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_SKIP_MODEL_ACCESS_MEMORY`                  | The [startup model checks](amazon-bedrock.md#startup-model-checks) on [Amazon Bedrock](amazon-bedrock.md) and [Google Cloud’s Agent Platform](google-vertex-ai.md) remember on this machine which models they found your account can’t invoke, for up to a day. Set to `1` to turn that memory off. Requires Claude Code v2.1.285 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `CLAUDE_CODE_SKIP_PROMPT_HISTORY`                       | Set to `1` to skip writing prompt history and session transcripts to disk. Sessions started with this variable set do not appear in `--resume`, `--continue`, or up-arrow history. Useful for ephemeral scripted sessions                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_SKIP_VERTEX_AUTH`                          | Skip Google authentication for Google Cloud’s Agent Platform (for example, when using an LLM gateway)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_STARTUP_FAILURE_RESULTS`                   | Set to `1` to have a session started with `--output-format stream-json` write a [result message naming why Claude Code refused to start](../05-Agent-SDK/agent-sdk-typescript.md#startup_failure_reason) for startup failures that otherwise end with stderr alone. Requires Claude Code v2.1.274 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`                       | Maximum number of consecutive times a [Stop](../07-Hooks/hooks.md#stop) or [SubagentStop](../07-Hooks/hooks.md#subagentstop) hook may block the turn from ending before Claude Code overrides it and ends the turn anyway (default: 8). Set to `0` to disable the cap. Raise this if your hook legitimately needs more iterations to resolve                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `CLAUDE_CODE_SUBAGENT_MODEL`                            | The default model for [subagents](../09-Agents-Patterns/sub-agents.md#choose-a-model), [agent team](../09-Agents-Patterns/agent-teams.md#specify-teammates-and-models) teammates, and [workflow](workflows.md) agents that aren’t assigned a model another way. Accepts an alias such as `haiku` or a full model name. Two sources take precedence over it: a model Claude passes when it spawns the agent, and a `model` field in the agent’s definition, including `inherit`. To change that, set [`CLAUDE_CODE_SUBAGENT_MODEL_FORCE`](../09-Agents-Patterns/sub-agents.md#run-every-subagent-on-one-model). See [Choose a model](../09-Agents-Patterns/sub-agents.md#choose-a-model) for the full order. Setting it to `inherit` is the same as leaving it unset. Before v2.1.251, this variable overrode both the per-invocation model and the definition’s `model` field                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `CLAUDE_CODE_SUBAGENT_MODEL_FORCE`                      | Set to `1` to force one model onto subagents, teammates, and workflow agents. [Run every subagent on one model](../09-Agents-Patterns/sub-agents.md#run-every-subagent-on-one-model) says which model that is. Requires Claude Code v2.1.257 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL`                 | Set `5m` or `1h`, the only values Claude Code accepts, to choose the [prompt cache TTL](prompt-caching.md#cache-lifetime) for requests outside the main conversation, such as [subagents](../09-Agents-Patterns/sub-agents.md), workflows, and background work. Takes precedence over the `subagentPromptCacheTtl` setting and over `ENABLE_PROMPT_CACHING_1H`, and `FORCE_PROMPT_CACHING_5M` overrides it. The API bills 1-hour cache writes at a higher rate. Requires Claude Code v2.1.242 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `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](../08-Plugins-Skills/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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `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](../05-Agent-SDK/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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `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`](settings-reference.md#syntaxhighlightingdisabled) setting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_CODE_TASK_LIST_ID`                              | Share a task list across sessions. Set the same ID in multiple Claude Code instances to coordinate on a shared task list, in [sessions that have the Task tools](tools-reference.md#task-tool-availability). See [Task list](interactive-mode.md#task-list)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_TMPDIR`                                    | Override the temp directory used for internal temp files. Claude Code appends `/claude-{uid}/` to this path on Unix, or `/claude/` on Windows. Default: `/tmp` on macOS, `os.tmpdir()` on Linux and Windows. On macOS and Linux, [sandboxed](sandboxing.md) Bash subprocesses receive a short fallback `$TMPDIR` under the system default when your override is a long path, since some tools fail when temp paths get too long. Unsandboxed Bash commands inherit your shell’s `$TMPDIR` when it is set. On native Windows, when your shell doesn’t set `$TMPDIR`, a Bash command that references `$TMPDIR` receives your override, or `%TEMP%` when you haven’t set one. Claude Code’s own temp files always use your override. Set it in your shell, user settings, or managed settings. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env)                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `CLAUDE_CODE_TMUX_TRUECOLOR`                            | Set to any non-empty value, such as `1`, to allow 24-bit truecolor output inside tmux. **Setting it to `0` or `false` still allows truecolor**, unlike most on/off variables; unset the variable to restore the 256-color clamp. By default, Claude Code clamps to 256 colors when `$TMUX` is set because tmux does not pass through truecolor escape sequences unless configured to. Set this after adding `set -ga terminal-overrides ',*:Tc'` to your `~/.tmux.conf`. See [Terminal configuration](terminal-config.md) for other tmux settings                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_CODE_TOOL_MEMORY_CGROUP_EXCLUDE`                | On Linux and WSL, set to a comma-separated list of the kinds of processes Claude Code [excludes from the tool memory cap](tools-reference.md#memory-limit-on-linux-and-wsl), such as `mcp` or `lsp`. Set `none` to cap every kind, or `all-new` to cap only Bash, PowerShell, and Monitor tool commands. Claude Code keeps Bash, PowerShell, and Monitor tool commands under the cap whatever you list. Requires Claude Code v2.1.246 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `CLAUDE_CODE_TOOL_MEMORY_LIMIT`                         | On Linux and WSL, set to a size such as `4G` to [cap the memory that Bash and PowerShell tool commands can use](tools-reference.md#memory-limit-on-linux-and-wsl), and Monitor tool commands on v2.1.246 or later. Write the size in plain digits, alone for a number of bytes or with a `K`, `M`, `G`, or `T` suffix. Set `0` or `off` to turn the cap off. Once the first process Claude Code starts has turned the cap on or off, a changed value takes effect the next time you launch `claude`. Requires Claude Code v2.1.233 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_CODE_TRANSCRIPT_LOCAL_GC`                       | Set to `1` to limit how large the [transcript file](sessions.md#where-transcripts-are-stored) of a long `-p` or Agent SDK session grows. After each compaction, once the file is larger than 5 MB, Claude Code removes the history from before that compaction. On v2.1.296 or later, the file stays as it is when removing that history would shrink it by less than 10%. Resuming the session restores the same conversation whether or not the file was trimmed. Set it in the environment you start Claude Code from, since a settings `env` block can’t turn it on. Requires Claude Code v2.1.287 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS`                    | Deadline in milliseconds before Claude Code cancels a dialog it forwards to a remote client such as a [Remote Control](remote-control.md) or SDK host, or the approval dialog for a [held cross-session message](cross-session-messaging.md#control-inbound-messages); permission prompts and `AskUserQuestion` questions use their own flows and aren’t governed by it. On Claude Code v2.1.236 or later, it also bounds the mid-session [Fable usage-credits consent prompt](model-config.md#fable-and-usage-credits) in a session that may be running unattended. [Control inbound messages](cross-session-messaging.md#control-inbound-messages) and [non-interactive sessions](cross-session-messaging.md#non-interactive-sessions) cover the full held-message expiry rules, including the cases where the deadline doesn’t apply. Overrides the [`dialogExpiry`](settings-reference.md#dialogexpiry) setting. `0` or a negative value disables the deadline. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env)                                                                                                                                                                                                             |
| `CLAUDE_CODE_USE_ANTHROPIC_AWS`                         | Use [Claude Platform on AWS](claude-platform-on-aws.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_USE_BEDROCK`                               | Use [Amazon Bedrock](amazon-bedrock.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_USE_FOUNDRY`                               | Use [Microsoft Foundry](microsoft-foundry.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `CLAUDE_CODE_USE_MANTLE`                                | Use the Amazon Bedrock [Mantle endpoint](amazon-bedrock.md#use-the-mantle-endpoint)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_USE_POWERSHELL_TOOL`                       | Controls the PowerShell tool. On Windows without Git Bash, the tool is enabled automatically; set to `0` to disable it. On Windows with Git Bash installed, the tool is on by default for claude.ai and Console accounts; set to `1` to enable it in Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry sessions, or `0` to turn it off. On Linux, macOS, and WSL, set to `1` to enable it, which requires `pwsh` on your `PATH`. When enabled on Windows, Claude can run PowerShell commands natively instead of routing through Git Bash. See [PowerShell tool](tools-reference.md#powershell-tool)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `CLAUDE_CODE_USE_VERTEX`                                | Use [Google Cloud’s Agent Platform](google-vertex-ai.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `CLAUDE_CODE_WARN_DISK_FREE_GIB`                        | Set to a whole number of GiB, such as `10`, to have Claude Code warn Claude when free space on the working directory’s filesystem falls below that amount. The warning is a system reminder saying how much is free. The reminder is off when the variable is unset, `0`, or not plain digits. Set it in the environment that launches Claude Code, since Claude Code ignores a copy delivered through a settings `env` block. Requires Claude Code v2.1.304 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_CODE_WARN_MEMORY_FREE_GIB`                      | On Linux and WSL, set to a whole number of GiB such as `4` to have Claude Code warn Claude when available memory falls below that amount. The warning is a system reminder saying how much is available. The reminder is off when the variable is unset, `0`, or not plain digits. Set it in the environment that launches Claude Code, since Claude Code ignores a copy delivered through a settings `env` block. Requires Claude Code v2.1.304 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_CODE_WEBFETCH_CACHE_TTL_MS`                     | Set to the number of milliseconds [WebFetch](tools-reference.md#webfetch-tool-behavior) keeps each fetched URL’s response cached. The default is `900000`, which is 15 minutes. Takes plain digits only; `0`, a decimal, or any other spelling keeps the default. Claude Code reads the value once per launch, so a change in a settings `env` block applies when you next launch `claude`. Requires Claude Code v2.1.233 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CODE_WEBFETCH_DEADLINE_MS`                      | Upper bound in milliseconds on how long [WebFetch](tools-reference.md#webfetch-tool-behavior) waits for a page to download, including any redirects it follows. A download that hasn’t completed by then fails with a deadline error. The default is `300000`, which is five minutes. Set to `0` to remove the limit. Takes plain digits only; a decimal or any other spelling keeps the default. Requires Claude Code v2.1.268 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `CLAUDE_CODE_WEB_SEARCH_REFILLS_PER_HOUR`               | Rate at which a session’s [WebSearch limit](tools-reference.md#session-search-limit) refills, in calls per hour. The default is `100` in an interactive terminal session. In a [non-interactive](headless.md) session the default is `0`, which turns refill off. Takes plain digits only; any other spelling reads as unset. Requires Claude Code v2.1.290 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `CLAUDE_CODE_WORKER_CHECKIN_SCHEDULE`                   | When `CLAUDE_AUTO_BACKGROUND_TASKS` is set to `1`, how long Claude Code waits before each reminder to Claude to check on [background subagents](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) that are still running. Takes one or more comma-separated waits in whole seconds from `1` to `86400`, such as `600` or `600,1800,3600`. Each value is the wait before the next reminder, and the last value repeats. Takes plain digits only; any other value or spelling reads as unset. When unset, there are no reminders. Requires Claude Code v2.1.283 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `CLAUDE_CODE_WORKFLOW_MAX_CONCURRENT_AGENTS`            | How many agents a single [workflow](workflows.md) run executes at once, from `1` to `256`. By default, a run executes up to 16 agents at once, fewer when Claude Code has fewer CPUs available; queued `agent()` calls wait for a free slot. Each running agent’s transcript stays in Claude Code’s memory, so higher values raise memory use. Takes plain digits only; out-of-range values and other spellings keep the default. Requires Claude Code v2.1.269 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `CLAUDE_CODE_WORKFLOW_PREFIX_STAGGER_MS`                | Upper bound in milliseconds on how long a [workflow](workflows.md) agent waits for a same-prefix sibling’s first response to begin before sending its own first request. When a fan-out starts several agents that share a [prompt-cache prefix](workflows.md#prompt-caching-in-a-fan-out), Claude Code holds all but the first agent for up to this long so the rest read the cached prefix instead of each processing it uncached. Default `5000`. Set to `0` to disable the wait. When `DISABLE_PROMPT_CACHING` is set, agents never wait. Requires Claude Code v2.1.229 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `CLAUDE_CODE_YOU_SHOULD_KNOW_DEBUG`                     | Set to `1` to show, above the prompt, a line for each of the last three checks the [You should know mod](interactive-mode.md#you-should-know-suggestions) made in this session. Use it to confirm the mod is checking when no notes appear. Requires Claude Code v2.1.287 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `CLAUDE_CONFIG_DIR`                                     | Override the configuration directory (default: `~/.claude`). All settings, session history, and plugins are stored under this path. For credentials, see [where Claude Code stores credentials](authentication.md#credential-management). Useful for running multiple accounts side by side: for example, `alias claude-work='CLAUDE_CONFIG_DIR=~/.claude-work claude'`. Set it in your shell, user settings, or managed settings. In a settings file, write the [absolute path](#in-settings-files). Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `CLAUDE_EFFORT`                                         | Set automatically in Bash tool subprocesses and hook commands to the [effort level](model-config.md#adjust-effort-level) in effect when the subprocess starts: `low`, `medium`, `high`, `xhigh`, or `max`. Matches the `effort.level` field passed to [hooks](../07-Hooks/hooks.md). Only set when the current model supports the effort parameter                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_ENABLE_BYTE_WATCHDOG`                           | Set to `1` to force-enable the byte-level streaming idle watchdog, or set to `0` to force-disable it. `0` also turns off the [first-byte deadline](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs) on the connections where that deadline runs. When unset, the watchdog is enabled by default for direct Anthropic API and [Claude Platform on AWS](claude-platform-on-aws.md) connections, and for streaming responses on [gateway](../13-Enterprise-Admin/gateways.md) connections reached through `ANTHROPIC_BASE_URL` or `ANTHROPIC_AWS_BASE_URL`; before v2.1.222 it didn’t run on those gateway connections, so the event-level watchdog could report a stall there even while keep-alive pings were arriving. For timeouts and how the timers interact, see [Streaming idle watchdogs](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `CLAUDE_ENABLE_BYTE_WATCHDOG_BEDROCK`                   | Set to `1` to enable the byte-level streaming idle watchdog on Amazon Bedrock `vnd.amazon.eventstream` responses, which also enables the [first-byte deadline](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs) on Bedrock streaming requests. Off by default. Configure the timeout with `CLAUDE_STREAM_IDLE_TIMEOUT_MS`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_ENABLE_STREAM_WATCHDOG`                         | Set to `0` to force-disable the event-level streaming idle watchdog, or set to `1` to force-enable it. When unset, the watchdog is on by default for all providers. Before v2.1.196, the unset default was server-controlled on the direct Anthropic API and off on other providers. Configure the timeout with `CLAUDE_STREAM_IDLE_TIMEOUT_MS`; for the other stall timers that run alongside this one, see [Streaming idle watchdogs](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_ENV_FILE`                                       | Path to a shell script whose contents Claude Code runs before each Bash command in the same shell process, so exports in the file are visible to the command. Use to persist virtualenv or conda activation across commands. PowerShell commands receive its variables too, in v2.1.296 or later, under the conditions in [Persisted variables in PowerShell commands](../07-Hooks/hooks.md#persisted-variables-in-powershell-commands). Also populated dynamically by [SessionStart](../07-Hooks/hooks.md#persist-environment-variables), [Setup](../07-Hooks/hooks.md#setup), [CwdChanged](../07-Hooks/hooks.md#cwdchanged), and [FileChanged](../07-Hooks/hooks.md#filechanged) hooks                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `CLAUDE_JOB_DIR`                                        | Set by Claude Code in each [background session](../09-Agents-Patterns/agent-view.md) to that session’s `~/.claude/jobs/<id>` directory. Shell commands that the session runs inherit it. Write scratch files to [`$CLAUDE_JOB_DIR/tmp`](../09-Agents-Patterns/agent-view.md#where-state-is-stored). Claude’s `Write` and `Edit` calls there don’t prompt for permission, and the directory is removed when the session is deleted                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CLAUDE_PID`                                            | Claude Code sets this to its own process ID in the subprocesses it spawns: Bash and PowerShell tool commands and hook commands. On Linux, the Bash tool’s shell integration uses it to refuse a `pkill` pattern that would match the Claude Code process itself; see [the error reference](errors.md#pkill-pattern-matches-the-claude-code-process). Read it from your own scripts to identify or signal the parent Claude Code process deliberately. Requires Claude Code v2.1.214 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX`             | Prefix for auto-generated [Remote Control](remote-control.md) session names when no explicit name is provided. Defaults to your machine’s hostname, producing names like `myhost-graceful-unicorn`. The `--remote-control-session-name-prefix` CLI flag sets the same value for a single invocation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS`                   | Deadline in milliseconds for the first response byte of a streaming request, on the connections where the [first-byte deadline](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs) runs. For how Claude Code clamps it, the extra time it adds for large request bodies, and how it picks the deadline when you leave this unset, see [No response from API](errors.md#no-response-from-api). Requires Claude Code v2.1.242 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_STREAM_IDLE_TIMEOUT_MS`                         | Timeout in milliseconds before the event- and byte-level streaming idle watchdogs close a stalled connection. When you set this variable explicitly, the minimum is `300000` (5 minutes); lower values are silently clamped to absorb extended thinking pauses and proxy buffering, and the byte-level watchdog caps the value at 30 minutes. `CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS` takes precedence over this variable for the byte-level watchdog. For the per-watchdog unset defaults, see [Streaming idle watchdogs](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `CLAUDE_SUBAGENT_BG_SHELL_MAX_MS`                       | Removed in v2.1.260 and now a no-op. Previously capped how long a [background shell command](interactive-mode.md#background-bash-commands) that a [subagent](../09-Agents-Patterns/sub-agents.md) started could run, in milliseconds, with a 60-minute default. See [the background command lifetime rules](tools-reference.md#background-commands)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `DEBUG`                                                 | Set to `1` to enable debug mode, equivalent to launching with [`--debug`](cli-reference.md#cli-flags). Debug logs are written to `~/.claude/debug/<session-id>.txt`, or to the path set by `CLAUDE_CODE_DEBUG_LOGS_DIR`. Only the truthy values `1`, `true`, `yes`, and `on` enable debug mode, so namespace patterns like `DEBUG=express:*` set for other tools do not trigger it                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `DISABLE_AUTOUPDATER`                                   | Set to `1` to disable automatic background updates. Manual `claude update` still works. Use `DISABLE_UPDATES` to block both                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `DISABLE_AUTO_COMPACT`                                  | Set to `1` to disable automatic compaction when approaching the context limit, along with [idle compaction](settings-reference.md#idlecompaction). The manual `/compact` command remains available. Use when you want explicit control over when compaction occurs. Overrides the [`autoCompactEnabled`](settings-reference.md#autocompactenabled) setting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `DISABLE_COMPACT`                                       | Set to `1` to disable all compaction: both automatic compaction and the manual `/compact` command                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `DISABLE_COST_WARNINGS`                                 | Set to `1` to disable cost warning messages                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `DISABLE_DOCTOR_COMMAND`                                | Set to `1` to hide the [`/doctor`](commands.md#all-commands) setup checkup skill and its `/checkup` alias. Useful for managed deployments where users shouldn’t run setup diagnostics from a session. Doesn’t affect the `claude doctor` terminal command. Before v2.1.205, this variable hid the `/doctor` diagnostics screen command                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `DISABLE_ERROR_REPORTING`                               | Set to any non-empty value, such as `1`, to opt out of error reporting. **Setting it to `0` or `false` still opts out**, unlike most on/off variables; unset the variable to turn error reporting back on                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `DISABLE_EXTRA_USAGE_COMMAND`                           | Set to `1` to hide the `/usage-credits` command that lets users purchase additional usage beyond rate limits                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `DISABLE_FEEDBACK_COMMAND`                              | Set to `1` to disable the `/feedback` command and [Claude-drafted feedback](tools-reference.md#sendfeedback-tool-behavior). Also disables `/bug` and `/share`, which report through the same path; before v2.1.212 they were aliases of `/feedback`, so the command was disabled under every name. The older name `DISABLE_BUG_COMMAND` is also accepted                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `DISABLE_GROWTHBOOK`                                    | Set to `1` or `true` to disable feature-flag fetching and use code defaults for every flag. This makes [Remote Control](remote-control.md#requirements) and the other [features that need feature-flag fetching](#features-that-need-feature-flag-fetching) unavailable. Setting it to `0` or `false` leaves fetching on. Telemetry event logging stays on unless `DISABLE_TELEMETRY` is also set                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `DISABLE_INSTALLATION_CHECKS`                           | Set to `1` to disable installation warnings. Use only when manually managing the installation location, as this can mask issues with standard installations                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `DISABLE_INSTALL_GITHUB_APP_COMMAND`                    | Set to `1` to hide the `/install-github-app` command. Already hidden when using third-party providers (Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `DISABLE_INTERLEAVED_THINKING`                          | Set to `1` to prevent sending the interleaved-thinking beta header. Useful when your LLM gateway or provider does not support [interleaved thinking](../04-API-Reference/Guides/build-with-claude-extended-thinking.md#interleaved-thinking)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `DISABLE_LOGIN_COMMAND`                                 | Set to `1` to hide the `/login` command. Useful when authentication is handled externally via API keys or `apiKeyHelper`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `DISABLE_LOGOUT_COMMAND`                                | Set to `1` to hide the `/logout` command                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `DISABLE_PROMPT_CACHING`                                | Set to `1` to disable [prompt caching](prompt-caching.md#disable-prompt-caching) for all models (takes precedence over per-model settings)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `DISABLE_PROMPT_CACHING_FABLE`                          | Set to `1` to disable prompt caching for Fable models                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `DISABLE_PROMPT_CACHING_HAIKU`                          | Set to `1` to disable prompt caching for the [default Haiku model](prompt-caching.md#disable-prompt-caching), wherever it runs                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `DISABLE_PROMPT_CACHING_OPUS`                           | Set to `1` to disable prompt caching for the [default Opus model](prompt-caching.md#disable-prompt-caching)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `DISABLE_PROMPT_CACHING_SONNET`                         | Set to `1` to disable prompt caching for the [default Sonnet model](prompt-caching.md#disable-prompt-caching)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `DISABLE_TELEMETRY`                                     | Set to any non-empty value, such as `1`, to opt out of telemetry. **Setting it to `0` or `false` still opts out**, unlike most on/off variables; unset the variable to turn telemetry back on. Telemetry events don’t include user data like code, file paths, or Bash commands. Also disables [feature-flag fetching](#features-that-need-feature-flag-fetching). See [Turn telemetry off for your organization](../13-Enterprise-Admin/managed-settings.md#turn-telemetry-off-for-your-organization)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `DISABLE_UPDATES`                                       | Set to `1` to block all updates including manual `claude update` and `claude install`. Stricter than `DISABLE_AUTOUPDATER`. Use when distributing Claude Code through your own channels and users should not self-update                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `DISABLE_UPGRADE_COMMAND`                               | Set to `1` to hide the `/upgrade` command                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `DO_NOT_TRACK`                                          | Set to `1` to opt out of telemetry, with the same effect as `DISABLE_TELEMETRY`, including on [feature-flag fetching](#features-that-need-feature-flag-fetching). Claude Code reads this variable as a standard boolean, so `0` leaves telemetry on, and honors it as the cross-tool convention recognized by many developer CLIs                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `ENABLE_BETA_TRACING_DETAILED`                          | Set to `1`, and set `BETA_TRACING_ENDPOINT` to your OTLP/HTTP collector endpoint, to turn on [detailed beta tracing](../13-Enterprise-Admin/monitoring-usage.md#traces-beta), which adds content-bearing span attributes and the `claude_code.hook` span. Interactive CLI sessions also require your organization to be allowlisted for the beta. Both variables are ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `ENABLE_CLAUDEAI_MCP_SERVERS`                           | Set to `false` to stop Claude Code from fetching [claude.ai MCP servers](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai). Enabled by default for logged-in users. To disable per-project or per-org, set [`disableClaudeAiConnectors`](settings-reference.md#disableclaudeaiconnectors) in settings instead                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `ENABLE_PROMPT_CACHING_1H`                              | Set to `1` to request a 1-hour [prompt cache TTL](prompt-caching.md#cache-lifetime) instead of the default 5 minutes. Intended for API key, [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), [Microsoft Foundry](microsoft-foundry.md), and [Claude Platform on AWS](claude-platform-on-aws.md) users. For subscription users within included usage, Claude Code requests the 1-hour TTL automatically on the [main conversation](prompt-caching.md#which-ttl-each-request-gets). Subscription users drawing on [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md) can set it to keep the 1-hour TTL. 1-hour cache writes are billed at a higher rate. To choose the TTL separately for the main conversation and for requests outside it, use `CLAUDE_CODE_PROMPT_CACHE_TTL` and `CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL`, which take precedence over this variable                                                                                                                                                                                                                                                                                                                             |
| `ENABLE_PROMPT_CACHING_1H_BEDROCK`                      | Deprecated. Use `ENABLE_PROMPT_CACHING_1H` instead. Has no effect on [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sessions, even when the gateway routes to Amazon Bedrock                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `ENABLE_TOOL_SEARCH`                                    | Controls [MCP tool search](../06-MCP-Tools/General/mcp.md#scale-with-mcp-tool-search). Unset or `true` defers MCP tools, except in the [cases that keep tool search off](../06-MCP-Tools/General/mcp.md#configure-tool-search). `auto` turns tool search on once definitions reach 10% of the context window. `auto:N` sets a custom threshold, such as `auto:5` for 5%. `false` loads all tools upfront. If a gateway rejects tool search, see [Tool search through an LLM gateway](../06-MCP-Tools/General/mcp.md#tool-search-through-a-gateway)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `FORCE_AUTOUPDATE_PLUGINS`                              | Set to `1` to force plugin auto-updates even when the main auto-updater is disabled via `DISABLE_AUTOUPDATER`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `FORCE_HYPERLINK`                                       | Set to `1` to enable clickable OSC 8 hyperlinks when your terminal supports them but isn’t auto-detected, or `0` to disable them. When unset, Claude Code enables hyperlinks only when it detects terminal support. Claude Code parses this value as a number, not a Boolean, so a value such as `false`, `no`, or `off` enables hyperlinks rather than disabling them. The footer [PR or merge request badge](interactive-mode.md#pr-review-status) renders as a hyperlink even when Claude Code can’t detect terminal support, such as over SSH. Set `0` to render the badge as plain text                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `FORCE_PROMPT_CACHING_5M`                               | Set to `1` to force the 5-minute prompt cache TTL even when 1-hour TTL would otherwise apply. Overrides `CLAUDE_CODE_PROMPT_CACHE_TTL`, `CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL`, `ENABLE_PROMPT_CACHING_1H`, and the `promptCacheTtl` and `subagentPromptCacheTtl` settings                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `HTTP_PROXY`                                            | Specify HTTP proxy server for network connections                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `HTTPS_PROXY`                                           | Specify HTTPS proxy server for network connections                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `IS_DEMO`                                               | Set to any non-empty value, such as `1`, to enable demo mode: hides your email and organization name from the header and `/status` output, and skips onboarding. **Setting it to `0` or `false` still enables demo mode**, unlike most on/off variables; unset the variable to turn it off. Useful when streaming or recording a session                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `MAX_MCP_OUTPUT_TOKENS`                                 | Maximum number of tokens allowed in MCP tool responses (default: 25000). Claude Code displays a warning when output exceeds 10,000 tokens. Tools that declare [`anthropic/maxResultSizeChars`](../06-MCP-Tools/General/mcp.md#raise-the-limit-for-a-specific-tool) use that character limit for text content instead, but image content from those tools is still subject to this variable. A successful text result longer than 50,000 characters from a tool without that annotation is [saved to a file](../06-MCP-Tools/General/mcp.md#mcp-output-limits-and-warnings) regardless of this variable                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `MAX_STRUCTURED_OUTPUT_RETRIES`                         | Number of attempts Claude Code allows when the model’s response fails validation against the [`--json-schema`](cli-reference.md#cli-flags) in non-interactive mode with the `-p` flag; after that many failed attempts with no valid output, the run fails. The same cap applies when a [workflow](workflows.md) subagent’s structured output fails validation. Defaults to 5, a first attempt plus four retries                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `MAX_THINKING_TOKENS`                                   | Fixed token budget for [extended thinking](../04-API-Reference/Guides/build-with-claude-extended-thinking.md). Claude Code caps it at one token below the request’s max output tokens and never below 1,024. See `CLAUDE_CODE_MAX_OUTPUT_TOKENS` for how that limit is set. When unset and thinking is enabled, models with [adaptive reasoning](model-config.md#adjust-effort-level) choose their own thinking depth, and other models use the cap. Set to `0` to disable thinking on the Anthropic API, except on Opus 5.5, Sonnet 5.5, Haiku 5.5, and the Fable models, which can’t have thinking turned off. On [third-party providers](third-party-integrations.md), `0` omits the `thinking` parameter instead. With thinking turned off on the Anthropic API, Claude Code sends effort `high` instead of a higher level to models it knows [don’t accept that combination](errors.md#effort-isnt-available-with-thinking-turned-off), such as Opus 5. For a positive value, Claude Code ignores the number itself on adaptive reasoning models, except when `CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING` turns adaptive reasoning off                                                                                                                                                               |
| `MCP_CLIENT_SECRET`                                     | OAuth client secret for MCP servers that require [pre-configured credentials](../06-MCP-Tools/General/mcp.md#use-pre-configured-oauth-credentials). Avoids the interactive prompt when adding a server with `--client-secret`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `MCP_CONNECTION_NONBLOCKING`                            | Controls whether startup waits for MCP servers to connect before the first query. MCP startup is non-blocking by default: servers connect in the background and their tools become available as they finish. Set to `0` to make Claude Code wait for servers to connect before the first query. Servers configured with [`alwaysLoad: true`](../06-MCP-Tools/General/mcp.md#exempt-a-server-from-deferral) still make startup wait regardless, except when served from the [discovery cache](../06-MCP-Tools/General/mcp.md#server-status-detail), since their tools must be present when the first prompt is built. In non-interactive mode (`-p`) without `--input-format stream-json`, Claude Code also waits for still-pending servers before the first turn regardless of this variable. When you pass [`--mcp-config`](cli-reference.md#cli-flags) explicitly, the wait has a longer deadline; see that flag’s entry for the cached-server exception                                                                                                                                                                                                                                                                                                                                                                                                  |
| `MCP_CONNECT_TIMEOUT_MS`                                | How long blocking MCP startup waits, in milliseconds, for the connection batch before snapshotting the tool list (default: 5000). Applies when `MCP_CONNECTION_NONBLOCKING=0` or for servers marked [`alwaysLoad: true`](../06-MCP-Tools/General/mcp.md#exempt-a-server-from-deferral). Servers still pending at the deadline keep connecting in the background. Distinct from `MCP_TIMEOUT`, which bounds an individual server’s connect attempt                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `MCP_DISCOVERY_CACHE`                                   | Turns the [MCP discovery cache](../06-MCP-Tools/General/mcp.md#server-status-detail) on or off. With the cache on, a remote HTTP or SSE server you’ve used before can show the [`cached` status](../06-MCP-Tools/General/mcp.md#server-status-detail), and Claude Code connects it on its first tool call instead of at startup. The cache is off by default unless a gradual rollout has enabled it for your account. Set to `1` to turn it on, or `0` to keep it off even when the rollout has enabled it. Before v2.1.238, the cache was on by default. The `cached` status requires Claude Code v2.1.221 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `MCP_DISCOVERY_CACHE_MAX_STALE_S`                       | Maximum age, in seconds, of a [discovery-cache](../06-MCP-Tools/General/mcp.md#server-status-detail) entry (default: 14400, or 4 hours). At a start where the entry is older than that, Claude Code discards it and connects the server at startup, as it does with the cache off. Claude Code caps the value at 7 days. Before v2.1.238, the default was 86400, or 24 hours, and Claude Code didn’t cap the value                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `MCP_DISCOVERY_CACHE_STRIKES`                           | At a start where a [discovery-cache](../06-MCP-Tools/General/mcp.md#server-status-detail) entry is older than `MCP_DISCOVERY_CACHE_TTL_S`, Claude Code refreshes it in the background. This variable sets how many refreshes in a row can fail before Claude Code discards the entry and connects the server at the next start instead (default: 1). Raise it if your network connection drops occasionally, so that one failed refresh doesn’t discard the entry. Requires Claude Code v2.1.238 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `MCP_DISCOVERY_CACHE_TTL_S`                             | Seconds for which Claude Code uses a [discovery-cache](../06-MCP-Tools/General/mcp.md#server-status-detail) entry without refreshing it (default: 900). At a start where the entry is older than that, Claude Code still uses it but refreshes it in the background. Once the entry is older than `MCP_DISCOVERY_CACHE_MAX_STALE_S`, Claude Code discards it instead. Claude Code caps the value at `MCP_DISCOVERY_CACHE_MAX_STALE_S`, which is 4 hours by default. Before v2.1.238, Claude Code didn’t cap the value                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `MCP_OAUTH_CALLBACK_PORT`                               | Fixed port for the OAuth redirect callback, as an alternative to `--callback-port` when adding an MCP server with [pre-configured credentials](../06-MCP-Tools/General/mcp.md#use-pre-configured-oauth-credentials)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `MCP_PROTOCOL_NEGOTIATION`                              | On the [v2 MCP client runtime](../06-MCP-Tools/General/mcp.md#mcp-client-runtimes) only, controls whether Claude Code probes servers for MCP protocol revision 2026-07-28. Set `legacy` to skip the probe, so that every server connects with the handshake from before that revision. Set `auto` to probe the server kinds that support the probe: HTTP and stdio servers, claude.ai connectors, and the connectors of cloud and Remote Control sessions. With the variable unset, Claude Code probes those same kinds by default; see [MCP client runtimes](../06-MCP-Tools/General/mcp.md#mcp-client-runtimes). Any other value is ignored with a warning in the debug log. Requires Claude Code v2.1.221 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `MCP_REMOTE_SERVER_CONNECTION_BATCH_SIZE`               | Maximum number of remote MCP servers (HTTP/SSE) to connect in parallel during startup (default: 20)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `MCP_SDK_GENERATION`                                    | Pin which [MCP client runtime](../06-MCP-Tools/General/mcp.md#mcp-client-runtimes) this process connects to MCP servers with: `v1`, built on MCP TypeScript SDK 1.x, or `v2`, built on [MCP TypeScript SDK 2.0](https://ts.sdk.modelcontextprotocol.io/v2/). Without the variable, Claude Code uses v2, starting with the versions listed in that section. On Claude Code v2.1.221 or later, the v2 runtime checks the issuer an MCP OAuth server returns in its authorization response and fails the sign-in with an error that begins `Issuer mismatch in authorization response` when it doesn’t match. The v1 runtime doesn’t run this check. If you set an unrecognized value, Claude Code ignores it and writes a warning to the debug log. Claude Code reads the value once per process. Requires Claude Code v2.1.218 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `MCP_SERVER_CONNECTION_BATCH_SIZE`                      | Maximum number of local MCP servers (stdio) to connect in parallel during startup (default: 3)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `MCP_TIMEOUT`                                           | Timeout in milliseconds for MCP server startup (default: 30000, or 30 seconds)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `MCP_TOOL_TIMEOUT`                                      | Timeout in milliseconds for MCP tool execution (default: 100000000, about 28 hours). For an HTTP, SSE, or claude.ai connector server, each request also times out after 60 seconds by default; set this variable, or the per-server `timeout`, above 60000 to raise that per-request limit. A lower value still shortens the overall tool-execution timeout but leaves the per-request limit at 60 seconds. Stdio and WebSocket servers have no per-request timer. A per-server `timeout` field in `.mcp.json` overrides this for that server. A per-server `timeout` of at least 1000 also sets the minimum idle window for that server’s tool calls, so `CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT` never aborts them sooner; this floor requires Claude Code v2.1.203 or later. For the env variable, values below 1000 are floored to one second; for the per-server field, values below 1000 are ignored                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `NO_PROXY`                                              | List of domains and IPs to which requests will be directly issued, bypassing proxy                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT`                     | Standard OpenTelemetry SDK limit on attribute value length. Claude Code caps content-bearing telemetry attributes at the smaller of this and `CLAUDE_CODE_OTEL_CONTENT_MAX_LENGTH`, so the truncation marker stays within the SDK limit. Claude Code reads the `OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT` and `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` variants the same way, and the smallest set value applies to all signals. Requires Claude Code v2.1.214 or later. See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md#common-configuration-variables)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `OTEL_LOG_ASSISTANT_RESPONSES`                          | Set to `1` to include the model’s response text on `assistant_response` OpenTelemetry log events. When unset, Claude Code uses the value of `OTEL_LOG_USER_PROMPTS` instead. Set to `0` to keep responses redacted even when `OTEL_LOG_USER_PROMPTS` is set. Set it in your shell, user settings, or managed settings. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env). Requires Claude Code v2.1.193 or later. See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md#assistant-response-event)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `OTEL_LOG_MANAGED_SETTINGS`                             | Set to `1` to add the redacted managed settings, and a SHA-256 digest of the settings before redaction, to `managed_settings_resolved` OpenTelemetry log events. Disabled by default. Set it in your shell, user settings, or managed settings; a value in project or local settings doesn’t turn it on. Requires Claude Code v2.1.274 or later. See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md#managed-settings-resolved-event)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `OTEL_LOG_RAW_API_BODIES`                               | Emit Anthropic Messages API request and response JSON as `api_request_body` / `api_response_body` log events. Set to `1` for inline bodies truncated at the content limit, or `file:<dir>` to write untruncated bodies to disk and emit a `body_ref` path instead. `CLAUDE_CODE_OTEL_CONTENT_MAX_LENGTH` configures the content limit, 60 KB by default. Disabled by default; bodies include the entire conversation history. Set it in your shell, user settings, or managed settings. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env). See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md#api-request-body-event)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `OTEL_LOG_TOOL_CONTENT`                                 | Set to `1` to include tool content in the `tool.output` OpenTelemetry span event. Span attributes carry tool content under [their own gates](../13-Enterprise-Admin/monitoring-usage.md#new-context-gates). Requires [tracing](../13-Enterprise-Admin/monitoring-usage.md#traces-beta). Disabled by default to protect sensitive data. Set it in your shell, user settings, or managed settings. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env), apart from the off values that section describes. See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md#tool-output-span-event)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `OTEL_LOG_TOOL_DETAILS`                                 | Set to `1` to include tool input arguments; MCP server names; user-authored workflow names; raw error strings on tool failures; the refusal `category` on `api_refusal` events; real agent, skill, plugin, and MCP server names on [cost and token metrics](../13-Enterprise-Admin/monitoring-usage.md#cost-counter); and other tool details in OpenTelemetry metrics, traces, and logs. Disabled by default to protect PII. Set it in your shell, user settings, or managed settings. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env), apart from the off values that section describes. See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `OTEL_LOG_USER_PROMPTS`                                 | Set to `1` to include user prompt text in OpenTelemetry traces and logs. Disabled by default (prompts are redacted). Set it in your shell, user settings, or managed settings. Ignored in [project and local settings](settings-reference.md#variables-claude-code-ignores-in-env), apart from the off values that section describes. See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `OTEL_METRICS_INCLUDE_ACCOUNT_UUID`                     | Set to `false` to exclude account UUID from metrics attributes (default: included). See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `OTEL_METRICS_INCLUDE_ENTRYPOINT`                       | Set to `true` to include the session entrypoint in metrics attributes (default: excluded). Added in v2.1.152. See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `OTEL_METRICS_INCLUDE_REPOSITORY`                       | Set to `true` to tag OpenTelemetry metrics and events with `vcs.*` attributes identifying the session’s repository (default: excluded). Requires Claude Code v2.1.269 or later. See [Repository attributes](../13-Enterprise-Admin/monitoring-usage.md#repository-attributes)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `OTEL_METRICS_INCLUDE_RESOURCE_ATTRIBUTES`              | As of v2.1.161, Claude Code attaches `OTEL_RESOURCE_ATTRIBUTES` keys to metric datapoint labels. Set to `false` to exclude them (default: included). See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md#multi-team-organization-support)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `OTEL_METRICS_INCLUDE_SESSION_ID`                       | Set to `false` to exclude session ID from metrics attributes (default: included). See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `OTEL_METRICS_INCLUDE_VERSION`                          | Set to `true` to include Claude Code version in metrics attributes (default: excluded). See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `SLASH_COMMAND_TOOL_CHAR_BUDGET`                        | Override the character budget for skill metadata shown to the [Skill tool](../08-Plugins-Skills/skills.md#control-who-invokes-a-skill). The budget scales dynamically at 1% of the context window, with a fallback of 8,000 characters. Legacy name kept for backwards compatibility                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `TASK_MAX_OUTPUT_LENGTH`                                | Removed in v2.1.277 and now a no-op, together with the `TaskOutput` tool it sized. Previously set the maximum number of characters of a [background task’s](tools-reference.md#background-commands) output that the `TaskOutput` tool kept. Claude reads a background task’s output file with `Read` instead                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `USE_BUILTIN_RIPGREP`                                   | Set to `0` to use system-installed `rg` instead of `rg` included with Claude Code                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `VERTEX_REGION_CLAUDE_3_5_HAIKU`                        | Override region for Claude 3.5 Haiku when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `VERTEX_REGION_CLAUDE_3_5_SONNET`                       | Override region for Claude 3.5 Sonnet when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `VERTEX_REGION_CLAUDE_3_7_SONNET`                       | Override region for Claude 3.7 Sonnet when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `VERTEX_REGION_CLAUDE_4_0_OPUS`                         | Override region for Claude Opus 4 when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `VERTEX_REGION_CLAUDE_4_0_SONNET`                       | Override region for Claude Sonnet 4 when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `VERTEX_REGION_CLAUDE_4_1_OPUS`                         | Override region for Claude Opus 4.1 when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `VERTEX_REGION_CLAUDE_4_5_OPUS`                         | Override region for Claude Opus 4.5 when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `VERTEX_REGION_CLAUDE_4_5_SONNET`                       | Override region for Claude Sonnet 4.5 when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `VERTEX_REGION_CLAUDE_4_6_OPUS`                         | Override region for Claude Opus 4.6 when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `VERTEX_REGION_CLAUDE_4_6_SONNET`                       | Override region for Claude Sonnet 4.6 when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `VERTEX_REGION_CLAUDE_4_7_OPUS`                         | Override region for Claude Opus 4.7 when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `VERTEX_REGION_CLAUDE_4_8_OPUS`                         | Override region for Claude Opus 4.8 when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `VERTEX_REGION_CLAUDE_5_5_OPUS`                         | Override region for Claude Opus 5.5 when using Google Cloud’s Agent Platform. Added in v2.1.280                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `VERTEX_REGION_CLAUDE_5_5_SONNET`                       | Override region for Claude Sonnet 5.5 when using Google Cloud’s Agent Platform. Added in v2.1.284                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `VERTEX_REGION_CLAUDE_5_OPUS`                           | Override region for Claude Opus 5 when using Google Cloud’s Agent Platform. Added in v2.1.219                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `VERTEX_REGION_CLAUDE_5_SONNET`                         | Override region for Claude Sonnet 5 when using Google Cloud’s Agent Platform. Added in v2.1.197                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `VERTEX_REGION_CLAUDE_FABLE_5`                          | Override region for Claude Fable 5 when using Google Cloud’s Agent Platform. Added in v2.1.170                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `VERTEX_REGION_CLAUDE_FABLE_5_1`                        | Override region for Claude Fable 5.1 when using Google Cloud’s Agent Platform. Added in v2.1.257                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `VERTEX_REGION_CLAUDE_HAIKU_4_5`                        | Override region for Claude Haiku 4.5 when using Google Cloud’s Agent Platform                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `VERTEX_REGION_CLAUDE_HAIKU_5_5`                        | Override region for Claude Haiku 5.5 when using Google Cloud’s Agent Platform. Added in v2.1.293                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |

Standard OpenTelemetry exporter variables (`OTEL_METRICS_EXPORTER`, `OTEL_LOGS_EXPORTER`, `OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_EXPORTER_OTLP_PROTOCOL`, `OTEL_EXPORTER_OTLP_HEADERS`, `OTEL_METRIC_EXPORT_INTERVAL`, `OTEL_RESOURCE_ATTRIBUTES`, and signal-specific variants) are also supported. See [Monitoring](../13-Enterprise-Admin/monitoring-usage.md) for configuration details. Set `CLAUDE_CODE_ENABLE_TELEMETRY` and the OpenTelemetry variables that turn on export, choose its destination, or capture content in your shell, user settings, or managed settings. Claude Code [ignores them in project and local settings](settings-reference.md#variables-claude-code-ignores-in-env), apart from the off values that section describes. `OTEL_RESOURCE_ATTRIBUTES` and the export interval, timeout, and compression variables, such as `OTEL_METRIC_EXPORT_INTERVAL`, still apply from project and local settings.


[​](#what-the-subprocess-environment-scrub-removes)

What the subprocess environment scrub removes

When you set [`CLAUDE_CODE_SUBPROCESS_ENV_SCRUB`](#variables) to `1`, Claude Code removes credentials from the environments of the subprocesses it starts, such as Bash commands, hooks, and stdio MCP servers. This reduces what a prompt injection attack can read. The Claude Code process keeps the credentials for its own API calls. The scrub recognizes a credential by its variable name or by the shape of its value, so use it as one layer alongside narrow [permission rules](permissions.md) rather than as the only control. The table shows what the scrub does to example variables:

| Example variable                                                             | What the scrub does                                                                                                                                                                                                          |
|:-----------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `ANTHROPIC_API_KEY`, `AWS_SECRET_ACCESS_KEY`                                 | Removes it                                                                                                                                                                                                                   |
| `NPM_TOKEN`, `DB_PASSWORD`                                                   | Removes it, because the name looks like a credential                                                                                                                                                                         |
| `DATABASE_URL` that contains a password                                      | Removes it, because the value looks like a credential                                                                                                                                                                        |
| `PIP_INDEX_URL` or `NPM_CONFIG_REGISTRY` that contains a password            | Keeps the URL and cuts the username and password from it                                                                                                                                                                     |
| `CLAUDE_CONFIG_DIR`                                                          | Removes it                                                                                                                                                                                                                   |
| `GITHUB_TOKEN`, `GH_TOKEN`, `GH_ENTERPRISE_TOKEN`, `GITHUB_ENTERPRISE_TOKEN` | Leaves it in place, so that `gh` and scripts that call the GitHub API keep working                                                                                                                                           |
| `HTTP_PROXY`, `HTTPS_PROXY`                                                  | Leaves it in place, including a [username and password in the URL](../13-Enterprise-Admin/network-config.md#basic-authentication). The [sandbox](sandboxing.md#network-isolation) can set these variables itself for sandboxed commands |
| `GIT_CONFIG_COUNT`, `GIT_CONFIG_KEY_<n>`, `GIT_CONFIG_VALUE_<n>`             | Leaves it in place, whatever it holds                                                                                                                                                                                        |
| A secret whose variable name and value don’t look like a credential          | Leaves it in place                                                                                                                                                                                                           |

Because the scrub leaves `GITHUB_TOKEN` in place, give a GitHub Actions job the narrowest `permissions` it needs. To remove a GitHub token from sandboxed Bash commands, add a `deny` entry under [`sandbox.credentials`](sandboxing.md#protect-credentials). Leave the scrub unset if a subprocess needs one of the removed variables. On Linux, the scrub also runs Bash subprocesses in an isolated PID namespace so they can’t read host process environments through `/proc`. As a side effect, `ps`, `pgrep`, and `kill` can’t see or signal host processes. Before v2.1.251, the scrub removed `ANTHROPIC_API_KEY` and `AWS_SECRET_ACCESS_KEY` and left the table’s other example variables unchanged.


[​](#features-that-need-feature-flag-fetching)

Features that need feature-flag fetching

Claude Code turns some features on through feature flags it fetches from Anthropic. Claude Code skips that fetch in these sessions:

- A session where you set `DISABLE_GROWTHBOOK`, `DISABLE_TELEMETRY`, `DO_NOT_TRACK`, or `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`; each variable’s row in the [variables table](#variables) says which values turn fetching off
- A session on a [third-party provider](third-party-integrations.md), such as Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, or Microsoft Foundry, unless a host platform that embeds Claude Code sets `CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`
- A [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) session

With fetching off, you can’t:

- Use [Remote Control](remote-control.md) with `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` or `DISABLE_GROWTHBOOK` set. For `DISABLE_TELEMETRY` and `DO_NOT_TRACK`, see the [Remote Control requirements](remote-control.md#requirements)
- [Message sessions beyond this machine](cross-session-messaging.md#message-sessions-on-other-machines) when [Remote Control](remote-control.md#requirements) is unavailable. Messaging between sessions on this machine works with fetching off
- Run [`claude import` or the `/import` command](cli-reference.md#cli-commands)
- Run [`/skill-doctor`](../08-Plugins-Skills/skills.md#find-unused-skills) or open its report in the `/plugin` **Stats** tab
- Sync the [skills](../08-Plugins-Skills/skills.md#where-synced-skills-load) and [plugins](../08-Plugins-Skills/plugins-loading.md#synced-plugins) enabled for your claude.ai account into your terminal sessions
- Turn on the [You should know mod](interactive-mode.md#you-should-know-suggestions)
- Use [the advisor tool](advisor.md#requirements)
- Read or reply to [comments on an artifact](artifacts.md#collect-comments-on-an-artifact)
- Have Claude read [another organization’s public artifact](artifacts.md#read-an-artifact-shared-with-you)
- Get the [PowerShell tool](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
- Get [Claude-drafted feedback](tools-reference.md#sendfeedback-tool-behavior), which Claude Code turns on through a fetched flag
- Have Claude [treat large pastes as pasted rather than typed text](terminal-config.md#how-claude-treats-pasted-text); the content behind a `[Pasted text #N]` placeholder reaches Claude unmarked
- Have Claude Code [exclude MCP tools whose input schema the API would reject](../06-MCP-Tools/General/mcp.md#tools-with-invalid-input-schemas); it sends the schema anyway, and a request that includes it fails with [a 400 error naming the tool by its position](errors.md#tool-input-schema-is-invalid)
- Have Claude Code [compact a long conversation while your terminal session is idle](settings-reference.md#idlecompaction), shortly before a one-hour prompt cache expires


[​](#first-session-after-an-install-or-upgrade)

First session after an install or upgrade

In your first session after you install Claude Code, or upgrade to a version that adds a feature, a [flag-gated feature](#features-that-need-feature-flag-fetching) can be missing. When Claude Code fetches its feature flags during that session, it saves them on the machine, so your next session on that machine has the feature. In setups such as these, sessions after the first also start without freshly fetched flags:

- **A clean environment on every run**: if each run starts in a CI container, or any other environment without the flags an earlier session saved, every run is a first session
- **A gateway token with no API key**: if you authenticate with `ANTHROPIC_AUTH_TOKEN` and no API key, and `ANTHROPIC_BASE_URL` points at a host other than Anthropic’s, such as an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md), Claude Code has no credential to fetch the flags with


[​](#see-also)

See also

- [Settings](settings.md): all `settings.json` configuration, including the `env` key
- [CLI reference](cli-reference.md): launch-time flags
- [Network configuration](../13-Enterprise-Admin/network-config.md): proxy and TLS setup
- [Monitoring](../13-Enterprise-Admin/monitoring-usage.md): OpenTelemetry configuration

---

## Error reference - Claude Code Docs

Source: https://code.claude.com/docs/en/errors
Path: 02-Claude-Code-CLI/errors.md

## On this page

- [Find your error](#find-your-error)
- [Automatic retries](#automatic-retries)
  - [What you see while Claude Code retries or waits](#what-you-see-while-claude-code-retries-or-waits)
  - [Tune retry behavior](#tune-retry-behavior)
- [Server errors](#server-errors)
  - [API Error: 500 Internal server error](#api-error-500-internal-server-error)
  - [API Error: Repeated 529 Overloaded errors](#api-error-repeated-529-overloaded-errors)
  - [Request timed out](#request-timed-out)
  - [No response from API](#no-response-from-api)
  - [The response above may be incomplete](#the-response-above-may-be-incomplete)
  - [Auto mode cannot determine the safety of an action](#auto-mode-cannot-determine-the-safety-of-an-action)
  - [The server returned no safety verdict](#the-server-returned-no-safety-verdict)
  - [Was not reviewed and did not run](#was-not-reviewed-and-did-not-run)
  - [Agent terminated early due to an API error](#agent-terminated-early-due-to-an-api-error)
- [Usage limits](#usage-limits)
  - [You’ve hit your session limit](#youve-hit-your-session-limit)
  - [Usage credits required for 1M context](#usage-credits-required-for-1m-context)
  - [The prompt to confirm went unanswered](#the-prompt-to-confirm-went-unanswered)
  - [Server is temporarily limiting requests](#server-is-temporarily-limiting-requests)
  - [Request rejected (429)](#request-rejected-429)
  - [You’ve hit your monthly spend limit](#youve-hit-your-monthly-spend-limit)
  - [Spend limit reached](#spend-limit-reached)
  - [Credit balance is too low](#credit-balance-is-too-low)
  - [Could not update your spend limit](#could-not-update-your-spend-limit)
- [Authentication errors](#authentication-errors)
  - [Not logged in](#not-logged-in)
  - [Could not resolve authentication method](#could-not-resolve-authentication-method)
  - [Invalid API key](#invalid-api-key)
  - [Your apiKeyHelper script is failing](#your-apikeyhelper-script-is-failing)
  - [Invalid request header value](#invalid-request-header-value)
  - [This organization has been disabled](#this-organization-has-been-disabled)
  - [Your organization has disabled API key authentication](#your-organization-has-disabled-api-key-authentication)
  - [Your organization has disabled Claude subscription access](#your-organization-has-disabled-claude-subscription-access)
  - [Routines are disabled by your organization’s policy](#routines-are-disabled-by-your-organizations-policy)
  - [Remote Control requires the Anthropic API](#remote-control-requires-the-anthropic-api)
  - [Remote Control couldn’t refresh your login](#remote-control-couldnt-refresh-your-login)
  - [Remote Control could not renew this computer’s connection](#remote-control-could-not-renew-this-computers-connection)
  - [Remote Control stopped because the signed-in account changed](#remote-control-stopped-because-the-signed-in-account-changed)
  - [Remote Control stopped because the app running the session signed out or switched accounts](#remote-control-stopped-because-the-app-running-the-session-signed-out-or-switched-accounts)
  - [OAuth token revoked or expired](#oauth-token-revoked-or-expired)
  - [API Error: 401 Invalid authentication credentials](#api-error-401-invalid-authentication-credentials)
  - [Login expired](#login-expired)
  - [Could not refresh your login because another Claude Code process is refreshing it](#could-not-refresh-your-login)
  - [Couldn’t save your login](#couldnt-save-your-login)
  - [Couldn’t start the local listener that receives the browser sign-in](#couldnt-start-the-local-sign-in-listener)
  - [Claude login not accepted](#claude-login-not-accepted)
  - [Artifacts need a claude.ai login](#artifacts-need-a-claude-ai-login)
  - [Administrator policy requires a Cloud gateway sign-in](#administrator-policy-requires-a-cloud-gateway-sign-in)
  - [Your account is on hold](#your-account-is-on-hold)
  - [Anthropic profile login expired](#anthropic-profile-login-expired)
  - [OAuth scope requirement](#oauth-scope-requirement)
  - [claude.ai rejected the session token](#claude-ai-rejected-the-session-token)
  - [MCP server needs you to sign in again](#mcp-server-needs-you-to-sign-in-again)
  - [Couldn’t read the stored credentials for MCP server](#couldnt-read-the-stored-credentials-for-mcp-server)
  - [MCP server URL is missing or not a valid URL](#mcp-server-url-is-missing-or-not-a-valid-url)
  - [Issuer mismatch in authorization response](#issuer-mismatch-in-authorization-response)
  - [Refusing to send credentials to non-https token endpoint](#refusing-to-send-credentials-to-non-https-token-endpoint)
  - [AWS credentials expired or invalid](#aws-credentials-expired-or-invalid)
  - [AWS authentication failed](#aws-authentication-failed)
  - [Google Cloud credentials expired or invalid](#google-cloud-credentials-expired-or-invalid)
  - [Google Cloud authentication failed](#google-cloud-authentication-failed)
  - [Microsoft Foundry authentication failed](#microsoft-foundry-authentication-failed)
  - [Could not load AWS or Google Cloud credentials](#could-not-load-aws-or-google-cloud-credentials)
  - [AWS default-chain credential resolve timed out](#aws-default-chain-credential-resolve-timed-out)
  - [Bedrock setup verification timed out waiting for AWS](#bedrock-setup-verification-timed-out-waiting-for-aws)
  - [Cloud gateway session expired](#cloud-gateway-session-expired)
  - [Sign-in timed out while waiting for you to continue](#sign-in-timed-out-while-waiting-for-you-to-continue)
  - [Gateway refused the request](#gateway-refused-the-request)
- [Network and connection errors](#network-and-connection-errors)
  - [Unable to connect to API](#unable-to-connect-to-api)
  - [Unable to connect to Anthropic services](#unable-to-connect-to-anthropic-services)
  - [Socket is closed](#socket-is-closed)
  - [API returned an empty or malformed response](#api-returned-an-empty-or-malformed-response)
  - [Streaming response ended before any complete data was received](#streaming-response-ended-before-any-complete-data-was-received)
  - [Bedrock streaming response has an unexpected content-type](#bedrock-streaming-response-has-an-unexpected-content-type)
  - [SSL certificate errors](#ssl-certificate-errors)
  - [Host not allowed in a cloud session](#host-not-allowed-in-a-cloud-session)
  - [The proxy refused the connection](#the-proxy-refused-the-connection)
  - [The cloud environments service returned an empty or unexpected response](#the-cloud-environments-service-returned-an-empty-or-unexpected-response)
  - [Failed to fetch session from Sessions API](#failed-to-fetch-session-from-sessions-api)
  - [Couldn’t reconnect to your Remote Control session](#couldnt-reconnect-to-your-remote-control-session)
  - [Sessions ended while this machine was offline](#sessions-ended-while-this-machine-was-offline)
  - [Couldn’t share the transcript](#couldnt-share-the-transcript)
  - [Couldn’t send feedback](#couldnt-send-feedback)
  - [MCP server connection timed out during a sleep or clock change](#mcp-server-connection-timed-out-during-a-sleep-or-clock-change)
- [Request errors](#request-errors)
  - [Prompt is too long](#prompt-is-too-long)
  - [Context exceeds the token limit](#context-exceeds-the-token-limit)
  - [Request too large](#request-too-large)
  - [Image was too large](#image-was-too-large)
  - [Unable to resize image](#unable-to-resize-image)
  - [Request rejected as unprocessable by the model](#request-rejected-as-unprocessable-by-the-model)
  - [PDF errors](#pdf-errors)
  - [Extra inputs are not permitted](#extra-inputs-are-not-permitted)
  - [Tool input schema is invalid](#tool-input-schema-is-invalid)
  - [MCP tool name over 128 characters](#mcp-tool-name-over-128-characters)
  - [tool_use.name over 200 characters](#tool-use-name-over-200-characters)
  - [There’s an issue with the selected model](#theres-an-issue-with-the-selected-model)
  - [Model is not a recognized model id](#model-is-not-a-recognized-model-id)
  - [Model not found](#model-not-found)
  - [Couldn’t confirm model with the API](#couldnt-confirm-model-with-the-api)
  - [API error when checking the picked model](#api-error-model-not-changed)
  - [Claude Opus is not available with the Claude Pro plan](#claude-opus-is-not-available-with-the-claude-pro-plan)
  - [Claude Code does not support this model](#claude-code-does-not-support-this-model)
  - [Model is restricted by your organization’s settings](#model-is-restricted-by-your-organizations-settings)
  - [Can’t switch to the default model](#cant-switch-to-the-default-model)
  - [Model switch was blocked by a PreModelSwitch hook](#model-switch-was-blocked-by-a-premodelswitch-hook)
  - [Couldn’t save it as your default](#couldnt-save-it-as-your-default)
  - [Advisor is less capable than the current main model](#advisor-is-less-capable-than-the-current-main-model)
  - [thinking.type.enabled is not supported for this model](#thinking-type-enabled-is-not-supported-for-this-model)
  - [Effort isn’t available with thinking turned off](#effort-isnt-available-with-thinking-turned-off)
  - [Thinking budget exceeds output limit](#thinking-budget-exceeds-output-limit)
  - [Response exceeded the output token maximum](#response-exceeded-the-output-token-maximum)
  - [Tool use or thinking block mismatch](#tool-use-or-thinking-block-mismatch)
  - [Invalid data in redacted_thinking block](#invalid-data-in-redacted-thinking-block)
  - [Unsupported tool content removed](#unsupported-tool-content-removed)
  - [role ‘system’ must precede an ‘assistant’ message](#role-system-must-precede-an-assistant-message)
  - [Invalid encrypted_content in search_result block](#invalid-encrypted-content-in-search-result-block)
  - [Usage Policy refusal](#usage-policy-refusal)
  - [Safety measures flagged a cybersecurity topic](#safety-measures-flagged-a-cybersecurity-topic)
  - [Safeguards flagged a request for Claude’s reasoning](#safeguards-flagged-a-request-for-claudes-reasoning)
  - [Output blocked by content filtering policy](#output-blocked-by-content-filtering-policy)
- [Command-line errors](#command-line-errors)
  - [Conflict between --bg and --print](#conflict-between-bg-and-print)
  - [Couldn’t tell whether --bg is a flag or text](#couldnt-tell-whether-bg-is-a-flag-or-text)
  - [Conflict between a system prompt flag and its file form](#conflict-between-a-system-prompt-flag-and-its-file-form)
  - [Invalid --agents configuration](#invalid-agents-configuration)
  - [Cloud sessions cannot be created from a --restricted session](#cloud-sessions-cannot-be-created-from-a-restricted-session)
  - [Cloud sessions are disabled by your organization’s policy](#cloud-sessions-are-disabled-by-your-organizations-policy)
  - [Cloud sessions use your claude.ai login](#cloud-sessions-use-your-claude-ai-login)
  - [Couldn’t verify your organization’s policy for cloud sessions](#couldnt-verify-your-organizations-policy-for-cloud-sessions)
  - [Nothing was stashed because a folder replaced a tracked file](#nothing-was-stashed-because-a-folder-replaced-a-tracked-file)
  - [The --json-schema value is not a valid JSON Schema](#the-json-schema-value-is-not-a-valid-json-schema)
  - [Settings file exceeds the 2MiB limit](#settings-file-exceeds-the-2mib-limit)
  - [The current directory no longer exists](#the-current-directory-no-longer-exists)
  - [Temp directory refused or cannot be created](#temp-directory-refused-or-cannot-be-created)
  - [Directory couldn’t be resolved to a real location](#directory-couldnt-be-resolved-to-a-real-location)
  - [Workspace not trusted when starting Remote Control](#workspace-not-trusted-when-starting-remote-control)
  - [Workspace not trusted when running claude ultrareview](#workspace-not-trusted-when-running-claude-ultrareview)
  - [Not carried over to the sessions Remote Control starts](#not-carried-over-to-the-sessions-remote-control-starts)
  - [--sandbox or --no-sandbox is not supported by claude remote-control](#sandbox-is-not-supported-by-claude-remote-control)
  - [claude import is not yet available in this build](#claude-import-is-not-yet-available-in-this-build)
  - [Could not read Claude Code config](#could-not-read-claude-code-config)
  - [Could not import a server from Claude Desktop](#could-not-import-a-server-from-claude-desktop)
  - [Cannot add MCP server to the managed scope](#cannot-add-mcp-server-to-the-managed-scope)
  - [Cannot add MCP server when managed settings allow only plugin servers](#cannot-add-mcp-server-when-managed-settings-allow-only-plugin-servers)
  - [Can’t read .mcp.json](#cant-read-mcp-json)
  - [MCP server was not saved or removed](#mcp-server-was-not-saved-or-removed)
  - [MCP server may not have been saved or removed](#mcp-server-may-not-have-been-saved-or-removed)
  - [Server is Anthropic-hosted and doesn’t support local OAuth](#anthropic-hosted-and-doesnt-support-local-oauth)
  - [Server rejected the Authorization header minted by the configured headersHelper](#server-rejected-the-authorization-header-minted-by-the-configured-headershelper)
  - [MCP permission prompt tool not found](#mcp-permission-prompt-tool-not-found)
  - [OAuth callback port is already in use](#oauth-callback-port-is-already-in-use)
  - [No available ports for OAuth redirect](#no-available-ports-for-oauth-redirect)
  - [/security-review fails without origin/HEAD](#security-review-fails-without-origin-head)
  - [No shell command in a skill or command was run](#no-shell-command-was-run)
  - [Input must be provided when using --print](#input-must-be-provided-when-using-print)
  - [Claude Code can’t read the keyboard here](#claude-code-cant-read-the-keyboard-here)
  - [Input contained only whitespace](#input-contained-only-whitespace)
  - [stream-json input carried over 256M characters with no newline](#stream-json-input-carried-over-256m-characters-with-no-newline)
  - [Unknown command](#unknown-command)
  - [Diff is too large for ultrareview](#diff-is-too-large-for-ultrareview)
  - [Could not find merge-base with the base branch](#could-not-find-merge-base-with-the-base-branch)
  - [Your checkout has no branches](#your-checkout-has-no-branches)
  - [No GitHub account is connected to your Claude account](#no-github-account-is-connected-to-your-claude-account)
  - [Your connected GitHub account can’t see the repository](#your-connected-github-account-cant-see-the-repository)
  - [The GitHub App preflight failed transiently](#the-github-app-preflight-failed-transiently)
  - [The repository upload can’t follow a git setting](#the-repository-upload-cant-follow-a-git-setting)
  - [GitHub isn’t connected to your Claude account](#github-isnt-connected-to-your-claude-account)
  - [A GitHub organization policy is blocking Claude](#a-github-organization-policy-is-blocking-claude)
  - [Single sign-on authorization needed](#single-sign-on-authorization-needed)
  - [Failed to resume the conversation](#failed-to-resume-the-conversation)
  - [No conversation found with the session ID](#no-conversation-found-with-the-session-id)
  - [Windows reported an error (EBADF) when Claude Code read this session’s transcript file](#windows-reported-an-error-ebadf)
  - [Cannot switch renderers in this session](#cannot-switch-renderers-in-this-session)
  - [Claude Code couldn’t restart](#claude-code-couldnt-restart)
  - [Couldn’t open Claude Desktop](#couldnt-open-claude-desktop)
  - [/terminal-setup left your Zed keymap unchanged](#terminal-setup-left-your-zed-keymap-unchanged)
  - [Skill usage reports are not available on this connection](#skill-usage-reports-are-not-available-on-this-connection)
  - [Custom output styles can’t be selected over Remote Control](#custom-output-styles-cant-be-selected-over-remote-control)
  - [Output styles are saved to local settings which this session doesn’t load](#output-styles-are-saved-to-local-settings-which-this-session-doesnt-load)
  - [/recap only runs when you ask for it yourself](#recap-only-runs-when-you-ask-for-it-yourself)
  - [/feedback is disabled by your organization’s policy](#feedback-is-disabled-by-your-organizations-policy)
- [Plugin errors](#plugin-errors)
  - [plugin eval is currently in early access](#plugin-eval-is-currently-in-early-access)
  - [Marketplace is registered from an untrusted source](#marketplace-is-registered-from-an-untrusted-source)
  - [Marketplace name is another spelling of a reserved name](#marketplace-name-is-another-spelling-of-a-reserved-name)
  - [Claude Code refuses the marketplace name](#claude-code-refuses-the-marketplace-name)
  - [Marketplace is already added from a different source](#marketplace-is-already-added-from-a-different-source)
  - [Plugin command references user_config in a shell command](#plugin-command-references-user-config)
  - [Plugin archive integrity check failed](#plugin-archive-integrity-check-failed)
  - [Path escapes plugin directory](#path-escapes-plugin-directory)
  - [Plugin not loaded: its manifest was not read](#plugin-not-loaded-its-manifest-was-not-read)
  - [Path could not be checked](#path-could-not-be-checked)
  - [Marketplace entry path does not stay inside the marketplace directory](#marketplace-entry-path-does-not-stay-inside-the-marketplace-directory)
  - [Failed to load marketplace configuration](#failed-to-load-marketplace-configuration)
  - [Plugin is required by your organization](#plugin-is-required-by-your-organization)
  - [Plugin was not uninstalled](#plugin-was-not-uninstalled)
  - [Skipping connection (recent failure cached; retries automatically in 15 min, or edit the plugin config to retry now)](#skipping-connection-recent-failure-cached)
- [Tool errors](#tool-errors)
  - [No such tool available](#no-such-tool-available)
  - [MCP server connection closed before the tool call was answered](#connection-closed-before-the-tool-call-was-answered)
  - [Agent would be spawned with zero tools](#agent-would-be-spawned-with-zero-tools)
  - [File is covered by a Read deny rule](#file-is-covered-by-a-read-deny-rule)
  - [Path cannot contain null bytes](#path-cannot-contain-null-bytes)
  - [File is too large to read as an image](#file-is-too-large-to-read-as-an-image)
  - [subagent_type is required](#subagent-type-is-required)
  - [Memory index is over its read limit](#memory-index-is-over-its-read-limit)
  - [pkill pattern matches the Claude Code process](#pkill-pattern-matches-the-claude-code-process)
  - [Failed to write to a teammate’s inbox](#failed-to-write-to-a-teammate-inbox)
  - [Teammate’s agent definition was not restored](#teammate-agent-definition-not-restored)
  - [Only a teammate can approve a shutdown request](#only-a-teammate-can-approve-a-shutdown-request)
  - [Message too large for cross-session delivery](#message-too-large-for-cross-session-delivery)
  - [Too many messages to this session just now](#too-many-messages-to-this-session-just-now)
  - [Cross-session message was dropped at the recipient session’s inbox](#cross-session-message-dropped-at-the-inbox)
  - [Refusing to send a cross-session message](#refusing-to-send-a-cross-session-message)
  - [Refusing to read, write, or search a path](#refusing-after-a-symlink-changed)
  - [Task output swap refused](#task-output-swap-refused)
  - [Disk full or disk quota used up](#disk-quota-or-temp-filesystem-is-full)
  - [File is not valid UTF-8](#file-is-not-valid-utf-8)
  - [The source file is not valid UTF-8 text](#the-source-file-is-not-valid-utf-8-text)
  - [Not published: that file is on a network share](#not-published-that-file-is-on-a-network-share)
  - [Not published: Claude sent the same content again after a newer version of the artifact turned it away](#not-published-a-newer-version-of-the-artifact-turned-it-away)
  - [Reading a local file from outside the connected folders in a Cowork session](#reading-a-local-file-from-outside-the-connected-folders)
  - [WebFetch cannot fetch localhost](#webfetch-cannot-fetch-localhost)
  - [WebFetch domain safety check failed](#webfetch-domain-safety-check-failed)
- [Background session errors](#background-session-errors)
  - [Commands refused in a background session](#commands-refused-in-a-background-session)
  - [Write or command blocked because the path cannot be safely resolved](#write-or-command-blocked-because-the-path-cannot-be-safely-resolved)
  - [Write or command blocked because the path names a network location](#write-or-command-blocked-because-the-path-names-a-network-location)
  - [Command blocked by the worktree isolation checks](#command-blocked-by-the-worktree-isolation-checks)
  - [This session has no saved transcript](#this-session-has-no-saved-transcript)
  - [This session is running in another terminal](#this-session-is-running-in-another-terminal)
  - [This session’s saved conversation is no longer on disk](#this-sessions-saved-conversation-is-no-longer-on-disk)
  - [Worktree has commits that are not pushed anywhere](#worktree-has-commits-that-are-not-pushed-anywhere)
  - [Terminal host process died](#terminal-host-process-died)
  - [Session isn’t responding](#session-isnt-responding)
  - [Session was stopped while the respawn was in flight](#session-was-stopped-while-the-respawn-was-in-flight)
  - [Session agent no longer available](#session-agent-no-longer-available)
  - [This session restarted after its next /loop wakeup was due](#restarted-after-its-next-loop-wakeup-was-due)
  - [No LLM gateway: a gateway set in your shell isn’t passed to a session opened from another folder](#no-llm-gateway-opened-from-another-folder)
  - [CLAUDE_CODE_PROCESS_WRAPPER launcher errors](#claude_code_process_wrapper-launcher-errors)
  - [EUNKNOWN when starting a background session](#eunknown-when-starting-a-background-session)
  - [EACCES when starting a background session](#eacces-when-starting-a-background-session)
  - [Background service exited before it became reachable](#background-service-exited-before-it-became-reachable)
  - [Working directory no longer exists when starting a background session](#working-directory-no-longer-exists-when-starting-a-background-session)
  - [Workspace not trusted when dispatching a background session](#workspace-not-trusted-when-dispatching-a-background-session)
- [Wrapper and IDE errors](#wrapper-and-ide-errors)
  - [Claude Code process exited with code N](#claude-code-process-exited-with-code-n)
  - [Could not locate the Claude CLI on PATH](#could-not-locate-the-claude-cli-on-path)
  - [The connection to Claude Code ended before this message completed](#the-connection-to-claude-code-ended-before-this-message-completed)
- [Rewind warnings and errors](#rewind-warnings-and-errors)
  - [Restored the code, but skipped files](#restored-the-code-but-skipped-files)
  - [No files were restored](#no-files-were-restored)
- [Session saving warnings](#session-saving-warnings)
  - [Transcript writes are failing](#transcript-writes-are-failing)
  - [Transcript saving is off because CLAUDE_CODE_SKIP_PROMPT_HISTORY is set](#transcript-saving-is-off-skip-prompt-history)
  - [Transcript saving is off because of an inherited CLAUDE_CODE_CHILD_SESSION marker](#transcript-saving-is-off-child-session-marker)
- [Configuration warnings](#configuration-warnings)
  - [Claude Code exited after an unrecoverable interface error](#exited-after-an-unrecoverable-interface-error)
  - [Agent descriptions are over the 15.0k-token limit](#agent-descriptions-are-over-the-15000-token-limit)
  - [Hook needs quotes around a path with a space](#hook-needs-quotes-around-a-path-with-a-space)
  - [Instruction file not loaded](#instruction-file-not-loaded)
  - [A skill, command, or workflow wasn’t loaded because its name is reserved](#a-skill-command-or-workflow-wasnt-loaded-because-its-name-is-reserved)
  - [Skill or command name refused](#skill-or-command-name-refused)
  - [Workspace has not been trusted](#workspace-has-not-been-trusted)
  - [Working directory is a network path](#working-directory-is-a-network-path)
  - [Remote managed settings failed to load](#remote-managed-settings-failed-to-load)
  - [Managed settings were not approved](#managed-settings-were-not-approved)
  - [Managed settings need your approval](#managed-settings-need-your-approval)
  - [Managed settings block the default model](#managed-settings-block-the-default-model)
  - [Managed settings don’t allow this API provider](#managed-settings-dont-allow-this-api-provider)
  - [MCP server is blocked by enterprise managed policy](#mcp-server-is-blocked-by-enterprise-managed-policy)
  - [MCP server name is reserved](#mcp-server-name-is-reserved)
  - [Managed settings document could not be parsed](#managed-settings-document-could-not-be-parsed)
  - [Unable to read managed policy settings](#unable-to-read-managed-policy-settings)
  - [Managed settings contain invalid entries, including PreToolUse/PermissionRequest hooks that are NOT loaded](#managed-settings-hooks-not-loaded)
  - [otelHeadersHelper failed](#otelheadershelper-failed)
  - [headersHelper not run](#headershelper-not-run)
  - [Malformed Tool(content) rule](#malformed-tool-content-rule)
  - [Matches no tool · check for typos](#matches-no-tool)
  - [Is not matched by file permission checks](#is-not-matched-by-file-permission-checks)
  - [Has a wildcard before the rest of the command](#has-a-wildcard-before-the-rest-of-the-command)
  - [Denying Bash also turns off the PowerShell tool](#denying-bash-also-turns-off-the-powershell-tool)
  - [crossSessionInbound must be one of accept, hold, refuse](#crosssessioninbound-must-be-one-of-accept-hold-refuse)
  - [ANTHROPIC_FOUNDRY_RESOURCE must be a Foundry resource name](#anthropic-foundry-resource-must-be-a-foundry-resource-name)
  - [The 200K limit isn’t enforced](#the-200k-limit-isnt-enforced)
  - [Unrecognized model ID on a request](#unrecognized-model-id-on-a-request)
  - [Sandbox allow entries are ignored under a managed lock](#sandbox-allow-entries-are-ignored-under-a-managed-lock)
  - [Sandbox mask files left behind at write-deny paths](#stale-sandbox-mask-files-left-by-a-killed-session)
- [Responses seem lower quality than usual](#responses-seem-lower-quality-than-usual)
- [Report an error](#report-an-error)

Troubleshooting

# Error reference

Copy pageCopy page

Look up Claude Code runtime error messages with what each one means and how to fix it.

Copy pageCopy page

This page lists runtime errors Claude Code displays and how to recover from each one, plus what to check when responses seem off without an error. For installation errors such as `command not found` or TLS failures during setup, see [Troubleshoot installation and login](troubleshoot-install.md). Except for [Wrapper and IDE errors](#wrapper-and-ide-errors), which the launching program prints rather than Claude Code itself, these errors and recovery commands apply across the CLI, the [Desktop app](../16-Mobile-Desktop/desktop.md), and [cloud sessions](claude-code-on-the-web.md), since all three wrap the same Claude Code CLI. For other surface-specific issues, see the troubleshooting section on that surface’s page.

Claude Code calls the Claude API for model responses, so most runtime errors map to an underlying API error code. This page covers what each error means inside Claude Code and how to recover. For the raw HTTP status code definitions, see the [Claude Platform error reference](../04-API-Reference/Endpoints/errors.md).


[​](#find-your-error)

Find your error

Match the message you see to a section below.

| Message                                                                                                                                                                                                                                                              | Section                                                                                                                                                                                                                        |
|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `API Error: 500 Internal server error`                                                                                                                                                                                                                               | [Server errors](#api-error-500-internal-server-error)                                                                                                                                                                          |
| `API Error: Repeated 529 Overloaded errors`                                                                                                                                                                                                                          | [Server errors](#api-error-repeated-529-overloaded-errors)                                                                                                                                                                     |
| `Opus is experiencing high load` / `Fable is experiencing high load`                                                                                                                                                                                                 | [Server errors](#api-error-repeated-529-overloaded-errors)                                                                                                                                                                     |
| `Request timed out`                                                                                                                                                                                                                                                  | [Server errors](#request-timed-out), or [Network](#unable-to-connect-to-api) if the message mentions your internet connection                                                                                                  |
| `API Error: No response from API`                                                                                                                                                                                                                                    | [Server errors](#no-response-from-api)                                                                                                                                                                                         |
| `API Error: Stream idle timeout - no chunks received`                                                                                                                                                                                                                | [Streaming idle watchdogs](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs), or [Long thinking ends in proxy timeouts](../13-Enterprise-Admin/claude-apps-gateway-deploy.md#long-thinking-ends-in-proxy-timeouts) behind a Claude apps gateway |
| `Server error mid-response. The response above may be incomplete.`                                                                                                                                                                                                   | [Server errors](#the-response-above-may-be-incomplete)                                                                                                                                                                         |
| `Connection lost mid-response` / `Your computer went to sleep mid-response` / `The response stopped arriving`                                                                                                                                                        | [Server errors](#the-response-above-may-be-incomplete)                                                                                                                                                                         |
| `Connection closed mid-response` / `Response stalled mid-stream`                                                                                                                                                                                                     | [Server errors](#the-response-above-may-be-incomplete)                                                                                                                                                                         |
| `Part of the response never arrived` / `The response stream was malformed`                                                                                                                                                                                           | [Server errors](#the-response-above-may-be-incomplete)                                                                                                                                                                         |
| `API Error: Content block not found` / `API Error: Content block already closed` / `API Error: Stream event unreadable`                                                                                                                                              | [Server errors](#the-response-above-may-be-incomplete)                                                                                                                                                                         |
| `Connection lost before a response was produced` / `Your computer went to sleep before a response was produced` / `The response stalled before a response was produced`                                                                                              | [Automatic retries](#automatic-retries)                                                                                                                                                                                        |
| `Connection closed while thinking` / `Response stalled while thinking`                                                                                                                                                                                               | [Automatic retries](#automatic-retries)                                                                                                                                                                                        |
| `Connection lost while your computer was asleep`                                                                                                                                                                                                                     | [Automatic retries](#automatic-retries)                                                                                                                                                                                        |
| `The model's tool call could not be parsed (retry also failed).`                                                                                                                                                                                                     | [Automatic retries](#automatic-retries)                                                                                                                                                                                        |
| `<model> is temporarily unavailable, so auto mode cannot determine the safety of...`                                                                                                                                                                                 | [Server errors](#auto-mode-cannot-determine-the-safety-of-an-action)                                                                                                                                                           |
| `Auto mode could not evaluate this action and is blocking it for safety`                                                                                                                                                                                             | [Server errors](#auto-mode-cannot-determine-the-safety-of-an-action)                                                                                                                                                           |
| `Not run · auto mode's check had no usable answer`                                                                                                                                                                                                                   | [Server errors](#auto-mode-cannot-determine-the-safety-of-an-action)                                                                                                                                                           |
| `Auto mode classifier transcript exceeded context window`                                                                                                                                                                                                            | [Server errors](#auto-mode-cannot-determine-the-safety-of-an-action)                                                                                                                                                           |
| `Agent aborted: auto mode classifier request refused by the safety safeguard`                                                                                                                                                                                        | [Server errors](#auto-mode-cannot-determine-the-safety-of-an-action)                                                                                                                                                           |
| `The server-side auto mode classifier gave no verdict`                                                                                                                                                                                                               | [Server errors](#the-server-returned-no-safety-verdict)                                                                                                                                                                        |
| `<tool> was not reviewed and did not run: the conversation is too long for auto mode's classifier`                                                                                                                                                                   | [Server errors](#was-not-reviewed-and-did-not-run)                                                                                                                                                                             |
| `Auto mode is unavailable — the server returned no safety verdict for the last 10 responses`                                                                                                                                                                         | [Server errors](#the-server-returned-no-safety-verdict)                                                                                                                                                                        |
| `Agent terminated early due to an API error`                                                                                                                                                                                                                         | [Server errors](#agent-terminated-early-due-to-an-api-error)                                                                                                                                                                   |
| `You've hit your session limit` / `You've hit your weekly limit` / `You've hit your Opus limit` / `You've hit your Sonnet limit`                                                                                                                                     | [Usage limits](#youve-hit-your-session-limit)                                                                                                                                                                                  |
| `Usage credits required for 1M context`                                                                                                                                                                                                                              | [Usage limits](#usage-credits-required-for-1m-context)                                                                                                                                                                         |
| `the prompt to confirm went unanswered — nothing was sent`                                                                                                                                                                                                           | [Usage limits](#the-prompt-to-confirm-went-unanswered)                                                                                                                                                                         |
| `Server is temporarily limiting requests`                                                                                                                                                                                                                            | [Usage limits](#server-is-temporarily-limiting-requests)                                                                                                                                                                       |
| `Request rejected (429)`                                                                                                                                                                                                                                             | [Usage limits](#request-rejected-429)                                                                                                                                                                                          |
| `Credit balance is too low`                                                                                                                                                                                                                                          | [Usage limits](#credit-balance-is-too-low)                                                                                                                                                                                     |
| `You've hit your monthly spend limit` / `You've hit your individual spend limit` / `You've hit your org's monthly spend limit` / `You've hit your channel's monthly spend limit` / `You've hit your team's shared budget` / `You've hit your individual usage limit` | [Usage limits](#youve-hit-your-monthly-spend-limit)                                                                                                                                                                            |
| `Could not update your spend limit`                                                                                                                                                                                                                                  | [Usage limits](#could-not-update-your-spend-limit)                                                                                                                                                                             |
| `spend limit reached` / `spend limit unavailable`                                                                                                                                                                                                                    | [Usage limits](#spend-limit-reached)                                                                                                                                                                                           |
| `Not logged in · Please run /login`                                                                                                                                                                                                                                  | [Authentication](#not-logged-in)                                                                                                                                                                                               |
| `Couldn't save your login`                                                                                                                                                                                                                                           | [Authentication](#couldnt-save-your-login)                                                                                                                                                                                     |
| `Authentication required · Sign in again to continue`                                                                                                                                                                                                                | [Authentication](#not-logged-in)                                                                                                                                                                                               |
| `Could not resolve authentication method`                                                                                                                                                                                                                            | [Authentication](#could-not-resolve-authentication-method)                                                                                                                                                                     |
| `Invalid API key`                                                                                                                                                                                                                                                    | [Authentication](#invalid-api-key)                                                                                                                                                                                             |
| `Your apiKeyHelper script is failing`                                                                                                                                                                                                                                | [Authentication](#your-apikeyhelper-script-is-failing)                                                                                                                                                                         |
| `Invalid auth token · Fix external auth token`                                                                                                                                                                                                                       | [Authentication](#invalid-request-header-value)                                                                                                                                                                                |
| `Invalid ANTHROPIC_CUSTOM_HEADERS · Fix the environment variable`                                                                                                                                                                                                    | [Authentication](#invalid-request-header-value)                                                                                                                                                                                |
| `Invalid request header from the environment · Fix the environment variable`                                                                                                                                                                                         | [Authentication](#invalid-request-header-value)                                                                                                                                                                                |
| `This organization has been disabled`                                                                                                                                                                                                                                | [Authentication](#this-organization-has-been-disabled)                                                                                                                                                                         |
| `Your organization has disabled API key authentication`                                                                                                                                                                                                              | [Authentication](#your-organization-has-disabled-api-key-authentication)                                                                                                                                                       |
| `Your organization has disabled Claude subscription access`                                                                                                                                                                                                          | [Authentication](#your-organization-has-disabled-claude-subscription-access)                                                                                                                                                   |
| `Routines are disabled by your organization's policy`                                                                                                                                                                                                                | [Authentication](#routines-are-disabled-by-your-organizations-policy)                                                                                                                                                          |
| `Remote Control is only available when using Claude via api.anthropic.com`                                                                                                                                                                                           | [Authentication](#remote-control-requires-the-anthropic-api)                                                                                                                                                                   |
| `OAuth token refresh failed — run /login to re-authenticate`                                                                                                                                                                                                         | [Authentication](#remote-control-couldnt-refresh-your-login)                                                                                                                                                                   |
| `JWT refresh failed: no OAuth token — run /login`                                                                                                                                                                                                                    | [Authentication](#remote-control-couldnt-refresh-your-login)                                                                                                                                                                   |
| `Claude.ai login expired`                                                                                                                                                                                                                                            | [Authentication](#remote-control-couldnt-refresh-your-login)                                                                                                                                                                   |
| `Claude.ai login was rejected — run /login, then /remote-control`                                                                                                                                                                                                    | [Authentication](#remote-control-couldnt-refresh-your-login)                                                                                                                                                                   |
| `OAuth token unavailable — run /login to restore Remote Control`                                                                                                                                                                                                     | [Authentication](#remote-control-couldnt-refresh-your-login)                                                                                                                                                                   |
| `Signed out of Claude — run /login, then /remote-control`                                                                                                                                                                                                            | [Authentication](#remote-control-couldnt-refresh-your-login)                                                                                                                                                                   |
| `Remote Control could not renew this computer's connection`                                                                                                                                                                                                          | [Authentication](#remote-control-could-not-renew-this-computers-connection)                                                                                                                                                    |
| `signed-in claude.ai account or organization changed on this machine`                                                                                                                                                                                                | [Authentication](#remote-control-stopped-because-the-signed-in-account-changed)                                                                                                                                                |
| `Remote Control stopped — the app running this session is now signed in to a different Claude account`                                                                                                                                                               | [Authentication](#remote-control-stopped-because-the-app-running-the-session-signed-out-or-switched-accounts)                                                                                                                  |
| `Remote Control stopped — the app running this session is signed out of Claude`                                                                                                                                                                                      | [Authentication](#remote-control-stopped-because-the-app-running-the-session-signed-out-or-switched-accounts)                                                                                                                  |
| `Couldn't verify your organization's policy for remote control`                                                                                                                                                                                                      | [Troubleshoot Remote Control](remote-control.md#couldnt-verify-your-organizations-policy-for-remote-control)                                                                                                             |
| `Remote Control is disabled by your organization's policy`                                                                                                                                                                                                           | [Troubleshoot Remote Control](remote-control.md#remote-control-is-disabled-by-your-organizations-policy)                                                                                                                 |
| `Remote Control was turned off by your organization's policy`                                                                                                                                                                                                        | [Troubleshoot Remote Control](remote-control.md#remote-control-was-turned-off-by-your-organizations-policy)                                                                                                              |
| `OAuth token revoked` / `OAuth token has expired`                                                                                                                                                                                                                    | [Authentication](#oauth-token-revoked-or-expired)                                                                                                                                                                              |
| `Failed to authenticate: OAuth token revoked`                                                                                                                                                                                                                        | [Authentication](#oauth-token-revoked-or-expired)                                                                                                                                                                              |
| `Your account does not have access to Claude. Please login again or contact your administrator.`                                                                                                                                                                     | [Authentication](#oauth-token-revoked-or-expired)                                                                                                                                                                              |
| `API Error: 401 Invalid authentication credentials`                                                                                                                                                                                                                  | [Authentication](#api-error-401-invalid-authentication-credentials)                                                                                                                                                            |
| `Login expired · Please run /login`                                                                                                                                                                                                                                  | [Authentication](#login-expired)                                                                                                                                                                                               |
| `The browser can't return the sign-in to Claude Code automatically`                                                                                                                                                                                                  | [Authentication](#couldnt-start-the-local-sign-in-listener)                                                                                                                                                                    |
| `Couldn't start the local listener that receives the browser sign-in. Try again.`                                                                                                                                                                                    | [Authentication](#couldnt-start-the-local-sign-in-listener)                                                                                                                                                                    |
| `Failed to start OAuth callback server`                                                                                                                                                                                                                              | [Authentication](#failed-to-start-oauth-callback-server)                                                                                                                                                                       |
| `Claude login not accepted · Run /login, then try again`                                                                                                                                                                                                             | [Authentication](#claude-login-not-accepted)                                                                                                                                                                                   |
| `Artifacts need a claude.ai login`                                                                                                                                                                                                                                   | [Authentication](#artifacts-need-a-claude-ai-login)                                                                                                                                                                            |
| `Not signed in to the Cloud gateway — run /login.`                                                                                                                                                                                                                   | [Authentication](#administrator-policy-requires-a-cloud-gateway-sign-in)                                                                                                                                                       |
| `Administrator policy requires a Cloud gateway sign-in on this machine`                                                                                                                                                                                              | [Authentication](#administrator-policy-requires-a-cloud-gateway-sign-in)                                                                                                                                                       |
| `Failed to authenticate: OAuth session expired and could not be refreshed`                                                                                                                                                                                           | [Authentication](#login-expired)                                                                                                                                                                                               |
| `Could not refresh your login because another Claude Code process is refreshing it`                                                                                                                                                                                  | [Authentication](#could-not-refresh-your-login)                                                                                                                                                                                |
| `Failed to refresh OAuth token: another Claude Code process is refreshing it or exited mid-refresh`                                                                                                                                                                  | [Authentication](#could-not-refresh-your-login)                                                                                                                                                                                |
| `Your account is on hold and can't use Claude Code. View details or appeal: https://claude.ai/restricted`                                                                                                                                                            | [Authentication](#your-account-is-on-hold)                                                                                                                                                                                     |
| `Your account is on hold and can't sign in to Claude Code. View details or appeal: https://claude.ai/restricted`                                                                                                                                                     | [Authentication](#your-account-is-on-hold)                                                                                                                                                                                     |
| `Anthropic profile login expired · Re-authenticate your Anthropic profile`                                                                                                                                                                                           | [Authentication](#anthropic-profile-login-expired)                                                                                                                                                                             |
| `Login expired · Run /login to sign in again, or re-authenticate your Anthropic profile`                                                                                                                                                                             | [Authentication](#anthropic-profile-login-expired)                                                                                                                                                                             |
| `Anthropic profile login expired · Run /login to use your claude.ai account instead, or re-authenticate the profile`                                                                                                                                                 | [Authentication](#anthropic-profile-login-expired)                                                                                                                                                                             |
| `does not meet scope requirement user:profile`                                                                                                                                                                                                                       | [Authentication](#oauth-scope-requirement)                                                                                                                                                                                     |
| `claude.ai rejected the session token` / `session token rejected`                                                                                                                                                                                                    | [Authentication](#claude-ai-rejected-the-session-token)                                                                                                                                                                        |
| `MCP server "<name>" needs you to sign in again (run /mcp to re-authenticate)`                                                                                                                                                                                       | [Authentication](#mcp-server-needs-you-to-sign-in-again)                                                                                                                                                                       |
| `rejected the credential from its headersHelper` / `rejected the Authorization header in its config`                                                                                                                                                                 | [Authentication](#mcp-server-needs-you-to-sign-in-again)                                                                                                                                                                       |
| `(check the helper, then start a new task or chat)` / `(update it, then start a new task or chat)`                                                                                                                                                                   | [Authentication](#mcp-credential-rejected-in-cowork)                                                                                                                                                                           |
| `MCP server "<name>" needs additional permissions (scope: "<scope>") — run /mcp to re-authenticate`                                                                                                                                                                  | [Authentication](#mcp-server-needs-you-to-sign-in-again)                                                                                                                                                                       |
| `MCP server "<name>" requires re-authorization (token expired)`                                                                                                                                                                                                      | [Authentication](#mcp-server-needs-you-to-sign-in-again)                                                                                                                                                                       |
| `Couldn't read the stored credentials for MCP server "<name>", so the request didn't run`                                                                                                                                                                            | [Authentication](#couldnt-read-the-stored-credentials-for-mcp-server)                                                                                                                                                          |
| `A request to MCP server "<name>" was sent without your stored credentials`                                                                                                                                                                                          | [Authentication](#couldnt-read-the-stored-credentials-for-mcp-server)                                                                                                                                                          |
| `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)                                                                                                                                                                |
| `Issuer mismatch in authorization response (RFC 9207)`                                                                                                                                                                                                               | [Authentication](#issuer-mismatch-in-authorization-response)                                                                                                                                                                   |
| `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)                                                                                                                                                    |
| `Cloud gateway session expired — run /login to reconnect.`                                                                                                                                                                                                           | [Authentication](#cloud-gateway-session-expired)                                                                                                                                                                               |
| `Cloud gateway <url> no longer accepts this session`                                                                                                                                                                                                                 | [Authentication](#cloud-gateway-session-expired)                                                                                                                                                                               |
| `Sign-in timed out while waiting for you to continue. Try again.`                                                                                                                                                                                                    | [Authentication](#sign-in-timed-out-while-waiting-for-you-to-continue)                                                                                                                                                         |
| `AWS credentials expired or invalid`                                                                                                                                                                                                                                 | [Authentication](#aws-credentials-expired-or-invalid)                                                                                                                                                                          |
| `AWS authentication failed`                                                                                                                                                                                                                                          | [Authentication](#aws-authentication-failed)                                                                                                                                                                                   |
| `Google Cloud credentials expired or invalid`                                                                                                                                                                                                                        | [Authentication](#google-cloud-credentials-expired-or-invalid)                                                                                                                                                                 |
| `Google Cloud authentication failed`                                                                                                                                                                                                                                 | [Authentication](#google-cloud-authentication-failed)                                                                                                                                                                          |
| `Microsoft Foundry authentication failed`                                                                                                                                                                                                                            | [Authentication](#microsoft-foundry-authentication-failed)                                                                                                                                                                     |
| `Gateway refused the request`                                                                                                                                                                                                                                        | [Authentication](#gateway-refused-the-request)                                                                                                                                                                                 |
| `Could not load AWS credentials` / `Could not load Google Cloud credentials`                                                                                                                                                                                         | [Authentication](#could-not-load-aws-or-google-cloud-credentials)                                                                                                                                                              |
| `AWS default-chain credential resolve timed out`                                                                                                                                                                                                                     | [Authentication](#aws-default-chain-credential-resolve-timed-out)                                                                                                                                                              |
| `Timed out after 60s waiting for AWS`                                                                                                                                                                                                                                | [Authentication](#bedrock-setup-verification-timed-out-waiting-for-aws)                                                                                                                                                        |
| `A request to AWS timed out. Check your network and proxy settings, then try again.`                                                                                                                                                                                 | [Authentication](#bedrock-setup-verification-timed-out-waiting-for-aws)                                                                                                                                                        |
| `Could not load the default credentials` on Google Cloud’s Agent Platform                                                                                                                                                                                            | [Authentication](#could-not-load-aws-or-google-cloud-credentials)                                                                                                                                                              |
| `Unable to connect to API`                                                                                                                                                                                                                                           | [Network](#unable-to-connect-to-api)                                                                                                                                                                                           |
| `Connection refused —` / `Can't reach the API server —` / `No internet route —` / `Couldn't connect through your proxy` / `Connection dropped`, each with an error code in parentheses                                                                               | [Network](#unable-to-connect-to-api)                                                                                                                                                                                           |
| `Unable to connect to Anthropic services` during setup                                                                                                                                                                                                               | [Network](#unable-to-connect-to-anthropic-services)                                                                                                                                                                            |
| `Socket is closed`                                                                                                                                                                                                                                                   | [Network](#socket-is-closed)                                                                                                                                                                                                   |
| `Waiting for API response · will retry in`                                                                                                                                                                                                                           | [Automatic retries](#automatic-retries), or [Network](#unable-to-connect-to-api) if it persists                                                                                                                                |
| `API returned an empty or malformed response`                                                                                                                                                                                                                        | [Network](#api-returned-an-empty-or-malformed-response)                                                                                                                                                                        |
| `Streaming response ended before any complete data was received`                                                                                                                                                                                                     | [Network](#streaming-response-ended-before-any-complete-data-was-received)                                                                                                                                                     |
| `Bedrock streaming response has content-type "..."; expected "application/vnd.amazon.eventstream"`                                                                                                                                                                   | [Network](#bedrock-streaming-response-has-an-unexpected-content-type)                                                                                                                                                          |
| `SSL certificate verification failed`                                                                                                                                                                                                                                | [Network](#ssl-certificate-errors)                                                                                                                                                                                             |
| `SSL certificate error (...)` during login or startup                                                                                                                                                                                                                | [Network](#ssl-certificate-errors)                                                                                                                                                                                             |
| `unable to get local issuer certificate`                                                                                                                                                                                                                             | [Network](#ssl-certificate-errors)                                                                                                                                                                                             |
| `403` with `x-deny-reason: host_not_allowed` in a cloud session or cloud scheduled task                                                                                                                                                                              | [Network](#host-not-allowed-in-a-cloud-session)                                                                                                                                                                                |
| `proxy refused the connection`                                                                                                                                                                                                                                       | [Network](#the-proxy-refused-the-connection)                                                                                                                                                                                   |
| `403` with `GitHub GraphQL is not available from Claude Code sessions` in a cloud session                                                                                                                                                                            | [GitHub proxy](cloud-environments.md#github-proxy)                                                                                                                                                                       |
| `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)                                                                                                                                            |
| `Failed to fetch session from Sessions API: Failed to fetch session logs`                                                                                                                                                                                            | [Network](#failed-to-fetch-session-from-sessions-api)                                                                                                                                                                          |
| `Couldn't reconnect to your Remote Control session`                                                                                                                                                                                                                  | [Network](#couldnt-reconnect-to-your-remote-control-session)                                                                                                                                                                   |
| `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)                                                                                                                                                                      |
| `Couldn't share the transcript.`                                                                                                                                                                                                                                     | [Network](#couldnt-share-the-transcript)                                                                                                                                                                                       |
| `Couldn't send feedback`                                                                                                                                                                                                                                             | [Network](#couldnt-send-feedback)                                                                                                                                                                                              |
| `MCP server "<name>" connection timed out. Your computer went to sleep or its clock changed while connecting.`                                                                                                                                                       | [Network](#mcp-server-connection-timed-out-during-a-sleep-or-clock-change)                                                                                                                                                     |
| `Prompt is too long` / `Input is too long for requested model`                                                                                                                                                                                                       | [Request errors](#prompt-is-too-long)                                                                                                                                                                                          |
| `Prompt is too long · automatic compaction failed:`                                                                                                                                                                                                                  | [Request errors](#prompt-is-too-long)                                                                                                                                                                                          |
| `Prompt is too long · this conversation is a single exchange` / `A single-exchange conversation cannot be compacted`                                                                                                                                                 | [Request errors](#prompt-is-too-long)                                                                                                                                                                                          |
| `Context limit reached · /compact or /clear to continue`                                                                                                                                                                                                             | [Request errors](#prompt-is-too-long)                                                                                                                                                                                          |
| `Context limit reached · /clear to continue`                                                                                                                                                                                                                         | [Request errors](#prompt-is-too-long)                                                                                                                                                                                          |
| `capability_rejected: prompt_too_long` on a Claude apps gateway session                                                                                                                                                                                              | [Request errors](#prompt-is-too-long)                                                                                                                                                                                          |
| `upstream rejected the request` / `request too large for this upstream` on a Claude apps gateway session                                                                                                                                                             | [Upstream error messages](../13-Enterprise-Admin/claude-apps-gateway-config.md#upstream-error-messages)                                                                                                                                         |
| `upstream rate limit exceeded` on a Claude apps gateway session                                                                                                                                                                                                      | [Upstream error messages](../13-Enterprise-Admin/claude-apps-gateway-config.md#upstream-error-messages)                                                                                                                                         |
| `all upstreams failed (N attempted)` on a Claude apps gateway session                                                                                                                                                                                                | [Upstream error messages](../13-Enterprise-Admin/claude-apps-gateway-config.md#upstream-error-messages)                                                                                                                                         |
| `Claude Code may not be enabled for your organization` after a Claude apps gateway sign-in                                                                                                                                                                           | [Claude apps gateway troubleshooting](../13-Enterprise-Admin/claude-apps-gateway-deploy.md#troubleshooting)                                                                                                                                     |
| `Context exceeds the ...-token limit by ... tokens` in `/context` output                                                                                                                                                                                             | [Request errors](#context-exceeds-the-token-limit)                                                                                                                                                                             |
| `Request too large`                                                                                                                                                                                                                                                  | [Request errors](#request-too-large)                                                                                                                                                                                           |
| `Request too large for the API's 32MB request limit`                                                                                                                                                                                                                 | [Request errors](#request-too-large)                                                                                                                                                                                           |
| `Image was too large`                                                                                                                                                                                                                                                | [Request errors](#image-was-too-large)                                                                                                                                                                                         |
| `API Error: an image in the conversation could not be processed and was removed`                                                                                                                                                                                     | [Request errors](#image-was-too-large)                                                                                                                                                                                         |
| `Unable to resize image`                                                                                                                                                                                                                                             | [Request errors](#unable-to-resize-image)                                                                                                                                                                                      |
| `Request rejected as unprocessable by the model`                                                                                                                                                                                                                     | [Request errors](#request-rejected-as-unprocessable-by-the-model)                                                                                                                                                              |
| `PDF too large` / `PDF is password protected` / `pdftoppm is not installed`                                                                                                                                                                                          | [Request errors](#pdf-errors)                                                                                                                                                                                                  |
| `Extra inputs are not permitted`                                                                                                                                                                                                                                     | [Request errors](#extra-inputs-are-not-permitted)                                                                                                                                                                              |
| `API Error: 400 ... tools.N.custom.input_schema: JSON schema is invalid` / `Property keys should match pattern`                                                                                                                                                      | [Request errors](#tool-input-schema-is-invalid)                                                                                                                                                                                |
| `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)                                                                                                                                                                           |
| `tools.N.custom.name: String should have at most 128 characters`                                                                                                                                                                                                     | [Request errors](#mcp-tool-name-over-128-characters)                                                                                                                                                                           |
| `tool_use.name: String should have at most 200 characters`                                                                                                                                                                                                           | [Request errors](#tool-use-name-over-200-characters)                                                                                                                                                                           |
| `There's an issue with the selected model`                                                                                                                                                                                                                           | [Request errors](#theres-an-issue-with-the-selected-model)                                                                                                                                                                     |
| `Model ... is not a recognized model id`                                                                                                                                                                                                                             | [Request errors](#model-is-not-a-recognized-model-id)                                                                                                                                                                          |
| `Model ... not found`                                                                                                                                                                                                                                                | [Request errors](#model-not-found)                                                                                                                                                                                             |
| `Couldn't confirm model ... with the API`                                                                                                                                                                                                                            | [Request errors](#couldnt-confirm-model-with-the-api)                                                                                                                                                                          |
| `API error: ... · model not changed`                                                                                                                                                                                                                                 | [Request errors](#api-error-model-not-changed)                                                                                                                                                                                 |
| `Claude Opus is not available with the Claude Pro plan`                                                                                                                                                                                                              | [Request errors](#claude-opus-is-not-available-with-the-claude-pro-plan)                                                                                                                                                       |
| `Claude Code ... does not support this model; version ... or newer is required`                                                                                                                                                                                      | [Request errors](#claude-code-does-not-support-this-model)                                                                                                                                                                     |
| `Claude Code ... is older than the minimum version required by your organization's policy`                                                                                                                                                                           | [Request errors](#claude-code-does-not-support-this-model)                                                                                                                                                                     |
| `Model ... is restricted by your organization's settings`                                                                                                                                                                                                            | [Request errors](#model-is-restricted-by-your-organizations-settings)                                                                                                                                                          |
| `Model ... is not available. Your organization restricts model selection.`                                                                                                                                                                                           | [Request errors](#model-is-restricted-by-your-organizations-settings)                                                                                                                                                          |
| `Can't switch to the default model`                                                                                                                                                                                                                                  | [Request errors](#cant-switch-to-the-default-model)                                                                                                                                                                            |
| `Model switch ... blocked by a PreModelSwitch hook`                                                                                                                                                                                                                  | [Request errors](#model-switch-was-blocked-by-a-premodelswitch-hook)                                                                                                                                                           |
| `couldn't save it as your default` / `couldn't confirm it was saved as your default`                                                                                                                                                                                 | [Request errors](#couldnt-save-it-as-your-default)                                                                                                                                                                             |
| `is less capable than the current main model` / `Advisor will not activate on the main model` / `cannot advise`                                                                                                                                                      | [Request errors](#advisor-is-less-capable-than-the-current-main-model)                                                                                                                                                         |
| `thinking.type.enabled is not supported for this model`                                                                                                                                                                                                              | [Request errors](#thinking-type-enabled-is-not-supported-for-this-model)                                                                                                                                                       |
| `Effort '<level>' isn't available with thinking turned off on this model`                                                                                                                                                                                            | [Request errors](#effort-isnt-available-with-thinking-turned-off)                                                                                                                                                              |
| `effort '<level>' is not supported when thinking is disabled`                                                                                                                                                                                                        | [Request errors](#effort-isnt-available-with-thinking-turned-off)                                                                                                                                                              |
| `max_tokens must be greater than thinking.budget_tokens`                                                                                                                                                                                                             | [Request errors](#thinking-budget-exceeds-output-limit)                                                                                                                                                                        |
| `Claude's response exceeded the ... output token maximum`                                                                                                                                                                                                            | [Request errors](#response-exceeded-the-output-token-maximum)                                                                                                                                                                  |
| `API Error: 400 due to tool use concurrency issues`                                                                                                                                                                                                                  | [Request errors](#tool-use-or-thinking-block-mismatch)                                                                                                                                                                         |
| `API Error: 400 orphaned tool_result in conversation history`                                                                                                                                                                                                        | [Request errors](#tool-use-or-thinking-block-mismatch)                                                                                                                                                                         |
| `API Error: 400 duplicate tool_use ID in conversation history`                                                                                                                                                                                                       | [Request errors](#tool-use-or-thinking-block-mismatch)                                                                                                                                                                         |
| `Invalid data in redacted_thinking block`                                                                                                                                                                                                                            | [Request errors](#invalid-data-in-redacted-thinking-block)                                                                                                                                                                     |
| `[Unsupported tool content removed]`                                                                                                                                                                                                                                 | [Request errors](#unsupported-tool-content-removed)                                                                                                                                                                            |
| `role 'system' must precede an 'assistant' message`                                                                                                                                                                                                                  | [Request errors](#role-system-must-precede-an-assistant-message)                                                                                                                                                               |
| `Invalid encrypted_content in search_result block` / `Invalid encrypted_index in text block` / `Failed to decrypt web search result content`                                                                                                                         | [Request errors](#invalid-encrypted-content-in-search-result-block)                                                                                                                                                            |
| `Invalid encrypted_stdout in encrypted_code_execution_result block`                                                                                                                                                                                                  | [Request errors](#invalid-encrypted-content-in-search-result-block)                                                                                                                                                            |
| `server_tool_use.name: Input should be` on every turn of a resumed session                                                                                                                                                                                           | [Request errors](#unsupported-tool-content-removed)                                                                                                                                                                            |
| `<model> can't help with this. Start a new session to continue`                                                                                                                                                                                                      | [Request errors](#usage-policy-refusal)                                                                                                                                                                                        |
| `Claude Code is unable to respond to this request, which appears to violate our Usage Policy`                                                                                                                                                                        | [Request errors](#usage-policy-refusal)                                                                                                                                                                                        |
| `<model>'s safeguards flagged this message`                                                                                                                                                                                                                          | [Request errors](#safety-measures-flagged-a-cybersecurity-topic)                                                                                                                                                               |
| `<model>'s safeguards flagged this session`                                                                                                                                                                                                                          | [Request errors](#safety-measures-flagged-a-cybersecurity-topic)                                                                                                                                                               |
| `<model> has safety measures that flagged this message for a cybersecurity topic`                                                                                                                                                                                    | [Request errors](#safety-measures-flagged-a-cybersecurity-topic)                                                                                                                                                               |
| `` Details: `[reasoning_extraction]` ``                                                                                                                                                                                                                              | [Request errors](#safeguards-flagged-a-request-for-claudes-reasoning)                                                                                                                                                          |
| `API Error: Output blocked by content filtering policy`                                                                                                                                                                                                              | [Request errors](#output-blocked-by-content-filtering-policy)                                                                                                                                                                  |
| `Installation was killed before it could finish (exit code 137)`                                                                                                                                                                                                     | [Troubleshoot installation and login](troubleshoot-install.md#installation-was-killed-before-it-could-finish)                                                                                                            |
| `The connection dropped while downloading the update`                                                                                                                                                                                                                | [Troubleshoot installation and login](troubleshoot-install.md#the-connection-dropped-while-downloading-the-update)                                                                                                       |
| `Download timed out: exceeded the total deadline`                                                                                                                                                                                                                    | [Troubleshoot installation and login](troubleshoot-install.md#the-connection-dropped-while-downloading-the-update)                                                                                                       |
| `Release verification failed for Claude Code <version> (<reason>). The update was not installed.`                                                                                                                                                                    | [Troubleshoot installation and login](troubleshoot-install.md#release-verification-failed)                                                                                                                               |
| `Auto-update failed · Run claude doctor`                                                                                                                                                                                                                             | [Troubleshoot installation and login](troubleshoot-install.md#auto-update-failed)                                                                                                                                        |
| `--bg and --print conflict`                                                                                                                                                                                                                                          | [Command-line errors](#conflict-between-bg-and-print)                                                                                                                                                                          |
| `Couldn't tell whether --bg is a flag or text here, so nothing was started`                                                                                                                                                                                          | [Command-line errors](#couldnt-tell-whether-bg-is-a-flag-or-text)                                                                                                                                                              |
| `Error: Cannot use both --append-subagent-system-prompt and --append-subagent-system-prompt-file. Please use only one.`                                                                                                                                              | [Command-line errors](#conflict-between-a-system-prompt-flag-and-its-file-form)                                                                                                                                                |
| `Cloud sessions cannot be created from a --restricted session`                                                                                                                                                                                                       | [Command-line errors](#cloud-sessions-cannot-be-created-from-a-restricted-session)                                                                                                                                             |
| `Cloud sessions are disabled by your organization's policy`                                                                                                                                                                                                          | [Command-line errors](#cloud-sessions-are-disabled-by-your-organizations-policy)                                                                                                                                               |
| `Cloud sessions use your claude.ai login`, at the end of a policy denial that names a credential                                                                                                                                                                     | [Command-line errors](#cloud-sessions-use-your-claude-ai-login)                                                                                                                                                                |
| `Couldn't verify your organization's policy for cloud sessions`                                                                                                                                                                                                      | [Command-line errors](#couldnt-verify-your-organizations-policy-for-cloud-sessions)                                                                                                                                            |
| `Cloud sessions aren't available:` followed by why your organization’s policy couldn’t be loaded                                                                                                                                                                     | [Command-line errors](#couldnt-verify-your-organizations-policy-for-cloud-sessions)                                                                                                                                            |
| `Cloud sessions need a claude.ai sign-in`                                                                                                                                                                                                                            | [Unable to get organization UUID](claude-code-on-the-web.md#unable-to-get-organization-uuid)                                                                                                                             |
| `Nothing was stashed: "<path>" is now a folder in place of a tracked file or link` / `are now folders in place of tracked files or links`                                                                                                                            | [Command-line errors](#nothing-was-stashed-because-a-folder-replaced-a-tracked-file)                                                                                                                                           |
| `Error: --json-schema is not a valid JSON Schema`                                                                                                                                                                                                                    | [Command-line errors](#the-json-schema-value-is-not-a-valid-json-schema)                                                                                                                                                       |
| `Error: Invalid --agents configuration:`                                                                                                                                                                                                                             | [Command-line errors](#invalid-agents-configuration)                                                                                                                                                                           |
| `Error: --agents takes a JSON object, or a file path only with --print (-p)`                                                                                                                                                                                         | [Command-line errors](#invalid-agents-configuration)                                                                                                                                                                           |
| `Error: --agents file not found`                                                                                                                                                                                                                                     | [Command-line errors](#invalid-agents-configuration)                                                                                                                                                                           |
| `Error: Settings file exceeds the 2MiB limit`                                                                                                                                                                                                                        | [Command-line errors](#settings-file-exceeds-the-2mib-limit)                                                                                                                                                                   |
| `The current directory no longer exists (it was deleted or moved)` / `Can't read the current directory`                                                                                                                                                              | [Command-line errors](#the-current-directory-no-longer-exists)                                                                                                                                                                 |
| `Temp directory <dir> ... Refusing to use it` / `Claude Code's temporary directory <dir> could not be created`                                                                                                                                                       | [Command-line errors](#temp-directory-refused-or-cannot-be-created)                                                                                                                                                            |
| `ENOSPC: no space left on device, mkdir '<dir>'`                                                                                                                                                                                                                     | [Command-line errors](#temp-directory-refused-or-cannot-be-created)                                                                                                                                                            |
| `couldn't be resolved to a real location, so its skills, commands, and agents weren't loaded`                                                                                                                                                                        | [Command-line errors](#directory-couldnt-be-resolved-to-a-real-location)                                                                                                                                                       |
| `Error: Workspace not trusted` when starting Remote Control                                                                                                                                                                                                          | [Command-line errors](#workspace-not-trusted-when-starting-remote-control)                                                                                                                                                     |
| `Error: Workspace not trusted` when running `claude ultrareview`                                                                                                                                                                                                     | [Command-line errors](#workspace-not-trusted-when-running-claude-ultrareview)                                                                                                                                                  |
| `Ultrareview did not start`                                                                                                                                                                                                                                          | [Command-line errors](#ultrareview-did-not-start)                                                                                                                                                                              |
| `` `<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)                                                                                                                                                 |
| `--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)                                                                                                                                                      |
| `` `claude import` is not yet available in this build ``                                                                                                                                                                                                             | [Command-line errors](#claude-import-is-not-yet-available-in-this-build)                                                                                                                                                       |
| `Could not read Claude Code config`                                                                                                                                                                                                                                  | [Command-line errors](#could-not-read-claude-code-config)                                                                                                                                                                      |
| `Could not import <server>: <reason>`                                                                                                                                                                                                                                | [Command-line errors](#could-not-import-a-server-from-claude-desktop)                                                                                                                                                          |
| `Cannot add MCP server to scope: managed`                                                                                                                                                                                                                            | [Command-line errors](#cannot-add-mcp-server-to-the-managed-scope)                                                                                                                                                             |
| `Cannot add MCP server: your organization's managed settings allow only MCP servers that plugins provide`                                                                                                                                                            | [Command-line errors](#cannot-add-mcp-server-when-managed-settings-allow-only-plugin-servers)                                                                                                                                  |
| `is Anthropic-hosted and doesn't support local OAuth`                                                                                                                                                                                                                | [Command-line errors](#anthropic-hosted-and-doesnt-support-local-oauth)                                                                                                                                                        |
| `Can't read .mcp.json: it isn't a regular file or is larger than 2097152 bytes`                                                                                                                                                                                      | [Command-line errors](#cant-read-mcp-json)                                                                                                                                                                                     |
| `MCP server "<name>" was not saved to` / `was not removed from`                                                                                                                                                                                                      | [Command-line errors](#mcp-server-was-not-saved-or-removed)                                                                                                                                                                    |
| `MCP server "<name>" may not have been saved` / `may not have been removed`                                                                                                                                                                                          | [Command-line errors](#mcp-server-may-not-have-been-saved-or-removed)                                                                                                                                                          |
| `Server rejected the Authorization header minted by the configured headersHelper`                                                                                                                                                                                    | [Command-line errors](#server-rejected-the-authorization-header-minted-by-the-configured-headershelper)                                                                                                                        |
| `Error: MCP tool <name> (passed via --permission-prompt-tool) not found`                                                                                                                                                                                             | [Command-line errors](#mcp-permission-prompt-tool-not-found)                                                                                                                                                                   |
| `OAuth callback port <port> is already in use — another process may be holding it`                                                                                                                                                                                   | [Command-line errors](#oauth-callback-port-is-already-in-use)                                                                                                                                                                  |
| `No available ports for OAuth redirect`                                                                                                                                                                                                                              | [Command-line errors](#no-available-ports-for-oauth-redirect)                                                                                                                                                                  |
| `Shell command failed for pattern "..."`, from `/security-review` or any skill that injects dynamic context                                                                                                                                                          | [Command-line errors](#security-review-fails-without-origin-head)                                                                                                                                                              |
| `Shell command permission check failed for pattern "..."`, from a skill that injects dynamic context                                                                                                                                                                 | [Command-line errors](#security-review-fails-without-origin-head)                                                                                                                                                              |
| `` Skill <name> requires bash (`shell: bash` in frontmatter) but Git Bash was not found ``                                                                                                                                                                           | [Command-line errors](#security-review-fails-without-origin-head)                                                                                                                                                              |
| `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)                                                                                                                                                                               |
| `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)                                                                                                                                                                |
| `Claude Code can't read the keyboard here: stdin is not a terminal`                                                                                                                                                                                                  | [Command-line errors](#claude-code-cant-read-the-keyboard-here)                                                                                                                                                                |
| `Error: Input contained only whitespace`                                                                                                                                                                                                                             | [Command-line errors](#input-contained-only-whitespace)                                                                                                                                                                        |
| `Blank prompt — the message was only whitespace, so nothing was sent to the model.`                                                                                                                                                                                  | [Command-line errors](#input-contained-only-whitespace)                                                                                                                                                                        |
| `Error: stream-json input carried over 256M characters with no newline`                                                                                                                                                                                              | [Command-line errors](#stream-json-input-carried-over-256m-characters-with-no-newline)                                                                                                                                         |
| `Unknown command: /<name>`, with or without a `Did you mean` suggestion                                                                                                                                                                                              | [Command-line errors](#unknown-command)                                                                                                                                                                                        |
| `Diff is too large for ultrareview` / `PR #<N> is too large for ultrareview`                                                                                                                                                                                         | [Command-line errors](#diff-is-too-large-for-ultrareview)                                                                                                                                                                      |
| `Could not find merge-base with <branch>`                                                                                                                                                                                                                            | [Command-line errors](#could-not-find-merge-base-with-the-base-branch)                                                                                                                                                         |
| `Your checkout has no branches (detached HEAD only)`                                                                                                                                                                                                                 | [Command-line errors](#your-checkout-has-no-branches)                                                                                                                                                                          |
| `Ultrareview clones <owner>/<repo> in the cloud with the GitHub account connected to your Claude account, and none is connected`                                                                                                                                     | [Command-line errors](#no-github-account-is-connected-to-your-claude-account)                                                                                                                                                  |
| `Your connected GitHub account can't see <owner>/<repo>`                                                                                                                                                                                                             | [Command-line errors](#your-connected-github-account-cant-see-the-repository)                                                                                                                                                  |
| `The GitHub App preflight failed transiently (network or service hiccup) — retry in a moment to start from GitHub instead`                                                                                                                                           | [Command-line errors](#the-github-app-preflight-failed-transiently)                                                                                                                                                            |
| `Not uploading this working tree` with `the upload cannot follow that setting`                                                                                                                                                                                       | [Command-line errors](#the-repository-upload-cant-follow-a-git-setting)                                                                                                                                                        |
| `GitHub isn't connected to your Claude account, so this repository can't be cloned in the cloud`                                                                                                                                                                     | [Command-line errors](#github-isnt-connected-to-your-claude-account)                                                                                                                                                           |
| `Your GitHub organization has an IP allowlist that is blocking Claude`                                                                                                                                                                                               | [Command-line errors](#a-github-organization-policy-is-blocking-claude)                                                                                                                                                        |
| `Your GitHub organization requires single sign-on`                                                                                                                                                                                                                   | [Command-line errors](#a-github-organization-policy-is-blocking-claude)                                                                                                                                                        |
| `Your GitHub organization's identity provider (Microsoft Entra ID) has a Conditional Access policy that is blocking Claude`                                                                                                                                          | [Command-line errors](#a-github-organization-policy-is-blocking-claude)                                                                                                                                                        |
| `Single sign-on authorization needed`                                                                                                                                                                                                                                | [Command-line errors](#single-sign-on-authorization-needed)                                                                                                                                                                    |
| `Failed to resume the conversation`                                                                                                                                                                                                                                  | [Command-line errors](#failed-to-resume-the-conversation)                                                                                                                                                                      |
| `No conversation found with session ID: <session-id>`                                                                                                                                                                                                                | [Command-line errors](#no-conversation-found-with-the-session-id)                                                                                                                                                              |
| `Windows reported an error (EBADF) when Claude Code read this session's transcript file`                                                                                                                                                                             | [Command-line errors](#windows-reported-an-error-ebadf)                                                                                                                                                                        |
| `Cannot switch renderers in this session`                                                                                                                                                                                                                            | [Command-line errors](#cannot-switch-renderers-in-this-session)                                                                                                                                                                |
| `Cannot switch renderers while work is running in the background`                                                                                                                                                                                                    | [Command-line errors](#cannot-switch-renderers-in-this-session)                                                                                                                                                                |
| `Claude Code couldn't restart`                                                                                                                                                                                                                                       | [Command-line errors](#claude-code-couldnt-restart)                                                                                                                                                                            |
| `Couldn't open Claude Desktop`                                                                                                                                                                                                                                       | [Command-line errors](#couldnt-open-claude-desktop)                                                                                                                                                                            |
| `Failed to open Claude Desktop. Please try opening it manually.`                                                                                                                                                                                                     | [Command-line errors](#couldnt-open-claude-desktop)                                                                                                                                                                            |
| `Couldn't read your Zed keymap` / `Couldn't back up your Zed keymap` / `Couldn't update your Zed keymap`                                                                                                                                                             | [Command-line errors](#terminal-setup-left-your-zed-keymap-unchanged)                                                                                                                                                          |
| `Your Zed keymap isn't a readable list of keybindings`                                                                                                                                                                                                               | [Command-line errors](#terminal-setup-left-your-zed-keymap-unchanged)                                                                                                                                                          |
| `Skill usage reports are not available on this connection.`                                                                                                                                                                                                          | [Command-line errors](#skill-usage-reports-are-not-available-on-this-connection)                                                                                                                                               |
| `Custom output styles can't be selected over Remote Control or from a relayed message`                                                                                                                                                                               | [Command-line errors](#custom-output-styles-cant-be-selected-over-remote-control)                                                                                                                                              |
| `Output styles are saved to local settings (.claude/settings.local.json), which this session doesn't load`                                                                                                                                                           | [Command-line errors](#output-styles-are-saved-to-local-settings-which-this-session-doesnt-load)                                                                                                                               |
| `/recap only runs when you ask for it yourself in this session`                                                                                                                                                                                                      | [Command-line errors](#recap-only-runs-when-you-ask-for-it-yourself)                                                                                                                                                           |
| `/feedback is disabled by your organization's policy`, or the same for `/bug` or `/share`                                                                                                                                                                            | [Command-line errors](#feedback-is-disabled-by-your-organizations-policy)                                                                                                                                                      |
| `` `plugin eval` is currently in early access `` / `` `plugin eval` is currently unavailable ``                                                                                                                                                                      | [Plugin errors](#plugin-eval-is-currently-in-early-access)                                                                                                                                                                     |
| `cannot be evaluated where sessions load it`                                                                                                                                                                                                                         | [Test plugins with evals](../08-Plugins-Skills/plugin-evals.md#cannot-be-evaluated-where-sessions-load-it)                                                                                                                                    |
| `Marketplace "<name>" is registered from an untrusted source`                                                                                                                                                                                                        | [Plugin errors](#marketplace-is-registered-from-an-untrusted-source)                                                                                                                                                           |
| `Claude Code refuses the marketplace name "<name>"`                                                                                                                                                                                                                  | [Plugin errors](#claude-code-refuses-the-marketplace-name)                                                                                                                                                                     |
| `Marketplace name impersonates an official Anthropic/Claude marketplace`                                                                                                                                                                                             | [Plugin errors](#claude-code-refuses-the-marketplace-name)                                                                                                                                                                     |
| `Marketplace "<name>" is already added from a different source`                                                                                                                                                                                                      | [Plugin errors](#marketplace-is-already-added-from-a-different-source)                                                                                                                                                         |
| `"<name>" is another spelling of "<reserved>", a reserved marketplace name`                                                                                                                                                                                          | [Plugin errors](#marketplace-name-is-another-spelling-of-a-reserved-name)                                                                                                                                                      |
| `Cannot add marketplace "<name>": Claude Code cannot install plugins from a marketplace with this name`                                                                                                                                                              | [Plugin troubleshooting](../08-Plugins-Skills/plugins-troubleshooting.md#cannot-install-plugins-from-a-marketplace-with-this-name)                                                                                                            |
| `Cannot add marketplace "<name>": Claude Code reserves this name and cannot register a marketplace under it`                                                                                                                                                         | [Plugin troubleshooting](../08-Plugins-Skills/plugins-troubleshooting.md#claude-code-reserves-this-name)                                                                                                                                      |
| `Marketplace "<name>" is added but ignored`                                                                                                                                                                                                                          | [Plugin troubleshooting](../08-Plugins-Skills/plugins-troubleshooting.md#marketplace-is-added-but-ignored)                                                                                                                                    |
| `Marketplace "<name>" is registered but was refused (see the debug log)`                                                                                                                                                                                             | [Plugin troubleshooting](../08-Plugins-Skills/plugins-troubleshooting.md#marketplace-is-added-but-ignored)                                                                                                                                    |
| `references ${user_config.*} in a shell-form command`                                                                                                                                                                                                                | [Plugin errors](#plugin-command-references-user-config)                                                                                                                                                                        |
| `Monitor "<name>" from plugin <plugin> references ${user_config.*} in its command`                                                                                                                                                                                   | [Plugin errors](#plugin-command-references-user-config)                                                                                                                                                                        |
| `headersHelper for MCP server '<name>' references ${user_config.*}`                                                                                                                                                                                                  | [Plugin errors](#plugin-command-references-user-config)                                                                                                                                                                        |
| `Plugin archive integrity check failed`                                                                                                                                                                                                                              | [Plugin errors](#plugin-archive-integrity-check-failed)                                                                                                                                                                        |
| `An npm plugin source must name a registry package`                                                                                                                                                                                                                  | [Plugin troubleshooting](../08-Plugins-Skills/plugins-troubleshooting.md#an-npm-plugin-source-must-name-a-registry-package)                                                                                                                   |
| `The packages it lists are not installed` / `The packages it lists were not installed, because`                                                                                                                                                                      | [Plugin troubleshooting](../08-Plugins-Skills/plugins-troubleshooting.md#the-packages-it-lists-are-not-installed)                                                                                                                             |
| `does not load (...), so Claude Code ignores the whole file`                                                                                                                                                                                                         | [Plugin troubleshooting](../08-Plugins-Skills/plugins-troubleshooting.md#does-not-load-so-claude-code-ignores-the-whole-file)                                                                                                                 |
| `path escapes plugin directory`                                                                                                                                                                                                                                      | [Plugin errors](#path-escapes-plugin-directory)                                                                                                                                                                                |
| `Plugin not loaded: its manifest <path> was not read`                                                                                                                                                                                                                | [Plugin errors](#plugin-not-loaded-its-manifest-was-not-read)                                                                                                                                                                  |
| `path could not be checked`                                                                                                                                                                                                                                          | [Plugin errors](#path-could-not-be-checked)                                                                                                                                                                                    |
| `its marketplace entry path does not stay inside the marketplace directory`                                                                                                                                                                                          | [Plugin errors](#marketplace-entry-path-does-not-stay-inside-the-marketplace-directory)                                                                                                                                        |
| `Plugin source path refused`                                                                                                                                                                                                                                         | [Plugin errors](#marketplace-entry-path-does-not-stay-inside-the-marketplace-directory)                                                                                                                                        |
| `Failed to load marketplace configuration`                                                                                                                                                                                                                           | [Plugin errors](#failed-to-load-marketplace-configuration)                                                                                                                                                                     |
| `Marketplace configuration file is corrupted`                                                                                                                                                                                                                        | [Plugin errors](#failed-to-load-marketplace-configuration)                                                                                                                                                                     |
| `Plugin "<name>@synced" is required by your organization and can't be disabled here`                                                                                                                                                                                 | [Plugin errors](#plugin-is-required-by-your-organization)                                                                                                                                                                      |
| `"<plugin>" was not uninstalled: it is still switched on in <file>`                                                                                                                                                                                                  | [Plugin errors](#plugin-was-not-uninstalled)                                                                                                                                                                                   |
| `"<plugin>" was not uninstalled: <file> is there and could not be read`                                                                                                                                                                                              | [Plugin errors](#plugin-was-not-uninstalled)                                                                                                                                                                                   |
| `Plugin "<plugin>" was not uninstalled: installed_plugins.json`                                                                                                                                                                                                      | [Plugin troubleshooting](../08-Plugins-Skills/plugins-troubleshooting.md#installed-plugins-json-holds-a-record-this-version-cannot-read)                                                                                                      |
| `Plugin directory does not exist: <path>`                                                                                                                                                                                                                            | [Plugin troubleshooting](../08-Plugins-Skills/plugins-troubleshooting.md#plugin-directory-does-not-exist)                                                                                                                                     |
| `Skipping connection (recent failure cached; retries automatically in 15 min, or edit the plugin config to retry now)`                                                                                                                                               | [Plugin errors](#skipping-connection-recent-failure-cached)                                                                                                                                                                    |
| `Error: No such tool available: <tool name>`                                                                                                                                                                                                                         | [Tool errors](#no-such-tool-available)                                                                                                                                                                                         |
| `MCP server "<name>" connection closed before the tool call was answered`                                                                                                                                                                                            | [Tool errors](#connection-closed-before-the-tool-call-was-answered)                                                                                                                                                            |
| `would be spawned with zero tools — refusing`                                                                                                                                                                                                                        | [Tool errors](#agent-would-be-spawned-with-zero-tools)                                                                                                                                                                         |
| `File is covered by a Read deny rule in your permission settings`                                                                                                                                                                                                    | [Tool errors](#file-is-covered-by-a-read-deny-rule)                                                                                                                                                                            |
| `cannot contain null bytes (\0)`                                                                                                                                                                                                                                     | [Tool errors](#path-cannot-contain-null-bytes)                                                                                                                                                                                 |
| `Path contains null bytes`                                                                                                                                                                                                                                           | [Tool errors](#path-cannot-contain-null-bytes)                                                                                                                                                                                 |
| `File is too large to read as an image (the limit is 128MB)`                                                                                                                                                                                                         | [Tool errors](#file-is-too-large-to-read-as-an-image)                                                                                                                                                                          |
| `Cannot read this as an image: <path> is a pipe or a device`                                                                                                                                                                                                         | [Tool errors](#file-is-too-large-to-read-as-an-image)                                                                                                                                                                          |
| `subagent_type is required: the general-purpose agent is not available in this session`                                                                                                                                                                              | [Tool errors](#subagent-type-is-required)                                                                                                                                                                                      |
| `Error: this write left the memory index at MEMORY.md at ..., over its ... read limit`                                                                                                                                                                               | [Tool errors](#memory-index-is-over-its-read-limit)                                                                                                                                                                            |
| `pkill: refusing to run`                                                                                                                                                                                                                                             | [Tool errors](#pkill-pattern-matches-the-claude-code-process)                                                                                                                                                                  |
| `Failed to write to <name>'s inbox — nothing was sent`                                                                                                                                                                                                               | [Tool errors](#failed-to-write-to-a-teammate-inbox)                                                                                                                                                                            |
| `Failed to write the plan approval request to the lead's inbox — plan not submitted`                                                                                                                                                                                 | [Tool errors](#failed-to-write-to-a-teammate-inbox)                                                                                                                                                                            |
| `Its agent definition was not restored: the folder its definition file came from is not trusted`                                                                                                                                                                     | [Tool errors](#teammate-agent-definition-not-restored)                                                                                                                                                                         |
| `Only a teammate can approve a shutdown request`                                                                                                                                                                                                                     | [Tool errors](#only-a-teammate-can-approve-a-shutdown-request)                                                                                                                                                                 |
| `Message too large for cross-session delivery`                                                                                                                                                                                                                       | [Tool errors](#message-too-large-for-cross-session-delivery)                                                                                                                                                                   |
| `Too many messages to this session just now`                                                                                                                                                                                                                         | [Tool errors](#too-many-messages-to-this-session-just-now)                                                                                                                                                                     |
| `Cross-session message was dropped at the recipient session's inbox`                                                                                                                                                                                                 | [Tool errors](#cross-session-message-dropped-at-the-inbox)                                                                                                                                                                     |
| `Refusing to send: reply target is a symlink` / `Refusing to send: cannot vet reply target`                                                                                                                                                                          | [Tool errors](#refusing-to-send-a-cross-session-message)                                                                                                                                                                       |
| `Refusing to read <path>: its symlink resolution changed after permission was checked (<reason>)` / `Refusing to search <path>: its symlink resolution changed after permission was checked`                                                                         | [Tool errors](#refusing-after-a-symlink-changed)                                                                                                                                                                               |
| `Refusing to write <path>: its parent-directory symlink resolution changed after permission was checked` / `Refusing to write <path>: it is a symbolic link. Write to the link's target path instead`                                                                | [Tool errors](#refusing-after-a-symlink-changed)                                                                                                                                                                               |
| `Refusing to write through symlink: <path>` / `Refusing to write into symlinked directory: <path>`                                                                                                                                                                   | [Tool errors](#refusing-after-a-symlink-changed)                                                                                                                                                                               |
| `Refusing to write <path>: where it leads on disk could not be determined` / `Refusing to read <path>: where it leads on disk could not be determined`                                                                                                               | [Tool errors](#refusing-after-a-symlink-changed)                                                                                                                                                                               |
| `Refusing to search <path>: a path one of its Read deny rules is written through changed while the search was being prepared` / `Refusing to search <path>: it could not be opened`                                                                                  | [Tool errors](#refusing-after-a-symlink-changed)                                                                                                                                                                               |
| `its permission check expired before it ran (too many concurrent file operations)` / `ripgrep was found only by name on PATH`                                                                                                                                        | [Tool errors](#refusing-after-a-symlink-changed)                                                                                                                                                                               |
| `task output swap refused (tasks dir moved or linked)`                                                                                                                                                                                                               | [Tool errors](#task-output-swap-refused)                                                                                                                                                                                       |
| `Command killed: its output file was replaced or could no longer be verified`                                                                                                                                                                                        | [Tool errors](#task-output-swap-refused)                                                                                                                                                                                       |
| `Disk full: this computer's volume holding <dir> (Claude Code's temporary directory) has <n> MB free` / `Nearly out of inodes: this computer's volume holding <dir>`                                                                                                 | [Tool errors](#disk-quota-or-temp-filesystem-is-full)                                                                                                                                                                          |
| `Disk full: a test write beside this command's output file` / `Disk quota used up: a test write beside this command's output file`                                                                                                                                   | [Tool errors](#disk-quota-or-temp-filesystem-is-full)                                                                                                                                                                          |
| `The command was not started: this computer's disk is full (ENOSPC)` / `the user's disk quota is used up (EDQUOT)`                                                                                                                                                   | [Tool errors](#disk-quota-or-temp-filesystem-is-full)                                                                                                                                                                          |
| `Your disk quota is full on the filesystem with Claude Code's temp directory <dir> (EDQUOT)` / `The filesystem with Claude Code's temp directory <dir>, or your disk quota on it, is full (ENOSPC)`                                                                  | [Tool errors](#disk-quota-or-temp-filesystem-is-full)                                                                                                                                                                          |
| `Command output was lost: the temp filesystem at <dir> is full` / `is out of inodes`                                                                                                                                                                                 | [Tool errors](#disk-quota-or-temp-filesystem-is-full)                                                                                                                                                                          |
| `File is not valid UTF-8. It may use a legacy encoding such as Windows-1252, Shift-JIS or GBK, or be binary`                                                                                                                                                         | [Tool errors](#file-is-not-valid-utf-8)                                                                                                                                                                                        |
| `the source file is not valid UTF-8 text` / `the source file is not valid UTF-16 text`                                                                                                                                                                               | [Tool errors](#the-source-file-is-not-valid-utf-8-text)                                                                                                                                                                        |
| `the source file has the replacement character U+FFFD`                                                                                                                                                                                                               | [Tool errors](#the-source-file-is-not-valid-utf-8-text)                                                                                                                                                                        |
| `Not published: that file is on a network share`                                                                                                                                                                                                                     | [Tool errors](#not-published-that-file-is-on-a-network-share)                                                                                                                                                                  |
| `Not published: Claude sent the same content again after a newer version of the artifact turned it away` / `Not published: Claude sent its changes again over the same file after a newer version of the artifact turned them away`                                  | [Tool errors](#not-published-a-newer-version-of-the-artifact-turned-it-away)                                                                                                                                                   |
| `Reading a local file from outside this session's connected folders, or through a link, needs the approval card`                                                                                                                                                     | [Tool errors](#reading-a-local-file-from-outside-the-connected-folders)                                                                                                                                                        |
| `cannot read file_path (...) — the file could not be examined, and no one can answer the approval card`                                                                                                                                                              | [Tool errors](#reading-a-local-file-from-outside-the-connected-folders)                                                                                                                                                        |
| `WebFetch cannot fetch localhost or other hostnames without a dot`                                                                                                                                                                                                   | [Tool errors](#webfetch-cannot-fetch-localhost)                                                                                                                                                                                |
| `The safety check for domain ... is rate-limited`                                                                                                                                                                                                                    | [Tool errors](#webfetch-domain-safety-check-failed)                                                                                                                                                                            |
| `The safety check for domain ... is temporarily rate-limited`                                                                                                                                                                                                        | [Tool errors](#webfetch-domain-safety-check-failed)                                                                                                                                                                            |
| `Unable to verify if domain ... is safe to fetch`                                                                                                                                                                                                                    | [Tool errors](#webfetch-domain-safety-check-failed)                                                                                                                                                                            |
| `Can't open MCP settings while no terminal is attached to this background session`                                                                                                                                                                                   | [Background session errors](#commands-refused-in-a-background-session)                                                                                                                                                         |
| `Can't open MCP settings in a background session`                                                                                                                                                                                                                    | [Background session errors](#commands-refused-in-a-background-session)                                                                                                                                                         |
| `blocked because the path is spelled in a form that cannot be safely resolved`                                                                                                                                                                                       | [Background session errors](#write-or-command-blocked-because-the-path-cannot-be-safely-resolved)                                                                                                                              |
| `blocked because the path is network-shaped`                                                                                                                                                                                                                         | [Background session errors](#write-or-command-blocked-because-the-path-names-a-network-location)                                                                                                                               |
| `is isolated in the worktree <path>, but this command <reason>. Refusing to run it`                                                                                                                                                                                  | [Background session errors](#command-blocked-by-the-worktree-isolation-checks)                                                                                                                                                 |
| `too complex to verify that it stays inside the worktree`                                                                                                                                                                                                            | [Background session errors](#command-blocked-by-the-worktree-isolation-checks)                                                                                                                                                 |
| `This session has no saved transcript`                                                                                                                                                                                                                               | [Background session errors](#this-session-has-no-saved-transcript)                                                                                                                                                             |
| `Can't open — this session is running in another terminal`                                                                                                                                                                                                           | [Background session errors](#this-session-is-running-in-another-terminal)                                                                                                                                                      |
| `This conversation is already open in another running Claude session`                                                                                                                                                                                                | [Background session errors](#this-session-is-running-in-another-terminal)                                                                                                                                                      |
| `This session's saved conversation is no longer on disk`                                                                                                                                                                                                             | [Background session errors](#this-sessions-saved-conversation-is-no-longer-on-disk)                                                                                                                                            |
| `Bypass permissions was requested at launch and ignored`                                                                                                                                                                                                             | [Bypass permissions ignored in a background session](permission-modes.md#bypass-permissions-ignored-in-a-background-session)                                                                                             |
| `kept <id> — its worktree is still at <path>`                                                                                                                                                                                                                        | [Background session errors](#worktree-has-commits-that-are-not-pushed-anywhere)                                                                                                                                                |
| `kept <id> — <n> unpushed commits on <branch>`                                                                                                                                                                                                                       | [Background session errors](#worktree-has-commits-that-are-not-pushed-anywhere)                                                                                                                                                |
| `kept <id> — worktree has commits that are not pushed anywhere`                                                                                                                                                                                                      | [Background session errors](#worktree-has-commits-that-are-not-pushed-anywhere)                                                                                                                                                |
| `terminal host process died — press Enter to restart` / `This session's terminal host process died`                                                                                                                                                                  | [Background session errors](#terminal-host-process-died)                                                                                                                                                                       |
| `Session isn't responding` / `Press enter again to restart this session — it isn't responding`                                                                                                                                                                       | [Background session errors](#session-isnt-responding)                                                                                                                                                                          |
| `Session <id> was stopped while the respawn was in flight`                                                                                                                                                                                                           | [Background session errors](#session-was-stopped-while-the-respawn-was-in-flight)                                                                                                                                              |
| `This session was running agent '<name>', which is no longer available`                                                                                                                                                                                              | [Background session errors](#session-agent-no-longer-available)                                                                                                                                                                |
| `This session restarted <time> after its next /loop wakeup was due, so that wakeup will not fire`                                                                                                                                                                    | [Background session errors](#restarted-after-its-next-loop-wakeup-was-due)                                                                                                                                                     |
| `No LLM gateway: a gateway set in your shell isn't passed to a session opened from another folder`                                                                                                                                                                   | [Background session errors](#no-llm-gateway-opened-from-another-folder)                                                                                                                                                        |
| `No LLM gateway: opened from another folder · respawn from <folder>`                                                                                                                                                                                                 | [Background session errors](#no-llm-gateway-opened-from-another-folder)                                                                                                                                                        |
| `CLAUDE_CODE_PROCESS_WRAPPER: launcher ...`                                                                                                                                                                                                                          | [Background session errors](#claude_code_process_wrapper-launcher-errors)                                                                                                                                                      |
| `EUNKNOWN: unknown error, uv_spawn`                                                                                                                                                                                                                                  | [Background session errors](#eunknown-when-starting-a-background-session)                                                                                                                                                      |
| `EACCES: permission denied, posix_spawn`                                                                                                                                                                                                                             | [Background session errors](#eacces-when-starting-a-background-session)                                                                                                                                                        |
| `exited before it became reachable`                                                                                                                                                                                                                                  | [Background session errors](#background-service-exited-before-it-became-reachable)                                                                                                                                             |
| `Couldn't start a background session (working directory no longer exists or is not accessible: ...)`                                                                                                                                                                 | [Background session errors](#working-directory-no-longer-exists-when-starting-a-background-session)                                                                                                                            |
| `Workspace not trusted.` when starting or restarting a background session                                                                                                                                                                                            | [Background session errors](#workspace-not-trusted-when-dispatching-a-background-session)                                                                                                                                      |
| `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)                                                                                                                                                        |
| `Claude Code process exited with code N`                                                                                                                                                                                                                             | [Wrapper and IDE errors](#claude-code-process-exited-with-code-n)                                                                                                                                                              |
| `The connection to Claude Code ended before this message completed`                                                                                                                                                                                                  | [Wrapper and IDE errors](#the-connection-to-claude-code-ended-before-this-message-completed)                                                                                                                                   |
| `Could not locate the Claude CLI on PATH`                                                                                                                                                                                                                            | [Wrapper and IDE errors](#could-not-locate-the-claude-cli-on-path)                                                                                                                                                             |
| `Restored the code, but skipped N files`                                                                                                                                                                                                                             | [Rewind warnings and errors](#restored-the-code-but-skipped-files)                                                                                                                                                             |
| `No files were restored: N files failed (backup missing, or the file could not be updated)`                                                                                                                                                                          | [Rewind warnings and errors](#no-files-were-restored)                                                                                                                                                                          |
| `Transcript writes are failing (...)`                                                                                                                                                                                                                                | [Session saving warnings](#transcript-writes-are-failing)                                                                                                                                                                      |
| `Transcript saving is off — CLAUDE_CODE_SKIP_PROMPT_HISTORY is set`                                                                                                                                                                                                  | [Session saving warnings](#transcript-saving-is-off-skip-prompt-history)                                                                                                                                                       |
| `Transcript saving is off — inherited CLAUDE_CODE_CHILD_SESSION marker`                                                                                                                                                                                              | [Session saving warnings](#transcript-saving-is-off-child-session-marker)                                                                                                                                                      |
| `Claude Code's fullscreen renderer didn't finish starting last time on this machine` / `Claude Code's fullscreen renderer has repeatedly failed to start on this machine`                                                                                            | [Fullscreen rendering](fullscreen.md#fullscreen-renderer-didnt-finish-starting)                                                                                                                                          |
| `Claude Code exited after an unrecoverable interface error (...)`                                                                                                                                                                                                    | [Configuration warnings](#exited-after-an-unrecoverable-interface-error)                                                                                                                                                       |
| `Agent descriptions are over the 15.0k-token limit`                                                                                                                                                                                                                  | [Configuration warnings](#agent-descriptions-are-over-the-15000-token-limit)                                                                                                                                                   |
| `hook needs quotes around a path with a space`                                                                                                                                                                                                                       | [Configuration warnings](#hook-needs-quotes-around-a-path-with-a-space)                                                                                                                                                        |
| `Instruction file not loaded`                                                                                                                                                                                                                                        | [Configuration warnings](#instruction-file-not-loaded)                                                                                                                                                                         |
| `Not loaded: rename <path>, then restart — its name uses "<name>", a name reserved for the skills synced from your claude.ai account`                                                                                                                                | [Configuration warnings](#a-skill-command-or-workflow-wasnt-loaded-because-its-name-is-reserved)                                                                                                                               |
| `N skill or command names refused: run with --debug to see which ([names]), rename, then restart`                                                                                                                                                                    | [Configuration warnings](#skill-or-command-name-refused)                                                                                                                                                                       |
| `Ignoring N permissions.allow entries from ... this workspace has not been trusted`                                                                                                                                                                                  | [Configuration warnings](#workspace-has-not-been-trusted)                                                                                                                                                                      |
| `is a network path, which cannot be added as a working directory`                                                                                                                                                                                                    | [Configuration warnings](#working-directory-is-a-network-path)                                                                                                                                                                 |
| `Remote managed settings failed to load (<cause>)`                                                                                                                                                                                                                   | [Configuration warnings](#remote-managed-settings-failed-to-load)                                                                                                                                                              |
| `Managed settings were not approved; exiting without applying them.`                                                                                                                                                                                                 | [Configuration warnings](#managed-settings-were-not-approved)                                                                                                                                                                  |
| `Your organization's managed settings need your approval, which couldn't be asked for here.`                                                                                                                                                                         | [Configuration warnings](#managed-settings-need-your-approval)                                                                                                                                                                 |
| `Claude Code can't start: your organization's managed settings block the default model` / `Claude Code can't start: your organization allows only the models listed in "availableModels"`                                                                            | [Configuration warnings](#managed-settings-block-the-default-model)                                                                                                                                                            |
| `Your organization's managed settings allow Claude Code to use: <providers>`                                                                                                                                                                                         | [Configuration warnings](#managed-settings-dont-allow-this-api-provider)                                                                                                                                                       |
| `Your organization's managed settings allow Claude Code to use no API provider at all`                                                                                                                                                                               | [Configuration warnings](#managed-settings-dont-allow-this-api-provider)                                                                                                                                                       |
| `MCP server <name> is blocked by enterprise managed policy`                                                                                                                                                                                                          | [Configuration warnings](#mcp-server-is-blocked-by-enterprise-managed-policy)                                                                                                                                                  |
| `"<name>" is a reserved MCP server name and was not loaded`                                                                                                                                                                                                          | [Configuration warnings](#mcp-server-name-is-reserved)                                                                                                                                                                         |
| `Managed settings document could not be parsed as a JSON object; none of its settings are in effect. Fix or remove it.`                                                                                                                                              | [Configuration warnings](#managed-settings-document-could-not-be-parsed)                                                                                                                                                       |
| `Managed settings drop-in directory could not be read`                                                                                                                                                                                                               | [Configuration warnings](#managed-settings-document-could-not-be-parsed)                                                                                                                                                       |
| `Unable to read managed policy settings`                                                                                                                                                                                                                             | [Configuration warnings](#unable-to-read-managed-policy-settings)                                                                                                                                                              |
| `Managed settings contain invalid entries, including PreToolUse/PermissionRequest hooks that are NOT loaded; fix or remove each entry:`                                                                                                                              | [Configuration warnings](#managed-settings-hooks-not-loaded)                                                                                                                                                                   |
| `otelHeadersHelper failed; telemetry is not being exported. See /status: ...`                                                                                                                                                                                        | [Configuration warnings](#otelheadershelper-failed)                                                                                                                                                                            |
| `"crossSessionInbound" must be one of "accept", "hold", "refuse"`                                                                                                                                                                                                    | [Configuration warnings](#crosssessioninbound-must-be-one-of-accept-hold-refuse)                                                                                                                                               |
| `API Error: ANTHROPIC_FOUNDRY_RESOURCE must be a Foundry resource name`                                                                                                                                                                                              | [Configuration warnings](#anthropic-foundry-resource-must-be-a-foundry-resource-name)                                                                                                                                          |
| `headersHelper not run — this workspace has no persisted trust`                                                                                                                                                                                                      | [Configuration warnings](#headershelper-not-run)                                                                                                                                                                               |
| `Invalid permission rule "..." was skipped: Malformed Tool(content) rule`                                                                                                                                                                                            | [Configuration warnings](#malformed-tool-content-rule)                                                                                                                                                                         |
| `matches no tool · check for typos` / `matches no known tool — check for typos`                                                                                                                                                                                      | [Configuration warnings](#matches-no-tool)                                                                                                                                                                                     |
| `... is not matched by file permission checks`                                                                                                                                                                                                                       | [Configuration warnings](#is-not-matched-by-file-permission-checks)                                                                                                                                                            |
| `Write(<path>) never matches · use Edit(<path>)` / `Glob(<path>) never matches · use Read(<path>)`                                                                                                                                                                   | [Configuration warnings](#is-not-matched-by-file-permission-checks)                                                                                                                                                            |
| `... has a wildcard before the rest of the command`                                                                                                                                                                                                                  | [Configuration warnings](#has-a-wildcard-before-the-rest-of-the-command)                                                                                                                                                       |
| `allows any option at its * · use an exact value`                                                                                                                                                                                                                    | [Configuration warnings](#has-a-wildcard-before-the-rest-of-the-command)                                                                                                                                                       |
| `Denying Bash also turns off the PowerShell tool, so Claude has neither`                                                                                                                                                                                             | [Configuration warnings](#denying-bash-also-turns-off-the-powershell-tool)                                                                                                                                                     |
| `CLAUDE_CODE_DISABLE_1M_CONTEXT is set, but the 200K limit isn't enforced`                                                                                                                                                                                           | [Configuration warnings](#the-200k-limit-isnt-enforced)                                                                                                                                                                        |
| `CLAUDE_CODE_AUTO_COMPACT_WINDOW="<value>" reads as <N> tokens, so Claude Code treats it as the 100k minimum`                                                                                                                                                        | [Values and warnings for `CLAUDE_CODE_AUTO_COMPACT_WINDOW`](model-config.md#claude_code_auto_compact_window-values)                                                                                                      |
| `CLAUDE_CODE_AUTO_COMPACT_WINDOW="<value>" is too large, so Claude Code treats it as the 1M maximum`                                                                                                                                                                 | [Values and warnings for `CLAUDE_CODE_AUTO_COMPACT_WINDOW`](model-config.md#claude_code_auto_compact_window-values)                                                                                                      |
| `CLAUDE_CODE_AUTO_COMPACT_WINDOW="<value>" isn't a usable size, so Claude Code ignores it`                                                                                                                                                                           | [Values and warnings for `CLAUDE_CODE_AUTO_COMPACT_WINDOW`](model-config.md#claude_code_auto_compact_window-values)                                                                                                      |
| `Model "<model>" isn't recognized · context assumed to be 200k tokens`                                                                                                                                                                                               | [Correct the window for a gateway or custom model ID](model-config.md#correct-the-window-for-a-gateway-or-custom-model-id)                                                                                               |
| `Claude Code doesn't recognize the model "<model>", so it assumes a context window of 200k tokens`                                                                                                                                                                   | [Correct the window for a gateway or custom model ID](model-config.md#correct-the-window-for-a-gateway-or-custom-model-id)                                                                                               |
| `[claude-code:unrecognized_model]`                                                                                                                                                                                                                                   | [Configuration warnings](#unrecognized-model-id-on-a-request)                                                                                                                                                                  |
| `is ignored — managed settings set allowManagedReadPathsOnly` / `is ignored — managed settings set allowManagedDomainsOnly`                                                                                                                                          | [Configuration warnings](#sandbox-allow-entries-are-ignored-under-a-managed-lock)                                                                                                                                              |
| `Sandbox mask files left behind at write-deny paths`                                                                                                                                                                                                                 | [Configuration warnings](#stale-sandbox-mask-files-left-by-a-killed-session)                                                                                                                                                   |
| `Stale sandbox mask files left by a killed session`                                                                                                                                                                                                                  | [Configuration warnings](#stale-sandbox-mask-files-left-by-a-killed-session)                                                                                                                                                   |
| Responses seem lower quality than usual                                                                                                                                                                                                                              | [Response quality](#responses-seem-lower-quality-than-usual)                                                                                                                                                                   |


[​](#automatic-retries)

Automatic retries

Claude Code retries transient failures up to 10 times with exponential backoff before showing you an error. It doesn’t always retry a failure that arrives partway through Claude’s response. When you see one of the errors on this page, Claude Code has already made whatever retries apply to that failure. Claude Code retries these failures:

- Server errors, overloaded responses, and request timeouts that arrive before any of Claude’s response has streamed.
- A server error or overloaded response that arrives after Claude has finished thinking but before it has started any text or tool call. Claude Code retries a server error at that point up to two times. Before v2.1.284, Claude Code ended the turn with the error at that point.
- Dropped connections. When a connection drops partway through a request before Claude has completed any part of its response, including its thinking, Claude Code re-issues the request with the same backoff and the turn continues, even if some text had already started streaming. When it drops after Claude has finished thinking but before it has started any text or tool call, Claude Code instead re-issues the request up to two times in quick succession, and ends the turn with `Connection lost before a response was produced` if the connection keeps dropping at that point.
- A connection that Claude Code detects was broken by your computer going to sleep partway through a request. Claude Code counts it as a dropped connection under the rules above; once the retry label names the specific reason, it reads `Connection lost while your computer was asleep`, and if the turn ends after Claude has finished thinking but before any text or tool call, the message reads `Your computer went to sleep before a response was produced`.
- A stalled response stream, when the response headers have arrived but none of Claude’s response has arrived, or when Claude has finished thinking but hasn’t started any text or tool call: Claude Code aborts the stalled connection and streams the request again at most once. If the response stalls a second time after Claude has finished thinking but before any text or tool call, Claude Code ends the turn with `The response stalled before a response was produced`.
- A streaming request the API never answers with response headers, on a connection where the [first-byte deadline runs](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs). At the deadline, Claude Code aborts the request and re-sends it within the retry budget. If the deadline fires for a re-send too, the turn ends with [No response from API](#no-response-from-api). When you set `CLAUDE_CODE_RETRY_WATCHDOG`, Claude Code keeps re-sending within the budget instead.
- A streaming response that the API’s output content filter stops before Claude has either finished thinking or started any text or tool call. Claude Code re-sends the request once, within the retry budget, and shows [Output blocked by content filtering policy](#output-blocked-by-content-filtering-policy) if the filter stops the second response too.
- Temporary 429 throttles, but not a gateway’s spend-limit `429`, which isn’t a throttle; see [Spend limit reached](#spend-limit-reached).
  - When you’re signed in with a claude.ai subscription, this includes 429 throttles that don’t carry your plan’s quota headers. Before v2.1.199, Claude Code retried those throttles only for API key and Enterprise sign-ins.
- A request rejected because the input plus `max_tokens` exceeds the context limit. Re-sending it unchanged would fail the same way, so Claude Code retries with a reduced `max_tokens`, and stops retrying and compacts instead in two cases:
  - When no reduction can fit, for example when the conversation itself nearly fills the context window.
  - When a retry can’t shrink `max_tokens` any further. Before v2.1.218, Claude Code could re-send a reduced request that still didn’t fit, such as when the extended thinking budget exceeded the remaining context, until the retry budget ran out.
- A response that says Claude is calling a tool but contains no tool call. Claude Code retries by asking Claude for the tool call, up to two times. If both retries fail the same way, you see `The model's tool call could not be parsed (retry also failed).` and the turn ends. To try again, send another message. Before v2.1.307, Claude Code retried once before ending the turn.
- An expired or missing Google Cloud credential on [Google Cloud’s Agent Platform](google-vertex-ai.md), or AWS credentials that fail to load on your machine. Claude Code discards its cached credentials and retries up to two times, then reports the error so you can re-authenticate right away, as described under [Could not load AWS or Google Cloud credentials](#could-not-load-aws-or-google-cloud-credentials). Before v2.1.228, Claude Code retried a failing Google Cloud credential through the full retry budget before showing the error.
- A `401` or `403` from the Anthropic API, directly or through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md), while an [`apiKeyHelper`](settings-reference.md#apikeyhelper) script supplies the credential. Claude Code re-runs the script and retries with its fresh output, within the full retry budget. When the script itself fails on the re-run, Claude Code shows [Your apiKeyHelper script is failing](#your-apikeyhelper-script-is-failing) instead.

Before v2.1.227, `Connection lost before a response was produced` read `Connection closed while thinking, before producing a response` and `The response stalled before a response was produced` read `Response stalled while thinking, before producing a response`. Claude Code doesn’t retry these failures:

- A TLS certificate validation failure, such as a TLS-inspecting proxy, a missing `NODE_EXTRA_CA_CERTS` bundle, or an expired certificate. Claude Code reports the error on the first attempt, so you can fix the certificate setup right away; see [SSL certificate errors](#ssl-certificate-errors). Claude Code still retries transient TLS conditions such as a handshake timeout. Before v2.1.199, Claude Code retried certificate failures through the full retry budget before showing the error.
- A server error, dropped connection, or stalled stream that arrives after Claude has completed a block of text or a tool call, or has started one after finishing its thinking, but before it finishes the response. Claude Code doesn’t re-run the request, because that could execute the same tool calls twice. It keeps what Claude completed, runs any tool calls Claude finished, and continues the turn from their results. For what you see in an interactive session and in a non-interactive one, read [The response above may be incomplete](#the-response-above-may-be-incomplete). Before v2.1.199, Claude Code discarded the partial output and reported the whole turn as an error when a server error arrived mid-stream.
- A failure that arrives after Claude has finished the response: nothing needs retrying, so Claude Code keeps the complete response and ends the turn normally.
- An [Amazon Bedrock streaming response with an unexpected content-type](#bedrock-streaming-response-has-an-unexpected-content-type), because the gateway or proxy rewriting the response would rewrite the retry the same way. Requires Claude Code v2.1.208 or later.
- A non-streaming retry of a failed streaming request that gets a success status but [no Claude API message in the body](#api-returned-an-empty-or-malformed-response). Claude Code ends the turn with that error.
- A request that your organization’s policy check denied, which surfaces as an `API Error:` line carrying the denial message. Your organization’s administrators set up the check with [Inference hooks](../04-API-Reference/Other/manage-claude-inference-hooks.md), a Claude Enterprise feature, and the message ends with the instructions they configured, or by default tells you to contact them. Claude Code doesn’t re-send the denied request to the same model or to a [fallback model](model-config.md#fallback-model-chains), because the denial is about the request’s content rather than the model. Before v2.1.239, Claude Code could re-send a denied request, without streaming or on a configured fallback model, before showing you the denial.


[​](#what-you-see-while-claude-code-retries-or-waits)

What you see while Claude Code retries or waits

While retrying, the spinner shows a `Retrying in Ns · attempt x/y` countdown after an error label. The label names the specific reason from the first attempt for failures you can act on right away: the network is down, a TLS handshake failed, or you hit a rate limit. For other errors it reads `API error` at first. As of v2.1.198 it switches to the specific reason from the third attempt, or on the final attempt when `CLAUDE_CODE_MAX_RETRIES` allows fewer than three; earlier versions switch only on the final attempt. As of v2.1.198, the usual spinner tip is suppressed during retries. Once the error reason is revealed, if the failure is a 529 overload the line below the countdown also names where to check service status: `status.claude.com` on the Anthropic API, or the provider or gateway host named in the message on other configurations. If no data arrives on the response stream for 20 seconds while a request is still pending, the spinner shows `Waiting for API response · will retry in … · check your network` before any retry has started. The request hasn’t failed yet: the countdown runs to the point where Claude Code aborts the stalled connection. After the abort, what you see depends on how far the response had got:

- Before Claude has completed a block of text or a tool call, or started one after finishing its thinking, Claude Code retries the request or ends the turn with an error. [Automatic retries](#automatic-retries) says which stalls it retries and how many times.
- After Claude has completed a block of text or a tool call, or started one after finishing its thinking, but before Claude has finished the response, Claude Code keeps what Claude completed, continues the turn from any tool calls Claude finished, and shows [The response above may be incomplete](#the-response-above-may-be-incomplete). In a non-interactive session, and for a subagent’s response in any session, Claude Code may first prompt Claude to continue the response; that entry says when it does and when you still see the notice there.
- After Claude finished the response, Claude Code ends the turn normally.

The banner clears on its own once data resumes or a retry succeeds. If it reappears on every attempt, treat it as a [network issue](#unable-to-connect-to-api). Before v2.1.185, the banner appeared after 10 seconds with different wording. While Claude is consulting the [advisor](advisor.md), the banner appears after 90 seconds without data instead of 20, because a long advisor review can send nothing for well over 20 seconds. Before v2.1.214, the 20-second threshold applied during advisor calls too, so the banner appeared during advisor reviews even when nothing was wrong.


[​](#tune-retry-behavior)

Tune retry behavior

You can tune retry behavior with these environment variables:

| Variable                                                                 | Default | Effect                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
|:-------------------------------------------------------------------------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`CLAUDE_CODE_MAX_RETRIES`](env-vars.md)                           | 10      | Number of retry attempts. Capped at 15 as of v2.1.186; as of v2.1.199 `CLAUDE_CODE_RETRY_WATCHDOG` raises the default and removes the cap. Lower it to surface failures faster in scripts.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| [`CLAUDE_CODE_RETRY_WATCHDOG`](env-vars.md)                        | unset   | Set to `1` in unattended sessions such as CI jobs to retry `429` and `529` capacity errors indefinitely instead of failing after `CLAUDE_CODE_MAX_RETRIES` attempts. Claude Code fails at once when a standard-speed request gets a `429` that reports a spend limit or exhausted usage credits, even one from a [gateway spend cap](#spend-limit-reached) that resets on a schedule. Before v2.1.239, the watchdog retried these indefinitely. For fast mode requests, see [Handle rate limits](fast-mode.md#handle-rate-limits). On v2.1.199 or later it also raises the default retry count for other transient errors, such as server errors, timeouts, and dropped connections, to 300, roughly three hours of backoff, and removes the cap of 15 on `CLAUDE_CODE_MAX_RETRIES` if you set that variable explicitly. |
| [`CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS`](env-vars.md)            | unset   | Maximum time in milliseconds that each API request spends waiting out `429` and `529` errors when `CLAUDE_CODE_RETRY_WATCHDOG` is set. When unset, the wait has no limit. Requires Claude Code v2.1.295 or later.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| [`CLAUDE_CODE_RETRY_WATCHDOG_USAGE_LIMIT_RECHECK_MS`](env-vars.md) | 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](env-vars.md). Requires Claude Code v2.1.305 or later.                                                                                                                                                                                                                                                                                       |
| [`CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS`](env-vars.md)        | 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](fast-mode.md#handle-rate-limits). Requires Claude Code v2.1.292 or later.                                                                                                                                                                                                                                                                                                                                                                                              |
| [`CLAUDE_CODE_OVERLOADED_RETRY_MAX_DELAY_MS`](env-vars.md)         | 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](fast-mode.md#handle-rate-limits). Requires Claude Code v2.1.296 or later.                                                                                                                                                                                                                                                                                                                                                                                                     |
| [`API_TIMEOUT_MS`](env-vars.md)                                    | 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).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| [`CLAUDE_CODE_NONSTREAMING_TIMEOUT_RETRIES`](env-vars.md)          | 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. Each non-streaming attempt times out after 300 seconds in a local session, or after `API_TIMEOUT_MS` when you set a positive value. Requires Claude Code v2.1.285 or later.                                                                                                                                                                                                                                                                                                                           |
| [`CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS`](env-vars.md)               | 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).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |


[​](#server-errors)

Server errors

Most of these errors come from the inference provider: Anthropic’s service on the Anthropic API, and the service behind that provider’s endpoint on Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, or a custom gateway. [Auto mode cannot determine the safety of an action](#auto-mode-cannot-determine-the-safety-of-an-action) and [Agent terminated early due to an API error](#agent-terminated-early-due-to-an-api-error) also cover causes on your side, such as an Amazon Bedrock account that can’t invoke the classifier model or a subagent that hit a usage limit.


[​](#api-error-500-internal-server-error)

API Error: 500 Internal server error

Claude Code shows the status code and the API’s error message for any 5xx response. The example below shows a 500 response on the Anthropic API:

```python
API Error: 500 Internal server error. This is a server-side issue, usually temporary — try again in a moment. If it persists, check https://status.claude.com.
```

The trailing sentence names where to check service health and varies by provider. Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry configurations name that provider’s service status. A custom `ANTHROPIC_BASE_URL` names the gateway host. A 5xx from the API itself indicates an unexpected failure inside the API. It is not caused by your prompt, settings, or account. When a proxy, load balancer, or gateway answers with an HTML error page, the message shows the status code and the page’s title, such as `API Error: 502 Bad Gateway`. For a page with no title, the message shows the status code and its standard name instead. Before v2.1.281, the status code was dropped when the page had a title, and the page’s raw markup was printed when it had none. **What to do:**

- Check [status.claude.com](https://status.claude.com), or the provider status page named in the message, for active incidents
- Wait a minute, then send your message again. Your original message is still in the conversation, so for a long prompt you can type `try again` instead of pasting the whole thing.
- If [`ANTHROPIC_BASE_URL`](env-vars.md) points at an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) and every request fails this way, check whether your gateway is rejecting the tool search fields Claude Code sends by default. To check, set `ENABLE_TOOL_SEARCH=false` as [Tool search through an LLM gateway](../06-MCP-Tools/General/mcp.md#tool-search-through-a-gateway) describes, then try again. Before v2.1.304, tool search was off behind a gateway unless you turned it on with `ENABLE_TOOL_SEARCH`.
- If the error persists with no posted incident, run `/feedback` so Anthropic can investigate with your request details. See [Report an error](#report-an-error) if `/feedback` is unavailable in your environment.


[​](#api-error-repeated-529-overloaded-errors)

API Error: Repeated 529 Overloaded errors

The API is temporarily at capacity across all users. Claude Code has already retried several times before showing this message:

```python
API Error: Repeated 529 Overloaded errors. The API is at capacity — this is usually temporary. Try again in a moment. If it persists, check https://status.claude.com.
```

The trailing sentence varies by provider in the same way as the 500 error above. A 529 is not your usage limit and doesn’t count against your quota. **What to do:**

- Check [status.claude.com](https://status.claude.com), or the provider status page named in the message, for capacity notices
- Try again in a few minutes
- Run `/model` and switch to a different model to keep working, since capacity is tracked per model. Claude Code prompts you to do this when one model is under particularly high load, for example `Opus is experiencing high load, please use /model to switch to Sonnet`. On Fable models the message names Fable. In a session the Claude Desktop app runs, such as the Code tab or Cowork, the message reads `Opus is experiencing high load. Switch to Sonnet.` and you switch models with the app’s model picker.


[​](#request-timed-out)

Request timed out

The API didn’t respond before the connection deadline.

```python
Request timed out
```

The default request timeout is 10 minutes. If you set [`API_TIMEOUT_MS`](env-vars.md) to `0`, this request timeout is off. The [first-byte deadline](#no-response-from-api) and the body idle timeout don’t turn off when you set `0`, so a streaming request still runs under [whichever of them apply to your connection](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs). A non-streaming attempt keeps its 300-second limit in a local session and can still end with this message. **What to do:**

- If every request fails with this message and you set `API_TIMEOUT_MS` to `0`, check `claude --version`. On a version before v2.1.305, update Claude Code or set a positive value.
- Retry the request
- If a slow network or proxy is the cause, raise `API_TIMEOUT_MS` as described in [Automatic retries](#automatic-retries)
- If timeouts are frequent and your network is otherwise healthy, see [Network and connection errors](#network-and-connection-errors) below


[​](#no-response-from-api)

No response from API

Claude Code sent a streaming request, and the API returned no response headers within the deadline for the first byte. Claude Code aborts such a request rather than wait for the full `API_TIMEOUT_MS` request timeout, and sends it again if the [retry budget](#tune-retry-behavior) allows. When the deadline passes for the retry too, the turn ends with this message, which shows how long each attempt waited. If you set [`CLAUDE_CODE_RETRY_WATCHDOG`](env-vars.md), Claude Code keeps retrying under the budget described in [Tune retry behavior](#tune-retry-behavior) instead of ending the turn.

```python
API Error: No response from API (waited 3m, then 10m on the retry). If a proxy or gateway on your network holds responses until they complete, raise API_TIMEOUT_MS or CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS to wait longer.
```

Claude Code sets the first attempt’s wait for response headers and the retry’s wait separately:

- **First attempt**: [`CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS`](env-vars.md) when you set it to 1 or more, clamped to between 10 seconds and 30 minutes. Otherwise Claude Code uses the byte-level watchdog timeout listed in [Streaming idle watchdogs](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs), so the variables that change that timeout change this wait too. Either way, Claude Code adds one second for every 32KB of request body.
- **Retry**: one second less than `API_TIMEOUT_MS`, just under 10 minutes by default, so that the retry can outlast a proxy or gateway that holds the response until generation completes. On Amazon Bedrock, the retry uses the same deadline as the first attempt, and the message shows one duration instead of two. Except on Amazon Bedrock, if you set `API_TIMEOUT_MS` to `0`, the retry waits 10 minutes plus one second per 32KB, or as long as the first attempt if that’s longer.

Neither wait exceeds one second less than a positive `API_TIMEOUT_MS`, and a positive `API_TIMEOUT_MS` under 11 seconds turns the deadline off. The byte-level watchdog starts only once the response headers arrive, so a response that stops sending bytes after that follows the [stalled-stream rules](#automatic-retries) instead of this deadline. In a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) session, this deadline runs only when you [turn it on](../13-Enterprise-Admin/claude-apps-gateway-deploy.md#retry-an-unanswered-request-sooner-with-the-first-byte-deadline) by setting `CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS` to `1` or more. **What to do:**

- Send your message again. Your original message is still in the conversation, so for a long prompt you can type `try again` instead of pasting the whole thing.
- If it repeats, treat it as a [network or proxy problem](#unable-to-connect-to-api).
- If a proxy or gateway on your network holds responses until they complete, raise `API_TIMEOUT_MS` so the retry waits longer. On Amazon Bedrock, raise `CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS` as well.
- If the first attempt keeps timing out and the retry then succeeds, raise `CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS` so the first attempt waits long enough too.

Before v2.1.242, Claude Code waited for the full `API_TIMEOUT_MS` request timeout, 10 minutes by default, before failing an unanswered streaming request. Before v2.1.261, the retry waited the same deadline as the first attempt and the message showed no durations. Before v2.1.307, Claude Code ignored `CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS` in a Claude apps gateway session.


[​](#the-response-above-may-be-incomplete)

The response above may be incomplete

A streaming request failed while the response was still in progress, after Claude had completed a block of text or a tool call, or had started one after finishing its thinking. Re-sending the request could run the same tool calls twice, so Claude Code keeps the output Claude completed and appends this notice instead of discarding the turn. Which variant you see names the cause:

```python
API Error: Server error mid-response. The response above may be incomplete.
API Error: Connection lost mid-response. The response above may be incomplete.
API Error: Your computer went to sleep mid-response. The response above may be incomplete.
API Error: The response stopped arriving. The response above may be incomplete.
API Error: Part of the response never arrived. The response above may be incomplete.
API Error: The response stream was malformed. The response above may be incomplete.
```

- `Server error mid-response`: a mid-stream overloaded or 5xx server error. This variant requires Claude Code v2.1.199 or later; before then that case discarded the partial output and reported the whole turn as an error.
- `Connection lost mid-response`: the connection dropped. You also see this variant when a proxy or gateway ends the response body cleanly before the response has finished.
- `Your computer went to sleep mid-response`: Claude Code detected that your computer went to sleep while the response was streaming. Once your computer wakes, Claude Code treats the connection as broken and stops reading from it.
- `Part of the response never arrived`: a stream event was dropped between the API and Claude Code, so a later event referenced content that never arrived. Before v2.1.281, this case ended the turn with `API Error: Content block not found`.
- `The response stream was malformed`: an event arrived for a content block that had already finished, or an event arrived damaged. A damaged event is one whose data isn’t valid JSON, whose content is missing, or whose content doesn’t match the event’s type. Before v2.1.284, the parser’s raw error, such as one beginning `API Error: JSON Parse error`, appeared instead when an event with invalid JSON arrived after Claude had completed its thinking, a block of text, or a tool call.
- `The response stopped arriving`: the connection stayed open but stopped delivering data, so the streaming idle watchdog aborted it. Before v2.1.222, Claude Code could also report this failure on [gateway](../13-Enterprise-Admin/gateways.md) connections reached through `ANTHROPIC_BASE_URL` or `ANTHROPIC_AWS_BASE_URL` while the server’s keep-alive pings were still arriving, because it counted only parsed response events there; upgrading stops those spurious timeouts on those routes. Gateways reached through a provider base URL such as `ANTHROPIC_BEDROCK_BASE_URL` aren’t wrapped by the byte watchdog; see [Streaming idle watchdogs](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs).

Before v2.1.227, `Connection lost mid-response` read `Connection closed mid-response` and `The response stopped arriving` read `Response stalled mid-stream`. When a dropped, duplicated, or damaged stream event arrives before Claude has started any text or tool call, you don’t see this notice:

- If Claude had completed only its thinking, Claude Code re-issues the request. When the re-issued streams break the same way, the turn ends with `Part of the response never arrived and no response was produced. Try again.` or `The response stream was malformed and no response was produced. Try again.`
- If nothing had completed, Claude Code re-sends the request without streaming instead. If you turned that fallback off with [`CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK`](env-vars.md), the turn ends with `API Error: Content block not found` for a dropped event or `API Error: Content block already closed` for a duplicated one. For a damaged event with the fallback off, the turn ends with `API Error: Stream event unreadable` or the parser’s raw error.

In four cases, Claude Code handles the failure without showing this notice right away:

- Earlier in the response, Claude Code either retries the failure or ends the turn with a different error. See [Automatic retries](#automatic-retries).
- When one of these failures arrives after Claude has finished the response, Claude Code keeps the complete response and ends the turn normally, without this notice. Before v2.1.222, Claude Code showed this notice when the connection dropped or stalled after the response finished, and reported the turn as an error even though the response was complete.
- In a [non-interactive session](headless.md), such as a `-p` run, an [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) run, or a [cloud session](claude-code-on-the-web.md), you don’t have to send `continue` yourself when the cut-off response is in the main conversation and contains text but no tool calls: Claude Code keeps the partial output and prompts Claude to continue from where it stopped, up to three times in a row. You see this notice for such a response only once Claude Code has used up those continuations. Before v2.1.246, Claude Code ended a non-interactive turn with this notice on the first cut-off.
- In a [subagent](../09-Agents-Patterns/sub-agents.md#api-errors-in-subagents), whether the session is interactive or not: when its cut-off response contains text but no tool calls, Claude Code prompts the subagent to continue. The notice becomes the subagent’s last message only once those continuations are used up. Before v2.1.257, a subagent showed this notice on the first cut-off.

**What to do:**

- In an interactive session, read the response that remains on screen: Claude Code keeps every block Claude completed before the error, but discards an interrupted final block when the turn ends, so the final sentences or tool calls may be missing. Reply with `continue` to have Claude pick up from its last completed block.
- In [non-interactive mode](headless.md) (`-p`):
  - With the default text output, Claude Code prints the last completed block of text it still holds from earlier in the turn, followed by this message. When it holds none, Claude Code prints this message alone, for example because Claude Code compacted the conversation mid-turn and cleared that text. Before v2.1.219, Claude Code printed only this message in `-p` text output and dropped the response it had already produced.
  - With `--output-format json` or `stream-json`, Claude Code reports this message in the `result` field.
  - To continue the turn once the connection is stable, resume the session and send `continue` as described in [Continue conversations](headless.md#continue-conversations).


[​](#auto-mode-cannot-determine-the-safety-of-an-action)

Auto mode cannot determine the safety of an action

The model that [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) uses to classify actions couldn’t produce a decision, so auto mode didn’t approve the action automatically. The message you see depends on how the classifier failed. Reads, searches, and edits inside your working directory skip the classifier, so they keep working in all of these cases. When the classifier model is unavailable:

```python
<model> is temporarily unavailable, so auto mode cannot determine the safety of <tool> right now. Wait a moment and then try this action again.
```

In an interactive session, a dim `Not run · auto mode's check had no usable answer` row appears under the tool call instead of this message. Press `Ctrl+O` to read the message in the [transcript viewer](interactive-mode.md#transcript-viewer). The `gave no verdict` denials under [The server returned no safety verdict](#the-server-returned-no-safety-verdict) show the same row. Before v2.1.296, the message appeared under the call as a red error. When Claude Code can determine the failure category, it names the category in parentheses after `temporarily unavailable`, for example `<model> is temporarily unavailable (rate-limited), so auto mode cannot determine the safety of <tool> right now`. The categories are `(rate-limited)`, `(overloaded)`, `(server error)`, `(timed out)`, and `(connection failed)`. If `(timed out)` or `(connection failed)` repeats, check your connection; see [Unable to connect to API](#unable-to-connect-to-api). Before v2.1.229, the message never named a category and read `Wait briefly and then try this action again`. When no category fits, the message appears with no category in parentheses; more than one failure produces that form. On [Amazon Bedrock](amazon-bedrock.md), including the [Mantle endpoint](amazon-bedrock.md#use-the-mantle-endpoint), it also appears when your AWS account can’t invoke the model named in the message, and that failure repeats on every retry until your account is granted access to the model. **What to do:**

- Retry after a few seconds; Claude sees the same message and usually retries on its own. A transient failure is unrelated to [auto mode eligibility](permission-modes.md#eliminate-prompts-with-auto-mode); you don’t need to change settings
- If retries keep failing, continue with read-only tasks and come back to the blocked action later
- On Amazon Bedrock, if the message returns on every retry, check that your account can invoke the model it names: for standard Amazon Bedrock models, confirm your [IAM policy](amazon-bedrock.md#iam-configuration) allows invoking it; for Mantle model IDs, [contact your AWS account team](amazon-bedrock.md#mantle-endpoint-errors)
- If the message returns on every retry and names the model you set in [`CLAUDE_CODE_AUTO_MODE_MODEL`](permission-modes.md#choose-the-classifier-model), check that the API or cloud provider your session runs on serves that model ID. If it doesn’t, set the variable to a model ID it serves, or unset the variable to use the [default classifier model](permission-modes.md#default-classifier-model).

When a classifier request fails because your OAuth token expired or was rotated by another session, Claude Code refreshes the token and retries the request once, so a routine token expiry doesn’t surface as this message. Before v2.1.216, an expired or rotated token failed each classifier request, and auto mode denied every checked action with this message until the token was refreshed. When the classifier returned an unparseable response:

```python
Auto mode could not evaluate this action and is blocking it for safety — run with --debug for details
```

**What to do:**

- Retry the action; this usually succeeds on the next attempt
- Run `claude --debug` and repeat the action for details in the debug log

When a separate API safety check blocked the classifier request because of earlier conversation content:

```python
Auto mode could not evaluate this action and is blocking it for safety — a safety check separate from auto mode blocked this request because of earlier conversation content — it isn't about the action itself — run with --debug for details
```

Claude Code denies the action but tells Claude this isn’t a judgment that the action is unsafe, and to continue with other tasks rather than retry. These denials don’t count toward [auto mode’s pause thresholds](permission-modes.md#when-auto-mode-falls-back). In a [non-interactive](headless.md) `-p` run, Claude Code doesn’t stop the run. What Claude receives depends on where it requested the action:

- To a [background subagent](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) in a `-p` run without `--input-format stream-json`, Claude Code returns an error result containing `Agent aborted: auto mode classifier request refused by the safety safeguard in headless mode`
- Everywhere else, including interactive sessions and the main conversation of a `-p` run, Claude Code returns that denial to Claude

Before v2.1.225, Claude Code counted these refusals toward the pause thresholds and returned the same rejection message as a genuine classifier block. **What to do:**

- This is not a decision about your action. Content already in your conversation triggered a safety filter on the API when auto mode sent the conversation to the classifier
- Retrying will not help; the same conversation content will trigger the filter again
- In an interactive session, switch to a different [permission mode](permission-modes.md) so you can approve the action when prompted
- Start a fresh conversation without the triggering content

When the conversation is too long for Claude Code’s classifier request and Claude Code can’t [compact it on its own](#was-not-reviewed-and-did-not-run):

```python
Auto mode classifier transcript exceeded context window — falling back to manual approval (try /compact to reduce conversation size)
```

What happens to the action depends on where Claude requested it:

- In an interactive session, auto mode falls back to a normal permission prompt for that action so you can approve or deny it manually
- To a [background subagent](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) in a [non-interactive](headless.md) `-p` run without `--input-format stream-json`, Claude Code returns an error result containing `Agent aborted: auto mode classifier transcript exceeded context window in headless mode`, and the run continues
- Elsewhere in a `-p` run without a [`--permission-prompt-tool`](cli-reference.md#cli-flags), there is no prompt to fall back to, so the action doesn’t run and the run continues

**What to do:**

- In an interactive session, approve or deny the action in the prompt that appears
- In an interactive session, run `/compact` to reduce the conversation size so subsequent actions fit within the classifier window again


[​](#the-server-returned-no-safety-verdict)

The server returned no safety verdict

Under [server-side classifier review](permission-modes.md#server-side-classifier-review), auto mode denies an action when the server gives no verdict for it. The denial names a category in parentheses when Claude Code can determine one, such as `(timed out)`:

```python
The server-side auto mode classifier gave no verdict (timed out), so auto mode cannot determine the safety of <tool>.
```

The rest of the message tells Claude whether one retry can help. Before some of these denials, Claude Code waits so that Claude’s next attempt doesn’t follow at once. During the wait in an interactive session, the spinner shows `Auto mode check unavailable` with a countdown, and pressing `Esc` interrupts the turn. After ten responses in a row with no verdict, auto mode stops the turn:

```python
Auto mode is unavailable — the server returned no safety verdict for the last 10 responses, so Claude stopped. Send a message to try again, or switch out of auto mode.
```

The stop message appears in a different place in each kind of session:

- In an interactive session, the message appears as a warning in the transcript and the turn ends
- In a [non-interactive](headless.md) `-p` run, the run ends and reports an execution error. With the default text output, the message prints on stderr.
- When a [subagent](../09-Agents-Patterns/sub-agents.md) hit the limit, the subagent stops before finishing, and Claude receives whatever it produced with a note that auto mode stopped it

**What to do:**

- In an interactive session, press `Ctrl+O` to read the denial text in the [transcript viewer](interactive-mode.md#transcript-viewer).
- If the denial names `(the conversation is too long for the check)`, run `/compact` at the Claude Code prompt to shorten the conversation. Until the conversation is shorter, sending another message gets the same denial. If you turned [auto-compact](settings-reference.md#autocompactenabled) off, turn it back on so Claude Code compacts on its own next time.
- Send another message to have Claude try again. The count of responses starts over.
- If the stop repeats and your requests go through an [LLM gateway or proxy](../13-Enterprise-Admin/llm-gateway.md), check whether it cuts streaming responses short or rewrites them. [Server-side classifier review](permission-modes.md#server-side-classifier-review) says which gateway behavior causes denials, and the [gateway compatibility guide](../13-Enterprise-Admin/llm-gateway-protocol.md#feature-pass-through) lists what to pass through unchanged.
- Set `CLAUDE_CODE_AUTO_MODE_SERVER=0` before you start Claude Code to use its own classifier requests instead. Before v2.1.281, Claude Code didn’t read the variable on a direct connection to the Anthropic API.
- To approve the actions yourself instead, [switch out of auto mode](permission-modes.md#switch-permission-modes)

Before v2.1.280, Claude Code denied each action from a response without a verdict immediately and never stopped the turn. Before v2.1.302, on a direct connection to the Anthropic API, Claude Code didn’t compact a conversation that had grown too long for the server’s check.


[​](#was-not-reviewed-and-did-not-run)

Was not reviewed and did not run

A `was not reviewed and did not run` denial means the conversation is too long for the [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) classifier to check the action, so the action didn’t run. Claude Code returns this message to Claude:

```python
<tool> was not reviewed and did not run: the conversation is too long for auto mode's classifier. Claude Code will try to compact the conversation before the next request; if this action is still needed after that, issue it again and it will be reviewed normally.
```

If the compaction fails, later actions the classifier can’t check get one of two other messages:

- A [`gave no verdict (the conversation is too long for the check)`](#the-server-returned-no-safety-verdict) denial
- The [`Auto mode classifier transcript exceeded context window`](#auto-mode-cannot-determine-the-safety-of-an-action) message

**What to do:**

- If the compaction the message announces succeeds, you don’t need to do anything.
- If you see either of those two messages, run `/compact` at the Claude Code prompt to shorten the conversation yourself. If you turned [auto-compact](settings-reference.md#autocompactenabled) off, turn it back on so Claude Code compacts on its own next time.


[​](#agent-terminated-early-due-to-an-api-error)

Agent terminated early due to an API error

A [subagent](../09-Agents-Patterns/sub-agents.md)’s API request failed terminally, for example because a usage limit was reached or retries for a server error ran out, so the subagent stopped before finishing its task. This message requires Claude Code v2.1.199 or later; before then the API error text was returned to Claude as if it were the subagent’s result.

```python
Agent terminated early due to an API error: <error detail>
```

**What to do:**

- Match the error detail after the colon to its own section on this page, such as [Usage limits](#usage-limits) or [Server errors](#server-errors), and follow that section’s steps
- Once the underlying error clears, ask Claude to retry the task or [resume the subagent](../09-Agents-Patterns/sub-agents.md#resume-subagents)

When a rate limit, overload, or server error interrupts a foreground subagent that already produced text output, Claude receives that partial output marked as incomplete instead of this error. A subagent whose only output was tool calls gets this error too; in v2.1.199 that shape returned an empty partial result instead. See [API errors in subagents](../09-Agents-Patterns/sub-agents.md#api-errors-in-subagents).


[​](#usage-limits)

Usage limits

Most errors in this section mean a quota tied to your account or plan has been reached. Three work differently: [`Server is temporarily limiting requests`](#server-is-temporarily-limiting-requests) is a server-side throttle unrelated to your plan quota, [`Usage credits required for 1M context`](#usage-credits-required-for-1m-context) is an entitlement check rather than an exhausted quota, and [`The prompt to confirm went unanswered`](#the-prompt-to-confirm-went-unanswered) means a usage-credits consent prompt closed unanswered, whether or not a quota was reached.


[​](#youve-hit-your-session-limit)

You’ve hit your session limit

Subscription plans include a rolling usage allowance. When it runs out you see one of these messages:

```python
You've hit your session limit · resets 3:45pm
You've hit your weekly limit · resets Mon 12:00am
You've hit your Opus limit · resets 3:45pm
You've hit your Sonnet limit · resets 3:45pm
```

Claude Code blocks further requests until the reset time shown in the message. The session and weekly limits are shared across all models, so switching models doesn’t restore access. The Opus and Sonnet limits each apply only to requests to that model family, so switching to a model outside the family with `/model` keeps you working. In an interactive session signed in with a claude.ai subscription, Claude Code can also wait in the open session and continue the interrupted task shortly after the reset. See [Wait for a usage limit to reset](interactive-mode.md#wait-for-a-usage-limit-to-reset) for what you see, how to start or cancel a wait, and how to turn automatic continue off. Before v2.1.234, Claude Code didn’t offer this wait. Usage counts against the session and weekly allowances at the same time. A single burst of heavy activity, such as a large workflow fanout, can exhaust the weekly allowance before the session window resets. **What to do:**

- Wait for the reset time shown in the error
- In the Code tab of the [Desktop app](../16-Mobile-Desktop/desktop.md), the session-limit card offers an **Auto-continue when limits reset** checkbox. The weekly-limit card doesn’t. When it’s checked, the Desktop app retries the interrupted turn after the reset and shows the retry time on the card. The Desktop checkbox and the CLI’s **Continue automatically at usage limit** setting in `/config` are separate, so turn each off on its own.
- For the Opus or Sonnet limit, run `/model` and switch to a model outside that family to keep working. Each model has its own prompt cache, so the next request re-reads the whole conversation with no cache hits; see [Switching models](prompt-caching.md#switching-models)
- Run `/usage` to see your plan limits and when they reset
- Run `/usage-credits` to buy additional usage on Pro and Max, or to request it from your admin on Team and Enterprise. See [usage credits for paid plans](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md) for how this is billed.
- To upgrade your plan for higher base limits, see [claude.com/pricing](../17-Billing-Plans/pricing.md)

Before a window runs out, Claude Code can warn you that you’ve used most of it, with a message such as `You've used 85% of your session limit · resets 3:45pm`. To watch your remaining allowance continuously, add the `rate_limits` fields to a [custom status line](statusline.md#rate-limit-usage), or in the Desktop app click the [usage ring](../16-Mobile-Desktop/desktop.md#check-usage) next to the model picker.


[​](#usage-credits-required-for-1m-context)

Usage credits required for 1M context

The selected model uses the 1M-token extended context window, and your plan only includes it through usage credits.

```python
API Error: Usage credits required for 1M context · run /usage-credits to turn them on (they take effect after you restart Claude Code), or /model to switch to standard context
```

In a session the Claude Desktop app runs, the hint names no commands: it points at the claude.ai usage settings page, or on Team and Enterprise plans says to turn on usage credits at claude.ai/admin-settings/usage or to ask your admin. This is an entitlement check, not a quota exhaustion. It fires even when your session and weekly allowances have capacity remaining. See [Extended context](model-config.md#extended-context) for which plans include 1M context directly and which require usage credits. When this error appears mid-conversation because the context grew past 200K tokens, Claude Code automatically compacts the conversation back under the standard context limit and keeps the session at that limit afterward, so no action is needed. On versions before v2.1.172, the error repeated on every subsequent request including `/compact`; run `/clear` on those versions to recover. The steps below apply when you explicitly selected a `[1m]` model. **What to do:**

- Run `/model` and select the variant without the `[1m]` suffix to fall back to the standard context window
- Where the message names `/usage-credits`, run it to turn on metered billing for the 1M variant on Pro and Max, or to request usage credits from your admin on Team and Enterprise. Once usage credits are on, restart Claude Code or start a new session, whichever the message says. Until then, the session stays at the standard context limit.
- If the error persists after `/model`, a 1M model ID may be set elsewhere. See [Setting your model](model-config.md#setting-your-model) for the configuration locations to check in priority order.
- To remove 1M variants from the model picker entirely, set [`CLAUDE_CODE_DISABLE_1M_CONTEXT=1`](env-vars.md)

Before v2.1.268, the message ended with `run /usage-credits to turn them on, or /model to switch to standard context` and didn’t mention restarting.


[​](#the-prompt-to-confirm-went-unanswered)

The prompt to confirm went unanswered

If your account requires the [Fable usage-credits consent](model-config.md#fable-and-usage-credits), Claude Code asks you to confirm before a Fable request bills usage credits. When the consent prompt closes with nobody answering it, Claude Code ends the turn with one of these messages:

```python
Fable limit reached · continuing on Fable 5.1 uses usage credits, and the prompt to confirm went unanswered — nothing was sent · answer it where this session is running, or /model to change
Fable 5.1 now uses usage credits · the prompt to confirm went unanswered — nothing was sent · answer it where this session is running, or /model to change
```

The messages name the session’s Fable model, so on Fable 5 they read `continuing on Fable 5` and `Fable 5 now uses usage credits`. Before v2.1.257, the first message began `Fable 5 limit reached`. This happens in [Remote Control](remote-control.md) sessions, [background sessions](../09-Agents-Patterns/agent-view.md), [agent team](../09-Agents-Patterns/agent-teams.md) teammate sessions, and sessions that another application hosts through the Agent SDK. For when Claude Code closes the prompt, see [Fable and usage credits](model-config.md#fable-and-usage-credits). **What to do:**

- Where the session runs, at the terminal or in the application hosting it, send another prompt and answer the consent prompt when it reappears. For a background session, attach to it from the [agents view](../09-Agents-Patterns/agent-view.md) first. Resending from a Remote Control client shows this message again, because the client can’t display the prompt.
- Run `/model` to switch to a model that doesn’t bill usage credits
- To give yourself more time, set [`dialogExpiry`](settings-reference.md#dialogexpiry) to a longer value or `"never"`

Before v2.1.236, this message didn’t appear: while a Remote Control client was connected, Claude Code waited 60 seconds for an answer and then continued the turn on your default model.


[​](#server-is-temporarily-limiting-requests)

Server is temporarily limiting requests

The API applied a short-lived throttle that is unrelated to your plan quota.

```python
API Error: Server is temporarily limiting requests (not your usage limit)
```

Claude Code tells these apart from your plan limit by the absence of the unified quota headers a real limit response carries. As of v2.1.199 this is [retried automatically](#automatic-retries) with backoff before being shown, whichever way you authenticate. On earlier versions, a session signed in with a claude.ai subscription failed the turn on the first occurrence; only API key and Enterprise sign-ins retried it. **What to do:**

- Wait briefly and try again
- Check [status.claude.com](https://status.claude.com) if it persists


[​](#request-rejected-429)

Request rejected (429)

You have hit the rate limit configured for your API key, Amazon Bedrock project, or Google Cloud project.

```python
API Error: Request rejected (429) · this may be a temporary capacity issue. If it persists, check https://status.claude.com.
```

The trailing sentence names where to check service health and varies by provider. Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry configurations name that provider’s service status instead of the Anthropic status page. A custom `ANTHROPIC_BASE_URL` names the gateway host. When a proxy, load balancer, or gateway between Claude Code and the API answers with its own HTML 429 page, the text after the `·` is that page’s title when it has one, such as `Too Many Requests`. Before v2.1.281, the whole page’s markup was printed after the `·`. **What to do:**

- Run `/status` and confirm the active credential is the one you expect. A stray `ANTHROPIC_API_KEY` in your environment can route requests through a low-tier key instead of your subscription.
- Check your provider console for the active limits and request a higher tier if needed
- For Anthropic API keys, see the [rate limits reference](../04-API-Reference/Endpoints/rate-limits.md) for how tiers work and how to set per-workspace caps
- Reduce concurrency: avoid running many parallel subagents, or switch to a smaller model with `/model` for high-volume scripted runs


[​](#youve-hit-your-monthly-spend-limit)

You’ve hit your monthly spend limit

Your plan’s included usage can’t cover this request, and the [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md) 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](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:

```python
You've hit your monthly spend limit · raise it at https://claude.ai/settings/usage?from=cc_cli_limit_message
You've hit your individual spend limit · ask your admin for a higher limit
You've hit your org's monthly spend limit · visit https://claude.ai/admin-settings/usage to raise it
You've hit your team's shared budget · ask your admin to raise it at https://claude.ai/admin-settings/usage
You've hit your channel's monthly spend limit · an org owner or channel manager can raise it in the channel's Claude settings
```

`team's shared budget` is a pooled budget an admin assigned to a group you belong to; the message doesn’t name the group. `channel's monthly spend limit` is the budget of the one Slack channel the session runs in, so your organization may still have budget outside it. When one of your plan’s windows is what ran out, the message also says when that window resets, for example `· your session limit resets 3:45pm`, and access returns then without anyone raising the limit. On organizations with usage-based billing, the message says `usage limit` in place of `spend limit`, as in `You've hit your individual usage limit`. If you connect through a Claude apps gateway and see lowercase `spend limit reached`, that is your gateway operator’s cap instead; see [Spend limit reached](#spend-limit-reached). **What to do:**

- On Pro and Max, increase your monthly spend limit in [**Settings \> Usage**](https://claude.ai/settings/usage) on claude.ai, or run `/usage-credits`
- On Team and Enterprise, increase the limit in [**Organization settings \> Usage**](https://claude.ai/admin-settings/usage) if you manage billing, or ask an admin to. `/usage-credits` sends that request to your admin for you
- For a channel’s limit, ask an org owner or the channel’s manager to raise it on claude.ai. See [Per-channel limits](https://claude.com/docs/claude-tag/admins/set-spend-limit#per-channel-limits) in the Claude Tag documentation
- If the message names a reset time for your plan’s window, you can wait for it instead
- Run `/usage` to see your plan’s windows and when each resets


[​](#spend-limit-reached)

Spend limit reached

You connect through a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) and have passed a [spend cap](../13-Enterprise-Admin/claude-apps-gateway-spend-limits.md) your gateway operator set. The gateway blocks your requests until the named period resets or the operator raises the cap. It marks each blocked `429` response `x-should-retry: false`, so Claude Code shows this message without retrying.

```python
spend limit reached (daily; resets 2026-08-09 00:00 UTC)
```

The message names the cap’s period and reset time, and when the operator configured a `blocked_message`, their instructions follow it. Before v2.1.225, the message read only `spend limit reached`; a gateway on an older version still sends that shorter form. **What to do:**

- Wait for the reset time the message names, or follow the operator’s instructions if the message carries them
- Ask your gateway operator to raise the cap if you hit it routinely

A related message, `spend limit unavailable`, means the gateway could not read its spend records and blocked the request as a precaution rather than over your cap. It usually clears on its own; if it persists, tell your gateway operator.


[​](#credit-balance-is-too-low)

Credit balance is too low

Your Console organization has run out of prepaid credits, or Claude Code is sending your requests with a Console API key when you meant to use your subscription.

```python
Credit balance is too low
```

**What to do:**

- If you have a Pro, Max, Team, or Enterprise plan and see this, run `/status` and check the `API key` row. An approved `ANTHROPIC_API_KEY` in your environment routes requests through that key instead of your subscription. Unset it in the current shell and remove it from your shell profile, then relaunch `claude`. Run `/login` if you haven’t signed in with your subscription yet.
- Add credits at [platform.claude.com/settings/billing](../04-API-Reference/Other/playground.md), and consider enabling auto-reload there so the balance refills before it hits zero
- Set per-workspace spend caps in the Console to prevent a single project from draining the org balance. See [Manage costs effectively](../17-Billing-Plans/costs.md).


[​](#could-not-update-your-spend-limit)

Could not update your spend limit

The server rejected a spend limit change you made from the prompt that appears when you reach your spend limit.

```python
Could not update your spend limit: <reason from the server>
```

When the server explains the rejection, the message ends with that reason, and retrying the same value fails again. When the failure has no server-provided reason, such as a dropped connection, the message reads `Could not update your spend limit. Press Enter to retry.` and retrying can succeed. Before v2.1.216, Claude Code showed the generic form for every failure. **What to do:**

- If the message includes a reason, choose a limit that satisfies it, such as a lower amount
- If the message shows only the generic form, retry; the failure may be transient
- If the change keeps failing, make it from your [claude.ai billing settings](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md) in the browser instead


[​](#authentication-errors)

Authentication errors

These errors mean Claude Code cannot prove who you are to the API. Run `/status` at any time to see which credential is currently active.


[​](#not-logged-in)

Not logged in

No valid credential is available for this session.

```python
Not logged in · Please run /login
```

In a session the Claude Desktop app runs, such as the Code tab or Cowork, the message reads `Authentication required · Sign in again to continue`, and you sign in again from the app. If you sign in with your claude.ai account in another Claude Code window that uses the same [configuration directory](claude-directory.md), an interactive session showing this message starts using that login on its own. You don’t need to restart it. Before v2.1.286 on macOS, the session could keep showing the message after you signed in from another window. On those versions, restart the session that shows the message. **What to do:**

- Run `/login` to authenticate with your Claude subscription or Console account
- If you expected an environment variable to authenticate you, confirm `ANTHROPIC_API_KEY` is set and exported in the shell where you launched `claude`
- For CI or automation where interactive login is not possible, configure an [`apiKeyHelper`](settings-reference.md#apikeyhelper) script that fetches a key at startup
- See [Authentication precedence](authentication.md#authentication-precedence) to understand which credential Claude Code uses when several are present

If you are prompted to log in repeatedly, see [Not logged in or token expired](troubleshoot-install.md#not-logged-in-or-token-expired) for system clock checks and macOS credential-storage recovery steps.


[​](#could-not-resolve-authentication-method)

Could not resolve authentication method

The session reached the API client without any credential. [Background sessions](../09-Agents-Patterns/agent-view.md) and cloud sessions show this message when the worker starts without a credential. Interactive, `-p`, and Agent SDK runs report the same condition as [Not logged in](#not-logged-in) and write this string only to their debug log, so if you found it there, follow that entry instead.

```python
Could not resolve authentication method. Expected one of apiKey, authToken, credentials, config, or profile to be set. Or for one of the "X-Api-Key" or "Authorization" headers to be explicitly omitted
```

On current versions the error means no credential was available to the worker process. Before v2.1.174, a background session assigned to an idle pre-initialized worker could fail this way even when valid credentials were configured. Before v2.1.176, a cloud session that sat idle before being claimed could too. Upgrade to recover. **What to do:**

- Upgrade to v2.1.176 or later if this appears in a background or cloud session and your credentials are already configured
- Confirm `ANTHROPIC_API_KEY`, `CLAUDE_CODE_OAUTH_TOKEN`, or your cloud provider credentials are set in the environment that launches the worker, not only in your interactive shell
- For the Agent SDK, see [authentication setup in the quickstart](../05-Agent-SDK/agent-sdk-quickstart.md#setup)
- Run `/status` in an interactive session in the same environment to confirm which credential source resolves


[​](#invalid-api-key)

Invalid API key

The `ANTHROPIC_API_KEY` environment variable or `apiKeyHelper` script returned a key the API rejected, or Claude Code blocked a key from `ANTHROPIC_API_KEY` before sending it.

```python
Invalid API key · Fix external API key
```

When the message continues past `Fix external API key` with a description such as `Invalid X-Api-Key header value from ANTHROPIC_API_KEY: it contains a line break at character 41 (120 characters on 2 lines).`, the API never saw the key. Claude Code found a character that HTTP headers can’t carry and stopped the request before sending it. See [Invalid request header value](#invalid-request-header-value) for how to read the description and fix the value. **What to do:**

- Check for typos and confirm the key has not been revoked in the [Console](../04-API-Reference/Other/playground.md)
- In the same shell, run `env | grep ANTHROPIC`, or in PowerShell `Get-ChildItem Env:ANTHROPIC*`. Tools like direnv, dotenv shell plugins, and IDE terminals can load a stale key from a `.env` file in your project without you setting it explicitly.
- Unset `ANTHROPIC_API_KEY` and run `/login` to use subscription auth instead
- If the key comes from an [`apiKeyHelper`](settings-reference.md#apikeyhelper) script, run the script directly to confirm it prints a valid key on stdout
- Run `/status` to confirm which credential source Claude Code is actually using


[​](#your-apikeyhelper-script-is-failing)

Your apiKeyHelper script is failing

Claude Code ran the command in your [`apiKeyHelper`](settings-reference.md#apikeyhelper) setting and didn’t get a key back. Without one, the request reaches the API with a placeholder credential, and the API rejects it with `401`. The `Authentication` panel in the terminal shows which of these happened:

- The command exited with an error or timed out
- The command printed nothing to stdout
- The command printed something besides the key, such as a login banner or a log line. The panel shows `returned output that cannot be used as an API key` and says what’s wrong, without repeating the output. Before v2.1.227, Claude Code sent whatever the command printed, after trimming surrounding whitespace.

```python
Your apiKeyHelper script is failing · This usually means you need to re-authenticate with your provider · Run /status to see the script's error output
```

In [non-interactive mode](headless.md), stderr also carries the specific reason, prefixed with `apiKeyHelper failed:`. Claude Code re-runs the script and retries the request up to two more times before showing this message, so the failure surfaces within three attempts. Before v2.1.208, Claude Code spent the full [retry budget](#automatic-retries) resending the request with the placeholder credential and then reported a generic `401` authentication error instead of the script failure. Running `/login` doesn’t help here: the helper’s output [takes precedence](authentication.md#authentication-precedence) over a saved login for as long as the setting is present. **What to do:**

- Run the command configured in `apiKeyHelper` directly in your shell to reproduce the failure
- If the command reports an expired session, re-authenticate with your credential provider, for example by signing in to your SSO or secrets vault again
- Fix the command so it prints only the key to stdout, as a single token of printable ASCII up to 16,384 characters, and exits with code 0. See [rotate credentials with apiKeyHelper](../13-Enterprise-Admin/llm-gateway-connect.md#rotate-credentials-with-apikeyhelper) for a working setup.
- Run `/status` to see the failure and confirm `apiKeyHelper` is the active credential source. The `apiKeyHelper` row shows `Failing` with the last failure’s detail, such as the exit code and the command’s error output, and disappears after the next successful run. Before v2.1.274, `/status` showed only the credential source, not the failure.
- Each time the command fails, its exit code and error output also appear in an `Authentication` panel in the terminal. Before v2.1.212, the panel was titled `Cloud authentication`.


[​](#invalid-request-header-value)

Invalid request header value

A value Claude Code was about to send as a request header contains a character that HTTP headers can’t carry: a line break, a NUL byte, or a character above `U+00FF`, such as a curly quote or a zero-width space. Claude Code stops the request before anything is sent and names the variable or setting to fix. The usual cause is a credential pasted from a document or chat that carried an invisible character or a stray line break. Claude Code runs this check when it sends requests to the Claude API directly or through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md). On a third-party cloud provider such as [Amazon Bedrock](amazon-bedrock.md), Claude Code doesn’t run it before sending.

```python
Invalid auth token · Fix external auth token
Invalid ANTHROPIC_CUSTOM_HEADERS · Fix the environment variable
Invalid request header from the environment · Fix the environment variable
```

The first part of the message depends on where the bad value came from:

- `Invalid auth token`: a bearer token from [`ANTHROPIC_AUTH_TOKEN`](env-vars.md) or [`CLAUDE_CODE_OAUTH_TOKEN`](env-vars.md)
- `Invalid ANTHROPIC_CUSTOM_HEADERS`: a header name or value you set in [`ANTHROPIC_CUSTOM_HEADERS`](env-vars.md). The description counts which `Name: Value` pair is at fault, such as `distinct header 2 of 3 parsed from ANTHROPIC_CUSTOM_HEADERS`, without repeating the name or value, since you chose both.
- `Invalid request header from the environment`: a value Claude Code copies into a request header from another environment variable, such as `CLAUDE_AGENT_SDK_CLIENT_APP`. The description names the variable to fix.

Claude Code reports a bad `ANTHROPIC_API_KEY` caught by this check as [Invalid API key](#invalid-api-key), with the same trailing description. It reports a bad saved `/login` credential as [Not logged in](#not-logged-in) instead; run `/login` to save a fresh one. An [`apiKeyHelper`](settings-reference.md#apikeyhelper) script’s output never reaches this check: Claude Code validates it when the script runs, and output an HTTP header can’t carry fails with [Your apiKeyHelper script is failing](#your-apikeyhelper-script-is-failing). After the second `·`, the message describes the problem, as in this full example:

```python
Invalid auth token · Fix external auth token · Invalid Authorization header value from ANTHROPIC_AUTH_TOKEN: it contains a line break at character 41 (120 characters on 2 lines).
```

Positions count characters starting at one. The description is built from fixed phrases and character counts, so it never includes the value itself. It names the offending character only when it is a well-known invisible or typographic character, such as a byte-order mark, a zero-width space, or a curly quote, and reports anything else as `a non-ASCII character`. **What to do:**

- Re-set the variable or setting the message names, retyping the characters around the reported position rather than pasting from the same source again
- For `ANTHROPIC_CUSTOM_HEADERS`, keep one `Name: Value` pair per line and rewrite the pair the message counts
- Run `/status` to confirm which credential source is active


[​](#this-organization-has-been-disabled)

This organization has been disabled

Claude Code is using a stale `ANTHROPIC_API_KEY` from a disabled Console organization. When you have a saved subscription login, the key overrides it.

```python
Your ANTHROPIC_API_KEY belongs to a disabled organization · Unset the environment variable to use your subscription instead
Your ANTHROPIC_API_KEY belongs to a disabled organization · Update or unset the environment variable
API Error: 400 ... This organization has been disabled.
```

The hint after the `·` depends on your saved credentials: the first form appears when a stored `/login` can take over after you unset the key, and the second when the key is your only credential. Environment variables take precedence over `/login`, so a key exported in your shell profile or loaded from a `.env` file is used even when you have a working Pro or Max subscription. In non-interactive mode (`-p`), the key is always used when present. **What to do:**

- Unset `ANTHROPIC_API_KEY` in the current shell and remove it from your shell profile, then relaunch `claude`
- If the message says `Update or unset`, you have no saved login to fall back to. Unset the key and run `/login`, or replace the key with one from an active Console organization.
- Run `/status` afterward to confirm the active credential is your subscription
- If no environment variable is set and the error persists, contact support or sign in with a different account.


[​](#your-organization-has-disabled-api-key-authentication)

Your organization has disabled API key authentication

This message requires Claude Code v2.1.169 or later. Your Console organization’s admin has turned off API key authentication, so the API rejects the key Claude Code is sending. The recovery hint after the `·` varies by where the key came from:

```python
Your organization has disabled API key authentication · Run /login to sign in with your claude.ai account
Your organization has disabled API key authentication · Unset ANTHROPIC_API_KEY to use your claude.ai account instead
Your organization has disabled API key authentication · Unset ANTHROPIC_API_KEY and run /login to sign in with your claude.ai account
Your organization has disabled API key authentication · Unset the apiKeyHelper setting and run /login to sign in with your claude.ai account
Your organization has disabled API key authentication · Sign in again with your claude.ai account
```

The last form appears in a session the Claude Desktop app runs, such as the Code tab or Cowork, where you sign in again from the app. Environment variables and `apiKeyHelper` take precedence over `/login`, so running `/login` alone doesn’t help while either is still supplying a key. See [Authentication precedence](authentication.md#authentication-precedence). **What to do:**

- If the message names `ANTHROPIC_API_KEY`, unset it in the current shell and remove it from your shell profile or `.env` file, then relaunch `claude`
- If the message names `apiKeyHelper`, remove the [`apiKeyHelper`](settings-reference.md#apikeyhelper) setting from your `settings.json`
- Run `/login` to sign in with your claude.ai account
- Run `/status` afterward to confirm the active credential is your subscription rather than an API key
- If you need API key authentication for automation, ask your organization admin to re-enable it in the Console


[​](#your-organization-has-disabled-claude-subscription-access)

Your organization has disabled Claude subscription access

Your Claude organization doesn’t allow signing in to Claude Code with a subscription login. Running `/login` again with the same account returns the same error.

```python
Your organization has disabled Claude subscription access for Claude Code · Use an Anthropic API key instead, or ask your admin to enable access
```

This is a server-side organization setting, so it can’t be overridden from local settings, environment variables, or CLI flags. The Agent SDK and `-p` non-interactive mode surface this as the `oauth_org_not_allowed` error code. **What to do:**

- Ask your admin to enable Claude Code access for your organization
- Authenticate with a Console API key instead of your subscription. See [Claude Console authentication](authentication.md#claude-console-authentication) for setup.
- If you are the admin and do not see an option to enable access, contact [Anthropic support](https://support.claude.com)


[​](#routines-are-disabled-by-your-organizations-policy)

Routines are disabled by your organization’s policy

An Owner in your Team or Enterprise organization has turned off [cloud scheduled tasks](web-scheduled-tasks.md), formerly routines, at the organization level. The error appears when you try to create or run one, for example at [claude.ai/code/routines](https://claude.ai/code/routines). On Claude Code v2.1.227 or later, the same setting also [hides `/schedule`](web-scheduled-tasks.md#troubleshooting) in the CLI.

```python
Routines are disabled by your organization's policy.
```

This is a server-side setting, so it can’t be overridden from local settings, environment variables, or CLI flags. **What to do:**

- Ask an Owner in your organization to turn on the **Scheduled tasks (Was Routines)** toggle at [**Organization settings \> Capabilities \> Remote sessions**](https://claude.ai/admin-settings/capabilities)


[​](#remote-control-requires-the-anthropic-api)

Remote Control requires the Anthropic API

The session isn’t talking to the Anthropic API directly, which [Remote Control](remote-control.md) requires.

```python
Remote Control is only available when using Claude via api.anthropic.com. CLAUDE_CODE_USE_BEDROCK is set, so this session is using Amazon Bedrock — unset it (or run in a shell without it) to use Remote Control.
```

A second sentence explains what routed the session away from the Anthropic API; before v2.1.219, the message was the first sentence alone. Depending on the cause, the message names:

- A `CLAUDE_CODE_USE_*` provider variable, such as `CLAUDE_CODE_USE_BEDROCK` for [Amazon Bedrock](amazon-bedrock.md) or `CLAUDE_CODE_USE_VERTEX` for [Google Cloud’s Agent Platform](google-vertex-ai.md)
- [`ANTHROPIC_BASE_URL`](env-vars.md) pointing at a host other than `api.anthropic.com`, such as an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) or proxy, even when you sign in with claude.ai; before v2.1.196, a custom base URL didn’t block Remote Control
- `ANTHROPIC_UNIX_SOCKET` set, so the session sends its requests through a local socket rather than to `api.anthropic.com`
- An enterprise [cloud gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sign-in made through `/login`, which doesn’t support Remote Control and has no variable to unset

**What to do:**

- Unset the variable the message names, such as `CLAUDE_CODE_USE_BEDROCK` or `ANTHROPIC_BASE_URL`, and restart the session, or start Remote Control from a session that talks to the Anthropic API directly
- If the variable isn’t set in your shell, check the `env` key in your [settings files](settings.md#where-settings-live), which applies environment variables to every session
- For this and the other Remote Control startup messages, see [Troubleshoot Remote Control](remote-control.md#troubleshooting)


[​](#remote-control-couldnt-refresh-your-login)

Remote Control couldn’t refresh your login

Claude Code runs a live [Remote Control](remote-control.md) connection on short-lived credentials that it obtains and renews using your saved claude.ai login. When claude.ai stops accepting that login, or Claude Code has no saved login left, Claude Code stops Remote Control and needs you to sign in again. Either failure can happen while Claude Code is still connecting or later, when it renews the credentials. When Claude Code asks the login service to refresh your saved login and gets no answer, it keeps Remote Control running and tries the refresh again while the connection’s current credential is still valid. A refresh gets no answer when Claude Code can’t reach the login service, the request times out, or the service fails without rejecting your login. If the login service still isn’t answering when that credential expires, Claude Code stops Remote Control and reports `OAuth token refresh failed`. When Claude Code stops Remote Control, it shows the reason in a warning and in a transcript line that starts with `Remote Control disconnected`. Your local session keeps running without Remote Control. This section covers these lines:

```python
Remote Control disconnected — Claude.ai login expired — run /login to restore Remote Control
Remote Control disconnected — Claude.ai login expired — run /login, then /remote-control
Remote Control disconnected — Claude.ai login was rejected — run /login, then /remote-control
Remote Control disconnected — OAuth token unavailable — run /login to restore Remote Control
Remote Control disconnected — OAuth token refresh failed — run /login to re-authenticate
Remote Control disconnected — JWT refresh failed: no OAuth token — run /login
Remote Control disconnected — Signed out of Claude — run /login, then /remote-control
```

Claude Code names the cause in the middle of the message:

- `Claude.ai login expired` and `Claude.ai login was rejected`: claude.ai no longer accepts your saved login token, because it expired or was revoked
- `OAuth token unavailable`: Claude Code had no saved login token when the connection’s credential came due for renewal
- `OAuth token refresh failed`: claude.ai rejected your saved login token while Claude Code was reconnecting, and refreshing the token produced no new one
- `JWT refresh failed: no OAuth token`: Claude Code found no saved login token to renew with
- `Signed out of Claude`: you signed out on this machine, for example by running `/logout` in another terminal, so Claude Code has no saved login left to renew the connection with

**What to do:**

- Run `/login` to sign in again
- Run `/remote-control` to reconnect the session. Messages ending `run /login to restore Remote Control` don’t need this step: Claude Code reconnects on its own once you sign in.

Before v2.1.224, `OAuth token refresh failed — run /login to re-authenticate` read `OAuth token refresh failed — re-authenticate, then re-enable Remote Control`, and `JWT refresh failed: no OAuth token — run /login` read `no OAuth token available for recovery (code <N>)`. The `Claude.ai login expired`, `Claude.ai login was rejected`, and `OAuth token unavailable` messages were added in v2.1.225. Before v2.1.238, Claude Code reported the cases that now say `Signed out of Claude` as `JWT refresh failed: no OAuth token — run /login`, and stopped Remote Control with `Claude.ai login expired — run /login to restore Remote Control` as soon as one login refresh got no answer.


[​](#remote-control-could-not-renew-this-computers-connection)

Remote Control could not renew this computer’s connection

This warning appears in the terminal running [`claude remote-control`](remote-control.md#start-a-remote-control-session) when the server can’t use your claude.ai login to renew its connection’s credential before it expires. The warning’s last sentence says how long the current credential still works, or that it has already expired:

```python
Remote Control could not renew this computer's connection: claude.ai did not accept the sign-in it uses. Run `claude /login` to sign in again. The connection keeps working for about 26 hours; if it still cannot sign in then, it stops.
```

**What to do:**

- If the warning tells you to run `claude /login`, open another terminal on the machine running the server, run `claude /login` there, and sign in with your claude.ai account
- If the server still can’t sign in once the connection’s credential has expired, it prints an error containing `Poll: Authentication failed (401)` and stops. Sign in again as the warning’s second sentence says, then run `claude remote-control` again in the terminal where the server stopped.


[​](#remote-control-stopped-because-the-signed-in-account-changed)

Remote Control stopped because the signed-in account changed

Claude Code shows this line during a [Remote Control](remote-control.md) session when you sign in to a different claude.ai account or organization on this machine. You made the switch outside the Claude Code session, for example by running `/login` in another terminal. A Remote Control session that you started while signed in through `/login` belongs to the claude.ai account and organization that were signed in at the time.

```python
Remote Control disconnected — signed-in claude.ai account or organization changed on this machine — run /remote-control to start a session for the current account, or /login to switch back, then /remote-control
```

Claude Code stops the Remote Control session as soon as claude.ai confirms that the account or organization changed. Your local session keeps running without Remote Control. **What to do:**

- Run `/remote-control` to start a new Remote Control session under the current account or organization
- To switch back, run `/login` and sign in to the previous account or organization again. Then run `/remote-control`.

Before v2.1.234, Claude Code didn’t notice when you switched to a different account or organization outside the Claude Code session. Claude Code kept the Remote Control session connected until a later request to the Remote Control server failed with `Remote Control server rejected the request (HTTP 404)`. That failure could come hours after the switch.


[​](#remote-control-stopped-because-the-app-running-the-session-signed-out-or-switched-accounts)

Remote Control stopped because the app running the session signed out or switched accounts

When the Claude desktop app or an IDE hosts your session, Claude Code gets its login token from that app rather than from `/login`. When claude.ai rejects that token, Claude Code asks the app for a new one. If the app answers that it’s signed out, or that it’s now signed in to a different Claude account, Claude Code ends the [Remote Control](remote-control.md) session and sends the app one of these lines:

```python
Remote Control stopped — the app running this session is now signed in to a different Claude account
Remote Control stopped — the app running this session is signed out of Claude. Sign in there, then turn Remote Control back on
```

Your local session keeps running without Remote Control. **What to do:**

- If the app is signed out, sign in to it again, then turn Remote Control back on in the app
- If the app switched accounts, Claude Code can’t continue the ended session under the new account. Start a new Remote Control session under that account.

Before v2.1.238, Claude Code sent the app the `run /login` messages listed under [Remote Control couldn’t refresh your login](#remote-control-couldnt-refresh-your-login) in both cases.


[​](#oauth-token-revoked-or-expired)

OAuth token revoked or expired

Your saved login is no longer valid. A revoked token means you signed out everywhere or an admin removed access; an expired token means the automatic refresh failed mid-session. Both messages report a rejection the API returned for a request Claude Code sent. When the saved login has already been cleared after a failed refresh, you see [Login expired](#login-expired) instead. If you authenticate with a long-lived token in [`CLAUDE_CODE_OAUTH_TOKEN`](env-vars.md), you see the same messages when that token expires or is revoked.

```python
OAuth token revoked · Please run /login
Please run /login · API Error: 401 OAuth token has expired ...
```

In [non-interactive mode](headless.md) (`-p`) and the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md), the messages read as follows, and the structured error code is `authentication_failed`:

```python
Failed to authenticate: OAuth token revoked. Please log in again or contact your administrator.
Failed to authenticate. API Error: 401 OAuth token has expired ...
```

Before v2.1.287, in non-interactive mode and the Agent SDK, the revoked message read `Your account does not have access to Claude. Please login again or contact your administrator.` **What to do:**

- Run `/login` at the Claude Code prompt to sign in again
- If your `-p` command or Agent SDK program uses a saved login, run `claude` in the same environment, complete `/login`, then run the command or program again. For automation that can’t sign in interactively, authenticate with [`ANTHROPIC_API_KEY`](env-vars.md) or [generate a long-lived token with `claude setup-token`](authentication.md#generate-a-long-lived-token).
- If you authenticate with the `CLAUDE_CODE_OAUTH_TOKEN` environment variable, Claude Code keeps sending the value you set after a request fails with a 401, rather than switching to a stored login’s token. [`/status`](commands.md) shows this credential as an `Auth token` row reading `CLAUDE_CODE_OAUTH_TOKEN`. Generate a fresh token with [`claude setup-token`](authentication.md#generate-a-long-lived-token) and restart with it, or unset the variable and run `/login`. Before v2.1.225, Claude Code could replace the variable’s value mid-session with the short-lived access token from a stored login, and the session failed with 401 errors again once that token expired.
- For repeated prompts to log in across launches, see the system clock checks and macOS credential-storage recovery steps in [Troubleshooting](troubleshoot-install.md#not-logged-in-or-token-expired)
- For other failures including `403 Forbidden` and OAuth browser issues, see [Login and authentication](troubleshoot-install.md#login-and-authentication)


[​](#api-error-401-invalid-authentication-credentials)

API Error: 401 Invalid authentication credentials

The API recognized the format of your credential but rejected the account or organization behind it. Anthropic returns this message when a credential was recently revoked, when an organization was disabled or removed your access, or when the account itself was deactivated, so an expired token isn’t the cause. The credential can be your saved login or an approved `ANTHROPIC_API_KEY`, and the fix differs, so start by running `/status` to see which one is active.

```python
Please run /login · API Error: 401 Invalid authentication credentials
```

**What to do:**

- If `/status` shows an `API key` row that isn’t marked as not in use, an approved [`ANTHROPIC_API_KEY`](authentication.md#authentication-precedence) is the active credential and takes precedence over your login, so `/login` doesn’t replace it. Rotate the key in the Claude Console, or fall back to your subscription by running `unset ANTHROPIC_API_KEY`, or in PowerShell `Remove-Item Env:ANTHROPIC_API_KEY`.
- If `/status` shows only your login, run `/login` once. If the credential was revoked, a fresh login replaces it.
- If the same message returns for the same login account, the account or organization is no longer active. Check the account and organization that `/status` reports, and ask your organization admin to restore access.
- If [`ANTHROPIC_BASE_URL`](env-vars.md) points at an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md), the text after `401` is your gateway’s message rather than Anthropic’s, and `/login` doesn’t change it. Fix the credential your gateway expects instead.
- If every request fails with a `401` once your gateway has the credential it expects, check whether the gateway is rejecting the tool search fields Claude Code sends by default. To check, set `ENABLE_TOOL_SEARCH=false` as [Tool search through an LLM gateway](../06-MCP-Tools/General/mcp.md#tool-search-through-a-gateway) describes, then try again. Before v2.1.304, tool search was off behind a gateway unless you turned it on with `ENABLE_TOOL_SEARCH`.


[​](#login-expired)

Login expired

Claude Code tried to renew your saved claude.ai login and the OAuth service rejected the stored refresh token, so Claude Code cleared the saved credentials. After that, each model request stops locally with this message before it reaches the API, because only `/login` can create new credentials. Before v2.1.206, Claude Code sent the model request anyway with whatever credential remained in the environment, and every model then failed with [There’s an issue with the selected model](#theres-an-issue-with-the-selected-model) or a 401 instead of a prompt to sign in.

```python
Login expired · Please run /login
```

In [non-interactive mode](headless.md) (`-p`) and the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md), the message reads as follows, and the structured error code is `authentication_failed`:

```python
Failed to authenticate: OAuth session expired and could not be refreshed
```

For a `Login expired` message that ends with `or re-authenticate your Anthropic profile`, see [Anthropic profile login expired](#anthropic-profile-login-expired). This is not the same state as [OAuth token revoked or expired](#oauth-token-revoked-or-expired). Those messages report a rejection the API returned. Claude Code itself produces `Login expired` for a login it already failed to renew, so it sends no request. When the renewal fails because the account itself is suspended rather than the login being stale, Claude Code shows [Your account is on hold](#your-account-is-on-hold) instead. Sessions authenticated with an API key, [`CLAUDE_CODE_OAUTH_TOKEN`](env-vars.md), or a third-party provider don’t use the saved login and never see this message. You can check for this state before a request fails: [`/status`](commands.md) shows a `Login` row reading `Expired — log in again`, plus the organization and email it has saved for the expired login. The row appears only when the saved login is your active credential and can no longer be refreshed. Sessions authenticated another way don’t show the row, even if an expired login remains saved. Before v2.1.210, `/status` gave no indication in this state that a login had ever existed, because the cleared credential left it nothing to report. **What to do:**

- Run `/login` to sign in again. Retrying without signing in shows the same message on every request.
- If you sign in with your claude.ai account in another Claude Code window, see [Not logged in](#not-logged-in) for when this session starts using that login on its own.
- In non-interactive mode, run `claude` in the same environment, complete `/login`, then rerun your command. For automation that can’t sign in interactively, authenticate with `ANTHROPIC_API_KEY` or [generate a long-lived token with `claude setup-token`](authentication.md#generate-a-long-lived-token).
- If signing in keeps failing, see [Login and authentication](troubleshoot-install.md#login-and-authentication)


[​](#could-not-refresh-your-login)

Could not refresh your login because another Claude Code process is refreshing it

This message doesn’t mean your login was rejected. Your saved claude.ai login had expired and needed renewing. Another Claude Code process on the same machine held the shared refresh lock, or exited and left it behind, and the refresh made no progress while this session waited. Claude Code stops the request before sending it:

```python
Could not refresh your login because another Claude Code process is refreshing it (or exited mid-refresh) · Try again in a minute; if it keeps happening, close other Claude Code windows or sign in again with /login
```

In [non-interactive mode](headless.md) (`-p`) and the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md), the message reads as follows, and the structured error code is `server_error`:

```python
Failed to refresh OAuth token: another Claude Code process is refreshing it or exited mid-refresh. This is usually transient; retry in a minute, and if it persists close other Claude Code processes or sign in again
```

Sessions authenticated with an API key, [`CLAUDE_CODE_OAUTH_TOKEN`](env-vars.md), or a third-party provider don’t use the saved login and never see this message. **What to do:**

- Try again in a minute. If another process completes the refresh first, this session uses the renewed login.
- If the message keeps returning, close other Claude Code windows and processes, then retry.
- If it returns with no other Claude Code process running, run `/login`. Signing in again doesn’t wait on the refresh lock.


[​](#couldnt-save-your-login)

Couldn’t save your login

You signed in with claude.ai, but Claude Code couldn’t save the login to its credential store, so the login didn’t complete. On macOS this can happen when the login keychain locks, for example on sleep or idle, after Claude Code has already read or saved credentials in it during the same session.

```python
Couldn't save your login. If your Mac's keychain is locked, unlock it and log in again.
Couldn't save your login. Try logging in again.
```

The first form appears on macOS and the second everywhere else. A transient credential-store failure, such as a timeout or an unreadable store, produces the same message. **What to do:**

- On macOS, unlock the login keychain, then run `/login` again
- On other platforms, run `/login` again
- If the login still doesn’t save, see [Not logged in or token expired](troubleshoot-install.md#not-logged-in-or-token-expired) for the keychain unlock command and other credential-storage recovery steps


[​](#couldnt-start-the-local-sign-in-listener)

Couldn’t start the local listener that receives the browser sign-in

Each of these messages from `/login`, `claude auth login`, or `claude setup-token` means Claude Code couldn’t open the port on `127.0.0.1` where your browser returns the sign-in result. With the notice that begins `The browser can't return the sign-in to Claude Code automatically`, the sign-in continues without that port. No browser opens, and the notice appears above a URL where you sign in instead:

```python
The browser can't return the sign-in to Claude Code automatically. After you sign in, paste the code shown.
```

With the message that includes `Couldn't start the local listener`, the sign-in stopped. That happens, for example, when you pipe input into `claude auth login`:

```python
Couldn't start the local listener that receives the browser sign-in. Try again.
```

**What to do:**

- **`The browser can't return the sign-in to Claude Code automatically`**: you don’t need to fix anything first. Open the URL shown under the notice in a browser and sign in. The browser then shows a code: paste it into Claude Code at the `Paste code here >` prompt, and the sign-in continues from there.
- **`Couldn't start the local listener that receives the browser sign-in`**: run the same command again. If it stops the same way, sign in with a token or API key instead of the browser. Or, if you piped input into `claude auth login`, run it in a terminal so it can take a pasted code.
- **To sign in with a token or API key instead of the browser**: if you use a claude.ai subscription, run [`claude setup-token`](authentication.md#generate-a-long-lived-token) on a machine where sign-in works. Then set the token it prints as the [`CLAUDE_CODE_OAUTH_TOKEN`](env-vars.md) environment variable on this machine. Otherwise set the `ANTHROPIC_API_KEY` environment variable to a key from the [Claude Console](../04-API-Reference/Other/playground.md). [Authentication precedence](authentication.md#authentication-precedence) explains how Claude Code chooses between credentials.
- **To get the automatic browser return back**: Claude Code must be able to listen on `127.0.0.1`. If it runs inside a sandbox, check that the sandbox’s policy allows listening on local ports, then sign in again. If listening should work there and the notice still appears, run `/feedback` so the report includes your environment details.

Before v2.1.305, the sign-in stopped as soon as the port couldn’t be opened and showed no URL to sign in at. The message read, for example, `Failed to start OAuth callback server: Failed to start server. Is port 0 in use?`. On those versions, update Claude Code and sign in again, or sign in with a token or API key instead of the browser.


[​](#claude-login-not-accepted)

Claude login not accepted

You tried to start a [cloud session](claude-code-on-the-web.md), and the server refused to create it with a 401: it didn’t accept the Claude login this machine sent, usually because the login expired or was revoked. The first part of the line is the server’s own reason when it gives one. Otherwise the line reads:

```python
Claude login not accepted · Run /login, then try again
```

**What to do:**

- Run `/login`, complete the sign-in, then start the session again


[​](#artifacts-need-a-claude-ai-login)

Artifacts need a claude.ai login

Claude Code refused an [artifact](artifacts.md) publish or read because the session has no claude.ai login it can use for artifacts. Every form of the message starts with the same words, followed by a remedy that depends on how your session authenticates. With no competing credential it reads:

```python
Artifacts need a claude.ai login. Run /login and select "Claude account with subscription", then retry — the "Anthropic Console account" option does not provide claude.ai credentials.
```

**What to do:**

- Run `/login` and select **Claude account with subscription**. The **Anthropic Console account** option doesn’t provide claude.ai credentials.
- When the message names a credential that takes precedence, such as `ANTHROPIC_API_KEY`, an `apiKeyHelper` setting, or a Console key saved by a previous `/login`, remove it the way the message says, then run `/login`
- When the message says this remote session authenticates through the machine that launched it, sign in to claude.ai on that machine, then reconnect the session
- When the message says the credential is injected by the session’s host environment, you can’t change it in that session; start a session that is signed in to claude.ai
- See [Availability](artifacts.md#availability) for the other requirements artifacts have, such as plan, model provider, and organization policy


[​](#administrator-policy-requires-a-cloud-gateway-sign-in)

Administrator policy requires a Cloud gateway sign-in

An administrator’s [managed settings](../13-Enterprise-Admin/managed-settings.md) on this machine set [`forceLoginMethod`](settings-reference.md#forceloginmethod) to `"gateway"` or set [`forceLoginGatewayUrl`](settings-reference.md#forcelogingatewayurl). Unless you select a cloud provider through a variable such as `CLAUDE_CODE_USE_BEDROCK`, Claude Code then accepts only the [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sign-in. You see one of two messages:

```python
Not signed in to the Cloud gateway — run /login.
```

Model requests fail with this message when the session has no gateway sign-in, for example because you haven’t run `/login` since the policy reached the machine. If the machine also holds an Anthropic-issued credential and the managed settings set `forceLoginMethod` or `forceLoginOrgUUID`, Claude Code exits at startup instead. That credential can be an `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN` variable, an `apiKeyHelper` setting, or an API key saved by an earlier Claude Console login. The startup message names the credential the session is configured with, where it’s set, and the step that removes it. For example, with an `ANTHROPIC_API_KEY` variable set in your shell, it reads:

```python
Administrator policy requires a Cloud gateway sign-in on this machine, but this session is configured with an API key from ANTHROPIC_API_KEY, which a gateway machine does not accept.

To continue: unset ANTHROPIC_API_KEY (or run in a shell without it), then run claude and sign in with /login.
```

**What to do:**

- For `Not signed in to the Cloud gateway`, run `/login` and complete the sign-in on the **Cloud gateway** screen
- For the startup message, remove the credential by following the steps at the end of the message
- If you believe the machine shouldn’t require the gateway, ask the administrator who manages it to remove `forceLoginMethod` and `forceLoginGatewayUrl` from its managed settings

Before v2.1.284, the startup message listed the possible credentials instead of naming the configured one. It began `Administrator policy requires a Cloud gateway sign-in on this machine; the Anthropic-issued credential configured here (ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, or apiKeyHelper) is not used.` If you see that wording and can’t tell which credential to remove, update to v2.1.284 or later and start `claude` again. On v2.1.265, a regression also showed the first message in some LLM-gateway and proxy configurations that authenticate with an API key, `apiKeyHelper`, or custom headers, even with no administrator requirement on the machine. Update to v2.1.266 or later. You don’t need to change your configuration. Before v2.1.261, on machines that set `forceLoginMethod` to `"gateway"`, Claude Code used a leftover saved login instead of failing model requests, and reported a configured environment credential with `This machine's managed settings require a first-party login` instead of the startup message.


[​](#your-account-is-on-hold)

Your account is on hold

The Claude account behind your login has been suspended. Claude Code shows the first message when it tries to renew your saved login and learns of the hold, and the second when a sign-in you complete in the browser reports it:

```python
Your account is on hold and can't use Claude Code. View details or appeal: https://claude.ai/restricted
Your account is on hold and can't sign in to Claude Code. View details or appeal: https://claude.ai/restricted
```

Signing in again with the same account doesn’t clear the message, because the hold is on the account rather than the login. In [non-interactive mode](headless.md) (`-p`) and the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md), the structured error code is `account_on_hold`. Before v2.1.235, Claude Code reported a held account as [Login expired · Please run /login](#login-expired), whose recovery steps can’t clear a hold. **What to do:**

- Open the link in the message to view the hold’s details or appeal it
- If you have another Claude account or an API key that isn’t affected by the hold, you can keep working while the hold is resolved: run `/login` with that account, or set the key with `ANTHROPIC_API_KEY`


[​](#anthropic-profile-login-expired)

Anthropic profile login expired

Claude Code is authenticating through an Anthropic credential profile whose saved login credential has expired, and the profile holds no refresh credential Claude Code can use to renew it. Claude Code stops each request locally without retrying.

```python
Anthropic profile login expired · Re-authenticate your Anthropic profile
Login expired · Run /login to sign in again, or re-authenticate your Anthropic profile
```

**What to do:**

- If the message leads with `Login expired`, run `/login` to sign in again
- To renew a profile that the keyless Console sign-in or the Claude Platform CLI’s `ant auth login` wrote, run `/login` on a machine that [offers the keyless sign-in](authentication.md#sign-in-without-an-api-key). Choose the Anthropic Console account, then **Sign in with your Console account**. Claude Code replaces the expired credential in that profile
- To renew a profile that another tool created, sign in again with that tool. If you choose **Sign in with your Console account** at `/login` instead, Claude Code leaves the profile as it is and creates an API key
- If an administrator provisioned the profile’s credential, ask them to issue a new one
- Run `/status` to confirm the active credential source and profile name
- To stop using the profile, unset `ANTHROPIC_PROFILE` if you set it, then authenticate another way, such as `/login` or `ANTHROPIC_API_KEY`

How the message starts tells you how Claude Code found the profile:

- When Claude Code discovered the profile from your configuration directory and its auth mode is `user_oauth`, the message leads with `Login expired` and offers `/login` first. Claude Code gives a working `/login` precedence over the discovered profile and then authenticates with your claude.ai account instead. From v2.1.234 until v2.1.277, this form read `Anthropic profile login expired · Run /login to use your claude.ai account instead, or re-authenticate the profile`. Before v2.1.234, Claude Code showed the `Re-authenticate your Anthropic profile` form in this case too.
- When you selected the profile with `ANTHROPIC_PROFILE`, the message leads with `Anthropic profile login expired`.

This appears only when the active credential comes from an Anthropic credential profile, one you select with the `ANTHROPIC_PROFILE` environment variable, that Claude Code discovers as the active profile in your Anthropic configuration directory, or that Claude Code wrote when you [signed in without an API key](authentication.md#sign-in-without-an-api-key). Sessions that authenticate with an API key, a bearer token such as `ANTHROPIC_AUTH_TOKEN`, or a third-party provider never see this message.


[​](#oauth-scope-requirement)

OAuth scope requirement

The stored token predates a permission scope that a newer feature needs:

```python
OAuth token does not meet scope requirement: user:profile
```

**What to do:**

- Run `/login` to get a new token with the current scopes. You don’t need to log out first.


[​](#claude-ai-rejected-the-session-token)

claude.ai rejected the session token

A [claude.ai connector](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) request failed because claude.ai rejected the token from your Claude Code login. The rejected token is your login, not the connector’s own authorization in claude.ai, so authorizing the connector again doesn’t resolve it. In `/mcp`, the connector shows as `session token rejected` and its detail view reads:

```python
claude.ai rejected the session token. Run /login, then reconnect.
```

**What to do:**

- Run `/login` to sign in again
- Reconnect the connector from `/mcp`, or run `/mcp reconnect <server>`. Reconnecting before you sign in again leaves the connector in the same state. The `/mcp` panel’s **Reconnect** option reports `your claude.ai session token was rejected`; the typed `/mcp reconnect <server>` form reports a successful reconnect even though the token is still rejected.

Before v2.1.222, Claude Code marked the connector as needing authentication instead, which pointed you at the connector’s authorization flow even though completing it didn’t resolve the state.


[​](#mcp-server-needs-you-to-sign-in-again)

MCP server needs you to sign in again

A remote [MCP server](../06-MCP-Tools/General/mcp.md) rejected the credential on a tool call mid-session, usually because a sign-in or token expired or because the token lacks a permission the tool needs. The tool call fails, and `/mcp` marks the server as [needing authentication](../06-MCP-Tools/General/mcp.md#authenticate-with-remote-mcp-servers). For a server you sign in to from Claude Code, including a claude.ai connector, the sign-in expired or was revoked:

```python
MCP server "<name>" needs you to sign in again (run /mcp to re-authenticate)
```

Run `/mcp`, select the server, and sign in again from its menu. For a server configured with a [`headersHelper`](../06-MCP-Tools/General/mcp.md#use-dynamic-headers-for-custom-authentication) script, Claude Code has already re-run the helper and retried the call once before showing this:

```python
MCP server "<name>" rejected the credential from its headersHelper (check the helper and run /mcp to reconnect, or to authenticate if the server also uses OAuth)
```

Check that the helper returns a credential the server accepts, then reconnect from `/mcp`, which runs the helper again. For a server with a static `Authorization` header in its configuration:

```python
MCP server "<name>" rejected the Authorization header in its config (update it, then run /mcp to reconnect)
```

Update the header value where the server is configured, then reconnect from `/mcp`. In a [Cowork](https://claude.com/docs/cowork/overview) session on your machine in the Claude Desktop app, these messages mean the MCP server rejected a credential it was given. Fix the one the message names, then start a new task or chat in Cowork:

```python
MCP server "<name>" rejected the credential from its headersHelper (check the helper, then start a new task or chat)
MCP server "<name>" rejected the Authorization header in its config (update it, then start a new task or chat)
```

- **`headersHelper` credential rejected**: check that the helper returns a credential the server accepts, then start a new task or chat in Cowork
- **`Authorization` header rejected**: update the `Authorization` value under `headers` in that server’s configuration, then start a new task or chat in Cowork

Before v2.1.302, a Cowork session showed the `run /mcp to reconnect` endings instead, although `/mcp` isn’t available there. If you see such an ending in Cowork, still check the helper or update the header, then start a new task or chat. Before v2.1.273, the expired sign-in, `headersHelper`, and `Authorization` header cases all showed `MCP server "<name>" requires re-authorization (token expired)`. A server can also refuse a tool call with HTTP 403 `insufficient_scope` to ask you to authorize a scope, sometimes one your token already lists. The message names that scope:

```python
MCP server "<name>" needs additional permissions (scope: "<scope>") — run /mcp to re-authenticate
```

Run `/mcp`, select the server, and authenticate again from its menu. When the server’s configuration sets neither [`oauth.scopes`](../06-MCP-Tools/General/mcp.md#restrict-oauth-scopes) nor [`authServerMetadataUrl`](../06-MCP-Tools/General/mcp.md#override-oauth-metadata-discovery), Claude Code requests the scope the server named. With either setting, Claude Code requests that setting’s scopes instead. If you pinned `oauth.scopes`, add the missing scope to that list before you authenticate again. Before v2.1.274, this case showed the `needs you to sign in again` message, and before v2.1.273 it showed `requires re-authorization (token expired)` like the other cases.


[​](#couldnt-read-the-stored-credentials-for-mcp-server)

Couldn’t read the stored credentials for MCP server

Claude Code keeps your sign-ins for OAuth [MCP servers](../06-MCP-Tools/General/mcp.md) in a credential store. This message means Claude Code couldn’t read that store, so a request to the server didn’t run:

```python
Couldn't read the stored credentials for MCP server "<name>", so the request didn't run. If your Mac's keychain is locked, unlock it, then try again.
Couldn't read the stored credentials for MCP server "<name>", so the request didn't run. Try again.
```

Your stored sign-ins are unchanged: try again once the store can be read, and sign in again only if the server then asks you to. In a [`claude -p`](headless.md) or [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) run on macOS, the keychain can become readable after a request has already gone out without the stored sign-in. That request fails with:

```python
A request to MCP server "<name>" was sent without your stored credentials, so the server rejected it. The credentials are available now. Try again.
```

**What to do:**

- If the message asks you to unlock your Mac’s keychain, run [`claude doctor`](cli-reference.md#cli-commands) in the shell session you run Claude Code from, and check its report for a keychain warning:
  - If the report lists a warning that starts with `macOS Keychain is not writable`, or your shell has no `claude` command, run this unlock command in that shell session:

    ``` shiki
    security unlock-keychain ~/Library/Keychains/login.keychain-db
    ```
  - If the report lists no keychain warning, skip the unlock command
- Try again where you saw the message:
  - For `claude -p`, run the command again
  - In an interactive session, reconnect the server from `/mcp` if it shows as failed there, then ask Claude to try again
  - In an Agent SDK application that keeps running, call [`reconnectMcpServer()`](../05-Agent-SDK/agent-sdk-typescript.md#methods) in TypeScript or [`ClaudeSDKClient.reconnect_mcp_server()`](../05-Agent-SDK/agent-sdk-python.md#methods) in Python, or start a new session
- If the server then reports that it needs authentication, Claude Code found no sign-in it can use for that server. Sign in interactively: run `/mcp` in a Claude Code session, or [`claude mcp login <name>`](../06-MCP-Tools/General/mcp.md#authenticate-from-the-command-line) in your shell. In an Agent SDK application, see [OAuth2 authentication in the Agent SDK](../05-Agent-SDK/agent-sdk-mcp.md#oauth2-authentication).

Before v2.1.307, a `claude -p` or Agent SDK run on a Mac with a locked login keychain reported the server as needing authentication instead of showing either message.


[​](#mcp-server-url-is-missing-or-not-a-valid-url)

MCP server URL is missing or not a valid URL

Claude Code refused to start an OAuth sign-in for a remote MCP server because the server’s configured `url` doesn’t parse as a URL. Unless Claude Code has a more specific configuration problem to report for the server, running [`claude mcp login <name>`](../06-MCP-Tools/General/mcp.md#authenticate-from-the-command-line) in your shell prints the refusal as:

```python
Couldn't complete authentication for "<name>": This server's URL is missing or not a valid URL, so sign-in can't start. Fix the URL in its MCP config (or set the environment variable it uses) and try again.
```

**What to do:**

- Set the entry’s `url` to the server’s real endpoint where the server is configured, or set the environment variable that its [`${VAR}` reference](../06-MCP-Tools/General/mcp.md#environment-variable-expansion-in-mcp-json) names, then run the sign-in again.


[​](#issuer-mismatch-in-authorization-response)

Issuer mismatch in authorization response

During an [MCP OAuth sign-in](../06-MCP-Tools/General/mcp.md#authenticate-with-remote-mcp-servers), the authorization server redirected back to Claude Code with an `iss` parameter that doesn’t name the issuer that Claude Code expected from the server’s OAuth metadata. A wrong issuer at this step is how an authorization server mix-up attack looks, so Claude Code fails the sign-in instead of exchanging the authorization code. Claude Code shows the error in the `/mcp` server menu after the browser sign-in:

```python
Issuer mismatch in authorization response (RFC 9207): expected "https://auth.example.com", received "https://other.example.com"
```

`expected` is the issuer from the server’s OAuth metadata, and `received` is the `iss` value the redirect carried. A sign-in whose redirect carries no `iss` parameter passes the check, unless the server’s metadata sets `authorization_response_iss_parameter_supported`, in which case Claude Code fails the sign-in. **What to do:**

- Try the sign-in again from `/mcp`
- If the error repeats, report it to the server operator. The fix is server-side: the authorization server must return the same issuer in the `iss` parameter that it advertises in its metadata
- To connect while the server is being fixed, start Claude Code with [`MCP_SDK_GENERATION=v1`](env-vars.md), whose [runtime](../06-MCP-Tools/General/mcp.md#mcp-client-runtimes) doesn’t run this check. This removes a protection against mix-up attacks, so prefer the server-side fix

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


[​](#refusing-to-send-credentials-to-non-https-token-endpoint)

Refusing to send credentials to non-https token endpoint

On the [v2 runtime](../06-MCP-Tools/General/mcp.md#mcp-client-runtimes), Claude Code sends an [MCP OAuth](../06-MCP-Tools/General/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. In its full form, the message comes from the MCP SDK and quotes the token endpoint it refused. In the debug log, it follows `Error during auth completion:` for a sign-in or `Token refresh failed:` for a refresh. In your shell, `claude mcp login <name>` prints it after `Couldn't complete authentication for "<name>":`, and in a session, `/mcp` shows it under the server’s menu:

```python
Refusing to send credentials to non-https token endpoint 'http://192.168.1.50:8123/oauth/token'. OAuth token requests MUST use TLS (localhost / 127.0.0.1 / ::1 are exempt).
```

Claude Code treats a server URL that has a query string or a long random-looking path segment as possibly secret. For such a server, it redacts the sign-in errors the MCP SDK raises before it shows or logs them. This error then reads as a short name that can change between releases, such as `io`, followed by `from the MCP SDK for` and the redacted server URL. Other errors from the MCP SDK take the same shape there. The redacted message can be this error only when the server’s token endpoint is plain `http://` at an address other than `localhost`, `127.0.0.1`, or `::1`. **What to do:**

- Serve that token endpoint over HTTPS, for example by putting the server behind a reverse proxy or tunnel that terminates TLS and configuring the server to advertise the `https://` address
- To connect without changing the server, start Claude Code with [`MCP_SDK_GENERATION=v1`](env-vars.md), whose [runtime](../06-MCP-Tools/General/mcp.md#mcp-client-runtimes) doesn’t apply this rule and sends the token request over plain HTTP. That choice lasts until you exit and applies to every server. The v1 runtime also skips the [issuer check](#issuer-mismatch-in-authorization-response), so prefer serving the endpoint over HTTPS


[​](#aws-credentials-expired-or-invalid)

AWS credentials expired or invalid

Your AWS session token expired or was rejected. This message appears on a 401 from [Claude Platform on AWS](claude-platform-on-aws.md) or the [Mantle endpoint](amazon-bedrock.md#use-the-mantle-endpoint), which is how those providers report an expired security token. The action hint in the middle varies with your setup. The stable part is the leading `AWS credentials expired or invalid`:

```python
AWS credentials expired or invalid · run /login and select "Claude Platform on AWS · refresh credentials", or run `aws sso login --profile myprofile` in another terminal · API Error: 401 ...
```

Before v2.1.273, this message appeared only when `awsAuthRefresh` was configured. **What to do:**

- If the hint says credentials are managed by this environment, the app that launched Claude Code owns the credential and the other steps here don’t apply: retry, or contact your administrator
- If [`awsAuthRefresh`](amazon-bedrock.md#advanced-credential-configuration) is set, run the command named in the message, such as `aws sso login --profile myprofile`, in another terminal and complete the browser sign-in, then retry. Otherwise refresh the AWS credential you use yourself: your SSO sign-in, access keys, API key, or proxy token
- With `awsAuthRefresh` set in an interactive session, you can instead run `/login`, choose **3rd-party platform**, then select **Claude Platform on AWS · refresh credentials** under **Using 3rd-party platforms** to run the same command without restarting Claude Code. See [Configure AWS credentials](claude-platform-on-aws.md#1-configure-aws-credentials)
- If the error repeats after the refresh command succeeds, confirm the identity is valid outside Claude Code with `aws sts get-caller-identity` in the same shell and profile


[​](#aws-authentication-failed)

AWS authentication failed

Your AWS provider returned a 403, or [Amazon Bedrock](amazon-bedrock.md) returned a 401. Amazon Bedrock reports an expired security token as a 403, but a 403 is also how it reports an authorization denial, such as an `AccessDeniedException` from a missing IAM permission. Claude Code can’t tell those two causes apart. A 401 from Amazon Bedrock also lands here rather than under [AWS credentials expired or invalid](#aws-credentials-expired-or-invalid), because Amazon Bedrock doesn’t report an expired token as a 401. A 401 from that endpoint typically comes from something else in the request path, such as a corporate proxy. A credential refresh fixes an expired token and can’t fix the other causes, so the message offers both:

```python
AWS authentication failed · run /login and select "Claude Platform on AWS · refresh credentials", or run `aws sso login --profile myprofile` in another terminal · if credentials are current, check AWS permissions and model access · API Error: 403 ...
```

The action hint in the middle varies with your setup. The stable part is the leading `AWS authentication failed`. When the 403 is Amazon Bedrock’s answer that you don’t have access to the model with the specified model ID, the hint instead tells you to enable the model for your account and region in the Amazon Bedrock console. Before v2.1.273, this message appeared only when `awsAuthRefresh` was configured. **What to do:**

- If the hint says credentials are managed by this environment, the app that launched Claude Code owns the credential and the other steps here don’t apply: retry, or contact your administrator
- Refresh your AWS credentials in case an expired credential is the cause: run the [`awsAuthRefresh`](amazon-bedrock.md#advanced-credential-configuration) command named in the message when one is set, or refresh your SSO sign-in, access keys, API key, or proxy token yourself
- If your credentials are current, confirm the IAM permissions in [IAM configuration](amazon-bedrock.md#iam-configuration) are attached to the identity you’re using and that the selected model is enabled for your account and region
- Run `aws sts get-caller-identity` to confirm which identity your requests use


[​](#google-cloud-credentials-expired-or-invalid)

Google Cloud credentials expired or invalid

Your Google Cloud credentials for [Google Cloud’s Agent Platform](google-vertex-ai.md) expired or were rejected: the request returned a 401, which is how Agent Platform reports credential expiry. The action hint in the middle varies with your setup. The stable part is the leading `Google Cloud credentials expired or invalid`:

```python
Google Cloud credentials expired or invalid · refresh your Google Cloud credentials (application default sign-in, or the key file in GOOGLE_APPLICATION_CREDENTIALS) and retry · API Error: 401 ...
```

**What to do:**

- If the hint says credentials are managed by this environment, the app that launched Claude Code owns the credential and the other steps here don’t apply: retry, or contact your administrator
- If you authenticate with application default credentials, run the [`gcpAuthRefresh`](google-vertex-ai.md#advanced-credential-configuration) command named in the message, or `gcloud auth application-default login`, and complete the sign-in, then retry
- If you route through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) with `CLAUDE_CODE_SKIP_VERTEX_AUTH` set, refresh the gateway token in `ANTHROPIC_AUTH_TOKEN` or `ANTHROPIC_CUSTOM_HEADERS`, then retry
- If you authenticate with a service account key file, confirm `GOOGLE_APPLICATION_CREDENTIALS` points at a valid key. See [Configure GCP credentials](google-vertex-ai.md#3-configure-gcp-credentials)
- If the error repeats after a refresh, confirm the identity works outside Claude Code with `gcloud auth application-default print-access-token` in the same shell

Before v2.1.273, a 401 from Agent Platform showed the generic `Please run /login` or `Failed to authenticate` message instead, which can’t refresh Google Cloud credentials.


[​](#google-cloud-authentication-failed)

Google Cloud authentication failed

[Google Cloud’s Agent Platform](google-vertex-ai.md) returned a 403, which it uses for authorization denials rather than expired credentials. Usually the identity you authenticate with is missing an IAM permission, or the model isn’t enabled for your project. The action hint in the middle varies with your setup. The stable part is the leading `Google Cloud authentication failed`:

```python
Google Cloud authentication failed · refresh your Google Cloud credentials (application default sign-in, or the key file in GOOGLE_APPLICATION_CREDENTIALS) and retry · if credentials are current, check GCP IAM permissions and Vertex AI model access · API Error: 403 ...
```

**What to do:**

- If the hint says credentials are managed by this environment, the app that launched Claude Code owns the credential and the other steps here don’t apply: retry, or contact your administrator
- Confirm the roles in [IAM configuration](google-vertex-ai.md#iam-configuration) are granted to the identity you authenticate with
- Confirm the model is enabled for your project. See [Request model access](google-vertex-ai.md#2-request-model-access)

Before v2.1.273, a 403 from Agent Platform showed the generic `Please run /login` or `Failed to authenticate` message instead, which can’t refresh Google Cloud credentials.


[​](#microsoft-foundry-authentication-failed)

Microsoft Foundry authentication failed

[Microsoft Foundry](microsoft-foundry.md) returned a 401 or 403: the Azure credential on the request was rejected, or the identity behind it doesn’t have access to the Foundry resource. `/login` can’t mint Azure credentials. The action hint in the middle varies with your setup. The stable part is the leading `Microsoft Foundry authentication failed`:

```python
Microsoft Foundry authentication failed · refresh your Foundry credential (ANTHROPIC_FOUNDRY_AUTH_TOKEN, ANTHROPIC_FOUNDRY_API_KEY, Azure sign-in for Entra, or your proxy token) and retry · if credentials are current, check access to the Foundry resource · API Error: 401 ...
```

**What to do:**

- If the hint says credentials are managed by this environment, the app that launched Claude Code owns the credential and the other steps here don’t apply: retry, or contact your administrator
- Refresh the credential you configured in [Configure Azure credentials](microsoft-foundry.md#2-configure-azure-credentials): rotate `ANTHROPIC_FOUNDRY_API_KEY`, mint a fresh `ANTHROPIC_FOUNDRY_AUTH_TOKEN`, or run `az login` so the default Microsoft Entra credential chain can sign in again
- If the credential is current, confirm the identity has access to the Foundry resource. See [Azure RBAC configuration](microsoft-foundry.md#azure-rbac-configuration)

Before v2.1.273, a 401 or 403 from Microsoft Foundry showed the generic `Please run /login` or `Failed to authenticate` message instead, which can’t refresh Azure credentials.


[​](#could-not-load-aws-or-google-cloud-credentials)

Could not load AWS or Google Cloud credentials

Claude Code couldn’t obtain usable credentials from the AWS credential provider chain or from your Google application default credentials on the machine it runs on, so no request reached your cloud provider. The detail after the `·` names the specific cause, such as an expired SSO session, missing application default credentials reported as `Could not load the default credentials`, or a revoked sign-in reported as `invalid_grant`:

```python
API Error: Could not load AWS credentials · Could not load credentials from any providers. Check or refresh your AWS credentials and try again.
API Error: Could not load Google Cloud credentials · invalid_grant. Check or refresh your Google Cloud credentials and try again.
```

In [non-interactive mode](headless.md) with `-p` and in the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md), the structured error code is `cloud_credential_error`. Before v2.1.267, the message showed only the detail text after `API Error:`, and the structured code was `server_error` or `unknown`. **What to do:**

- Run your provider’s sign-in command, such as `aws sso login --profile myprofile` or `gcloud auth application-default login`, then retry. [Bedrock, Agent Platform, or Foundry credentials not loading](troubleshoot-install.md#bedrock-agent-platform-or-foundry-credentials-not-loading) shows how to confirm the credentials outside Claude Code
- If the detail reads `AWS default-chain credential resolve timed out`, the chain hung rather than failed, so follow [AWS default-chain credential resolve timed out](#aws-default-chain-credential-resolve-timed-out) instead


[​](#aws-default-chain-credential-resolve-timed-out)

AWS default-chain credential resolve timed out

The AWS default credential provider chain didn’t produce credentials within 60 seconds, so Claude Code stopped the resolve and failed the request. This timeout is one cause of [Could not load AWS or Google Cloud credentials](#could-not-load-aws-or-google-cloud-credentials). The failure is local credential resolution: the request never reached [Amazon Bedrock](amazon-bedrock.md), [Claude Platform on AWS](claude-platform-on-aws.md), or the [Mantle endpoint](amazon-bedrock.md#use-the-mantle-endpoint). Claude Code clears its [credential cache](amazon-bedrock.md#credential-caching-and-resolution-timeout) and retries before this error surfaces, so by the time you see it the chain has stalled on repeated attempts.

```python
API Error: Could not load AWS credentials · AWS default-chain credential resolve timed out. Check or refresh your AWS credentials and try again.
```

Common causes are a `credential_process` command in your AWS profile that waits for input it can’t receive, and a container or VM whose instance metadata service (IMDS) never answers the chain’s probe. Before v2.1.267, the message read `API Error: AWS default-chain credential resolve timed out`. Before v2.1.207, a stalled chain left the request waiting indefinitely instead of failing. **What to do:**

- Run `aws sts get-caller-identity` in the same shell with the same `AWS_PROFILE`. If it also hangs, fix the profile; a `credential_process` command that prompts interactively is a common cause.
- Complete the sign-in step before starting Claude Code, for example `aws sso login --profile myprofile`
- If your chain runs an interactive sign-in that legitimately needs more than 60 seconds, such as SSO with MFA through a wrapper like `aws-vault`, raise the limit in milliseconds with [`CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS`](env-vars.md)


[​](#bedrock-setup-verification-timed-out-waiting-for-aws)

Bedrock setup verification timed out waiting for AWS

A call to AWS during the [Bedrock setup wizard](amazon-bedrock.md#sign-in-with-bedrock)’s credential verification, such as the credential lookup or the identity check, didn’t finish within the 60-second limit. The wizard stops waiting and fails the verification step:

```python
Timed out after 60s waiting for AWS. Check your network and proxy settings; if a credential helper needs longer to prompt you, raise CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS.
```

The number reflects your limit: 60 seconds by default, or the value you set in [`CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS`](env-vars.md). Common causes are a network or proxy that stalls requests to AWS, including the SSO token refresh, and a credential helper still waiting for input you can’t see. Raise the limit only when the helper legitimately needs more time. A single stalled request to AWS can also fail on its own per-request timeout, which shows a shorter message on the same step:

```python
A request to AWS timed out. Check your network and proxy settings, then try again.
```

When the same timeouts occur on the model pin step, the wizard marks a model as `unreachable` instead of showing either message. **What to do:**

- Run `aws sts get-caller-identity` in the same shell. If it also hangs, the stall is outside Claude Code, in your network, your proxy, or the credential helper in your AWS profile; fix that first.
- Complete any interactive sign-in before opening the wizard, for example `aws sso login --profile myprofile`
- If a credential helper in your AWS profile legitimately needs longer than 60 seconds to prompt you, raise the limit in milliseconds with [`CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS`](env-vars.md)


[​](#cloud-gateway-session-expired)

Cloud gateway session expired

You signed in through a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md), and the gateway session saved on this machine has expired and couldn’t be renewed, or the gateway no longer accepts it, for example after the gateway’s [JWT secret is replaced](../13-Enterprise-Admin/claude-apps-gateway-deploy.md#jwt-secret-rotation). If you see this line when you start `claude` interactively, the session has opened signed out of the gateway:

```python
Cloud gateway session expired — run /login to reconnect.
```

The same line can appear mid-session when the gateway credential expires and Claude Code can’t renew it. In a [non-interactive](headless.md) run, a background or other unattended session, or a `claude` subcommand other than `claude auth`, Claude Code exits with this message instead when the gateway no longer accepts the session:

```python
Cloud gateway <url> no longer accepts this session. Start `claude` and sign in again with /login.
```

**What to do:**

- Run `/login` in the session and complete the browser sign-in
- For a non-interactive launch, start `claude` in the same environment, run `/login`, then rerun your command


[​](#sign-in-timed-out-while-waiting-for-you-to-continue)

Sign-in timed out while waiting for you to continue

During a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sign-in, the gateway named the account that signed in, and Claude Code asked you to confirm it before saving the credential. You left the confirmation open past the sign-in’s own expiry, and the gateway issued no refresh token that could renew it, so Claude Code stored nothing when you continued:

```python
Sign-in timed out while waiting for you to continue. Try again.
```

**What to do:**

- Run `/login` again and confirm the account before the sign-in expires


[​](#gateway-refused-the-request)

Gateway refused the request

You’re signed in through a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md), and a request returned a 403: the gateway, or the upstream behind it, refused it. Signing in again doesn’t change a refusal, so the message points at your gateway administrator:

```python
Gateway refused the request · signing in again won't change this — check with your gateway administrator · API Error: 403 ...
```

**What to do:**

- Ask your gateway administrator to look up the request. The `API Error:` tail carries the refusal the gateway returned
- For administrators: an [access control rule](../13-Enterprise-Admin/claude-apps-gateway-config.md#http-tuning) on the gateway returns a 403 that the [audit log](../13-Enterprise-Admin/claude-apps-gateway-deploy.md#logs) records with its reason, and an upstream’s authorization denial passes through per [Upstream error messages](../13-Enterprise-Admin/claude-apps-gateway-config.md#upstream-error-messages)

Before v2.1.273, a 403 on a gateway session showed the generic `Please run /login` or `Failed to authenticate` message instead, and signing in again didn’t clear the refusal.


[​](#network-and-connection-errors)

Network and connection errors

Most of these errors mean a network request from Claude Code failed to reach its destination, or something between Claude Code and the API altered the response on its way back; where an entry also has a local cause, such as a failed archive write, its body says so. They usually originate in your local network, proxy, or firewall, or in the cloud environment’s network policy.


[​](#unable-to-connect-to-api)

Unable to connect to API

The TCP connection to the API failed or never completed. For the common connection error codes, the message names the kind of failure and keeps the code in parentheses:

```python
Unable to connect to API. Check your internet connection
Connection refused — a firewall or proxy may be blocking it (ConnectionRefused)
Can't reach the API server — check your internet or DNS (ENOTFOUND)
No internet route — check your connection or VPN (EHOSTUNREACH)
Couldn't connect through your proxy (ERR_PROXY_TUNNEL) — the proxy refused the tunnel: check its credentials and that it allows this host
Connection dropped (ECONNRESET)
Request timed out. Check your internet connection and proxy settings
```

A code Claude Code doesn’t recognize appears as `Unable to connect to API` followed by the code in parentheses. Some of these messages can show more than one code: `Connection refused` can show `ConnectionRefused` or `ECONNREFUSED`, for example, and `Can't reach the API server` can show `ENOTFOUND` or `FailedToOpenSocket`. Before v2.1.227, each of these coded messages read `Unable to connect to API` followed by the code, for example `Unable to connect to API (ECONNREFUSED)`. Common causes include no internet access, a VPN that blocks `api.anthropic.com`, or a required corporate proxy that is not configured. **What to do:**

- Confirm you can reach the API host from the same shell by running `curl -I https://api.anthropic.com`. On Windows PowerShell use `curl.exe -I https://api.anthropic.com` so the built-in `Invoke-WebRequest` alias is not used.
- If you are behind a corporate proxy, set `HTTPS_PROXY` before launching Claude Code and see [Network configuration](../13-Enterprise-Admin/network-config.md)
- If you route through an LLM gateway or relay, set [`ANTHROPIC_BASE_URL`](env-vars.md) to its address. See [Connect Claude Code to an LLM gateway](../13-Enterprise-Admin/llm-gateway-connect.md) for setup.
- If `ANTHROPIC_BASE_URL` already points at your gateway and every request ends in `Connection dropped`, check whether your gateway is rejecting the tool search fields Claude Code sends by default. To check, set `ENABLE_TOOL_SEARCH=false` as [Tool search through an LLM gateway](../06-MCP-Tools/General/mcp.md#tool-search-through-a-gateway) describes, then try again. Before v2.1.304, tool search was off behind a gateway unless you turned it on with `ENABLE_TOOL_SEARCH`.
- Ensure your firewall allows the hosts listed in [Network access requirements](../13-Enterprise-Admin/network-config.md#network-access-requirements)
- Intermittent failures are [retried automatically](#automatic-retries)

If `curl` succeeds but Claude Code still fails, the cause is usually something between the runtime and the network rather than the network itself:

- Check whether `ANTHROPIC_BASE_URL` is set by running `echo $ANTHROPIC_BASE_URL`, or `echo $env:ANTHROPIC_BASE_URL` in PowerShell, and look for it in the `env` block of your [settings files](settings.md). When it’s set, Claude Code sends model requests to that address instead of `api.anthropic.com`, so a leftover value pointing at a local proxy or gateway that’s no longer running produces `Connection refused` even though `curl` reaches the API. Remove it from your shell profile or settings and start Claude Code from a new terminal.
- On Linux and WSL, check `/etc/resolv.conf` for an unreachable nameserver. WSL in particular can inherit a broken resolver from the host.
- On macOS, a VPN client that was disconnected or uninstalled can leave a tunnel interface or routing rule behind. Check `ifconfig` for stale `utun` interfaces and remove the VPN’s network extension in System Settings.
- Docker Desktop and similar container runtimes can intercept outbound traffic. Quit them and retry to rule this out.


[​](#unable-to-connect-to-anthropic-services)

Unable to connect to Anthropic services

During first-run setup, Claude Code checks that it can reach `api.anthropic.com` and `platform.claude.com` before showing the sign-in step. When either check fails, Claude Code prints the reason and exits.

```python
Unable to connect to Anthropic services
Failed to connect to api.anthropic.com: ECONNREFUSED
Connection to api.anthropic.com timed out after 10 seconds
A proxy is configured via HTTPS_PROXY. Check that it allows connections to the host above.
```

Claude Code sends the check through the same [proxy configuration](../13-Enterprise-Admin/network-config.md) as API requests and gives each probe 10 seconds. When the failed probe went through a proxy, the message names the environment variable that configured it, such as `HTTPS_PROXY`. Before v2.1.222, the check used a different proxy transport with no timeout: behind a proxy URL with the `https://` scheme, it could stall on `Checking connectivity...` indefinitely and then fail even though API requests through the same proxy succeed. Claude Code skips this check when a [managed settings file, MDM policy, or policy helper](../13-Enterprise-Admin/managed-settings.md) sets [`forceLoginMethod`](settings-reference.md#forceloginmethod) to `"gateway"`, or sets [`forceLoginGatewayUrl`](settings-reference.md#forcelogingatewayurl) without `forceLoginMethod`. With either configuration, Claude Code opens the sign-in step on the **Cloud gateway** screen rather than an Anthropic sign-in method. Claude Code also skips the check when a managed settings source on the machine exists but can’t be read, since that source may hold the gateway configuration. Before v2.1.247, Claude Code ran the check under this configuration too, and exited with this error when Anthropic’s endpoints were unreachable. Claude Code also skips the check on a machine with no managed settings when your own `~/.claude/settings.json` [names a gateway](../13-Enterprise-Admin/claude-apps-gateway.md#set-the-gateway-url-in-user-settings) with `forceLoginMethod` and `forceLoginGatewayUrl`. Before v2.1.295, Claude Code ran the check in that case. **What to do:**

- If the message names a proxy variable, check that its value points at the right proxy and ask your network team to allow HTTPS connections through it to the host in the message. See [Network configuration](../13-Enterprise-Admin/network-config.md).
- Work through the checks in [Unable to connect to API](#unable-to-connect-to-api). The `curl` test and firewall guidance there apply to this check too.
- If your network is open and the failure persists, Claude Code may not be [available in your country](https://www.anthropic.com/supported-countries)


[​](#socket-is-closed)

Socket is closed

`Socket is closed` means the connection carrying a streaming response was closed while the response was still arriving. The most common cause is a corporate proxy on Windows dropping an established tunnel mid-response. Depending on how far the response had progressed, Claude Code retries the request, keeps what Claude produced, or ends the turn. See [Automatic retries](#automatic-retries). Before v2.1.214, Claude Code didn’t retry this failure, and the turn stopped with an error containing `Socket is closed`. **What to do:**

- If you see this error, update to v2.1.214 or later with `claude update`, then send your message again
- If turns keep failing behind the same proxy after updating, work through [Unable to connect to API](#unable-to-connect-to-api) and check the proxy setup in [Network configuration](../13-Enterprise-Admin/network-config.md)


[​](#api-returned-an-empty-or-malformed-response)

API returned an empty or malformed response

Claude Code shows this error when its non-streaming retry of a failed streaming request gets an HTTP success status but the body isn’t a Claude API message: commonly an HTML error or sign-in page, an empty body, or JSON in another format. A proxy, gateway, or network sign-in page answering in the API’s place is the usual source. Claude Code doesn’t retry the request, and the turn ends with this error.

```python
API returned an empty or malformed response (HTTP 200) — check for a proxy or gateway intercepting the request.
```

After that opening, the message reports what came back and which request failed:

- A `Response:` clause with the content type, the kind of body, such as `body is an HTML page` or `empty body`, its size in bytes, and whether the response carried an Anthropic request id. When the response names a recognizable server, such as `nginx` or `cloudflare`, or carries intermediary headers, such as `cf-ray` or `via`, the clause lists those too.
- A sentence naming the failed streaming request’s id and the failure that triggered the retry. When a stream had opened before the failure, it also reports how many stream events arrived and, if any did, how long the stream had been silent when the attempt failed.

Before v2.1.234, the message ended after `intercepting the request`. Before v2.1.271, a reply that carried a valid API message under a non-JSON content type such as `text/plain` also ended the turn with this error. Some LLM gateways use that content type for the non-streaming reply. **What to do:**

- Read the `Response:` clause to see which system answered. An HTML body, no Anthropic request id, or a named server such as `nginx` or `cloudflare` means that something between Claude Code and the API replied in its place
- If you route through an [LLM gateway](../13-Enterprise-Admin/llm-gateway-connect.md#troubleshoot-gateway-errors), test the route with a direct request and fix the hop that returns the non-API response
- On a network with a sign-in page, such as guest Wi-Fi, complete the sign-in in a browser, then retry
- If only the non-streaming route through your gateway is broken, set [`CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK=1`](env-vars.md#variables) to turn off this fallback, except when the streaming endpoint itself returns `404`, where Claude Code still falls back


[​](#streaming-response-ended-before-any-complete-data-was-received)

Streaming response ended before any complete data was received

A streaming response from your model provider completed without delivering any usable data, so Claude Code re-sent the request without streaming to finish the turn. Claude Code shows the warning once per session, in interactive sessions only. Before v2.1.239, Claude Code silently retried without streaming.

```python
Streaming response ended before any complete data was received. Retrying without streaming. If this keeps happening, check any proxy or gateway between Claude Code and your model provider.
```

Claude Code sends each affected request twice: the empty streaming attempt and the retry. The usual cause is a proxy or gateway that consumes or transforms the streaming response body on its way back. **What to do:**

- Configure any proxy or gateway between Claude Code and your model provider to pass streaming response bodies and their headers through unmodified
- On [Amazon Bedrock](amazon-bedrock.md), see [Streaming errors behind a gateway or proxy](amazon-bedrock.md#streaming-errors-behind-a-gateway-or-proxy) for the header and body requirements


[​](#bedrock-streaming-response-has-an-unexpected-content-type)

Bedrock streaming response has an unexpected content-type

A gateway or proxy between Claude Code and [Amazon Bedrock](amazon-bedrock.md) is transforming the streaming response body or its `Content-Type` header. Amazon Bedrock streams responses as `application/vnd.amazon.eventstream`. Rather than decode a body it can’t read, Claude Code rejects a successful streaming response that reports a different content-type. Claude Code doesn’t retry the request.

```python
Bedrock streaming response has content-type "text/event-stream"; expected "application/vnd.amazon.eventstream". A gateway or proxy between Claude Code and Bedrock is likely transforming the response body — Bedrock's binary event-stream format must be passed through unmodified. Set CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_GUARD=1 to suppress this check while the gateway is being fixed.
```

Before v2.1.208, the same misconfiguration surfaced as `API Error: Truncated event message received` after the whole response had been buffered. **What to do:**

- Configure the gateway to pass the `InvokeModelWithResponseStream` response body and its `Content-Type` header through unmodified. An intermediary that re-emits the stream as server-sent events is a common cause.
- Setting [`CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_GUARD=1`](env-vars.md) hides this error, but Claude Code doesn’t decode a binary body under a rewritten header, so those requests fall back to a slower non-streaming path. See [Streaming errors behind a gateway or proxy](amazon-bedrock.md#streaming-errors-behind-a-gateway-or-proxy).


[​](#ssl-certificate-errors)

SSL certificate errors

A proxy or security appliance on your network is intercepting TLS traffic with its own certificate, and Claude Code does not trust it.

```python
Unable to connect to API: SSL certificate verification failed (UNABLE_TO_GET_ISSUER_CERT_LOCALLY). The certificate comes from an authority Claude Code doesn't trust, usually a TLS-inspecting corporate proxy or a gateway signed by a private CA: set NODE_EXTRA_CA_CERTS to that CA bundle, or add it to the system certificate store · see https://code.claude.com/docs/en/network-config
Unable to connect to API: Self-signed certificate detected (SELF_SIGNED_CERT_IN_CHAIN). The certificate comes from an authority Claude Code doesn't trust, usually a TLS-inspecting corporate proxy or a gateway signed by a private CA: set NODE_EXTRA_CA_CERTS to that CA bundle, or add it to the system certificate store · see https://code.claude.com/docs/en/network-config
```

Before v2.1.273, both messages ended at `Check your proxy or corporate SSL certificates`, without the OpenSSL code or the `NODE_EXTRA_CA_CERTS` hint. As of v2.1.199, a certificate validation failure isn’t retried, so this error appears on the first attempt instead of after the full [retry budget](#automatic-retries). Earlier versions spent a few minutes retrying before showing it. Transient TLS conditions, such as a handshake timeout, still retry. During `/login` and the startup connectivity check, the same failure produces a different message:

```python
SSL certificate error (UNABLE_TO_GET_ISSUER_CERT_LOCALLY). If you are behind a corporate proxy or TLS-intercepting firewall, set NODE_EXTRA_CA_CERTS to your CA bundle path, or ask IT to allowlist *.anthropic.com. Run `claude doctor` for details.
```

On [Amazon Bedrock](amazon-bedrock.md), the requests Claude Code itself sends to AWS, such as the STS and SSO role-credential calls, model discovery, and the setup wizard’s checks, depend on the same certificate configuration. See [Certificate errors behind a TLS-inspecting proxy](amazon-bedrock.md#certificate-errors-behind-a-tls-inspecting-proxy). **What to do:**

- Export your organization’s CA bundle and point Claude Code at it with `NODE_EXTRA_CA_CERTS=/path/to/ca-bundle.pem`
- See [Network configuration](../13-Enterprise-Admin/network-config.md#custom-ca-certificates) for full setup instructions
- Don’t set `NODE_TLS_REJECT_UNAUTHORIZED=0`, which disables certificate validation entirely


[​](#host-not-allowed-in-a-cloud-session)

Host not allowed in a cloud session

An outbound HTTP request from a cloud session or cloud scheduled task was blocked by the environment’s network policy.

```python
HTTP 403
x-deny-reason: host_not_allowed
```

You may also see a TLS certificate that doesn’t match the destination’s real certificate. Cloud sessions route outbound traffic through a proxy that enforces the network policy, so a mismatched certificate means the proxy terminated the connection, not the destination. This error is not a client-side network problem. Cloud sessions and [cloud scheduled tasks](web-scheduled-tasks.md) run inside a sandboxed VM whose outbound traffic through the session’s network is filtered to the [cloud environment’s](cloud-environments.md) allowlist:

- **GitHub and connector traffic**: [GitHub operations](cloud-environments.md#github-proxy) and MCP connector traffic use separate channels, which is why they can keep working while other hosts are blocked
- **Default environment**: the **Default** environment uses **Trusted** access, which permits the [default allowlist](cloud-environments.md#default-allowed-domains) of package registries, cloud provider APIs, container registries, and common development domains and blocks other domains on that path

**What to do:** These steps change one of your own environments. An [organization-shared environment](cloud-environments.md#organization-shared-environments) opens read-only in the selector, so ask an Owner to change its network access from the **Cloud environments** page in [admin settings](https://claude.ai/admin-settings).

- Open your environment for editing, either from the [cloud scheduled task’s form](web-scheduled-tasks.md#environments-and-network-access) or from the [environment selector](cloud-environments.md#configure-your-environment) where you start cloud sessions.
- In the **Edit cloud environment** dialog, change **Network access** from **Trusted** to **Custom**, then add the blocked domain to **Allowed domains**. Enter one domain per line. Check **Also include default list of common package managers** to keep the [default allowlist](cloud-environments.md#default-allowed-domains) alongside your custom domains. Select **Full** instead if you want unrestricted access.
- Click **Save changes**. The next run uses the updated allowlist. For a cloud session that’s already open, see [when a network access change reaches existing sessions](cloud-environments.md#network-access).

See [Network access](cloud-environments.md#network-access) for access levels and the default allowlist. Local CLI sessions are not affected by this policy.


[​](#the-proxy-refused-the-connection)

The proxy refused the connection

You see this message when Claude reads an [artifact](artifacts.md) through the proxy you set in `HTTPS_PROXY` or a related [proxy variable](../13-Enterprise-Admin/network-config.md#environment-variables). Artifact content comes from `*.frame.claudeusercontent.com`, so Claude Code first sends the proxy a `CONNECT` request asking it to open a tunnel to that host. When the proxy refuses, nothing reaches the host, and the message carries the proxy’s HTTP status:

```python
artifact content fetch failed (proxy refused the connection: HTTP 407)
artifact content fetch failed (proxy refused the connection: HTTP 403)
the proxy refused the connection to the artifact's content host (HTTP 502)
```

The status is the proxy’s answer to the `CONNECT`. The host never answered, so each status points at a different fix:

- `HTTP 407`: the proxy requires credentials it didn’t get. Put them in the proxy URL, as [Basic authentication](../13-Enterprise-Admin/network-config.md#basic-authentication) shows.
- `HTTP 403`: the proxy refuses to tunnel to `*.frame.claudeusercontent.com`. Ask whoever runs the proxy to allow that host, which [Network access requirements](../13-Enterprise-Admin/network-config.md#network-access-requirements) lists.
- Any other status, such as `HTTP 502`: the proxy didn’t open the tunnel for its own reason, such as failing to reach the host. Look the status up in the proxy’s logs.
- `unreadable reply` in place of a status: whatever is at the proxy address didn’t answer with an HTTP status line. Check that the address is an HTTP proxy.

**What to do:**

- Check the address and credentials in the proxy variable, as [Proxy configuration](../13-Enterprise-Admin/network-config.md#proxy-configuration) describes, then run `curl -x http://proxy.example.com:8080 -I https://api.anthropic.com` from the shell you start Claude Code in, using your own proxy URL. On Windows PowerShell, run `curl.exe`. If this probe fails the same way, fix the proxy setup first. If it succeeds, the refusal is specific to the artifact host.
- If your network lets Claude Code reach the artifact host directly, add `.frame.claudeusercontent.com` to [`NO_PROXY`](../13-Enterprise-Admin/network-config.md#environment-variables). Keep the entry that narrow: a broader `.claudeusercontent.com` entry also bypasses the proxy for `bridge.claudeusercontent.com`, which organizations with [IP allowlisting](../13-Enterprise-Admin/network-config.md#organization-ip-allowlists-and-proxy-egress) need to keep on the proxy.

Before v2.1.238, Claude Code reported a refused tunnel as a generic network error.


[​](#the-cloud-environments-service-returned-an-empty-or-unexpected-response)

The cloud environments service returned an empty or unexpected response

Claude Code requests your [cloud environments](cloud-environments.md) list at several points, such as when you create a cloud session from the CLI or run [`/remote-env`](cloud-environments.md#select-an-environment-from-the-cli). When it can’t read the server’s answer, it shows one of these messages:

```python
The cloud environments service returned an empty response (HTTP 200 with no body). This is usually temporary — try again in a moment.
The cloud environments service returned a response in an unexpected format (HTTP 200 with a non-JSON body). This is usually temporary — try again in a moment.
The cloud environments service returned a response in an unexpected format (HTTP 200 without a usable environments list). This is usually temporary — try again in a moment.
```

The server accepted the request but answered with a body that isn’t the environments list: empty, not JSON, or JSON without the list. This usually accompanies a service-side disruption and clears on its own. Depending on the surface that requested the list, Claude Code may add a prefix, such as `couldn't list environments:` in the `/remote-env` dialog. **What to do:**

- Retry the action. Claude Code requests the list again each time
- If the message keeps appearing, check [status.claude.com](https://status.claude.com) for active incidents

Before v2.1.236, Claude Code showed a raw JavaScript TypeError instead of these messages.


[​](#failed-to-fetch-session-from-sessions-api)

Failed to fetch session from Sessions API

This message means Claude Code found the [cloud session you asked to pull into your terminal](claude-code-on-the-web.md#from-cloud-to-terminal) but couldn’t read its conversation history from Anthropic’s servers, so it didn’t open it:

```python
Failed to fetch session from Sessions API: Failed to fetch session logs
```

You see it after `claude --teleport`, `/teleport`, or choosing the session in the [`/tasks`](commands.md) list. `claude --teleport <session-id>` prints it and exits with code 1. **What to do:**

- Run the same teleport again. If it fails the same way, [report the problem](#report-an-error)

Before 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.


[​](#couldnt-reconnect-to-your-remote-control-session)

Couldn’t reconnect to your Remote Control session

```python
Couldn't reconnect to your Remote Control session. Retry, or start a fresh session without --resume.
```

Resuming with `claude --resume` or `claude --continue` reconnects to the [Remote Control](remote-control.md) session recorded in that conversation. This message means the reconnection failed for a reason that may be temporary, such as a network interruption or a server error, so Claude Code can’t confirm whether the remote session still exists. Your local session keeps running without Remote Control. **What to do:**

- Run `/remote-control` to retry the connection
- Start a new session with `claude --remote-control` to create a new Remote Control session
- For other Remote Control startup messages, see [Troubleshoot Remote Control](remote-control.md#troubleshooting)

If the server reports instead that the previous session is gone, you don’t see this message. Claude Code starts a new session in its place or shows [`Previous session is unavailable — run /remote-control to start a new one`](remote-control.md#previous-session-is-unavailable).


[​](#sessions-ended-while-this-machine-was-offline)

Sessions ended while this machine was offline

Claude Code shows this message in the terminal running [`claude remote-control`](remote-control.md#start-a-remote-control-session) after your machine was offline long enough that the server cleaned up the Remote Control environment your machine was serving. The sessions in that environment ended, and you can’t resume them. The count is the number of sessions that ended.

```python
2 sessions ended while this machine was offline — the environment was cleaned up on the server and can't be resumed.
```

**What to do:**

- When Claude Code lists kept worktrees under this message, pick up any uncommitted work from them
- Run `claude remote-control` to start a fresh environment


[​](#couldnt-share-the-transcript)

Couldn’t share the transcript

After you agree to share your session transcript from a survey prompt, such as the [session quality survey](../13-Enterprise-Admin/data-usage.md#session-quality-surveys), Claude Code uploads it to Anthropic, or saves a local archive instead on third-party providers, on [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sessions, and when no Anthropic credentials are available. This message means the share didn’t complete.

```python
Couldn't share the transcript.
```

The upload must fit an 8 MiB limit. On a long session, Claude Code progressively drops parts of the share, the last request’s model settings first, then the structured conversation and subagent transcripts, and shows this message when no reduced version can be sent or a network or server error stops the upload. When Claude Code saves a local archive instead, the message means it couldn’t write the archive. **What to do:**

- Run `/feedback` to send the transcript with a description of what happened. See [Report an error](#report-an-error) if `/feedback` is unavailable in your environment
- If other requests are failing too, check your network connection and see [Unable to connect to API](#unable-to-connect-to-api)


[​](#couldnt-send-feedback)

Couldn’t send feedback

A message starting `Couldn't send feedback` means the report you submitted from the [`/feedback`, `/bug`, or `/share` dialog](commands.md#all-commands), or a queued [feedback draft](tools-reference.md#sendfeedback-tool-behavior), wasn’t sent. When a sentence about your organization follows the colon, your organization refuses feedback and the same report gets the same answer. The first of these two examples is a network failure and the second is an organization’s refusal:

```python
Couldn't send feedback (couldn't reach the service). If it keeps failing, you can file at https://github.com/anthropics/claude-code/issues instead.

Couldn't send feedback: Feedback has not been enabled for your organization. To report a bug, open an issue at https://github.com/anthropics/claude-code/issues. Issues are public, so leave out anything confidential.
```

**What to do:**

- **Not signed in**: the message continues `: not signed in. Run /login, then retry.` Run `/login`, then send again
- **Your organization’s refusal**: for example `: Feedback has not been enabled for your organization.` or `: Feedback collection is not available for organizations with custom data retention policies.` If the message adds `To report a bug, open an issue`, do so at [github.com/anthropics/claude-code/issues](https://github.com/anthropics/claude-code/issues). A queued draft stays queued, and you can [discard it](tools-reference.md#discard-or-keep-a-draft)
- **Refused credentials**: the message continues `: the sign-in this session uses is not allowed to send feedback` or `: the server did not accept the credentials this session uses`. Run `/status` at the Claude Code prompt to see which login, token, or API key this session sends
- **`(request timed out)` or `(couldn't reach the service)` straight after `Couldn't send feedback`**: these are network failures. Send the report or the queued draft again. The dialog keeps your text, and a queued draft’s message says `The draft is still queued.` If other requests are failing too, check your network connection and see [Unable to connect to API](#unable-to-connect-to-api). If it keeps failing, file the report at [github.com/anthropics/claude-code/issues](https://github.com/anthropics/claude-code/issues)
- **`(server returned <status>)`, or no reason, straight after `Couldn't send feedback`**: the status is the service’s response code. The service’s own message follows it when one was sent, as in `(server returned 403: Access Forbidden)`. If it keeps failing, file the report at [github.com/anthropics/claude-code/issues](https://github.com/anthropics/claude-code/issues)

Issues at github.com/anthropics/claude-code are public, so leave out code, transcripts, and anything else confidential when you open one. Before v2.1.281, every send failed with this message once a Remote Control **Stop** or an urgent cross-session message had arrived while the dialog was open. On those versions, close the dialog, reopen it, and send again.


[​](#mcp-server-connection-timed-out-during-a-sleep-or-clock-change)

MCP server connection timed out during a sleep or clock change

This message means a connection to an [MCP server](../06-MCP-Tools/General/mcp.md) timed out, and Claude Code found that your system clock jumped forward during the attempt:

```python
MCP server "<name>" connection timed out. Your computer went to sleep or its clock changed while connecting.
```

Claude Code can’t tell whether your computer slept or its clock was set forward, so the message names both. **What to do:** Connect to the server again, and keep your computer awake until the attempt finishes. If the server connects, you have nothing to fix.

- **In an interactive session**: run `/mcp`, select the server, and select **Reconnect**
- **In your shell**: run the [`claude -p`](headless.md), [`claude mcp list`](../06-MCP-Tools/General/mcp.md#managing-your-servers), or `claude mcp get` command again. If the server then fails with a message that starts `Skipping connection (recent failure cached`, wait 15 minutes and run the command again.
- **In an [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) application**: call [`reconnectMcpServer()`](../05-Agent-SDK/agent-sdk-typescript.md#methods) in TypeScript or [`ClaudeSDKClient.reconnect_mcp_server()`](../05-Agent-SDK/agent-sdk-python.md#methods) in Python
- **If the server fails again**: if the message differs from this one, see [what to check when an MCP server doesn’t connect](../06-MCP-Tools/General/mcp-quickstart.md#troubleshooting). If this message comes back although your computer stayed awake and nothing changed its clock, see [Report an error](#report-an-error).

Before v2.1.307, Claude Code showed a timeout message such as `MCP server "<name>" connection timed out after <N>ms` instead of this one.


[​](#request-errors)

Request errors

These errors relate to the content of your request. Most come back from the API after it rejected the request; a few are produced locally by Claude Code before any request is sent.


[​](#prompt-is-too-long)

Prompt is too long

The conversation plus attached files exceeds the model’s context window.

```python
Prompt is too long
```

In an interactive session, Claude Code shows this error as:

```python
Context limit reached · /compact or /clear to continue
```

The line names only `/clear` when [`DISABLE_COMPACT`](env-vars.md) is set. Longer forms of the error, such as the compaction-failed form below, keep the `Prompt is too long ·` wording. In `-p` output and the transcript, the text stays `Prompt is too long`. When you turned auto-compact off in your [user settings](settings-reference.md#autocompactenabled), the line also says so:

```python
Context limit reached · /compact or /clear to continue · auto-compact is off · /config to turn it on
```

The **Auto-compact** toggle in `/config` writes `autoCompactEnabled` to user settings. The hint appears only when a `/config` change would take effect. For example, it doesn’t appear when [`DISABLE_AUTO_COMPACT`](env-vars.md) or [`DISABLE_COMPACT`](env-vars.md) turned auto-compact off. It also doesn’t appear when a higher-precedence scope, such as project or managed settings, set `autoCompactEnabled` to `false`. Before v2.1.235, the line carried no auto-compact hint. Amazon Bedrock reports this condition as `Input is too long for requested model.`, which Claude Code handles the same way. Before v2.1.217, Claude Code didn’t recognize the Bedrock wording, so auto-compact never triggered on it and `/compact` failed with the same error. A [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway-config.md#upstream-error-messages) reports this condition as `capability_rejected: prompt_too_long` when a cloud upstream rejects the request in the provider’s own error shape. Claude Code treats the token the same as `Prompt is too long`. Before v2.1.228, Claude Code didn’t recognize the token, so auto-compact didn’t trigger on it. When automatic compaction ran on this turn and failed on an underlying error, such as an unavailable model or an authentication failure, the message names that error after a separator:

```python
Prompt is too long · automatic compaction failed: <the underlying error>
```

Resolve the named error first; `/compact` fails on the same error until you do. Before v2.1.229, a failed automatic compaction surfaced `Prompt is too long` without the cause. When automatic compaction runs on this error, it normally summarizes your oldest exchanges and keeps the newest. As a last resort, Claude Code summarizes differently:

- When it can’t summarize any whole exchange, Claude Code keeps your newest prompt word for word and summarizes everything before it.
- In that case, when the conversation doesn’t end with your prompt, Claude Code summarizes the whole conversation instead.

Claude Code skips this recovery when the content it would carry forward holds no model reply and less than about 1,000 tokens of your own text, such as a short retry sent after an oversized paste. Run `/clear` to start fresh. Before v2.1.269, compaction failed whenever it couldn’t summarize a whole exchange, so a session in that state hit this error again on every turn. A single-exchange conversation has no earlier turns to summarize. When automatic compaction would have run on one, Claude Code skips the attempt and explains what fills the request instead. When the API doesn’t report token counts in its error, the message reads:

```python
Prompt is too long · this conversation is a single exchange and cannot be compacted — the request size comes mostly from system prompt, tool definitions, or attachments.
```

When the API reports token counts in its error, Claude Code compares them with its own estimate of the conversation’s size to tell which is most of the request: the conversation’s own content, or the system prompt, tool definitions, and attachment content that Claude Code sends with it. When the conversation’s own content is most of the request, the message reads:

```python
Prompt is too long · the request is ~<request tokens> tokens (limit <limit>) and this conversation's own content is most of it. A single-exchange conversation cannot be compacted; start with less content (smaller files or pasted text).
```

When most of the request is outside the conversation, the message reads:

```python
Prompt is too long · the request is ~<request tokens> tokens (limit <limit>) but this conversation is only ~<conversation tokens> tokens — the rest is system prompt, tool definitions, and attachment content. A single-exchange conversation cannot be compacted; reduce attached files/tools or start with less context.
```

Before v2.1.162, Claude Code attempted the compaction anyway and surfaced the bare `Prompt is too long` when it failed. **What to do:**

- Run `/compact` to summarize earlier turns and free space, or `/clear` to start fresh. If `/compact` answers `Not enough messages to compact.`, the conversation is a single exchange with nothing earlier to summarize, so the space is taken by that one prompt and what Claude Code sends with every request: run `/clear` and resend with less pasted text or smaller attachments, or reduce the tool definitions and memory files using the steps below
- Run `/context` to see a breakdown of what is consuming the window: system prompt, tools, memory files, and messages
- Disable MCP servers you are not using with `/mcp disable <name>` to remove their tool definitions from context
- Trim large `CLAUDE.md` memory files, or move instructions into [path-scoped rules](memory.md#path-specific-rules) that load only when relevant
- Auto-compact is on by default and normally prevents this error. If you turned it off in `/config` or with [`DISABLE_AUTO_COMPACT`](env-vars.md), turn it back on. If you keep it off, run `/compact` yourself before the window fills.
- If the error appears near 200K tokens on a model that accepts more, one cause is a model ID that Claude Code doesn’t recognize. Claude Code assumes a 200K window for such an ID, so to keep working past that point, [give it the model’s real context window](model-config.md#correct-the-window-for-a-gateway-or-custom-model-id).
  - If you use a custom [`ANTHROPIC_BASE_URL`](env-vars.md) and the error starts with `Prompt is too long · automatic compaction failed`, [set the model’s context window](model-config.md#correct-the-window-for-a-gateway-or-custom-model-id) or [update](../01-Getting-Started/setup.md#update-claude-code) to v2.1.299 or later. Before v2.1.299, Claude Code ended the turn with that message near the assumed 200K window instead of sending the request.
- If the error appeared right after you stopped Claude while it was compacting the conversation, your conversation is unchanged and still large enough to need compacting. Run `/compact` and send your message again. To keep the error from recurring, [update Claude Code](../01-Getting-Started/setup.md#update-claude-code) to v2.1.304 or later. Before v2.1.304, stopping at that moment could end the turn with this error.
- On v2.1.305, with many MCP tools and a direct connection to the Anthropic API, this error can hide an unrelated 400 or 422 error from the API. [Update Claude Code](../01-Getting-Started/setup.md#update-claude-code) to v2.1.306 or later to see the original error.

See [Explore the context window](context-window.md) for an interactive view of how context fills up.


[​](#context-exceeds-the-token-limit)

Context exceeds the token limit

`/context` shows this warning at the top of its output when the conversation has grown past the model’s context window. Requests fail with [`Prompt is too long`](#prompt-is-too-long) until you free space. An interactive session shows that error as the `Context limit reached` line.

```python
Context exceeds the 200k-token limit by 94k tokens — run /compact or /clear to continue.
```

When the limit you exceeded is a compaction window, such as the 200K boundary on 1M-context models, the warning reads differently. A compaction window can sit below the model’s context window, so requests past it can still succeed.

```python
Context is 94k tokens past the 200k-token compaction window — run /compact to reduce usage.
```

Both forms name `/clear` instead of `/compact` when you have set [`DISABLE_COMPACT`](env-vars.md). **What to do:**

- In a multi-turn conversation, run `/compact` to summarize earlier turns and free space. To start fresh instead, run `/clear`
- For more ways to reduce usage, see [Prompt is too long](#prompt-is-too-long)

Before v2.1.216, `/context` showed usage above 100% with no warning line explaining what that meant or how to recover.


[​](#request-too-large)

Request too large

The raw request body exceeded the API’s 32MB limit before tokenization, usually because of large pasted content, tool results, or attachments. This limit is separate from the [context window](#prompt-is-too-long).

```python
Request too large (max 32MB). Accumulated images and attachments in the conversation pushed the request over the limit. Run /compact, or double press esc to go back and remove attachments.
```

When the request went straight to the Claude API and the API itself rejected it, Claude Code measures the conversation and words the message by whether recovery can work. Through a proxy, gateway, or cloud provider you get the general message. The measured forms:

- `Request too large (max 32MB; 20.1MB of about 33.4MB is images or documents).`: images or documents pushed the request over the limit. Claude Code retries with them stripped.
- `Request too large for the API's 32MB request limit`: the messages alone are over the limit, so the message says `compacting cannot make it fit` and Claude Code doesn’t retry. In [non-interactive mode](headless.md), the message tells you to reduce the input or start a new session instead.

Before v2.1.212, conversations with enough accumulated images failed on every turn with `Request too large (max 32MB). Double press esc to go back and try with a smaller file.` Before v2.1.229, Claude Code showed the attachment advice for every rejection, even when compacting couldn’t help. **What to do:**

- If the message says `compacting cannot make it fit`, press Esc twice to step back past the turn that added the large content, or run `/clear` to start fresh
- Otherwise, run `/compact`, which drops accumulated images and attachments
- Reference large files by path instead of pasting their contents, so Claude can read them in chunks
- For images, see [Image was too large](#image-was-too-large) below


[​](#image-was-too-large)

Image was too large

A pasted or attached image exceeds the API’s size or dimension limits.

```python
Image was too large. Double press esc to go back and try again with a smaller image.
API Error: 400 ... image dimensions exceed max allowed size
API Error: an image in the conversation could not be processed and was removed.
```

The `could not be processed and was removed` line means the API refused an image in the conversation, such as one over the size or dimension limits. If one of these errors keeps coming back, update Claude Code. On older versions, an image error could repeat for reasons such as these:

- Before v2.1.299, in a long conversation with many images, Claude Code could remove the images you attached last instead of the one over the limit. The `was removed` line then repeated on every turn, and Claude didn’t see your new images.
- Before v2.1.299, in VS Code, the Desktop app, and the Agent SDK, images you attached while Claude was working didn’t get the resizing that other attached images get. They reached the API at their original size, which led to repeated image errors in long conversations.
- Before v2.1.166, a pasted image could remain in the conversation, and the same error then repeated on every subsequent message

**What to do:**

- Resize the image before pasting. The API accepts images up to 8000 pixels on the longest edge for a single image, or 3000 pixels when more than 20 images are in context.
- Take a tighter screenshot of the relevant region instead of the full screen


[​](#unable-to-resize-image)

Unable to resize image

Claude Code couldn’t downscale an attached image before sending it to the API.

```python
Unable to resize image — image processing is unavailable and dimensions could not be read from the file header. Please convert the image to PNG, JPEG, GIF, or WebP.
Unable to resize image — dimensions exceed the 2000x2000px limit and image processing failed. Please resize the image to reduce its pixel dimensions.
Unable to resize image (… raw, … base64). The image exceeds the … API limit and compression failed. Please resize the image manually or use a smaller image.
Unable to resize image — could not verify image dimensions are within the 2000x2000px API limit.
Unable to resize image — it is a CMYK JPEG, which Claude Code cannot decode, and at …px it is over the 2000x2000px limit, so it cannot be sent. Re-save it as an RGB PNG or JPEG and try again.
Unable to resize image — it is an animated WebP whose first frame Claude Code cannot decode, and at …px it is over the 2000x2000px limit, so it cannot be sent. Save its first frame as a PNG or JPEG and try again.
Unable to resize image — its pixels could not be decoded (the file may be damaged, or use an encoding Claude Code cannot read), and it is over the … API limit (… raw, … base64), so it cannot be sent. Re-save it as a PNG or JPEG and try again.
```

Claude Code normally resizes large images automatically. These errors mean the image couldn’t be decoded or resized to fit within the API limits. **What to do:**

- 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.
- If the message reports a dimension or size limit, resize or recompress the image below that limit before attaching.
- If the message names a cause, such as a CMYK JPEG, an animated WebP, or a possibly damaged file, re-save the image in the format the message suggests and attach it again.


[​](#request-rejected-as-unprocessable-by-the-model)

Request rejected as unprocessable by the model

The API refused the request as one the model can’t process. The message is the API’s own.

```python
API Error: 400 Request rejected as unprocessable by the model (too many or oversized images, or unsupported parameters)
```

Claude Code can remove the oldest images and documents from a refused request and send it again. Before v2.1.290, Claude Code didn’t remove images on this refusal, so a long session that accumulated hundreds of them could fail with this error on every turn. **What to do:**

- If the message keeps appearing in a conversation with images or documents, remove them yourself. Press Esc twice to step back past the turns that added them, or run `/clear` to start fresh.


[​](#pdf-errors)

PDF errors

The PDF you attached couldn’t be processed. The messages are shown here in their non-interactive form; in an interactive session they instead prompt you to double press esc and try again.

```python
PDF too large (max 100 pages, 20MB). Try reading the file a different way (e.g., extract text with pdftotext).
PDF is password protected. Try using a CLI tool to extract or convert the PDF.
The PDF file was not valid. Try converting it to text first (e.g., pdftotext).
```

**What to do:**

- For oversized PDFs, ask Claude to read a page range with the Read tool instead of attaching the whole file, or extract text with a tool like `pdftotext` and reference the output file by path
- For protected or invalid PDFs, remove the password or re-export the file from its source application, then try again

When Claude reads a page range from a PDF with the Read tool, the read can fail with a different message:

```python
pdftoppm is not installed. Install poppler-utils (e.g. `brew install poppler` or `apt-get install poppler-utils`) to enable PDF page rendering.
```

Page-range reads render pages with `pdftoppm`. Install poppler-utils with the command the message gives, or on other platforms a poppler build that puts `pdftoppm` on your `PATH`. See [Read tool behavior](tools-reference.md#read-tool-behavior) for which PDFs are read by page range.


[​](#extra-inputs-are-not-permitted)

Extra inputs are not permitted

The endpoint that received the request rejected one of the request’s fields as an input it doesn’t accept, and the endpoint’s message names that field.

```python
API Error: 400 ... context_management: Extra inputs are not permitted
```

Claude Code sends beta-only fields such as `context_management` and tool search’s `defer_loading` alongside an `anthropic-beta` header that enables them. When a gateway forwards the body but drops the header, the API sees fields it doesn’t recognize. When a gateway forwards an Anthropic-format body to an upstream with a different schema, that upstream rejects such fields. [Beta header and body field pairs](../13-Enterprise-Admin/llm-gateway-protocol.md#beta-header-and-body-field-pairs) covers both cases. **What to do:**

- If the message contains `context_management: Extra inputs are not permitted`, [update Claude Code](../01-Getting-Started/setup.md#update-claude-code) to v2.1.304 or later. After you update, Claude Code answers this rejection by sending the request once more without the field. Before v2.1.304, Claude Code didn’t retry this rejection.
- If the message names `defer_loading` or `tool_reference`, update Claude Code or turn [tool search](../06-MCP-Tools/General/mcp.md#tool-search-through-a-gateway) off:
  - [Update Claude Code](../01-Getting-Started/setup.md#update-claude-code) to v2.1.305 or later. Claude Code then answers this rejection by sending the request once more without tool search fields.
  - If you can’t update, or the message still appears after you do, set `ENABLE_TOOL_SEARCH=false` in your shell or your [settings `env`](settings-reference.md#env). If a settings file already sets the variable, change it there, since that value [can override a shell export](settings-reference.md#how-env-values-interact-with-your-shell). Claude Code then loads MCP tools upfront.
- If your gateway drops the header, configure it to forward the `anthropic-beta` header. See [feature pass-through](../13-Enterprise-Admin/llm-gateway-protocol.md#feature-pass-through) for what gateways must forward.
- As a fallback, set [`CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1`](env-vars.md) before launching. [Disable pre-release capabilities](../13-Enterprise-Admin/llm-gateway-protocol.md#disable-pre-release-capabilities) covers the exact scope.

Before v2.1.302, this error could also name the field `diagnostics` with no gateway involved. It appeared when a session that had already used the Anthropic API moved to Amazon Bedrock or Google Cloud’s Agent Platform without a restart. For example, a session you left open moves to Bedrock when you run [`/setup-bedrock`](commands.md) in another Claude Code window. On those versions, run `/clear` in that session or restart it.


[​](#tool-input-schema-is-invalid)

Tool input schema is invalid

A tool in the request declared an `input_schema` that fails the API’s JSON Schema validation, so the API rejected the whole request. The number after `tools.` is the failing tool’s position in the request’s tool list, not a name you can look up.

```python
API Error: 400 ... tools.N.custom.input_schema: JSON schema is invalid
API Error: 400 ... tools.N.custom.input_schema.properties: Property keys should match pattern '^[a-zA-Z0-9_.-]{1,64}$'
```

The first form means the schema isn’t valid JSON Schema draft 2020-12. The second means a top-level property name doesn’t match the pattern the message quotes. Claude Code [excludes MCP tools whose input schema would fail this validation](../06-MCP-Tools/General/mcp.md#tools-with-invalid-input-schemas) when it loads a server’s tools, so requests normally never include one. On a [deployment where flag fetching is off](env-vars.md#features-that-need-feature-flag-fetching), or on a machine whose flags have never arrived, Claude Code records in the server’s log which tool would be rejected but sends it anyway, so this error can still occur. The error can also occur for a tool whose schema declares a JSON Schema dialect other than draft 2020-12 in `$schema`. Claude Code doesn’t check those schemas against the JSON Schema meta-schema, though the top-level property-name check still applies. Before v2.1.216, no deployment ran the exclusion checks. **What to do:**

- If your Claude Code version is earlier than v2.1.216, run `claude update`.
- Remove or [disable](../06-MCP-Tools/General/mcp.md#disable-a-server-without-removing-it) the MCP server that declares the invalid schema. The error names the tool only by position. On v2.1.216 or later, check each server’s log for a line naming a tool whose input schema would be rejected. If no log names one, disable servers one at a time.
- If you maintain the server, fix the tool’s `input_schema`. The schema must be valid JSON Schema, and top-level property names must be 1 to 64 characters long and use only ASCII letters and digits, `_`, `.`, and `-`. See [Tools with invalid input schemas](../06-MCP-Tools/General/mcp.md#tools-with-invalid-input-schemas).


[​](#mcp-tool-name-over-128-characters)

MCP tool name over 128 characters

An MCP server lists a tool whose full name, such as `mcp__<server>__<tool>`, is longer than the 128 characters the API accepts. Claude Code [leaves that tool out of the tools it sends to Claude](../06-MCP-Tools/General/mcp.md#tools-with-names-longer-than-128-characters), and the server’s other tools keep working. In a session you start with `claude --debug` from your shell, Claude Code writes this message to the debug log at `~/.claude/debug/<session-id>.txt`:

```python
Tool "mcp__<server>__<tool>" is not sent to Claude: its name has <N> characters and the API accepts at most 128
```

**What to do:**

- If you maintain the server, shorten the tool’s name.
- If the server is in your [MCP configuration](../06-MCP-Tools/General/mcp.md#mcp-installation-scopes), give it a shorter name there, such as `db` in place of `analytics-database`. Then update what refers to the server or its tools by the old name, such as [permission rules](permissions.md#mcp) and [hook matchers](../07-Hooks/hooks.md#match-mcp-tools).
- If a [plugin bundles the server](../06-MCP-Tools/General/mcp.md#plugin-provided-mcp-servers), the tool’s full name also includes the plugin name. Ask the plugin’s maintainer to shorten the server or tool name.

Before v2.1.292, Claude Code sent the tool anyway, and the API rejected every request that included it with `API Error: 400 ... tools.N.custom.name: String should have at most 128 characters`.


[​](#tool-use-name-over-200-characters)

tool_use.name over 200 characters

A tool call in the conversation history carries a name longer than the 200 characters the API accepts in a request:

```python
API Error: 400 ... tool_use.name: String should have at most 200 characters
```

Claude Code cuts such a name to 200 characters when the response arrives and when it loads a saved conversation, so the call fails with a [`No such tool available`](#no-such-tool-available) tool error and the conversation continues without this API error. **What to do:**

- Run `claude update`, then resume the conversation. The updated version repairs the overlong name when it loads the transcript, so a conversation that was stuck works again.

Before v2.1.281, the overlong name stayed in the history and the API rejected every request that re-sent the conversation, including `/compact` and `--resume`, so this error repeated and the conversation was stuck.


[​](#theres-an-issue-with-the-selected-model)

There’s an issue with the selected model

The configured model name was not recognized or your account lacks access to it. As of v2.1.160 the trailing hint, shown here in its interactive form, varies by surface.

```python
There's an issue with the selected model (claude-...). It may not exist or you may not have access to it. Run /model to pick a different model.
```

**What to do:**

- **Interactive CLI**: run `/model` to pick from models available to your account.
- **Non-interactive mode (`-p`)**: pass `--model` with a valid alias or ID, or set [`ANTHROPIC_MODEL`](env-vars.md). The error text shows `Run --model` on this surface.
- **Agent SDK**: the error text omits the hint because the model is set programmatically. Set [`model` on `Options`](../05-Agent-SDK/agent-sdk-typescript.md#options) in TypeScript or [`ClaudeAgentOptions(model=...)`](../05-Agent-SDK/agent-sdk-python.md#claudeagentoptions) in Python, and handle the structured `model_not_found` error to surface your own retry or model picker.
- Use an alias such as `sonnet` or `opus` instead of a full versioned ID. Aliases resolve to a maintained default so they don’t go stale. See [Model configuration](model-config.md).
- If the wrong model keeps coming back in the CLI, a stale ID is set somewhere. Check the places you can set a model in [priority order](model-config.md#setting-your-model) and remove the stale value.
- Claude Code reports an expired claude.ai login as [Login expired](#login-expired), not as this error. Before v2.1.206, an expired login that could no longer be refreshed failed every model with this error; run `/login` if you see that on an older version.
- If [`ANTHROPIC_BASE_URL`](env-vars.md) points at an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) and every model fails this way, check whether your gateway is rejecting the tool search fields Claude Code sends by default. To check, set `ENABLE_TOOL_SEARCH=false` as [Tool search through an LLM gateway](../06-MCP-Tools/General/mcp.md#tool-search-through-a-gateway) describes, then try again. Before v2.1.304, tool search was off behind a gateway unless you turned it on with `ENABLE_TOOL_SEARCH`.
- For Google Cloud’s Agent Platform deployments, see [Google Cloud’s Agent Platform troubleshooting](google-vertex-ai.md#troubleshooting).


[​](#model-is-not-a-recognized-model-id)

Model is not a recognized model id

The string you passed to a model switch isn’t one Claude Code can use as a model, so it refused the switch without sending a request and the session keeps its current model. You can get this error when a model is set through the [Agent SDK](../05-Agent-SDK/agent-sdk-typescript.md) `setModel()` method, by an app that runs the Claude Code CLI for you, such as the [Desktop app](../16-Mobile-Desktop/desktop.md), or when you pick a model from a device connected through [Remote Control](remote-control.md). Before v2.1.200, Claude Code saved the string and failed on the next request with [There’s an issue with the selected model](#theres-an-issue-with-the-selected-model).

```python
Model "Sonnet5" is not a recognized model id. Did you mean 'claude-sonnet-5'?
```

In this example an app sent the display name `Sonnet 5`, which the message repeats without its space. The trailing hint names the closest matching alias or model ID. When nothing is close enough, it reads `Run /model to see available models.` instead. In a session that the [Desktop app](../16-Mobile-Desktop/desktop.md) starts for you, the no-match hint reads `Switch to a different model.` When you switch through the Agent SDK or an app on the Anthropic API, only a string that can’t be a model ID gets this error, such as a display name or an empty string. When you pick a model from a Remote Control device, Claude Code checks the string locally. Any string that isn’t a model alias, a model Claude Code lists or you configured, or an ID that starts with `claude-` gets this error, a mistyped ID such as `claud-sonnet-5` included. Before v2.1.260, this check didn’t cover Remote Control picks, so an unrecognized string was applied and failed on the next request. **What to do:**

- Run `/model` with no argument to open the picker and choose from the models available to your account, then pass the alias or ID shown there
- If you used an alias that only a newer Claude Code version supports, run `claude update`, or pass the model’s full ID instead. The server can still require a minimum Claude Code version for that model; see [Claude Code does not support this model](#claude-code-does-not-support-this-model).
- A model saved before v2.1.200 isn’t repaired by this check. If a stale value keeps coming back, remove it from the locations listed under [Setting your model](model-config.md#setting-your-model).
- On any provider other than the Anthropic API, or behind a gateway or custom `ANTHROPIC_BASE_URL`, only an empty string gets this error. Claude Code can still write the [unrecognized-model diagnostic line](#unrecognized-model-id-on-a-request) at request time, on every provider.


[​](#model-not-found)

Model not found

You switched to a model by name and Claude Code couldn’t confirm that a model with that name exists. When the name isn’t a [model alias](model-config.md#model-aliases) or another spelling Claude Code accepts locally, Claude Code verifies it with a minimal API request, and this error is usually your API endpoint’s answer. With `/model <name>`, a name that can’t be a model ID at all, such as one containing spaces, gets the same message.

```python
Model 'claude-opus-9' not found
```

On providers with provider-specific model IDs, the message may add a `Try '...' instead` suggestion that names your provider’s ID for a fallback model. **What to do:**

- Run `/model` with no argument and pick from the models available to your account, or use a [model alias](model-config.md#model-aliases) such as `sonnet`, which resolves to a maintained default
- If you typed a full ID, check it against your provider’s model catalog. A newly launched model can be available on the Anthropic API before your provider or region offers it.
- In the Agent SDK, `setModel()` fails with this message and the session keeps running on its previous model. In the TypeScript SDK, call [`supportedModels()`](../05-Agent-SDK/agent-sdk-typescript.md#query-object) to list the models you can switch to.
- Before v2.1.265, `/model` also rejected the `opusplan[1m]` alias spelling with this error. On those versions, update Claude Code, or set the model in [settings](model-config.md#setting-your-model) or with `--model` instead.


[​](#couldnt-confirm-model-with-the-api)

Couldn’t confirm model with the API

You switched models through the [Agent SDK](../05-Agent-SDK/agent-sdk-typescript.md) `setModel()` method or an app that runs the Claude Code CLI for you, such as the [Desktop app](../16-Mobile-Desktop/desktop.md), and the request that confirms the model ID with your API endpoint got no answer within 15 seconds. The session keeps its current model.

```python
Couldn't confirm model "claude-sonnet-5" with the API. Try again, or run /model to see available models.
```

In a session that the [Desktop app](../16-Mobile-Desktop/desktop.md) starts for you, the message ends at `Try again.` **What to do:**

- Switch to the model again
- If the switch keeps failing, check that Claude Code can reach your API endpoint; see [Network and connection errors](#network-and-connection-errors)


[​](#api-error-model-not-changed)

API error when checking the picked model

You picked a model with `/model <name>`, or an app connected to the session requested the switch. The API refused the minimal request Claude Code sends to verify the model, for a reason that has no entry of its own, such as a rate limit or a server error. The session keeps its current model, and the message ends by saying so:

```python
API error: 429 <the server's explanation> · model not changed
```

The middle of the message is the HTTP status and the server’s own explanation. **What to do:**

- Act on the server’s explanation; for a rate limit or a 5xx status, wait and pick the model again
- The refusals with their own wording are covered by the surrounding entries, such as [Model not found](#model-not-found) and [Model is restricted by your organization’s settings](#model-is-restricted-by-your-organizations-settings)


[​](#claude-opus-is-not-available-with-the-claude-pro-plan)

Claude Opus is not available with the Claude Pro plan

Your active subscription plan does not include the model you selected.

```python
Claude Opus is not available with the Claude Pro plan. If you have updated your subscription plan recently, run /logout and /login for the plan to take effect.
```

In a session the Claude Desktop app runs, the message says to `sign out and sign in again` instead of naming the commands. **What to do:**

- Run `/model` and select a model your plan includes
- If you upgraded your plan recently and still see this, run `/logout` then `/login`. The stored token reflects your plan at the time you signed in, so upgrading on claude.ai does not take effect in an existing session until you re-authenticate.
- See [claude.com/pricing](../17-Billing-Plans/pricing.md) for which models each plan includes


[​](#claude-code-does-not-support-this-model)

Claude Code does not support this model

The API refused the request with a 400 because your Claude Code version is below a required minimum. Either the model you selected requires a newer version, which the server checks per model, or your organization’s policy requires one. The 400 carries the error code `claude_code_version_too_old`, and the message says which minimum applies.

```python
API Error: 400 Claude Code 2.1.219 does not support this model; version 2.1.255 or newer is required. Run 'claude update', or update the Claude desktop app, then try again.
```

The organization-policy wording reads:

```python
API Error: 400 Claude Code 2.1.240 is older than the minimum version required by your organization's policy. Run 'claude update', or update the Claude desktop app, to continue.
```

The version the API checks is the one reported by the Claude Code binary that made the request. **What to do:** Update that binary, then start a new session. Where the binary came from decides how, except in a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments-deploy.md#pin-the-version):

| The binary that made the request                             | How to update it                                                                                                                                                                                                            |
|:-------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| A Claude Code you installed                                  | Run `claude update`                                                                                                                                                                                                         |
| The Claude desktop app                                       | Update the app                                                                                                                                                                                                              |
| The binary the [VS Code extension](../03-IDE-Integrations/vs-code.md) bundles | Update the extension                                                                                                                                                                                                        |
| The binary an Agent SDK package bundles                      | [Upgrade the SDK package](../05-Agent-SDK/agent-sdk-hosting.md#runtime-dependencies), then restart your application. In a [compiled single-file executable](../05-Agent-SDK/agent-sdk-typescript.md#compile-to-a-single-executable), rebuild it |

- If you run `claude update` on the [stable release channel](../01-Getting-Started/setup.md#configure-release-channel), it doesn’t move you past the newest stable release, which can still be below the required minimum. Move to the latest channel, then update again. If your organization pins your channel or version through [managed settings](../13-Enterprise-Admin/managed-settings.md), ask your admin to change it
- For the per-model wording, you can keep working in the current session by switching to another model: run `/model` in the CLI, call [`setModel()`](../05-Agent-SDK/agent-sdk-typescript.md#query-object) on the TypeScript SDK’s `Query` object in streaming input mode, or call [`set_model()`](../05-Agent-SDK/agent-sdk-python.md#claudesdkclient) on the Python SDK’s `ClaudeSDKClient`
- For the organization-policy wording, update before you continue


[​](#model-is-restricted-by-your-organizations-settings)

Model is restricted by your organization’s settings

Your organization admin has disabled this model in the claude.ai admin console, or managed settings exclude it through an [`availableModels`](model-config.md#restrict-model-selection) allowlist or a [`deniedModels`](model-config.md#block-specific-models-or-versions) list. The notice appears at startup when `--model`, `ANTHROPIC_MODEL`, or the `model` setting named the restricted model, and it names the model the session uses instead. If managed settings leave no permitted model for the session to use, see [Managed settings block the default model](#managed-settings-block-the-default-model). The substitution notice can also appear mid-session after an admin disables the model a session is running on in the claude.ai admin console.

```python
Model "claude-opus-4-8" is restricted by your organization's settings. Using claude-sonnet-4-6 instead.
```

Typing `/model <name>` for a restricted model is rejected and the session keeps its current model. For a model disabled in the admin console, the rejection reads `Model '<name>' is restricted by your organization's settings. Run /model to choose a different model.` For a model that managed settings exclude, it reads `Model '<name>' is not available. Your organization restricts model selection.` A notice prefixed with an agent, skill, or command name means the restriction applied to that [subagent’s requested model](../09-Agents-Patterns/sub-agents.md#choose-a-model): the subagent runs on the substituted model and your session’s model is unchanged. Before v2.1.223, Claude Code showed the notice only for subagents launched with the Agent tool. Claude Code treats a model family alias, one of `opus`, `sonnet`, `haiku`, or `fable`, as a request for that family rather than for its newest version. On the Anthropic API and on [Claude Platform on AWS](claude-platform-on-aws.md), a restricted family alias resolves to the newest version of the family that your organization’s settings permit, and the substitution notice names that version. Claude Code rejects `/model <alias>` only when every version of the family is restricted. Before v2.1.205, a family alias was substituted or rejected based on its newest version alone, even when an older version of the same family was allowed. **What to do:**

- Run `/model` to pick from the models your organization allows. Restricted models are hidden from the picker.
- If the restricted model was set in `--model`, `ANTHROPIC_MODEL`, the `model` field of a settings file, or the `model` frontmatter of a [subagent](../09-Agents-Patterns/sub-agents.md#choose-a-model), skill, or command, remove or update that value so the notice doesn’t recur
- If you need access to the restricted model, ask your organization admin to enable it. See [Organization model restrictions](model-config.md#organization-model-restrictions).


[​](#cant-switch-to-the-default-model)

Can’t switch to the default model

You picked the Default model, for example by selecting the Default row in the `/model` picker or typing `/model default`. Claude Code refused the switch, so the session keeps its current model.

```python
Can't switch to the default model: your organization's managed settings block it (claude-opus-4-6) in "deniedModels", and none of the models they allow can be used as the default instead. Ask your administrator to update "deniedModels" or "availableModels".
```

The wording after the colon names what blocked the switch:

- **`your organization's managed settings block it ... in "deniedModels"`**: a managed deny list blocks the model the Default option resolves to
- **`your organization allows only the models listed in "availableModels"`**: a managed [`availableModels`](model-config.md#restrict-model-selection) allowlist with [`availableModelsMatch`](settings-reference.md#availablemodelsmatch) set to `"exact"` leaves out the model the Default option resolves to
- **`Claude Code couldn't read your organization's managed settings to check which models they allow`**: the [managed settings](../13-Enterprise-Admin/managed-settings.md) couldn’t be read, and Claude Code refuses the switch rather than apply it unchecked

**What to do:**

- For the [`deniedModels`](settings-reference.md#deniedmodels) and `availableModels` wordings, run `/model` and pick a model your organization allows by name
- Ask your administrator to update the managed setting the message names
- For the `couldn't read` wording, restart Claude Code; if it keeps happening, ask your administrator to check the managed settings

If a session instead fails to start with a `Claude Code can't start` message under these managed settings, see [Managed settings block the default model](#managed-settings-block-the-default-model).


[​](#model-switch-was-blocked-by-a-premodelswitch-hook)

Model switch was blocked by a PreModelSwitch hook

A [PreModelSwitch hook](../07-Hooks/hooks.md#premodelswitch) didn’t approve the model switch you or a client requested, so the session keeps its current model. When the switch came from an [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) host or [Remote Control](remote-control.md) rather than a command you typed, the message reads `Model switch blocked by a PreModelSwitch hook` without naming the target model.

```python
Model switch to Opus 4.6 was blocked by a PreModelSwitch hook: Opus 4.6 is retired for this project. Use a newer model.
```

The reason after the colon says what refused the switch:

- **A reason a hook wrote**: a PreModelSwitch hook supplied that reason when it [denied the switch or asked for confirmation](../07-Hooks/hooks.md#premodelswitch-decision-control). Address what it asks, or pick a model your hooks allow.
- **`PreModelSwitch hook <name> did not respond before its timeout`**: a hook that doesn’t answer before its [timeout](../07-Hooks/hooks.md#timeouts) blocks the switch. Fix the hanging command or raise that hook’s `timeout`, then switch again.
- **`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](headless.md) 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.
- **`so organization-managed PreModelSwitch hooks could not be checked`**: Claude Code couldn’t tell which PreModelSwitch hooks your organization’s [managed plugins](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.
- **`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.

Before 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.


[​](#couldnt-save-it-as-your-default)

Couldn’t save it as your default

You picked a model to save as your default, for example with `/model <name>` or `Enter` in the `/model` picker, and Claude Code couldn’t write the pick to your user settings file, `~/.claude/settings.json`. The switch itself applied, so the current session runs on the model you picked, but your default is unchanged and the next session starts on the old value.

```python
Set model to Fable 5.1 for this session only · couldn't save it as your default: ~/.claude/settings.json can't be written (EROFS)
```

The reason after the file path says what failed:

- **`can't be written (<code>)`**: the write failed with the operating system error code in parentheses, such as `EROFS` when the file, or the file it links to, sits on a filesystem that refuses writes. Make the file writable and switch again. If another tool generates the file, set the `model` key in that tool instead; see [A change you made in Claude Code is lost in new sessions](settings.md#a-change-you-made-in-claude-code-is-lost-in-new-sessions).
- **`isn't valid JSON`**: the file on disk doesn’t parse, and Claude Code leaves it untouched rather than overwrite content it can’t read back. Fix the syntax error, then switch again; see [Fix a broken settings file](settings.md#fix-a-broken-settings-file).

A notice ending `couldn't confirm it was saved as your default (~/.claude/settings.json is still being written)` means the write hadn’t finished after three seconds. It continues in the background, so the default may still be saved; check which model your next session starts on, or run `/model <name>` again. Before v2.1.265, the notice said the model was `saved as your default for new sessions` even when the write failed.


[​](#advisor-is-less-capable-than-the-current-main-model)

Advisor is less capable than the current main model

Your [advisor model](advisor.md) ranks below your session’s main model, so Claude Code keeps the selection but doesn’t attach the advisor to the main model’s requests.

```python
Advisor set to Opus 4.8
Note: Opus 4.8 is less capable than the current main model (Sonnet 5.5), so the advisor will not activate. Choose a more capable advisor, or switch to a smaller main model.
```

Other messages report the same condition:

- In an interactive session, a notification reads `Advisor will not activate on the main model (advisor is less capable); subagents may still use it and may use more tokens · /advisor`.
- When you launch with the `--advisor` flag in [non-interactive mode](headless.md), and the run isn’t a [background session](../09-Agents-Patterns/agent-view.md), a warning goes to stderr and the run starts anyway. It reads `"<advisor>" cannot advise "<main model>" (the advisor must be at least as capable as the main model). The advisor will not be used for the main model.` An interactive session writes that warning only to the [debug log](#configuration-warnings).

**What to do:**

- Choose a higher-ranked advisor or a lower-ranked main model. [Choose an advisor model](advisor.md#choose-an-advisor-model) shows the ranking and lists the accepted advisors for each main model.
- Leave the advisor set if you want [subagents](../09-Agents-Patterns/sub-agents.md) whose model it can advise to keep using it

Before v2.1.287, Claude Code ranked several pairings differently. It showed this note for a Sonnet 5.5 advisor with an Opus 4.7 or Opus 4.8 main model, a pairing it now accepts. It also attached some advisors that now produce this note, such as an Opus 4.8 advisor with a Sonnet 5.5 main model.


[​](#thinking-type-enabled-is-not-supported-for-this-model)

thinking.type.enabled is not supported for this model

Your Claude Code version is older than the minimum for the selected model. The CLI sent a thinking configuration the model no longer accepts.

```python
API Error: 400 ... "thinking.type.enabled" is not supported for this model. Use "thinking.type.adaptive" and "output_config.effort" to control thinking behavior.
```

**What to do:**

- Run `claude update` and restart Claude Code. Opus 4.7 needs v2.1.111 or later. Opus 4.8 needs v2.1.154 or later. Sonnet 5 needs v2.1.197 or later. Opus 5 needs v2.1.219 or later. Opus 5.5 needs v2.1.280 or later. Sonnet 5.5 needs v2.1.284 or later
- On the [stable release channel](../01-Getting-Started/setup.md#configure-release-channel), updating doesn’t move you past the newest stable release, which can still be older than these versions. Move to the latest channel, then update
- If you can’t upgrade, run `/model` and select Opus 4.6 or Sonnet 4.6 instead
- If you hit this in the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md), upgrade the SDK package instead. Opus 4.8 needs TypeScript SDK v0.3.154 or later and Python SDK v0.2.88 or later. Sonnet 5 needs TypeScript SDK v0.3.197 or later. Opus 5 needs TypeScript SDK v0.3.219 or later. Opus 5.5 needs TypeScript SDK v0.3.280 or later. Sonnet 5.5 needs TypeScript SDK v0.3.284 or later


[​](#effort-isnt-available-with-thinking-turned-off)

Effort isn’t available with thinking turned off

You turned [extended thinking](model-config.md#extended-thinking) off and ran at an [effort level](model-config.md#adjust-effort-level) above `high`. The model doesn’t accept that combination, so the API rejected the request.

```python
API Error: Effort 'xhigh' isn't available with thinking turned off on this model · run /effort high to continue, or turn thinking back on (unset MAX_THINKING_TOKENS=0)
```

The hint after the `·` varies by session: in a non-interactive session it reads `use --effort high (or the effortLevel setting)`, and in a session the Claude Desktop app runs it reads `you can lower effort to High`. **What to do:**

- [Lower the effort level](model-config.md#set-the-effort-level) to `high` or below.
- Turn thinking back on, for example by unsetting [`MAX_THINKING_TOKENS`](env-vars.md) or removing [`"alwaysThinkingEnabled": false`](settings-reference.md#alwaysthinkingenabled) from your settings.

Before v2.1.242, Claude Code showed the API’s own message: `API Error: 400 output_config.effort 'xhigh' is not supported when thinking is disabled on this model. Use effort 'high' or below, or enable thinking.` Before v2.1.251, Claude Code sent the request at the effort level you set, so Opus 5 rejected every request above `high` with thinking turned off. Claude Code now sends effort `high` instead to models it knows reject the combination, such as Opus 5.


[​](#thinking-budget-exceeds-output-limit)

Thinking budget exceeds output limit

The configured extended thinking budget exceeds the maximum response length, so there is no room left for the actual answer.

```python
API Error: 400 ... max_tokens must be greater than thinking.budget_tokens
```

**What to do:**

- Raise [`CLAUDE_CODE_MAX_OUTPUT_TOKENS`](env-vars.md) above the thinking budget
- See [Extended thinking](model-config.md#extended-thinking) for how the budget interacts with output length


[​](#response-exceeded-the-output-token-maximum)

Response exceeded the output token maximum

Claude’s reply reached the largest number of output tokens the request allowed and was cut off there:

```python
API Error: Claude's response exceeded the ... output token maximum. To configure this behavior, set the CLAUDE_CODE_MAX_OUTPUT_TOKENS environment variable.
API Error: Claude's response exceeded the 64000 output token maximum for a request sent without streaming. The CLAUDE_CODE_MAX_OUTPUT_TOKENS environment variable cannot raise this limit.
```

The form that names `a request sent without streaming` means a streaming request failed and Claude Code re-sent it without streaming, which limits the reply to 64,000 output tokens. Before v2.1.299, a reply cut off on such a re-sent request ended the turn without this message, as if the reply were complete. **What to do:**

- If Claude wrote some text before the reply was cut off, reply `continue` in an interactive session to ask for the rest. That text stays in the conversation.
- If the message says to set `CLAUDE_CODE_MAX_OUTPUT_TOKENS`, see [`CLAUDE_CODE_MAX_OUTPUT_TOKENS`](env-vars.md) for how the value is capped and [Set environment variables](env-vars.md#set-environment-variables) for where to set it
- To keep each reply under the limit, ask Claude for the output in smaller pieces, such as one file or one section per reply


[​](#tool-use-or-thinking-block-mismatch)

Tool use or thinking block mismatch

The conversation history reached the API in an inconsistent state.

```python
API Error: 400 due to tool use concurrency issues. Run /rewind to recover the conversation.
API Error: 400 orphaned tool_result in conversation history. Run /rewind to recover the conversation.
API Error: 400 duplicate tool_use ID in conversation history. Run /rewind to recover the conversation.
API Error: 400 ... unexpected `tool_use_id` found in `tool_result` blocks
API Error: 400 ... thinking blocks ... cannot be modified
```

All variants mean the same thing: the sequence of `tool_use`, `tool_result`, and `thinking` blocks in history no longer matches what the API expects. **What to do:**

- If you are using Opus 4.7 or Opus 4.8, run `claude update` first. Versions before v2.1.156 can trigger this error during normal tool use, and `/rewind` doesn’t clear it.
- Run `/rewind`, or press Esc twice, to step back to a checkpoint before the corrupted turn and continue from there. See [Checkpointing](checkpointing.md) for how checkpoints are created and restored.


[​](#invalid-data-in-redacted-thinking-block)

Invalid data in redacted_thinking block

The API refused the request with a 400 because it couldn’t accept a `redacted_thinking` block that an earlier turn in the conversation history carries.

```python
API Error: 400 ... Invalid `data` in `redacted_thinking` block
```

Claude Code leaves the conversation’s earlier thinking out of the request and retries once, so the session continues without showing the error. Before v2.1.282, Claude Code kept the refused block, and every later turn failed with the same error. **What to do:**

- If you’re on v2.1.281 or earlier and every turn fails with this error, run `claude update` and resume the session
- If the error persists, run `/clear` to start a conversation that doesn’t carry the block


[​](#unsupported-tool-content-removed)

Unsupported tool content removed

When Claude Code connects directly to the Anthropic API and loads or previews a saved session, it removes tool content the Anthropic API doesn’t accept and leaves this line where removed content sat between two thinking blocks:

```python
[Unsupported tool content removed]
```

Such content reaches a session file when something other than the Anthropic API answered in the API’s format, typically a third-party proxy set through [`ANTHROPIC_BASE_URL`](env-vars.md) that translates another provider’s tool calls. Claude Code removes it only when the session connects directly to the Anthropic API, and loads the saved history as it is when the session runs through a proxy or on another provider. Before v2.1.246, Claude Code sent the tool use and its result back to the API, and every turn of the resumed session failed with a 400 error such as `messages.1.content.0.server_tool_use.name: Input should be 'web_search', 'web_fetch', ...`. **What to do:**

- None needed when you see the placeholder line. The session continues without the removed content.
- If every turn of a resumed session fails with the 400 error instead, run `claude update` and resume the session again. Versions before v2.1.246 don’t remove the content.


[​](#role-system-must-precede-an-assistant-message)

role ‘system’ must precede an ‘assistant’ message

The API refused the request with a 400 because a system message sits at a position in the conversation it doesn’t accept:

```python
API Error: 400 messages.6: role 'system' must precede an 'assistant' message or end the array; ...
```

Claude Code sends some of its reminder and attachment text as system messages inside the conversation. When the API refuses one’s position, Claude Code retries the request once with that text sent as ordinary user messages instead. The API’s sibling placement wordings, such as `use the top-level 'system' parameter for the initial system prompt`, get the same recovery. When the error does appear, the refused system message isn’t one Claude Code can remove. That usually means a proxy or [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) between Claude Code and the API added a system message of its own. **What to do:**

- If the error repeats on every turn behind a proxy or gateway configured through [`ANTHROPIC_BASE_URL`](env-vars.md), connect without the proxy to confirm the source, and report the error to whoever operates it
- Run `/clear` to start a fresh conversation. If the error returns there too, the cause is on the request path, not in the saved conversation.

Before v2.1.280, Claude Code didn’t recognize this wording, so the error also appeared when the refused system message was one Claude Code itself sent, and every later turn of the conversation failed the same way.


[​](#invalid-encrypted-content-in-search-result-block)

Invalid encrypted_content in search_result block

The API refused the request with a 400 because the conversation history holds hosted web-search content it can’t decrypt. The wording names the field it can’t read:

```python
API Error: 400 ... Invalid `encrypted_content` in `search_result` block
API Error: 400 ... Invalid `encrypted_index` in `text` block
API Error: 400 ... Failed to decrypt web search result content
API Error: 400 ... Invalid `encrypted_stdout` in `encrypted_code_execution_result` block
```

Results from the API’s hosted [web search tool](../04-API-Reference/Agents-Tools/agents-and-tools-tool-use-web-search-tool.md) carry encrypted fields that only the API can read. The `encrypted_stdout` wording names the output of a hosted code execution program that read such results, which the API encrypts as well. The API refuses a request that replays content it can’t decrypt, such as content produced for a different organization. Claude Code’s own [WebSearch tool](tools-reference.md#websearch-tool-behavior) records search results as plain text, so these blocks usually reach a conversation through a proxy or [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) that ran hosted web search itself. For the three web search wordings, Claude Code leaves the search calls, results, and citations out of what it sends and retries the request once, so the session continues without showing the error. The `encrypted_stdout` wording has no such recovery, so that message still reaches you. Before v2.1.282, Claude Code kept the refused web search blocks too, and every later turn and `/compact` failed the same way. **What to do:**

- If you’re on v2.1.281 or earlier and every turn fails with one of the web search wordings, run `claude update` and resume the session
- If the error persists, or the message names `encrypted_stdout`, run `/rewind` to step back to a checkpoint before the turn that added the content, or run `/clear` to start a conversation that doesn’t carry it
- If you run Claude Code behind a proxy or gateway, report the error to whoever operates it


[​](#usage-policy-refusal)

Usage Policy refusal

The API declined to respond because content in the conversation triggered a [Usage Policy](https://www.anthropic.com/legal/aup) check. If the message includes the line `` Details: `[reasoning_extraction]` ``, see [Safeguards flagged a request for Claude’s reasoning](#safeguards-flagged-a-request-for-claudes-reasoning). The message includes a Request ID and a Message ID you can quote to support if you believe the refusal is incorrect.

```python
API Error: Opus 4.6 can't help with this. Start a new session to continue.

Send feedback with /feedback or learn more: https://www.anthropic.com/legal/aup
```

The message names the model that declined, or `Claude` when no model is recorded. The check evaluates the full conversation, not only your latest prompt, so sending a new message in the same session usually re-triggers the same refusal. The same applies after exiting and reopening the session with `--continue` or `--resume`, since the transcript on disk still contains the triggering content. On [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), and [Microsoft Foundry](microsoft-foundry.md), this message also covers requests the model’s safety measures flagged as a cybersecurity topic. See [Safety measures flagged a cybersecurity topic](#safety-measures-flagged-a-cybersecurity-topic). Before v2.1.219, the message read `Claude Code is unable to respond to this request, which appears to violate our Usage Policy (https://www.anthropic.com/legal/aup). Please double press esc to edit your last message or start a new session for Claude Code to assist with a different task.` **What to do:**

- Press Esc twice or run `/rewind` to step back to a checkpoint before the turn that triggered the refusal, then rephrase or take a different approach. See [Checkpointing](checkpointing.md).
- If you can’t identify which turn caused it, run `/clear` to start a fresh conversation in the same project. Your previous conversation is preserved on disk and remains available in `/resume`.
- In [non-interactive mode](headless.md) (`-p`), where rewind is unavailable, retry with a rephrased prompt in a new session without `--continue`. Policy checks vary by model, so switching to a different model with `--model` may also resolve the refusal in some cases.


[​](#safety-measures-flagged-a-cybersecurity-topic)

Safety measures flagged a cybersecurity topic

The model’s safety measures flagged content in the conversation as a cybersecurity topic. The message names the model that flagged the request:

```python
API Error: Opus 4.8's safeguards flagged this message. Our intentionally broad safeguards allow us to deliver more capabilities faster, but can sometimes flag legitimate cybersecurity work. Send feedback with /feedback or learn more: https://support.claude.com/en/articles/14604842-real-time-cyber-safeguards-on-claude
```

If the message includes the line `` Details: `[reasoning_extraction]` ``, see [Safeguards flagged a request for Claude’s reasoning](#safeguards-flagged-a-request-for-claudes-reasoning). This message links to the [Cyber Verification Program](https://support.claude.com/en/articles/14604842-real-time-cyber-safeguards-on-claude), which grants access for legitimate cybersecurity work. Models with [automatic model fallback](model-config.md#automatic-model-fallback) print a different message, without this link; on Opus 5.5 and Sonnet 5.5 it opens with `<model>'s safeguards flagged this session`. That section also covers when Claude Code switches models instead. On [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), and [Microsoft Foundry](microsoft-foundry.md), a cybersecurity flag produces the [Usage Policy refusal](#usage-policy-refusal) message instead. **What to do:**

- If your work requires this content, apply for access through the [Cyber Verification Program](https://support.claude.com/en/articles/14604842-real-time-cyber-safeguards-on-claude)
- If your request wasn’t about a cybersecurity topic, run `/feedback` to report the false positive
- To keep working in the same session, press Esc twice or run `/rewind` to step back to a checkpoint before the turn that triggered the flag, then take a different approach. See [Checkpointing](checkpointing.md).

If the message you see is worded like one of these instead, it’s the same flag on an earlier Claude Code version:

- From v2.1.219 through v2.1.296, the message could also include `Apply to the Cyber Verification Program to reduce these interruptions.` before its closing sentence
- From v2.1.203 through v2.1.218, the message read `<model> has safety measures that flagged this message for a cybersecurity topic. To learn about the Cyber Verification Program and apply for access, visit our help center:` followed by the same help-center link. In interactive sessions, it continued with `If you were not engaging in a cybersecurity topic, please send feedback via /feedback.`
- Before v2.1.203, it read `<model>'s safeguards flagged this message for a cybersecurity topic. If your work requires this access, you can apply for an exemption:` followed by an exemption form link


[​](#safeguards-flagged-a-request-for-claudes-reasoning)

Safeguards flagged a request for Claude’s reasoning

The API declined the request because safeguards flagged it as asking the model to reproduce its internal reasoning in the response. The API names this [refusal category](../04-API-Reference/Guides/build-with-claude-refusals-and-fallback.md#refusal-response) `reasoning_extraction`, and the refusal message includes this line:

```python
Details: `[reasoning_extraction]`
```

Before v2.1.234, refusal messages didn’t include the `Details` line. **What to do:**

- Remove or reword any instruction that asks Claude to write out its thinking or reasoning verbatim or in a fixed format, such as a `<thinking>` section, a scratchpad section, or a `reasoning` field in JSON output. The instruction can be in your prompt or in a customization that Claude Code loads with it, such as CLAUDE.md, a skill, a subagent prompt, an output style, or an MCP tool description.
- To check whether a customization is the trigger, run [`claude --safe-mode`](cli-reference.md#cli-flags) in your terminal to start a session with customizations disabled, then send the same prompt
- After you change a customization, start a new session
- To reword a prompt you already sent, see [Rewind and summarize](checkpointing.md#rewind-and-summarize)
- You can still ask Claude to explain its answer. Ask for a short explanation, the evidence behind a result, or a summary of the actions it took. To read summaries of Claude’s thinking, see [`showThinkingSummaries`](settings-reference.md#showthinkingsummaries).
- For more examples, and what to do if a reworded request is still declined, see [Keep reasoning in thinking blocks](../04-API-Reference/Guides/build-with-claude-refusals-and-fallback.md#keep-reasoning-in-thinking-blocks)


[​](#output-blocked-by-content-filtering-policy)

Output blocked by content filtering policy

The API’s output content filter stopped the response Claude was generating. The message text comes from the API:

```python
API Error: Output blocked by content filtering policy
```

**What to do:**

- Rephrase your last message or take a different approach
- To step back to a checkpoint before the turn that triggered the block, press Esc twice or run `/rewind`. See [Checkpointing](checkpointing.md)


[​](#command-line-errors)

Command-line errors

These errors come from the `claude` command line and its subcommands, from a command name you submit at the prompt, and from commands such as `/security-review` that gather context by running shell commands before their prompt runs. They also come from `/tui`, which relaunches the CLI.


[​](#conflict-between-bg-and-print)

Conflict between `--bg` and `--print`

This message requires Claude Code v2.1.198 or later. You combined `--bg` with `-p` or `--print` in the same `claude` invocation. `--bg` starts a [background session](../09-Agents-Patterns/agent-view.md#from-your-shell) that you later attach to with `claude agents`, while `--print` runs [non-interactively](headless.md) and never starts the interactive session that `claude agents` attaches to. Before v2.1.198 this combination silently created a background job that could never be attached to.

```python
--bg and --print conflict: --print never starts the interactive session that `claude agents` attaches to, so the job would be unattachable. The prompt is the positional — drop --print: `claude --bg '<task>'`.
```

**What to do:**

- Drop `-p` or `--print`. `--bg` takes the prompt as its positional argument, so `claude --bg "<task>"` is the complete command. See [Dispatch new agents from your shell](../09-Agents-Patterns/agent-view.md#from-your-shell).
- To run the prompt non-interactively and print the result instead of creating a background session, drop `--bg` and run `claude -p "<task>"`


[​](#couldnt-tell-whether-bg-is-a-flag-or-text)

Couldn’t tell whether `--bg` is a flag or text

You ran `claude` with `--bg` or `--background` at a position where Claude Code couldn’t tell whether you meant it as the background flag or as text. The command started nothing, printed this line, and exited with code 1:

```python
Couldn't tell whether --bg is a flag or text here, so nothing was started. To start a background session put it first: claude --bg <prompt>
```

If you typed `--background`, the line names `--background` instead. **What to do:**

- To start a [background session](../09-Agents-Patterns/agent-view.md#from-your-shell), run the command again in your shell with the flag first: `claude --bg --name nightly-audit "<task>"`


[​](#conflict-between-a-system-prompt-flag-and-its-file-form)

Conflict between a system prompt flag and its file form

You passed [`--append-subagent-system-prompt`](cli-reference.md#cli-flags) together with `--append-subagent-system-prompt-file` in one `claude` invocation, so `claude` exits with code 1 instead of starting the session:

```python
Error: Cannot use both --append-subagent-system-prompt and --append-subagent-system-prompt-file. Please use only one.
```

Before v2.1.283, `claude` exited the same way when you passed `--system-prompt` with `--system-prompt-file`, or `--append-system-prompt` with `--append-system-prompt-file`, because those pairs conflicted instead of [combining](cli-reference.md#system-prompt-flags). On those versions the message names the pair you combined. **What to do:**

- Keep one form of the flag and drop the other. To combine a fixed prompt file with per-run text, merge the text into the file before launching instead of passing both flags


[​](#invalid-agents-configuration)

Invalid `--agents` configuration

The value you passed to `--agents` is invalid, so `claude` exits with code 1 instead of starting the session. When you pass `--safe-mode` or set [`CLAUDE_CODE_SAFE_MODE`](env-vars.md#variables), Claude Code ignores `--agents` entirely. With `--resume` or `--continue`, an inline JSON value isn’t checked and the session starts; a value read from a file is checked on every launch. Before v2.1.242, Claude Code started the session anyway.

```python
Error: Invalid --agents configuration:
<what failed>
```

What follows the first line depends on how the value failed. Claude Code runs these checks in order and stops at the first one that fails. If your value has two kinds of problem, you see the second only after you fix the first:

1.  When the value begins with `{` but doesn’t parse as JSON, or the contents of an `--agents` file don’t parse, Claude Code prints one `invalid JSON:` line carrying the JSON parser’s own message
2.  When it parses but an agent definition doesn’t match the schema for [CLI-defined subagents](../09-Agents-Patterns/sub-agents.md#choose-the-subagent-scope), Claude Code prints one line per problem
3.  When an agent name starts with `-`, Claude Code prints `<name>: agent names must not start with '-'`

When there are more than 20 problem lines, Claude Code prints the first 20 and replaces the rest with `…and N more`. With `--print`, `--agents` also accepts [the path to a JSON file](../09-Agents-Patterns/sub-agents.md#choose-the-subagent-scope) in place of the inline object. Before v2.1.281, `--agents` accepted only inline JSON and treated a file path as invalid JSON. The file form has refusals of its own, printed in place of this message, including these:

- **`Error: --agents takes a JSON object, or a file path only with --print (-p)`**: Claude Code read the value as a file path in an interactive session. Pass the definitions as inline JSON, or add `-p` to read them from a file.
- **`Error: --agents file not found: <path>`**: no file exists at that path. A value that doesn’t begin with `{` and isn’t valid JSON is read as a path, so inline JSON that your shell mangled can fail this way too. Check the path or the quoting and run the command again.

**What to do:**

- Fix each problem the message lists, then run the command again. See [the fields a CLI-defined subagent takes](../09-Agents-Patterns/sub-agents.md#choose-the-subagent-scope).


[​](#cloud-sessions-cannot-be-created-from-a-restricted-session)

Cloud sessions cannot be created from a `--restricted` session

When you start a session with [`--restricted`](cli-reference.md#cli-flags), Claude Code refuses to create [cloud sessions](claude-code-on-the-web.md#from-terminal-to-cloud) from it, because the new session would run outside the restricted process and wouldn’t enforce restricted mode. Claude Code refuses on the client, before contacting the server, so no cloud session is created:

```python
Cloud sessions cannot be created from a --restricted session: they would not enforce it.
```

**What to do:**

- Run the task locally in the restricted session
- If you control how the session was launched, start a new `claude` session without `--restricted` and create the cloud session from there

Before v2.1.248, Claude Code had no `--restricted` flag; earlier versions reject the flag itself with an unknown-option error.


[​](#cloud-sessions-are-disabled-by-your-organizations-policy)

Cloud sessions are disabled by your organization’s policy

Your organization’s `allow_remote_sessions` policy is off, so [cloud sessions](claude-code-on-the-web.md) and the commands that use them aren’t available:

```python
Cloud sessions are disabled by your organization's policy. Contact your organization admin to enable them.
```

The message appears when you [create a cloud session from the terminal](claude-code-on-the-web.md#from-terminal-to-cloud) and when you submit a command that needs cloud sessions, such as `/teleport`, `/remote-env`, or `/web-setup`. Before v2.1.268, submitting one of those commands returned [`Unknown command`](#unknown-command) instead. If the message instead names a credential this session is using and ends with `Cloud sessions use your claude.ai login.`, see [Cloud sessions use your claude.ai login](#cloud-sessions-use-your-claude-ai-login). If Claude Code couldn’t load your organization’s policy at all, you see [a different message](#couldnt-verify-your-organizations-policy-for-cloud-sessions) instead. **What to do:**

- Ask an [Owner](../13-Enterprise-Admin/server-managed-settings.md#access-control) in your organization to enable cloud sessions in the Claude Code admin settings at [claude.ai/admin-settings/claude-code](https://claude.ai/admin-settings/claude-code)


[​](#cloud-sessions-use-your-claude-ai-login)

Cloud sessions use your claude.ai login

When the [policy denial](#cloud-sessions-are-disabled-by-your-organizations-policy) names a credential this session is using and ends with this sentence, Claude Code checked the cloud-session policy of the organization that issued that credential. That organization can differ from the one your claude.ai login belongs to:

```python
Cloud sessions are disabled by your organization's policy. This session is using ANTHROPIC_API_KEY, so Claude Code checked the policy for the organization that key belongs to. Cloud sessions use your claude.ai login.
```

The last sentence means that cloud sessions run on your claude.ai login rather than on that credential. This form appears when you start, resume, or message a cloud session from your shell, such as with `--cloud` or `--teleport`. Before v2.1.296, Claude Code printed the form that tells you to contact your organization admin in this case too.


[​](#couldnt-verify-your-organizations-policy-for-cloud-sessions)

Couldn’t verify your organization’s policy for cloud sessions

These messages mean Claude Code couldn’t load your organization’s policy, which it checks before it creates, resumes, or messages a [cloud session](claude-code-on-the-web.md). While the policy request hasn’t finished, the message is:

```python
Couldn't verify your organization's policy for cloud sessions. Check your network connection and try again.
```

Inside a session, a command that needs cloud sessions, such as `/teleport` or `/web-setup`, gives this message too. It does so even where your shell would print a `Cloud sessions aren't available:` form, and its second sentence reads `Check your network connection, then restart Claude Code and try again.` Once the policy request has failed, the message says what failed. This applies when you start, resume, or message a cloud session from your shell with a flag such as `--cloud` or `--teleport`. With no route to the API, it reads:

```python
Cloud sessions aren't available: couldn't reach api.anthropic.com to load your organization's policy. Check your network or proxy.
```

Other failures follow the same opening with their own cause, such as a proxy that refused the request with HTTP 403, a server error, or credentials the API didn’t accept. When the API didn’t accept a credential that this session uses in place of your claude.ai login, such as an `ANTHROPIC_API_KEY` environment variable, the message can also name it and say to unset it:

```python
Cloud sessions aren't available: api.anthropic.com didn't accept this session's credentials when Claude Code asked for your organization's policy. Cloud sessions use your claude.ai login. ANTHROPIC_API_KEY is set, so this session is using API-key auth — unset it (or run in a shell without it) to use cloud sessions.
```

Before v2.1.296, these failures printed the `Couldn't verify` message too. **What to do:**

- For the `Couldn't verify` message, check your network connection and try again. Inside a session, restart Claude Code first
- For a `Cloud sessions aren't available:` message, do what its cause calls for, such as checking your proxy or unsetting the credential it names, then run the command again


[​](#nothing-was-stashed-because-a-folder-replaced-a-tracked-file)

Nothing was stashed because a folder replaced a tracked file

This message means a folder in your checkout now sits where a git-tracked file or link used to be. It appears after you choose the stash option while pulling a [cloud session](claude-code-on-the-web.md#from-cloud-to-terminal) into your terminal, for example with `claude --teleport` or `/teleport`. Stashing that state could delete the files inside the folder, so Claude Code refuses the stash and leaves your checkout and index unchanged:

```python
Error: Nothing was stashed: "f" is now a folder in place of a tracked file or link, and stashing could delete what's in it for good. Commit the change or move the folder somewhere else, then try again.
```

**What to do:**

- Commit the change or move the folder somewhere else, as the message says, then run the teleport again


[​](#the-json-schema-value-is-not-a-valid-json-schema)

The `--json-schema` value is not a valid JSON Schema

The schema you passed to [`--json-schema`](cli-reference.md#cli-flags) in [non-interactive mode](headless.md#get-structured-output) failed JSON Schema compilation, so `claude` exits with code 1 instead of running the prompt. Before v2.1.205, an invalid schema produced unstructured output with no error, and any schema that used the `format` keyword was treated as invalid.

```python
Error: --json-schema is not a valid JSON Schema: data/type must be equal to one of the allowed values
```

The text after the second colon is the validator’s diagnostic and names the keyword or location that failed. Schemas that use the `format` keyword, such as `"format": "email"`, are valid: Claude Code accepts `format` as an annotation and doesn’t enforce it. Claude Code runs two checks before schema compilation: it rejects a value that isn’t parseable JSON with `Error: --json-schema is not valid JSON`, and valid JSON that isn’t an object with `Error: --json-schema must be a JSON object`. **What to do:**

- Fix the part of the schema the diagnostic names, then rerun the command
- See [Get structured output](headless.md#get-structured-output) for a working schema and command


[​](#settings-file-exceeds-the-2mib-limit)

Settings file exceeds the 2MiB limit

The file you passed to [`--settings`](cli-reference.md#cli-flags) is larger than 2 MiB, so `claude` exits with code 1 at startup instead of loading it. Before v2.1.214, Claude Code read the file with no size check, and a multi-gigabyte file or a device file such as `/dev/zero` grew memory without bound.

```python
Error: Settings file exceeds the 2MiB limit: /path/to/settings.json
```

Claude Code rejects a `--settings` path that isn’t a regular file the same way: a device, FIFO, or socket reports `Error: Cannot use settings file (Not a regular file (device, FIFO, or socket))` followed by the path, and a directory reports an `EISDIR` reason. **What to do:**

- Point `--settings` at a regular JSON settings file under 2 MiB. See [Settings](settings.md) for the format.


[​](#the-current-directory-no-longer-exists)

The current directory no longer exists

You started `claude` from a directory that was deleted or moved after your shell entered it, for example a worktree or temp directory another shell removed. Claude Code can’t read its working directory, so it exits with code 1 before starting the session, in interactive and [non-interactive](headless.md) mode alike. Before v2.1.239, Claude Code crashed with minified bundle source and a raw `ENOENT ... uv_cwd` stack on stderr instead of this message.

```python
The current directory no longer exists (it was deleted or moved). Start Claude Code from an existing directory.
error: The current working directory was deleted, so that command didn't work. Please cd into a different directory and try again.
```

The cause and the fix are the same for both forms. When Claude Code can’t read the working directory for a different reason, such as a permissions change, the message names the error code instead: `Can't read the current directory (EACCES). Start Claude Code from a different directory.` On macOS, `EPERM` for a directory in `~/Desktop`, `~/Documents`, `~/Downloads`, or iCloud Drive usually means macOS is blocking your terminal app from that folder. Other commands that read that folder fail the same way: `ls` there reports `Operation not permitted`, even with `sudo`. **What to do:**

- Change to a directory that exists, such as your home or project directory, then run `claude` again
- If the directory was recreated at the same path, your shell still holds the deleted one. Run `cd "$PWD"` or leave and re-enter the directory, then run `claude` again
- For `EPERM` on macOS, quit your terminal app with Cmd+Q, open it again, return to that folder, and run `claude`. If `ls` in that folder still fails, open **System Settings \> Privacy & Security \> Files and Folders**, turn on the folder for your terminal app, then reopen the terminal


[​](#temp-directory-refused-or-cannot-be-created)

Temp directory refused or cannot be created

On macOS and Linux, Claude Code creates a private temp directory at startup, `claude-<uid>` under the system temp directory or the [`CLAUDE_CODE_TMPDIR`](env-vars.md) override. When the directory can’t be created, or an entry already at that path fails the safety checks, Claude Code prints the failure to stderr and exits with code 1 rather than start the session:

```python
Claude Code's temporary directory /tmp/claude-501 could not be created: the volume holding /tmp is full (ENOSPC). Free space on that volume, or set CLAUDE_CODE_TMPDIR to a directory on another one, then try again.

Temp directory /tmp/claude-501 is not a directory (may be an attacker-planted symlink). Refusing to use it. Set CLAUDE_CODE_TMPDIR to a directory you control, or ask an administrator to remove it.

Temp directory /tmp/claude-501 is owned by uid 502, expected 501. Refusing to use it — another user may have pre-created it. Set CLAUDE_CODE_TMPDIR to a directory you control, or ask an administrator to remove it.

Temp directory /tmp/claude-501 is not readable (its mode may have been altered, or a path component denies search). Refusing to use it — restore its permissions (chmod 0700) or remove it. Set CLAUDE_CODE_TMPDIR to a directory you control, or ask an administrator to remove it.
```

**What to do:**

- For `could not be created` followed by `is full (ENOSPC)`, free disk space on the volume the message names. When it says `your disk quota on the volume holding /tmp is used up (EDQUOT)` instead, delete your own files on that volume that you no longer need
- For the `Refusing to use it` forms, remove the named entry itself, not what a link points to, and start Claude Code again; for the `owned by uid` form, only an administrator or that user can remove it
- For `is not readable`, run `chmod 0700` on the named directory, or remove it and start again
- In any of these cases, set [`CLAUDE_CODE_TMPDIR`](env-vars.md) to a directory you control and start Claude Code again, leaving the refused path alone

Before v2.1.309, Claude Code printed only the operating system’s error text when the volume was full or your quota was used up. An example is `ENOSPC: no space left on device, mkdir '/tmp/claude-501'`, and the same steps apply.


[​](#directory-couldnt-be-resolved-to-a-real-location)

Directory couldn’t be resolved to a real location

You ran `/add-dir` for a subdirectory of your working directory, and Claude Code couldn’t resolve the directory to its real location. You already have file access to a subdirectory of the working directory, so `/add-dir` only loads its skills, commands, and agents. Before loading them, Claude Code checks that the directory’s real location, with any symlinks resolved, is inside the working directory. When Claude Code can’t resolve that location, it loads nothing and shows this message:

```python
packages/app couldn't be resolved to a real location, so its skills, commands, and agents weren't loaded. Check that it is a directory inside the working directory and try again.
```

**What to do:**

- Check that the path names a real directory inside the working directory, then run `/add-dir` again
- The message doesn’t change your file access; it only reports that the directory’s `.claude/` content wasn’t loaded

Before v2.1.261, this message also appeared for every `/add-dir <subdirectory>` when the working directory was on a `/net/<host>` automount, where Claude Code declines to resolve paths by design; the directory was fine and retrying couldn’t help.


[​](#workspace-not-trusted-when-starting-remote-control)

Workspace not trusted when starting Remote Control

If `claude ultrareview` printed `Error: Workspace not trusted`, see [Workspace not trusted when running claude ultrareview](#workspace-not-trusted-when-running-claude-ultrareview) instead.

You started [Remote Control](remote-control.md) server mode with `claude remote-control` or its `claude rc` alias in a directory you haven’t trusted, and the command couldn’t ask you whether to trust it. For example, the command’s standard input or standard output isn’t a terminal because one of them is redirected or piped. The command exits with code 1:

```python
Error: Workspace not trusted. Please run `claude` in /Users/you/project first to review and accept the workspace trust dialog.
```

Two variants that also begin with `Error: Workspace not trusted.` appear in a terminal too small to show what trusting the directory turns on, or one that didn’t report its size. Enlarge the window or switch to a normal terminal window, then run `claude rc` again. In your home directory the message is different, because the workspace trust dialog never saves trust for the home directory, so accepting it there can’t satisfy this check. Before v2.1.214, the home directory showed the message above, whose advice can’t succeed there.

```python
Error: Workspace not trusted. /Users/you is your home directory, and for security home-directory trust is never saved, so running `claude` here first won't help. Run `claude rc` from a project directory instead (run `claude` there once to accept the trust dialog).
```

If you answer `n` or press Enter at the [`Trust <directory>?` question](remote-control.md#requirements), the command prints a `Remote Control did not start` message that names the directory and exits with code 1. Run `claude rc` again to answer `y`. **What to do:**

- Trust the directory from a terminal first: run `claude rc` there and answer `y`, or run `claude` there and accept the [workspace trust dialog](permissions.md#project-allow-rules-and-workspace-trust), then run your original command again
- In your home directory, change to a project directory and start Remote Control there

Before v2.1.284, the command never asked, even in a terminal.


[​](#workspace-not-trusted-when-running-claude-ultrareview)

Workspace not trusted when running claude ultrareview

In a folder you haven’t trusted, when [`claude ultrareview`](ultrareview.md#trust-the-folder-before-the-review-runs) can’t ask whether you trust it, the run exits with code 1 before the review starts:

```python
Error: Workspace not trusted. Please run `claude` in /Users/you/project first to review and accept the workspace trust dialog. Or, in a script or CI job, pass `--trust-workspace` to trust the folder for this run only.
```

For example, the subcommand can’t ask when its standard input or standard output isn’t a terminal. Sending the output to a file, as in `claude ultrareview --json > findings.json`, means standard output isn’t a terminal. **What to do:**

- In a script or CI job, append `--trust-workspace` to trust the checkout for that run only: `claude ultrareview --trust-workspace`. Append it only for code you trust, because the checkout’s git configuration and Claude Code project settings can then run programs. To review a pull request whose code you don’t trust, see [how to review it from a checkout you do trust](ultrareview.md#trust-the-folder-before-the-review-runs).
- On your own machine, run `claude` in that folder and accept the [workspace trust dialog](permissions.md#project-allow-rules-and-workspace-trust), then run your original command again

Each of these messages from `claude ultrareview` means that no review started and the exit code is 1:

- **`Error: Workspace not trusted. This terminal ...`**: the terminal reported no row and column count, or can’t fit the trust question and its warnings. Enlarge it or use a terminal that reports its size, then run `claude ultrareview` again. Outside your home directory, you can also run `claude` in that folder once and accept the trust dialog, so later runs there don’t ask.
- **`Error: Workspace not trusted. <folder> is your home directory`**: because trust for your home directory is never saved, running `claude` there first can’t help. Run `claude ultrareview` from a project directory instead, after running `claude` there once to accept the trust dialog, or append `--trust-workspace`.
- **`No answer in time.` followed by `Error: Workspace not trusted`**: the `Trust <folder>? [y/N]` question went unanswered for 5 minutes. Run `claude ultrareview` again and answer it.
- **`Ultrareview did not start: <folder> is not trusted`**: you declined at the `Trust <folder>? [y/N]` question, for example by answering `n` or pressing Enter. To start the review, run `claude ultrareview` again and answer `y`.
- **`` Ultrareview did not start: `--trust-workspace` takes no value ``**: something other than a flag follows `--trust-workspace`, such as a PR number or `false`. If you don’t trust the folder, leave the flag out. To trust it for this run, put the PR number or base branch before the flag: `claude ultrareview 1234 --trust-workspace`.

Before v2.1.309, `claude ultrareview` didn’t accept `--trust-workspace`.


[​](#not-carried-over-to-the-sessions-remote-control-starts)

Not carried over to the sessions Remote Control starts

You started [Remote Control](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:

```python
Error: `--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`).
```

Claude 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. Claude Code also refuses to start for a global flag it doesn’t yet recognize as harmless, so a flag added in a newer release can appear in this message until a later release marks it harmless. **What to do:**

- Remove the flag from before the verb and pass [Remote Control’s own options](remote-control.md#start-a-remote-control-session) after it; `claude remote-control --help` lists them
- When the refused flag is `--permission-mode`, run `claude remote-control --permission-mode <mode>` to set the permission mode for the sessions Remote Control starts

Before 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.


[​](#sandbox-is-not-supported-by-claude-remote-control)

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

This error means the command that starts your [Remote Control](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:

```python
Error: --sandbox is not supported by claude remote-control. The flag had no effect and was removed. To sandbox sessions, set sandbox.enabled to true in settings.
Error: --no-sandbox is not supported by claude remote-control. The flag had no effect and was removed. Remove it from the command.
```

**What to do:**

- Remove the flag from the command, including in a script or service definition that starts the server for you, then run it again
- To sandbox the sessions the server starts, turn on [sandboxing](sandboxing.md) by setting [`sandbox.enabled`](settings-reference.md#sandbox-enabled) to `true` in a [settings file](settings.md#where-settings-live)

Both flags were removed from `claude remote-control` in v2.1.300, so a command written for an earlier version can still carry one.


[​](#claude-import-is-not-yet-available-in-this-build)

claude import is not yet available in this build

You ran [`claude import`](cli-reference.md#cli-commands), and Claude Code found the import flow turned off, so the command exits with code 1 instead of starting the import. Before v2.1.222, a build with the import flow off treated `import` as a prompt and started an interactive session instead of printing this message.

```python
`claude import` is not yet available in this build. Run `claude` and use /mcp or edit ~/.claude/settings.json directly.
```

Claude Code turns `claude import` on through a feature flag it fetches from Anthropic and caches on disk. This message means the cached value is off. The cause is usually one of the following:

- You haven’t started a session since installing, so Claude Code hasn’t fetched the flag yet. The first `claude import` can print this even when the feature is available to you.
- You use Claude Code through Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, or Claude Platform on AWS, or through a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md#availability-and-limitations). Claude Code doesn’t fetch feature flags in these sessions, so `claude import` stays unavailable.
- You set `DISABLE_TELEMETRY`, `DO_NOT_TRACK`, `DISABLE_GROWTHBOOK`, or [`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`](env-vars.md), which turn off feature-flag fetching, so `claude import` stays unavailable.

**What to do:**

- On a fresh installation, start `claude`, wait for the session to load, exit, and run `claude import` again
- Where feature-flag fetching stays off, set the configuration up yourself: add MCP servers with [`claude mcp add`](../06-MCP-Tools/General/mcp.md#installing-mcp-servers), and create the [`CLAUDE.md` files](memory.md#how-claude-md-files-load), [skills and commands](../08-Plugins-Skills/skills.md#where-skills-live), and [subagents](../09-Agents-Patterns/sub-agents.md#choose-the-subagent-scope) you want to carry over. The message also names `~/.claude/settings.json`. Of the configuration `claude import` carries, that file holds only the [permission mode](settings-reference.md#permission-settings); Claude Code doesn’t read MCP servers from it.


[​](#could-not-read-claude-code-config)

Could not read Claude Code config

You ran [`claude import`](cli-reference.md#cli-commands) while Claude Code couldn’t parse `~/.claude.json`, the file where it stores your account details and per-project state. The subcommand reads that file to check availability but doesn’t show the recovery dialog the interactive session shows, so it exits with code 1. Before v2.1.222, `claude import` with an unreadable config file started an interactive session, whose recovery dialog handled the file.

```python
Could not read Claude Code config — run `claude` with no arguments to recover it.
```

**What to do:**

- Run `claude` with no arguments. Claude Code detects the invalid file and offers to reset it. Then run `claude import` again.
- To keep manual edits you’ve made, fix the JSON syntax in `~/.claude.json` in an editor instead, then rerun `claude import`


[​](#could-not-import-a-server-from-claude-desktop)

Could not import a server from Claude Desktop

Claude Code couldn’t add one of the servers you selected in `claude mcp add-from-claude-desktop`. The command still imports the other selected servers and prints one line per server it couldn’t add. Before v2.1.205, the first server that failed stopped the import.

```python
Could not import my server: Invalid name my server. Names can only contain letters, numbers, hyphens, and underscores.
```

The text after the server name is the reason. The most common one is the name check: Claude Desktop allows characters in server names, such as spaces and periods, that `claude mcp` restricts to letters, numbers, hyphens, and underscores. Other reasons include a server configuration that fails validation and a server blocked by your organization’s [MCP policy](../06-MCP-Tools/General/managed-mcp.md). **What to do:**

- Rename the server in `claude_desktop_config.json` to use only letters, numbers, hyphens, and underscores, then run `claude mcp add-from-claude-desktop` again
- Add that server directly with `claude mcp add` or `claude mcp add-json` under a valid name. See [Import MCP servers from Claude Desktop](../06-MCP-Tools/General/mcp.md#import-mcp-servers-from-claude-desktop).


[​](#cannot-add-mcp-server-to-the-managed-scope)

Cannot add MCP server to the managed scope

You ran `claude mcp add` or `claude mcp add-json` with `--scope managed`. That scope holds the servers your organization provides through the [`managedMcpServers`](settings-reference.md#managedmcpservers) managed setting. Claude Code reads them from managed settings only, so the command can’t write a server to that scope.

```python
Cannot add MCP server to scope: managed
```

**What to do:**

- Add the server to a scope you can write: `local`, `user`, or `project`. Without `--scope`, the command uses `local`. See [MCP installation scopes](../06-MCP-Tools/General/mcp.md#mcp-installation-scopes)
- To provide the server to every user in your organization, add it to [`managedMcpServers`](settings-reference.md#managedmcpservers) in the managed settings you deploy


[​](#cannot-add-mcp-server-when-managed-settings-allow-only-plugin-servers)

Cannot add MCP server when managed settings allow only plugin servers

You ran `claude mcp add` or `claude mcp add-json` while your organization’s managed settings set [`strictPluginOnlyCustomization`](settings-reference.md#strictpluginonlycustomization) to `true` or to a list that includes `mcp`. With that setting, Claude Code doesn’t load MCP servers from `~/.claude.json` or `.mcp.json`, so the command exits with code 1 instead of saving a server that would never load:

```python
Cannot add MCP server: your organization's managed settings allow only MCP servers that plugins provide. Install a plugin that provides this server, or ask your administrator to make it available.
```

`claude mcp add-from-claude-desktop` reports each server you select as not imported, with this message as the reason. [`/import`](commands.md#all-commands) reports this message for each MCP server it tries to add and still imports the other items it found. Before v2.1.284, these commands saved the server and reported success, and the server never loaded. **What to do:**

- Install a [plugin](../08-Plugins-Skills/discover-plugins.md) that provides the server
- Ask your administrator to distribute the server in a [plugin](../08-Plugins-Skills/plugins-org.md), or to provide it through [`managedMcpServers`](settings-reference.md#managedmcpservers) if it’s a remote HTTP or SSE server


[​](#cant-read-mcp-json)

Can’t read .mcp.json

A command that reads the project’s [`.mcp.json`](../06-MCP-Tools/General/mcp.md#project-scope), such as `claude mcp add` or `claude mcp add-json` with `--scope project`, or `claude mcp remove`, found that the file in your current directory isn’t a regular file or is larger than 2 MiB, so it exits with this error instead of reading the file.

```python
Can't read .mcp.json: it isn't a regular file or is larger than 2097152 bytes. Fix or remove it, then run the command again.
```

Before v2.1.257, a FIFO at `.mcp.json` left the command waiting forever with no output, and a symlink to a device file such as `/dev/zero` grew memory until the process was killed. **What to do:**

- Check what sits at `.mcp.json` in your current directory. Replace it with an ordinary JSON file in the [project-scope format](../06-MCP-Tools/General/mcp.md#project-scope), or delete it, then run the command again.


[​](#mcp-server-was-not-saved-or-removed)

MCP server was not saved or removed

You ran `claude mcp add`, `claude mcp add-json`, or `claude mcp remove` for a server in the `user` or `local` [scope](../06-MCP-Tools/General/mcp.md#mcp-installation-scopes). Both scopes are stored in `~/.claude.json`, and the change isn’t in that file when Claude Code reads it back after writing. The command exits with this error instead of its success line.

```python
MCP server "example" was not saved to /home/user/.claude.json. If that file is read-only or protected by a sandbox, make it writable or run the command outside the sandbox, then add the server again.
```

After a remove, the message reads `was not removed from` and ends with `then remove the server again`. For a `local`-scope server, the path is followed by the project directory the entry belongs to, as `(local scope for /path/to/project)`. Before v2.1.283, `claude mcp add`, `claude mcp add-json`, and `claude mcp remove` reported success even when the change didn’t reach the file. **What to do:**

- Make the file the message names writable, or run the command outside the sandbox, then run the same add or remove command again.


[​](#mcp-server-may-not-have-been-saved-or-removed)

MCP server may not have been saved or removed

You ran `claude mcp add`, `claude mcp add-json`, or `claude mcp remove` for a server in the `user` or `local` [scope](../06-MCP-Tools/General/mcp.md#mcp-installation-scopes), and Claude Code couldn’t read `~/.claude.json` back to confirm the change. The change may or may not be on disk. The text in parentheses is the error from that read.

```python
MCP server "example" may not have been saved: /home/user/.claude.json could not be read to confirm the change (EACCES: permission denied, open '/home/user/.claude.json'). Run `claude mcp get example` to check, then add the server again if it is missing.
```

After a remove, the message reads `may not have been removed` and ends with `then remove the server again if it is still listed`. Before v2.1.283, the commands reported success even when the change couldn’t be confirmed. **What to do:**

- Run `claude mcp get <name>` to check whether the change is on disk. For a `local`-scope server, run it from the project directory the server belongs to, since local scope is per project.
- If the server is missing after an add, or still listed after a remove, run the same add or remove command again.


[​](#anthropic-hosted-and-doesnt-support-local-oauth)

Server is Anthropic-hosted and doesn’t support local OAuth

You started a sign-in for an MCP server whose URL points at an Anthropic-hosted connector host that authenticates through a third-party identity provider. These hosts include `microsoft365.mcp.claude.com`, `gmail.mcp.claude.com`, and `gcal.mcp.claude.com`. Claude Code refuses to start its local OAuth flow for these hosts from both the `/mcp` panel and `claude mcp login`, because [their sign-in works only through claude.ai](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai).

```python
"gmail" is Anthropic-hosted and doesn't support local OAuth. Connect it via Settings → Connectors on claude.ai (requires `claude login`), then it'll be available here automatically.
```

**What to do:**

- Remove your entry with `claude mcp remove <name>`, so it can’t hide the claude.ai connector at the same URL
- After removing it, connect the service at [claude.ai/customize/connectors](https://claude.ai/customize/connectors), while signed in to the account you use in Claude Code. Once connected, [the connector appears in Claude Code automatically](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) if your active authentication method is a claude.ai subscription login


[​](#server-rejected-the-authorization-header-minted-by-the-configured-headershelper)

Server rejected the Authorization header minted by the configured headersHelper

An MCP server whose [`headersHelper`](../06-MCP-Tools/General/mcp.md#use-dynamic-headers-for-custom-authentication) supplies the `Authorization` header answered the connection with HTTP 401 or 403, so Claude Code reports the connection as failed. Because the helper supplies the `Authorization` header, Claude Code [doesn’t fall back to OAuth](../06-MCP-Tools/General/mcp.md#authenticate-with-remote-mcp-servers) for the server:

```python
Server rejected the Authorization header minted by the configured headersHelper (HTTP 401). Check that the helper command returns a valid credential for this MCP endpoint — OAuth fallback is disabled when the helper supplies Authorization.
```

Claude Code re-runs the helper on each connection attempt, so a retry after a transient rejection, such as a token-rotation race, can succeed with a fresh credential. **What to do:**

- Run the `headersHelper` command yourself the way Claude Code runs it: from the [directory Claude Code runs it in](../06-MCP-Tools/General/mcp.md#where-the-helper-runs), with the [environment variables Claude Code sets for it](../06-MCP-Tools/General/mcp.md#use-dynamic-headers-for-custom-authentication), and without the [credential variables Claude Code removes](../06-MCP-Tools/General/mcp.md#which-variables-a-helper-can-read) for a server from a project `.mcp.json`, a plugin, or a project agent file. Check that it prints an `Authorization` value the server’s endpoint accepts
- After fixing the helper or its credential source, select the server in `/mcp` and choose **Reconnect**

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


[​](#mcp-permission-prompt-tool-not-found)

MCP permission prompt tool not found

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

```python
Error: MCP tool mcp__permissions__approve (passed via --permission-prompt-tool) not found. Available MCP tools: none
```

The list after `Available MCP tools:` names the MCP tools that were connected. **What to do:**

- Check that the server starts and stays connected: run `claude mcp list` in the same directory and confirm the server is listed as connected
- Confirm the tool name matches the `mcp__<server>__<tool>` name the server exposes
- If the server needs longer than 30 seconds to start, raise [`MCP_TIMEOUT`](env-vars.md)


[​](#oauth-callback-port-is-already-in-use)

OAuth callback port is already in use

When you sign in to a remote MCP server with OAuth, Claude Code starts a local listener to receive the sign-in callback. If the port that listener needs is held by another process, the sign-in fails with this message. This mostly happens with a [fixed callback port](../06-MCP-Tools/General/mcp.md#use-a-fixed-oauth-callback-port) set through the [`MCP_OAUTH_CALLBACK_PORT`](env-vars.md) variable or `--callback-port`, since without one Claude Code picks an available port.

```python
OAuth callback port <port> is already in use — another process may be holding it. Run `lsof -ti:<port> -sTCP:LISTEN` to find it.
```

On Windows, the suggested command is `netstat -ano | findstr :<port>` instead. **What to do:**

- Run the command from the message to find the process holding the port, and stop it or wait for it to finish
- If another program needs that port permanently, register a different redirect URI with the server and set its port with `MCP_OAUTH_CALLBACK_PORT` or `--callback-port`, whichever you use
- Then start the sign-in again, for example by selecting the server in `/mcp`


[​](#no-available-ports-for-oauth-redirect)

No available ports for OAuth redirect

When you sign in to a remote MCP server with [OAuth](../06-MCP-Tools/General/mcp.md#authenticate-with-remote-mcp-servers), Claude Code starts a local listener to receive the sign-in callback. The sign-in fails with this message when Claude Code can’t bind a local port for it. Something on the machine is preventing it from listening on `127.0.0.1`, for example security software or a sandbox policy that denies local listeners.

```python
No available ports for OAuth redirect
```

Before v2.1.268, Claude Code didn’t fall back to an operating-system-assigned port, so the message also appeared when only its self-picked ports couldn’t be bound. That can happen on Windows hosts where Hyper-V reserves port ranges that cover the ports Claude Code picks from. **What to do:**

- Check whether security software or a sandbox policy blocks processes from listening on `127.0.0.1`, and allow Claude Code to bind a local port
- Then start the sign-in again, for example by selecting the server in `/mcp`


[​](#security-review-fails-without-origin-head)

/security-review fails without origin/HEAD

[`/security-review`](commands.md#all-commands) builds its review context by diffing your branch against `origin/HEAD`, the local ref that records which branch is the default on your `origin` remote. When that ref doesn’t exist, the git commands that gather the diff fail and the review stops before it starts.

```python
Error: Shell command failed for pattern "!`git diff --name-only origin/HEAD...`": [stderr]
fatal: ambiguous argument 'origin/HEAD...': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
```

The message may quote `git log` or a different `git diff` instead. Git creates `origin/HEAD` only when the remote advertises a default branch and your fetch refspec covers it, which a full `git clone` of a remote with commits does. The ref is missing in these setups:

- A single-branch or CI checkout, which fetches too narrow a refspec
- A remote whose server-side HEAD points at a branch nobody pushed
- A repository with no `origin` remote, or one you never fetched

Claude Code shows the same error for any skill that [injects dynamic context](../08-Plugins-Skills/skills.md#when-an-injected-command-fails), and a failed injected command aborts that skill’s invocation. Sibling strings fire before the command runs at all:

- `Shell command permission check failed for pattern "..."`: the command’s permission check didn’t allow it. [Permission checks on injected commands](../08-Plugins-Skills/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`
- `` 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](../08-Plugins-Skills/skills.md#how-injected-commands-run)
- `No shell command in <name> was run`: one of the file’s `!` commands contains a raw control character other than tab or newline, so none of them runs. See [how to find and remove the character](#no-shell-command-was-run)

**What to do:**

- Create the ref by naming your remote’s default branch: `git remote set-head origin <default-branch>`. This works whenever the local tracking ref `origin/<default-branch>` exists. If it doesn’t, as in single-branch clones, fetch the branch first: run `git remote set-branches --add origin <branch>`, then `git fetch origin`, then rerun the set-head command. Rerun `/security-review`.
- If you’d rather not name the branch, run `git fetch origin` and then `git remote set-head origin --auto`, which asks the remote which branch is its default. It fails with `error: Cannot determine remote HEAD` when the remote advertises no default branch, because it is empty or its HEAD points at a branch nobody pushed; name the branch explicitly instead. It fails with `error: Not a valid ref` when your clone doesn’t fetch that branch; widen the refspec as above first.
- If the repository has no remote, add one with `git remote add origin <url>` and fetch before creating the ref. If the remote is empty, push your branch first with `git push -u origin HEAD` and name that branch in the set-head command; `origin/HEAD` then points at the branch you just pushed, so `/security-review` sees an empty diff until the branch diverges from it.


[​](#no-shell-command-was-run)

No shell command in a skill or command was run

One of the `` !`<command>` `` [dynamic context commands](../08-Plugins-Skills/skills.md#inject-dynamic-context) in a skill or custom command file contains a raw control character other than tab or newline. Claude Code refuses the whole invocation before any of the file’s commands runs. The message names the shell tool that would have run the commands, Bash or PowerShell, and ends with the refused command. Each such character is replaced by `�` so you can see where it is:

```python
No shell command in /my-skill was run, because the Bash tool does not accept one of them: command contains control characters that would be hidden in the approval dialog. Unprintable characters are shown as � below: remove them from the skill or command file, or from the arguments or options substituted into it.
build.sh --target�dist
```

**What to do:**

- Find each `�` in the command quoted at the end of the message. Remove the character it stands for from the skill or command file, or from the arguments or options substituted into the file.


[​](#input-must-be-provided-when-using-print)

Input must be provided when using `--print`

Bare `claude` needs stdout to be a terminal to start the interactive UI. When stdout is redirected, or the console isn’t a real terminal, such as PowerShell ISE and some IDE output panes, `claude` runs [non-interactively](headless.md) instead. That is the same mode as `claude -p`, which requires a prompt, so the message names `--print` even when you didn’t pass the flag. Passing `-p`/`--print` with no prompt and nothing piped on stdin produces the same error anywhere.

```python
Error: Input must be provided either through stdin or as a prompt argument when using --print
```

**What to do:**

- For interactive use, run `claude` in a real terminal: Windows Terminal or the PowerShell console rather than ISE, and your IDE’s integrated terminal rather than an output pane
- For one-shot use, pass the prompt: `claude -p "your question"`, or pipe it with `echo "your question" | claude -p`


[​](#claude-code-cant-read-the-keyboard-here)

Claude Code can’t read the keyboard here

You ran `claude` without [`-p`](headless.md), which starts an [interactive session](interactive-mode.md), but its standard input isn’t a terminal. Something piped or redirected it, or the program that launched `claude` supplied its own input stream. An interactive session needs a terminal to read your keystrokes from, and what Claude Code does without one depends on your platform:

- **Windows**: Claude Code prints the message to stderr and exits with code 1 instead of starting the interface
- **macOS and Linux**: Claude Code reads your keystrokes from `/dev/tty` and starts the session, with any piped text as your first prompt. You see the message when `/dev/tty` can’t be opened, and its first line names `/dev/tty` in place of the Windows wording.

On Windows the message reads:

```python
Claude Code can't read the keyboard here: stdin is not a terminal (it is piped, redirected, or supplied by the program that launched claude), and on Windows it can't fall back to the console for input yet.
Run claude directly in Windows Terminal, PowerShell, or Command Prompt, without piping or redirecting its input.
To send text as a prompt and print the reply instead, add -p; it also works with --continue and --resume <session-id> (for example: type notes.md | claude -p --continue).
```

**What to do:**

- To work interactively, run `claude` directly in a terminal, without piping or redirecting its input
- To get a reply without the interactive interface, for example from a script, add `-p` and give the prompt as an argument or on stdin, as in `claude -p "your question"` or `echo "your question" | claude -p`. The same works with `--continue` and `--resume <session-id>`.

Before v2.1.287, Claude Code started the interface instead of printing this message, then either showed nothing on screen or failed with an error containing `Raw mode is not supported`. If you see `Raw mode is not supported` during `claude install` instead, see [`Raw mode is not supported` during install](troubleshoot-install.md#raw-mode-is-not-supported-during-install).


[​](#input-contained-only-whitespace)

Input contained only whitespace

In [non-interactive mode](headless.md), Claude Code refuses a prompt made up entirely of spaces, tabs, or newlines instead of sending it, because the API rejects messages with no visible text. Which message you see depends on where the blank prompt came from:

- **Prompt argument or piped stdin for `claude -p`**: `claude` exits with `Error: Input contained only whitespace. Provide a prompt with text through stdin or as a prompt argument when using --print`
- **Message submitted to a running `--input-format stream-json` or [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) session**: Claude Code ends the turn without calling the model and the session stays usable. The refusal arrives as an informational message and as the turn’s result text: `Blank prompt — the message was only whitespace, so nothing was sent to the model.`

Before v2.1.229, Claude Code sent the whitespace-only message to the API, which rejected the request with a 400 error. **What to do:**

- Include visible text in the prompt. If a script builds the prompt from a variable or file, check that the source isn’t empty before calling Claude Code.


[​](#stream-json-input-carried-over-256m-characters-with-no-newline)

stream-json input carried over 256M characters with no newline

Your program sent more than 268,435,456 characters on stdin without a newline to a `claude -p --input-format stream-json` run, so Claude Code prints this error to stderr and exits with code 1 instead of buffering more input. The message states that budget as `256M`. Before v2.1.257, Claude Code buffered such input without limit, growing memory until the process crashed or was killed.

```python
Error: stream-json input carried over 256M characters with no newline. Each stream-json message must be a single newline-terminated JSON line: either the producer is not newline-terminating its messages, or one message exceeded this budget.
```

Input this long without a newline usually means the producer isn’t a stream-json producer at all, such as a binary file or plain log output piped in by accident. A single message over the budget fails the same check. **What to do:**

- Check what’s piped to stdin. With [`--input-format stream-json`](cli-reference.md#cli-flags), every message must be one newline-terminated JSON line
- To send plain text instead, drop `--input-format stream-json`; `claude -p` reads a plain-text prompt from stdin by default


[​](#unknown-command)

Unknown command

In an interactive terminal session, you submitted a `/` name that doesn’t match any command in this session, so Claude Code reports the name instead of running anything:

```python
Unknown command: /hepl. Did you mean /help?
```

Claude Code suggests the closest command name or alias that the menu lists in this session. When nothing is close, the message ends after the name. The cause is usually one of the following:

- A typo, such as `/hepl` for `/help`. [How the command menu matches what you type](commands.md#how-the-command-menu-matches-what-you-type) covers picking a close match before you submit
- A command that exists but isn’t available in this session because a requirement isn’t met, such as your platform, plan, or authentication method. See the entry for [`/web-setup`](web-quickstart.md#web-setup-shows-no-commands-match-or-unknown-command), [`/schedule`](web-scheduled-tasks.md#schedule-returns-unknown-command), or [`/auto-mode-setup`](auto-mode-config.md#auto-mode-setup-returns-unknown-command). Some commands answer with their own message when your organization’s policy disables them, such as [`Cloud sessions are disabled by your organization's policy`](#cloud-sessions-are-disabled-by-your-organizations-policy)
- A command from a [plugin](../08-Plugins-Skills/plugins.md) or [MCP server](../06-MCP-Tools/General/mcp.md#use-mcp-prompts-as-commands) that isn’t installed or connected in this session

Claude Code answers an unmatched `/` name this way only in an interactive terminal session. In every other session, it sends the prompt to Claude as a normal message instead, with a note that the command didn’t run and a list of commands Claude can run in the session. Those sessions include:

- `-p` runs
- [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) applications
- The Code tab of the [Desktop app](../16-Mobile-Desktop/desktop.md)
- The chat panel of the [VS Code extension](../03-IDE-Integrations/vs-code.md)
- [Cloud sessions](claude-code-on-the-web.md) and [cloud scheduled tasks](web-scheduled-tasks.md)

For a built-in command that can’t run in one of those sessions, Claude Code still answers that the command isn’t available instead of sending it to Claude. Before v2.1.274, only cloud sessions and cloud scheduled tasks sent an unmatched name to Claude. Before v2.1.273, they answered `Unknown command` too. Claude Code doesn’t treat every prompt that starts with `/` as a command. It sends the prompt to Claude as a normal message when the first word after the `/` starts with punctuation, such as the `/--` that opens a Lean doc comment, or is a path such as `/var/log/syslog`. Before v2.1.236, if you pressed `Enter` while the command menu listed a near match for the name you typed, Claude Code ran that match, so a typo such as `/hepl` ran `/help` instead of producing this message. **What to do:**

- Run the suggested name, or type `/` followed by part of the name to see what’s available in this session
- If Claude Code reports a documented command as unknown, check its row in the [commands reference](commands.md) for the requirement it names


[​](#diff-is-too-large-for-ultrareview)

Diff is too large for ultrareview

The diff between your branch and the base branch, including uncommitted and staged changes, exceeds the size limits for an [ultrareview](ultrareview.md), so `/code-review ultra` and the `claude ultrareview` subcommand refuse the review before the cloud session starts. A refused review doesn’t use a free run and doesn’t bill usage credits. The message names the limits in effect, the size of your diff, and the files that contribute the most changed lines. Before v2.1.216, the message showed only the raw diff statistics.

```python
Diff is too large for ultrareview: 812 files, 96,410 lines changed (limits: 500 files, 8,000 lines). Largest files: package-lock.json (41,904 lines), dist/bundle.js (18,210 lines), src/generated/api.ts (9,876 lines). Pass a closer base branch (`/code-review ultra <branch>`) to narrow the scope, or split the change.
```

Reviewing a pull request applies the same limits; that form of the message begins `PR #<N> is too large for ultrareview` and names the PR’s file and line counts. **What to do:**

- Pass a base branch closer to your work, such as `/code-review ultra develop`, so the review covers only the diff against that branch
- Split the change into smaller branches and review each one. The files the message names contribute the most changed lines, so start by moving those to their own branch.


[​](#could-not-find-merge-base-with-the-base-branch)

Could not find merge-base with the base branch

`/code-review ultra` and the `claude ultrareview` subcommand review the diff between your branch and a base branch, which needs a commit the two share. When `git merge-base` finds none, Claude Code refuses the review before the cloud session starts. On a clone Claude Code can verify is complete, with at least one branch, it falls back to [reviewing every tracked file](ultrareview.md#diff-limits-and-fallbacks) instead of refusing. You see this refusal when the base branch can’t be found at all, when Claude Code can’t verify that your clone is complete, or in the rare repository where the whole-tree diff isn’t possible, such as the SHA-256 object format.

```python
Could not find merge-base with main. Pass the base branch explicitly (e.g. `/code-review ultra develop`) or make sure you're in a git repo with a main branch.
```

The hint after the first sentence depends on what Claude Code observed:

- **You didn’t pass a base branch**: Claude Code compared against the repository’s default branch and suggests passing your base explicitly, as in the example above
- **You passed a base branch that was already in your clone**: the hint reads `` Make sure <branch> exists locally or on origin (try `git fetch origin <branch>`) ``
- **You passed a base branch that wasn’t in your clone**: Claude Code fetched it from origin before comparing. The hint reads `` <branch> was fetched from origin but shares no history with HEAD. If another branch is your real base, pass it explicitly (`/code-review ultra <branch>`) ``; when Claude Code can’t tell whether your clone is shallow, it suggests `git fetch --unshallow origin` instead. Before v2.1.221, the hint suggested `git fetch --unshallow origin` for every fetched base branch, and on a complete clone that command fails with `fatal: --unshallow on a complete repository does not make sense`.

**What to do:**

- If another branch is your real base, pass it explicitly: `/code-review ultra <branch>`
- If your clone might not have full history, run `git fetch --unshallow origin` and rerun the review


[​](#your-checkout-has-no-branches)

Your checkout has no branches

A checkout can have commits but no branches: if you run `git init` followed by `git fetch <url>` and `git checkout FETCH_HEAD`, you get a detached HEAD with no refs. Claude Code packages your repository as a git bundle to upload it for an [ultrareview](ultrareview.md), and it can’t bundle a repository that has no branches or other refs, so `/code-review ultra` and the `claude ultrareview` subcommand refuse the review before the cloud session starts.

```python
Your checkout has no branches (detached HEAD only), which cloud review can't bundle. Create one first — `git checkout -b <name>` — then rerun /code-review ultra.
```

Before v2.1.221, Claude Code attempted to review every tracked file in this checkout, and the upload failed. **What to do:**

- Create a branch at your current commit with `git checkout -b <name>`, then rerun the review


[​](#no-github-account-is-connected-to-your-claude-account)

No GitHub account is connected to your Claude account

You ran `/code-review ultra <PR#>` or `claude ultrareview <PR#>`, and before creating the cloud session Claude Code asks the server whether [the GitHub account connected to your Claude account](ultrareview.md#review-a-pull-request) can reach the PR’s repository. No account is connected, or the connection expired, so the cloud clone would fail and Claude Code refuses the launch. Claude Code doesn’t spend a free run or bill usage credits for a refused launch.

```python
Ultrareview clones <owner>/<repo> in the cloud with the GitHub account connected to your Claude account, and none is connected (or the connection expired). To fix: run /web-setup to reuse your GitHub CLI login, or connect an account at https://claude.ai/connect-github — then re-run /code-review ultra 1234 (allow a minute after connecting).
```

When [`/web-setup`](web-quickstart.md#connect-from-your-terminal) isn’t available in your session, the message names only the claude.ai link. **What to do:**

- Run `/web-setup` to connect your GitHub CLI login to your Claude account, or connect an account at [claude.ai/connect-github](https://claude.ai/connect-github)
- Rerun the review a minute after connecting

Before v2.1.248, Claude Code didn’t check this before launch.


[​](#your-connected-github-account-cant-see-the-repository)

Your connected GitHub account can’t see the repository

You ran `/code-review ultra <PR#>` or `claude ultrareview <PR#>`, and [the GitHub account connected to your Claude account](ultrareview.md#review-a-pull-request) can’t read the PR’s repository, so the cloud clone would fail and Claude Code refuses the launch. Claude Code doesn’t spend a free run or bill usage credits for a refused launch.

```python
Your connected GitHub account can't see <owner>/<repo> — usually the Claude GitHub app isn't installed on <owner> or wasn't granted this repo (web-connected accounts need it for private repos), or a different GitHub account is connected. To fix: run /web-setup to reuse your GitHub CLI login, or install the app at https://github.com/apps/claude/installations/new — then re-run /code-review ultra 1234.
```

When [`/web-setup`](web-quickstart.md#connect-from-your-terminal) isn’t available in your session, the message names only the app install. **What to do:**

- If your local `gh` CLI can read the repository, run `/web-setup` to connect that login to your Claude account
- Rerun the review after the change

Before v2.1.248, Claude Code didn’t check this before launch.


[​](#the-github-app-preflight-failed-transiently)

The GitHub App preflight failed transiently

You started a [cloud session](claude-code-on-the-web.md) from a local repository, and two steps failed together. Claude Code couldn’t build or upload the bundle of your repository. Before the upload, it checked whether the cloud service can clone the repository from GitHub, and rather than a definite answer, that check ended in an error that a retry could clear, such as a network error, a timeout, or a temporary server error. The full message starts with what stopped the bundle, for example `Could not upload repo bundle (<error>)`, and ends with the preflight sentence:

```python
Could not upload repo bundle (<error>). The GitHub App preflight failed transiently (network or service hiccup) — retry in a moment to start from GitHub instead
```

**What to do:**

- Rerun the command after a moment. When the GitHub check passes, Claude Code can start the session from a GitHub clone, so the failed upload no longer blocks the launch
- If retries keep failing, the start of the message names what stopped the upload. When that cause is something you can fix, fix it so the session can start from your local repository instead

Before v2.1.251, Claude Code ended the message with `Please set up GitHub on https://claude.ai/code` even when the GitHub check failed only transiently, and setup advice can’t clear a transient failure.


[​](#the-repository-upload-cant-follow-a-git-setting)

The repository upload can’t follow a git setting

You started a [cloud session that uploads your local repository](claude-code-on-the-web.md#send-local-repositories-without-github), or an [ultrareview](ultrareview.md) of a branch, and the upload can’t follow one of the git settings that decide which attribute rules apply to your files. If the upload went ahead and missed a rule, a file that git transforms before storing it, such as one a clean filter encrypts, could reach the cloud as it is on disk. Claude Code refuses the upload instead, and nothing is uploaded:

```python
Not uploading this working tree: core.ignoreCase (which decides whether .gitattributes patterns match file names regardless of letter case) is set in <file>, and the upload cannot follow that setting, so a file git would change before storing it (to encrypt it, for example) could be uploaded as it is on disk. Move the core.ignoreCase line into this repository’s .git/config or directly into your ~/.gitconfig, then retry.
```

The message names the setting and where it’s set, and ends with the fix for the case you hit. The same refusal appears for `core.attributesFile` and `attr.tree`, each with its own fix. The message can name a config file that your git configuration pulls in through an `include` or `includeIf` directive, even when that directive’s condition doesn’t apply to this repository. **What to do:**

- Apply the fix in the message’s final sentence


[​](#github-isnt-connected-to-your-claude-account)


You started a [cloud session](claude-code-on-the-web.md) from your local repository, for example with `/autofix-pr`. No GitHub account is connected to your Claude account, or the connection expired, so Claude Code refuses the launch:

```python
```

When you create a cloud scheduled task with [`/schedule`](web-scheduled-tasks.md), the same message appears as a setup note that names the repository; the note doesn’t block creating the task. **What to do:**

- Run `/web-setup` to connect your GitHub CLI login to your Claude account, or connect an account at [claude.ai/connect-github](https://claude.ai/connect-github). See [GitHub authentication options](claude-code-on-the-web.md#github-authentication-options) for how the two differ.
- Rerun the command a minute after connecting

Before v2.1.268, Claude Code reported this as a temporary failure of the Claude GitHub App check and suggested retrying or installing the app; neither connects a GitHub account.


[​](#a-github-organization-policy-is-blocking-claude)

A GitHub organization policy is blocking Claude

You ran a command at the Claude Code prompt that starts a cloud session, such as [`/autofix-pr`](claude-code-on-the-web.md#auto-fix-pull-requests). Before it creates the session, Claude Code checks Claude’s access to the repository on GitHub, and GitHub refused because your GitHub organization has a policy that blocks Claude. Claude Code stops there and shows a message naming the policy. When an IP allow list is what blocks the access, the message reads:

```python
Your GitHub organization has an IP allowlist that is blocking Claude. Add Claude's IP ranges to your GitHub allowlist.
```

When single sign-on is what blocks it, the message reads:

```python
Your GitHub organization requires single sign-on. Disconnect and reconnect GitHub on the Connectors page in Claude on the web, click Authorize next to your organization when GitHub asks, then try again.
```

When a Microsoft Entra ID Conditional Access policy is what blocks it, the message reads:

```python
Your GitHub organization's identity provider (Microsoft Entra ID) has a Conditional Access policy that is blocking Claude. Ask your GitHub Enterprise or Entra ID admin to allow Claude in that policy.
```

**What to do:**

- **IP allow list**: ask an owner of your GitHub organization or enterprise to allow Anthropic’s outbound IP addresses. See [GitHub allow lists and firewalls](../13-Enterprise-Admin/network-config.md#github-allow-lists-and-firewalls) for the addresses and the GitHub settings to change.
- **Single sign-on**: disconnect GitHub at [claude.ai/customize/connectors](https://claude.ai/customize/connectors), then connect it again. When GitHub asks, click **Authorize** next to your organization so the new connection is authorized for its single sign-on.
- **Conditional Access policy**: ask your GitHub Enterprise or Microsoft Entra ID administrator to allow Claude in that policy
- After the change, run the command again


[​](#single-sign-on-authorization-needed)

Single sign-on authorization needed

You ran [`/install-github-app`](github-actions.md#quick-setup) and chose a repository whose organization enforces SAML single sign-on. Before setup, Claude Code checks your access to the repository with the GitHub CLI, and GitHub refused that check because your `gh` token isn’t authorized for the organization yet. The wizard shows the warning with the steps to authorize:

```python
Single sign-on authorization needed
<owner>/<repo> belongs to an organization that enforces SAML single sign-on, and your GitHub CLI token isn't authorized for it yet.
```

**What to do:**

- Re-authorize your GitHub CLI login with the `repo` and `workflow` scopes by running `gh auth refresh -h github.com -s repo,workflow`, and authorize the organization when GitHub prompts for single sign-on
- If you authenticate with a personal access token in `GH_TOKEN`, open [github.com/settings/tokens](https://github.com/settings/tokens), select **Configure SSO** on the token, and authorize the organization
- Run `/install-github-app` again

Before v2.1.273, Claude Code showed the `Admin permissions required` warning for this condition instead.


[​](#failed-to-resume-the-conversation)

Failed to resume the conversation

Claude Code couldn’t read or process the saved transcript for the session you selected from the [`claude --resume` picker](sessions.md#use-the-session-picker), so it ends the process rather than continue in a partially loaded state. The message includes the command to retry:

```python
Failed to resume the conversation.
Run claude --resume <session-id> to retry, or claude to start a new session.
```

Claude Code exits with code 1 after showing the message. The `/resume` picker inside a running session reports `Failed to resume conversation` in the conversation instead, and your current session keeps running. Before v2.1.216, a failed resume from the `claude --resume` picker stayed on the `Resuming conversation…` spinner indefinitely instead of showing this message. **What to do:**

- Run `claude --resume <session-id>` with the session ID from the message to retry
- On a version before v2.1.285, if the retry fails the same way, run `claude update` and resume again. Those versions fail the resume when the saved transcript contains an entry they can’t read.
- If the retry fails again, run `claude` to start a new session


[​](#no-conversation-found-with-the-session-id)

No conversation found with the session ID

You passed a session ID to `claude --resume <session-id>` and no saved transcript matched it:

```python
No conversation found with session ID: <session-id>
```

Claude Code exits with code 1 after showing the message. Claude Code [searches the current project first, then every other project on this machine](sessions.md#where-the-session-picker-looks) for the ID. Before v2.1.223, the lookup stopped at the current project directory and its git worktrees, so resume from the directory the session last worked in. Common causes:

- **Mistyped ID**: for a non-interactive run, the ID is the `session_id` field of the [`--output-format json` output](headless.md#get-structured-output)
- **Deleted transcript**: Claude Code removes transcripts after the [retention period](sessions.md#where-transcripts-are-stored), 30 days by default, following the [retention sweep rules](claude-directory.md#cleaned-up-automatically)
- **Different machine**: Claude Code stores transcripts locally, so resume the session on the machine where it ran
- **Duplicate copies**: if you copied a project directory under `~/.claude/projects` so two transcripts carry the same ID, Claude Code reports this message rather than resume one copy arbitrarily

**What to do:**

- For an interactive session, open the [session picker](sessions.md#use-the-session-picker) with `claude --resume` and press `Ctrl+A` to widen it to every project on this machine, then select the session
- Sessions created with `claude -p` or the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) don’t appear in the picker, so re-check the ID against the `session_id` your original run printed


[​](#windows-reported-an-error-ebadf)

Windows reported an error (EBADF) when Claude Code read this session’s transcript file

You resumed a session on Windows, its saved [transcript file](sessions.md#where-transcripts-are-stored) opened normally, and reading it then failed with the system error EBADF. The system error doesn’t say why the read failed, so the message suggests likely causes and what to try:

```python
Windows reported an error (EBADF) when Claude Code read this session's transcript file, although the file had opened normally. This can happen when other software intercepts file reads — security, encryption or endpoint-management tools, for example. If it keeps happening for this conversation, try excluding the folder that holds Claude Code's session transcripts from such software (the .claude folder in your user profile, unless the app or CLAUDE_CONFIG_DIR points Claude Code elsewhere), or adding Claude Code to its allowed applications, then resume again.
```

The message follows the command’s own failure line, such as `Failed to resume session <session-id>`. A `claude --resume` or [`claude -p`](headless.md) command exits with code 1 after showing it. After `/resume` inside a session, your current session keeps running. **What to do:**

- Exclude the folder that holds your session transcripts from software that scans or intercepts file reads, such as security, encryption, or endpoint-management tools. Transcripts live under `%USERPROFILE%\.claude\projects` by default, or under the directory [`CLAUDE_CONFIG_DIR`](env-vars.md) names
- If you can’t add an exclusion, add Claude Code to that software’s allowed applications instead
- Resume the session again

Before v2.1.282, the failure came with no explanation: `claude --resume <session-id>` ended at `Failed to resume session <session-id>`, and a `-p` run printed only the system error text, such as `Failed to resume session: EBADF: bad file descriptor, read`.


[​](#cannot-switch-renderers-in-this-session)

Cannot switch renderers in this session

When you switch renderers, Claude Code restarts its process. You ran [`/tui`](fullscreen.md#enable-fullscreen-rendering) in a session Claude Code declines to restart, so it doesn’t switch and saves nothing. Which message you see tells you the cause:

- `Cannot switch renderers while work is running in the background`: you have background work running that a restart would abandon, such as a background shell or a subagent. Wait for the work to finish or stop it with [`/tasks`](commands.md), then run `/tui fullscreen` or `/tui default` again
- `Cannot switch renderers in this session`: the session has restrictions Claude Code can’t pass to the restarted process. Before v2.1.234, Claude Code restarted anyway and the relaunched session ran without them

In the restrictions message, the part in parentheses names the restrictions Claude Code found:

```python
Cannot switch renderers in this session — it has restrictions a restart can't carry over (permission rules set for this session only). Nothing was changed. Running /tui fullscreen in a session started without them switches every later session too.
```

Each reason the message can show in parentheses:

- `launch flags: a custom system prompt, a tool allowlist, or restricted settings`: you started the session with a flag Claude Code doesn’t pass back to the restarted process. These flags include [`--system-prompt`](cli-reference.md#cli-flags), `--system-prompt-file`, `--append-system-prompt-file`, a [`--tools`](cli-reference.md#cli-flags) allowlist, [`--setting-sources`](cli-reference.md#cli-flags), and [`--permission-prompt-tool`](cli-reference.md#cli-flags)
- `permission rules set for this session only`: a [permission update](../07-Hooks/hooks.md#permission-update-entries) from a hook or SDK caller added deny or ask rules with the `session` destination. Session-scoped allow rules don’t trigger the refusal. A restart drops them, and Claude Code prompts again instead
- `ask-before-running rules with no command-line form`: a permission update from a hook or SDK caller added ask rules alongside the rules Claude Code passes back as `--allowed-tools` and `--disallowed-tools`. No flag exists for ask rules
- `permission rules a command line cannot carry intact` and `added directories a command line cannot carry intact`: a permission update added a rule or directory path mid-session. The restarted process’s command line can’t carry its text as the same value

**What to do:**

- In a session started without those restrictions, run `/tui fullscreen`, or `/tui default` to switch back. Claude Code saves the [`tui` setting](settings-reference.md#tui) there


[​](#claude-code-couldnt-restart)

Claude Code couldn’t restart

When this message says your conversation is saved, the conversation is on disk and you can pick it up where it stopped. Claude Code was restarting itself, for example to switch to or from fullscreen rendering after you ran [`/tui`](fullscreen.md#enable-fullscreen-rendering), and couldn’t start the new process, so it exited with status 1:

```python
Claude Code couldn't restart. Your conversation is saved. Start Claude Code again and run /resume to pick it up.
```

When the restart had no conversation to reopen, for example because `/tui` was your first input in a new session, the message reads `Claude Code couldn't restart. Start Claude Code again.` **What to do:**

- Run `claude` again in your shell. If the message said your conversation is saved, run [`/resume`](sessions.md#resume-a-session) in the new session and select the conversation. If it isn’t in the list, [widen the session picker](sessions.md#where-the-session-picker-looks)
- If restarts keep failing, start Claude Code from your shell with [`claude --debug-file claude-debug.log`](cli-reference.md#cli-flags). If a restart from that session fails, `claude-debug.log` in the directory you started from records a `Failed to relaunch:` line with the operating system’s error. Include that line when you [report the problem](#report-an-error)


[​](#couldnt-open-claude-desktop)

Couldn’t open Claude Desktop

You ran [`/desktop`](../16-Mobile-Desktop/desktop.md#coming-from-the-cli) or its alias `/app` in a session, or [`claude --desktop`](cli-reference.md#cli-flags) in your shell, and the system command Claude Code uses to open Claude Desktop failed. After `/desktop`, the session stays in the terminal; `claude --desktop` prints the message without the `Error:` prefix and exits with status 1. The text in parentheses names the command that failed, with its exit status and the first line of its error output when it produced them. On macOS that command is `open`, as in this example; on Windows it is `rundll32`:

```python
Error: Couldn't open Claude Desktop (`open` exited 1: LSOpenURLsWithRole() failed for the URL claude://resume?session=<session-id> with error -10814). Open Claude Desktop and try again.
```

**What to do:**

- Open Claude Desktop yourself, then run `/desktop` or `claude --desktop` again
- To read the failed command’s full error output, turn on debug logging with `/debug` and run `/desktop` again, or run `claude --desktop --debug-file <path>`, then check the debug log

Before v2.1.285, the message ended `Open Claude Desktop and run /desktop again.` Before v2.1.275, it was `Failed to open Claude Desktop. Please try opening it manually.` and didn’t say what failed.


[​](#terminal-setup-left-your-zed-keymap-unchanged)

/terminal-setup left your Zed keymap unchanged

You ran [`/terminal-setup`](terminal-config.md#enter-multiline-prompts) in Zed, and Claude Code couldn’t complete the update to your Zed `keymap.json`, so it left the file as it was. Each message names the path to your keymap and ends with the keybinding block to add yourself:

```python
Couldn't update your Zed keymap, so it was left unchanged.
To add the binding yourself, add this block to the keymap array in <path to keymap.json>:
{ "context": "Terminal", "bindings": { "shift-enter": ["terminal::SendText", "\u001b\r"] } }
```

The first line of the message names the cause:

- `Couldn't read your Zed keymap, so it was left unchanged.`: Claude Code couldn’t read the file, for example because of file permissions
- `Your Zed keymap isn't a readable list of keybindings, so it was left unchanged.`: the file read fine but doesn’t parse as an array of keybinding blocks, even with `//` comments and trailing commas allowed
- `Couldn't back up your Zed keymap; not modifying it.`: Claude Code couldn’t copy the file to a `.bak` backup beside it, so it changed nothing
- `Couldn't update your Zed keymap, so it was left unchanged.`: the merged result didn’t verify as a valid keymap carrying the binding, so Claude Code discarded it instead of writing. A keybinding block with a duplicated key can cause this

**What to do:**

- Copy the block from the message into the top-level array in your `keymap.json` at the path the message names
- For `isn't a readable list of keybindings`, fix the syntax error, or make the file’s top-level value an array, then run `/terminal-setup` again

Before v2.1.247, `/terminal-setup` couldn’t parse a Zed keymap that used `//` comments or trailing commas, and it replaced the entire file with only its own binding while reporting the binding as installed. To restore a keymap an earlier version replaced, use the `.bak` backup file described under [Enter multiline prompts](terminal-config.md#enter-multiline-prompts).


[​](#skill-usage-reports-are-not-available-on-this-connection)

Skill usage reports are not available on this connection

You ran [`/skill-doctor`](../08-Plugins-Skills/skills.md#find-unused-skills) over [Remote Control](remote-control.md), from your phone or browser. Claude Code doesn’t send the skill usage report over Remote Control and replies with this message instead:

```python
Skill usage reports are not available on this connection.
```

**What to do:**

- Run `/skill-doctor` in the terminal on the machine where the session is running, or run `claude -p "/skill-doctor"` there


[​](#custom-output-styles-cant-be-selected-over-remote-control)

Custom output styles can’t be selected over Remote Control

You ran [`/output-style`](output-styles.md#change-your-output-style) from the mobile app or web via [Remote Control](remote-control.md), or the command arrived in a message relayed into the session. Because such a turn may not come from the account owner, Claude Code lists and selects only [built-in styles](output-styles.md#built-in-output-styles) on it, and adds this notice whenever the command lists the styles or doesn’t recognize the name you gave. A [custom style](output-styles.md#create-a-custom-output-style) name gets the same reply as a name that doesn’t exist:

```python
Custom output styles can't be selected over Remote Control or from a relayed message. Select one in the session itself, or pick a built-in style here.
```

**What to do:**

- Pick a built-in style, for example `/output-style concise`
- To use a custom style, set [`outputStyle`](settings-reference.md#outputstyle) in the project’s `.claude/settings.local.json`, or run `/output-style <style>` at the session’s own terminal if it has one


[​](#output-styles-are-saved-to-local-settings-which-this-session-doesnt-load)

Output styles are saved to local settings which this session doesn’t load

You tried to switch [output styles](output-styles.md) with `/output-style <style>` or `/config outputStyle=<style>` in a session whose setting sources exclude `local`. Examples are an [Agent SDK](../05-Agent-SDK/agent-sdk-typescript.md) session whose [`settingSources`](../05-Agent-SDK/agent-sdk-typescript.md#options) leaves out `"local"` and a CLI session started with a [`--setting-sources`](cli-reference.md#cli-flags) value that leaves out `local`. Both commands save the style to `.claude/settings.local.json`, a file such a session never reads back, so Claude Code refuses instead of writing a setting that would have no effect:

```python
Output styles are saved to local settings (.claude/settings.local.json), which this session doesn't load, so the style can't be changed here.
```

**What to do:**

- Add `local` to the session’s setting sources and switch again
- Set the [`outputStyle`](settings-reference.md#outputstyle) key in a settings file the session does load, such as `.claude/settings.json` in the project or `~/.claude/settings.json`. In the TypeScript SDK, set `outputStyle` inside the inline `settings` object instead; see [Activate an output style](../05-Agent-SDK/agent-sdk-modifying-system-prompts.md#activate-an-output-style)


[​](#recap-only-runs-when-you-ask-for-it-yourself)

/recap only runs when you ask for it yourself

The [`/recap`](interactive-mode.md#session-recap) request didn’t come from your own input. It arrived in a message relayed into the session from a Slack, Teams, or [project](claude-projects.md) thread, or in a prompt that a [cloud scheduled task](web-scheduled-tasks.md) or another program sent. A relayed message gets the notice even when you wrote it yourself. Claude Code can’t tell that a relayed or automated message came from the person whose account runs the session, so it answers with this notice instead of a summary:

```python
/recap only runs when you ask for it yourself in this session: from the terminal, the Claude app or claude.ai/code, or over Remote Control. A message relayed from Slack, Teams or a project thread, or sent by a routine or another program, can't request it.
```

A `/recap` you pass to `claude -p`, or that your own [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) application sends to a session it launched, counts as your own input. **What to do:**

- Open the session yourself and run `/recap` there: in its terminal, in the [Desktop app](../16-Mobile-Desktop/desktop.md) or the [mobile app](../16-Mobile-Desktop/mobile.md), at [claude.ai/code](https://claude.ai/code), or over [Remote Control](remote-control.md)
- If a cloud scheduled task or another program sent it, remove `/recap` from that prompt


[​](#feedback-is-disabled-by-your-organizations-policy)

/feedback is disabled by your organization’s policy

This message means your organization’s policy doesn’t allow product feedback from Claude Code, so `/feedback`, `/bug`, and `/share` don’t open the feedback dialog. The message names the command you typed at the Claude Code prompt:

```python
/feedback is disabled by your organization's policy. To report a bug, open an issue at https://github.com/anthropics/claude-code/issues. Issues are public, so leave out anything confidential.
```

The message can also be its first sentence alone. **What to do:**

- To report a bug, open an issue at [github.com/anthropics/claude-code/issues](https://github.com/anthropics/claude-code/issues). Anyone can read issues there, so leave out code, transcripts, and anything else confidential.

Before v2.1.302, the full message read `/feedback is disabled by your organization's policy. Contact your organization admin to enable it.`


[​](#plugin-errors)

Plugin errors

These errors come from [plugin](../08-Plugins-Skills/plugins.md) and [marketplace](../08-Plugins-Skills/plugins.md) configuration. For plugin problems that don’t produce one of the messages on this page, such as a marketplace URL that doesn’t load or a plugin that installs but doesn’t appear, see [Plugin troubleshooting](../08-Plugins-Skills/plugins-troubleshooting.md).


[​](#plugin-eval-is-currently-in-early-access)

plugin eval is currently in early access

You ran [`claude plugin eval`](../08-Plugins-Skills/plugin-evals.md) or `claude plugin eval init` and it exited 1 with one of these messages before doing anything:

```python
`plugin eval` is currently in early access
```

```python
`plugin eval` is currently unavailable
```

The first message means your build is older than v2.1.269, the first version where the command is generally available. The second means Anthropic has switched the command off server-side; nothing on your machine turns it back on. **What to do:**

- Run `claude --version`, then `claude update`, and run the command again in a fresh session. See the [requirements for plugin evals](../08-Plugins-Skills/plugin-evals.md#requirements)
- If you see the second message on a current build, try again later after another `claude update`


[​](#marketplace-is-registered-from-an-untrusted-source)

Marketplace is registered from an untrusted source

The marketplace is registered under a name that is [reserved for official Anthropic marketplaces](../08-Plugins-Skills/plugins-marketplace-reference.md#marketplace-file), but its registered source isn’t an `anthropics` GitHub repository. Claude Code re-checks reserved names every time it loads or refreshes a marketplace, so the marketplace and the plugins installed from it stop loading. Before v2.1.205, an entry registered before its name became reserved kept loading.

```python
Marketplace "claude-community" is registered from an untrusted source: The name 'claude-community' is reserved for official Anthropic marketplaces. Only repositories from 'github.com/anthropics/' can use this name. To fix it, remove the marketplace and re-add it from the official source.
```

For a marketplace whose source isn’t a GitHub repository or a Git URL, such as a local directory, the middle sentence reads `can only be used with GitHub sources from the 'anthropics' organization` instead. `claude plugin marketplace add` runs the same check, and refuses a reserved name with `Failed to add marketplace:` followed by the same reserved-name sentence. **What to do:**

- If the marketplace is already registered, run `claude plugin marketplace remove <name>`, then add it again from the official `github.com/anthropics` repository
- If you publish a third-party marketplace that used the name before it became reserved, rename it and ask users to re-add it from your source
- See the reserved name list under [Marketplace schema](../08-Plugins-Skills/plugins-marketplace-reference.md#marketplace-file)


[​](#marketplace-name-is-another-spelling-of-a-reserved-name)

Marketplace name is another spelling of a reserved name

The marketplace’s name isn’t itself a reserved name, but Claude Code treats it as another spelling of one. [Reserved names](../08-Plugins-Skills/plugins-marketplace-reference.md#reserved-name-spellings) lists which spellings count as a reserved name. Claude Code refuses such a name when you add the marketplace:

```python
Failed to add marketplace: "claude.code.plugins" is another spelling of "claude-code-plugins", a reserved marketplace name.
```

When a marketplace is already registered under such a name, its entry stops loading, and `/plugin`, `claude plugin install`, and `claude plugin update` warn:

```python
known_marketplaces.json has an entry named "claude.code.plugins", another spelling of the reserved marketplace name "claude-code-plugins", so it is ignored. Remove it with: claude plugin marketplace remove claude.code.plugins
```

When the name would need shell quoting, the add-time refusal reads `This marketplace's name is another spelling of "<reserved>", a reserved marketplace name. It is not exactly the reserved name it appears to be.` **What to do:**

- Rename the marketplace to a name that doesn’t spell a reserved name and add it again
- For the ignored-entry warning, run the `claude plugin marketplace remove` command it gives, or remove the entry from `~/.claude/plugins/known_marketplaces.json`


[​](#claude-code-refuses-the-marketplace-name)

Claude Code refuses the marketplace name

A registered marketplace’s name [impersonates an official Anthropic marketplace](../08-Plugins-Skills/plugins-marketplace-reference.md#reserved-names) under the rules that section lists. If a marketplace was registered under such a name before the check blocked it, the marketplace and the plugins installed from it stop loading, because Claude Code checks the name every time it reads the marketplace’s catalog. When the name imitates an official one, `claude plugin list` and the `/plugin` **Errors** tab report each affected plugin with a message that begins:

```python
Claude Code refuses the marketplace name "anthropic-plugins-v2"
```

For an imitating name, the marketplace’s own error reads `Claude Code refuses this marketplace's name: it looks like one of Anthropic's own` instead. `claude plugin marketplace add` refuses any impersonating name with `Marketplace name impersonates an official Anthropic/Claude marketplace`. Before v2.1.282, `claude plugin list` and `/plugin` reported the plugins of an imitating name as failed to load too, without naming the marketplace’s name as the cause. **What to do:**

- To keep a marketplace that a settings file declares inline with `"source": "settings"`, rename it before you remove the old name, because removing the marketplace also deletes its entry from your settings files. Claude Code v2.1.292 or later lists these steps in the message:
  1.  In each settings file that lists the marketplace under `extraKnownMarketplaces`, give the entry’s key and its `source.name` one new plain-ASCII name that doesn’t look like an official one. If an administrator adds the marketplace through your organization’s managed settings, the administrator does this step
  2.  Run `claude plugin marketplace remove <old-name>`, or remove the old name in the **Marketplaces** tab in `/plugin`. This also uninstalls its plugins and deletes their data, options, and secrets
  3.  Start Claude Code again, in the project’s folder if the file is a project’s settings file. Then install the plugins from the renamed marketplace
- To keep any other marketplace, wait until its maintainer renames it, then run `claude plugin marketplace update <name>`
- To remove the marketplace, run `claude plugin marketplace remove <name>`. This also uninstalls the plugins installed from the marketplace and deletes their data, options, and secrets
- If you publish the marketplace, rename it in your `marketplace.json`; users then update the marketplace instead of removing it


[​](#marketplace-is-already-added-from-a-different-source)

Marketplace is already added from a different source

You named a new marketplace source with [`--marketplace <source>` on the install command](../08-Plugins-Skills/discover-plugins.md#add-a-marketplace-and-install-in-one-command), in a session or from your shell. The catalog Claude Code fetched from that source has the same name as a marketplace you already added from a different source. Claude Code keeps the existing marketplace instead of replacing it, and the plugin isn’t installed.

```python
Marketplace "acme-tools" is already added from a different source (github:acme/plugins). To use this source instead, remove that marketplace first with /plugin marketplace remove acme-tools.
```

**What to do:**

- If the marketplace you already added is the one you want, install from it by name: `/plugin install <plugin>@<name>`
- To switch to the new source, run `/plugin marketplace remove <name>`, then retry the install


[​](#plugin-command-references-user-config)

Plugin command references user_config in a shell command

A plugin hook, [monitor](../08-Plugins-Skills/plugins-components.md#monitors), or MCP [`headersHelper`](../06-MCP-Tools/General/mcp.md#use-dynamic-headers-for-custom-authentication) command references a `${user_config.KEY}` [plugin option](../08-Plugins-Skills/plugins-reference.md#user-configuration), and the substituted string would be passed to a shell. A configured value containing `$(...)`, backticks, or `;` would run as code there, so Claude Code refuses to start the component instead of substituting the value. The check runs on the command template, so the error appears even when no value is configured yet. Before v2.1.207, the value was substituted into the shell command. The wording depends on which surface referenced the option. A shell-form hook reports:

```python
Hook from plugin formatter@acme-tools references ${user_config.*} in a shell-form command. The substituted value would be re-parsed by the shell. Use exec form instead — {"command": "<executable>", "args": ["${user_config.KEY}", ...]} — or read $CLAUDE_PLUGIN_OPTION_<KEY> from the hook's environment. Command: ./scripts/notify.sh ${user_config.webhook_url}
```

A monitor reports:

```python
Monitor "deploy-status" from plugin deploy-tools references ${user_config.*} in its command. The substituted value would be passed to a shell. Monitor commands cannot safely reference ${user_config.*}; have the monitor script read the value from a config file or prompt instead.
```

An MCP `headersHelper` reports:

```python
headersHelper for MCP server 'internal-api' references ${user_config.*}. The substituted value would be passed to a shell; read the value inside the helper script instead (e.g. from an env var set in the server's "env" block).
```

**What to do:**

- For a hook, add an `args` array so it runs in [exec form](../07-Hooks/hooks.md#exec-form-and-shell-form), where each `${user_config.KEY}` becomes one argument with no shell in between. Or drop the reference and read the `$CLAUDE_PLUGIN_OPTION_<KEY>` environment variable inside the script
- For a monitor, drop the reference and have the monitor script read the value from a config file
- For a `headersHelper`, move `${user_config.KEY}` into the server’s `headers` field, which isn’t shell-parsed, or read the value inside the helper script


[​](#plugin-archive-integrity-check-failed)

Plugin archive integrity check failed

The plugin’s marketplace entry uses an [`archive` source](../08-Plugins-Skills/plugins-marketplace-reference.md#archive-plugin-source) with a `sha256` pin, and the digest of the downloaded file doesn’t match the pin. Claude Code refuses the install, so nothing changes in the plugin cache. The mismatch has three possible causes:

- The file at the URL changed after the author computed the pin
- The author entered the wrong digest in the marketplace entry
- The URL serves a different file than the author pinned

```python
Plugin archive integrity check failed for https://artifacts.example.com/claude-plugins/my-plugin.zip: expected sha256 6bfa50e3d2e00c052b46abe51fff89346ac803e45771f76dcf6df1ab74cca5e1, got ac52220c0914ef8ca6a602e4a7362f88d30fb021110f72a6d15b68c3fe7df2b7. The archive was not installed. Verify the sha256 in the marketplace entry, or that the URL serves the intended file.
```

**What to do:**

- If you publish the plugin, recompute the digest of the exact file the URL serves, for example with `shasum -a 256 my-plugin.zip`, or `Get-FileHash -Algorithm SHA256 my-plugin.zip` in PowerShell, and update the `sha256` in the marketplace entry
- If you install the plugin, run `/plugin marketplace update <name>` to refresh the catalog in case the entry was corrected, then retry the install
- If the digests still disagree after a refresh, ask the marketplace owner which file they pinned before installing


[​](#path-escapes-plugin-directory)

Path escapes plugin directory

One of the plugin’s component paths leads outside the plugin directory or couldn’t be confirmed inside it, so Claude Code drops that path and loads the rest of the plugin. For a path the plugin declares in `plugin.json` or its [marketplace entry](../08-Plugins-Skills/plugins-marketplace-reference.md#plugin-entries), the component name in the message, such as `commands` or `hooks`, names the field that declared the path.

```python
commands path escapes plugin directory: ./../shared.md
```

In `claude plugin` command output, the same error reads `Path escapes plugin directory: ./../shared.md (commands)`. Claude Code rejects both a path that points outside the plugin as written, such as `../shared-utils`, and a symlink that leads outside the plugin and isn’t one the [marketplace symlink rules](../08-Plugins-Skills/plugins-host-marketplace.md#share-files-within-a-marketplace-with-symlinks) allow. For a symlink, the message also says where the path resolves:

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

A 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](../08-Plugins-Skills/plugins-loading.md#in-place-and-copied-plugins), inside that marketplace. The message reports each of these files under the component name shown:

- `hooks/hooks.json`: `hooks`
- `monitors/monitors.json`: `monitors`
- `settings.json`: `settings`
- `SKILL.md` at the plugin root: `skills`

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

```python
hooks path escapes plugin directory: /home/user/my-marketplace/my-plugin/hooks/hooks.json — it resolves to /home/user/dotfiles/hooks.json, outside the plugin directory and its marketplace directory
```

On macOS and Linux, Claude Code also rejects a component path that contains a backslash anywhere in it, even when the path stays inside the plugin. A plugin whose component paths use Windows-style separators loads on Windows and triggers this rejection on the other platforms:

```python
commands path escapes plugin directory: ./commands\deploy.md — its path contains a backslash, which is not resolved reliably on this platform
```

Before v2.1.251, Claude Code loaded a `commands` path declared in a marketplace entry even when it pointed outside the plugin directory. Before v2.1.257, the check on paths the plugin declares looked only at the path’s spelling, not at where a symlink leads. **What to do:**

- If you installed the plugin and don’t maintain it, report the message to its author
- For a path the plugin declares, move the referenced file inside the plugin directory and point the path at it with a `./` relative path
- If the path, or a folder above it inside the plugin, is a symlink leading outside the plugin, replace the symlink with a copy of what it points to
- If the message says a path the plugin declares contains a backslash, write the path with forward slashes, for example `./commands/deploy.md`
- If the message ends with `EACCES`, restore your execute permission on every directory leading to the file or folder the path names. Check the directories above the path, then follow each symlink you reach and check the directories leading to where it points. For any other error code, look it up in the [causes and steps for a path that couldn’t be checked](#path-could-not-be-checked).
- To share files with other plugins in the same marketplace, link them with a symlink inside the plugin directory, following the [symlink rules](../08-Plugins-Skills/plugins-host-marketplace.md#share-files-within-a-marketplace-with-symlinks)


[​](#plugin-not-loaded-its-manifest-was-not-read)

Plugin not loaded: its manifest was not read

Claude Code couldn’t confirm that a marketplace plugin’s [manifest](../08-Plugins-Skills/plugins-reference.md) at `.claude-plugin/plugin.json` is inside the plugin, so it loads nothing from that plugin. For a plugin in a [local marketplace](../08-Plugins-Skills/plugins-loading.md#in-place-and-copied-plugins), Claude Code also couldn’t confirm that the manifest is inside that marketplace. The message appears in the `/plugin` **Errors** tab, and the reason at its end says what Claude Code found. For example, this message is for a plugin in a local marketplace whose `.claude-plugin` folder is a symlink leading outside the marketplace:

```python
Plugin not loaded: its manifest /home/user/my-marketplace/my-plugin/.claude-plugin/plugin.json was not read, because it resolves to /home/user/dotfiles/my-plugin/.claude-plugin/plugin.json, outside the plugin directory and its marketplace directory
```

**What to do:**

- If the reason ends with `EACCES`, restore your execute permission on every directory leading to the manifest. Check the directories above the manifest, then follow each symlink you reach and check the directories leading to where it points. For any other error code, look it up in the [causes and steps for a path that couldn’t be checked](#path-could-not-be-checked).
- If you maintain the plugin and the reason says where the manifest resolves, the `.claude-plugin` folder or `plugin.json` itself is a symlink that leads there. Replace that link with a copy of what it points to.
- If you installed the plugin and don’t maintain it, report the message to its author


[​](#path-could-not-be-checked)

Path could not be checked

Claude Code asked the operating system whether a plugin path exists and got an error other than “not found”, so it doesn’t load what the path names. How much of the plugin loads depends on which path failed:

- One of a plugin’s [default component locations](../08-Plugins-Skills/plugins-reference.md#standard-layout), such as the `skills/` folder, the `monitors/monitors.json` file, or a [`SKILL.md` at the plugin root](../08-Plugins-Skills/plugins-components.md#skills): the plugin’s other components still load
- The plugin’s own directory: nothing from that plugin loads

You don’t see this error for a path that doesn’t exist at all. In `/plugin`, the error appears under the plugin and names the path and the code the operating system returned:

```python
skills path could not be checked: /home/user/my-plugin/skills (ELOOP)
```

In `claude plugin list`, the same error reads `Path not found: /home/user/my-plugin/skills (skills, ELOOP)`. Causes that produce this error include:

- `ELOOP`: a symlink in the path points at itself or forms a loop
- `EIO` or `ESTALE`: the path is on a network mount that is broken or stale
- `EACCES`: one of the directories above the path denies you permission to traverse it

**What to do:**

- Replace a symlink that points at itself with a real folder, or delete it
- If the path is on a network mount, remount the share
- If the code is `EACCES`, restore your execute permission on the directories above the path
- Run `/reload-plugins` after fixing the path, or restart Claude Code, to load the plugin or component

Before v2.1.265, Claude Code treated a default component folder it couldn’t check as absent and loaded the plugin without that component, with no error.


[​](#marketplace-entry-path-does-not-stay-inside-the-marketplace-directory)

Marketplace entry path does not stay inside the marketplace directory

The plugin’s [marketplace entry](../08-Plugins-Skills/plugins-marketplace-reference.md#plugin-entries) declares a source path that Claude Code can’t resolve to a location inside the marketplace’s own directory, so the plugin doesn’t install or load. The refusal covers:

- An entry path that is absolute, climbs out of the marketplace with `..`, or is spelled like a network path
- On macOS and Linux, an entry path that contains a backslash anywhere after the leading `./`
- An entry in a marketplace fetched from a remote source, such as git or a URL, that reaches its target through a symlink resolving outside the marketplace directory
- A relative entry in a marketplace added from a direct URL to its `marketplace.json`: Claude Code downloads only that file, so no local plugin files exist for the path to name. See [Plugins with relative paths fail in URL-based marketplaces](../08-Plugins-Skills/plugins-troubleshooting.md#plugins-with-relative-paths-fail-in-url-based-marketplaces)

`claude plugin install` reports the refusal like this:

```python
Cannot install my-plugin@my-marketplace: its marketplace entry path does not stay inside the marketplace directory (an absolute, climbing, network-shaped, backslash-containing or link-traversing entry, an entry of a fetched marketplace that resolves or opens outside its tree — or a relative entry in a url-catalog marketplace, which has no local directory)
```

When an already-installed plugin’s entry fails the same check, `claude plugin list` shows the plugin as `failed to load` with:

```python
Plugin source path refused: ./my-plugin does not stay inside its marketplace directory. Check that the marketplace entry has a plain relative path.
```

**What to do:**

- If you maintain the marketplace, write the entry’s `source` as a plain relative path with forward slashes, such as `./plugins/my-plugin`, and keep any symlink it crosses pointed inside the marketplace directory
- If you added the marketplace from a direct URL, relative entries can’t resolve. Ask the marketplace author to use [another plugin source](../08-Plugins-Skills/plugins-marketplace-reference.md#plugin-sources), or add the marketplace from its git repository instead


[​](#failed-to-load-marketplace-configuration)

Failed to load marketplace configuration

Claude Code keeps the plugin marketplaces you’ve added in a registry file at `~/.claude/plugins/known_marketplaces.json`. A plugin command that needs the registry, such as `claude plugin install`, fails with one of two messages when Claude Code can’t use the file:

- `Failed to load marketplace configuration`: the file exists but isn’t valid JSON or can’t be read. An empty file fails this way too.
- `Marketplace configuration file is corrupted`: the file is valid JSON but its contents don’t match the registry schema.

With an empty file, `claude plugin install` reports:

```python
✘ Failed to install plugin "my-plugin": Failed to load marketplace configuration: JSON Parse error: Unexpected EOF
```

Before v2.1.246, `claude plugin install` didn’t report this failure. **What to do:**

- Open `~/.claude/plugins/known_marketplaces.json` and repair the JSON, or fix the entries the message names as not matching the registry schema
- If you can’t repair it, delete the file or replace its contents with `{}`, then re-add each marketplace with `claude plugin marketplace add <source>`. Claude Code re-registers the marketplaces your user or managed settings declare in [`extraKnownMarketplaces`](settings-reference.md#extraknownmarketplaces) the next time you start it in a folder you’ve trusted.


[​](#plugin-is-required-by-your-organization)

Plugin is required by your organization

You ran `claude plugin disable`, or used the `/plugin` **Installed** tab, to turn off a [plugin synced from claude.ai](../08-Plugins-Skills/plugins-loading.md#synced-plugins) that your organization marks as required:

```python
Plugin "<name>@synced" is required by your organization and can't be disabled here. Contact your admin to change it.
```

Claude Code saves nothing and the plugin stays enabled. When you try to disable a plugin that a required plugin depends on, Claude Code refuses the same way, with a message naming the required plugin that needs it. **What to do:**

- Ask an admin of your claude.ai organization to change the plugin’s required status on claude.ai


[​](#plugin-was-not-uninstalled)

Plugin was not uninstalled

You ran [`claude plugin uninstall`](../08-Plugins-Skills/plugins-cli-reference.md#plugin-uninstall), or chose **Uninstall** in the `/plugin` **Installed** tab, and the uninstall stopped with a message starting `"<plugin>" was not uninstalled:`. If the text after that colon starts with `installed_plugins.json` instead of naming a settings file, the cause is content in `installed_plugins.json` that this version of Claude Code can’t read. For that form, see [`installed_plugins.json` holds a record this version can’t read](../08-Plugins-Skills/plugins-troubleshooting.md#installed-plugins-json-holds-a-record-this-version-cannot-read). When Claude Code removed the plugin’s entry from `enabledPlugins` and read that scope’s settings files back, either the plugin was still switched on there, or a file that could switch it on couldn’t be read or checked. Deleting the plugin’s saved options, secrets, and data while a settings entry could switch it back on would lose them, so the uninstall stops instead: the plugin stays installed and nothing it saved is deleted.

```python
✘ Failed to uninstall plugin "formatter": "formatter" was not uninstalled: it is still switched on in /home/user/project/.claude/settings.local.json, although the settings change reported no error. It is still installed. Take it out of "enabledPlugins" in that file yourself, then uninstall it again.
```

The middle of the message names the file and the cause:

- `it is still switched on in <file>, although the settings change reported no error`: the settings write reported success but the entry is still there when the file is read back
- `it is still switched on in <file>, and the settings change failed (<error>)`: the file couldn’t be saved, for the reason in parentheses
- `<file> is there and could not be read`: the file exists but couldn’t be read as settings, for example because it isn’t valid JSON, so it may still enable the plugin
- `<file> (not read: it is on a network path or is a link to one, or could not be checked)`: Claude Code didn’t read the project or local settings file because the file, or the `.claude` folder that holds it, is a link that leads to a network location, or because it couldn’t examine that path

`claude plugin uninstall` exits 1, and with `--json` the result carries `failureCode: "settings_still_on"`. `/plugin` shows the same message. **What to do:**

- Follow the last sentence of the message: repair or replace the settings file it names, or remove the plugin’s entry from `enabledPlugins` in that file yourself, then run the uninstall again


[​](#skipping-connection-recent-failure-cached)

Skipping connection (recent failure cached; retries automatically in 15 min, or edit the plugin config to retry now)

This message means Claude Code didn’t start a stdio [MCP server that a plugin provides](../06-MCP-Tools/General/mcp.md#plugin-provided-mcp-servers), because a connection to that server failed less than 15 minutes earlier:

```python
Skipping connection (recent failure cached; retries automatically in 15 min, or edit the plugin config to retry now)
```

The session continues without the server’s tools, and Claude Code doesn’t try the server again in that session when the 15 minutes end. When you start a new session or [`claude -p`](headless.md) run at least 15 minutes after the most recent failed connection, Claude Code tries the server again. **What to do:** To have Claude Code try the server again without waiting:

- **In an interactive session**: run `/mcp`, select the server, and select **Reconnect**
- **In an [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) application**: call [`reconnectMcpServer()`](../05-Agent-SDK/agent-sdk-typescript.md#methods) in TypeScript or [`ClaudeSDKClient.reconnect_mcp_server()`](../05-Agent-SDK/agent-sdk-python.md#methods) in Python with the server’s name
- **In `claude -p`**: start an interactive session that loads the same plugin, on the same machine and with the same operating system account and [`CLAUDE_CONFIG_DIR`](env-vars.md) value as your runs. Reconnect the server there from `/mcp`. Once it connects, Claude Code tries the connection in your next run.
- **If you’re developing the plugin**: change the server’s `command`, `args`, or `env` in the plugin’s `.mcp.json` or `plugin.json`. Claude Code tries the connection in the next session or `claude -p` run that loads the changed entry.

The message replaces the error from the failed connection. If the new attempt fails too, Claude Code reports that attempt’s error instead of this message.


[​](#tool-errors)

Tool errors

These errors come from Claude’s tool calls. Claude corrects most tool errors on its own. When one needs a change from you, that error’s **What to do** list says what to change.


[​](#no-such-tool-available)

No such tool available

Claude called a tool by a name that isn’t in the session’s tool list. Claude Code returns the error to Claude as the tool call’s result, and the turn continues. When Claude Code can tell why the tool is missing, it adds a sentence after the tool name that gives the reason or names the tool to call instead, as in the second line:

```python
Error: No such tool available: <tool name>
Error: No such tool available: read. Tool names are case-sensitive: call Read instead.
```

Right after you resume a session, an MCP server can still be on its first connection attempt when Claude calls one of its tools. Claude Code then [waits for the server](../06-MCP-Tools/General/mcp.md#tool-availability) and returns this error if the tool still isn’t available when the wait ends. Before v2.1.284, such a call failed at once instead of waiting. A call whose tool name Claude Code [cut to 200 characters](#tool-use-name-over-200-characters) also fails with this error. **What to do:**

- If it happens once, you don’t need to do anything. Claude reads the error and the turn continues.
- If calls to an MCP server’s tools keep failing with this error, run `/mcp` in the session or `claude mcp list` in your shell to check the server’s [status](../06-MCP-Tools/General/mcp.md#server-status), and reconnect a failed server from `/mcp`. In the Agent SDK, see [Error handling](../05-Agent-SDK/agent-sdk-mcp.md#error-handling).


[​](#connection-closed-before-the-tool-call-was-answered)

MCP server connection closed before the tool call was answered

A tool call to an HTTP [MCP server](../06-MCP-Tools/General/mcp.md) or a [claude.ai connector](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) lost its connection before the server answered, so Claude Code can’t tell whether the tool ran:

```python
MCP server "<name>" connection closed before the tool call was answered. The tool may have run: check whether it did before running it again.
```

Repeating the call could repeat the tool’s action, such as creating a second issue. Claude Code therefore repeats the call on its own, once, when the server marks the tool as safe to repeat. **What to do:**

- Check in the service the tool acts on whether the action happened, for example whether the issue or record it was meant to create is there
- If the action happened, don’t run the tool again. Claude received this message in place of the tool’s result, so tell Claude the outcome.
- If the action didn’t happen, ask Claude to run the tool again. You don’t need to reconnect the server first, because Claude Code connects to it again for the next call to one of its tools. If that connection fails too, see [Mid-session drops of a remote server](../06-MCP-Tools/General/mcp.md#mid-session-drops-of-a-remote-server).
- If you build the server and the tool is safe to call twice, [mark it as safe to repeat](../06-MCP-Tools/General/mcp.md#tool-calls-pending-when-a-connection-closes) so that Claude Code can repeat a lost call


[​](#agent-would-be-spawned-with-zero-tools)

Agent would be spawned with zero tools

Every entry in the subagent’s [`tools` list](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields) failed to match a usable tool, so Claude Code refused to launch the subagent: with no tools, it couldn’t act. The message groups your entries by what went wrong:

- **Unrecognized**: the entry matches no tool name, usually a typo such as `Grpe` for `Grep`.
- **Not available to subagents**: the entry names a real tool that [subagents can’t use](../09-Agents-Patterns/sub-agents.md#available-tools). Background subagents keep a smaller built-in tool set, so an entry that only a foreground subagent can use lands here when the subagent would run in the background, which is the default. If you list `Agent`, the message reports it under the next group instead.
- **Matched no tools in this session**: the entry is valid but no tool in the current session matches it right now, such as `mcp__github__*` with no GitHub MCP server connected, or `Agent` for a subagent at the [depth limit](../09-Agents-Patterns/sub-agents.md#let-subagents-spawn-their-own-subagents).

Omitting the `tools` field never triggers this refusal. If you leave the `tools` list empty, or `disallowedTools` removes every entry in it, Claude Code also skips the refusal and launches the subagent without tools. Before v2.1.208, the subagent launched with no tools and could return an empty or confusing result.

```python
Agent 'code-reviewer' would be spawned with zero tools — refusing. Its tools list resolved to nothing: unrecognized [Grpe]. Fix the agent's tools frontmatter or pass a different subagent_type.
```

**What to do:**

- Correct each entry the error names against the [tools available to subagents](../09-Agents-Patterns/sub-agents.md#available-tools)
- Remove entries for tools the session doesn’t have, such as MCP tools from a server that isn’t connected
- If the entry names a connected MCP server, compare the entry with that server’s name as the server’s [tool names](permissions.md#mcp) spell it, such as `reports__v2` in `mcp__reports__v2__get_totals`. For that server, write `mcp__reports__v2__*`, which is `mcp__` followed by the whole name and `__*`. With the shorter `mcp__reports`, which names a server called `reports`, the subagent gets none of the `reports__v2` tools
- For a tool that [background subagents drop](../09-Agents-Patterns/sub-agents.md#available-tools), such as `CronCreate`, remove the entry
- To keep a tool such as `CronCreate` instead, [let Claude wait for the subagent](../09-Agents-Patterns/sub-agents.md#let-claude-wait-for-a-subagent), since a subagent Claude waits for runs in the foreground and keeps the tool. If the definition sets `background: true`, remove that field first, because it keeps the subagent in the background
- Delete the `tools` field instead of listing tools to give the subagent every [tool available to subagents](../09-Agents-Patterns/sub-agents.md#available-tools)
- For a `tools` list that contains only `Agent`, raise the [depth limit](../09-Agents-Patterns/sub-agents.md#let-subagents-spawn-their-own-subagents) or give the agent at least one other tool: Claude Code withholds `Agent` at that limit, so a list with nothing else in it resolves to no tools


[​](#file-is-covered-by-a-read-deny-rule)

File is covered by a Read deny rule

The Edit or Write tool was called on a path matched by a [`Read` deny rule](permissions.md#read-and-edit), including creating a new file at that path. Both tools change content Claude has to be able to read back, so Claude Code refuses the call before any file access. NotebookEdit isn’t covered by `Read` deny rules. Before v2.1.228, the rule blocked the Edit tool only, and before v2.1.208, only an `Edit` deny rule blocked edits.

```python
File is covered by a Read deny rule in your permission settings and cannot be edited.
```

When Claude Code refuses the Write tool, the message ends `and cannot be written` instead. **What to do:**

- If Claude should be able to change the file, remove or narrow the `Read` deny rule in `/permissions` or in [settings](settings-reference.md#permission-settings)
- If the file must stay untouched, keep the rule and add an `Edit` deny rule for the same path to block the NotebookEdit tool too


[​](#path-cannot-contain-null-bytes)

Path cannot contain null bytes

A file tool call’s path or pattern argument contained a null byte, which file systems and search tools can’t accept. Read, Write, Edit, NotebookEdit, Glob, and Grep check for this, and the message names the tool and the argument:

```python
Read file_path cannot contain null bytes (\0). Remove the null byte and try again.
```

The tool call fails, Claude sees the error, and the turn continues. **What to do:**

- Nothing on your side: the error is returned to Claude as the tool’s result, and the message itself tells Claude to remove the null byte and try again

Before v2.1.281, a null byte in a Read, Write, Edit, or NotebookEdit path ended the whole turn with an error naming `Path contains null bytes`, and the tool never ran.


[​](#file-is-too-large-to-read-as-an-image)

File is too large to read as an image

Claude tried to read a file as an image with the [Read tool](tools-reference.md#read-tool-behavior), and the file is larger than 128 MB, the most Read loads from an image file. Nothing was read, and Claude receives this error as the tool result:

```python
File is too large to read as an image (the limit is 128MB): <path>. If it is an image, resize it or export a smaller copy, then read that.
```

When the path is a pipe or a device rather than a regular file, Read stops once more than 128 MB has arrived and returns this error instead:

```python
Cannot read this as an image: <path> is a pipe or a device, not a regular file, and it sent more than 128MB without ending.
```

**What to do:**

- If Claude followed the `File is too large` message and went on to resize the image or read a smaller copy, do nothing
- If Claude stopped at the error, export a copy under 128 MB yourself, for example at a lower resolution, and point Claude at that file
- If the path was a pipe or a device, point Claude at a regular image file instead


[​](#subagent-type-is-required)

subagent_type is required

```python
subagent_type is required: the general-purpose agent is not available in this session. Available agents: ...
```

Claude called the [Agent tool](tools-reference.md#agent-tool-behavior) without a `subagent_type`, and this session has no [general-purpose subagent](../09-Agents-Patterns/sub-agents.md#built-in-subagents) to fall back on. That is the case in two setups:

- [`CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS=1`](env-vars.md) is set in non-interactive mode, which removes every built-in subagent
- The session’s main-thread agent has a [`tools: Agent(...)` allowlist](../09-Agents-Patterns/sub-agents.md#restrict-which-subagents-can-be-spawned) that leaves out `general-purpose`

**What to do:**

- Usually nothing: the message lists the subagents the session does have, so Claude can retry with one of them
- If Claude keeps failing, add `general-purpose` to the `tools: Agent(...)` allowlist, or unset `CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS`

Before v2.1.235, the same call failed with `Agent type 'general-purpose' not found`.


[​](#memory-index-is-over-its-read-limit)

Memory index is over its read limit

Claude wrote to the [auto memory](memory.md#auto-memory) index `MEMORY.md` and left it over one of its read limits: 200 lines or 25KB. The write succeeded, but only the first 200 lines or 25KB, whichever comes first, load at the start of a session, so everything past the limit is dropped each time the index is read. Before v2.1.210, an over-limit index was silently truncated on the next load with no write-time signal.

```python
Error: this write left the memory index at MEMORY.md at 214 lines, over its 200-line read limit. The write succeeded, but everything past the limit is silently dropped each time the index is loaded — entries at the end are already invisible to readers. Rewrite it to under 140 lines now: keep one line per entry, move detail into topic files, and merge or drop stale entries.
```

Only the content that loads counts toward the limits. YAML frontmatter and block-level HTML comments are stripped before the index is loaded, so they’re excluded from the measurement. Before v2.1.211, Claude Code measured the raw file, and frontmatter or comments could trigger this error even when the loaded content fit. Claude Code delivers the error to Claude after the write rather than printing it as a banner in your terminal, so you may notice it only in the transcript. When Claude’s write brings the file near a limit without crossing it, Claude Code returns a milder reminder to compact the index instead of this error. **What to do:**

- Let Claude rewrite `MEMORY.md`, or ask it to: keep one line per entry, move detail into topic files, and merge or drop stale entries
- To trim the index yourself, see [Audit and edit your memory](memory.md#audit-and-edit-your-memory)


[​](#pkill-pattern-matches-the-claude-code-process)

pkill pattern matches the Claude Code process

A `pkill` command in a Bash tool call used a pattern, typically with `-f`, that matches the Claude Code process itself, so Claude Code refuses the command instead of letting it end the session. Claude Code tests the pattern with `pgrep` before running `pkill` and refuses when its own process ID is in the result. The check runs on Linux only; on macOS, `pkill` runs unmodified. Before v2.1.214, the command ran, and a matching pattern killed the Claude Code session mid-turn.

```python
pkill: refusing to run — this pattern matches the Claude CLI process (PID 12345). Narrow the pattern, or target your own children with `pkill -P $$ ...`.
```

The refusal appears in the Bash tool result rather than as a banner in your terminal, and Claude usually adjusts the command on its own. **What to do:**

- Narrow the pattern so it matches only the intended process, for example the full path of the target binary rather than a short substring
- To stop processes started by the current shell, use `pkill -P $$` with the pattern, which limits the match to the shell’s own child processes


[​](#failed-to-write-to-a-teammate-inbox)

Failed to write to a teammate’s inbox

Claude Code couldn’t write a message to a teammate’s mailbox file under `~/.claude/teams/{team-name}/inboxes/`, so the recipient received nothing. The write fails when Claude Code can’t create or update the file, for example because the disk is full, the directory isn’t writable, or another agent holds the inbox lock for too long. Before v2.1.224, Claude Code reported the message as sent even when the write failed. The error appears in the sending agent’s tool result rather than as a banner in your terminal, and its text tells Claude to try again:

```python
Failed to write to researcher's inbox — nothing was sent. Try again, or message the lead.
```

Structured [agent team](../09-Agents-Patterns/agent-teams.md) protocol messages fail the same way, and the error names the undelivered message: when Claude Code can’t write a plan approval, plan rejection, shutdown request, or shutdown rejection, the error reads `Failed to write the <message> to <name>'s inbox — nothing was sent`. The `plan approval` in that list is the lead’s decision approving a teammate’s plan; the teammate’s plan submission is the separate `plan approval request` message. That message and two other protocol messages carry their own message text and consequence:

- `Failed to write the plan approval request to the lead's inbox — plan not submitted; try again`: the teammate’s plan never reached the lead, and the teammate stays in plan mode until a resubmission succeeds
- `The permission request could not be delivered to the team lead (mailbox write failed)`: the teammate’s permission request never reached the lead, so nobody approved the tool call
- `The confirmation could not be written to team-lead's inbox.`: the shutdown approval itself took effect and the teammate exits; only the confirmation to the lead is missing

When you message a teammate yourself, typing `@name` followed by the message in the lead session, the same failure appears as a notification, `Couldn't write to @name's inbox — message not sent. Try again.`, and Claude Code keeps your text in the prompt box so you can send it again. **What to do:**

- Ask the sender to resend the message; contention for the inbox lock is transient and clears on retry
- Check free disk space, and check that `~/.claude/teams` and the files under it are writable by your user


[​](#teammate-agent-definition-not-restored)

Teammate’s agent definition was not restored

Claude messaged a stopped [agent team](../09-Agents-Patterns/agent-teams.md) teammate, and Claude Code brought it back without re-applying the [subagent definition](../09-Agents-Patterns/agent-teams.md#use-subagent-definitions-for-teammates) it was spawned from. The notice follows the resume report in the sending agent’s tool result and names the reason. When the definition file came from a folder with no saved trust, it reads:

```python
Its agent definition was not restored: the folder its definition file came from is not trusted (source: projectSettings), so the teammate is running with the team-essential tools and no custom instructions. To restore it, the user needs to run Claude Code in that folder once and accept the trust dialog (the --debug log names the folder); do not change trust settings on the user's behalf.
```

The check applies to a definition in the `.claude/agents/` directory of the project or of an `--add-dir` directory, and accepting the trust dialog for a parent folder doesn’t satisfy it. **What to do:**

- Run `claude` in the folder the [debug log](debug-your-config.md) names and accept the trust dialog. The definition is re-applied the next time Claude Code brings the teammate back; you don’t need to restart the lead session
- Or set the `hasTrustDialogAccepted` entry to `true` in `~/.claude.json`, using the exact `projects["<path>"]` key the debug log prints


[​](#only-a-teammate-can-approve-a-shutdown-request)

Only a teammate can approve a shutdown request

Claude Code refused an [agent team](../09-Agents-Patterns/agent-teams.md) shutdown approval because the session that sent it isn’t running as a teammate. Nothing was sent and nothing shut down. The refusal appears in the sending session’s tool result:

```python
Only a teammate can approve a shutdown request, and this session is not running as one. Nothing was sent. To shut down a teammate, send that teammate a shutdown_request message. The teammate is the one that approves it.
```

**What to do:**

- If the refusal appeared in your lead session, first check whether the teammate has since shut down. The refusal goes back to Claude with the instruction to send a `shutdown_request` instead, and the turn continues. In an interactive lead session, `<name> has shut down.` appears when the teammate approves a shutdown request.
- If the teammate is still running, ask the lead at its prompt to shut the teammate down, for example `Ask the researcher teammate to shut down`. See [Shut down teammates](../09-Agents-Patterns/agent-teams.md#shut-down-teammates).
- If a former teammate you resumed yourself with `claude --resume` got this refusal, nothing was sent. To end that session, run `/exit` at its prompt.


[​](#message-too-large-for-cross-session-delivery)

Message too large for cross-session delivery

Claude’s [cross-session message](cross-session-messaging.md) to another of your sessions on this machine was too long to send. Claude Code refused it, and the receiving session got nothing. The refusal appears in the sending session’s tool result, not as a banner in your terminal. It names both sizes and how to make the message fit:

```python
Failed to send to api-worker: Message too large for cross-session delivery: the serialized message is 1,203,844 characters and the limit is 1,048,576. Shorten the message text — put bulk content in a file the recipient can read rather than in the message — or split it into smaller messages.
```

Resending the same text fails the same way. **What to do:**

- Ask Claude to summarize the message, or to put the bulk content in a file and send the file’s path
- Ask Claude to split the content across several shorter messages

Before v2.1.235, Claude Code reported an oversized message as sent. The receiving session dropped it unread.


[​](#too-many-messages-to-this-session-just-now)

Too many messages to this session just now

Claude sent a rapid burst of [cross-session messages](cross-session-messaging.md) to one of your sessions on this machine, and the burst reached what that session’s inbox accepts. Claude Code refused the next send, and the receiving session got nothing from it. The refusal appears in the sending session’s tool result, not as a banner in your terminal:

```python
Failed to send to api-worker: Too many messages to this session just now: 30 were sent recently and more would be dropped by its rate limit, so this one was not sent. Batch what remains into one message, or wait a little before sending more.
```

**What to do:**

- Usually nothing: Claude batches the remaining content into one message, or waits before sending more
- If you prompted the burst yourself, ask Claude to combine what’s left into a single message

Before v2.1.236, Claude Code reported these sends as sent. The receiving session dropped them unread.


[​](#cross-session-message-dropped-at-the-inbox)

Cross-session message was dropped at the recipient session’s inbox

Claude sent a [cross-session message](cross-session-messaging.md) to another of your sessions on this machine, and that session’s inbox discarded it before Claude in that session read it. The line names the recipient and, when the recipient gave a reason, adds the reason after a dash:

```python
Cross-session message was dropped at the recipient session's inbox (recipient: uds:/tmp/cc-socks/13605.sock) and not delivered — its queue of undelivered peer messages was full. Claude was told not to resend right away.
```

One line can cover several dropped messages. It then starts in the plural, for example `Cross-session messages (12) were dropped`. To find which session an address belongs to, compare it with the [`Peer address` row](cross-session-messaging.md#the-sessions-inbox-socket) that `/status` shows in each session. After the dash, the line gives one or more of these reasons:

- `its queue of undelivered peer messages was full`: the recipient already held as many undelivered messages from other sessions as its queue allows
- `you sent faster than that session accepts`: the sending session’s messages arrived faster than the recipient accepts from one sender
- `it repeated your previous message`: the message was identical to one the sending session sent this recipient shortly before
- `a relay loop between sessions was cut`: the message continued a chain of sessions messaging each other, and the chain had passed through the recipient too many times or grown too long

**What to do:**

- Assume the recipient never saw the dropped messages. Claude Code tells Claude the same, and tells it to include anything that still matters in one later message instead of resending right away
- If your sessions send each other frequent updates, ask Claude to send fewer, larger messages, such as one report when a session finishes its work
- For `a relay loop between sessions was cut`, type the next instruction into one of the sessions yourself. A message Claude sends in response to your own prompt begins a new chain

Before v2.1.238, the sending session got no report when the recipient’s inbox discarded a message.


[​](#refusing-to-send-a-cross-session-message)

Refusing to send a cross-session message

Before Claude Code writes a [cross-session message](cross-session-messaging.md) to another of your sessions on this machine, it checks that the target session’s inbox socket is the endpoint the message was addressed to. When a check fails, Claude Code refuses the send in the sending session, and the target session receives nothing. For a message Claude sends, the refusal appears in the sending session’s tool result:

```python
Failed to send to api-worker: Refusing to send: reply target is a symlink
```

The text after `Refusing to send:` names the check that failed:

- `reply target is a symlink`: a symbolic link sits at the target session’s socket path. Claude Code doesn’t deliver through it, because a link there could redirect the message to an endpoint the target session didn’t create.
- `cannot vet reply target`: Claude Code couldn’t inspect the target path at all, for example because reading it failed with a permission error.

**What to do:**

- Usually nothing: the checks keep a message from reaching an endpoint other than the session it was addressed to, and nothing was sent
- If `reply target is a symlink` repeats for one session, check what created a link at that session’s socket path, shown in its `/status` under `Peer address`


[​](#refusing-after-a-symlink-changed)

Refusing to read, write, or search a path

Claude Code checks a file path’s [permission rules](permissions.md#read-and-edit), then confirms that resolution again when the tool opens the file or starts the search. When it can’t confirm that the path still leads to the location the check approved, Claude Code refuses the operation instead of following it. The refusal appears in the tool result:

```python
Refusing to read /path/to/file: its symlink resolution changed after permission was checked (a link on the way now leads somewhere the check did not see). If a link in the working directory is being rewritten concurrently, stop that and retry.
```

Each refusal names its reason:

- `its symlink resolution changed after permission was checked`: a symlink along the path, or at a Grep or Glob search root, was replaced between the permission check and the operation. In a read refusal, the parenthesized phrase names which comparison failed.
- `its parent-directory symlink resolution changed after permission was checked`: a directory the write path passes through no longer resolves to the approved location
- `where it leads on disk could not be determined (a link on the way could not be examined, or the links do not resolve)`: Claude Code couldn’t follow the path to a final location on disk, for example because symlinks on it form a loop
- `it is a symbolic link. Write to the link's target path instead`: a symbolic link sits at the requested write location itself, for example a `CLAUDE.md` that is a symlink to `AGENTS.md`; the message directs Claude to the link’s target
- `Refusing to write through symlink: <path>. Resolve the symlink and pass the real target path explicitly.`: the same condition caught when another writer opens the file, such as a write to a symlinked `.mcp.json`
- `Refusing to write into symlinked directory: <path>`: the directory that holds the file is itself a symbolic link, for example a project’s `.claude/` directory linked to another location
- `a path one of its Read deny rules is written through changed while the search was being prepared. Retry.`: a `Read` deny rule for the search names a path that passes through a symlink, and that link changed while Claude Code was preparing the search
- `it could not be opened (EACCES) — it is unreadable, or is being replaced concurrently.`: the search root exists but couldn’t be opened; the parenthesized code is the operating system error
- `its permission check expired before it ran (too many concurrent file operations). Retry.`: Claude Code evicted the approval record under many simultaneous file operations before the tool used it; retrying runs a fresh permission check
- `ripgrep was found only by name on PATH, and a search outside the working directory cannot apply your Read deny rules in that configuration`: Claude Code couldn’t resolve the `rg` binary to an absolute path, so it refuses searches outside the working directory rather than run one your deny rules don’t cover

**What to do:**

- Usually nothing: the refusal reaches Claude as the tool result, and the refused operation doesn’t run
- If a symlink refusal repeats on one path, find what keeps rewriting a link there, such as a build tool or file watcher, or ask Claude to use the file’s resolved path instead of the linked one
- If this refusal appears for every file while Claude Code runs on Windows inside an AppContainer or restricted-token sandbox, upgrade to v2.1.265 or later
- If a read refusal appears on macOS for a file that nothing is rewriting, such as a screenshot dragged into the prompt, upgrade to v2.1.273 or later
- For the ripgrep refusal, install ripgrep with your package manager so `rg` resolves to an absolute path on `PATH`, or keep searches under the working directory

Before v2.1.251, Claude Code re-checked a path’s resolution only for file writes, so a link replaced after the permission check could redirect a read or search to a different location without a message. Of these, only the parent-directory, through-symlink, and symlinked-directory write refusals appear on earlier versions. Before v2.1.280, the `where it leads on disk could not be determined` refusal didn’t appear.


[​](#task-output-swap-refused)

Task output swap refused

Claude Code saves each Bash command’s output to a file under its temp directory. Every time it opens one of these files, it checks that the path still leads to the file it created, with no symbolic link, extra hard link, or moved directory redirecting it. This message means that check failed, so Claude Code refused the operation rather than write or read output through that path. The message appears in the Bash tool result:

```python
task output swap refused (tasks dir moved or linked): /private/tmp/claude-501/-Users-you-my-project/1f0e62dc-4b0a-4f5e-9c2d-8a7b6c5d4e3f/tasks/b7k2f9m3q.output. To recover: restart Claude Code with CLAUDE_CODE_TMPDIR set to a fresh directory; or, if /private/tmp/claude-501/-Users-you-my-project is a stray directory or a symbolic link that should not be there, remove that entry itself (not what it points to) and restart.
```

The parenthesized text names the check that failed. Reasons such as `output symlink was re-pointed`, `output file identity changed`, and `not a regular file` all report the same condition: something at or along the output path is no longer the file Claude Code created. Only some reasons carry a `To recover:` sentence. If the check fails while a command is still running, Claude Code stops the command, and its result reports:

```python
Command killed: its output file was replaced or could no longer be verified
```

**What to do:**

- Upgrade to v2.1.260 or later. Earlier versions sometimes showed this message when no link or moved directory was present
- Restart Claude Code with [`CLAUDE_CODE_TMPDIR`](env-vars.md) set to a fresh directory
- Or check your project’s directory under the Claude Code temp directory, `/private/tmp/claude-501/-Users-you-my-project` in the example message. If that path is a symbolic link, or a directory that shouldn’t be there, remove the link or directory itself rather than the link’s target, and restart Claude Code
- If the refusal repeats, a process is replacing, linking, or removing entries under Claude Code’s temp directory while the session runs. Set [`CLAUDE_CODE_TMPDIR`](env-vars.md) to a directory nothing else manages and restart


[​](#disk-quota-or-temp-filesystem-is-full)

Disk full or disk quota used up

Free up space, inodes, or disk quota on the volume that holds Claude Code’s temporary directory. A line in a command’s result starting `Disk full:`, `Disk quota used up:`, or `Nearly out of inodes:` names that directory. Claude Code saves each Bash and PowerShell command’s output to a file under that directory. If it can’t create that file because the volume or your quota on it is full, your command doesn’t start, and the result Claude reads is:

```python
The command was not started: this computer's disk is full (ENOSPC) on the volume holding /tmp/claude-501 (Claude Code's temporary directory), so the file that captures command output could not be created there and nothing ran. Free space on that volume, or restart Claude Code with CLAUDE_CODE_TMPDIR set to a directory on another one, then retry. If this is the user's own computer, tell them before deleting anything to make room.
```

The other three messages follow a command that ran and exited with a nonzero code. This example is the `Disk full:` form:

```python
Disk full: this computer's volume holding /tmp/claude-501 (Claude Code's temporary directory) has 3 MB free, so whatever this command printed was lost and its own writes may have failed with "No space left on device". Free space on that volume, or restart Claude Code with CLAUDE_CODE_TMPDIR set to a directory on another one, then retry. If this is the user's own computer, tell them before deleting anything to make room.
```

**What to do:**

- On macOS and Linux, run `df -h <dir>` in your shell to see which volume holds the directory and how full it is. `df -i <dir>` shows how many inodes are free. `<dir>` is the directory your message names, as in `df -i /tmp/claude-501`
- **`Disk full: this computer's volume` or `disk is full (ENOSPC)`**: anywhere on that volume, delete files you don’t need
- **`Disk quota used up:` or `Disk full: a test write`**: delete your own files on that volume, even if it still shows free space
- **`disk quota is used up (EDQUOT)`**: delete your own files on that volume
- **`Nearly out of inodes:`**: delete many files on that volume. Each takes one inode whatever its size, so their number matters, not their size
- Or restart Claude Code with [`CLAUDE_CODE_TMPDIR`](env-vars.md) set to a directory on a volume with room
- Then have Claude run the command again

Before v2.1.309, the messages read as follows, and the same steps apply:

- `Your disk quota is full on the filesystem with Claude Code's temp directory <dir> (EDQUOT)`
- `The filesystem with Claude Code's temp directory <dir>, or your disk quota on it, is full (ENOSPC)`
- `Command output was lost: the temp filesystem at <dir> is full` or `... is out of inodes`
- `The command was not started: this computer's disk is full (ENOSPC), so the file that captures command output could not be created. Nothing ran.`, or the same with `(EDQUOT)`. This form names no directory: look on the volume holding your system temp directory, such as `/tmp`, or the directory set in `CLAUDE_CODE_TMPDIR`

Before v2.1.305, a command that Claude Code couldn’t start because the disk was full returned only the operating system’s error text. That text read, for example, `ENOSPC: no space left on device, open <path>.output`.


[​](#file-is-not-valid-utf-8)

File is not valid UTF-8

Claude used the Edit or NotebookEdit tool on a file whose bytes don’t decode as UTF-8, and Claude Code refused the change. Nothing was written, so the file is as it was. Those tools save the whole file back as UTF-8, which would have turned every byte they couldn’t decode into the replacement character `U+FFFD`. The message appears in the tool result:

```python
File is not valid UTF-8. It may use a legacy encoding such as Windows-1252, Shift-JIS or GBK, or be binary. This tool saves the whole file as UTF-8, which would replace every byte it cannot decode with U+FFFD. Nothing was written. Make the change with a shell command that reads and writes the file in its own encoding, or ask the user whether to convert the file to UTF-8 first.
```

A file that is meant to be UTF-8 gets this message too when it contains even one invalid byte sequence, because the check covers the file’s bytes as a whole. **What to do:**

- To keep the file in its current encoding, let Claude make the change with a shell command that reads and writes the file in that encoding, as the message tells it to
- To keep editing the file with the Edit tool, convert it to UTF-8, or fix the invalid bytes in a file that is meant to be UTF-8, then ask Claude to make the edit again

Before v2.1.296, Edit and NotebookEdit applied such an edit and saved every byte they couldn’t decode as `U+FFFD`. On those versions, update Claude Code.


[​](#the-source-file-is-not-valid-utf-8-text)

The source file is not valid UTF-8 text

Claude tried to publish an [artifact](artifacts.md) from a file whose bytes don’t decode as text, or whose text already contains the replacement character `U+FFFD`, so Claude Code refused the publish before uploading anything. The message appears in the Artifact tool result and names the first position to fix:

```python
file_path: the source file is not valid UTF-8 text (first invalid byte at line 12, column 40). It may be saved in another encoding or contain binary data. Rewrite it as UTF-8, then publish again. Nothing was published.

file_path: the source file has the replacement character U+FFFD at line 12, column 40, usually left where an earlier edit or paste lost a character. Replace it with the intended text (in HTML, write an intended U+FFFD as &#xFFFD;), then publish again. Nothing was published.
```

Claude Code decodes the file as UTF-8, or as UTF-16 when it starts with a little-endian UTF-16 byte-order mark. When such a UTF-16 file doesn’t decode, the first message names `UTF-16` and still tells you to rewrite the file as UTF-8. When more positions follow the named one, the message adds a count such as `(+2 more)` after the position. **What to do:**

- Usually nothing: Claude rewrites the file and publishes again
- If the file is one you wrote or exported, save it again as UTF-8, and replace each `U+FFFD` with the character an earlier edit, paste, or conversion lost
- To show an intentional `U+FFFD` on the page, write it as `&#xFFFD;` in the HTML instead of the literal character

Before v2.1.267, Claude Code uploaded such a file without checking it, and the server refused the publish instead.


[​](#not-published-that-file-is-on-a-network-share)

Not published: that file is on a network share

Claude tried to publish an [artifact](artifacts.md) from a file at a path that names a network host:

- On Windows, a `\\server\share` path that isn’t under a mapped network drive you passed at launch with [`--add-dir`](cli-reference.md#cli-flags)
- On macOS or Linux, an automount path such as `/net/<host>/page.html`

Looking up such a path contacts the host it names, and on Windows that contact can send the host your credentials. Claude Code refuses to publish the file and doesn’t read it. The refusal appears in the Artifact tool result:

```python
Not published: that file is on a network share. Publish a file from this session's folders instead.
```

**What to do:**

- Nothing, if you don’t need that exact file: the message tells Claude to publish a file from the session’s own folders instead
- To publish that exact file, copy it into a folder on a local disk and ask again
- On Windows, to let Claude publish directly from the share, map it to a drive letter and pass the drive when you start Claude Code. In PowerShell, for example, run `net use Z: \\server\share` and then `claude --add-dir Z:\`. Claude can then publish files from that drive. Adding the drive mid-session with `/add-dir` isn’t enough.
- On macOS or Linux, mount the share at a directory such as one under `/mnt` or `/Volumes`, and publish from that path instead of the automount path


[​](#not-published-a-newer-version-of-the-artifact-turned-it-away)

Not published: Claude sent the same content again after a newer version of the artifact turned it away

This red line under an Artifact call means Claude Code stopped a repeated publish: the [artifact](artifacts.md) wasn’t updated, and nothing was written to the file Claude publishes from. You don’t need to do anything unless Claude stops without publishing. Earlier in the session, Claude Code turned a publish away because the artifact had a newer version, for example one that an [editor](artifacts.md#let-someone-edit-with-you) or another of your sessions published. The line’s ending says what Claude has to do next:

```python
Not published: Claude sent the same content again after a newer version of the artifact turned it away. Claude needs to work from that newer version first.
Not published: Claude sent the same content again after a newer version of the artifact turned it away. The artifact hasn't changed since, so publishing it once more should go through.
Not published: Claude sent its changes again over the same file after a newer version of the artifact turned them away. Claude needs to work from that newer version first.
Not published: Claude sent its changes again over the same file after a newer version of the artifact turned them away. The artifact hasn't changed since, so publishing once more should go through.
```

**What to do:**

- **Ends with `Claude needs to work from that newer version first`**: if Claude stopped there, ask it to fetch the artifact’s current version, merge its changes in, and publish again
- **Ends with `should go through`**: if Claude stopped there, ask it to publish again


[​](#reading-a-local-file-from-outside-the-connected-folders)

Reading a local file from outside the connected folders in a Cowork session

In a [Cowork](https://claude.com/docs/cowork/overview) session running on your machine in the Claude Desktop app, Claude named a local file for an [artifact](artifacts.md). Claude Code couldn’t confirm the file is a plain file inside the session’s connected folders: the path sits outside those folders, passes through a symbolic link, or is spelled in a way that can name a different file than it appears to. Reading such a file needs your approval, and in a session that can’t show you the approval card, such as one set to skip all approvals, Claude Code refuses the read. The refusal appears in the Artifact tool result; when the file couldn’t be examined at all, it names that failure instead:

```python
Reading a local file from outside this session's connected folders, or through a link, needs the approval card, and no one can answer it in this Cowork session. Use a plain file inside the connected folders; do not retry this file in this session.

cannot read file_path (ENOENT) — the file could not be examined, and no one can answer the approval card in this Cowork session. Check that the file exists as a plain file inside the connected folders, then retry with that path.
```

**What to do:**

- Usually nothing: the message tells Claude to use a plain file inside the connected folders instead
- To put that exact file in the artifact, copy it into one of the session’s connected folders as a regular file, not a symlink, and ask again


[​](#webfetch-cannot-fetch-localhost)

WebFetch cannot fetch localhost

Claude called [WebFetch](tools-reference.md#webfetch-tool-behavior) with a URL whose hostname has no dot, such as `http://localhost:3000` or a bare intranet name like `http://wiki/`. WebFetch refuses these URLs before making any request:

```python
WebFetch cannot fetch localhost or other hostnames without a dot. To reach a local server, use Bash with curl instead.
```

**What to do:**

- Usually nothing: the message points Claude at `curl` through the Bash tool, which can reach local and intranet servers

Before v2.1.268, WebFetch reported these URLs with a generic `Invalid URL` error.


[​](#webfetch-domain-safety-check-failed)

WebFetch domain safety check failed

Before fetching a URL, WebFetch sends the URL’s hostname to `api.anthropic.com` to check it against Anthropic’s [domain safety blocklist](../13-Enterprise-Admin/data-usage.md#webfetch-domain-safety-check). If the check can’t complete, WebFetch can’t confirm that the domain is safe, so it doesn’t fetch the page and the tool result carries one of these messages instead:

```python
The safety check for domain example.com is rate-limited (too many domain checks from this network; the limit is shared and can stay exhausted for minutes). Do not retry WebFetch in a loop or sleep to wait it out; continue without this page and report that its safety check was rate-limited. A single later attempt is fine; if that is rate-limited too, stop.

Unable to verify if domain example.com is safe to fetch. This may be due to network restrictions or enterprise security policies blocking claude.ai.
```

- `rate-limited`: the check endpoint answered with HTTP `429`. The message tells Claude to continue without the page and to try again at most once later. Claude Code doesn’t cache a failed check, so a later fetch of that domain runs the check again. If sessions on your network hit this often, you can skip the check with [`skipWebFetchPreflight: true`](settings-reference.md#skipwebfetchpreflight) in settings.
- `Unable to verify`: the check request failed, timed out, or got another error status. If your network blocks `api.anthropic.com`, allowlist that domain, or skip the check with [`skipWebFetchPreflight: true`](settings-reference.md#skipwebfetchpreflight) in settings.

Before v2.1.286, the rate-limited message read `The safety check for domain example.com is temporarily rate-limited (too many domain checks from this network). Retry after about a minute; retrying sooner will fail the same way.`. Before v2.1.285, a rate-limited check was reported with the `Unable to verify` message instead.


[​](#background-session-errors)

Background session errors

[Background sessions](../09-Agents-Patterns/agent-view.md) run without an interactive terminal of their own, so commands that need one behave differently there. These messages appear in the transcript of a background session, in the terminal that attaches to one, in the session or shell you dispatch from, or, for the [worktree-guard entries](#write-or-command-blocked-because-the-path-cannot-be-safely-resolved) below, in any session isolated in a worktree or running a worktree-isolated subagent; where a message is specific to one surface, its entry says so.


[​](#commands-refused-in-a-background-session)

Commands refused in a background session

Commands that open an interactive dialog can’t do so while no terminal is attached to a background session. `/install-github-app`, the `/mcp` settings list, and the authentication actions in the MCP server menu respond with a message. For `/install-github-app` and the `/mcp` settings list, the session also appears under **Needs input** in [agent view](../09-Agents-Patterns/agent-view.md) so you can find it, attach, and run the command again. While a terminal is attached, these commands work normally. Before v2.1.216, the session didn’t appear under **Needs input** after `/install-github-app` or the `/mcp` settings list was refused. In v2.1.213 through v2.1.215, the commands still worked while a terminal was attached, and the refusal message told you to attach and run the command again. From v2.1.208 through v2.1.212, Claude Code refused them even while a terminal was attached, with a message such as `Can't open MCP settings in a background session`; on those versions, run the command from a regular `claude` session instead, or upgrade. Before v2.1.208, they opened their dialog inside the background session. In v2.1.208 only, Claude Code also refused the `/model` picker in a background session, and `/upgrade` printed the upgrade URL instead of opening a browser. The wording names the command. The `/mcp` settings list reports:

```python
Can't open MCP settings while no terminal is attached to this background session. This session now shows "needs input" in agent view — open it and run /mcp to manage servers, or use `/mcp enable|disable|reconnect <server>` to steer without the panel.
```

**What to do:**

- Attach to the session from agent view and run the command again
- Or use the form the message names, such as `/mcp reconnect <server>`, `/mcp enable`, or `/mcp disable`, which work without attaching


[​](#write-or-command-blocked-because-the-path-cannot-be-safely-resolved)

Write or command blocked because the path cannot be safely resolved

Claude addressed a file or working directory through a spelling that the [worktree-isolation guard](../09-Agents-Patterns/agent-view.md#how-file-edits-are-isolated) can’t resolve to one verifiable location. The guard checks writes and command working directories in [any session isolated in a worktree](worktrees.md#how-claude-code-enforces-isolation), interactive or background, and in [worktree-isolated subagents](worktrees.md#isolate-subagents-with-worktrees). It resolves symlinks before checking that the operation doesn’t reach the shared checkout, and when resolution fails, it blocks the operation rather than letting it land there. The message names the path forms it refuses and how to retry:

```python
This write was blocked because the path is spelled in a form that cannot be safely resolved (for example through a symlink storing a raw dot segment, a network-share or device-namespace shape, or an unreadable ancestor directory). If the file is inside the worktree /path/to/worktree, address it by its direct symlink-free path instead.
```

A blocked command reports the same cause for its working directory and ends with `re-run the command from its direct symlink-free path`. Before v2.1.217, the guard compared path spellings without resolving symlinks, so these spellings weren’t blocked and a write routed through a symlink could land in the shared checkout. **What to do:**

- Usually nothing: the full message goes to Claude as a tool error, and Claude retries with the direct path it names. For a blocked file edit, the conversation view shows only a short `Error editing file` line; the full message appears in the transcript view, which you open with `Ctrl+O`. A blocked command prints it in its command output.
- If the block repeats on the same file, the path likely runs through a committed symlink whose target contains `..`, such as `docs/current -> ../README.md`; ask Claude to edit the target file by its real path instead of through the link


[​](#write-or-command-blocked-because-the-path-names-a-network-location)

Write or command blocked because the path names a network location

Claude addressed a file or working directory through a path that names a drive that isn’t on your machine, a UNC share such as `\\server\share\file` or a `/net` automount path, while the session’s checkout is on a local disk. The same [worktree-isolation guard](#write-or-command-blocked-because-the-path-cannot-be-safely-resolved) can’t verify that such a path stays out of the shared checkout, so it blocks the operation. Isolating the session in a worktree doesn’t lift the block. The message names the form of path to use instead:

```python
This write was blocked because the path is network-shaped (a UNC share or /net automount spelling) while this session's checkout is local. Isolating cannot unblock it. If the file is genuinely inside the worktree /path/to/worktree, address it by its local, plainly-spelled path instead.
```

A blocked command reports the same cause for its working directory and ends with `re-run the command from its local, plainly-spelled path`. Before v2.1.217, the guard compared path text only, so addressing a file inside the checkout through a UNC or `/net` path wasn’t blocked. **What to do:**

- Usually nothing: Claude retries with the local spelling the message asks for


[​](#command-blocked-by-the-worktree-isolation-checks)

Command blocked by the worktree isolation checks

Claude ran a Bash, [PowerShell](tools-reference.md#powershell-tool), or [Monitor](tools-reference.md#monitor-tool) command in a [session isolated in a worktree](worktrees.md#how-claude-code-enforces-isolation), and Claude Code refused it for one of these reasons:

- The command would run in the main checkout or in another worktree. The message says its working directory `resolved to the shared checkout` or `is in a different worktree`.
- A Bash or Monitor command points git at the main checkout.
- Claude Code can’t verify from a Bash or Monitor command’s text that any git the command runs stays inside the worktree. A command that never names git can still be refused for this reason, because expanding a variable indirection such as `${!name}` or running a Bash function substitution such as `${ command; }` produces a value at runtime that can itself be a command.

The message says `is isolated in the worktree <path>, but this command`, followed by the reason, such as a command whose text Claude Code couldn’t verify:

```python
This session is isolated in the worktree /path/to/worktree, but this command evaluates ${!x@P} arithmetically inside a construct too complex to verify, which can run a command hidden in a variable's value. Refusing to run it — a worktree-isolated session's git operations must target its own worktree. Split it into plain, separate commands and run them from /path/to/worktree.
```

**What to do:**

- **Git pointed at the main checkout, or command text that can’t be verified**: nothing. Claude reads the message and rewrites the command the way its final sentence asks. If a command you asked for keeps being refused over an expansion in its text, spell the flagged value literally and run git as its own plain command from inside the worktree
- To act on the main checkout on purpose, run the command yourself in a terminal outside the session


[​](#this-session-has-no-saved-transcript)

This session has no saved transcript

You attached to a session that you [moved to the background](../09-Agents-Patterns/agent-view.md#from-inside-a-session) with `←` or `/background` and that stopped before it ran a turn of its own. Claude Code couldn’t find the conversation you moved it from, so the session has nothing to resume. The message ends with the `claude respawn` command for this session:

```python
This session has no saved transcript — it was stopped before its first response finished. If it was backgrounded from another conversation, that one is still intact; `claude respawn <id>` starts this one fresh.
```

Opening the same session’s row in [agent view](../09-Agents-Patterns/agent-view.md) shows `Press enter again to restart this session fresh` below the list instead, and a second `Enter` on the row restarts the session with an empty conversation. **What to do:**

- To start the stopped session fresh, run `claude respawn <id>` with the ID from the message, or press `Enter` twice on its row in agent view
- If the session did finish a response and you still see this refusal on a version before v2.1.214, an unreadable folder in `~/.claude/projects` could make the transcript scan miss the saved conversation; update to v2.1.214 or later, which tolerates unreadable folders during the scan


[​](#this-session-is-running-in-another-terminal)

This session is running in another terminal

You opened a stopped session’s row in [agent view](../09-Agents-Patterns/agent-view.md), and its saved conversation is already open in another live Claude Code process on this machine, so Claude Code refuses to start a second process that would write to the same transcript. Which message you see depends on [what holds the conversation](../09-Agents-Patterns/agent-view.md#opening-a-session-says-the-conversation-is-already-open):

```python
Can't open — this session is running in another terminal
This conversation is already open in another running Claude session — use that one, or close it and try again
```

- **`running in another terminal`**: a terminal holds the conversation, for example one where you resumed it with `claude --resume` or `/resume`. The row also shows `Open in a terminal`.
- **`already open in another running Claude session`**: another non-interactive Claude Code process holds it, for example a [background session](../09-Agents-Patterns/agent-view.md#the-supervisor-process) process for the same conversation that hasn’t exited yet.

**What to do:**

- Continue the conversation in the process that has it open, or exit that process and open the row again

Before v2.1.248, only the `already open in another running Claude session` refusal existed: a conversation resumed in a terminal didn’t count as open, and opening the row started a second Claude Code process writing to the same conversation.


[​](#this-sessions-saved-conversation-is-no-longer-on-disk)

This session’s saved conversation is no longer on disk

You opened a [background session](../09-Agents-Patterns/agent-view.md) that ended while the background service was off, and [transcript cleanup](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](../09-Agents-Patterns/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:

```python
This 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.
```

`claude attach <id>` prints this text. In agent view, the footer is shorter and ends with `ctrl+x deletes the row`. **What to do:**

- Run `claude rm <id>` to delete the row. When one of the [kept cases](../09-Agents-Patterns/agent-view.md#what-deleting-a-session-removes) applies, `claude rm` keeps the row and the worktree instead and names the reason
- To run the session’s original prompt again as a fresh conversation, run `claude respawn <id>`

Before v2.1.248, opening such a row re-ran the session’s original prompt instead of refusing, pulling a weeks-old task back into the foreground.


[​](#worktree-has-commits-that-are-not-pushed-anywhere)

Worktree has commits that are not pushed anywhere

You tried to delete a [background session](../09-Agents-Patterns/agent-view.md#what-deleting-a-session-removes) whose worktree holds commits Claude Code can’t confirm are saved elsewhere. Claude Code keeps the worktree and the session row rather than destroy the commits unseen. `claude rm` names the branch and the unpushed commits, and says how to proceed:

```python
kept 7c5dcf5d — its worktree is still at “/home/you/project/.claude/worktrees/fix-login”
  2 unpushed commits on “claude/fix-login”: a1b2c3d “Fix login flow” and 1 more. They exist on no remote, so deleting the worktree would lose them.
  push them and run 'claude rm 7c5dcf5d' again, or discard the worktree and its commits: claude rm 7c5dcf5d --discard-unpushed a1b2c3d000000000000000000000000000000000@0123456789abcdef0123456789abcdef
```

When Claude Code can’t summarize the commits, the detail line reads `The worktree has unpushed commits` instead. In [agent view](../09-Agents-Patterns/agent-view.md), the session’s row shows `not deleted` with the same reason. 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. **What to do:**

- To keep the commits, push the worktree’s branch, or merge it into the default branch checked out in your main checkout, then delete the session again
- To discard the commits, run the `claude rm <id> --discard-unpushed` command the message printed, or press `Ctrl+X` twice on the session’s row in agent view again. This removes the session and the worktree along with its branch, the unpushed commits, and any uncommitted changes. If the worktree has gained a commit since the refusal, Claude Code keeps it again and shows the updated state
- When the message says the worktree is also recorded by another finished session, deleting again doesn’t discard it: push the commits, then delete the session again

Before v2.1.268, `claude rm` put the commit summary on the `kept` line itself. When `claude rm` couldn’t summarize the commits, the `kept` line read `worktree has commits that are not pushed anywhere` in place of the summary. Before v2.1.260, the message didn’t name the branch or the commits, and deleting again was refused the same way: deleting the session without pushing meant removing the worktree yourself with `git worktree remove --force <path>`, then running `claude rm <id>` again. Before v2.1.248, the default branch checked out in your main checkout didn’t count: a branch you had already merged there still triggered this refusal until its commits reached a remote.


[​](#terminal-host-process-died)

Terminal host process died

Each [background session’s](../09-Agents-Patterns/agent-view.md) terminal runs in a host process under the background service, and that process died while the service still held its connection, so the session couldn’t be reached. On Linux and WSL, the background service checks each host process every few seconds, marks the session failed when the process has exited but its connection to the service never closed, and shows the reason on its row in [agent view](../09-Agents-Patterns/agent-view.md#read-session-state):

```python
terminal host process died — press Enter to restart
```

From the shell, `claude attach <id>` restarts a session already marked failed for a dead host, and otherwise prints the cause and exits:

```python
Couldn't attach to <id> — This session's terminal host process died (the conversation is saved) — run `claude attach <id>` again to restart it on a fresh host.
```

The conversation is saved either way. A row running a [shell command](../09-Agents-Patterns/agent-view.md#run-a-shell-command) instead shows `terminal host process died — its output is gone; the command was not run again`, and `claude attach` prints `This command's terminal host process died — its output is gone and the command was not run again`. Claude Code never reruns the command for you. **What to do:**

- In agent view, press `Enter` on the failed row; the session restarts on a fresh host process and the conversation resumes
- From the shell, run `claude attach <id>` again. Claude Code prints `Session <id>'s terminal host died — restarting it on a fresh one…` and reopens the session
- You can’t restart a shell-command row this way; dispatch the command again to rerun it

Before v2.1.247, a dead host process could pass every liveness check the background service ran, so opening the session showed `opening… · esc to cancel` indefinitely and `claude attach <id>` waited without reporting an error.


[​](#session-isnt-responding)

Session isn’t responding

You opened a [background session](../09-Agents-Patterns/agent-view.md) and the background service accepted the open, but no output arrived for about ten seconds, so Claude Code concludes that the process relaying the session’s terminal can’t deliver output, and ends the attempt instead of waiting. In agent view, Claude Code offers a restart in the footer:

```python
Press enter again to restart this session — it isn't responding (its conversation is saved and resumes).
```

From the shell, `claude attach <id>` prints the cause and exits:

```python
Couldn't attach to <id> — Session isn't responding — `claude stop <id>`, then `claude attach <id>` restarts it (the conversation is saved).
```

Claude Code never restarts a row running a [shell command](../09-Agents-Patterns/agent-view.md#run-a-shell-command) for you, because a restart would run the command again. **What to do:**

- In agent view, press `Enter` on the same row again. Claude Code stops the unresponsive process and restarts the session, and the conversation resumes. Nothing is stopped without that second press
- From the shell, run `claude stop <id>`, then `claude attach <id>`
- For a shell-command row, press `Ctrl+X` in agent view or run `claude stop <id>` to stop it; dispatch the command again to rerun it


[​](#session-was-stopped-while-the-respawn-was-in-flight)

Session was stopped while the respawn was in flight

You opened a [background session](../09-Agents-Patterns/agent-view.md) whose process wasn’t running, and while Claude Code was restarting it, another Claude Code process stopped it, for example `claude stop` in another terminal. Claude Code keeps the session stopped:

```python
Session <id> was stopped while the respawn was in flight
```

Opening a session you just dispatched, while its process is still starting, waits for the process instead. Before v2.1.246, opening it at that moment could stop it and show this message. **What to do:**

- If you didn’t stop the session, open its row again in agent view or run `claude respawn <id>` to restart it
- If you stopped it yourself, nothing remains to do: the session stays stopped


[​](#session-agent-no-longer-available)

Session agent no longer available

You resumed a session that was running a [custom agent](../09-Agents-Patterns/sub-agents.md#invoke-subagents-explicitly), started with `--agent` or the `agent` setting, and Claude Code didn’t find an agent by that name. It searches the session’s original directory first, when you have [trusted that workspace](permissions.md#project-allow-rules-and-workspace-trust), then the directory you resume from. The session still resumes, but with the default tools, so the agent’s tool restrictions no longer apply:

```python
This session was running agent 'code-reviewer', which is no longer available (no agent by that name in /home/you/project). Continuing with the default tools and system prompt — the agent's tool restrictions no longer apply. To restore it, re-create the agent, or resume with an explicit --agent <name>.
```

The warning names only the directories Claude Code searched, and it appears in the resumed conversation whether you wake a [background session](../09-Agents-Patterns/agent-view.md), run `/resume` or `claude --resume`, or resume in [non-interactive mode](headless.md), where it also goes to stderr. Sessions using `--input-format stream-json` don’t show it, because the Agent SDK supplies agents after startup. Claude Code doesn’t save the fallback to the session, so the warning repeats on each resume until you act. The built-in `claude` agent doesn’t trigger the warning, since falling back to the default toolset changes nothing for it. Before v2.1.216, Claude Code silently continued as the default agent, and the lookup covered only the directory you resumed from, so a project-scoped agent was lost on any resume from another directory. **What to do:**

- Re-create the agent file at `.claude/agents/<name>.md` in the session’s project, or at `~/.claude/agents/<name>.md` for a personal agent, then resume again
- Or resume with `--agent <name>` naming an agent that does exist, to run the session as that agent instead
- If the agent is project-scoped and you haven’t trusted the session’s original directory, run Claude Code there once, accept the trust dialog, then resume again


[​](#restarted-after-its-next-loop-wakeup-was-due)

This session restarted after its next /loop wakeup was due

A [self-paced `/loop`](scheduled-tasks.md#let-claude-choose-the-interval) in a [background session](../09-Agents-Patterns/agent-view.md) has stopped. The session’s process ended while the loop was waiting for its next wakeup, and that wakeup came due before the session’s [next process](../09-Agents-Patterns/agent-view.md#the-supervisor-process) started. The missed wakeup doesn’t fire late. The notice says how overdue the wakeup was when the session restarted:

```python
This session restarted 12m after its next /loop wakeup was due, so that wakeup will not fire. The loop stays stopped until Claude schedules it again: reply to continue it.
```

Before v2.1.295, the loop stopped in this situation without a notice. **What to do:**

- To continue the loop, [reply to the session](../09-Agents-Patterns/agent-view.md#peek-and-reply) and say so, such as `keep the loop running`. Claude reads the notice with your reply and can schedule the next wakeup
- If you’re done with the loop, do nothing. It has already stopped


[​](#no-llm-gateway-opened-from-another-folder)

No LLM gateway: a gateway set in your shell isn’t passed to a session opened from another folder

The [background session](../09-Agents-Patterns/agent-view.md) showing this message isn’t using your [LLM gateway](../13-Enterprise-Admin/llm-gateway.md): it didn’t get the gateway’s address, so its requests fail. The message appears in the conversation in place of Claude’s reply, with your session’s ID and folder filled in:

```python
No LLM gateway: a gateway set in your shell isn't passed to a session opened from another folder. To fix, run `claude respawn abc12345` from ~/project in another terminal where your gateway is set, or set ANTHROPIC_BASE_URL and its API key or token in a settings file's env block.
```

While you’re attached to the session, the notice under its prompt shows the short form `No LLM gateway: opened from another folder · respawn from ~/project`. You dispatched, woke, or restarted the session from a folder other than the one the message names, while `ANTHROPIC_BASE_URL` was set to your gateway. For the cases where a shell-exported gateway does reach a background session, see [LLM gateway](../09-Agents-Patterns/agent-view.md#llm-gateway). **What to do:**

- **You used agent view in a project whose settings set the gateway**: put `ANTHROPIC_BASE_URL` and its API key or token in [a settings file’s `env` block](../13-Enterprise-Admin/llm-gateway-connect.md#set-in-a-settings-file). Use `~/.claude/settings.json`, or `.claude/settings.local.json` in the session’s own project, both of which a respawned session reads. Then run `claude respawn <id>` in your shell from any folder.
- **You exported the gateway in your terminal**: in a terminal where you’ve exported the gateway variables, `cd` to the folder the message names and run the message’s `claude respawn <id>` command. The session restarts from its saved conversation.
  - The gateway reaches the session only when the [supervisor](../09-Agents-Patterns/agent-view.md#the-supervisor-process) was itself started from a shell that exported the same gateway. If the supervisor wasn’t, restart it from that terminal as [Dispatch fails with `Could not resolve authentication method`](../09-Agents-Patterns/agent-view.md#dispatch-fails-with-could-not-resolve-authentication-method) describes, then run the respawn command again.

Before v2.1.302, a background session in this situation showed a sign-in error such as [`Not logged in · Please run /login`](#not-logged-in) instead, without naming the folder.


[​](#claude_code_process_wrapper-launcher-errors)

CLAUDE_CODE_PROCESS_WRAPPER launcher errors

[`CLAUDE_CODE_PROCESS_WRAPPER`](../13-Enterprise-Admin/corporate-launcher.md) is set, and its value can’t be used, so Claude Code refuses to start the affected process rather than run it without the launcher. Configuration problems are reported with a message that starts with the variable name and states the reason, for example:

```python
CLAUDE_CODE_PROCESS_WRAPPER: launcher `/opt/corp/launcher` is not an executable regular file
```

A launcher that starts but exits without replacing itself with Claude Code fails the session it was starting, and the session’s row in agent view reports that the launcher `must exec, not daemonize`, followed by anything the launcher printed. A session that can’t start or reach the background service because of the launcher reports the launcher problem as the reason inside `Couldn't reach the background service (...)`. **What to do:**

- Set the variable to the absolute path of an executable that ends by calling `exec "$@"`. See [the launcher contract](../13-Enterprise-Admin/corporate-launcher.md#the-launcher-contract) for the full contract
- Check `/status`, which shows the resolved launch command in its Self-exec entry and warns when the running background service doesn’t match it, or run `claude daemon status` from a shell
- After fixing the value in the `env` block of [settings](../13-Enterprise-Admin/corporate-launcher.md#set-up-the-launcher), restart the background service with `claude daemon stop --any` so the next dispatch starts a wrapped one


[​](#eunknown-when-starting-a-background-session)

EUNKNOWN when starting a background session

Windows refused to start a program with an error code that has no standard name, so the failure surfaces as `EUNKNOWN`. The usual trigger is a software restriction policy, such as Group Policy or AppLocker, blocking the program being started. The error appears when you start a [background session](../09-Agents-Patterns/agent-view.md) with `/background` or `claude --bg`:

```python
Couldn't reach the background service (spawn background service: EUNKNOWN: unknown error, uv_spawn) — run 'claude daemon status'
```

On some accounts the message says `daemon` in place of `background service`. On an npm installation, an `EUNKNOWN` that appears while `npm install -g @anthropic-ai/claude-code` is replacing the binary has the same cause as [`EACCES` during a reinstall](#eacces-when-starting-a-background-session) and clears when you retry after the install finishes. Claude Code starts the background service through PowerShell so the service survives closing the terminal, using PowerShell 7 when it’s installed and Windows PowerShell 5.1 otherwise. When neither PowerShell can run, Claude Code starts the service directly instead, so a policy that blocks only PowerShell doesn’t cause this error. Before v2.1.212, Claude Code used only Windows PowerShell 5.1 to start the service, so any machine where Group Policy blocked PowerShell 5.1 failed with `Couldn't start the session — EUNKNOWN: unknown error, uv_spawn`, even with PowerShell 7 installed. **What to do:**

- If the message reads `Couldn't start the session`, upgrade to v2.1.212 or later. On earlier versions you can also run `claude daemon run` in a separate terminal first, then start the background session again. That command runs the background service in the terminal’s foreground, so the service lasts only as long as that terminal stays open.
- If an npm install was replacing the binary, wait for it to finish, then start the background session again
- If the error appears on v2.1.212 or later while no npm install is running, check with your Windows administrator whether a restriction policy blocks the Claude Code executable
- If the background service stops when you close the terminal, Claude Code started it without PowerShell. Install PowerShell 7, or ask your administrator to unblock PowerShell, so the service can outlive the terminal.


[​](#eacces-when-starting-a-background-session)

EACCES when starting a background session

Claude Code couldn’t run its own binary to start the [background service](../09-Agents-Patterns/agent-view.md#the-supervisor-process) that hosts background sessions. On an npm installation, this usually means `npm install -g @anthropic-ai/claude-code` was replacing the binary at that moment, whether you ran it or the [auto-updater](../01-Getting-Started/setup.md#auto-updates) did. The error appears when you open a session from [agent view](../09-Agents-Patterns/agent-view.md):

```python
Couldn't start the background service — spawn background service: EACCES: permission denied, posix_spawn '/usr/local/lib/node_modules/@anthropic-ai/claude-code/bin/claude'
```

When you start a session with `/background` or `claude --bg`, the same reason appears inside `Couldn't reach the background service (...)`. During the same reinstall window the error can name another code instead, such as `ENOENT` or `ENOEXEC`, or `EUNKNOWN` or `EPERM` on Windows; an `EUNKNOWN` that persists across retries has a [different cause](#eunknown-when-starting-a-background-session). On an npm installation, Claude Code waits for the reinstall to finish and retries on its own: up to ten seconds, and up to two minutes while an npm install of Claude Code is visibly still running on the machine, which covers another Claude Code process downloading an update. When the install outlasts that wait, the failure names the update instead of the bare error code:

```python
Claude Code is being updated by npm on this machine (still not runnable after 2 min, EACCES) — try again when the update finishes
```

Before v2.1.257, the wait stopped at ten seconds in every case, so this error appeared while another Claude Code process was still downloading an update. Before v2.1.246, Claude Code failed at once, without waiting. **What to do:**

- Wait a few seconds, then open the session or dispatch again. When the message says Claude Code is being updated, retry after the update finishes.
- If the error persists while no npm install is running, your user can’t run the installed binary. Check its permissions and its directory’s, or reinstall Claude Code.


[​](#background-service-exited-before-it-became-reachable)

Background service exited before it became reachable

The process Claude Code started as the [background service](../09-Agents-Patterns/agent-view.md#the-supervisor-process) exited before it accepted connections, so Claude Code couldn’t open your session. When the service printed an error before exiting, the reason in parentheses gives the exit code or signal and the first line the service printed, which names what stopped it:

```python
Couldn't reach the background service (background service exited before it became reachable (exit code N): <the service's first error line>) — run 'claude daemon status'
```

When you open a session from [agent view](../09-Agents-Patterns/agent-view.md), the same reason follows `Couldn't start the background service —`. When the service printed nothing before exiting, the message says `nothing on stderr` instead. Claude Code reports the failure with the service’s error line. Before v2.1.246, the failure surfaced only after a 45-second wait, as `background service did not become reachable within 45s`, without the service’s error line. Two quoted reasons have known causes:

- `Error: claude native binary not installed.`: an npm install was replacing the Claude Code binary at that moment, so the service ran npm’s placeholder instead. Retry after the install finishes; if the line persists with no install running, [complete the npm install](troubleshoot-install.md#native-binary-not-found-after-npm-install). Before v2.1.257, a macOS npm self-update produced this failure on every start during the install window.
- `nothing on stderr` with exit code 1, on every start, on Windows: `daemon.lock` names a process that Claude Code can neither signal nor prove is gone, so each new service concludes another one holds the lock and exits. A lock whose writer Claude Code can prove is gone is replaced on its own and doesn’t produce this failure. When the failure repeats on every start, delete `~/.claude/daemon.lock`, then open the session or dispatch again. Before v2.1.257, such a lock blocked every start until you deleted the file.

**What to do:**

- If the message quotes a line, fix what it names, then open the session or dispatch again. The next attempt starts the service again
- Run `claude daemon status` to check whether a service is running now


[​](#working-directory-no-longer-exists-when-starting-a-background-session)

Working directory no longer exists when starting a background session

The directory you started a [background session](../09-Agents-Patterns/agent-view.md) in was removed while the session was starting. Claude Code doesn’t start the session, and the message names the missing directory:

```python
Couldn't start a background session (working directory no longer exists or is not accessible: /tmp/demo)
```

Before v2.1.257, the session appeared to start and then showed in agent view as a failed row with the same reason. Before v2.1.281, this message also appeared when the directory was already gone before you started the session. That case reports [`could not be resolved on disk`](#workspace-not-trusted-when-dispatching-a-background-session). **What to do:**

- Recreate the directory the message names, or dispatch from a directory that exists, then try again


[​](#workspace-not-trusted-when-dispatching-a-background-session)

Workspace not trusted when dispatching a background session

You started or restarted a [background session](../09-Agents-Patterns/agent-view.md) in a directory you haven’t [trusted](permissions.md#project-allow-rules-and-workspace-trust), and the workspace trust dialog couldn’t appear to ask you. Claude Code doesn’t start the session:

```python
Workspace not trusted. Run `claude` in /path/to/project once and accept the trust prompt, then retry.
```

From a terminal in the session’s own directory, the same command shows the trust dialog instead and starts the session once you accept. This message appears where no dialog can, such as in a script, or when you restart a session from a directory other than its own. Two variants name a different cause:

- **`The home directory is trusted one session at a time`**: the session’s directory is your home directory. Claude Code never saves trust for the home directory, so accepting the dialog there in an earlier session doesn’t count.
- **`<path> could not be resolved on disk`**: Claude Code couldn’t find the session’s directory on disk.

Before v2.1.286, on Windows, this message could also appear in a directory you had already trusted, if its trust record was saved with the path in a different letter case. Update to v2.1.286 or later. **What to do:**

- Run `claude` in the directory the message names and accept the trust dialog, then run the command again
- For the home-directory message, run the command from a terminal in your home directory so the dialog can appear, or start the session from a project directory instead
- For the `could not be resolved on disk` message, recreate the directory, or start a new session from a directory that exists


[​](#wrapper-and-ide-errors)

Wrapper and IDE errors

These errors come from the program that launched Claude Code for you, such as an IDE extension or an [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) application, rather than from Claude Code itself.


[​](#claude-code-process-exited-with-code-n)

Claude Code process exited with code N

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

```python
Error: Claude Code process exited with code 1
```

On Windows, the native build can exit with code `4294967295` right after a turn completes. When that exit lands at a turn boundary, with no message waiting and no background task running, the [VS Code extension](../03-IDE-Integrations/vs-code.md) closes the session quietly instead of showing this error. Your next message resumes the conversation. Before v2.1.273, the extension showed the error for that exit at every turn boundary, even though nothing was lost. **What to do:**

- In VS Code, follow the **View output logs** link shown with the error to see the underlying failure
- In an Agent SDK application, catch the error around your message loop. The entries under [CLI process exit](../05-Agent-SDK/agent-sdk-troubleshooting.md#cli-process-exit) cover what your code receives in each SDK language.
- Run `claude` in a terminal in the same project. The failure usually reproduces there with its real error message, which you can then look up on this page.
- Run `claude doctor` in a terminal to check the installation and configuration


[​](#could-not-locate-the-claude-cli-on-path)

Could not locate the Claude CLI on PATH

The [VS Code extension](../03-IDE-Integrations/vs-code.md) shows this error on Windows when you open Claude Code in the integrated terminal, the terminal’s shell is PowerShell, and the extension can’t find the installed `claude` executable on PATH. The extension refuses to launch Claude Code until it finds the installed `claude` on PATH.

```python
Failed to run Claude Code: Error: Could not locate the Claude CLI on PATH. Launching by name in a PowerShell terminal would run a 'claude' from the open folder instead of the installed CLI, so the launch was blocked. Make sure the Claude CLI's install directory is on your system PATH (not only your PowerShell profile), then restart VS Code and try again. VS Code reads PATH when it starts, so PATH changes take effect only after a restart.
```

**What to do:**

- Open a new PowerShell window outside VS Code and run `where.exe claude`. If it doesn’t print a path, the CLI isn’t on your PATH: add its install directory by following [Verify your PATH](troubleshoot-install.md#verify-your-path). If it prints a path, the entry comes from your PowerShell profile or from a PATH change VS Code hasn’t picked up yet; the next two steps cover those cases.
- Set the PATH entry as a user or system environment variable, not in your PowerShell profile. The extension doesn’t run your profile, so a PATH edit that lives only there never reaches it.
- Restart VS Code after changing PATH. The extension checks the PATH that VS Code captured at startup, so a PATH change takes effect only after a restart.


[​](#the-connection-to-claude-code-ended-before-this-message-completed)

The connection to Claude Code ended before this message completed

The [VS Code extension](../03-IDE-Integrations/vs-code.md) sent your message to the `claude` process, and the connection ended without an error before the process acknowledged or finished it. The extension can’t tell whether the message was processed, so it asks you to send it again:

```python
The connection to Claude Code ended before this message completed — it may not have been processed, so please send it again.
```

**What to do:**

- Send the message again. The next message starts a fresh `claude` process that resumes the conversation.
- If it repeats, run `claude` in a terminal in the same project. A failure that keeps ending the process usually reproduces there with its real error message.


[​](#rewind-warnings-and-errors)

Rewind warnings and errors

These messages come from a [`/rewind`](checkpointing.md) code restore. `Restored the code, but skipped N files` is a warning that Claude Code skipped some paths. `No files were restored` is an error that means it restored nothing.


[​](#restored-the-code-but-skipped-files)

Restored the code, but skipped files

A `/rewind` code restore skipped one or more tracked paths instead of writing or deleting through them. Claude Code skips a path when:

- it is, or became, a symlink, hard link, or other non-regular file
- its directory changed since the checkpoint
- its backup can’t be safely read

Skipped paths keep their current contents. Before v2.1.216, `/rewind` wrote and deleted through links at tracked paths, and didn’t report a partial restore.

```python
Restored the code, but skipped 2 files: the tracked path is (or became) a link or other non-regular file, its directory changed since the checkpoint, or its backup could not be safely read. Skipped files were left untouched — run with --debug for the paths.
```

**What to do:**

- Identify which files were skipped so you can handle each one with the steps below. The message gives only a count; the debug log at `~/.claude/debug/<session-id>.txt` names each skipped path as the restore runs, so turn on debug logging with `/debug` before your next restore. On macOS or Linux, you can instead find the links directly: `find . -type l` for symlinks and `find . -type f -links +1` for hard-linked files.
- If a skipped file is a link you created on purpose, such as a config file managed by a dotfile manager or a file hard-linked by tools like pnpm, the rewind left its contents alone. To undo the session’s changes to it, ask Claude to reverse the edit or edit the file yourself
- If you didn’t create the link, inspect the path before trusting its contents


[​](#no-files-were-restored)

No files were restored

Claude Code shows this message when you restore code with [`/rewind`](checkpointing.md) and it can’t restore any of the files in that checkpoint. For each file, either the backup Claude Code saved before editing it is missing, or Claude Code couldn’t write to or delete the file.

```python
Failed to restore the code:
No files were restored: 1 file failed (backup missing, or the file could not be updated)
```

Claude Code deletes a session’s backups in the [retention sweep](claude-directory.md#cleaned-up-automatically), by default about 30 days after the session last saved one. If you resume a session after that, `/rewind` still lists its checkpoints, but rewinding to one of them can fail with this error. If the message also says `N paths were skipped for link safety`, see [Restored the code, but skipped files](#restored-the-code-but-skipped-files) for those paths. When you fork a session, for example with [`--fork-session`](cli-reference.md#cli-flags) or [`/branch`](sessions.md#branch-a-session), Claude Code copies the original session’s backups into the fork. When Claude Code can’t copy a backup, for example because the disk is full, that backup is missing in the fork. Rewinding to a checkpoint that needs it can fail with this error. **What to do:**

- Undo the changes another way: ask Claude to reverse its edits, or restore the files from version control. When the backups are gone, running `/rewind` again fails the same way.
- If Claude Code couldn’t write or delete a file, fix what blocks the write, such as file permissions, then run `/rewind` again.
- To keep backups longer in future sessions, raise [`cleanupPeriodDays`](settings-reference.md#cleanupperioddays).

Before v2.1.260, Claude Code silently skipped files whose backups were missing, and the rewind appeared to succeed.


[​](#session-saving-warnings)

Session saving warnings

Claude Code shows these warnings on a persistent line below the input box when it isn’t saving your session transcript. The session keeps working either way; the warnings tell you the session may be missing from [`--resume`](sessions.md) later.


[​](#transcript-writes-are-failing)

Transcript writes are failing

Claude Code saves the transcript to disk as you work, and its writes to [the transcript file](sessions.md#where-transcripts-are-stored) are failing. The message names the cause with the underlying error code, for example a full disk:

```python
Transcript writes are failing (disk full — ENOSPC) · recent messages may not be saved for resume
```

The warning appears at different points depending on the error:

- On the first failure for conditions that don’t clear on their own: a full disk, an exceeded disk quota, a read-only filesystem, a path over the filesystem’s length limit, or, on macOS and Linux, a permission error
- After repeated failures spanning at least a minute for everything else, including permission errors on Windows, where an antivirus scan can fail a single write that then succeeds on retry

Before v2.1.217, Claude Code dropped the failing writes without a warning, and a later `--resume` missing recent messages was the first sign. **What to do:**

- Fix the condition the error code names: free disk space for `ENOSPC`; raise or clear the quota for `EDQUOT`; restore write access to the transcript location for `EACCES`, `EPERM`, or `EROFS`
- The warning clears on its own at the next successful write; no restart is needed
- Messages sent while the warning was showing may still be missing when you resume the session later


[​](#transcript-saving-is-off-skip-prompt-history)

Transcript saving is off because CLAUDE_CODE_SKIP_PROMPT_HISTORY is set

This session started with [`CLAUDE_CODE_SKIP_PROMPT_HISTORY`](env-vars.md) set, so Claude Code writes no transcript or prompt history for it:

```python
Transcript saving is off — CLAUDE_CODE_SKIP_PROMPT_HISTORY is set · --resume will not find this session; if unintended, unset it and restart
```

The variable is an intentional opt-out for ephemeral scripted sessions, but it can also reach a session through a shell profile, a wrapper script, or a parent process that exported it. **What to do:**

- If you set the variable on purpose, no action is needed; the notice confirms the session won’t appear in `--resume`, `--continue`, or up-arrow history
- If you didn’t, remove the variable from the shell or script that launches `claude`, then start a new session. Messages from the current session aren’t saved retroactively.


[​](#transcript-saving-is-off-child-session-marker)

Transcript saving is off because of an inherited CLAUDE_CODE_CHILD_SESSION marker

Claude Code sets [`CLAUDE_CODE_CHILD_SESSION`](env-vars.md) in the subprocesses it spawns, and treats an interactive session that inherits it as nested: Claude Code saves no transcript for it, so sessions that Claude itself starts don’t fill your `--resume` list. This notice means your current session inherited the marker:

```python
Transcript saving is off — inherited CLAUDE_CODE_CHILD_SESSION marker · restart with CLAUDE_CODE_FORCE_SESSION_PERSISTENCE=1 to keep future transcripts
```

The notice is expected when you ran `claude` from inside another Claude Code session; it signals a misclassification when the marker leaked through a long-lived intermediary, for example a terminal, `screen` session, or launcher that a Claude Code session originally started. Inside tmux, Claude Code detects a marker that arrived through the tmux server’s global environment and keeps saving, so this notice doesn’t appear for that case. **What to do:**

- If you started this session from inside another Claude Code session on purpose, no action is needed
- If this is a top-level session, exit and restart with [`CLAUDE_CODE_FORCE_SESSION_PERSISTENCE=1`](env-vars.md) set. Saving applies from the restart, so messages sent before it aren’t saved.
- To fix future launches from the same terminal or launcher, remove `CLAUDE_CODE_CHILD_SESSION` from its environment


[​](#configuration-warnings)

Configuration warnings

To find a warning that Claude Code gave at startup in an interactive session, look below the startup banner first, then in the debug log:

- **Row below the startup banner**: some warnings about [permission rules](permissions.md), such as [`⚠ Deny rule Bsh matches no tool · check for typos`](#matches-no-tool)
- **Debug log**: Claude Code keeps this log only in debug mode. To read the warnings in it, start Claude Code from your shell with `claude --debug-file <path>`, then open the file at that path.

In [non-interactive mode](headless.md) with text output, outside a [background session](../09-Agents-Patterns/agent-view.md), look for startup warnings on stderr. Before v2.1.305, look on stderr in an interactive session as well, including for the permission-rule warnings that now show as rows below the banner.


[​](#exited-after-an-unrecoverable-interface-error)

Claude Code exited after an unrecoverable interface error

Claude Code prints this message when it exits because its terminal interface hit an error it can’t recover from, in either renderer. The second sentence appears only when the error happened while the [fullscreen](fullscreen.md) renderer was starting:

```python
Claude Code exited after an unrecoverable interface error (<error>). It happened while the fullscreen renderer was starting, so the next launch will use the classic renderer (CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1 forces that any time).
```

**What to do:**

- Start Claude Code again. To pick the conversation back up, run `claude --resume` in the same directory.
- If the message names the fullscreen renderer, [Fullscreen rendering](fullscreen.md#fullscreen-renderer-didnt-finish-starting) says what the next launch does, which depends on how you turned fullscreen on, and how to try fullscreen again or keep the classic renderer.

Before v2.1.236, Claude Code exited without printing a message after this kind of error.


[​](#agent-descriptions-are-over-the-15000-token-limit)

Agent descriptions are over the 15.0k-token limit

Claude Code shows this warning as a startup notice in the conversation view rather than on stderr. The combined descriptions of your [subagents](../09-Agents-Patterns/sub-agents.md), except the built-in ones, exceed 15,000 tokens as Claude Code estimates them. Each agent counts its name plus its `description` frontmatter. Claude Code loads every agent whether or not the total is over the limit, so the warning doesn’t change what loads.

```python
Agent descriptions are over the 15.0k-token limit (~16.2k tokens) · ask Claude to trim agent descriptions in .claude/agents/
```

**What to do:**

- Shorten the `description` frontmatter of your agent files, or ask Claude to trim them for you.
- Remove agent files you no longer use.


[​](#hook-needs-quotes-around-a-path-with-a-space)

Hook needs quotes around a path with a space

This notification in the conversation view means a hook’s script didn’t run because its path has a space and isn’t quoted. That hook is an [`asyncRewake`](../07-Hooks/hooks.md#run-hooks-in-the-background) hook in shell form. In its `command`, an interpreter such as `python3` is followed by an unquoted path placeholder, and the resolved path contains a space. The notification starts with the hook’s event name and names the script:

```python
Stop hook needs quotes around a path with a space (check.py)
```

**What to do:**

- In the `command` of the hook that runs the script the notification names, wrap the path in double quotes. In a JSON file, write it as `"command": "python3 \"${CLAUDE_PLUGIN_ROOT}/hooks/check.py\""`.


[​](#instruction-file-not-loaded)

Instruction file not loaded

This notice in the conversation view of an interactive session means a [memory file](memory.md#how-claude-md-files-load) that exists wasn’t loaded. A read restriction is in force.

```python
Instruction file not loaded (a Read deny rule covers it):
path: .claude/rules/shared.md
```

The parenthetical names the reason, for example:

- **`a Read deny rule covers it`**: a `Read` [deny rule](permissions.md#read-and-edit) matches the file’s path as written or where a link on it leads
- **`it's read from outside your working directories, where reads are blocked`**: the file resolves outside the [working directories](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) while [`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) is on
- **`where it leads couldn't be worked out`**: for example, the file is a link that leads back to itself, directly or through other links

When a subdirectory’s own memory file can’t be loaded as Claude works with files there, the same lines appear in the conversation during the turn. When more files are withheld than the lines name, a final line counts the rest, such as `and 3 more instruction files not loaded`. **What to do:**

- Nothing, if the restriction is intended: the session runs without that file’s instructions.
- To load a file withheld because `a Read deny rule covers it`, [remove or narrow that rule](permissions.md#manage-permissions). Then start a new session.
- To load a file withheld because `it's read from outside your working directories, where reads are blocked`, move it or its link target inside the working directories. Then start a new session.
- To load a file withheld because `where it leads couldn't be worked out`, check whether the file is a link that leads back to itself. If it is, point the link at a file that exists or put a regular file in its place. Then start a new session.

Before v2.1.292, the notice named the file at the end of the same line after the reason.


[​](#a-skill-command-or-workflow-wasnt-loaded-because-its-name-is-reserved)

A skill, command, or workflow wasn’t loaded because its name is reserved

A skill folder, a frontmatter `name`, a file or subfolder in `.claude/commands/`, or a [saved workflow](workflows.md#save-the-workflow-for-reuse) uses the name `anthropic-skills` or a name that starts with `anthropic-skills:`. Claude Code [reserves that name for skills synced from claude.ai](../08-Plugins-Skills/skills.md#names-reserved-for-synced-skills) and doesn’t load that item. Claude Code shows this warning as a startup notice in the conversation view rather than on stderr:

```python
Not loaded: rename .claude/skills/anthropic-skills, then restart — its name uses "anthropic-skills", a name reserved for the skills synced from your claude.ai account
```

The notice names what to change for the first item it refused: a folder or file to rename, a `name:` line to edit, or a workflow to rename. When more than one item was refused, the notice ends with a count such as `· 2 more`, and the [debug log](debug-your-config.md) names each one. **What to do:**

- Rename the item the notice names, or edit the `name:` line it points to, then restart the session.

Before v2.1.282, Claude Code loaded skills and commands with these names.


[​](#skill-or-command-name-refused)

Skill or command name refused

This startup notice means Claude Code refused the name of at least one [skill or custom command](../08-Plugins-Skills/skills.md), so it didn’t load or loaded without its `name` field:

```python
1 skill or command name refused: run with --debug to see which ([names]), rename, then restart — a name may not hold hidden, direction-changing or blank-like characters, < or >, or be over 256 characters
```

- **Not loaded**: Claude Code refused the name a skill or command goes by, such as its directory name or a command file’s name or subfolder. It’s missing from the `/` menu and Claude can’t invoke it. Its line in the debug log reads `<name> is not offered`.
- **`name` field ignored**: Claude Code refused a skill’s frontmatter `name`. The skill still loads, but the `/` menu doesn’t show the `name` value and typing it doesn’t invoke the skill. Its line in the debug log reads `<name value> is not shown for <skill>`.

**What to do:**

- Start Claude Code with `claude --debug` from your shell and search the [debug log](debug-your-config.md) for `[names]`. Each name the notice counts has one line there. The line spells out some hidden characters as codes, such as `\u{200B}` for a zero-width space, so you can see where they are.
- Remove the [characters a skill name can’t hold](../08-Plugins-Skills/skills.md#characters-a-skill-name-cant-hold) by renaming the folder or file or editing the `name:` line, or shorten a name that is over 256 characters. Then restart the session, unless the file is in a directory Claude Code [watches for changes](../08-Plugins-Skills/skills.md#live-change-detection). For a skill from a plugin you didn’t write, ask the plugin’s author to rename it.


[​](#workspace-has-not-been-trusted)

Workspace has not been trusted

Claude Code found `permissions.allow` rules or `permissions.additionalDirectories` entries in the project’s `.claude/settings.json` or `.claude/settings.local.json` and didn’t apply them, because [allow rules from project settings require workspace trust](permissions.md#project-allow-rules-and-workspace-trust). The count, the setting name, and the file named in the message vary with your configuration. `deny` and `ask` rules aren’t affected.

```python
Ignoring 2 permissions.allow entries from .claude/settings.local.json: this workspace has not been trusted. Run Claude Code interactively here once and accept the trust dialog, or set projects["/Users/you/project"].hasTrustDialogAccepted: true in /Users/you/.claude.json.
```

**What to do:**

- Run `claude` in the directory and accept the trust dialog. [Project allow rules and workspace trust](permissions.md#project-allow-rules-and-workspace-trust) says which folder that acceptance covers.
- In [non-interactive mode](headless.md) with `-p` no dialog is shown. Set the `hasTrustDialogAccepted` entry in `~/.claude.json` using the exact `projects` key the message prints.
- If the message names `.claude/settings.local.json` and you started Claude Code outside a git repository or in your home directory, update to v2.1.200 or later. Versions 2.1.196 through 2.1.199 treated your own `.claude/settings.local.json` as repository-supplied in those workspaces. On v2.1.207 and later, updating isn’t enough outside a git repository if you haven’t trusted the folder: determining that a folder isn’t inside a repository runs git, and Claude Code runs that check only after you accept the trust dialog, so use the first step. Your home directory and any other [configuration home](permissions.md#project-allow-rules-and-workspace-trust) are exempt and don’t wait for the dialog. See [Project allow rules and workspace trust](permissions.md#project-allow-rules-and-workspace-trust).


[​](#working-directory-is-a-network-path)

Working directory is a network path

Claude Code doesn’t add network paths as working directories. Looking up a network path can contact the host it names, and on Windows that contact can send the host your credentials. Claude Code therefore refuses the path without looking it up. You see this message when you run `/add-dir` with a network path:

```python
\\server\share is a network path, which cannot be added as a working directory. On Windows, map the share to a drive letter and pass it at launch with --add-dir (a drive letter added mid-session does not yet carry remote-read trust).
```

When you pass one at startup instead, with `--add-dir` or in `permissions.additionalDirectories`, Claude Code starts without that directory. In an interactive session you don’t see the message at startup, because it goes to the debug log with the other [startup warnings](#configuration-warnings). Paths that Claude Code refuses this way include:

- UNC shares such as `\\server\share`
- Automount paths such as `/net/<host>`, unless you launched Claude Code from a directory under that host’s automount. Reads under that automount still go through the [network path check](permissions.md#network-paths).
- Local paths that reach a network location through a symbolic link or junction

Mapped drive letters and `\\wsl$` paths don’t count as network paths. **What to do:**

- On Windows, map the share to a drive letter and pass the drive at launch. In PowerShell, for example, run `net use Z: \\server\share` and then `claude --add-dir Z:\`.
- On macOS or Linux, mount the share at a local path and add that path instead.
- If the path is in `permissions.additionalDirectories`, remove it from the settings file that lists it.

Before v2.1.257, Claude Code accepted a reachable network path as a working directory.


[​](#remote-managed-settings-failed-to-load)

Remote managed settings failed to load

Your session is eligible for [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md), but Claude Code couldn’t fetch them or couldn’t apply what the server returned, so it shows this warning in interactive sessions. The parenthesized cause names what failed, such as `network error`, `request timed out`, or `authentication rejected (401)`. The cause `no setting in the server response could be applied as written` means the server answered but none of the settings it returned passed [validation](../13-Enterprise-Admin/server-managed-settings.md#invalid-entries-in-delivered-settings). Before v2.1.282, this cause read `server returned invalid settings`. The rest of the line says which policy the session runs on:

- **Settings cached from an earlier successful fetch**: Claude Code runs the session on that cached policy, except the [withheld environment variables](../13-Enterprise-Admin/server-managed-settings.md#fetch-and-caching-behavior), and the line reads `using cached policy`.
- **No cache**: Claude Code runs the session without server-managed settings, and the line reads `no remote policy applied`.

**What to do:**

- Act on the cause the message names: for a network cause, check that this machine can reach `api.anthropic.com`; for an authentication cause, check your sign-in with `/status`
- For `no setting in the server response could be applied as written`, ask your administrator to correct the settings on the server
- Run `/status` or `claude doctor` for the full diagnostic

Before v2.1.248, Claude Code reported a failed settings fetch only in the debug log.


[​](#managed-settings-were-not-approved)

Managed settings were not approved

Your organization’s [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) include settings that need your approval, and you declined the [security approval dialog](../13-Enterprise-Admin/server-managed-settings.md#security-approval-dialogs), so Claude Code exits without applying them:

```python
Managed settings were not approved; exiting without applying them.
```

**What to do:**

- Start Claude Code again and approve the dialog to continue under your organization’s settings. A declined dialog isn’t remembered, so it appears again at the next start.
- If you’re unsure about a setting the dialog lists, ask whoever maintains your organization’s managed settings before approving


[​](#managed-settings-need-your-approval)

Managed settings need your approval

Your organization’s [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) include settings that need your approval in the [security approval dialog](../13-Enterprise-Admin/server-managed-settings.md#security-approval-dialogs). The `claude plugin` command you ran couldn’t read from the keyboard, so it couldn’t show that dialog. That happens when you pipe or redirect its input and, on macOS and Linux, it also can’t open `/dev/tty`. The command stopped before making any changes:

```python
Your organization's managed settings need your approval, which couldn't be asked for here. Run `claude` in a terminal and approve them, then run this command again.
```

**What to do:**

- Run `claude` in a terminal and approve the settings when the dialog appears, then run the same `claude plugin` command again. Claude Code keeps the approval and the approved settings in your [configuration directory](../13-Enterprise-Admin/server-managed-settings.md#approval-memory). If the command that stopped ran as another user or with `CLAUDE_CONFIG_DIR` set, run `claude` the same way so that both use the same directory.


[​](#managed-settings-block-the-default-model)

Managed settings block the default model

Your organization’s [managed settings](../13-Enterprise-Admin/managed-settings.md) block the model the Default option resolves to and every model it could step down to. A session that would start on the Default option exits at startup instead of running a blocked model. Which message you see depends on the setting that blocks it. When a [`deniedModels`](model-config.md#block-specific-models-or-versions) list blocks it, the message reads:

```python
Claude Code can't start: your organization's managed settings block the default model (claude-opus-5-5) in "deniedModels", and none of the models they allow can be used as the default instead. Ask your administrator to update "deniedModels" or "availableModels".
```

When an `availableModels` list with [`availableModelsMatch`](settings-reference.md#availablemodelsmatch) set to `"exact"` omits it, the message reads:

```python
Claude Code can't start: your organization allows only the models listed in "availableModels", and none of them can be used as the default model (claude-opus-5-5 isn't listed). Ask your administrator to update "availableModels".
```

**What to do:**

- If you administer the settings, add a model your users can run to `availableModels`, or narrow the `deniedModels` entries that block every fallback. [Block specific models or versions](model-config.md#block-specific-models-or-versions) describes how the Default option steps down
- If you don’t administer them, send the message to your administrator. Your own settings files can’t widen a managed `availableModels` or `deniedModels` list


[​](#managed-settings-dont-allow-this-api-provider)

Managed settings don’t allow this API provider

Your organization’s [managed settings](../13-Enterprise-Admin/managed-settings.md) set an [`allowedProviders`](settings-reference.md#allowedproviders) list, and the session’s API provider isn’t on it or the session uses an endpoint that isn’t pinned the way that entry requires. Claude Code refuses at startup, before a login, or when the session next contacts the API. The message begins with the permitted providers:

```python
Your organization's managed settings allow Claude Code to use: Anthropic API, Amazon Bedrock.
```

When the list is empty, the message reads instead:

```python
Your organization's managed settings allow Claude Code to use no API provider at all (allowedProviders is an empty list), so it cannot start on this machine.
```

When every entry is unrecognized, the parenthetical reads `(allowedProviders lists only unrecognized entries)` instead. **What to do:**

- Follow the message’s `To continue:` steps
- If you administer the settings, the message’s lines starting `Admins:` name the entry to add or the value to pin, and the [`allowedProviders`](settings-reference.md#allowedproviders) entry says which source’s `env` block can pin it


[​](#mcp-server-is-blocked-by-enterprise-managed-policy)

MCP server is blocked by enterprise managed policy

You selected **Reconnect** on a server in `/mcp`, or turned a disabled server back on there, and a setting that [restricts MCP servers](../06-MCP-Tools/General/managed-mcp.md) blocks that server. Claude Code refuses to connect it and shows:

```python
MCP server <name> is blocked by enterprise managed policy
```

Any of these settings can produce the message:

- A [`deniedMcpServers`](../06-MCP-Tools/General/managed-mcp.md#policy-based-control-with-allowlists-and-denylists) entry that matches the server, including one in your own `~/.claude/settings.json` or the project’s `.claude/settings.json`
- An [`allowedMcpServers`](../06-MCP-Tools/General/managed-mcp.md#policy-based-control-with-allowlists-and-denylists) list that the server doesn’t match
- [`strictPluginOnlyCustomization`](settings-reference.md#strictpluginonlycustomization) with `mcp` locked, which blocks servers configured in `~/.claude.json` and `.mcp.json`
- [`disableClaudeAiConnectors`](../06-MCP-Tools/General/mcp.md#disable-claude-ai-connectors), when the server is a claude.ai connector

**What to do:**

- Check your own user and project settings files for one of these settings and change or remove it
- If none of your own settings explains the block, ask your administrator which managed setting blocks the server

Before v2.1.257, **Reconnect** and re-enable in `/mcp` could connect a server that a mid-session policy update blocked.


[​](#mcp-server-name-is-reserved)

MCP server name is reserved

This message names one of your MCP servers, whose name is among those Claude Code reserves, such as the names of its built-in servers:

```python
"workspace" is a reserved MCP server name and was not loaded
```

**What to do:**

- Rename the server where you define it, for example from `workspace` to `my-workspace`
- For other reserved names to avoid, see [MCP configuration warnings](../06-MCP-Tools/General/mcp.md#configuration-warnings)


[​](#managed-settings-document-could-not-be-parsed)

Managed settings document could not be parsed

Your organization deploys [managed settings](../13-Enterprise-Admin/managed-settings.md), and one of the deployed documents is present but can’t be parsed as a JSON object, so Claude Code exits with code 1 at startup instead of running without the policy the document carries. The line names the failed source before the message:

```python
/Library/Application Support/ClaudeCode/managed-settings.json: Managed settings document could not be parsed as a JSON object; none of its settings are in effect. Fix or remove it.
```

The source is one of:

- The path of the `managed-settings.json` file or a drop-in file under `managed-settings.d`
- The macOS managed preferences profile, `per-user managed preferences` or `device-level managed preferences`
- The Windows registry value, `Registry: HKLM\SOFTWARE\Policies\ClaudeCode\Settings`

[Find entries Claude Code dropped](../13-Enterprise-Admin/managed-settings.md#find-entries-claude-code-dropped) lists what makes each source unparseable. Claude Code refuses to start even when another admin source delivers a valid policy. You see this error in interactive sessions, `claude -p`, Agent SDK sessions, [background sessions](../09-Agents-Patterns/agent-view.md), and most subcommands, `claude doctor` included. The refusal fails closed on purpose: settings in a document Claude Code can’t parse can’t be enforced, and starting anyway would run sessions without the organization’s controls. A schema problem in a parseable document doesn’t produce this error. [Find entries Claude Code dropped](../13-Enterprise-Admin/managed-settings.md#find-entries-claude-code-dropped) covers what Claude Code does with one. When a `managed-settings.d/` directory exists but can’t be listed, Claude Code reports `Managed settings drop-in directory could not be read:` followed by the underlying error instead. [Find entries Claude Code dropped](../13-Enterprise-Admin/managed-settings.md#find-entries-claude-code-dropped) covers when a read failure exits at startup. **What to do:**

- If you administer the machine, fix the named document so it parses as a JSON object, or remove the file, profile, or registry value. An empty `managed-settings.json` counts as `{}` and doesn’t block launch.
- If you don’t, ask your administrator to fix the deployed document. Nothing in your own settings files causes or clears this error.


[​](#unable-to-read-managed-policy-settings)

Unable to read managed policy settings

Your organization deploys [managed settings](../13-Enterprise-Admin/managed-settings.md), and one of the deployed sources exists but couldn’t be read, for a reason such as an I/O error rather than the operating system denying the read. With no other admin source supplying a policy, Claude Code exits at startup rather than run without the policy the source may carry:

```python
Unable to read managed policy settings.
This machine may require organization login enforcement, but the policy file failed to load.
Contact your administrator.

Detail: <source>: <reason>
```

In the same state, sign-in flows, API requests from a session that is already running, and the [`claude gateway`](../13-Enterprise-Admin/claude-apps-gateway.md) server are refused with a variant of the first line that names [`allowedProviders`](settings-reference.md#allowedproviders). A read that the operating system denied, such as on a root-only file, doesn’t produce this exit: [the session starts without that source’s policies](../13-Enterprise-Admin/managed-settings.md#find-entries-claude-code-dropped). For a source that can’t be parsed, Claude Code exits with [a different message naming the source](#managed-settings-document-could-not-be-parsed). **What to do:**

- If you administer the machine, fix the problem the `Detail:` line names so the deployed source can be read, or remove the source
- If you don’t, send the message to your administrator. Nothing in your own settings files causes or clears this error

Before v2.1.285, only sessions signed in with claude.ai or Claude Console credentials exited with this message, and a read that the operating system denied produced it too.


[​](#managed-settings-hooks-not-loaded)

Managed settings contain invalid entries, including PreToolUse/PermissionRequest hooks that are NOT loaded

This stderr block from a `-p` run means that a [managed settings](../13-Enterprise-Admin/managed-settings.md) source holds a hook entry Claude Code can’t load. That hook doesn’t run, and when a line lists the source’s `hooks` field as ignored, none of that source’s hooks run. Each line names the source, the field when there is one, and the problem, such as an unknown hook `type` or a hook declared outside the `hooks` key:

```python
Managed settings contain invalid entries, including PreToolUse/PermissionRequest hooks that are NOT loaded; fix or remove each entry:
  <source> (<field>): <message>
```

**What to do:**

- If you administer the source, fix or remove each entry the block lists. [Hook configuration](../07-Hooks/hooks.md#configuration) shows the shape Claude Code expects under `hooks`.
- If a line’s source is `parent managed settings`, the application that launched Claude Code passed that entry in as [parent settings](../13-Enterprise-Admin/managed-settings.md#parent-settings-from-embedding-hosts), so report it to that application’s developer
- Otherwise, send the block to your administrator

Before v2.1.300, a `-p` run listed this case under the `Managed settings failed to load; policies from the failed source are NOT in effect:` header.


[​](#otelheadershelper-failed)

otelHeadersHelper failed

Claude Code shows this warning as a notification in the terminal interface, once per interactive session, when the [`otelHeadersHelper`](settings-reference.md#otelheadershelper) script fails or prints output that doesn’t meet the [script requirements](../13-Enterprise-Admin/monitoring-usage.md#script-requirements). While the script keeps failing, exports fail and your telemetry backend receives nothing from the session. The text after `See /status:` says what failed, such as the script’s exit code followed by its error output:

```python
otelHeadersHelper failed; telemetry is not being exported. See /status: exited 1: token service unreachable
```

**What to do:**

- Run `/status` to read the failure detail.
- Fix the script so it exits 0 within 30 seconds and prints a JSON object of string header values on stdout. See [script requirements](../13-Enterprise-Admin/monitoring-usage.md#script-requirements).
- If your organization deploys the script through [managed settings](../13-Enterprise-Admin/managed-settings.md), ask whoever maintains them to fix it.

In [non-interactive mode](headless.md) with `-p`, the same failure appears on stderr as `otelHeadersHelper failed (OpenTelemetry export headers unavailable): <error>` instead.


[​](#headershelper-not-run)

headersHelper not run

Claude Code connected an MCP server with its static `headers` alone and skipped the server’s [`headersHelper`](../06-MCP-Tools/General/mcp.md#use-dynamic-headers-for-custom-authentication), because the helper is a shell command and the folder has no saved trust. A folder gets saved trust when you set its entry in `~/.claude.json` by hand or, outside your home directory, when you accept the trust dialog for it in an interactive session. See [Trust a folder before its headersHelper runs](../06-MCP-Tools/General/mcp.md#trust-a-folder-before-its-headershelper-runs) for which servers this check applies to. Claude Code writes this line in [non-interactive mode](headless.md) only, once per server. In an interactive session it writes the same refusal to the debug log instead.

```python
MCP server 'internal-api': headersHelper not run — this workspace has no persisted trust; accept the trust dialog here once interactively, or set projects["/Users/you/project"].hasTrustDialogAccepted in /Users/you/.claude.json.
```

The `projects` key the message prints is the folder [Project allow rules and workspace trust](permissions.md#project-allow-rules-and-workspace-trust) says Claude Code keys the trust on. Accepting the trust dialog for a parent folder doesn’t satisfy the check, and a `-p` or SDK session doesn’t satisfy it either. **What to do:**

- Run `claude` in the folder the message names, accept the trust dialog, then run your `-p` or SDK command again
- Set the `hasTrustDialogAccepted` entry in `~/.claude.json` yourself, using the exact `projects` key the message prints
- If you started the session in your home directory, work from a project directory you have trusted. When you accept the trust dialog in your home directory, Claude Code holds that trust for the current session only.


[​](#malformed-tool-content-rule)

Malformed Tool(content) rule

A [permission rule](permissions.md#permission-rule-syntax) in one of your settings files doesn’t have the shape `Tool` or `Tool(content)`, for example because text follows the closing parenthesis or one of the parentheses is missing. Claude Code skips the rule and lists it in the invalid-settings dialog when an interactive session starts, and in [`claude doctor`](debug-your-config.md#check-resolved-settings) output:

```python
Invalid permission rule "Bash(ls) x" was skipped: Malformed Tool(content) rule. Rules take the form Tool or Tool(content) and must end at the closing ")"; parentheses inside the content are literal
```

**What to do:**

- In the settings file listed with the message, rewrite the rule so it ends at its closing parenthesis, for example `Bash(ls *)` in place of `Bash(ls) x`
- Leave parentheses inside the content as they are. They’re literal, so a rule such as `Edit(./Finance (2024)/**)` is valid without escaping

Before v2.1.260, Claude Code reported a rule with unmatched parentheses as `Mismatched parentheses`.


[​](#matches-no-tool)

Matches no tool · check for typos

This row below the startup banner names a deny or ask [permission rule](permissions.md) whose tool name Claude Code doesn’t recognize, so the rule doesn’t apply to the tool you meant. A deny rule written as `Bsh` isn’t applied to Bash, and neither is one that uses the label a tool shows in the transcript instead of its canonical name. The row repeats the rule as you wrote it:

```python
⚠ Deny rule Bsh matches no tool · check for typos
```

In [non-interactive mode](headless.md) with text output, Claude Code prints the warning on stderr in its longer form instead:

```python
Permission deny rule "Bsh" matches no known tool — check for typos.
```

**What to do:**

- Correct the tool name in the rule, for example `Bash` in place of `Bsh`. Look up canonical names in the [tools reference](tools-reference.md).
- To find where the rule is defined, run `/permissions` in the session and select the rule. Its details say where it comes from, such as `From project local settings`, or `From CLI argument` for a `--disallowedTools` value.
- If the details read `From enterprise managed settings`, forward the row to whoever maintains your [managed settings](../13-Enterprise-Admin/managed-settings.md), since you can’t change that rule yourself.

In a [background session](../09-Agents-Patterns/agent-view.md) or with `--output-format json` or `stream-json`, Claude Code writes the warning to the debug log instead of stderr. Run with `--debug` to capture it at `~/.claude/debug/<session-id>.txt`. Before v2.1.305, an interactive session printed the longer form on stderr at startup instead of showing the row.


[​](#is-not-matched-by-file-permission-checks)

Is not matched by file permission checks

Claude Code found a `Write`, `NotebookEdit`, `MultiEdit`, or `Glob` [permission rule](permissions.md#read-and-edit) with a path in one of your [settings files](settings.md#where-settings-live), in [managed settings](../13-Enterprise-Admin/managed-settings.md), or in a `--allowedTools`, `--disallowedTools`, or `--settings` flag value. It checks file permissions against `Edit` and `Read` rules only, so it never consults a path rule that names one of the other file tools. It keeps the rule and changes nothing else.

- **Interactive session**: the full warning goes to the [debug log](#configuration-warnings), and a deny or ask rule of this shape also shows as this row below the startup banner:

  ``` shiki
  ⚠ Deny rule Write(docs/**) never matches · use Edit(docs/**)
  ```

  An allow rule of this shape gets no row. To find where the rule is defined, run `/permissions` in the session and select the rule.
- **[Non-interactive mode](headless.md) with text output**: the full warning on stderr names the rule, its source in parentheses, and the replacement to write:

  ``` shiki
  Permission deny rule (.claude/settings.json): Write(docs/**) is not matched by file permission checks — only Edit(path) rules are. Use Edit(docs/**) instead (Edit rules cover all file-editing tools).
  ```
- **[Background session](../09-Agents-Patterns/agent-view.md), or `--output-format json` or `stream-json`**: the full warning goes to the debug log instead of stderr, so machine-read output stays clean. Run with `--debug` to capture it at `~/.claude/debug/<session-id>.txt`.

**What to do:**

- Replace `Write(path)`, `NotebookEdit(path)`, and legacy `MultiEdit(path)` rules with `Edit(path)`. `Edit` rules cover all file-editing tools.
- Except in `--allowedTools`, where Claude Code accepts a `Glob` rule without warning, replace `Glob(path)` rules with `Read(path)`.
- Fix the rule at its source, which the full warning names in parentheses: a settings file path, or the flag itself for `--allowed-tools` and `--disallowed-tools`. A `claude-settings-<hash>.json` path that doesn’t exist on disk stands for an inline `--settings` value. Fix the JSON you pass to that flag.
- Leave bare tool-name rules such as `Write` or `Glob` alone. Claude Code matches them at the [tool level](permissions.md#match-all-uses-of-a-tool) and doesn’t warn about them.
- For a rule from managed settings, the full warning’s parentheses read `managed policy settings` and the rule’s details in `/permissions` read `From enterprise managed settings`. Forward that warning to whoever maintains your managed settings, since you can’t clear it yourself.

Before v2.1.210, Claude Code accepted these rules without a warning. Before v2.1.305, an interactive session printed the full warning on stderr.


[​](#has-a-wildcard-before-the-rest-of-the-command)

Has a wildcard before the rest of the command

Claude Code found a `Bash` allow rule whose `*` comes before a later word that determines which command it is, such as `Bash(git * main)` or `Bash(git -C * status *)`, in one of your [settings files](settings.md#where-settings-live), in [managed settings](../13-Enterprise-Admin/managed-settings.md), or in an `--allowedTools` or `--settings` flag value. The `*` matches any text, including options inserted at that position: `Bash(git * main)` also approves `git -c core.fsmonitor=<script> diff main`, where `-c` makes git run a program the command names. [Wildcard patterns](permissions.md#wildcard-patterns) shows the matching rules. The warning exists so you can narrow a rule whose wildcard is broader than you intended. Claude Code keeps the rule and changes nothing about how it matches. In [non-interactive mode](headless.md) with text output, the warning on stderr names the rule and its source in parentheses:

```python
Permission allow rule (.claude/settings.json): Bash(git -C * status *) has a wildcard before the rest of the command, so it also matches any options inserted at that position and approves them without a prompt. For git, options such as -c and --exec-path can run arbitrary commands. Replace that * with the exact value you mean, or only use * after the subcommand (for example Bash(git status *)).
```

In an interactive session, the full warning goes to the [debug log](#configuration-warnings) and the rule shows as this row below the startup banner:

```python
⚠ Allow rule Bash(git -C * status *) allows any option at its * · use an exact value
```

To find where the rule is defined, run `/permissions` in the session and select the rule. **What to do:**

- Replace the `*` before the subcommand with the exact value you mean: `Bash(git checkout main)` in place of `Bash(git * main)`.
- Move every `*` after the subcommand: `Bash(git status *)` in place of `Bash(git -C * status *)`. Write one rule per subcommand you want to allow.
- Fix the rule at its source, which the full warning names in parentheses: a settings file path, or the `--allowed-tools` flag itself. A `claude-settings-<hash>.json` path that doesn’t exist on disk stands for an inline `--settings` value. Fix the JSON you pass to that flag.
- For a rule from managed settings, the full warning’s parentheses read `managed policy settings` and the rule’s details in `/permissions` read `From enterprise managed settings`. Forward that warning to whoever maintains your managed settings, since you can’t clear it yourself.

In a [background session](../09-Agents-Patterns/agent-view.md) or with `--output-format json` or `stream-json`, Claude Code writes the warning to the debug log instead of stderr, so machine-read output stays clean. Run with `--debug` to capture it at `~/.claude/debug/<session-id>.txt`. Before v2.1.246, Claude Code accepted these rules without a warning. Before v2.1.305, an interactive session printed the full warning on stderr instead of showing a row.


[​](#denying-bash-also-turns-off-the-powershell-tool)

Denying Bash also turns off the PowerShell tool

You removed the whole Bash tool, for example with `--disallowedTools Bash` or with a bare `Bash` or `Bash(*)` [deny rule](permissions.md#match-all-uses-of-a-tool) in one of your settings files. On Windows with Git Bash installed, [denying Bash also turns the PowerShell tool off](tools-reference.md#bash-deny-rules-also-turn-off-the-powershell-tool), so the session starts with no shell tool. In [non-interactive mode](headless.md) with text output, Claude Code prints this warning on stderr at startup, and an interactive session writes it only to the [debug log](#configuration-warnings):

```python
Denying Bash also turns off the PowerShell tool, so Claude has neither. To use PowerShell, set CLAUDE_CODE_USE_POWERSHELL_TOOL=1.
```

**What to do:**

- To have Claude use PowerShell, set [`CLAUDE_CODE_USE_POWERSHELL_TOOL`](env-vars.md) to `1` in your environment or in the `env` block of a settings file, as [Enable the PowerShell tool](tools-reference.md#enable-the-powershell-tool) shows. The PowerShell tool then stays on alongside your Bash deny rule.
- To block particular commands instead of the whole tool, replace the bare `Bash` entry with scoped rules such as `Bash(git push *)` in the same settings file or flag. Claude keeps the Bash tool, and the PowerShell tool stays off until you also set the variable or add a scoped [`PowerShell` permission rule](permissions.md#powershell).

In a [background session](../09-Agents-Patterns/agent-view.md) or with `--output-format json` or `stream-json`, Claude Code writes the warning to the debug log instead of stderr. Run with `--debug` to capture it at `~/.claude/debug/<session-id>.txt`. Before v2.1.287, Claude Code turned the PowerShell tool off the same way without printing a warning. Before v2.1.305, an interactive session printed the warning on stderr at startup too.


[​](#crosssessioninbound-must-be-one-of-accept-hold-refuse)

crossSessionInbound must be one of accept, hold, refuse

A settings file sets [`crossSessionInbound`](settings-reference.md#crosssessioninbound) to a value Claude Code doesn’t recognize, such as the typo `"reject"`. The warning’s second sentence depends on which file holds the value; in a user, project, local, or `--settings` file it reads:

```python
"crossSessionInbound" must be one of "accept", "hold", "refuse"; received "reject". This value was ignored; while it is present, cross-session messages are held for your approval instead of being delivered. Set it to one of the values above.
```

In [managed settings](../13-Enterprise-Admin/managed-settings.md), Claude Code treats the unrecognized value as `refuse`, the most restrictive value, and the warning says cross-session messages are turned away until an administrator fixes it. For how the hold combines with values in your other settings files, see [`crossSessionInbound`](settings-reference.md#crosssessioninbound). **What to do:**

- Set the key to `"accept"`, `"hold"`, or `"refuse"`, or remove it
- When the warning names managed settings, ask the administrator to fix the value

Before v2.1.248, Claude Code ignored an unrecognized value without warning.


[​](#anthropic-foundry-resource-must-be-a-foundry-resource-name)

ANTHROPIC_FOUNDRY_RESOURCE must be a Foundry resource name

You set [`ANTHROPIC_FOUNDRY_RESOURCE`](env-vars.md) to something other than a bare [Microsoft Foundry](microsoft-foundry.md) resource name, such as the endpoint URL or its host name. Claude Code refused the value before sending a request. The message appears in place of Claude’s reply, not as a startup warning:

```python
API Error: ANTHROPIC_FOUNDRY_RESOURCE must be a Foundry resource name (2-64 letters, digits and hyphens, not starting or ending with a hyphen, such as my-resource), not a URL or host name. To use a full URL, set ANTHROPIC_FOUNDRY_BASE_URL instead.
```

**What to do:**

- Set `ANTHROPIC_FOUNDRY_RESOURCE` to the resource name alone and restart Claude Code. For the endpoint `https://my-resource.services.ai.azure.com/anthropic`, the name is `my-resource`.
- To give the full endpoint URL instead, set [`ANTHROPIC_FOUNDRY_BASE_URL`](env-vars.md) to the URL and remove `ANTHROPIC_FOUNDRY_RESOURCE`, then restart Claude Code. Claude Code accepts only one of the two variables.


[​](#the-200k-limit-isnt-enforced)

The 200K limit isn’t enforced

You set [`CLAUDE_CODE_DISABLE_1M_CONTEXT=1`](env-vars.md), which normally makes [auto-compaction](model-config.md#default-auto-compact-thresholds) hold sessions on 1M-context models to a 200K window, but no compaction threshold caps this session at or below 200K, so the conversation can grow past it.

```python
CLAUDE_CODE_DISABLE_1M_CONTEXT is set, but the 200K limit isn't enforced for <model>, so this session can grow past it. To enforce it, set CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000 (or the autoCompactWindow setting).
```

Claude Code enforces the 200K limit on its own for every model it recognizes as having a native 1M window, and for model IDs it doesn’t recognize it compacts at the window it assumes. The warning appears when other configuration defeats that enforcement:

- The model ID isn’t one Claude Code recognizes, such as an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) alias, and you set [`CLAUDE_CODE_DISABLE_UNKNOWN_MODEL_WINDOW_ENFORCEMENT=1`](env-vars.md) or raised the assumed window past 200K with [`CLAUDE_CODE_MAX_CONTEXT_TOKENS`](env-vars.md). In this case the message also offers `or update to a Claude Code version that recognizes <model>` as a remedy.
- A `context-1m` beta requested through [`ANTHROPIC_BETAS`](env-vars.md) or the [`--betas`](cli-reference.md#cli-flags) flag still asks the API for the 1M window on a model that accepts that beta, while nothing compacts the session at 200K

**What to do:**

- Set [`CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000`](env-vars.md), or the [`autoCompactWindow`](settings-reference.md#autocompactwindow) setting to `200000`, so auto-compaction compacts at the 200K boundary
- If the message names a model ID this version doesn’t recognize, run `claude update`. A version that recognizes the ID as a 1M-context model enforces the limit without further configuration.
- If you want the session to use the model’s full window instead, unset `CLAUDE_CODE_DISABLE_1M_CONTEXT`; the warning reports only that the 200K limit isn’t enforced

In [non-interactive mode](headless.md) with text output, this warning appears on stderr. In an interactive session, a [background session](../09-Agents-Patterns/agent-view.md), or with `--output-format json` or `stream-json`, it goes to the debug log instead. Run with `--debug` to capture it at `~/.claude/debug/<session-id>.txt`. Before v2.1.305, an interactive session printed the warning on stderr at startup.


[​](#unrecognized-model-id-on-a-request)

Unrecognized model ID on a request

Claude Code sent a request for a model ID that your Claude Code version doesn’t recognize, and found no [`modelOverrides`](model-config.md#override-model-ids-per-version) entry that maps that ID to a model it does recognize. Claude Code still sends the request with the ID as you configured it, and doesn’t exit or switch models.

```python
[claude-code:unrecognized_model] {"model":"my-proxy-model","query_source":"sdk"}
```

In a script or harness that reads stderr, match on the `[claude-code:unrecognized_model]` prefix. After the prefix and one space, Claude Code writes a one-line JSON object. Claude Code can add fields to it in a later version, so ignore any field you don’t expect. It writes at least these two:

- `model`: the model string as you configured it
- `query_source`: the request path that used the model. Claude Code reports `sdk` for a `-p` run and a value that starts with `agent:` for a subagent.

Claude Code writes the line to one of two places, depending on how you run it:

- In [non-interactive mode](headless.md) with `-p`, Claude Code writes it to stderr under every `--output-format`, so you can parse stdout without filtering the line out
- In an interactive session or a [background session](../09-Agents-Patterns/agent-view.md), Claude Code writes it to the debug log instead; run with `--debug` to capture it at `~/.claude/debug/<session-id>.txt`

Claude Code writes the line once per model string per process. It writes a separate line for each further unrecognized ID, such as one that a [subagent](../09-Agents-Patterns/sub-agents.md#choose-a-model) or [background functionality](../17-Billing-Plans/costs.md#background-token-usage) uses. Claude Code doesn’t write the line for provider IDs it resolves to a model it recognizes, such as Amazon Bedrock `us.anthropic.claude-...` IDs, Google Cloud’s Agent Platform IDs with an `@` version suffix, and Microsoft Foundry deployment names that contain a Claude model ID. Claude Code checks the model behind an Amazon Bedrock [application inference profile ARN](amazon-bedrock.md#map-each-model-version-to-an-inference-profile) rather than the ARN itself. It writes no line for an ARN it can’t resolve, such as a mistyped one. **What to do:**

- If you set the ID on purpose, such as an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) alias, add a [`modelOverrides`](model-config.md#override-model-ids-per-version) entry to your [settings file](settings.md#where-settings-live) with the ID as its value. Use an Anthropic model ID as the key, not a family alias such as `opus`. For `my-proxy-model` from the example line, add this entry:

  ``` shiki
  {
    "modelOverrides": {
      "claude-opus-4-6": "my-proxy-model"
    }
  }
  ```

  Claude Code then treats `my-proxy-model` as `claude-opus-4-6` and stops writing the line.
- If the ID names a model newer than your Claude Code version, run `claude update`
- If the ID is a typo, fix it in whichever of the [places you can set a model](model-config.md#setting-your-model) or [alias variables](model-config.md#environment-variables) holds it. If `query_source` starts with `agent:`, fix it where you set the [subagent’s model](../09-Agents-Patterns/sub-agents.md#choose-a-model) instead.

Before v2.1.233, Claude Code wrote no line when it sent a request for a model ID it didn’t recognize.


[​](#sandbox-allow-entries-are-ignored-under-a-managed-lock)

Sandbox allow entries are ignored under a managed lock

This warning in `/status` and `claude doctor` means managed settings set [`allowManagedReadPathsOnly`](settings-reference.md#sandbox-filesystem-allowmanagedreadpathsonly) or [`allowManagedDomainsOnly`](settings-reference.md#sandbox-network-allowmanageddomainsonly), so the [`allowRead`](settings-reference.md#sandbox-filesystem-allowread) or [`allowedDomains`](settings-reference.md#sandbox-network-alloweddomains) entries in the file it names don’t apply:

```python
sandbox.filesystem.allowRead is ignored — managed settings set allowManagedReadPathsOnly, so only allowRead paths from managed settings are honored. The 3 entries in /home/you/.claude/settings.json will NOT apply (see https://code.claude.com/docs/en/settings#sandbox-settings).
```

For the network lock, the warning names `sandbox.network.allowedDomains` and `allowManagedDomainsOnly`, and says `only allowed domains (and WebFetch domain rules) from managed settings are honored`. **What to do:**

- You don’t have to act on the warning
- If you need those paths or domains and your organization’s managed settings set the lock, ask your administrator to add them to those settings. The warning stays until you also remove the entries from the named file.
- To clear the warning, remove the entries from the named file. For a file you share, such as a project’s `.claude/settings.json`, you can leave the entries in for teammates without the lock and leave the warning showing.


[​](#stale-sandbox-mask-files-left-by-a-killed-session)

Sandbox mask files left behind at write-deny paths

This warning in `claude doctor` and `/status` lists mask files: 0-byte read-only placeholder files at paths the [sandbox](sandboxing.md) denies writes to. It appears on Linux and WSL2 when sandboxing is enabled with filesystem isolation on. Delete them from your shell once no Claude Code session is open in the project that holds them. The sandbox creates a placeholder while a sandboxed command runs and removes it when the command ends. One stays behind in cases such as these:

- The session is killed before the command ends, for example by SIGKILL
- You quit the session while a sandboxed command is still running, such as one in the background

In `claude doctor`, the warning reads:

```python
- Sandbox mask files left behind at write-deny paths: /home/you/project/.claude/settings.local.json
  Fix: A session leaves one where it was killed, or where it exited while a sandboxed command was still running. Remove each with `rm <path>` while no other Claude Code session is running in that project — a 0-byte read-only file where a settings file belongs makes "Yes, and don't ask again" fail to save, and the sandbox binds it read-only again on every start
```

**What to do:**

- Quit every Claude Code session open in the project that holds the listed files, including any session where `/status` showed the warning, then work from your shell. A placeholder that another session’s sandbox is still using is a live part of that session’s write protection
- In your shell, delete each listed file with `rm`, and confirm if `rm` asks about a write-protected file. The warning names up to three files and counts the rest, so run `claude doctor` again after deleting until the warning no longer appears
- If a permission choice you saved with “Yes, and don’t ask again” didn’t stick, save it again after deleting the placeholder

Before v2.1.309, the warning read `Stale sandbox mask files left by a killed session`. Before v2.1.257, `claude doctor` didn’t flag these files; earlier versions leave the same placeholders behind when a session is killed.


[​](#responses-seem-lower-quality-than-usual)

Responses seem lower quality than usual

If Claude’s answers seem less capable than you expect but no error is shown, the cause is usually conversation state rather than the model itself. Claude Code doesn’t silently change model versions. It can switch to a fallback model in these cases:

- A configured [`--fallback-model`](cli-reference.md#cli-flags) takes over after an availability error, for that turn only, with a notice in the transcript
- An Amazon Bedrock or Google Cloud’s Agent Platform startup check finds your default model unavailable, or your account [loses access to it mid-session](amazon-bedrock.md#when-a-model-is-disabled-mid-session)
- [Automatic model fallback](model-config.md#automatic-model-fallback) on Fable 5.1, Fable 5, Opus 5.5, Sonnet 5.5, and Opus 5 moves the session to the flagged category’s fallback model, when that category has one, and shows a notice in the transcript

The Model selection check below catches the second and third cases; the first appears as a transcript notice rather than a `/model` change. [Model configuration](model-config.md) explains when each fallback applies. Check these first:

- **Model selection**: run `/model` to confirm you are on the model you expect. A previous `/model` choice or an `ANTHROPIC_MODEL` environment variable may have you on a smaller model than you intended.
- **Effort level**: run `/effort` to check the current reasoning level and raise it for hard debugging or design work. Defaults vary by model, so check before assuming you are below the maximum. See [Adjust effort level](model-config.md#adjust-effort-level) for per-model defaults and the `ultrathink` shortcut.
- **Context pressure**: run `/context` to see how full the window is. If it is near capacity, run `/compact` at a natural breakpoint or `/clear` to start fresh. See [Explore the context window](context-window.md) for how auto-compact affects earlier turns.
- **Stale instructions**: large or outdated `CLAUDE.md` files and MCP tool definitions consume context and can steer responses. The `/doctor` checkup flags oversized memory files and unused extensions, and `/context` shows MCP tool token usage. Before v2.1.205, `/doctor` opened a diagnostics screen that flagged oversized memory files and subagent definitions.

When a response goes wrong, rewinding usually works better than replying with corrections. Press Esc twice or run `/rewind` to step back to before the bad turn, then rephrase the prompt with more specifics. Correcting in-thread keeps the wrong attempt in context, which can anchor later answers to it. See [Checkpointing](checkpointing.md). If quality still seems off after checking the above, run `/feedback` and describe what you expected versus what you got. Feedback submitted this way includes the conversation transcript, which is the fastest way for Anthropic to diagnose a real regression. See [Report an error](#report-an-error) if `/feedback` is unavailable in your environment. If Claude warns about a suspected prompt injection, or refuses a request because of a suspected injection, and the text the warning names is context Claude Code adds to the conversation automatically rather than file or web content, run `claude update` and retry. If the warning repeats after updating, [report it](#report-an-error) rather than pasting the flagged content back into the prompt. Before v2.1.201, Sonnet 5 refused some requests the same way.


[​](#report-an-error)

Report an error

For errors from components this page doesn’t cover, see the relevant guide:

- MCP server failed to connect or authenticate: [MCP](../06-MCP-Tools/General/mcp.md)
- Hook script failed or blocked a tool: [Debug hooks](../07-Hooks/hooks.md#debug-hooks)
- Permission denied or filesystem errors during install: [Troubleshoot installation and login](troubleshoot-install.md)

If an error is not listed here or the suggested fix does not help:

- Run `/feedback` inside Claude Code to send the transcript and a description to Anthropic. The command also offers to open a prefilled GitHub issue. Sending to Anthropic requires [authentication](authentication.md). On Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and other third-party providers, or when no Anthropic credentials are configured, `/feedback` saves a local archive you can send to your Anthropic account representative instead.
- If `/feedback` answers that it’s disabled by your organization’s policy, see [that message’s entry](#feedback-is-disabled-by-your-organizations-policy)
- Run `claude doctor` from your shell for a read-only diagnostic of your installation, or run the `/doctor` checkup inside Claude Code to find and fix setup problems
- Check [status.claude.com](https://status.claude.com) for active incidents
- Search [existing issues](https://github.com/anthropics/claude-code/issues) on GitHub

---

## Speed up responses with fast mode - Claude Code Docs

Source: https://code.claude.com/docs/en/fast-mode
Path: 02-Claude-Code-CLI/fast-mode.md

## On this page

- [Toggle fast mode](#toggle-fast-mode)
  - [Switch models while fast mode is on](#switch-models-while-fast-mode-is-on)
  - [Use fast mode in cloud sessions](#use-fast-mode-in-cloud-sessions)
- [Understand the cost tradeoff](#understand-the-cost-tradeoff)
  - [See where fast mode spend appears](#see-where-fast-mode-spend-appears)
- [Decide when to use fast mode](#decide-when-to-use-fast-mode)
  - [Fast mode vs effort level](#fast-mode-vs-effort-level)
- [Requirements](#requirements)
  - [Enable fast mode for your organization](#enable-fast-mode-for-your-organization)
  - [Use fast mode behind proxies and LLM gateways](#use-fast-mode-behind-proxies-and-llm-gateways)
  - [Require per-session opt-in](#require-per-session-opt-in)
- [Handle rate limits](#handle-rate-limits)
- [Research preview](#research-preview)
- [See also](#see-also)

Model and responses

# Speed up responses with fast mode

Copy pageCopy page

Get faster Opus responses in Claude Code by toggling fast mode.

Copy pageCopy page

Fast mode is in [research preview](#research-preview). The feature, pricing, and availability may change based on feedback.

Fast mode is a high-speed configuration for Claude Opus, making the model up to 2.5x faster at a higher cost per token. Toggle it on with `/fast` when you need speed for interactive work like rapid iteration or live debugging, and toggle it off when cost matters more than latency. Fast mode is not a different model. It uses Claude Opus with a different API configuration that prioritizes speed over cost efficiency. You get identical quality and capabilities with faster responses. Fast mode is supported on Opus 5.5, Opus 5, and Opus 4.8. It is not available on Sonnet, Haiku, or other models. Opus 4.7 doesn’t support fast mode, so switching to it turns fast mode off. Fast mode for Opus 4.7 was deprecated on June 25, 2026, and removed on July 24, 2026. What to know:

- Use `/fast` to toggle on fast mode in the Claude Code CLI. The [VS Code extension](../03-IDE-Integrations/vs-code.md) offers a **Toggle fast mode** command when the selected model supports fast mode. Claude Code saves that toggle to your [`fastMode` setting](#toggle-fast-mode).
- Fast mode pricing per MTok input/output is \$8/\$40 on Opus 5.5 and \$10/\$50 on Opus 5 and Opus 4.8.
- Available to Claude Code users on subscription plans (Pro/Max/Team/Enterprise) and on Claude Console. Team and Enterprise organizations need an Owner to enable it first, and Console organizations need access provisioned first, both described under [Requirements](#requirements).
- For Claude Code users on subscription plans (Pro/Max/Team/Enterprise), fast mode is available via usage credits only and not included in the subscription rate limits.


[​](#toggle-fast-mode)

Toggle fast mode

In the CLI, toggle fast mode in either of these ways:

- Run `/fast`, press Space to toggle on or off, then press Enter to confirm
- Set `"fastMode": true` in your [user settings file](settings.md)

By default, fast mode you turn on in an interactive session persists across sessions. You can configure fast mode to reset each session. See [require per-session opt-in](#require-per-session-opt-in) for details. Outside a [cloud session](#use-fast-mode-in-cloud-sessions), in [non-interactive mode](headless.md) with the `-p` flag, `/fast` works only in a session launched with fast mode in its [`--settings`](cli-reference.md#cli-flags) value, for example `claude -p --settings '{"fastMode": true}'`; the toggle then applies to that session only and isn’t saved as your default. The `-p` form requires Claude Code v2.1.205 or later. Elsewhere in non-interactive mode, the command reports that fast mode isn’t available. You can run `/fast` while Claude is working, and Claude Code toggles fast mode without waiting for the turn to end. Claude Code finishes the running turn at its original speed, so the speed change takes effect from your next turn. If your current model doesn’t support fast mode, turning it on also switches your model, and Claude Code uses the new model from its next request in that turn. For the best cost efficiency, enable fast mode at the start of a session rather than switching mid-conversation. See [understand the cost tradeoff](#understand-the-cost-tradeoff) for details. When you enable fast mode:

- If your current model doesn’t support fast mode, Claude Code switches to Opus
- You’ll see a confirmation message: “Fast mode ON”
- A small `↯` icon appears next to the prompt while fast mode is active
- Run `/fast` again at any time to check whether fast mode is on or off

Opus 5.5 is the fast mode default in Claude Code v2.1.280 and later. Before v2.1.280, fast mode defaulted to Opus 5 from v2.1.219, and to Opus 4.8 on v2.1.154 through v2.1.218. When you disable fast mode with `/fast` again, you remain on Opus. To switch to a different model, use `/model`.


[​](#switch-models-while-fast-mode-is-on)

Switch models while fast mode is on

Fast mode follows your model switches in both directions:

- **Switch away**: when you switch to a model that doesn’t support fast mode, Claude Code turns fast mode off. This includes Opus 4.7; before v2.1.221, fast mode stayed on after a switch to Opus 4.7 and the API rejected the requests.
- **Switch back**: switching back to a supported Opus model turns fast mode on again when your saved fast mode preference is on, the same preference a new session starts from by default. A model switch never turns fast mode on for a session whose saved preference is off, and with [per-session opt-in](#require-per-session-opt-in) configured, switching back doesn’t turn it on either; run `/fast` to re-enable it.

Whenever a model switch turns fast mode on or off, Claude Code shows a `Fast mode ON` or `Fast mode OFF` confirmation, and the `↯` icon appears while fast mode is on. This holds whether you switch with `/model`, with [`/config model=<model>`](settings.md), or from a device connected through [Remote Control](remote-control.md). Claude Code resends the session’s fast mode status to devices connected through Remote Control after a model switch, a reconnection, or a failed [availability check](#use-fast-mode-behind-proxies-and-llm-gateways).


[​](#use-fast-mode-in-cloud-sessions)

Use fast mode in cloud sessions

Fast mode works in [cloud sessions](claude-code-on-the-web.md) when it’s available on your account, whether the session runs on Anthropic-managed infrastructure or a [self-hosted runner](../13-Enterprise-Admin/self-hosted-environments.md). Requires Claude Code v2.1.271 or later in the session’s environment. Type `/fast on` in the session to turn fast mode on. It stays on for that session only and isn’t saved as your default. The [requirements](#requirements) apply in cloud sessions too. In the browser at [claude.ai/code](https://claude.ai/code), you can also turn fast mode on and off from the model menu on the message box. The menu shows the switch when your plan includes fast mode and the selected model supports it.


[​](#understand-the-cost-tradeoff)

Understand the cost tradeoff

Fast mode has higher per-token pricing than standard Opus:

| Model    | Input (MTok) | Output (MTok) |
|----------|--------------|---------------|
| Opus 5.5 | \$8          | \$40          |
| Opus 5   | \$10         | \$50          |
| Opus 4.8 | \$10         | \$50          |

Fast mode pricing is flat across the full 1M token context window. For the standard Opus rate to compare against, see the [Claude pricing reference](../17-Billing-Plans/about-claude-pricing.md). The first time you enable fast mode in a conversation, you pay the full fast mode uncached input token price for the entire conversation context. The deeper into a conversation you are, the more this costs, so the charge is smallest when you enable fast mode at the start. The cost applies once per conversation, so toggling fast mode off and on again later doesn’t repeat it. For the mechanism, see [how fast mode interacts with the prompt cache](prompt-caching.md#turning-on-fast-mode).


[​](#see-where-fast-mode-spend-appears)

See where fast mode spend appears

You see fast mode spend in a different place depending on how you signed in, so first run [`/status`](commands.md) to check. If it shows a `Login method` row such as `Claude Max account`, you signed in with a Claude subscription. If it shows an `API key` row instead, your requests bill to a Claude Console organization.

- **Pro and Max**: you pay for fast mode from your usage credits. Go to [**Settings \> Usage**](https://claude.ai/settings/usage) on claude.ai, where the **Usage credits** section shows how much you’ve spent in usage credits this month. That figure includes fast mode but doesn’t break it out separately.
- **Team and Enterprise**: your organization pays for your fast mode usage from its usage credits. To see your own usage-credits spend, run [`/usage`](../17-Billing-Plans/costs.md#check-your-usage-credits-spend). For where your organization sees that spend, see [Claude for Teams and Enterprise](../17-Billing-Plans/costs.md#claude-for-teams-and-enterprise).
- **Claude Console**: your organization pays for fast mode with the rest of its API usage. On the Console [Usage](../04-API-Reference/Other/playground.md) and [Cost](../04-API-Reference/Other/playground.md) pages, select **Speed (Research Preview)** in the **Group by** menu to separate fast mode from standard-speed usage. You see that option only when the selected date range includes fast mode usage.


[​](#decide-when-to-use-fast-mode)

Decide when to use fast mode

Fast mode is best for interactive work where response latency matters more than cost:

- Rapid iteration on code changes
- Live debugging sessions
- Time-sensitive work with tight deadlines

Standard mode is better for:

- Long autonomous tasks where speed matters less
- Batch processing or CI/CD pipelines
- Cost-sensitive workloads


[​](#fast-mode-vs-effort-level)

Fast mode vs effort level

Fast mode and effort level both affect response speed, but differently:

| Setting                | Effect                                                                           |
|------------------------|----------------------------------------------------------------------------------|
| **Fast mode**          | Same model quality, lower latency, higher cost                                   |
| **Lower effort level** | Less thinking time, faster responses, potentially lower quality on complex tasks |

You can combine both: use fast mode with a lower [effort level](model-config.md#adjust-effort-level) for maximum speed on straightforward tasks.


[​](#requirements)

Requirements

Fast mode requires all of the following:

- **Anthropic API or subscription only**: fast mode is available through the Anthropic Console API and for Claude subscription plans using usage credits. It is not available on Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, or Claude Platform on AWS. Console organizations must also have [fast mode access provisioned](#enable-fast-mode-for-your-organization).
- **Usage credits turned on for subscription plans**: on a Pro, Max, Team, or Enterprise plan, your account must have [usage credits](../17-Billing-Plans/costs.md#add-usage-credits-to-your-subscription) turned on, which allows billing beyond your plan’s included usage. Until they’re on, `/fast` reports “Fast mode requires usage credits”. How you turn them on depends on your plan:
  - On Pro and Max, turn them on in the **Usage credits** section of [**Settings \> Usage**](https://claude.ai/settings/usage) on claude.ai, or run `/usage-credits` to open that page.
  - On Team and Enterprise, a member with billing access turns them on for the organization at [**Organization settings \> Usage**](https://claude.ai/admin-settings/usage), and a member without it runs `/usage-credits` to send the organization’s admins a request.

Fast mode usage draws directly from usage credits, even if you have remaining usage on your plan.

- **Paid Console organization**: Claude Console accounts don’t use usage credits, and your organization pays for fast mode per token with the rest of its API usage. On the Console’s free Evaluation plan, `/fast` shows “Fast mode unavailable during evaluation. Please purchase credits.” To clear it, purchase credits in your [Console billing settings](../04-API-Reference/Other/playground.md).
- **Owner enablement for Team and Enterprise**: fast mode is disabled by default for Team and Enterprise organizations. An Owner must explicitly [enable fast mode](#enable-fast-mode-for-your-organization) before users can access it.

Four organization settings can block turning fast mode on with `/fast`:

- **Fast mode not enabled**: if fast mode hasn’t been enabled for your organization, turning fast mode on with `/fast` shows “Fast mode has been disabled by your organization.”
- **Fast mode turned off by managed settings**: if your organization deploys [managed settings](../13-Enterprise-Admin/managed-settings.md) that set [`fastMode: false`](settings-reference.md#fastmode), turning fast mode on with `/fast` shows the same “Fast mode has been disabled by your organization” message.
- **Per-session opt-in required**: managed settings that set [`fastModePerSessionOptIn: true`](#require-per-session-opt-in) refuse `/fast on` with the same message everywhere except an interactive terminal session.
- **Fast-mode model not allowed**: if your organization’s [`availableModels`](model-config.md#restrict-model-selection) allowlist excludes the fast-mode Opus model, turning it on is refused with “is not in your organization’s allowed models”. In a session already running on an allowed Opus model that supports fast mode, `/fast` instead enables fast mode on your current model without switching models.


[​](#enable-fast-mode-for-your-organization)

Enable fast mode for your organization

Where you enable fast mode depends on which product your organization uses:

- **Console** (API customers): an admin enables it in [Claude Code preferences](https://platform.claude.com/claude-code/preferences). Fast mode is in [research preview](#research-preview), so your organization must also have fast mode access provisioned before fast mode requests succeed. To get access, contact your account manager or join the waitlist, as described in [fast mode on the Claude API](../04-API-Reference/Guides/build-with-claude-fast-mode.md). Without provisioned access, the API rejects each fast mode request with a 429, and Claude Code treats each rejection as a [fast mode rate limit](#handle-rate-limits). Unlike a rate limit’s cooldown, the rejections continue until access is provisioned.
- **Claude AI** (Team and Enterprise): an Owner enables it at [**Organization settings \> Claude Code**](https://claude.ai/admin-settings/claude-code)

Another option to disable fast mode entirely is to set `CLAUDE_CODE_DISABLE_FAST_MODE=1`. See [Environment variables](env-vars.md).


[​](#use-fast-mode-behind-proxies-and-llm-gateways)

Use fast mode behind proxies and LLM gateways

Before offering fast mode, Claude Code checks your organization’s fast mode availability with a request directly to `api.anthropic.com`. The check doesn’t follow [`ANTHROPIC_BASE_URL`](../13-Enterprise-Admin/llm-gateway-connect.md#set-the-base-url-and-credential), so on a network that routes Claude traffic through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) and blocks direct egress to `api.anthropic.com`, the check fails even though inference requests work. The check does use a configured [HTTP proxy](../13-Enterprise-Admin/network-config.md#proxy-configuration), so a network block fails the check only where `api.anthropic.com` is unreachable even through the proxy. When the check fails, `/fast` reports “Fast mode unavailable due to network connectivity issues”, and requests run at standard speed, even when your organization has fast mode enabled. A check that succeeded in the past keeps working from its cached result, so a blocked check mostly affects new installations. The same connectivity message appears on an open network when the check reaches `api.anthropic.com` but presents a credential Anthropic rejects. A session whose resolved key is a gateway-issued credential, held in [`ANTHROPIC_API_KEY`](../13-Enterprise-Admin/llm-gateway-connect.md#set-the-base-url-and-credential) or produced by an [`apiKeyHelper`](settings-reference.md#apikeyhelper), sends the check with that key, and the rejected request is reported as a connectivity failure. To restore fast mode, allowlist direct egress to `api.anthropic.com` where a network block is the cause, or set whichever variable matches how the check fails:

- `CLAUDE_CODE_SKIP_FAST_MODE_NETWORK_ERRORS=1` treats a failed check as available and still honors a “disabled by your organization” response. Use it when your network refuses the connection, or when Anthropic rejects a gateway credential; allowlisting doesn’t help the credential case, since nothing is blocked.
- `CLAUDE_CODE_SKIP_FAST_MODE_ORG_CHECK=1` skips the check entirely. Use it when your network intercepts the request rather than refusing it.

Two gateway configurations report “Fast mode has been disabled by your organization” rather than the connectivity message, even when your organization has fast mode enabled:

- A session that authenticates with [`ANTHROPIC_AUTH_TOKEN`](../13-Enterprise-Admin/llm-gateway-connect.md#set-the-base-url-and-credential) alone skips the check: without a claude.ai login or an Anthropic API key, and without a cached successful check, Claude Code treats fast mode as disabled by your organization without sending the request.
- A proxy that intercepts the check and answers with its own page, for example a TLS-inspecting proxy returning an HTTP 200 block page, is read as a response saying your organization has fast mode disabled.

In both cases, set `CLAUDE_CODE_SKIP_FAST_MODE_ORG_CHECK=1` to restore fast mode. `CLAUDE_CODE_SKIP_FAST_MODE_NETWORK_ERRORS` doesn’t apply to either case, since it only bypasses failed checks and both of these produce a disabled response instead. Allowlisting direct egress doesn’t help the bearer-token case, which never sends the request. The variables affect only the client-side check. When your organization has fast mode disabled, the API rejects fast mode requests whether or not they’re set. A rejection from the API stands even with a skip variable set. Claude Code retries the rejected request at standard speed, turns fast mode off, and `/fast` reports that your organization has disabled fast mode. Setting `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` also suppresses the availability check. Without a previously cached successful check, `/fast` reports “Fast mode is currently unavailable”; both skip variables restore fast mode in that configuration too.


[​](#require-per-session-opt-in)

Require per-session opt-in

By default, fast mode a user turns on in an interactive session persists across sessions. To change this, set `fastModePerSessionOptIn` to `true` in any [settings file](settings.md#where-settings-live), which causes each session to start with fast mode off and requires users to explicitly enable it with `/fast`. Owners on [Team](../17-Billing-Plans/pricing.md#team-&-enterprise) or [Enterprise](https://anthropic.com/contact-sales?utm_source=claude_code&utm_medium=docs&utm_content=fast_mode_enterprise) plans can deploy it organization-wide through [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md).

```python
{
  "fastModePerSessionOptIn": true
}
```

This is useful for controlling costs in organizations where users run multiple concurrent sessions. The user’s fast mode preference is still saved, so removing this setting restores the default persistent behavior. When managed settings set the key, `/fast on` works only in an interactive terminal session. Everywhere else, including [non-interactive mode](headless.md), the [VS Code extension](../03-IDE-Integrations/vs-code.md), and [cloud sessions](#use-fast-mode-in-cloud-sessions), it’s refused with a message that your organization has disabled fast mode.


[​](#handle-rate-limits)

Handle rate limits

Fast mode has separate rate limits from standard Opus. All supported Opus models share one fast mode rate limit pool: usage on any of them draws from the same limits. When you hit the fast mode rate limit:

1.  Fast mode automatically falls back to standard speed
2.  The `↯` icon turns gray to indicate cooldown
3.  You continue working at standard speed and pricing
4.  When the cooldown expires, fast mode automatically re-enables

To disable fast mode manually instead of waiting for cooldown, run `/fast` again. If you run out of usage credits mid-session, Claude Code retries each rejected fast mode request at standard speed and pricing, so you keep working, and there is no cooldown. How you see the rejection depends on the session type:

- In an interactive session, Claude Code shows a “Fast mode disabled · usage credits exhausted” notification and turns fast mode off for the rest of the session. Your saved fast mode preference doesn’t change; run `/fast` to turn fast mode back on.
- In [non-interactive mode](headless.md) with `--output-format stream-json`, and through the Agent SDK, Claude Code emits the same text on the message stream as a `system` message with subtype `notification`, once per turn while you’re out of usage credits. Fast mode stays on. Requires Claude Code v2.1.221 or later.


[​](#research-preview)

Research preview

Fast mode is a research preview feature. This means:

- The feature may change based on feedback
- Availability and pricing are subject to change
- The underlying API configuration may evolve

Report issues or feedback through your usual Anthropic support channels.


[​](#see-also)

See also

- [Model configuration](model-config.md): switch models and adjust effort levels
- [Manage costs effectively](../17-Billing-Plans/costs.md): track token usage and reduce costs
- [Status line configuration](statusline.md): display model and context information

---

## Feature availability - Claude Code Docs

Source: https://code.claude.com/docs/en/feature-availability
Path: 02-Claude-Code-CLI/feature-availability.md

## On this page

- [Availability by model provider](#availability-by-model-provider)
  - [Features available on every provider](#features-available-on-every-provider)
  - [Features that require a Claude subscription](#features-that-require-a-claude-subscription)
  - [CLI capabilities that vary by provider](#cli-capabilities-that-vary-by-provider)
  - [Admin and analytics](#admin-and-analytics)
  - [Summary by provider](#summary-by-provider)
- [Availability by subscription plan](#availability-by-subscription-plan)
- [Model availability](#model-availability)
- [Related resources](#related-resources)

Deployment

# Feature availability

Copy pageCopy page

Compare which Claude Code features are available across Anthropic subscription plans, the Anthropic Console, Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, and Microsoft Foundry.

Copy pageCopy page

The Claude Code CLI and everything that runs locally work on every provider. For setup instructions per provider, see the [Enterprise deployment overview](third-party-integrations.md). To skip straight to what is missing on your provider, see the [summary by provider](#summary-by-provider) tabs. In the tables below, ✓ means available, ✗ means not available, and “See note” links to a footnote for partial support. A qualifier after ✓ narrows availability to that subset, and “Admin-enabled” means the feature is off until an organization admin turns it on.


[​](#availability-by-model-provider)

Availability by model provider

How you authenticate determines which features Claude Code can reach. For a single list of what is missing on your provider, see the [summary by provider](#summary-by-provider) tabs. To find your column in the tables:

- **Claude subscription**: you sign in with a claude.ai account on the Pro, Max, Team, or Enterprise plan
- **Anthropic Console**: you authenticate with an Anthropic API key or by [signing in to a Console account without one](authentication.md#sign-in-without-an-api-key)
- **Amazon Bedrock**: you use Claude models from the Amazon Bedrock model catalog and set `CLAUDE_CODE_USE_BEDROCK`. The [Mantle endpoint](amazon-bedrock.md#use-the-mantle-endpoint) (`CLAUDE_CODE_USE_MANTLE`) is covered by this column
- **Claude Platform on AWS**: you bought Claude through AWS Marketplace but call the Anthropic API, and set `CLAUDE_CODE_USE_ANTHROPIC_AWS`
- **Google Cloud’s Agent Platform**: Google-operated; you set `CLAUDE_CODE_USE_VERTEX`
- **Microsoft Foundry**: Anthropic-operated; you set `CLAUDE_CODE_USE_FOUNDRY`


[​](#features-available-on-every-provider)

Features available on every provider

These work on every provider:

- [CLI](../01-Getting-Started/quickstart.md) and [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md)
- [VS Code](../03-IDE-Integrations/vs-code.md) and [JetBrains](../03-IDE-Integrations/jetbrains.md) extensions
- [Subagents](../09-Agents-Patterns/sub-agents.md), [hooks](../07-Hooks/hooks-guide.md), [commands](commands.md), and [skills](../08-Plugins-Skills/skills.md)
- [CLAUDE.md memory](memory.md), [plugins](../08-Plugins-Skills/plugins.md), and [MCP servers](../06-MCP-Tools/General/mcp.md)
- [Checkpoints](checkpointing.md), [sandboxing](sandboxing.md), and [Workflows](workflows.md)
- [OpenTelemetry metrics](../13-Enterprise-Admin/monitoring-usage.md) and the [managed settings file](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms)

These have provider-specific differences:

- **MCP servers**: [connectors from claude.ai](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) load only when your claude.ai subscription is the active authentication method. [Tool search](../06-MCP-Tools/General/mcp.md#configure-tool-search) isn’t supported on Microsoft Foundry [deployments hosted on Azure](../04-API-Reference/Guides/build-with-claude-claude-in-microsoft-foundry.md#hosting-options). On Google Cloud’s Agent Platform, tool search isn’t supported on models earlier than Claude Opus 4.5, Claude Sonnet 4.5, and Claude Haiku 4.5
- **Subagents**: when the main conversation runs Fable, the built-in [Explore subagent](../09-Agents-Patterns/sub-agents.md#built-in-subagents) runs on Opus with a Claude subscription, an Anthropic Console account, or an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) reached through `ANTHROPIC_BASE_URL`. On other providers, including Claude Platform on AWS, it runs on Fable
- **[Commands](commands.md#all-commands)**:
  - `/design-sync` and `/import` with its `claude import` subcommand form are unavailable on Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and Claude Platform on AWS, and through a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md#availability-and-limitations)
  - `/voice` requires a claude.ai account
  - `/list-agents` and its alias `/peers` are available only in sessions where [cross-session messaging is enabled](cross-session-messaging.md#availability)


[​](#features-that-require-a-claude-subscription)

Features that require a Claude subscription

These require signing in with a claude.ai account and are not reachable with an Anthropic Console API key or from a third-party provider:

- [Cloud sessions](claude-code-on-the-web.md) and Claude Code on mobile
- [Claude Code in Slack](../14-Connectors/slack.md): Pro and Max plans
- [Claude Code Desktop](../16-Mobile-Desktop/desktop.md)
- [Cloud scheduled tasks](web-scheduled-tasks.md) (`/schedule`)
- [Ultrareview](ultrareview.md)
- [Code Review](code-review.md): Team and Enterprise plans
- [Remote Control](remote-control.md)
- [Chrome extension](../03-IDE-Integrations/chrome.md)
- [Computer use](computer-use.md): Pro and Max plans
- [Artifacts](artifacts.md): Pro, Max, Team, and Enterprise plans
- [Voice dictation](voice-dictation.md)

Desktop is the partial exception: [gateway routing can be configured in the app or by an administrator](../13-Enterprise-Admin/llm-gateway-connect.md#desktop-app). [Claude Desktop on 3P](https://claude.com/docs/third-party/claude-desktop/overview) also runs the Code tab on Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, or a self-hosted LLM gateway. It also runs the Code tab on the [Claude API](https://claude.com/docs/third-party/claude-desktop/claude-api) with an Anthropic Console API key. For per-plan availability of these features, see [Availability by subscription plan](#availability-by-subscription-plan).


[​](#cli-capabilities-that-vary-by-provider)

CLI capabilities that vary by provider

These features work in the local CLI but depend on a server-side capability that not every provider exposes.

| Feature                                                        | Claude subscription                                                                                   | Anthropic Console             | Amazon Bedrock                | Claude Platform on AWS        | Google Cloud’s Agent Platform | Microsoft Foundry             |
|----------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|-------------------------------|-------------------------------|-------------------------------|-------------------------------|-------------------------------|
| [Web search](tools-reference.md#websearch-tool-behavior) | ✓                                                                                                     | ✓                             | ✗                             | ✓                             | See note ^([1](#fn1))         | ✓                             |
| [Fast mode](fast-mode.md)                                | ✓ ([Owner-enabled](fast-mode.md#enable-fast-mode-for-your-organization) on Team and Enterprise) | ✓ (provisioned organizations) | ✗                             | ✗                             | ✗                             | ✗                             |
| [Auto mode](auto-mode-config.md)                         | ✓                                                                                                     | ✓                             | See note ^([2](#fn2))         | ✓                             | See note ^([2](#fn2))         | See note ^([2](#fn2))         |
| [Advisor](advisor.md)                                    | ✓                                                                                                     | ✓                             | ✗                             | ✗                             | ✗                             | ✗                             |
| [Cross-session messaging](cross-session-messaging.md)    | ✓ ^([5](#fn5))                                                                                        | ✓ (same machine) ^([5](#fn5)) | ✓ (same machine) ^([5](#fn5)) | ✓ (same machine) ^([5](#fn5)) | ✓ (same machine) ^([5](#fn5)) | ✓ (same machine) ^([5](#fn5)) |
| [Channels](channels.md)                                  | ✓                                                                                                     | ✓                             | ✗                             | ✗                             | ✗                             | ✗                             |
| [GitHub Actions](github-actions.md)                      | ✓                                                                                                     | ✓                             | ✓                             | ✗                             | ✓                             | ✓                             |
| [GitLab CI/CD](gitlab-ci-cd.md)                          | ✓                                                                                                     | ✓                             | ✓                             | ✓                             | ✓                             | ✗                             |


[​](#admin-and-analytics)

Admin and analytics

Organization-level controls and usage visibility.

| Feature                                                     | Claude subscription                                 | Anthropic Console                                                                   | Amazon Bedrock        | Claude Platform on AWS | Google Cloud’s Agent Platform | Microsoft Foundry     |
|-------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------------------------------|-----------------------|------------------------|-------------------------------|-----------------------|
| [Analytics dashboard and API](../13-Enterprise-Admin/analytics.md)           | ✓ (dashboard: Team and Enterprise; API: Enterprise) | ✓ ^([4](#fn4))                                                                      | ✗                     | ✗                      | ✗                             | ✗                     |
| [Server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) | ✓ (Team and Enterprise)                             | See [Platform availability](../13-Enterprise-Admin/server-managed-settings.md#platform-availability) | ✗                     | ✗                      | ✗                             | ✗                     |
| [Zero Data Retention](zero-data-retention.md)         | ✓ (qualified Enterprise accounts)                   | ✓ (qualified accounts)                                                              | See note ^([3](#fn3)) | ✓ (qualified accounts) | See note ^([3](#fn3))         | See note ^([3](#fn3)) |

¹ On Google Cloud’s Agent Platform, web search is available for Opus 4, Sonnet 4, Haiku 4.5, and later models.  
² On these providers, auto mode supports only Claude Sonnet 5 or later, Opus 4.7 or later, Haiku 5.5, and the Fable models. See [Auto mode configuration](auto-mode-config.md). For the permission mode a session on these providers starts in, see [Which mode a session starts in](permission-modes.md#which-mode-a-session-starts-in).  
³ Subject to your agreement with the cloud provider.  
⁴ Dashboard and API only. [Contribution metrics](../13-Enterprise-Admin/analytics.md#enable-contribution-metrics) requires a claude.ai Team or Enterprise organization.  
⁵ Requires Claude Code v2.1.224 or later on macOS and Linux, including Linux inside WSL 2. On native Windows, requires Claude Code v2.1.234 or later. With API key authentication, messaging is same-machine only. On Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, and Microsoft Foundry, messaging is same-machine only and requires Claude Code v2.1.248 or later. Claude can find your [cloud sessions](claude-code-on-the-web.md) and your sessions on other machines only from a session that is connected to [Remote Control](remote-control.md). To connect, you need a claude.ai sign-in and the other [Remote Control requirements](remote-control.md#requirements). See [Message sessions on other machines](cross-session-messaging.md#message-sessions-on-other-machines).

If you authenticate through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md), feature availability matches the underlying provider the gateway forwards to, except for the features Claude Code itself turns off. Whenever `ANTHROPIC_BASE_URL` points at a host other than `api.anthropic.com`, Claude Code turns off features such as [Remote Control](remote-control.md#requirements) and [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md#platform-availability), whatever the gateway forwards. Some Anthropic-only features such as the [Advisor](advisor.md) work only if the gateway forwards requests intact to the Anthropic API.For how the requests Claude Code sends differ between an Amazon Bedrock- or Agent Platform-format gateway, an `ANTHROPIC_BASE_URL` gateway, and a Claude apps gateway sign-in, see [client behavior by connection method](../13-Enterprise-Admin/llm-gateway-protocol.md#how-the-connection-method-changes-client-behavior).


[​](#summary-by-provider)

Summary by provider

Each tab lists what is unavailable or partially supported on that provider, with alternatives where one exists. Everything not listed works the same as on a Claude subscription, apart from the [provider-specific differences](#features-available-on-every-provider) noted above. On Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and Claude Platform on AWS, error reporting and telemetry to Anthropic are off by default. See [default behaviors by API provider](../13-Enterprise-Admin/data-usage.md#default-behaviors-by-api-provider) for what traffic still reaches Anthropic and how to opt out.

- Amazon Bedrock

- Claude Platform on AWS

- Google Cloud's Agent Platform

- Microsoft Foundry

- Anthropic Console

**Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription), plus [web search](tools-reference.md#websearch-tool-behavior), [fast mode](fast-mode.md), [Advisor](advisor.md), [Channels](channels.md), the [analytics dashboard](../13-Enterprise-Admin/analytics.md), [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md), and the [`/design-sync` and `/import` commands](commands.md#all-commands).**Partial support:**

- [Desktop](../16-Mobile-Desktop/desktop.md): only via [Claude Desktop on 3P](https://claude.com/docs/third-party/claude-desktop/overview)
- [Auto mode](auto-mode-config.md): Sonnet 5 or later, Opus 4.7 or later, Haiku 5.5, and Fable models only
- [Cross-session messaging](cross-session-messaging.md): between your sessions on this machine only ^([5](#fn5))
- [Zero Data Retention](zero-data-retention.md): subject to your AWS agreement

**Alternatives:** for scheduling, use [`/loop`](scheduled-tasks.md) instead of `/schedule`. For cloud sessions, use [GitHub Actions](github-actions.md) or [GitLab CI/CD](gitlab-ci-cd.md). For web lookups, use the [WebFetch tool](tools-reference.md#webfetch-tool-behavior) with a specific URL.

**Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription), plus [fast mode](fast-mode.md), [Advisor](advisor.md), [Channels](channels.md), [GitHub Actions](github-actions.md), the [analytics dashboard](../13-Enterprise-Admin/analytics.md), [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md), and the [`/design-sync` and `/import` commands](commands.md#all-commands).**Available where Amazon Bedrock is not:** [web search](tools-reference.md#websearch-tool-behavior).**Partial support:**

- [Cross-session messaging](cross-session-messaging.md): between your sessions on this machine only ^([5](#fn5))

**Alternatives:** for scheduling, use [`/loop`](scheduled-tasks.md) instead of `/schedule`. For cloud sessions, use [GitLab CI/CD](gitlab-ci-cd.md).

**Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription), plus [fast mode](fast-mode.md), [Advisor](advisor.md), [Channels](channels.md), the [analytics dashboard](../13-Enterprise-Admin/analytics.md), [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md), and the [`/design-sync` and `/import` commands](commands.md#all-commands).**Partial support:**

- [Desktop](../16-Mobile-Desktop/desktop.md): via [managed settings](https://claude.com/docs/third-party/claude-desktop/configuration) or [Claude Desktop on 3P](https://claude.com/docs/third-party/claude-desktop/overview)
- [Web search](tools-reference.md#websearch-tool-behavior): Opus 4, Sonnet 4, Haiku 4.5, and later models
- [Auto mode](auto-mode-config.md): Sonnet 5 or later, Opus 4.7 or later, Haiku 5.5, and Fable models only
- [Cross-session messaging](cross-session-messaging.md): between your sessions on this machine only ^([5](#fn5))
- [Zero Data Retention](zero-data-retention.md): subject to your Google Cloud agreement

**Alternatives:** for scheduling, use [`/loop`](scheduled-tasks.md) instead of `/schedule`. For cloud sessions, use [GitHub Actions](github-actions.md) or [GitLab CI/CD](gitlab-ci-cd.md).

**Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription), plus [fast mode](fast-mode.md), [Advisor](advisor.md), [Channels](channels.md), [GitLab CI/CD](gitlab-ci-cd.md), the [analytics dashboard](../13-Enterprise-Admin/analytics.md), [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md), and the [`/design-sync` and `/import` commands](commands.md#all-commands).**Partial support:**

- [Desktop](../16-Mobile-Desktop/desktop.md): only via [Claude Desktop on 3P](https://claude.com/docs/third-party/claude-desktop/overview)
- [Auto mode](auto-mode-config.md): Sonnet 5 or later, Opus 4.7 or later, Haiku 5.5, and Fable models only
- [Cross-session messaging](cross-session-messaging.md): between your sessions on this machine only ^([5](#fn5))
- [Zero Data Retention](zero-data-retention.md): subject to your Azure agreement

**Alternatives:** for scheduling, use [`/loop`](scheduled-tasks.md) instead of `/schedule`. For cloud sessions, use [GitHub Actions](github-actions.md).

**Not available:** all [features that require a Claude subscription](#features-that-require-a-claude-subscription).Everything in [CLI capabilities that vary by provider](#cli-capabilities-that-vary-by-provider) is available, except that [fast mode](fast-mode.md) requires [provisioned access](fast-mode.md#enable-fast-mode-for-your-organization). [Server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) that you configure in a claude.ai Team or Enterprise organization don’t reach a session that authenticates with a Console API key. See [Platform availability](../13-Enterprise-Admin/server-managed-settings.md#platform-availability) for how to cover those sessions.**Partial support:**

- [Desktop](../16-Mobile-Desktop/desktop.md): via [Claude Desktop on 3P with the Claude API](https://claude.com/docs/third-party/claude-desktop/claude-api)


[​](#availability-by-subscription-plan)

Availability by subscription plan

If you authenticate through Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, or an Anthropic Console API key, this section does not apply to you. When you sign in with a claude.ai account, your plan determines which of the features below are available. In Enterprise organizations with the [HIPAA configuration](hipaa-setup.md) applied, some features in this table are turned off.

| Feature                                                                     | Pro | Max | Team          | Enterprise     |
|:----------------------------------------------------------------------------|:----|:----|:--------------|:---------------|
| [Cloud sessions](claude-code-on-the-web.md)                           | ✓   | ✓   | ✓             | ✓ ^([6](#fn6)) |
| [Cloud scheduled tasks](web-scheduled-tasks.md)                                  | ✓   | ✓   | ✓             | ✓              |
| [Remote Control](remote-control.md)                                   | ✓   | ✓   | Admin-enabled | Admin-enabled  |
| [Channels](channels.md)                                               | ✓   | ✓   | Admin-enabled | Admin-enabled  |
| [Computer use](computer-use.md)                                       | ✓   | ✓   | ✗             | ✗              |
| Dispatch ([Desktop](../16-Mobile-Desktop/desktop.md#sessions-from-dispatch))               | ✓   | ✓   | ✗             | ✗              |
| [Code Review](code-review.md)                                         | ✗   | ✗   | ✓             | ✓              |
| [Artifacts](artifacts.md)                                             | ✓   | ✓   | ✓             | ✓              |
| [Analytics dashboard and contribution metrics](../13-Enterprise-Admin/analytics.md)          | ✗   | ✗   | ✓             | ✓              |
| [Enterprise Analytics API](../13-Enterprise-Admin/analytics.md#access-data-programmatically) | ✗   | ✗   | ✗             | ✓              |
| [Server-managed settings](../13-Enterprise-Admin/server-managed-settings.md)                 | ✗   | ✗   | ✓             | ✓              |
| [SSO](../17-Billing-Plans/what-is-the-team-plan.md) | ✗   | ✗   | ✓             | ✓              |
| SCIM                                                                        | ✗   | ✗   | ✗             | ✓              |
| [Compliance API](../04-API-Reference/Admin/compliance.md)        | ✗   | ✗   | ✗             | ✓              |
| [Zero Data Retention](zero-data-retention.md)                         | ✗   | ✗   | ✗             | ✓ ^([7](#fn7)) |

⁶ On Enterprise, requires a premium seat or a Chat + Claude Code seat. See [Use Claude Code in the cloud](claude-code-on-the-web.md).  
⁷ Not included in the standard Enterprise plan. Requires separate enablement by Anthropic for qualified accounts. See [Zero Data Retention](zero-data-retention.md). For pricing and the full plan comparison, see [Team plans](../17-Billing-Plans/what-is-the-team-plan.md) and [Enterprise plans](../17-Billing-Plans/what-is-the-enterprise-plan.md).


[​](#model-availability)

Model availability

For which Claude models and context-window sizes are available per provider and region, see [Model configuration](model-config.md) and the [Models overview](../20-Models/about-claude-models-overview.md). Vision, PDF input, and extended thinking are model capabilities rather than Claude Code features and work on every provider that offers the model. [Prompt caching](prompt-caching.md) works the same way on most providers; on Amazon Bedrock, support varies by model.


[​](#related-resources)

Related resources

- [Enterprise deployment overview](third-party-integrations.md): compare authentication, billing, and regions across providers
- Provider setup guides: [Amazon Bedrock](amazon-bedrock.md), [Claude Platform on AWS](claude-platform-on-aws.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), [Microsoft Foundry](microsoft-foundry.md)
- [Platforms and integrations](platforms.md): where Claude Code runs, including the CLI, Desktop, IDE extensions, web, mobile, and CI/CD

---

## Extend Claude Code - Claude Code Docs

Source: https://code.claude.com/docs/en/features-overview
Path: 02-Claude-Code-CLI/features-overview.md

## On this page

- [Overview](#overview)
- [Match features to your goal](#match-features-to-your-goal)
  - [Build your setup over time](#build-your-setup-over-time)
  - [Compare similar features](#compare-similar-features)
  - [Understand how features layer](#understand-how-features-layer)
  - [Combine features](#combine-features)
- [Understand context costs](#understand-context-costs)
  - [Context cost by feature](#context-cost-by-feature)
  - [Understand how features load](#understand-how-features-load)
- [Learn more](#learn-more)

Core concepts

# Extend Claude Code

Copy pageCopy page

Understand when to use CLAUDE.md, Skills, subagents, hooks, MCP, and plugins.

Copy pageCopy page

Claude Code combines a model that reasons about your code with [built-in tools](how-claude-code-works.md#tools) for file operations, search, execution, and web access. The built-in tools cover most coding tasks. This guide covers the extension layer: features you add to customize what Claude knows, connect it to external services, and automate workflows.

For how the core agentic loop works, see [How Claude Code works](how-claude-code-works.md).

**New to Claude Code?** Start with [CLAUDE.md](memory.md) for project conventions, then add other extensions [as specific triggers come up](#build-your-setup-over-time).


[​](#overview)

Overview

Extensions plug into different parts of the agentic loop:

- **[CLAUDE.md](memory.md)** adds persistent context Claude sees every session
- **[Output styles](output-styles.md)** set Claude’s role, tone, and response format for every response in a session
- **[Skills](../08-Plugins-Skills/skills.md)** add reusable knowledge and invocable workflows
- **[Code intelligence](tools-reference.md#lsp-tool-behavior)** connects Claude to a language server for symbol-level navigation and live type errors
- **[MCP](../06-MCP-Tools/General/mcp.md)** connects Claude to external services and tools
- **[Subagents](../09-Agents-Patterns/sub-agents.md)** run their own loops in isolated context, returning summaries
- **[Dynamic workflows](workflows.md)** run many subagents from a script Claude writes, returning one result
- **[Cross-session messaging](cross-session-messaging.md)** lets Claude pass a message from one of your sessions to another
- **[Hooks](../07-Hooks/hooks-guide.md)** run your script, HTTP request, MCP tool call, prompt, or subagent when Claude Code reaches a lifecycle event
- **[Plugins](../08-Plugins-Skills/plugins.md)** and **[marketplaces](../08-Plugins-Skills/plugins.md)** package and distribute these features

[Skills](../08-Plugins-Skills/skills.md) are the most flexible extension. A skill is a markdown file containing knowledge, workflows, or instructions. You can invoke skills with a command like `/deploy`, or Claude can load them automatically when relevant. Skills can run in your current conversation or in an isolated context via subagents.


[​](#match-features-to-your-goal)

Match features to your goal

Features range from always-on context that Claude sees every session, to on-demand capabilities you or Claude can invoke, to background automation that runs on specific events. The table below shows what’s available and when each one makes sense.

| Feature                                                             | What it does                                                                       | When to use it                                                                                                       | Example                                                                                                           |
|---------------------------------------------------------------------|------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|
| **CLAUDE.md**                                                       | Persistent context loaded every conversation                                       | Project conventions, “always do X” rules                                                                             | ”Use pnpm, not npm. Run tests before committing.”                                                                 |
| **[Output style](output-styles.md)**                          | Instructions that set Claude’s role, tone, and response format for a whole session | A voice, length, or format you want in every response, or Claude working as something other than a software engineer | The built-in Concise style for shorter responses; a custom style that answers every question with a diagram first |
| **Skill**                                                           | Instructions, knowledge, and workflows Claude can use                              | Reusable content, reference docs, repeatable tasks                                                                   | `/deploy` runs your deployment checklist; API docs skill with endpoint patterns                                   |
| **Subagent**                                                        | Isolated execution context that returns summarized results                         | Context isolation, parallel tasks, specialized workers                                                               | Research task that reads many files but returns only key findings                                                 |
| **[Dynamic workflow](workflows.md)**                          | Script Claude writes that runs many subagents in the background                    | Work that outgrows a handful of subagents, or findings you want cross-checked                                        | Audit a whole codebase, with a second set of agents verifying each finding                                        |
| **[Cross-session messaging](cross-session-messaging.md)**     | Claude delivers a message from one of your sessions to another                     | Sessions you run yourself that need each other’s findings mid-task                                                   | One session warns another that a change it made breaks what the other is building on                              |
| **[Code intelligence](tools-reference.md#lsp-tool-behavior)** | Language-server navigation and diagnostics                                         | Typed languages, large codebases where grep is slow or imprecise                                                     | Jump to a symbol’s definition instead of reading the whole file                                                   |
| **MCP**                                                             | Connect to external services                                                       | External data or actions                                                                                             | Query your database, post to Slack, control a browser                                                             |
| **Hook**                                                            | Script, HTTP request, MCP tool call, prompt, or subagent triggered by events       | Automation that must run on every matching event                                                                     | Run ESLint after every file edit                                                                                  |
| **[Artifact](artifacts.md)**                                  | Publish session output as a private, interactive web page                          | Output you want to see or share visually rather than as terminal text                                                | An incident timeline that updates as Claude investigates                                                          |

**[Plugins](../08-Plugins-Skills/plugins.md)** are the packaging layer. A plugin bundles skills, hooks, subagents, and MCP servers into a single installable unit. Plugin skills are namespaced (like `/my-plugin:review`) so multiple plugins can coexist. Use plugins when you want to reuse the same setup across multiple repositories or distribute to others via a **[marketplace](../08-Plugins-Skills/plugins.md)**.


[​](#build-your-setup-over-time)

Build your setup over time

You don’t need to configure everything up front. Each feature has a recognizable trigger, and most teams add them in roughly this order:

| Trigger                                                                          | Add                                                                                        |
|:---------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------|
| Claude gets a convention or command wrong twice                                  | Add it to [CLAUDE.md](memory.md)                                                     |
| You keep asking Claude to be shorter, explain more, or answer in the same format | Set an [output style](output-styles.md)                                              |
| You keep typing the same prompt to start a task                                  | Save it as a user-invocable [skill](../08-Plugins-Skills/skills.md)                                       |
| You paste the same playbook or multi-step procedure into chat for the third time | Capture it as a [skill](../08-Plugins-Skills/skills.md)                                                   |
| You keep copying data from a browser tab Claude can’t see                        | Connect that system as an [MCP server](../06-MCP-Tools/General/mcp.md)                                       |
| Claude reads many files to find where a symbol is defined or used                | Install a [code intelligence plugin](../08-Plugins-Skills/plugins-code-intelligence.md) for your language |
| A side task floods your conversation with output you won’t reference again       | Route it through a [subagent](../09-Agents-Patterns/sub-agents.md)                                         |
| You want something to happen every time without asking                           | Write a [hook](../07-Hooks/hooks-guide.md)                                                       |
| A second repository needs the same setup                                         | Package it as a [plugin](../08-Plugins-Skills/plugins.md)                                        |

The same triggers tell you when to update what you already have. A repeated mistake or a recurring review comment is a CLAUDE.md edit, not a one-off correction in chat. A workflow you keep tweaking by hand is a skill that needs another revision.


[​](#compare-similar-features)

Compare similar features

Some features can seem similar. For a deeper walkthrough of choosing between them, see [Steering Claude Code: when to use CLAUDE.md, skills, hooks, and subagents](https://claude.com/blog/steering-claude-code-skills-hooks-rules-subagents-and-more) on the blog. Here’s how to tell them apart.

- Skill vs Subagent

- CLAUDE.md vs Skill

- CLAUDE.md vs Output style

- CLAUDE.md vs Rules vs Skills

- Subagent vs Dynamic workflow

- MCP vs Skill

- Hook vs Skill

Skills and subagents solve different problems:

- **Skills** are reusable content you can load into any context
- **Subagents** are isolated workers that run separately from your main conversation

| Aspect                                               | Skill                                          | Subagent                                                         |
|------------------------------------------------------|------------------------------------------------|------------------------------------------------------------------|
| **What it is**                                       | Reusable instructions, knowledge, or workflows | Isolated worker with its own context                             |
| **Key benefit**                                      | Share content across contexts                  | Context isolation. Work happens separately, only summary returns |
| **[Context window](context-window.md) impact** | Adds to your main window                       | Uses a separate window with its own input and output tokens      |
| **Best for**                                         | Reference material, invocable workflows        | Tasks that read many files, parallel work, specialized workers   |

**Skills can be reference or action.** Reference skills provide knowledge Claude uses throughout your session (like your API style guide). Action skills tell Claude to do something specific (like `/deploy` that runs your deployment workflow).**Use a subagent** when you need context isolation or when your context window is getting full. The subagent might read dozens of files or run extensive searches, but your main conversation only receives a summary. Since subagent work doesn’t consume your main context, this is also useful when you don’t need the intermediate work to remain visible. Custom subagents can have their own instructions and can preload skills.**They can combine.** A subagent can preload specific skills (`skills:` field). A skill can run in isolated context using `context: fork`. See [Skills](../08-Plugins-Skills/skills.md) for details.

Both store instructions, but they load differently and serve different purposes.

| Aspect                    | CLAUDE.md                    | Skill                                   |
|---------------------------|------------------------------|-----------------------------------------|
| **Loads**                 | Every session, automatically | On demand                               |
| **Can include files**     | Yes, with `@path` imports    | Yes, with `@path` imports               |
| **Can trigger workflows** | No                           | Yes, with `/<name>`                     |
| **Best for**              | ”Always do X” rules          | Reference material, invocable workflows |

**Put it in CLAUDE.md** if Claude should always know it: coding conventions, build commands, project structure, “never do X” rules.**Put it in a skill** if it’s reference material Claude needs sometimes (API docs, style guides) or a workflow you trigger with `/<name>` (deploy, review, release).**Rule of thumb:** Keep CLAUDE.md under 200 lines. If it’s growing, move reference content to skills or split into [`.claude/rules/`](memory.md#organize-rules-with-claude/rules/) files.

Both give Claude standing instructions. CLAUDE.md carries what Claude should know, and an output style sets how Claude responds.

| Aspect        | CLAUDE.md                                       | Output style                                                                                             |
|---------------|-------------------------------------------------|----------------------------------------------------------------------------------------------------------|
| **Holds**     | Facts and rules about your project              | A role, tone, and response format                                                                        |
| **Switching** | Always loaded                                   | One active at a time; [switch styles](output-styles.md#change-your-output-style) whenever you want |
| **Best for**  | Build commands, conventions, “never do X” rules | Shorter responses, explanations alongside code, a non-engineering role                                   |

**Put it in CLAUDE.md** if it’s true of the project whatever style you’re in: coding conventions, build commands, project structure.**Use an output style** if it’s about the response itself and you might want it off again: length, format, how much Claude explains, or a different role such as a writing assistant. Claude Code includes [built-in styles](output-styles.md#built-in-output-styles), and you can write your own.**They combine.** CLAUDE.md stays loaded whichever style you pick. Claude follows both as instructions, so neither is enforced. For anything that has to happen every time, use a [hook](../07-Hooks/hooks-guide.md).

All three store instructions, but they load differently:

| Aspect       | CLAUDE.md                           | `.claude/rules/`                                   | Skill                                    |
|--------------|-------------------------------------|----------------------------------------------------|------------------------------------------|
| **Loads**    | Every session                       | Every session, or when matching files are opened   | On demand, when invoked or relevant      |
| **Scope**    | Whole project                       | Can be scoped to file paths                        | Task-specific                            |
| **Best for** | Core conventions and build commands | Language-specific or directory-specific guidelines | Reference material, repeatable workflows |

**Use CLAUDE.md** for instructions every session needs: build commands, test conventions, project architecture.**Use rules** to keep CLAUDE.md focused. Rules with [`paths` frontmatter](memory.md#path-specific-rules) only load when Claude works with matching files, saving context.**Use skills** for content Claude only needs sometimes, like API documentation or a deployment checklist you trigger with `/<name>`.

Both do work outside your main conversation. With subagents, Claude decides turn by turn what runs next. In a workflow, the script decides:

- **Subagents** are workers Claude spawns, each returning a summary to the conversation that spawned it
- **[Dynamic workflows](workflows.md)** are scripts Claude writes that run many subagents in the background and return one result

**Use a subagent** when you need a quick, focused worker: research a question, verify a claim, review a file. The subagent does the work and returns a summary, so your main conversation stays clean. Subagents that Claude [named](../09-Agents-Patterns/sub-agents.md#subagent-names) when it spawned them can also [message each other](../09-Agents-Patterns/sub-agents.md#what-loads-at-startup).**Use a dynamic workflow** when a job [outgrows a handful of subagents](workflows.md#when-to-use-a-workflow), or when you want the findings cross-checked before you see them, such as a codebase-wide audit, a large migration, or a plan drafted from several angles. To start one, [ask for a workflow in your prompt](workflows.md#ask-for-a-workflow-in-your-prompt).**To pass a finding from one of your sessions to another**, ask the first session’s Claude to send it. Claude delivers it with [cross-session messaging](cross-session-messaging.md). [Run agents in parallel](../09-Agents-Patterns/agents.md) compares the other ways to run more than one Claude at once, including sessions you hand off and check back on later.

MCP connects Claude to external services. Skills extend what Claude knows, including how to use those services effectively.

| Aspect         | MCP                                                  | Skill                                                   |
|----------------|------------------------------------------------------|---------------------------------------------------------|
| **What it is** | Protocol for connecting to external services         | Knowledge, workflows, and reference material            |
| **Provides**   | Tools and data access                                | Knowledge, workflows, reference material                |
| **Examples**   | Slack integration, database queries, browser control | Code review checklist, deploy workflow, API style guide |

These solve different problems and work well together:**MCP** gives Claude purpose-built tools for an external system, with the connection and authentication handled by the server.**Skills** give Claude knowledge about how to use those tools effectively, plus workflows you can trigger with `/<name>`. A skill might include your team’s database schema and query patterns, or a `/post-to-slack` workflow with your team’s message formatting rules.

Claude Code runs a hook at a lifecycle event; it loads a skill into context for Claude to apply.

| Aspect           | Hook                                                                                   | Skill                                                                 |
|------------------|----------------------------------------------------------------------------------------|-----------------------------------------------------------------------|
| **Runs**         | A shell command, HTTP request, MCP tool call, LLM prompt, or subagent                  | Instructions Claude reads and follows                                 |
| **Triggered by** | [Lifecycle events](../07-Hooks/hooks.md#hook-events) such as `PostToolUse` or `SessionStart` | You typing `/<name>`, or Claude matching the description to your task |
| **Determinism**  | Fires on its event without Claude deciding                                             | Claude interprets the instructions; outcome can vary                  |
| **Context cost** | Zero unless the hook returns output                                                    | Description loads each session; full content loads when used          |
| **Best for**     | Linting after edits, blocking unsafe commands, logging, notifications                  | Workflows that need reasoning, reference material, multi-step tasks   |

**Use a hook** when the action must happen the same way every time and doesn’t need Claude to think. For example: format on save, reject `rm -rf /`, post a Slack message when a session ends.**Use a skill** when Claude should decide how to apply the steps, or when the content is knowledge rather than a script. For example: a `/release` checklist, your API style guide, a debugging playbook.**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.**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.


[​](#understand-how-features-layer)

Understand how features layer

Features can be defined at multiple levels: user-wide, per-project, via plugins, or through managed policies. You can also nest CLAUDE.md files in subdirectories or place skills in specific packages of a monorepo. When the same feature exists at multiple levels, here’s how they layer:

- **CLAUDE.md files** are additive: all levels contribute content to Claude’s context simultaneously. Files from your working directory and above load at launch; subdirectories load as you work in them. When instructions conflict, Claude uses judgment to reconcile them. See [how CLAUDE.md files load](memory.md#how-claude-md-files-load).
- **Skills and subagents** override by name: when the same name exists at multiple levels, one definition wins based on priority (managed \> user \> project for skills; managed \> CLI flag \> project \> user \> plugin for subagents). Plugin skills are [namespaced](../08-Plugins-Skills/plugins-components.md#skills) to avoid conflicts. See [skill discovery](../08-Plugins-Skills/skills.md#resolve-skills-that-share-a-name) and [subagent scope](../09-Agents-Patterns/sub-agents.md#choose-the-subagent-scope).
- **MCP servers** override by name: local \> project \> user. See [MCP scope](../06-MCP-Tools/General/mcp.md#scope-hierarchy-and-precedence).
- **Hooks** merge: all registered hooks fire for their matching events regardless of source. See [hooks](../07-Hooks/hooks.md).


[​](#combine-features)

Combine features

Each extension solves a different problem: CLAUDE.md handles always-on context, skills handle on-demand knowledge and workflows, MCP handles external connections, subagents handle isolation, and hooks handle automation. Real setups combine them based on your workflow. For example, you might use CLAUDE.md for project conventions, a skill for your deployment workflow, MCP to connect to your database, and a hook to run linting after every edit. Each feature handles what it’s best at.

| Pattern                | How it works                                                                     | Example                                                                                           |
|------------------------|----------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
| **Skill + MCP**        | MCP provides the connection; a skill teaches Claude how to use it well           | MCP connects to your database, a skill documents your schema and query patterns                   |
| **Skill + Subagent**   | A skill spawns subagents for parallel work                                       | `/audit` skill kicks off security, performance, and style subagents that work in isolated context |
| **CLAUDE.md + Skills** | CLAUDE.md holds always-on rules; skills hold reference material loaded on demand | CLAUDE.md says “follow our API conventions,” a skill contains the full API style guide            |
| **Hook + MCP**         | A hook triggers external actions through MCP                                     | Post-edit hook sends a Slack notification when Claude modifies critical files                     |


[​](#understand-context-costs)

Understand context costs

Every feature you add consumes some of Claude’s context. Too much can fill up your context window, but it can also add noise that makes Claude less effective; skills may not trigger correctly, or Claude may lose track of your conventions. Understanding these trade-offs helps you build an effective setup. For an interactive view of how these features combine in a running session, see [Explore the context window](context-window.md).


[​](#context-cost-by-feature)

Context cost by feature

Each feature has a different loading strategy and context cost:

| Feature               | When it loads                                   | What loads                                                                                                                      | Context cost                                 |
|-----------------------|-------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------|
| **CLAUDE.md**         | Session start                                   | Full content of each file that loads at session start                                                                           | Every request                                |
| **Output styles**     | Session start, and again when you switch styles | The active style’s full instructions; nothing for the Default style                                                             | Every request                                |
| **Skills**            | Session start + when used                       | Descriptions at start, full content when used                                                                                   | Low (descriptions every request)\*           |
| **MCP servers**       | Session start                                   | Tool names; full schemas on demand                                                                                              | Low until a tool is used                     |
| **Code intelligence** | After file edits and on demand                  | Diagnostics after edits; symbol locations on lookup                                                                             | Low; reduces file reads elsewhere            |
| **Subagents**         | When spawned                                    | Fresh context with specified skills, or the parent conversation for a [fork](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation) | Isolated from main session                   |
| **Hooks**             | On trigger                                      | Nothing (runs externally)                                                                                                       | Zero, unless hook returns additional context |

\*Set [`disable-model-invocation: true`](../08-Plugins-Skills/skills.md#control-who-invokes-a-skill) in a skill’s frontmatter to keep its description out of Claude’s context. For a skill you didn’t write, set [`skillOverrides`](../08-Plugins-Skills/skills.md#override-skill-visibility-from-settings) in settings to do the same without editing its file.


[​](#understand-how-features-load)

Understand how features load

Each feature loads at different points in your session. The tabs below explain when each one loads and what goes into context.

- CLAUDE.md

- Skills

- MCP servers

- Code intelligence

- Subagents

- Hooks

**When:** Session start**What loads:** Full content of each CLAUDE.md file that loads at session start (managed, user, and project levels).**Inheritance:** Claude reads CLAUDE.md files from your working directory up to the root, and discovers nested ones in subdirectories as it accesses those files. See [How CLAUDE.md files load](memory.md#how-claude-md-files-load) for details. If a nested CLAUDE.md is over its [per-file size limit](memory.md#claude-ignores-the-end-of-my-subdirectory-claude-md), Claude receives only the start of the file.

Keep CLAUDE.md under 200 lines. Move reference material to skills, which load on demand. To get [trim proposals for a checked-in CLAUDE.md](memory.md#my-claude-md-is-too-large), run `/doctor`.

Skills are extra capabilities in Claude’s toolkit. They can be reference material (like an API style guide) or invocable workflows you trigger with `/<name>` (like `/deploy`). Claude Code includes [bundled skills](commands.md) like `/code-review`, `/batch`, and `/debug` that work without setup. You can also create your own.**When:** Depends on the skill’s configuration. By default, descriptions load at session start and full content loads when used. For user-only skills (`disable-model-invocation: true`), nothing loads until you invoke them.**What loads:** For model-invocable skills, Claude sees names and descriptions in every request. When you invoke a skill with `/<name>` or Claude loads it automatically, the full content loads into your conversation.**How Claude chooses skills:** Claude matches your task against skill descriptions to decide which are relevant. If descriptions are vague or overlap, Claude may load the wrong skill or miss one that would help. To tell Claude to use a specific skill, invoke it with `/<name>`.**Context cost:** Low until used. User-only skills have zero cost until invoked.**In subagents:** Skills work differently in subagents. Instead of on-demand loading, skills listed in the subagent’s `skills` field are fully preloaded into its context at launch. Subagents can still discover and invoke unlisted project, user, and plugin skills through the Skill tool.

Use `disable-model-invocation: true` for skills with side effects. This saves context and ensures they run only when you name them.

**When:** Session start.**What loads:** Tool names and server instructions from connected servers. Full JSON schemas stay deferred until Claude needs a specific tool.**Context cost:** [Tool search](../06-MCP-Tools/General/mcp.md#scale-with-mcp-tool-search) is on by default, so idle MCP tools consume minimal context.

Run `/mcp` to see each server’s connection status. Run `/context all` to see how many tokens each loaded MCP tool uses. Claude Code [reconnects to remote servers automatically](../06-MCP-Tools/General/mcp.md#automatic-reconnection) if they drop, and you can disconnect servers you’re not actively using.

**When:** After file edits, and on demand when Claude navigates code.**What loads:** Type errors and warnings after each file edit. Definition, reference, and type information when Claude looks up a symbol.**Context cost:** Low. Symbol lookups often replace broad file reads, so net context use can go down.

The LSP tool is inactive until you install a [code intelligence plugin](../08-Plugins-Skills/plugins-code-intelligence.md) for your language.

**When:** On demand, when you or Claude spawns one for a task.**What loads:** Fresh, isolated context containing:

- The agent’s own system prompt, not the Claude Code system prompt
- Full content of skills listed in the agent’s `skills:` field
- CLAUDE.md and git status. The built-in Explore and Plan agents [start with neither](../09-Agents-Patterns/sub-agents.md#what-loads-at-startup), and an agent whose definition sets [`omitClaudeMd`](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields) starts without the user, project, and local CLAUDE.md files.
- Whatever context the lead agent passes in the prompt

For a [fork](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation), Claude Code loads the parent’s conversation so far, system prompt, and tools instead.**Context cost:** Isolated from main session.

Use subagents for work that doesn’t need your full conversation context. Their isolation prevents bloating your main session.

**When:** On trigger. Claude Code runs hooks at specific lifecycle events like tool execution, session boundaries, prompt submission, permission requests, and compaction. See [Hooks](../07-Hooks/hooks.md) for the full list.**What loads:** Nothing by default. Hooks execute outside the main conversation.**Context cost:** Zero, unless the hook returns output that gets added as messages to your conversation.

Hooks are ideal for side effects (linting, logging) that don’t need to affect Claude’s context.


[​](#learn-more)

Learn more

Each feature has its own guide with setup instructions, examples, and configuration options.

## CLAUDE.md

Store project context, conventions, and instructions

## Skills

Give Claude domain expertise and reusable workflows

## Subagents

Offload work to isolated context

## Dynamic workflows

Run many subagents from one script

## Cross-session messaging

Let Claude message your other sessions

## MCP

Connect Claude to external services

## Hooks

Automate actions with hooks

## Plugins

Bundle and share feature sets

## Marketplaces

Host and distribute plugin collections

---

## Fullscreen rendering - Claude Code Docs

Source: https://code.claude.com/docs/en/fullscreen
Path: 02-Claude-Code-CLI/fullscreen.md

## On this page

- [Enable fullscreen rendering](#enable-fullscreen-rendering)
  - [Fullscreen by default](#fullscreen-by-default)
- [What changes](#what-changes)
- [Use the mouse](#use-the-mouse)
- [Scroll the conversation](#scroll-the-conversation)
  - [Auto-follow](#auto-follow)
  - [Mouse wheel scrolling](#mouse-wheel-scrolling)
  - [Scroll in the JetBrains IDE terminal](#scroll-in-the-jetbrains-ide-terminal)
- [Search and review the conversation](#search-and-review-the-conversation)
- [Watch your changes in the diff panel](#watch-your-changes-in-the-diff-panel)
- [Clear the conversation](#clear-the-conversation)
- [Use with tmux](#use-with-tmux)
- [Keep native text selection](#keep-native-text-selection)
- [Troubleshooting](#troubleshooting)
  - [Stale or misplaced text on screen](#stale-or-misplaced-text-on-screen)
  - [Claude Code's fullscreen renderer didn't finish starting last time appears at startup](#fullscreen-renderer-didnt-finish-starting)
  - [How Claude Code counts failed starts](#how-claude-code-counts-failed-starts)
- [Research preview](#research-preview)

Interface

# Fullscreen rendering

Copy pageCopy page

Enable a smoother, flicker-free rendering mode with mouse support and stable memory usage in long conversations.

Copy pageCopy page

Fullscreen rendering is a [research preview](#research-preview). Whether you [start in fullscreen or in the classic renderer](#fullscreen-by-default) depends on your setup. Run `/tui fullscreen` or `/tui default` to switch in your current conversation. Behavior may change based on feedback.

Fullscreen rendering is an alternative rendering path for the Claude Code CLI that eliminates flicker, keeps memory usage flat in long conversations, and adds mouse support. It draws the interface on the terminal’s alternate screen buffer, like `vim` or `htop`, and only renders messages that are currently visible. This reduces the amount of data sent to your terminal on each update. The difference is most noticeable in terminal emulators where rendering throughput is the bottleneck, such as the VS Code integrated terminal, tmux, and iTerm2. If your terminal scroll position jumps to the top while Claude is working, or the screen flashes as tool output streams in, this mode addresses those.

The term fullscreen describes how Claude Code takes over the terminal’s drawing surface, the way `vim` does. It has nothing to do with maximizing your terminal window, and works at any window size.


[​](#enable-fullscreen-rendering)

Enable fullscreen rendering

Run `/tui fullscreen` inside any Claude Code conversation. The CLI saves the [`tui` setting](settings-reference.md#tui) and relaunches into fullscreen with your conversation intact, so you can switch mid-session without losing context. Run `/tui default` to switch back to the classic renderer, or `/tui` with no argument to print which renderer is active. In [screen reader mode](accessibility.md), Claude Code always uses the classic renderer except in attached [background sessions](../09-Agents-Patterns/agent-view.md), which still render fullscreen. If you run `/tui fullscreen` in any other session, Claude Code prints an explanation instead of switching and doesn’t change the saved `tui` setting. Claude Code carries these into the relaunched session:

- The conversation as it appears on screen. After a [`/rewind`](checkpointing.md#rewind-and-summarize), that means:
  - If you rewound earlier in the session, Claude Code relaunches from the rewound point, not from the longer transcript saved on disk. For example, if you rewound past your last three messages, the relaunched session opens without them
  - If you rewound to before your first message, Claude Code relaunches with an empty conversation
- Your [permission mode](permission-modes.md) and [effort level](model-config.md#adjust-effort-level)
- The model you last picked with [`/model`](model-config.md#setting-your-model)
- Rules you passed with [`--allowed-tools` or `--disallowed-tools`](cli-reference.md#cli-flags), and your `--agent`, `--agents`, `--append-system-prompt`, and `--system-prompt-snapshot` flags
- A `--chrome` or `--no-chrome` flag you launched with, so [Chrome integration](../03-IDE-Integrations/chrome.md) stays on or off as you chose for this session

Claude Code declines to relaunch if the session has a restriction it can’t pass to the restarted process. Restrictions it can’t pass include:

- Launch flags such as a [`--system-prompt`](cli-reference.md#cli-flags) replacement, a [`--tools`](cli-reference.md#cli-flags) allowlist, or [`--setting-sources`](cli-reference.md#cli-flags)
- Deny or ask rules that a [hook or SDK permission update](../07-Hooks/hooks.md#permission-update-entries) added for this session only

In that case Claude Code prints [`Cannot switch renderers in this session`](errors.md#cannot-switch-renderers-in-this-session) with the reasons. It doesn’t switch or save anything. You can also set the `CLAUDE_CODE_NO_FLICKER` environment variable before starting Claude Code:

```python
CLAUDE_CODE_NO_FLICKER=1 claude
```

For how the [`tui`](settings-reference.md#tui) setting and the variable combine when both are set, see the setting’s entry. After a [failed fullscreen start](#fullscreen-renderer-didnt-finish-starting), Claude Code still honors the variable but not the setting. The `/tui` command clears `CLAUDE_CODE_NO_FLICKER` from the relaunched process so the setting it writes takes effect.


[​](#fullscreen-by-default)

Fullscreen by default

Attached [background sessions](../09-Agents-Patterns/agent-view.md) render fullscreen, and other sessions in [screen reader mode](accessibility.md) use the classic renderer. Otherwise, Claude Code starts you in the renderer from the first row of this table that matches your setup:

| Your situation                                                                                                                                                                                 | Renderer you start in          |
|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------|
| You set [`CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1`](env-vars.md) or `CLAUDE_CODE_NO_FLICKER=0`                                                                                            | Classic                        |
| You set `CLAUDE_CODE_NO_FLICKER=1`                                                                                                                                                             | Fullscreen                     |
| Claude Code [turned fullscreen off after a failed fullscreen start](#fullscreen-renderer-didnt-finish-starting) on this machine                                                                | Classic                        |
| You’re in iTerm2’s [`tmux -CC` integration mode](#use-with-tmux), or you’re connected over SSH to Claude Code running on Windows                                                               | Classic                        |
| You saved a [`tui` setting](settings-reference.md#tui)                                                                                                                                   | The renderer the setting names |
| Your session doesn’t [fetch feature flags from Anthropic](env-vars.md#features-that-need-feature-flag-fetching), and Claude Code has stopped offering the startup dialog on this machine | Classic                        |
| Your session doesn’t fetch feature flags from Anthropic, and this machine’s first Claude Code launch ran v2.1.239 or later                                                                     | Fullscreen                     |
| Your session fetches feature flags from Anthropic, and you first used Claude Code on or after May 6, 2026                                                                                      | Fullscreen                     |
| Anything else                                                                                                                                                                                  | Classic                        |

Sessions that don’t fetch feature flags include those through [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), or [Microsoft Foundry](microsoft-foundry.md), and those with telemetry turned off. If you start in the classic renderer and haven’t saved a `tui` setting, Claude Code may open a dialog at startup offering the switch:

- If you accept, Claude Code relaunches the same way `/tui fullscreen` does, carrying the same session state, and saves the setting once the relaunched session has [started successfully](#fullscreen-renderer-didnt-finish-starting).
- If you choose **Not now**, Claude Code doesn’t offer again on this machine.
- Claude Code stops offering after it has shown the dialog on three launches, answered or not.


[​](#what-changes)

What changes

Fullscreen rendering changes how the CLI draws to your terminal. The input box stays fixed at the bottom of the screen instead of moving as output streams in. If the input doesn’t move while Claude is working, fullscreen rendering is active. Only visible messages are kept in the render tree, so memory stays constant regardless of conversation length. Because the conversation lives in the alternate screen buffer instead of your terminal’s scrollback, a few things work differently:

| Before                                              | Now                                                                            | Details                                                                   |
|:----------------------------------------------------|:-------------------------------------------------------------------------------|:--------------------------------------------------------------------------|
| `Cmd+f` or tmux search to find text                 | `Ctrl+o` for transcript mode, then `/` to search or `[` to write to scrollback | [Search and review the conversation](#search-and-review-the-conversation) |
| Terminal’s native click-and-drag to select and copy | In-app selection, copies automatically on mouse release                        | [Use the mouse](#use-the-mouse)                                           |
| `Cmd`-click to open a URL                           | `Cmd`-click on macOS, `Ctrl`-click elsewhere                                   | [Use the mouse](#use-the-mouse)                                           |

If mouse capture interferes with your workflow, you can [turn it off](#keep-native-text-selection) while keeping the flicker-free rendering.


[​](#use-the-mouse)

Use the mouse

Fullscreen rendering captures mouse events and handles them inside Claude Code:

- **Click in the prompt input** to position your cursor anywhere in the text you’re typing.
- **Click a suggestion in the `/` command or `@` file list** to accept it. Hovering highlights the row under your cursor.
- **Click an option in a select menu** to choose it. This covers permission prompts, `/model`, `/config`, and other dialogs that show a list of options.
- **Click an option in a multi-select menu** to toggle it, and click the submit button to confirm your choices. Clicking a free-text row, such as the `Other` row in a multiple-choice question, focuses its input field so you can type an answer.
- **Click a setting’s value in the `/config` panel** to change it, and scroll the settings list with the mouse wheel. Requires Claude Code v2.1.271 or later.
- **Scroll a select or multi-select menu with the mouse wheel** when it has more options than it shows at once, such as the `/model` list in a short terminal window. The wheel scrolls the list while the pointer is over its options. Requires Claude Code v2.1.280 or later.
- **Scroll an overflowing list with its scrollbar.** In list panels such as `/skills`, `/mcp`, and `/plugin`’s Installed list, a scrollbar appears beside a list with more rows than fit while the pointer is over it. Click the track to jump to that point, or drag the thumb. Requires Claude Code v2.1.281 or later.
  - Where the bar has `↑` and `↓` arrows at its ends, click an arrow to scroll a single row, or hold it to keep scrolling. The arrows require Claude Code v2.1.286 or later.
- **Click the `↑ N more` or `↓ N more` row at the edge of a list** to jump to that end of the list without choosing an option. Requires Claude Code v2.1.286 or later.
- **Click a collapsed tool result** to expand it and see the full output. Click again to collapse. The tool call and its result expand together. Only messages that have more to show are clickable.
  - Clicking also expands the output of a `!` shell command, whether an older truncated result or the live progress row while the command runs. Requires Claude Code v2.1.257 or later.
  - Clicking also expands a dim `Message from @<sender>` line when the sender is a [teammate](../09-Agents-Patterns/agent-teams.md) or another agent running in your session.
- **Hold `Cmd` on macOS, or `Ctrl` on Linux and Windows, and click a URL or file path** to open it. Plain `http://` and `https://` URLs open in your browser. When Claude Code handles the click, file paths in tool output, like the ones printed after an Edit or Write, open in your file manager with the file selected. A plain click without the modifier doesn’t open links, matching native terminal behavior.
  - On Linux and WSL, clicking a file path needs a file manager that provides the `org.freedesktop.FileManager1` D-Bus interface. Without one, nothing opens.
  - Claude Code renders a network (UNC) path, such as `\\server\share\file.ts`, as plain text with no link, because opening a network path can send your Windows credentials to the host it names.
  - Some macOS terminals forward `Cmd`+click to the running app instead of opening the link themselves, and the terminal mouse protocol has no way to encode the `Cmd` key, so Claude Code receives a plain click. In Ghostty, and in Warp on macOS, Claude Code detects this and lets a plain click on a link open it, and holding `Cmd` still works.
  - In the VS Code integrated terminal and similar xterm.js-based terminals, Claude Code defers to the terminal’s own link handler, which uses the same gesture.
- **Click and drag** to select text anywhere in the conversation. Double-click selects a word, matching iTerm2’s word boundaries so a file path selects as one unit. Double-clicking a URL selects the whole URL, including the scheme. Triple-click selects the line.
- **Scroll with the mouse wheel** to move through the conversation.

Selected text copies to your clipboard automatically on mouse release. To turn this off, toggle Copy on select in `/config`. With Copy on select off, press `Ctrl+Shift+c` to copy manually. On terminals that support the kitty keyboard protocol, such as kitty, WezTerm, Ghostty, and iTerm2, `Cmd+c` also works. If you have a selection active, `Ctrl+c` copies instead of cancelling. With a selection active, hold `Shift` and press the arrow keys to extend it from the keyboard. `Shift+↑` and `Shift+↓` scroll the viewport when the selection reaches the top or bottom edge. `Shift+Home` and `Shift+End` extend to the start or end of the current line. In the normal prompt view, what happens to an active selection depends on the key you press:

- **`Esc`**: Claude Code performs the key’s usual action, such as interrupting the running response or dismissing an open dialog, and the selection stays highlighted.
- **`PgUp`, `PgDn`, `Ctrl+Home`, `Ctrl+End`, or `Shift`, `Alt` or `Option`, or `Cmd`, `Win`, or `Super` with an arrow, `Home`, or `End` key**: the selection stays.
- **Any other key, including plain arrow keys, `Enter`, and typed characters**: Claude Code clears the selection.
- **A key bound to [`selection:clear`](keybindings.md#scroll-actions)**: Claude Code clears the selection, even when the key is `Esc` or another key that otherwise keeps it. The action has no default binding.

In [transcript mode](#search-and-review-the-conversation), the navigation keys listed there also keep the selection.


[​](#scroll-the-conversation)

Scroll the conversation

Fullscreen rendering handles scrolling inside the app. Use these shortcuts to navigate:

| Shortcut        | Action                                               |
|:----------------|:-----------------------------------------------------|
| `PgUp` / `PgDn` | Scroll up or down by half a screen                   |
| `Ctrl+Home`     | Jump to the start of the conversation                |
| `Ctrl+End`      | Jump to the latest message and re-enable auto-follow |
| Mouse wheel     | Scroll a few lines at a time                         |

If you close a [compacted](context-window.md#what-survives-compaction) session and [resume](sessions.md#what-a-resumed-session-restores) it, scrolling up stops at the `Conversation compacted` row, and your earlier messages stay on disk in the [transcript file](sessions.md#where-transcripts-are-stored). To get a detail from those messages, ask Claude to look it up in that file. On keyboards without dedicated `PgUp`, `PgDn`, `Home`, or `End` keys, like MacBook keyboards, hold `Fn` with the arrow keys: `Fn+↑` sends `PgUp`, `Fn+↓` sends `PgDn`, `Fn+←` sends `Home`, and `Fn+→` sends `End`. `Ctrl+Fn+→` doesn’t reach Claude Code on macOS, so a MacBook keyboard has no working jump-to-bottom chord by default. Instead, use one of these options:

- Click the [jump-to-bottom button](#auto-follow).
- Scroll to the bottom with the mouse wheel to resume following.
- Rebind `scroll:bottom` to a chord your keyboard can send.

These actions are rebindable. See [Scroll actions](keybindings.md#scroll-actions) for the full list of action names, including half-page and full-page variants that have no default binding. While you’re scrolled up, a dim header row at the top of the conversation shows the most recent prompt that has scrolled above the view. Click the row to jump to that prompt.


[​](#auto-follow)

Auto-follow

Scrolling up pauses auto-follow so new output doesn’t pull you back to the bottom. A `Jump to bottom` button floats over the bottom edge of the transcript while you’re scrolled up, and shows a count such as `3 new messages` when new output arrives. Click it, press `Ctrl+End`, or scroll to the bottom to resume following. While auto-follow is paused, the view also stays where you scrolled it when a response finishes streaming. The button’s keyboard hint reflects what your keyboard can send. On macOS it suggests clicking, or `Fn+↓` to scroll, because `Ctrl+End` doesn’t reach Claude Code from a Mac keyboard. Rebind [`scroll:bottom`](keybindings.md#scroll-actions) and the button shows your chord on every platform. On a terminal too narrow for the full label, the button shortens the hint instead of wrapping onto the transcript row underneath. To turn auto-follow off entirely so the view stays where you leave it, open `/config` and set Auto-scroll to off. With auto-scroll disabled, the view never jumps to the bottom on its own. Permission prompts and other dialogs that need a response still scroll into view regardless of this setting.


[​](#mouse-wheel-scrolling)

Mouse wheel scrolling

Mouse wheel scrolling requires your terminal to forward mouse events to Claude Code. Most terminals do this whenever an application requests it. iTerm2 makes it a per-profile setting: if the wheel does nothing but `PgUp` and `PgDn` work, open Settings → Profiles → Terminal and turn on Enable mouse reporting. The same setting is also required for click-to-expand and text selection to work. If mouse wheel scrolling feels slow, your terminal may be sending one scroll event per physical notch with no multiplier. Some terminals, like Ghostty and iTerm2 with faster scrolling enabled, already amplify wheel events. Others, including the VS Code integrated terminal, send exactly one event per notch. Claude Code can’t detect which. Set `CLAUDE_CODE_SCROLL_SPEED` to multiply the base scroll distance:

```python
export CLAUDE_CODE_SCROLL_SPEED=3
```

A value of `3` matches the default in `vim` and similar applications. The setting accepts any positive value up to 20, including fractional values below 1 such as `0.25` to slow accelerated trackpad and wheel scrolling in terminals that already amplify wheel events. To adjust scroll speed interactively, run `/scroll-speed`. Scroll while the dialog is open to feel the change immediately. Press `←` and `→` to adjust the speed, `r` to reset to the auto-detected default, and `Enter` to save. The dialog steps in whole numbers up to 10, and on terminals that support finer control it also offers quarter steps down to 0.25. The command writes the same value the `CLAUDE_CODE_SCROLL_SPEED` environment variable sets, persisted to `~/.claude/settings.json`. The dialog’s maximum is 10: if you set a higher value through the environment variable, the dialog shows 10, and saving from the dialog persists 10. The command isn’t available in the JetBrains IDE terminal. Separately from the base speed, Claude Code accelerates the scroll rate when you spin the wheel quickly, so a fast spin covers more distance than the same number of slow notches. To turn acceleration off and keep a constant rate per notch, set `wheelScrollAccelerationEnabled` to `false` in [`settings.json`](settings-reference.md#all-settings). This setting requires Claude Code v2.1.174 or later.


[​](#scroll-in-the-jetbrains-ide-terminal)

Scroll in the JetBrains IDE terminal

In the JetBrains IDE terminal, Claude Code applies its own scroll handling and ignores `CLAUDE_CODE_SCROLL_SPEED`. The terminal sends scroll events at a much higher rate than other emulators, so a multiplier tuned elsewhere overshoots here. In 2025.2, the terminal also has scroll-wheel bugs that produce spurious arrow keys and wrong-direction events. Claude Code detects these at runtime and mitigates them automatically, so trackpad and mouse wheel scrolling work without configuration. For the best scroll experience, upgrade to 2025.3 or later. Claude Code shows a hint the first time you scroll if it detects the bug.


[​](#search-and-review-the-conversation)

Search and review the conversation

`Ctrl+o` toggles between the normal prompt and transcript mode. For a quieter view that shows only your last prompt, a one-line summary of tool calls with edit diffstats, and the final response, run `/focus`. The setting persists across sessions. Run `/focus` again to turn it off. Transcript mode gains `less`-style navigation and search:

| Key                                  | Action                                                                                                 |
|:-------------------------------------|:-------------------------------------------------------------------------------------------------------|
| `/`                                  | Open search. Type to find matches, `Enter` to accept, `Esc` to cancel and restore your scroll position |
| `n` / `N`                            | Jump to next or previous match. Works after you’ve closed the search bar                               |
| `j` / `k` or `↑` / `↓`               | Scroll one line                                                                                        |
| `g` / `G` or `Home` / `End`          | Jump to top or bottom                                                                                  |
| `{` / `}`                            | Jump to the previous or next prompt                                                                    |
| `Ctrl+u` / `Ctrl+d`                  | Scroll half a page                                                                                     |
| `Ctrl+b` / `Ctrl+f` or `Space` / `b` | Scroll a full page                                                                                     |
| `Ctrl+o`, `Esc`, or `q`              | Exit transcript mode and return to the prompt                                                          |

Your terminal’s `Cmd+f` and tmux search don’t see the conversation because it lives in the alternate screen buffer, not the native scrollback. To hand the content back to your terminal, press `Ctrl+o` to enter transcript mode first, then:

- **`[`**: writes the full conversation into your terminal’s native scrollback buffer, with all tool output expanded. The conversation is now ordinary text in your terminal, so `Cmd+f`, tmux copy mode, and any other native tool can search or select it. Long sessions may pause for a moment while this happens. This lasts until you exit transcript mode with `Esc` or `q`, which returns you to fullscreen rendering. The next `Ctrl+o` starts fresh.
- **`v`**: writes the conversation to a temporary file and opens it in `$VISUAL` or `$EDITOR`.


[​](#watch-your-changes-in-the-diff-panel)

Watch your changes in the diff panel

In fullscreen rendering, [`/diff`](interactive-mode.md#review-changes-with-%2Fdiff) opens a panel beside the conversation, so you can watch the changes accumulate while Claude works. [Diff panel](interactive-mode.md#diff-panel) covers what it shows, when it opens on its own, how to keep it closed, and how to change what it compares against.


[​](#clear-the-conversation)

Clear the conversation

Run `/clear` to start a new conversation. If the display looks garbled or partially blank, press `Ctrl+L` to redraw the screen. The redraw keeps the conversation and your input in place. `Cmd+K` does the same as `Ctrl+L` when your terminal passes it through to Claude Code. iTerm2 and Terminal.app handle `Cmd+K` themselves and clear their own screen, and Claude Code detects the cleared screen and repaints the conversation. Before v2.1.280, starting with v2.1.260, pressing `Ctrl+L`, or `Cmd+K` where it reaches Claude Code, cleared the screen in fullscreen rendering. Before v2.1.238, pressing `Ctrl+L` twice within two seconds ran `/clear`.


[​](#use-with-tmux)

Use with tmux

Fullscreen rendering works inside tmux, with three caveats. Mouse wheel scrolling requires tmux’s mouse mode. If your `~/.tmux.conf` doesn’t already enable it, add this line and reload your config:

```python
set -g mouse on
```

Without mouse mode, wheel events go to tmux instead of Claude Code. Keyboard scrolling with `PgUp` and `PgDn` works either way. Claude Code prints a one-time hint at startup if it detects tmux with mouse mode off. Fullscreen rendering is incompatible with iTerm2’s tmux integration mode, which is the mode you enter with `tmux -CC`. In integration mode, iTerm2 renders each tmux pane as a native split rather than letting tmux draw to the terminal. The alternate screen buffer and mouse tracking don’t work correctly there: the mouse wheel does nothing, and double-click can corrupt the terminal state. Don’t enable fullscreen rendering in `tmux -CC` sessions. Regular tmux inside iTerm2, without `-CC`, works fine. tmux releases through the 3.6 series don’t implement synchronized output, so under those versions you may see more flicker during redraws than when running Claude Code directly in your terminal. Claude Code probes the terminal for synchronized-output support at startup and uses it when the terminal reports it. If you see flicker under tmux, upgrade to the newest tmux or run Claude Code in its own terminal tab outside tmux.


[​](#keep-native-text-selection)

Keep native text selection

Mouse capture is the most common friction point, especially over SSH or inside tmux. When Claude Code captures mouse events, your terminal’s native copy-on-select stops working. The selection you make with click-and-drag exists inside Claude Code, not in your terminal’s selection buffer, so tmux copy mode, Kitty hints, and similar tools don’t see it. Claude Code writes the selection to your system clipboard, and the path it uses depends on your setup. On a local session it runs a native clipboard tool:

- **macOS**: `pbcopy`
- **Linux**: `wl-copy` on Wayland, or `xclip` or `xsel` on X11, whichever is installed. Claude Code writes both the clipboard and the PRIMARY selection, so middle-click paste works.
- **Windows and WSL**: PowerShell `Set-Clipboard`

Inside tmux it also writes to the tmux paste buffer. Over SSH it falls back to OSC 52 escape sequences. Inside GNU screen, Claude Code copies long selections to the clipboard too. Before v2.1.219, if you copied a selection longer than roughly 570 characters, GNU screen printed base64 text into the window instead. Claude Code prints a toast after each copy telling you which path it used. Some terminals block OSC 52 by default. iTerm2 blocks it until you turn on Settings → General → Selection → Applications in terminal may access clipboard; running [`/terminal-setup`](terminal-config.md) in iTerm2 enables this for you. For a one-off native selection, the key to use depends on your terminal:

- **Terminal.app**: `Fn`
- **iTerm2**: `Option`
- **VS Code, Cursor, and Devin Desktop**: `Shift`, or `Option` on macOS with the `terminal.integrated.macOptionClickForcesSelection` setting enabled
- **Most other terminals**: `Shift`

Hold that key while you click and drag. Your terminal handles the selection itself instead of passing it to Claude Code, so copy shortcuts like `Cmd+C` work on what you select. Claude Code also shows the correct key in its on-screen hint. Over SSH or inside tmux, Claude Code can’t always detect the terminal you’re connecting from, so the hint lists the candidate keys instead. If you rely on native selection all the time, set `CLAUDE_CODE_DISABLE_MOUSE=1` to opt out of mouse capture while keeping the flicker-free rendering and flat memory:

```python
CLAUDE_CODE_NO_FLICKER=1 CLAUDE_CODE_DISABLE_MOUSE=1 claude
```

With mouse capture disabled, keyboard scrolling with `PgUp`, `PgDn`, `Ctrl+Home`, and `Ctrl+End` still works, and your terminal handles selection natively. You lose click-to-position-cursor, click-to-expand, URL clicking, and wheel scrolling inside Claude Code. To keep wheel scrolling but turn off click, drag, and hover handling, set `CLAUDE_CODE_DISABLE_MOUSE_CLICKS=1` instead. `CLAUDE_CODE_DISABLE_MOUSE` takes precedence when both variables are set. With clicks disabled, Claude Code still captures the mouse, so the wheel and touchpad scroll the conversation but left clicks do nothing inside Claude Code. You still need to hold your terminal’s key for native click-and-drag selection. Right-click and middle-click paste continue to work on terminals that support them.


[​](#troubleshooting)

Troubleshooting


[​](#stale-or-misplaced-text-on-screen)

Stale or misplaced text on screen

Fullscreen rendering sends only the cells that changed between frames. Some terminals, most commonly Windows Terminal and other ConPTY-backed hosts, coalesce these positioned writes incorrectly and leave fragments of earlier output on screen until you resize the window. Set [`CLAUDE_CODE_ALT_SCREEN_FULL_REPAINT=1`](env-vars.md) to repaint every cell on every frame instead of sending incremental updates. On Windows PowerShell:

```python
$env:CLAUDE_CODE_ALT_SCREEN_FULL_REPAINT = "1"
claude
```

On macOS or Linux:

```python
CLAUDE_CODE_ALT_SCREEN_FULL_REPAINT=1 claude
```

On Windows, Claude Code already enables full repaint automatically for background sessions and [agent view](../09-Agents-Patterns/agent-view.md), so you only need to set the variable for an interactive fullscreen session you launched directly.


[​](#fullscreen-renderer-didnt-finish-starting)

`Claude Code's fullscreen renderer didn't finish starting last time` appears at startup

If a fullscreen session on this machine crashes before it has started successfully, Claude Code starts your next session in the classic renderer and prints one of two lines. A session has started successfully once it has drawn its first frame and then either stayed up for 10 seconds or you ended it with `/exit`, Ctrl+C, or Ctrl+D. The line you see tells you what Claude Code does after this session:

- After one failed start, you see `Claude Code's fullscreen renderer didn't finish starting last time on this machine`. Claude Code tries fullscreen rendering again in the next session you start
- After two failed starts, you see `Claude Code's fullscreen renderer has repeatedly failed to start on this machine`. Claude Code keeps using the classic renderer until you update Claude Code or run `/tui fullscreen`, and prints nothing in those later sessions

To confirm that a failed start is why you’re in the classic renderer, run `/tui` with no argument. While a failed start is the reason, the `Current renderer` line says so. To keep the classic renderer, run `/tui default`, which saves the `tui` setting without relaunching. To try fullscreen rendering again, run `/tui fullscreen`. If that session doesn’t finish starting either, [report the problem](#research-preview). Before v2.1.236, Claude Code kept starting sessions in fullscreen rendering after a failed start.


[​](#how-claude-code-counts-failed-starts)

How Claude Code counts failed starts

- Sessions that count: only sessions that started in fullscreen rendering because your `tui` setting says so, because you accepted the [startup dialog](#fullscreen-by-default), or because Claude Code starts you in fullscreen by default
- `CLAUDE_CODE_NO_FLICKER=1`: if you set it, Claude Code renders that session fullscreen even after a failed start, and doesn’t count it
- Count reset: Claude Code counts failed starts per Claude Code version, and a successful fullscreen start resets the count
- Startup dialog: if you accepted the dialog and the relaunched session crashed, Claude Code prints neither line and doesn’t show the dialog again on this Claude Code version


[​](#research-preview)

Research preview

Fullscreen rendering is a research preview feature. It has been tested on common terminal emulators, but you may encounter rendering issues on less common terminals or unusual configurations. If you encounter a problem, run `/feedback` inside Claude Code to report it, or open an issue on the [claude-code GitHub repo](https://github.com/anthropics/claude-code/issues). Include your terminal emulator name and version. To turn fullscreen rendering off, run `/tui default`, or unset `CLAUDE_CODE_NO_FLICKER` if you enabled it that way. When you switch back with `/tui default`, Claude Code may first show an optional feedback prompt asking what made you switch. Type a reason and press `Enter` to send it, or press `Esc` to skip. The CLI relaunches into the classic renderer either way. To force the classic renderer regardless of the saved `tui` setting, set `CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1`. The classic renderer keeps the conversation in your terminal’s native scrollback so `Cmd+f` and tmux copy mode work as usual. Background sessions opened from [agent view](../09-Agents-Patterns/agent-view.md) or `claude attach` always use fullscreen rendering. The attaching terminal enters the alternate screen buffer to show the session, and the classic renderer has no scrollback or mouse handling there, so the `tui` setting and `CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN` don’t apply to them.

---

## Use Claude Code GitHub Actions with cloud providers - Claude Code Docs

Source: https://code.claude.com/docs/en/github-actions-cloud-providers
Path: 02-Claude-Code-CLI/github-actions-cloud-providers.md

## On this page

- [Choose your provider](#choose-your-provider)
- [Prerequisites](#prerequisites)
- [Set up the integration](#set-up-the-integration)
- [Troubleshooting](#troubleshooting)
- [What’s next](#what%E2%80%99s-next)

Code review & CI/CD

# Use Claude Code GitHub Actions with cloud providers

Copy pageCopy page

Run Claude Code GitHub Actions through Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry instead of the Claude API

Copy pageCopy page

[Claude Code GitHub Actions](github-actions.md) calls the Claude API by default. To route inference through your own cloud account instead, set the Claude Code GitHub Action’s provider input and configure your cloud to trust the workflow’s OpenID Connect (OIDC) token. The workflow authenticates with that token, so you store no long-lived cloud credential in your repository.

This page builds on the [GitHub Actions setup](github-actions.md#setup). It assumes you already know the workflow file and the `anthropics/claude-code-action` step, and covers only what a cloud provider changes.


[​](#choose-your-provider)

Choose your provider

The Claude Code GitHub Action supports three providers, and the setup steps below differ only in the cloud-side configuration. Use the one where your organization already has Claude model access. You tell the Claude Code GitHub Action which provider to use with one input in the `anthropics/claude-code-action` step’s `with:` block:

- **Amazon Bedrock**: `use_bedrock: "true"`
- **Google Cloud’s Agent Platform**: `use_vertex: "true"`
- **Microsoft Foundry**: `use_foundry: "true"`

The complete workflow examples under [Set up the integration](#set-up-the-integration) already include the input for each provider.


[​](#prerequisites)

Prerequisites

Before you start, you need:

- Admin access to the repository where the Claude Code GitHub Action runs, to install a GitHub App and add secrets
- Permission to create identity resources in your cloud account: IAM roles and OIDC identity providers on AWS, Workload Identity Federation resources and service accounts on Google Cloud, or Microsoft Entra applications on Azure
- Claude model access on your provider:
  - **Amazon Bedrock**: access granted to Claude models. Cross-region inference profiles, such as the `us.` model IDs in this page’s examples, need access granted in every region of their region group. See [Claude Code on Amazon Bedrock](amazon-bedrock.md)
  - **Google Cloud’s Agent Platform**: a project with the Agent Platform API enabled and access to Claude models. See [Claude Code on Google Cloud’s Agent Platform](google-vertex-ai.md)
  - **Microsoft Foundry**: a Foundry resource with a Claude model deployment. See [Claude Code on Microsoft Foundry](microsoft-foundry.md)


[​](#set-up-the-integration)

Set up the integration

Beyond the prerequisites, you create a GitHub identity for the Claude Code GitHub Action, the cloud-side trust configuration, the repository secrets, and the workflow file. The steps below walk through each.

1

Choose a GitHub identity

The Claude Code GitHub Action pushes commits and posts comments through a GitHub identity. The [quick setup](github-actions.md#quick-setup) installs the official Claude GitHub App for this. With a cloud provider, you choose the identity yourself:

- **Official [Claude GitHub App](https://github.com/apps/claude)**: install it on the repository, or skip to the next step if it’s already installed
- **Custom GitHub App**: create your own app when you want only the three permissions the Claude Code GitHub Action uses rather than the [official app’s full set](github-actions.md#github-app-permissions)
- **GitHub’s automatic `GITHUB_TOKEN`**: no app to create or install, but GitHub doesn’t trigger your CI workflows on commits made with it

The workflow examples in the fourth step authenticate with a custom app. That step also says what to change for the other two options.To create a custom app, [register a new GitHub App](https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app) with webhooks disabled, since this integration doesn’t use them. Grant it three repository permissions:

- **Contents**: read and write
- **Issues**: read and write
- **Pull requests**: read and write

After registering the app, generate a private key and keep the downloaded `.pem` file, note the App ID from the app’s settings page, and [install the app](https://docs.github.com/en/apps/using-github-apps/installing-your-own-github-app) on the repository where the Claude Code GitHub Action runs. You add the key and the ID as secrets in the third step.

2

Configure cloud authentication

Configure your cloud to trust the OIDC token that GitHub issues to the workflow, so each workflow run gets short-lived cloud credentials. The bullets in each tab summarize what to create, and each tab links the cloud vendor’s own guide for the console-level steps.

- Amazon Bedrock

- Google Cloud's Agent Platform

- Microsoft Foundry

Create the trust configuration in your AWS account, following the [AWS guide to creating OIDC identity providers](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html):

- Add a GitHub OIDC identity provider with provider URL `https://token.actions.githubusercontent.com` and audience `sts.amazonaws.com`
- Create an IAM role trusted by that provider as a web identity, and attach the scoped invocation policy from [IAM configuration](amazon-bedrock.md#iam-configuration), which grants `bedrock:InvokeModel`, `bedrock:InvokeModelWithResponseStream`, `bedrock:ListInferenceProfiles`, and `bedrock:GetInferenceProfile`, along with two `aws-marketplace` subscription actions
- Limit the role’s trust policy to your repository with a subject condition such as `repo:your-org/your-repo:*`. See [GitHub’s OIDC hardening guide](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) for the claim format

Note the role’s ARN. You add it as a secret in the next step.

Create the federation resources in your Google Cloud project, following the [Workload Identity Federation documentation](https://cloud.google.com/iam/docs/workload-identity-federation):

- Enable three APIs: IAM Credentials, Security Token Service (STS), and the Agent Platform API, whose service name is `aiplatform.googleapis.com`
- Create a Workload Identity Pool with a GitHub OIDC provider whose issuer is `https://token.actions.githubusercontent.com`, and add an attribute condition that limits the pool to your repository
- Create a dedicated service account with only the `Vertex AI User` role, which is `roles/aiplatform.user`, and allow the pool to impersonate it

Note the provider’s full resource name and the service account’s email address. You add them as secrets in the next step.

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):

- 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
- Assign the application the `Azure AI User` role on your Foundry resource. See [Azure RBAC configuration](microsoft-foundry.md#azure-rbac-configuration) for a narrower custom role

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

3

Add repository secrets

In the repository where the Claude Code GitHub Action runs, add the secrets for your provider, plus the two app secrets if you created a custom GitHub App in the first step. See GitHub’s guide to [using secrets in GitHub Actions](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions).

| Secret                           | Needed for                    | Value                                       |
|----------------------------------|-------------------------------|---------------------------------------------|
| `AWS_ROLE_TO_ASSUME`             | Amazon Bedrock                | The ARN of the IAM role                     |
| `GCP_WORKLOAD_IDENTITY_PROVIDER` | Google Cloud’s Agent Platform | The provider’s full resource name           |
| `GCP_SERVICE_ACCOUNT`            | Google Cloud’s Agent Platform | The service account’s email address         |
| `AZURE_CLIENT_ID`                | Microsoft Foundry             | The Entra application’s client ID           |
| `AZURE_TENANT_ID`                | Microsoft Foundry             | Your Microsoft Entra tenant ID              |
| `AZURE_SUBSCRIPTION_ID`          | Microsoft Foundry             | Your Azure subscription ID                  |
| `APP_ID`                         | Custom GitHub App             | The GitHub App’s ID                         |
| `APP_PRIVATE_KEY`                | Custom GitHub App             | The contents of the `.pem` private key file |

4

Create the workflow file

Create a workflow file for your provider, such as `.github/workflows/claude.yml`. Each example responds to `@claude` mentions, authenticates to GitHub with a custom app, and includes the `id-token: write` permission, which GitHub requires to issue the OIDC token that your cloud provider exchanges for credentials.If you chose a different GitHub identity in the first step, adjust the example:

- **Official Claude GitHub App**: delete the Generate GitHub App token step and the `github_token` line
- **GitHub’s automatic token**: delete the token-generation step and change the `github_token` line to `github_token: ${{ secrets.GITHUB_TOKEN }}`

On public repositories, a comment containing the trigger phrase from any user starts this workflow. The credential steps run before the Claude Code GitHub Action checks the commenter’s write access, so the action rejects unauthorized users only after the workflow has generated an App token and signed in to your cloud provider, which leaves audit-log entries and consumes Actions minutes. To avoid those runs, add a step that verifies the commenter’s write access before the credential steps.

- Amazon Bedrock

- Google Cloud's Agent Platform

- Microsoft Foundry

Replace the `aws-region` value with your own. The credentials step exports it as `AWS_REGION` for the rest of the job.

```python
name: Claude PR Action

permissions:
  contents: write
  pull-requests: write
  issues: write
  id-token: write

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
  issues:
    types: [opened]

jobs:
  claude-pr:
    if: |
      (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Generate GitHub App token
        id: app-token
        uses: actions/create-github-app-token@v2
        with:
          app-id: ${{ secrets.APP_ID }}
          private-key: ${{ secrets.APP_PRIVATE_KEY }}

      - name: Configure AWS Credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
          aws-region: us-west-2

      - uses: anthropics/claude-code-action@v1
        with:
          github_token: ${{ steps.app-token.outputs.token }}
          use_bedrock: "true"
          claude_args: '--model us.anthropic.claude-sonnet-4-6'
```

Bedrock model IDs include a cross-region inference profile prefix such as `us.`. Use the prefix for the region group where you granted model access.

Replace the `CLOUD_ML_REGION` value with your own. You don’t need to hardcode the project ID, because the workflow reads it from the `auth` step’s output.

```python
name: Claude PR Action

permissions:
  contents: write
  pull-requests: write
  issues: write
  id-token: write

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
  issues:
    types: [opened]

jobs:
  claude-pr:
    if: |
      (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Generate GitHub App token
        id: app-token
        uses: actions/create-github-app-token@v2
        with:
          app-id: ${{ secrets.APP_ID }}
          private-key: ${{ secrets.APP_PRIVATE_KEY }}

      - name: Authenticate to Google Cloud
        id: auth
        uses: google-github-actions/auth@v2
        with:
          workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
          service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}

      - uses: anthropics/claude-code-action@v1
        with:
          github_token: ${{ steps.app-token.outputs.token }}
          use_vertex: "true"
          claude_args: '--model claude-sonnet-5'
        env:
          ANTHROPIC_VERTEX_PROJECT_ID: ${{ steps.auth.outputs.project_id }}
          CLOUD_ML_REGION: us-east5
```

Replace `your-resource-name` with your Foundry resource name. Claude Code builds the endpoint URL from it. The `azure/login` step signs in with the workflow’s OIDC token, and Claude Code picks up the credentials through the Azure [default credential chain](https://learn.microsoft.com/en-us/azure/developer/javascript/sdk/authentication/credential-chains#defaultazurecredential-overview).

```python
name: Claude PR Action

permissions:
  contents: write
  pull-requests: write
  issues: write
  id-token: write

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
  issues:
    types: [opened]

jobs:
  claude-pr:
    if: |
      (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Generate GitHub App token
        id: app-token
        uses: actions/create-github-app-token@v2
        with:
          app-id: ${{ secrets.APP_ID }}
          private-key: ${{ secrets.APP_PRIVATE_KEY }}

      - name: Authenticate to Azure
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

      - uses: anthropics/claude-code-action@v1
        with:
          github_token: ${{ steps.app-token.outputs.token }}
          use_foundry: "true"
          claude_args: '--model claude-sonnet-5'
        env:
          ANTHROPIC_FOUNDRY_RESOURCE: your-resource-name
```

Use a model ID that matches a Claude deployment in your Foundry resource. See [Claude Code on Microsoft Foundry](microsoft-foundry.md) for model configuration and version pinning.

With any provider, you can bound run length and cost by adding `--max-turns` to `claude_args`. See [Manage costs](github-actions.md#manage-costs).

5

Test the setup

Mention `@claude` in an issue or PR comment, then watch the run in the repository’s Actions tab. Claude replies in a comment on the same issue or PR.


[​](#troubleshooting)

Troubleshooting

A failing run usually breaks in one of two places:

- **Authentication errors**: usually an OIDC misconfiguration. Check that the workflow includes the `id-token: write` permission, that the trust configuration’s repository condition matches your repository exactly, and that the secret names in your workflow match the ones you added
- **Trigger and CI problems**: these behave the same as when the Claude Code GitHub Action calls the Claude API. See the main page’s [troubleshooting section](github-actions.md#troubleshooting) and the Claude Code GitHub Action’s [FAQ](https://github.com/anthropics/claude-code-action/blob/main/docs/faq.md)


[​](#what’s-next)

What’s next

- [Claude Code GitHub Actions](github-actions.md) for examples, parameters, and best practices
- [Claude Code on Amazon Bedrock](amazon-bedrock.md) for Bedrock model IDs and regions
- [Claude Code on Google Cloud’s Agent Platform](google-vertex-ai.md) for Agent Platform model IDs and regions
- [Claude Code on Microsoft Foundry](microsoft-foundry.md) for Foundry model and endpoint configuration

---

## Claude Code GitHub Actions - Claude Code Docs

Source: https://code.claude.com/docs/en/github-actions
Path: 02-Claude-Code-CLI/github-actions.md

## On this page

- [Setup](#setup)
  - [Quick setup](#quick-setup)
  - [Manual setup](#manual-setup)
  - [Set up for an organization](#set-up-for-an-organization)
  - [Uninstall](#uninstall)
  - [GitHub App permissions](#github-app-permissions)
- [Interactive and automation modes](#interactive-and-automation-modes)
  - [Who can trigger runs](#who-can-trigger-runs)
- [Example use cases](#example-use-cases)
  - [Respond to @claude mentions](#respond-to-%40claude-mentions)
  - [Run a skill](#run-a-skill)
  - [Run on a schedule](#run-on-a-schedule)
- [Best practices](#best-practices)
  - [Define project standards in CLAUDE.md](#define-project-standards-in-claude-md)
  - [Protect your credentials](#protect-your-credentials)
  - [Manage costs](#manage-costs)
- [Use a cloud provider](#use-a-cloud-provider)
- [Troubleshooting](#troubleshooting)
  - [Claude not responding to @claude commands](#claude-not-responding-to-%40claude-commands)
  - [CI not running on Claude’s commits](#ci-not-running-on-claude%E2%80%99s-commits)
  - [Authentication errors](#authentication-errors)
- [Advanced configuration](#advanced-configuration)
  - [Action parameters](#action-parameters)
  - [Pass CLI arguments](#pass-cli-arguments)
- [Upgrade from beta](#upgrade-from-beta)
- [What’s next](#what%E2%80%99s-next)

Code review & CI/CD

# Claude Code GitHub Actions

Copy pageCopy page

Run Claude Code in GitHub Actions workflows to respond to @claude mentions, automate tasks, and turn issues into pull requests

Copy pageCopy page

[Claude Code GitHub Actions](https://github.com/anthropics/claude-code-action) is a GitHub Action that runs Claude Code inside your repository’s workflows. Mention `@claude` in a pull request or issue comment to have Claude analyze code, implement changes, and push commits. You can also give the Claude Code GitHub Action a prompt to run automatically on any GitHub event. Use it to turn issues into pull requests, fix bugs from a comment, or automate recurring tasks. Several products share the Claude Code name. This page covers the `claude-code-action` workflow integration, which you configure with workflow files in your repository. For the related products, see:

- [Code Review](code-review.md): automatic review on every pull request, without writing a workflow
- [Claude Code in the cloud](claude-code-on-the-web.md): Claude Code sessions that run on cloud infrastructure instead of your machine
- [Claude Agent SDK](../05-Agent-SDK/agent-sdk-overview.md): custom automation outside GitHub Actions. The Claude Code GitHub Action is built on the SDK
- [GitHub Enterprise Server](github-enterprise-server.md): Claude Code with self-hosted GitHub


[​](#setup)

Setup

You can set up the Claude Code GitHub Action in one of two ways:

- **Quick setup**: run `/install-github-app` from Claude Code. Claude Code installs the GitHub App, adds your authentication secret, and prepares the workflow pull request for you
- **Manual setup**: install the app, add the secret, and copy the workflow file into your repository yourself. Use this path when you don’t run Claude Code locally, when the command fails, or when you want full control of the workflow files

For either path, you need admin access to the repository.


[​](#quick-setup)

Quick setup

`/install-github-app` works only with github.com repositories. If your repository’s git remote is on gitlab.com or bitbucket.org, the command prints a notice and exits instead of starting setup. To run Claude Code from GitLab pipelines, see [Claude Code GitLab CI/CD](gitlab-ci-cd.md). Before you start, install the [GitHub CLI](https://cli.github.com) and authenticate it with `gh auth login`. Claude Code checks for it and warns you if it’s missing. Open `claude` in the repository you want to connect, run `/install-github-app`, and follow the prompts. Claude Code installs the Claude GitHub App, then sets up an authentication secret for the workflows:

- If Claude Code already has an API key, it reuses that key, and offers to keep the repository’s existing `ANTHROPIC_API_KEY` secret if one is already set
- Otherwise, choose between creating a long-lived token with your Claude subscription and pasting in an API key

Claude Code saves the credential as a repository secret, named `ANTHROPIC_API_KEY` for an API key or `CLAUDE_CODE_OAUTH_TOKEN` for a subscription token. Claude Code then pushes a branch with the workflow files you select, already set to use that secret, and opens GitHub in your browser with a pull request ready to create. Create and merge that pull request, and `@claude` works in the repository. To stop setup partway through, press Esc. A step already in progress finishes, and no later step starts. The closing message lists what already happened in the repository, such as a pushed branch or a saved secret. If you select the review workflow, Claude posts each review on the pull request itself, as an inline comment on each issue it finds or as one summary comment when it finds none. Claude skips some pull requests, such as drafts. The [review workflow example](#run-a-skill) uses the same skill and lists them. Before v2.1.229, Claude wrote its review only to the workflow run log. To update a review workflow that an earlier version generated, do one of the following:

- Run `/install-github-app` again. When the repository already has a `claude.yml`, select **Update workflow file with latest version**. Claude Code pushes fresh copies of the workflow files to a new branch and opens the pull request, the same as a first install.
- Add the `--comment` argument and the `claude_args` line from the [review workflow example](#run-a-skill) to the checked-in file yourself, which keeps any other edits you made to it.

After installing the GitHub App, Claude Code asks whether to continue with GitHub Actions setup. Choose **Skip for now** to stop with only the GitHub App installed. Run `/install-github-app` again later to finish the workflow and secret steps.

- When you install the GitHub App, you grant it several permissions. See [GitHub App permissions](#github-app-permissions) for the full set
- Quick setup works with the Claude API and Claude subscriptions. If you use Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry, see [Use Claude Code GitHub Actions with cloud providers](github-actions-cloud-providers.md)


[​](#manual-setup)

Manual setup

To configure the Claude Code GitHub Action without running `/install-github-app`, install the app, add a secret, and copy a workflow file yourself:

1

Install the Claude GitHub App

Install the [Claude GitHub App](https://github.com/apps/claude) to your repository. The Claude Code GitHub Action relies on three of the app’s permissions:

- **Contents**: read and write, so Claude can modify repository files
- **Issues**: read and write, so Claude can respond to issues
- **Pull requests**: read and write, so Claude can create PRs and push changes

During installation, you also grant permissions that other Claude features use. See [GitHub App permissions](#github-app-permissions) for the full set.

2

Add an authentication secret

Add one of the following secrets to your repository, depending on how you authenticate. See GitHub’s guide to [using secrets in GitHub Actions](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions).

- `ANTHROPIC_API_KEY`: a Claude API key from the [Claude Console](../04-API-Reference/Other/playground.md)
- `CLAUDE_CODE_OAUTH_TOKEN`: an OAuth token that authenticates with your Claude subscription, available on Pro, Max, Team, and Enterprise plans. Generate one by running `claude setup-token` locally. See [Generate a long-lived token](authentication.md#generate-a-long-lived-token)

In workflow files, pass the secret to the matching input: `anthropic_api_key` for an API key, or `claude_code_oauth_token` for an OAuth token.

3

Copy the workflow file

Copy [examples/claude.yml](https://github.com/anthropics/claude-code-action/blob/main/examples/claude.yml) into your repository’s `.github/workflows/` directory. The file is a working workflow, not just an example. As committed, Claude responds whenever someone mentions `@claude` in an issue or pull request, authenticating with the `ANTHROPIC_API_KEY` secret. If you added `CLAUDE_CODE_OAUTH_TOKEN` instead, change the workflow’s `anthropic_api_key` line to `claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}`.

After setup, test the Claude Code GitHub Action by tagging `@claude` in an issue or PR comment.


[​](#set-up-for-an-organization)

Set up for an organization

With quick setup or manual setup, you configure one repository at a time. To roll the Claude Code GitHub Action out across an organization:

- Install the [Claude GitHub App](https://github.com/apps/claude) once at the organization level, choosing all repositories or a selected list
- Store the authentication secret as an organization-level Actions secret so each repository doesn’t need its own copy
- Add the workflow file to each repository that should run the Claude Code GitHub Action, or define the job once as a [reusable workflow](https://docs.github.com/en/actions/using-workflows/reusing-workflows) that each repository calls

For a secret shared across repositories, authenticate with an API key from the [Claude Console](../04-API-Reference/Other/playground.md) rather than an OAuth token, since an OAuth token is tied to the subscription of the person who ran `claude setup-token`. To avoid storing a long-lived secret entirely, authenticate through workload identity federation, where the Claude Code GitHub Action exchanges the workflow’s GitHub OpenID Connect (OIDC) token for Claude API access through a Claude Console service account. Set these inputs:

- `anthropic_federation_rule_id`: the federation rule ID, `fdrl_...`
- `anthropic_organization_id`: your Anthropic organization ID
- `anthropic_service_account_id`: the service account ID, `svac_...`. Optional, since the federation rule you create in the Console already targets a service account
- `anthropic_workspace_id`: the workspace ID, `wrkspc_...`. Optional when the federation rule targets a single workspace

Grant the workflow the `id-token: write` permission, which the Claude Code GitHub Action needs for the federation exchange even when you pass your own `github_token`. See the [Claude Code GitHub Action’s setup guide](https://github.com/anthropics/claude-code-action/blob/main/docs/setup.md) for the Console-side configuration. For data handling and retention questions in a security review, see [data usage](../13-Enterprise-Admin/data-usage.md) and [security](../13-Enterprise-Admin/security.md).


[​](#uninstall)

Uninstall

To remove the Claude Code GitHub Action, undo each piece of the setup that applies to your installation:

- **Workflow files**: delete the workflows that use `anthropics/claude-code-action` from `.github/workflows/`. If you used quick setup, look for `claude.yml` and, if you selected the review workflow, `claude-code-review.yml`. With the workflows deleted, the Claude Code GitHub Action no longer runs
- **Secrets**: delete the `ANTHROPIC_API_KEY` or `CLAUDE_CODE_OAUTH_TOKEN` secret from the repository, and from organization-level Actions secrets if you [shared it across repositories](#set-up-for-an-organization). If you delete a secret, the credential it held stays valid. To retire an API key entirely, also delete the key in the [Claude Console](../04-API-Reference/Other/playground.md)
- **GitHub App**: uninstall the Claude GitHub App in your repository or organization settings under GitHub Apps, but only if you don’t use it for another Claude feature, such as Code Review or web auto-fix

If you configured a [cloud provider](github-actions-cloud-providers.md), also delete the provider secrets, such as `AWS_ROLE_TO_ASSUME`, the `GCP_*` secrets, or the `AZURE_*` secrets, and uninstall the custom GitHub App along with its `APP_ID` and `APP_PRIVATE_KEY` secrets.


[​](#github-app-permissions)


The [Claude GitHub App](https://github.com/apps/claude) is shared by every Claude feature that integrates with GitHub, including the Claude Code GitHub Action, [Code Review](code-review.md), and [auto-fix for pull requests](claude-code-on-the-web.md#auto-fix-pull-requests) in cloud sessions. A GitHub App has a single permission set covering all of its features, so the set includes some permissions that the Claude Code GitHub Action doesn’t use. When you install the app, you grant the following permissions:

| Permission       | Access         |
|------------------|----------------|
| Actions          | Read and write |
| Administration   | Read           |
| Checks           | Read and write |
| Contents         | Read and write |
| Discussions      | Read and write |
| Issues           | Read and write |
| Members          | Read           |
| Merge queues     | Read           |
| Metadata         | Read           |
| Pull requests    | Read and write |
| Repository hooks | Read and write |
| Statuses         | Read           |
| Workflows        | Read and write |

The permission set can also change ahead of the features that use it. When the app requests a permission it didn’t have before, GitHub prompts the account owner to approve it, an organization owner for an organization install, and the installation keeps its old permissions until they do. For example, when Actions access changes from read to write, the app can re-run workflows rather than only view runs and logs, so GitHub asks the owner to approve the change. When you install the app, you accept its full permission set. GitHub doesn’t let you accept a subset. If your organization requires only the permissions the Claude Code GitHub Action uses, create a custom GitHub App with Contents, Issues, and Pull requests instead, following the [Claude Code GitHub Action’s setup guide](https://github.com/anthropics/claude-code-action/blob/main/docs/setup.md). A custom app covers only the Claude Code GitHub Action. Code Review and web auto-fix still require the official app. For details on how the Claude Code GitHub Action limits what Claude can do with these permissions, see the [security documentation](https://github.com/anthropics/claude-code-action/blob/main/docs/security.md).


[​](#interactive-and-automation-modes)

Interactive and automation modes

The Claude Code GitHub Action detects how to run from your workflow configuration:

- **Interactive mode**: when the workflow provides no `prompt` input, Claude waits for the trigger phrase, `@claude` by default, in an issue or pull request comment, in a pull request review, or in the body or title of a newly opened issue, then responds to that request. Progress and results appear as a comment on the triggering issue or PR.
- **Automation mode**: when the workflow provides a `prompt` input, Claude runs without waiting for a mention, subject only to the [checks on who can trigger runs](#who-can-trigger-runs). By default, results appear in the workflow run log rather than a comment. Claude can post to the issue or pull request when the prompt directs it to and it has a tool that can post, as in the [code-review example](#run-a-skill).


[​](#who-can-trigger-runs)

Who can trigger runs

In both modes, the Claude Code GitHub Action runs two checks on the triggering actor before Claude starts, and the run fails when either check rejects it:

- **Write access**: on issue and pull request events, the triggering user must have write access to the repository. To allow specific users without write access, set `allowed_non_write_users` and pass your own `github_token` input. Events that no user authors, such as a `schedule` trigger, skip this check.
- **Human actor**: on every event, the Claude Code GitHub Action rejects a bot actor unless you list it in `allowed_bots`, which keeps bots from triggering Claude in a loop. This check also applies to scheduled runs, which GitHub attributes to a repository user, usually the one who last changed the workflow’s `cron` schedule. If that user is a bot, list it in `allowed_bots`.


[​](#example-use-cases)

Example use cases

The [examples directory](https://github.com/anthropics/claude-code-action/tree/main/examples) contains ready-to-use workflows for different scenarios. The examples on this page show API key authentication. If you authenticate with a Claude subscription, replace the `anthropic_api_key` line in any example with `claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}`.


[​](#respond-to-@claude-mentions)

Respond to @claude mentions

This workflow runs the Claude Code GitHub Action in interactive mode, so Claude responds whenever someone mentions `@claude` in an issue or PR comment.

```python
name: Claude Code
on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
jobs:
  claude:
    if: contains(github.event.comment.body, '@claude')
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
      issues: write
      id-token: write
      actions: read
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 1
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
```

The parts of this workflow that aren’t boilerplate:

- `id-token: write`: required for the Claude Code GitHub Action’s default GitHub App authentication
- `actions: read`: lets Claude read CI results on PRs
- `actions/checkout`: gives Claude a local copy of the repository to work in
- `if`: keeps runners from starting on comments that don’t mention `@claude`. The Claude Code GitHub Action also checks the trigger phrase itself before responding

Once the workflow is in place, mention `@claude` in any issue or PR comment with a request:

```python
@claude implement this feature based on the issue description
@claude how should I implement user authentication for this endpoint?
@claude fix the TypeError in the user dashboard component
```

Claude replies in a comment on the same issue or PR and updates it as it works.


[​](#run-a-skill)

Run a skill

The `prompt` input accepts a [skill](../08-Plugins-Skills/skills.md) invocation as well as plain text:

- For a skill in your repository’s `.claude/skills/` directory, run `actions/checkout` before the `anthropics/claude-code-action` step so the skill files are available on the runner, then pass `/skill-name` as the `prompt`.
- For a skill packaged in a [plugin](../08-Plugins-Skills/plugins.md), install the plugin with the `plugin_marketplaces` and `plugins` inputs, then pass the namespaced `/plugin-name:skill-name` as the `prompt`. The `plugins` input takes `plugin-name@marketplace-name`, where the marketplace name comes from the marketplace’s own manifest rather than its repository URL.

The following workflow installs the `code-review` plugin and runs its skill when a pull request is opened, updated, reopened, or marked ready for review. It runs the same plugin as the review workflow from quick setup. Use a workflow like this when you want to control the prompt, model, and triggers yourself. For automatic reviews without maintaining a workflow file, see [Code Review](code-review.md). On public repositories, GitHub withholds secrets from runs triggered by fork pull requests, so the review runs only on pull requests from branches in the same repository.

```python
name: Code Review
on:
  pull_request:
    types: [opened, synchronize, ready_for_review, reopened]
jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: read
      issues: read
      id-token: write
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 1
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          plugin_marketplaces: "https://github.com/anthropics/claude-code.git"
          plugins: "code-review@claude-code-plugins"
          prompt: "/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number }}"
          claude_args: '--allowedTools "mcp__github_inline_comment__create_inline_comment"'
```

Two lines in this workflow control where the review goes:

- **`--comment`**: Claude posts its review on the pull request, as an inline comment on each issue it finds or as one summary comment when it finds none. Without it, Claude posts nothing, and you read the findings in the workflow run log.
- **`claude_args`**: keep this line even though the skill’s own `allowed-tools` frontmatter names the same tool, because the Claude Code GitHub Action starts the MCP server that posts inline comments only when `--allowedTools` in `claude_args` names it.

Claude skips draft and closed pull requests, pull requests it judges not to need a review, such as automated or trivial ones, and pull requests that already have a comment from Claude.


[​](#run-on-a-schedule)

Run on a schedule

With a `prompt` input, the Claude Code GitHub Action runs in automation mode on any GitHub event, including a cron schedule. For a plain-text prompt, Claude has no shell or GitHub API access until you grant the tools the prompt needs, with `--allowedTools` in `claude_args` or a [`permissions.allow` rule](permissions.md#permission-rule-syntax) in the `settings` input. If you invoke a skill instead, Claude can use the tools its [`allowed-tools` frontmatter](../08-Plugins-Skills/skills.md#pre-approve-tools-for-a-skill) grants. GitHub runs scheduled workflows only from the default branch and, in public repositories, disables the schedule after 60 days without repository activity. This workflow generates a report in the workflow run log at 09:00 UTC each day. Its `claude_args` line [passes CLI arguments](#pass-cli-arguments) that select the model and allow two GitHub MCP tools. Claude reads commits and issues through the GitHub API with those tools, so you can omit the checkout step:

```python
name: Daily Report
on:
  schedule:
    - cron: "0 9 * * *"
jobs:
  report:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      issues: read
      id-token: write
    steps:
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          prompt: "Generate a summary of yesterday's commits and open issues"
          claude_args: |
            --model claude-opus-5-5
            --allowedTools "mcp__github__list_commits,mcp__github__list_issues"
```


[​](#best-practices)

Best practices


[​](#define-project-standards-in-claude-md)

Define project standards in CLAUDE.md

Create a `CLAUDE.md` file in your repository root to define code style guidelines, review criteria, project-specific rules, and preferred patterns. Claude follows these guidelines when creating PRs and responding to requests. See the [memory documentation](memory.md) for details.


[​](#protect-your-credentials)

Protect your credentials

Never commit API keys or OAuth tokens directly to your repository. Always store them as GitHub Secrets and reference them in workflows, for example `anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}`.

Grant the workflow only the permissions it needs, and review Claude’s changes before merging. For security guidance including permissions and authentication, see the [Claude Code Action security documentation](https://github.com/anthropics/claude-code-action/blob/main/docs/security.md).


[​](#manage-costs)

Manage costs

Each run consumes two kinds of resources:

- **GitHub Actions minutes**: the Claude Code GitHub Action runs on GitHub-hosted runners, which consume your GitHub Actions minutes. See [GitHub’s billing documentation](https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-actions/about-billing-for-github-actions) for pricing and minute limits.
- **API tokens**: each interaction consumes tokens based on the length of prompts and responses, task complexity, and codebase size. See [Claude’s pricing page](https://claude.com/platform/api) for current token rates. If you authenticate with an OAuth token, runs use your Claude subscription instead of API billing.

You can lower both kinds of cost by giving Claude clearer context and by capping how much work each run can do:

- Write specific `@claude` requests so Claude needs fewer turns to finish
- Use issue templates to provide context up front
- Keep your `CLAUDE.md` concise, since Claude reads it on every run
- Set `--max-turns` in `claude_args` to limit iterations
- Set workflow-level timeouts to avoid runaway jobs
- Use GitHub’s concurrency controls to limit parallel runs

For usage tracking across your organization, see the [analytics dashboard](../13-Enterprise-Admin/analytics.md) and [monitoring](../13-Enterprise-Admin/monitoring-usage.md). For how usage is measured and billed, see [costs](../17-Billing-Plans/costs.md).


[​](#use-a-cloud-provider)

Use a cloud provider

By default, the Claude Code GitHub Action calls the Claude API directly with your API key or OAuth token. To route inference through your own cloud account instead, set the input for your provider and follow [Use Claude Code GitHub Actions with cloud providers](github-actions-cloud-providers.md):

- **Amazon Bedrock**: `use_bedrock: "true"`
- **Google Cloud’s Agent Platform**: `use_vertex: "true"`
- **Microsoft Foundry**: `use_foundry: "true"`

With all three providers, you authenticate through OIDC identity federation instead of a Claude API key, so you store no static cloud credentials in your repository.


[​](#troubleshooting)

Troubleshooting


[​](#claude-not-responding-to-@claude-commands)

Claude not responding to @claude commands

- Verify the GitHub App is installed on the repository
- Check that workflows are enabled for the repository
- Ensure your API key or OAuth token is set in repository secrets
- Confirm the comment contains `@claude` as a complete word, not `/claude` or `@claude-bot`
- Confirm the commenting user has write access to the repository. See [Who can trigger runs](#who-can-trigger-runs) for the exceptions


[​](#ci-not-running-on-claude’s-commits)

CI not running on Claude’s commits

- GitHub doesn’t trigger workflows on commits made with the default `GITHUB_TOKEN`. If you pass `github_token: ${{ secrets.GITHUB_TOKEN }}` to the Claude Code GitHub Action, remove it so it authenticates as the Claude GitHub App, or pass a custom app token instead
- Check that your CI workflow’s triggers include the events Claude’s pushes produce, such as `push` or `pull_request`


[​](#authentication-errors)

Authentication errors

- Confirm the API key or OAuth token is valid by testing it locally with `claude` before debugging the workflow
- For Bedrock, Agent Platform, and Foundry, see the cloud provider page’s [troubleshooting section](github-actions-cloud-providers.md#troubleshooting)

For more solutions, see the Claude Code GitHub Action’s [FAQ](https://github.com/anthropics/claude-code-action/blob/main/docs/faq.md).


[​](#advanced-configuration)

Advanced configuration


[​](#action-parameters)

Action parameters

These are the most commonly used inputs. Each maps to a `with:` key in the `anthropics/claude-code-action` step.

| Parameter                 | Description                                                                                                                                                                       | Required                                                                                                                                                                      |
|---------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `prompt`                  | Instructions for Claude, as plain text or a [skill](../08-Plugins-Skills/skills.md) invocation. When omitted, Claude responds to the [trigger phrase](#interactive-and-automation-modes) instead | No                                                                                                                                                                            |
| `claude_args`             | CLI arguments passed to Claude Code                                                                                                                                               | No                                                                                                                                                                            |
| `anthropic_api_key`       | Claude API key                                                                                                                                                                    | For the Claude API, unless you use `claude_code_oauth_token` or [workload identity federation](#set-up-for-an-organization). Not used for Bedrock, Agent Platform, or Foundry |
| `claude_code_oauth_token` | OAuth token for authenticating with a Claude subscription, generated with `claude setup-token`                                                                                    | No                                                                                                                                                                            |
| `github_token`            | Token for GitHub operations. When omitted, the Claude Code GitHub Action authenticates as the Claude GitHub App                                                                   | No                                                                                                                                                                            |
| `plugin_marketplaces`     | Newline-separated list of plugin marketplace Git URLs                                                                                                                             | No                                                                                                                                                                            |
| `plugins`                 | Newline-separated list of plugin names to install before execution                                                                                                                | No                                                                                                                                                                            |
| `settings`                | Claude Code settings, as a JSON string or a path to a settings JSON file                                                                                                          | No                                                                                                                                                                            |
| `trigger_phrase`          | Trigger phrase Claude responds to. Default: `@claude`                                                                                                                             | No                                                                                                                                                                            |
| `use_bedrock`             | Use Amazon Bedrock instead of the Claude API                                                                                                                                      | No                                                                                                                                                                            |
| `use_vertex`              | Use Google Cloud’s Agent Platform instead of the Claude API                                                                                                                       | No                                                                                                                                                                            |
| `use_foundry`             | Use Microsoft Foundry instead of the Claude API                                                                                                                                   | No                                                                                                                                                                            |

For the full input list, see the Claude Code GitHub Action’s [configuration reference](https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md#inputs).


[​](#pass-cli-arguments)

Pass CLI arguments

The `claude_args` parameter accepts any [Claude Code CLI argument](cli-reference.md):

```python
claude_args: "--max-turns 5 --model claude-sonnet-5 --mcp-config /path/to/config.json"
```

Common arguments:

- `--max-turns`: limit the number of conversation turns
- `--model`: model to use, for example `claude-sonnet-5`. Without this argument, the Claude Code GitHub Action uses the Claude Code [default model](model-config.md)
- `--mcp-config`: path to [MCP configuration](../06-MCP-Tools/General/mcp.md)
- `--allowedTools`: comma-separated list of allowed tools. The `--allowed-tools` alias also works
- `--debug`: enable debug output


[​](#upgrade-from-beta)

Upgrade from beta

If your workflows still reference `anthropics/claude-code-action@beta`, update them to v1:

1.  Change `@beta` to `@v1` in the `uses` line
2.  Remove the `mode` input, since the Claude Code GitHub Action now [detects the mode automatically](#interactive-and-automation-modes)
3.  Replace `direct_prompt` with `prompt`
4.  Move CLI options such as `max_turns` and `model` into `claude_args`. `custom_instructions` has no same-name flag and becomes `--append-system-prompt`

For the full input mapping and before-and-after examples, see the [migration guide](https://github.com/anthropics/claude-code-action/blob/main/docs/migration-guide.md).


[​](#what’s-next)

What’s next

- [Use Claude Code GitHub Actions with cloud providers](github-actions-cloud-providers.md): route inference through Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry
- [Configuration reference](https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md#inputs): the full list of action inputs
- [Examples directory](https://github.com/anthropics/claude-code-action/tree/main/examples): ready-to-use workflows for more scenarios
- [Code Review](code-review.md): automatic pull request review without maintaining a workflow file

---

## Claude Code with GitHub Enterprise Server - Claude Code Docs

Source: https://code.claude.com/docs/en/github-enterprise-server
Path: 02-Claude-Code-CLI/github-enterprise-server.md

## On this page

- [What works with GitHub Enterprise Server](#what-works-with-github-enterprise-server)
- [Admin setup](#admin-setup)
  - [GitHub App permissions](#github-app-permissions)
  - [Manual setup](#manual-setup)
  - [Network requirements](#network-requirements)
- [Developer workflow](#developer-workflow)
  - [Teleport sessions to your terminal](#teleport-sessions-to-your-terminal)
- [Plugin marketplaces on GHES](#plugin-marketplaces-on-ghes)
  - [Add a GHES marketplace](#add-a-ghes-marketplace)
  - [Pre-register GHES marketplaces with managed settings](#pre-register-ghes-marketplaces-with-managed-settings)
  - [Allowlist GHES marketplaces in managed settings](#allowlist-ghes-marketplaces-in-managed-settings)
- [Limitations](#limitations)
- [Troubleshooting](#troubleshooting)
  - [Cloud session fails to clone repository](#cloud-session-fails-to-clone-repository)
  - [Marketplace add fails with a policy error](#marketplace-add-fails-with-a-policy-error)
  - [Marketplace add on claude.ai fails with a GitHub access error](#marketplace-add-on-claude-ai-fails-with-a-github-access-error)
  - [GHES instance not reachable](#ghes-instance-not-reachable)
  - [Session start fails with Unable to get organization UUID](#session-start-fails-with-unable-to-get-organization-uuid)
- [Related resources](#related-resources)

Code review and pull requests

# Claude Code with GitHub Enterprise Server

Copy pageCopy page

Connect Claude Code to your self-hosted GitHub Enterprise Server instance for cloud sessions, code review, and plugin marketplaces.

Copy pageCopy page


[​](#what-works-with-github-enterprise-server)

What works with GitHub Enterprise Server

The table below shows which Claude Code features support GHES and any differences from github.com behavior.

| Feature              | GHES support     | Notes                                                                                                                                             |
|:---------------------|:-----------------|:--------------------------------------------------------------------------------------------------------------------------------------------------|
| Cloud sessions       | ✅ Supported     | An Owner connects the GHES instance once; developers use `claude --cloud` or [claude.ai/code](https://claude.ai/code)                             |
| Code Review          | ✅ Supported     | Same automated PR reviews as github.com                                                                                                           |
| Claude Security      | ✅ Supported     | Available in public beta for Enterprise plans at [claude.ai/security](https://claude.ai/security)                                                 |
| Teleport sessions    | ✅ Supported     | Move sessions between cloud and terminal with `--teleport`                                                                                        |
| Plugin marketplaces  | ✅ Supported     | Credential requirements differ by surface. See [Plugin marketplaces on GHES](#plugin-marketplaces-on-ghes)                                        |
| Contribution metrics | ❌ Not supported | Requires repositories hosted on github.com. The [analytics dashboard](../13-Enterprise-Admin/analytics.md) still shows usage metrics for work in GHES repositories |
| GitHub Actions       | ✅ Supported     | Requires manual workflow setup; `/install-github-app` is github.com only                                                                          |
| GitHub MCP server    | ❌ Not supported | The GitHub MCP server does not work with GHES instances                                                                                           |


[​](#admin-setup)

Admin setup

An Owner connects your GHES instance to Claude Code once. You need the Owner or Primary Owner role in your Claude organization and permission to create GitHub Apps on your GHES instance. The guided setup generates a GitHub App manifest and redirects you to your GHES instance to create the app in one click. If your environment blocks the redirect flow, an [alternative manual setup](#manual-setup) is available.

1

Open Git providers settings

Go to [**Organization settings \> Git providers**](https://claude.ai/admin-settings/source-control#github-enterprise) and find the GitHub Enterprise section.

2

Start the guided setup

Click **Connect**, or **Add instance** if an instance is already connected, then select **Set up automatically**. Enter a display name of up to 20 characters for the connection and your GHES hostname, for example `github.example.com`. If your GHES instance uses a self-signed or private certificate authority, paste the CA certificate in the optional field.

3

Create the GitHub App

Click **Continue to GitHub Enterprise**. Your browser redirects to your GHES instance with a pre-filled app manifest. Review the configuration and click **Create GitHub App**. GHES redirects you back to Claude with the app credentials stored automatically.

4

Install the app on your repositories

From the GitHub App page on your GHES instance, install the app on the repositories or organizations you want Claude to access. You can start with a subset and add more later.

5

Enable Code Review

Go to [claude.ai/admin-settings/claude-code](https://claude.ai/admin-settings/claude-code) and enable [Code Review](code-review-setup.md) for your GHES repositories using the same configuration as github.com.


[​](#github-app-permissions)


The manifest configures the GitHub App with the permissions and webhook events below, which together cover cloud sessions, Code Review, Claude Security, and plugin marketplaces:

| Permission           | Access         | Used for                                                                                                                                                                                                                      |
|:---------------------|:---------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Contents             | Read and write | Cloning repositories and pushing branches                                                                                                                                                                                     |
| Pull requests        | Read and write | Creating PRs and posting review comments                                                                                                                                                                                      |
| Issues               | Read and write | Responding to issue mentions                                                                                                                                                                                                  |
| Checks               | Read and write | Posting Code Review check runs                                                                                                                                                                                                |
| Actions              | Read           | Reading CI status for auto-fix                                                                                                                                                                                                |
| Commit statuses      | Read           | Reading CI status from providers that report commit statuses instead of check runs                                                                                                                                            |
| Repository hooks     | Read and write | Creating a webhook on a plugin marketplace repository when **Sync automatically** is turned on for a marketplace in [**Organization settings \> Plugins & skills**](https://claude.ai/admin-settings/skills?tab=marketplaces) |
| Metadata             | Read           | Required by GitHub for all apps                                                                                                                                                                                               |
| Organization members | Read           | Matching the Claude GitHub App on github.com, which uses it to check a connecting user’s organization role when linking an installation                                                                                       |

The app subscribes to `pull_request`, `issue_comment`, `pull_request_review_comment`, `pull_request_review`, `check_run`, and `status` events. GitHub applies a manifest only when the app is created, so an app created from an earlier version of the manifest keeps the permissions and events it was created with. If your app is missing any of the permissions or events above, add them in the app’s settings on your GHES instance. GitHub then asks an owner of each installation to approve the new permissions, and the installation keeps its old permissions until they do.


[​](#manual-setup)

Manual setup

If the guided redirect flow is blocked by your network configuration, click **Connect** or **Add instance**, then select **Add manually** instead of **Set up automatically**. Create a GitHub App on your GHES instance with the [permissions and events above](#github-app-permissions), then enter the connection details in the form: a display name, your GHES hostname and optional port, and the app’s ID, client ID, client secret, webhook secret, and private key. The form also accepts an optional custom CA certificate and read replica hostnames. Claude generates the app’s webhook URL when you save the connection. After you click **Add configuration**, open the connection’s **More options** menu, select **Copy webhook URL**, and paste the URL into the app’s webhook settings on your GHES instance. Use the same webhook secret you entered in the form.


[​](#network-requirements)

Network requirements

For Anthropic-hosted sessions, your GHES instance must be reachable from Anthropic infrastructure so Claude can clone repositories and post review comments. If your GHES instance is behind a firewall, allowlist Anthropic’s [outbound IP addresses](../04-API-Reference/Endpoints/ip-addresses.md#outbound-ip-addresses). Sessions in a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments-deploy.md#configure-git) clone from inside your network instead, unless the runner opts into the [Anthropic git proxy](../13-Enterprise-Admin/self-hosted-environments-deploy.md#use-the-anthropic-git-proxy), which fetches from Anthropic’s side and needs the same reachability. Hosted pre-session flows, such as the repository picker, run on Anthropic’s side before a session starts. They need your GHES instance to be reachable from Anthropic infrastructure even when the session runs in a self-hosted environment. The [SCM connector](../13-Enterprise-Admin/self-hosted-environments-reference.md#scm-connector-flags) isn’t available, so those flows can’t reach a GHES host that’s only routable internally.


[​](#developer-workflow)

Developer workflow

Claude Code detects your GHES hostname automatically from the git remote in your working directory. Clone a repository from your GHES instance as you normally would, replacing `github.example.com` and the repository path with your GHES hostname and repository:

```python
git clone git@github.example.com:platform/api-service.git
cd api-service
```

Then start a cloud session. Claude detects the GHES host from your git remote and routes the session through your organization’s configured instance:

```python
claude --cloud "Add retry logic to the payment webhook handler"
```

The session clones your repository from GHES and pushes changes back to a branch. Monitor progress at [claude.ai/code](https://claude.ai/code). See [Use Claude Code in the cloud](claude-code-on-the-web.md) for the full cloud session workflow including diff review, auto-fix, and cloud scheduled tasks.


[​](#teleport-sessions-to-your-terminal)

Teleport sessions to your terminal

Pull a cloud session into your local terminal with `claude --teleport`. Teleport verifies you’re in a checkout of the same GHES repository before fetching the branch and loading the session history. See [teleport requirements](claude-code-on-the-web.md#teleport-requirements) for details.


[​](#plugin-marketplaces-on-ghes)

Plugin marketplaces on GHES

Host plugin marketplaces on your GHES instance to distribute internal tooling across your organization. The marketplace structure is identical to github.com-hosted marketplaces, but installation works differently depending on where you add the marketplace, and credentials differ across surfaces:

| Surface                                     | How installation works                                                                                                                                                                                                               | What each user needs                                                                                                                                                                                      |
|:--------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Claude Code CLI and desktop                 | Claude Code clones the marketplace repository using the machine’s existing git credentials                                                                                                                                           | Git access to your GHES host from their machine                                                                                                                                                           |
| Managed settings (`extraKnownMarketplaces`) | Claude Code registers the entry and clones the repository using the machine’s existing git credentials                                                                                                                               | Git access to your GHES host from their machine                                                                                                                                                           |
| claude.ai organization plugin settings      | An Owner selects the GHES instance as the source; Anthropic’s backend fetches and syncs the repository using the GitHub App from [admin setup](#admin-setup)                                                                         | Nothing per user once added. The Owner adding it needs their own GitHub Enterprise account connected as an access check, and the GitHub App must be installed on the marketplace repository               |
| claude.ai user settings                     | Anthropic’s backend fetches the repository using the submitting user’s GitHub Enterprise connection                                                                                                                                  | Their own GitHub Enterprise account connected to Claude                                                                                                                                                   |
| Cloud sessions                              | Cloud sessions clone marketplaces inside the session sandbox. The sandbox can reach your GHES instance only when the session’s repository is on that same instance, and its git credentials are scoped to the session’s repositories | Not reliable for GHES-hosted marketplaces: a different host than the session’s repository is not reachable, and even same-instance installs can fail. Use the CLI, managed settings, or claude.ai instead |


[​](#add-a-ghes-marketplace)

Add a GHES marketplace

The `owner/repo` shorthand always resolves to github.com. For GHES-hosted marketplaces, use the full git URL, replacing `github.example.com` and the repository path with your own. HTTPS URLs are recommended:

```python
/plugin marketplace add https://github.example.com/platform/claude-plugins.git
```

SSH URLs work if the machine already trusts your GHES host:

```python
/plugin marketplace add git@github.example.com:platform/claude-plugins.git
```

Claude Code runs git non-interactively and rejects SSH connections to hosts that are not in the machine’s `known_hosts` file. An HTTPS URL with a git credential helper avoids the `known_hosts` requirement. See [Create and distribute a plugin marketplace](../08-Plugins-Skills/plugin-marketplaces.md) for the full guide to building marketplaces.


[​](#pre-register-ghes-marketplaces-with-managed-settings)

Pre-register GHES marketplaces with managed settings

The `extraKnownMarketplaces` setting pre-registers a marketplace so developers get it without manual setup. It works from [any settings file](settings-reference.md#extraknownmarketplaces), including a repository’s `.claude/settings.json`; managed settings deliver it organization-wide:

```python
{
  "extraKnownMarketplaces": {
    "internal-tools": {
      "source": {
        "source": "git",
        "url": "https://github.example.com/platform/claude-plugins.git"
      }
    }
  }
}
```

Claude Code installs these marketplaces locally: it registers each entry and clones the repository with the machine’s existing git credentials. This path does not go through claude.ai, so the per-user GitHub Enterprise connection is not required. For a successful rollout:

- **Use a full git URL.** The `owner/repo` shorthand always resolves to github.com and cannot reference a GHES host.
- **Prefer HTTPS URLs.** SSH clones fail on machines that do not already trust your GHES host key. An HTTPS URL with your organization’s standard git credential helper works on any machine with credentials configured.
- **Confirm each machine can clone from your GHES host.** If a machine lacks credentials, the marketplace is registered but never installed, and its plugins report as not found instead of prompting for credentials.
- **Confirm the setting reaches each machine.** A managed settings file only takes effect on machines it’s deployed to, for example through your device management system. See [Deploy managed settings](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms) for file locations.


[​](#allowlist-ghes-marketplaces-in-managed-settings)

Allowlist GHES marketplaces in managed settings

If your organization uses [managed settings](settings.md) to restrict which marketplaces developers can add, use the `hostPattern` source type to allow all marketplaces from your GHES instance without enumerating each repository. See [Delivery mechanisms](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms) for file locations on each platform. Add the JSON to your `managed-settings.json` file or equivalent MDM policy:

```python
{
  "strictKnownMarketplaces": [
    {
      "source": "hostPattern",
      "hostPattern": "^github\\.example\\.com$"
    }
  ]
}
```

See the [strictKnownMarketplaces](settings-reference.md#strictknownmarketplaces) and [extraKnownMarketplaces](settings-reference.md#extraknownmarketplaces) settings reference for the complete schema.


[​](#limitations)

Limitations

A few features behave differently on GHES than on github.com. The [feature table](#what-works-with-github-enterprise-server) summarizes support; this section covers the workarounds.

- **`/install-github-app` command**: follow the [admin setup](#admin-setup) flow on claude.ai instead. If you also want GitHub Actions workflows on GHES, adapt the [example workflow](https://github.com/anthropics/claude-code-action/blob/main/examples/claude.yml) manually.
- **GitHub MCP server**: use the `gh` CLI configured for your GHES host instead. Run `gh auth login --hostname github.example.com` to authenticate, then Claude can use `gh` commands in sessions.


[​](#troubleshooting)

Troubleshooting


[​](#cloud-session-fails-to-clone-repository)

Cloud session fails to clone repository

If `claude --cloud` fails with a clone error, verify that an Owner has completed setup for your GHES instance and that the GitHub App is installed on the repository you’re working in. Ask the Owner who connected the instance to confirm that the hostname registered in Claude settings matches the hostname in your git remote. If the session stops with “Authentication failed while accessing the repository”, you may not have connected your own GitHub Enterprise account. Connect it from the repository picker on [claude.ai/code](https://claude.ai/code), then start a new session.


[​](#marketplace-add-fails-with-a-policy-error)

Marketplace add fails with a policy error

If `/plugin marketplace add` is blocked for your GHES URL, your organization has restricted marketplace sources. Ask your admin to add a `hostPattern` entry for your GHES hostname in [managed settings](#allowlist-ghes-marketplaces-in-managed-settings).


[​](#marketplace-add-on-claude-ai-fails-with-a-github-access-error)

Marketplace add on claude.ai fails with a GitHub access error

If adding a GHES marketplace from your user settings fails with a generic error like “Marketplace couldn’t be added”, check your GitHub Enterprise connection first. This is what appears when your own GitHub Enterprise account is not connected to Claude, even if your organization’s GHES instance is configured and other users are connected. The dialog does not point to the GitHub Enterprise connect flow, and the “Connect to GitHub” option on the Browse tab signs in to github.com, which does not grant access to GHES repositories. Connect your GitHub Enterprise account in one of these places, then add the marketplace again:

- **Repository picker**: on [claude.ai/code](https://claude.ai/code), the repository picker offers a connect option for each configured GHES instance.
- **Git providers page**: if you’re an Owner, go to the GitHub section of [**Organization settings \> Git providers**](https://claude.ai/admin-settings/source-control) and click **Connect**, or **Add organization** once an account is connected. Select the GHES hostname under **GitHub instance**, then click **Connect**.

Alternatively, ask an Owner to add the marketplace in the organization plugin settings, which removes the per-user connection requirement. On other claude.ai surfaces, a “Repository not found. If it’s private, GitHub access is required” error on a GHES marketplace usually indicates the same missing connection. Connect your GitHub Enterprise account through one of the paths above, then try again.


[​](#ghes-instance-not-reachable)

GHES instance not reachable

If reviews or Anthropic-hosted cloud sessions time out, your GHES instance may not be reachable from Anthropic infrastructure. Confirm your firewall allows inbound connections from Anthropic’s [outbound IP addresses](../04-API-Reference/Endpoints/ip-addresses.md#outbound-ip-addresses). Sessions in a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) reach GHES from inside your network, so when one of them can’t clone, check the runner’s own network path instead. For the repository picker and other hosted pre-session flows, see [Network requirements](#network-requirements).


[​](#session-start-fails-with-unable-to-get-organization-uuid)

Session start fails with `Unable to get organization UUID`

Claude Code couldn’t read a claude.ai organization from your credentials. Sign in with `/login` using an account in your Team or Enterprise organization, since GitHub Enterprise Server support is limited to those plans. See [Unable to get organization UUID](claude-code-on-the-web.md#unable-to-get-organization-uuid) for the causes and the other messages this state produces.


[​](#related-resources)

Related resources

These pages cover the features referenced throughout this guide in more depth:

- [Use Claude Code in the cloud](claude-code-on-the-web.md): run Claude Code sessions on cloud infrastructure
- [Code Review](code-review.md): automated PR reviews
- [Plugin marketplaces](../08-Plugins-Skills/plugins-host-marketplace.md): build and distribute plugin catalogs
- [Analytics](../13-Enterprise-Admin/analytics.md): track Claude Code usage across your organization
- [Managed settings](settings.md): organization-wide policy configuration
- [Network configuration](../13-Enterprise-Admin/network-config.md): firewall and IP allowlist requirements

---

## Claude Code GitLab CI/CD - Claude Code Docs

Source: https://code.claude.com/docs/en/gitlab-ci-cd
Path: 02-Claude-Code-CLI/gitlab-ci-cd.md

## On this page

- [Why use Claude Code with GitLab?](#why-use-claude-code-with-gitlab)
- [How it works](#how-it-works)
- [What can Claude do?](#what-can-claude-do)
- [Setup](#setup)
  - [Quick setup](#quick-setup)
  - [Manual setup (recommended for production)](#manual-setup-recommended-for-production)
- [Example use cases](#example-use-cases)
  - [Turn issues into MRs](#turn-issues-into-mrs)
  - [Get implementation help](#get-implementation-help)
  - [Fix bugs quickly](#fix-bugs-quickly)
- [Using with Amazon Bedrock and Google Cloud](#using-with-amazon-bedrock-and-google-cloud)
- [Configuration examples](#configuration-examples)
  - [Amazon Bedrock job example (OIDC)](#amazon-bedrock-job-example-oidc)
  - [Agent Platform job example (Workload Identity Federation)](#agent-platform-job-example-workload-identity-federation)
- [Best practices](#best-practices)
  - [CLAUDE.md configuration](#claude-md-configuration)
  - [Security considerations](#security-considerations)
  - [Optimizing performance](#optimizing-performance)
  - [CI costs](#ci-costs)
- [Troubleshooting](#troubleshooting)
  - [Claude not responding to @claude commands](#claude-not-responding-to-%40claude-commands)
  - [Job can’t write comments or open MRs](#job-can%E2%80%99t-write-comments-or-open-mrs)
  - [Authentication errors](#authentication-errors)
- [Advanced configuration](#advanced-configuration)
  - [Common parameters and variables](#common-parameters-and-variables)
  - [Customizing Claude’s behavior](#customizing-claude%E2%80%99s-behavior)

Code review & CI/CD

# Claude Code GitLab CI/CD

Copy pageCopy page

Learn about integrating Claude Code into your development workflow with GitLab CI/CD

Copy pageCopy page

Claude Code for GitLab CI/CD is currently in beta. Features and functionality may evolve as we refine the experience.This integration is maintained by GitLab. For support, see the following [GitLab issue](https://gitlab.com/gitlab-org/gitlab/-/issues/573776).

This integration is built on top of the [Claude Code CLI and Agent SDK](../05-Agent-SDK/agent-sdk-overview.md), enabling programmatic use of Claude in your CI/CD jobs and custom automation workflows.


[​](#why-use-claude-code-with-gitlab)

Why use Claude Code with GitLab?

- **Instant MR creation**: Describe what you need, and Claude proposes a complete MR with changes and explanation
- **Automated implementation**: Turn issues into working code with a single command or mention
- **Project-aware**: Claude follows your `CLAUDE.md` guidelines and existing code patterns
- **Simple setup**: Add one job to `.gitlab-ci.yml` and a masked CI/CD variable
- **Enterprise-ready**: Choose Claude API, Amazon Bedrock, or Google Cloud’s Agent Platform to meet data residency and procurement needs
- **Secure by default**: Runs in your GitLab runners with your branch protection and approvals


[​](#how-it-works)

How it works

Claude Code uses GitLab CI/CD to run AI tasks in isolated jobs and commit results back via MRs:

1.  **Event-driven orchestration**: GitLab listens for your chosen triggers (for example, a comment that mentions `@claude` in an issue, MR, or review thread). The job collects context from the thread and repository, builds prompts from that input, and runs Claude Code.
2.  **Provider abstraction**: Use the provider that fits your environment:
    - Claude API (SaaS)
    - Amazon Bedrock (IAM-based access, cross-region options)
    - Google Cloud’s Agent Platform (GCP-native, Workload Identity Federation)
3.  **Sandboxed execution**: Each interaction runs in a container with strict network and filesystem rules. Claude Code enforces workspace-scoped permissions to constrain writes. Every change flows through an MR so reviewers see the diff and approvals still apply.

Pick regional endpoints to reduce latency and meet data-sovereignty requirements while using existing cloud agreements.


[​](#what-can-claude-do)

What can Claude do?

In a GitLab pipeline, Claude Code can:

- Create and update MRs from issue descriptions or comments
- Analyze performance regressions and propose optimizations
- Implement features directly in a branch, then open an MR
- Fix bugs and regressions identified by tests or comments
- Respond to follow-up comments to iterate on requested changes


[​](#setup)

Setup


[​](#quick-setup)

Quick setup

The fastest way to get started is to add a minimal job to your `.gitlab-ci.yml` and set your API key as a masked variable.

1.  **Add a masked CI/CD variable**
    - Go to **Settings** → **CI/CD** → **Variables**
    - Add `ANTHROPIC_API_KEY` (masked, protected as needed)
2.  **Add a Claude job to `.gitlab-ci.yml`**

```python
stages:
  - ai

claude:
  stage: ai
  image: node:24-alpine3.21
  # Adjust rules to fit how you want to trigger the job:
  # - manual runs
  # - merge request events
  # - web/API triggers when a comment contains '@claude'
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
  variables:
    GIT_STRATEGY: fetch
  before_script:
    - apk update
    - apk add --no-cache git curl bash
    - curl -fsSL https://claude.ai/install.sh | bash
    # The installer places claude in ~/.local/bin, which isn't on PATH in this image
    - export PATH="$HOME/.local/bin:$PATH"
  script:
    # Optional: start a GitLab MCP server if your setup provides one
    - /bin/gitlab-mcp-server || true
    # Use AI_FLOW_* variables when invoking via web/API triggers with context payloads
    - echo "$AI_FLOW_INPUT for $AI_FLOW_CONTEXT on $AI_FLOW_EVENT"
    - >
      claude
      -p "${AI_FLOW_INPUT:-'Review this MR and implement the requested changes'}"
      --permission-mode acceptEdits
      --allowedTools "Bash Read Edit Write mcp__gitlab"
      --debug
```

After adding the job and your `ANTHROPIC_API_KEY` variable, test by running the job manually from **CI/CD** → **Pipelines**, or trigger it from an MR to let Claude propose updates in a branch and open an MR if needed.

To run on Amazon Bedrock or Google Cloud’s Agent Platform instead of the Claude API, see the [Using with Amazon Bedrock and Google Cloud](#using-with-amazon-bedrock-and-google-cloud) section below for authentication and environment setup.


[​](#manual-setup-recommended-for-production)

Manual setup (recommended for production)

If you prefer a more controlled setup or need enterprise providers:

1.  **Configure provider access**:
    - **Claude API**: Create and store `ANTHROPIC_API_KEY` as a masked CI/CD variable
    - **Amazon Bedrock**: **Configure GitLab** → **AWS OIDC** and create an IAM role for Amazon Bedrock
    - **Google Cloud’s Agent Platform**: **Configure Workload Identity Federation for GitLab** → **GCP**
2.  **Add project credentials for GitLab API operations**:
    - Use `CI_JOB_TOKEN` by default, or create a Project Access Token with `api` scope
    - Store as `GITLAB_ACCESS_TOKEN` (masked) if using a PAT
3.  **Add the Claude job to `.gitlab-ci.yml`**: use the [Quick setup](#quick-setup) job for the Claude API, or a provider job from [Configuration examples](#configuration-examples)
4.  **(Optional) Enable mention-driven triggers**:
    - Add a project webhook for “Comments (notes)” to your event listener (if you use one)
    - Have the listener call the pipeline trigger API with variables like `AI_FLOW_INPUT` and `AI_FLOW_CONTEXT` when a comment contains `@claude`


[​](#example-use-cases)

Example use cases


[​](#turn-issues-into-mrs)

Turn issues into MRs

In an issue comment:

```python
@claude implement this feature based on the issue description
```

Claude analyzes the issue and codebase, writes changes in a branch, and opens an MR for review.


[​](#get-implementation-help)

Get implementation help

In an MR discussion:

```python
@claude suggest a concrete approach to cache the results of this API call
```

Claude proposes changes, adds code with appropriate caching, and updates the MR.


[​](#fix-bugs-quickly)

Fix bugs quickly

In an issue or MR comment:

```python
@claude fix the TypeError in the user dashboard component
```

Claude locates the bug, implements a fix, and updates the branch or opens a new MR.


[​](#using-with-amazon-bedrock-and-google-cloud)

Using with Amazon Bedrock and Google Cloud

For enterprise environments, you can run Claude Code entirely on your cloud infrastructure with the same developer experience.

- Amazon Bedrock

- Google Cloud's Agent Platform


[​](#prerequisites)

Prerequisites

Before setting up Claude Code with Amazon Bedrock, you need:

1.  An AWS account with Amazon Bedrock access to the desired Claude models
2.  GitLab configured as an OIDC identity provider in AWS IAM
3.  An IAM role with Amazon Bedrock permissions and a trust policy restricted to your GitLab project/refs
4.  GitLab CI/CD variables for role assumption:
    - `AWS_ROLE_TO_ASSUME` (role ARN)
    - `AWS_REGION` (Amazon Bedrock region)


[​](#setup-instructions)

Setup instructions

Configure AWS to allow GitLab CI jobs to assume an IAM role via OIDC (no static keys).**Required setup:**

1.  Enable Amazon Bedrock and request access to your target Claude models
2.  Create an IAM OIDC provider for GitLab if not already present
3.  Create an IAM role trusted by the GitLab OIDC provider, restricted to your project and protected refs
4.  Attach least-privilege permissions for Amazon Bedrock invoke APIs

Use the [Amazon Bedrock job example](#configuration-examples) to exchange the job’s OIDC token for temporary AWS credentials at runtime.


[​](#prerequisites-2)

Prerequisites

Before setting up Claude Code with Google Cloud’s Agent Platform, you need:

1.  A Google Cloud project with:
    - Google Cloud’s Agent Platform API enabled
    - Workload Identity Federation configured to trust GitLab OIDC
2.  A dedicated service account with only the required Google Cloud’s Agent Platform roles
3.  GitLab CI/CD variables:
    - `GCP_WORKLOAD_IDENTITY_PROVIDER` (provider resource name without the `//iam.googleapis.com/` prefix, such as `projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider`)
    - `GCP_SERVICE_ACCOUNT` (service account email)
    - `GCP_PROJECT_ID` (Google Cloud project ID)


[​](#setup-instructions-2)

Setup instructions

Configure Google Cloud to allow GitLab CI jobs to impersonate a service account via Workload Identity Federation.**Required setup:**

1.  Enable IAM Credentials API, STS API, and Google Cloud’s Agent Platform API
2.  Create a Workload Identity Pool and provider for GitLab OIDC
3.  Create a dedicated service account with Google Cloud’s Agent Platform roles
4.  Grant the WIF principal permission to impersonate the service account

Use the [Agent Platform job example](#configuration-examples) to authenticate without storing keys.


[​](#configuration-examples)

Configuration examples

Below are ready-to-use snippets you can adapt to your pipeline.


[​](#amazon-bedrock-job-example-oidc)

Amazon Bedrock job example (OIDC)

**Prerequisites:**

- Amazon Bedrock enabled with access to your chosen Claude model(s)
- GitLab OIDC configured in AWS with a role that trusts your GitLab project and refs
- IAM role with Amazon Bedrock permissions (least privilege recommended)

**Required CI/CD variables:**

- `AWS_ROLE_TO_ASSUME`: ARN of the IAM role for Amazon Bedrock access
- `AWS_REGION`: Amazon Bedrock region (for example, `us-west-2`)

GitLab mints the job’s OIDC token from the `id_tokens:` block and exposes it as `GITLAB_OIDC_TOKEN`. Set `aud` to the audience value you configured on the IAM OIDC identity provider in AWS, for example your GitLab instance URL.

```python
stages:
  - ai

claude-bedrock:
  stage: ai
  image: node:24-alpine3.21
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.example.com
  before_script:
    - apk add --no-cache bash curl jq git aws-cli
    - curl -fsSL https://claude.ai/install.sh | bash
    # The installer places claude in ~/.local/bin, which isn't on PATH in this image
    - export PATH="$HOME/.local/bin:$PATH"
    # Exchange the job's OIDC token for AWS credentials
    - export AWS_WEB_IDENTITY_TOKEN_FILE="/tmp/oidc_token"
    - printf "%s" "$GITLAB_OIDC_TOKEN" > "$AWS_WEB_IDENTITY_TOKEN_FILE"
    - >
      aws sts assume-role-with-web-identity
      --role-arn "$AWS_ROLE_TO_ASSUME"
      --role-session-name "gitlab-claude-$(date +%s)"
      --web-identity-token "file://$AWS_WEB_IDENTITY_TOKEN_FILE"
      --duration-seconds 3600 > /tmp/aws_creds.json
    - export AWS_ACCESS_KEY_ID="$(jq -r .Credentials.AccessKeyId /tmp/aws_creds.json)"
    - export AWS_SECRET_ACCESS_KEY="$(jq -r .Credentials.SecretAccessKey /tmp/aws_creds.json)"
    - export AWS_SESSION_TOKEN="$(jq -r .Credentials.SessionToken /tmp/aws_creds.json)"
  script:
    - /bin/gitlab-mcp-server || true
    - >
      claude
      -p "${AI_FLOW_INPUT:-'Implement the requested changes and open an MR'}"
      --permission-mode acceptEdits
      --allowedTools "Bash Read Edit Write mcp__gitlab"
      --debug
  variables:
    AWS_REGION: "us-west-2"
    CLAUDE_CODE_USE_BEDROCK: "1"
```

Model IDs for Amazon Bedrock include region-specific prefixes (for example, `us.anthropic.claude-sonnet-4-6`). Pass the desired model via your job configuration or prompt if your workflow supports it.


[​](#agent-platform-job-example-workload-identity-federation)

Agent Platform job example (Workload Identity Federation)

**Prerequisites:**

- Google Cloud’s Agent Platform API enabled in your GCP project
- Workload Identity Federation configured to trust GitLab OIDC
- A service account with Google Cloud’s Agent Platform permissions

**Required CI/CD variables:**

- `GCP_WORKLOAD_IDENTITY_PROVIDER`: provider resource name without the `//iam.googleapis.com/` prefix, such as `projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider`
- `GCP_SERVICE_ACCOUNT`: service account email
- `GCP_PROJECT_ID`: Google Cloud project ID
- `CLOUD_ML_REGION`: Google Cloud’s Agent Platform region (for example, `us-east5`)

GitLab mints the job’s OIDC token from the `id_tokens:` block and exposes it as `GITLAB_OIDC_TOKEN`. Set `aud` to the audience value you configured on the Workload Identity Pool provider, for example your GitLab instance URL. The job writes the token to a file, and the credential configuration’s `credential_source` entry tells Google’s auth libraries to read it from there. Setting `GOOGLE_APPLICATION_CREDENTIALS` to the credential configuration file makes it available to Claude Code through [Application Default Credentials](google-vertex-ai.md#3-configure-gcp-credentials).

```python
stages:
  - ai

claude-vertex:
  stage: ai
  image: gcr.io/google.com/cloudsdktool/google-cloud-cli:slim
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.example.com
  before_script:
    - apt-get update && apt-get install -y git && apt-get clean
    - curl -fsSL https://claude.ai/install.sh | bash
    # The installer places claude in ~/.local/bin, which isn't on PATH in this image
    - export PATH="$HOME/.local/bin:$PATH"
    # Write the job's OIDC token where credential_source expects it
    - printf "%s" "$GITLAB_OIDC_TOKEN" > /tmp/oidc_token
    # Write the WIF credential configuration to a file (no downloaded keys)
    - |
      cat > /tmp/cred.json <<EOF
      {
        "type": "external_account",
        "audience": "//iam.googleapis.com/${GCP_WORKLOAD_IDENTITY_PROVIDER}",
        "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
        "token_url": "https://sts.googleapis.com/v1/token",
        "credential_source": {
          "file": "/tmp/oidc_token"
        },
        "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${GCP_SERVICE_ACCOUNT}:generateAccessToken"
      }
      EOF
    # Expose the credentials to Claude Code via Application Default Credentials
    - export GOOGLE_APPLICATION_CREDENTIALS=/tmp/cred.json
    # Authenticate the gcloud CLI with the same credential configuration
    - gcloud auth login --cred-file=/tmp/cred.json
    - gcloud config set project "$GCP_PROJECT_ID"
  script:
    - /bin/gitlab-mcp-server || true
    - >
      CLOUD_ML_REGION="${CLOUD_ML_REGION:-us-east5}"
      claude
      -p "${AI_FLOW_INPUT:-'Review and update code as requested'}"
      --permission-mode acceptEdits
      --allowedTools "Bash Read Edit Write mcp__gitlab"
      --debug
  variables:
    CLOUD_ML_REGION: "us-east5"
    CLAUDE_CODE_USE_VERTEX: "1"
    ANTHROPIC_VERTEX_PROJECT_ID: "$GCP_PROJECT_ID"
```

With Workload Identity Federation, you do not need to store service account keys. Use repository-specific trust conditions and least-privilege service accounts.


[​](#best-practices)

Best practices


[​](#claude-md-configuration)

CLAUDE.md configuration

Create a `CLAUDE.md` file at the repository root to define coding standards, review criteria, and project-specific rules. Claude reads this file during runs and follows your conventions when proposing changes.


[​](#security-considerations)

Security considerations

**Never commit API keys or cloud credentials to your repository**. Always use GitLab CI/CD variables:

- Add `ANTHROPIC_API_KEY` as a masked variable (and protect it if needed)
- Use provider-specific OIDC where possible (no long-lived keys)
- Limit job permissions and network egress
- Review Claude’s MRs like any other contributor


[​](#optimizing-performance)

Optimizing performance

- Keep `CLAUDE.md` focused and concise
- Provide clear issue/MR descriptions to reduce iterations
- Cache npm and package installs in runners where possible


[​](#ci-costs)

CI costs

When using Claude Code with GitLab CI/CD, be aware of associated costs:

- **GitLab Runner time**:
  - Claude runs on your GitLab runners and consumes compute minutes
  - See your GitLab plan’s runner billing for details
- **API costs**:
  - Each Claude interaction consumes tokens based on prompt and response size
  - Token usage varies by task complexity and codebase size
  - See [Anthropic pricing](../17-Billing-Plans/about-claude-pricing.md) for details
- **Cost optimization tips**:
  - Use specific `@claude` commands to reduce unnecessary turns
  - Set appropriate `--max-turns` and job `timeout` values
  - Limit concurrency to control parallel runs


[​](#troubleshooting)

Troubleshooting


[​](#claude-not-responding-to-@claude-commands)

Claude not responding to @claude commands

- Verify your pipeline is being triggered (manually, MR event, or via a note event listener/webhook)
- Ensure your `ANTHROPIC_API_KEY` or cloud provider variables are present
- Check that the comment contains `@claude` (not `/claude`) and that your mention trigger is configured


[​](#job-can’t-write-comments-or-open-mrs)

Job can’t write comments or open MRs

- Ensure `CI_JOB_TOKEN` has sufficient permissions for the project, or use a Project Access Token with `api` scope
- Check the `mcp__gitlab` tool is enabled in `--allowedTools`
- Confirm the job runs in the context of the MR or has enough context via `AI_FLOW_*` variables


[​](#authentication-errors)

Authentication errors

- **For Claude API**: Confirm `ANTHROPIC_API_KEY` is valid and unexpired
- **For Amazon Bedrock or Google Cloud’s Agent Platform**: Verify OIDC/WIF configuration, role impersonation, and secret names; confirm region and model availability


[​](#advanced-configuration)

Advanced configuration


[​](#common-parameters-and-variables)

Common parameters and variables

Control Claude Code runs in your jobs with these CLI flags, GitLab keywords, and variables:

- `-p`: provide instructions inline, for example `claude -p "Review this MR"`
- `--max-turns`: limit the number of back-and-forth iterations
- `timeout`: limit total job execution time with GitLab’s job-level `timeout` keyword, for example `timeout: 30m`
- `ANTHROPIC_API_KEY`: required for the Claude API (not used for Amazon Bedrock or Google Cloud’s Agent Platform)
- Provider-specific environment: `AWS_REGION`, project/region vars for Google Cloud’s Agent Platform

Exact flags and parameters may vary by version of `@anthropic-ai/claude-code`. Run `claude --help` in your job to see supported options.


[​](#customizing-claude’s-behavior)

Customizing Claude’s behavior

You can guide Claude in two primary ways:

1.  **CLAUDE.md**: Define coding standards, security requirements, and project conventions. Claude reads this during runs and follows your rules.
2.  **Custom prompts**: Pass task-specific instructions via `-p` in the job. Use different prompts for different jobs (for example, review, implement, refactor).

---

## Glossary - Claude Code Docs

Source: https://code.claude.com/docs/en/glossary
Path: 02-Claude-Code-CLI/glossary.md

## On this page

- [A](#a)
  - [AGENTS.md](#agents-md)
  - [Agent teams](#agent-teams)
  - [Agentic coding](#agentic-coding)
  - [Agentic harness](#agentic-harness)
  - [Agentic loop](#agentic-loop)
  - [Artifact](#artifact)
  - [Auto memory](#auto-memory)
  - [Auto mode](#auto-mode)
- [B](#b)
  - [Bare mode](#bare-mode)
  - [Bundled skills](#bundled-skills)
- [C](#c)
  - [Channel](#channel)
  - [Checkpoint](#checkpoint)
  - [.claude directory](#claude-directory)
  - [CLAUDE.md](#claude-md)
  - [Cloud session](#cloud-session)
  - [Command](#command)
  - [Compaction](#compaction)
  - [Connector](#connector)
  - [Context window](#context-window)
- [D](#d)
  - [Dispatch](#dispatch)
- [E](#e)
  - [Effort level](#effort-level)
  - [Extended thinking](#extended-thinking)
- [F](#f)
  - [Frontmatter](#frontmatter)
- [H](#h)
  - [Hook](#hook)
- [M](#m)
  - [Managed settings](#managed-settings)
  - [MCP (Model Context Protocol)](#mcp-model-context-protocol)
  - [MCP server](#mcp-server)
  - [MCP Tool Search](#mcp-tool-search)
- [N](#n)
  - [Non-interactive mode](#non-interactive-mode)
- [O](#o)
  - [Output style](#output-style)
- [P](#p)
  - [Permission mode](#permission-mode)
  - [Permission rule](#permission-rule)
  - [Plan mode](#plan-mode)
  - [Plugin](#plugin)
  - [Project trust](#project-trust)
  - [Prompt injection](#prompt-injection)
- [R](#r)
  - [Remote Control](#remote-control)
  - [Rules](#rules)
- [S](#s)
  - [Sandboxing](#sandboxing)
  - [Session](#session)
  - [Settings layers](#settings-layers)
  - [Skill](#skill)
  - [Subagent](#subagent)
  - [Surface](#surface)
  - [System prompt](#system-prompt)
  - [System reminder](#system-reminder)
- [T](#t)
  - [Teleport](#teleport)
  - [Tool](#tool)
  - [Transcript](#transcript)
  - [Turn](#turn)
- [V](#v)
  - [Verification loop](#verification-loop)
- [W](#w)
  - [Worktree isolation](#worktree-isolation)
- [Deprecated and renamed terms](#deprecated-and-renamed-terms)

Glossary

# Glossary

Copy pageCopy page

Definitions for Claude Code terminology. Learn what agentic loop, compaction, CLAUDE.md, hooks, subagents, MCP, and other core concepts mean.

Copy pageCopy page

This glossary defines Claude Code terminology. Each entry links to the page where the concept is covered in depth. For model-level concepts like tokens, temperature, and RAG, see the [platform glossary](../04-API-Reference/About/about-claude-glossary.md). For Claude Desktop terms such as desktop extension, MCPB, and DXT, see the [Claude Help Center](https://support.claude.com/).


[​](#a)

A


[​](#agents-md)

AGENTS.md

A markdown file of project instructions you write for AI coding agents. If your repository has one and no [CLAUDE.md](#claude-md), Claude reads it as your project instructions without you adding a second file. You can change the **Project instructions** setting in `/config` to have Claude read both files or only `CLAUDE.md`. Reading `AGENTS.md` directly requires Claude Code v2.1.277 or later. In some sessions Claude [can’t read `AGENTS.md`](memory.md#when-agents-md-support-is-unavailable), so [import it from a `CLAUDE.md`](memory.md#share-one-file-with-other-coding-tools) there instead. Learn more: [AGENTS.md](memory.md#agents-md)


[​](#agent-teams)

Agent teams

Multiple independent Claude Code sessions coordinated by a team lead, with a shared task list and peer-to-peer messaging. Unlike [subagents](#subagent), which run within a single session and report only to the parent, teammates each have their own context window and you can interact with any of them directly. Agent teams are experimental and disabled by default; see [Enable agent teams](../09-Agents-Patterns/agent-teams.md#enable-agent-teams). Learn more: [Run agent teams](../09-Agents-Patterns/agent-teams.md)


[​](#agentic-coding)

Agentic coding

A workflow where the AI can read files, run commands, and make changes autonomously while you watch, redirect, or step away, as opposed to chat-based assistants that only respond with text you must apply yourself. Claude Code is agentic because it has [tools](#tool) that let it act, not just advise. Learn more: [How Claude Code works](how-claude-code-works.md)


[​](#agentic-harness)

Agentic harness

The tools, context management, and execution environment that turn a language model into a capable coding agent. Claude Code is the harness; Claude is the model inside it. The harness supplies file access, shell execution, permission gating, memory loading, and the loop that chains actions together. Learn more: [How Claude Code works](how-claude-code-works.md)


[​](#agentic-loop)

Agentic loop

The cycle Claude works through for every task: gather context, take action, verify results, and repeat until done. Each tool use returns information that informs the next step. You can interrupt the loop at any point to redirect. Most extension points, including [hooks](#hook), [skills](#skill), and [MCP](#mcp-model-context-protocol), plug into specific phases of this loop. Learn more: [How Claude Code works](how-claude-code-works.md#the-agentic-loop)


[​](#artifact)

Artifact

A live, interactive web page Claude Code publishes from your session to a private URL on claude.ai, so you can see output visually or share it instead of reading terminal text. The page updates in place when the session republishes. Artifacts you create from Claude Code appear in the same gallery as artifacts created in claude.ai conversations. Sharing options depend on your plan: see [Share an artifact](artifacts.md#share-an-artifact). Learn more: [Share session output as artifacts](artifacts.md)


[​](#auto-memory)

Auto memory

Notes Claude writes for itself based on your corrections and preferences, stored per git repository under `~/.claude/projects/`. All worktrees of the same repository share one auto memory directory. The first 200 lines or 25 KB of the `MEMORY.md` index loads at the start of every session. Auto memory is the Claude-written counterpart to [CLAUDE.md](#claude-md), which you write. Learn more: [Auto memory](memory.md#auto-memory)


[​](#auto-mode)

Auto mode

A [permission mode](#permission-mode) where a separate classifier model reviews actions instead of you, so Claude Code runs most of them without asking you. Claude Code still asks you before actions your explicit ask rules match. With Claude Code v2.1.283 or later, auto mode is the [built-in starting permission mode](permission-modes.md#which-mode-a-session-starts-in) for interactive terminal and VS Code sessions, and on earlier versions only on Pro, Max, and Team plans. The classifier blocks scope escalation, untrusted infrastructure, and [prompt injection](#prompt-injection). Tool results are stripped from what it sees, so hostile content in a file or web page can’t manipulate it directly. Learn more: [Eliminate prompts with auto mode](permission-modes.md#eliminate-prompts-with-auto-mode)


[​](#b)

B


[​](#bare-mode)

Bare mode

With `--bare`, Claude Code starts without loading hooks, skills, custom commands, subagents, installed plugins, MCP servers, auto memory, or CLAUDE.md, apart from skills in a directory you pass with `--add-dir`. Recommended for CI and scripted calls where you need the same result on every machine. Learn more: [Start faster with bare mode](headless.md#start-faster-with-bare-mode)


[​](#bundled-skills)

Bundled skills

Prompt-based playbooks included with Claude Code, such as `/batch`, `/code-review`, `/debug`, and `/loop`. Unlike built-in commands, which execute fixed logic, bundled skills give Claude a detailed prompt and let it orchestrate the work, so they can spawn agents, read files, and adapt to your codebase. Learn more: [Bundled skills](../08-Plugins-Skills/skills.md#bundled-skills)


[​](#c)

C


[​](#channel)

Channel

An [MCP server](#mcp-model-context-protocol) that pushes events into your running session so Claude can react to things that happen while you’re away from the terminal. Channels can be two-way: Claude reads an inbound event and replies back through the same channel. Telegram, Discord, and iMessage are included in the research preview. Learn more: [Channels](channels.md)


[​](#checkpoint)

Checkpoint

A restore point created at each prompt you send that starts a turn. Claude Code snapshots files before every edit so a checkpoint can revert them. Press `Esc` twice or run `/rewind` to restore code, conversation, or both to an earlier point, or to summarize part of the conversation from a selected message. Checkpoints are saved with the conversation, so a resumed session can still `/rewind` to them. Rewinding doesn’t undo a Bash command’s changes to a file unless Claude had already used its file editing tools on that file in your conversation. Learn more: [Checkpointing](checkpointing.md)


[​](#claude-directory)

`.claude` directory

The directory where Claude Code reads project-scoped configuration: settings, hooks, skills, subagents, rules, and auto memory. A project has `.claude/` at its root; your user-level defaults are at `~/.claude/`. Learn more: [The `.claude` directory](claude-directory.md)


[​](#claude-md)

CLAUDE.md

A markdown file of persistent instructions you write for Claude, loaded at the start of every session as a user message after the system prompt. Put project conventions, architecture notes, and “always do X” rules here. Project-root CLAUDE.md survives [compaction](#compaction) and is re-read fresh from disk afterward. You can place CLAUDE.md at project scope in `./CLAUDE.md` or `./.claude/CLAUDE.md`, at user scope in `~/.claude/CLAUDE.md`, or as [managed policy](#managed-settings) for your organization. All discovered files are concatenated into context rather than overriding each other, ordered from broadest scope to most specific. Claude Code can also load a project’s [AGENTS.md](#agents-md) files in place of CLAUDE.md. Learn more: [CLAUDE.md files](memory.md#claude-md-files)


[​](#cloud-session)

Cloud session

A Claude Code session that keeps running after you close your laptop, because it runs on cloud infrastructure instead of your machine. That infrastructure is Anthropic-managed by default, or a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) your organization operates. You start one from claude.ai/code, the Claude mobile app, the Desktop app with **Cloud** selected, `claude --cloud`, or a [cloud scheduled task](web-scheduled-tasks.md). A session in your terminal, IDE, or the Desktop app with **Local** selected is a local session; to reach a local session from another device, use [Remote Control](#remote-control). Learn more: [Use Claude Code in the cloud](claude-code-on-the-web.md)


[​](#command)

Command

A reusable instruction you invoke by typing `/name` in the prompt. Built-in commands such as `/clear`, `/model`, and `/compact` control the session. You can define your own commands as files in `.claude/commands/`, or install them from a [plugin](#plugin). [Skills](#skill) are the recommended way to package multi-step commands. Two other uses of the word are unrelated: `claude` CLI subcommands such as `claude mcp add`, listed in the [CLI reference](cli-reference.md#cli-commands), and the `command` field of a stdio [MCP server](#mcp-server) entry, which specifies the executable Claude Code launches to start the server. Learn more: [Commands](commands.md) · [Skills](../08-Plugins-Skills/skills.md)


[​](#compaction)

Compaction

Automatic summarization of your conversation when the [context window](#context-window) approaches its limit. Older tool outputs are cleared first, then the conversation is summarized. Project-root CLAUDE.md and auto memory survive compaction and reload from disk; instructions given only in conversation may be lost. Run `/compact` to trigger manually, optionally with a focus like `/compact focus on the API changes`. Learn more: [What survives compaction](context-window.md#what-survives-compaction) · [When context fills up](how-claude-code-works.md#when-context-fills-up)


[​](#connector)

Connector

An [MCP server](#mcp-server) added to your claude.ai account rather than configured in Claude Code. When you sign in to Claude Code with that account, your connectors appear in `/mcp` alongside the servers you added locally. Organizations can also provision connectors and set per-tool controls on them. Learn more: [Use MCP servers from claude.ai](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai)


[​](#context-window)

Context window

The working memory for a session, holding conversation history, file contents, command outputs, CLAUDE.md, auto memory, loaded skills, and system instructions. As you work, context fills up until [compaction](#compaction) summarizes it. Run `/context` to see what’s using space. For the underlying model concept, see the [platform glossary](../04-API-Reference/About/about-claude-glossary.md#context-window). Learn more: [Explore the context window](context-window.md)


[​](#d)

D


[​](#dispatch)

Dispatch

A phone-initiated task router that spawns a Claude Code session in the Desktop app when you send a coding task from the Claude mobile app. Your prompt routes to the right tool automatically. Available on Pro and Max plans. Learn more: [Sessions from Dispatch](../16-Mobile-Desktop/desktop.md#sessions-from-dispatch)


[​](#e)

E


[​](#effort-level)

Effort level

A setting that controls adaptive reasoning, which lets the model decide whether and how much to think on each step. Higher effort means more thinking tokens and deeper reasoning; lower effort is faster and cheaper. Effort is supported on Fable models, on Opus 4.6 and later, on Sonnet 4.6 and later, and on Haiku 5.5. Learn more: [Adjust effort level](model-config.md#adjust-effort-level)


[​](#extended-thinking)

Extended thinking

Visible step-by-step reasoning the model performs before responding. You can adjust it with the [effort level](#effort-level), or cap thinking tokens with `MAX_THINKING_TOKENS` on models with a fixed thinking budget. Thinking appears in gray italic text in the terminal. Learn more: [Use extended thinking](model-config.md#extended-thinking)


[​](#f)

F


[​](#frontmatter)

Frontmatter

A block of YAML settings at the very top of a Markdown file, between an opening `---` line and a closing `---` line. Skills, subagents, output styles, and rules each read their configuration from frontmatter, such as a skill’s `description` or a subagent’s `tools`, and treat everything after the closing `---` as the instructions. The opening `---` must be the file’s first line. Each file type accepts its own set of fields. Learn more: [Skill frontmatter](../08-Plugins-Skills/skills.md#frontmatter-reference), [Subagent frontmatter](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields), [Output style frontmatter](output-styles.md#frontmatter), [Rule frontmatter](memory.md#rules-frontmatter-reference)


[​](#h)

H


[​](#hook)

Hook

A user-defined handler that executes automatically at a specific point in Claude Code’s lifecycle, such as before a tool runs, after a file edit, or at session start. Handlers can be a shell command, HTTP endpoint, MCP tool, LLM prompt, or subagent. Hooks are deterministic: they fire at fixed lifecycle points rather than at the model’s discretion. A hook configuration has three levels:

- **Hook event**: the lifecycle point
- **Matcher**: filters which events fire it
- **Hook handler**: what runs

Learn more: [Get started with hooks](../07-Hooks/hooks-guide.md) · [Hooks reference](../07-Hooks/hooks.md)


[​](#m)

M


[​](#managed-settings)

Managed settings

Settings enforced org-wide by IT or DevOps, delivered from Anthropic’s servers through the admin console or deployed to devices at an OS-level path outside `~/.claude`. User and project settings cannot override managed settings. Server-managed delivery applies on [eligible configurations](../13-Enterprise-Admin/server-managed-settings.md#platform-availability); see [Security considerations](../13-Enterprise-Admin/server-managed-settings.md#security-considerations). Use this for security policies, compliance requirements, or standardized tooling across a fleet. Learn more: [Server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) · [Settings files](settings.md#where-settings-live)


[​](#mcp-model-context-protocol)

MCP (Model Context Protocol)

An open standard for connecting AI tools to external data sources and services. MCP servers give Claude new tools for Slack, Jira, databases, browsers, and hundreds of other integrations. You connect servers via `/mcp` or by adding them to `.mcp.json`. For the protocol itself, see the [platform glossary](../04-API-Reference/About/about-claude-glossary.md#mcp-model-context-protocol). Learn more: [Model Context Protocol](../06-MCP-Tools/General/mcp.md)


[​](#mcp-server)

MCP server

A program that gives Claude tools, prompts, or resources over [MCP](#mcp-model-context-protocol). You add servers with `claude mcp add`, in `.mcp.json`, through a [plugin](#plugin), or as a claude.ai [connector](#connector). A local stdio server runs as a process Claude Code starts from the `command` and `args` fields of its configuration, which have nothing to do with the [commands](#command) you type at the prompt. Learn more: [Model Context Protocol](../06-MCP-Tools/General/mcp.md)


[​](#mcp-tool-search)

MCP Tool Search

A context-saving mechanism that defers MCP tool schemas until needed. Only tool names and server instructions load at startup; Claude fetches the full schema on demand when it decides to use a specific tool. This keeps idle MCP servers from consuming much context. Learn more: [Scale with MCP Tool Search](../06-MCP-Tools/General/mcp.md#scale-with-mcp-tool-search)


[​](#n)

N


[​](#non-interactive-mode)

Non-interactive mode

A mode that executes a single prompt and exits without an interactive prompt, invoked with `-p` or `--print`. Used for CI, scripts, and piping. The run is still saved as a resumable session unless you pass `--no-session-persistence`. The [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) is the Python and TypeScript equivalent. Formerly called headless mode. Learn more: [Run Claude Code programmatically](headless.md)


[​](#o)

O


[​](#output-style)

Output style

A configuration that changes the instructions Claude Code gives Claude, to set response behavior, tone, or format. Unlike [CLAUDE.md](#claude-md), which adds project context alongside Claude Code’s default instructions, a custom output style adds its own instructions and can leave out the default software engineering instructions. Learn more: [Output styles](output-styles.md)


[​](#p)

P


[​](#permission-mode)

Permission mode

The baseline approval behavior for the session. Cycle with `Shift+Tab` in the CLI or use the mode selector in VS Code, Desktop, and claude.ai. Available modes are `default`, `acceptEdits`, `plan`, `auto`, `dontAsk`, and `bypassPermissions`. The `default` mode is labeled Manual in the CLI, in the VS Code and JetBrains extensions, and in the desktop app, and Claude Code accepts `manual` as an alias for the value. Learn more: [Choose a permission mode](permission-modes.md)


[​](#permission-rule)

Permission rule

A settings entry that allows, asks about, or denies a tool invocation based on the tool name and argument pattern. Rules are evaluated deny→ask→allow, first match wins. Permission rules are fine-grained controls layered on top of the broader [permission mode](#permission-mode). Learn more: [Configure permissions](permissions.md)


[​](#plan-mode)

Plan mode

A [permission mode](#permission-mode) where Claude researches and proposes changes without editing your source files. It can read, search, and run exploration commands, then presents a plan for approval before touching anything. Enter plan mode with `/plan` or by pressing `Shift+Tab`. Learn more: [Analyze before you edit with plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode)


[​](#plugin)

Plugin

A bundle of skills, hooks, subagents, and MCP servers packaged as a single installable unit. Plugin skills are namespaced as `plugin-name:skill-name` so multiple plugins coexist. Distribute plugins across teams via a [marketplace](../08-Plugins-Skills/plugins.md). Learn more: [Plugins](../08-Plugins-Skills/plugins.md)


[​](#project-trust)

Project trust

A dialog accepting a directory before Claude Code loads its configuration. Acceptance is saved per project directory, except your home directory, where trust is held for the current session only and the prompt reappears on each launch. Until you trust a directory, Claude Code holds back some of the content its repository supplies, such as project allow rules and marketplaces from `.claude/settings.json`. [What runs before you trust a folder](permissions.md#what-runs-before-you-trust-a-folder) lists each kind of content, including what a `-p` session runs without a dialog. Learn more: [The `.claude` directory](claude-directory.md)


[​](#prompt-injection)

Prompt injection

Hostile instructions embedded in a file, web page, or tool result that attempt to redirect Claude toward actions you never asked for. Claude Code’s defenses include the permission system, command injection detection, and trust verification. [Auto mode](#auto-mode) adds a server-side probe that scans tool results for suspicious content and a classifier that reviews actions with tool results stripped, so injected text can’t manipulate it directly. Learn more: [Protect against prompt injection](../13-Enterprise-Admin/security.md#protect-against-prompt-injection)


[​](#r)

R


[​](#remote-control)

Remote Control

A way to continue a local Claude Code session from your phone or browser via claude.ai. Your code execution and files stay on your machine; the interface is remote. Different from a [cloud session](claude-code-on-the-web.md), which runs in a cloud sandbox. Learn more: [Remote Control](remote-control.md)


[​](#rules)

Rules

Modular instruction files in `.claude/rules/` that load alongside CLAUDE.md. A rule can be path-scoped with YAML `paths:` frontmatter so it only loads when Claude reads, writes, or edits a matching file, keeping context lean until it’s relevant. Learn more: [Organize rules with `.claude/rules/`](memory.md#organize-rules-with-claude/rules/)


[​](#s)

S


[​](#sandboxing)

Sandboxing

OS-level filesystem and network isolation for the Bash tool. Commands run inside a boundary you define upfront, so Claude can work freely within it without per-command approval prompts. Sandboxing is a separate layer from [permission rules](#permission-rule). Learn more: [Sandboxing](sandboxing.md)


[​](#session)

Session

A conversation tied to your current directory, with its own independent [context window](#context-window). Sessions can be resumed with `claude -c`, forked with `--fork-session` to preserve history under a new session ID, or run in parallel across terminals. Running `/clear` starts a new session; the previous one stays stored and is available via `/resume`. Each session’s transcript is stored under `~/.claude/projects/`. Learn more: [Work with sessions](how-claude-code-works.md#work-with-sessions)


[​](#settings-layers)

Settings layers

The hierarchy Claude Code reads configuration from, in precedence order from highest to lowest: [managed policy](#managed-settings), settings you pass with the `--settings` flag, local settings at `.claude/settings.local.json`, project settings at `.claude/settings.json`, then user settings at `~/.claude/settings.json`. Arrays merge across layers; scalars at a higher layer override lower ones. See [Settings precedence](settings.md#settings-precedence). Learn more: [Settings files](settings.md#where-settings-live)


[​](#skill)

Skill

A `SKILL.md` file containing instructions, knowledge, or a workflow that Claude adds to its toolkit. Claude loads a skill automatically when relevant, or you invoke it directly with `/skill-name`. Skills follow the Agent Skills open standard; Claude Code extends it with invocation control and subagent execution. Skills are the recommended successor to custom commands. A file at `.claude/commands/deploy.md` and one at `.claude/skills/deploy/SKILL.md` both create `/deploy` and work the same way; existing command files continue to work. Learn more: [Extend Claude with skills](../08-Plugins-Skills/skills.md)


[​](#subagent)

Subagent

A specialized AI assistant that runs in its own context window with a custom system prompt, specific tool access, and independent permissions. It works on a delegated task and returns a summary to the main conversation. Use subagents to keep large explorations out of your primary context or to run parallel research. A subagent stays inside the session that spawned it. To pass findings between separate sessions you run yourself, use [cross-session messaging](cross-session-messaging.md). Built-in subagents include Explore, Plan, and general-purpose. Learn more: [Create custom subagents](../09-Agents-Patterns/sub-agents.md)


[​](#surface)

Surface

Any place you access Claude Code: the CLI, VS Code, JetBrains, Desktop, or claude.ai. All surfaces share the same engine. Sessions on your machine read your local CLAUDE.md, settings, and skills; [cloud sessions](cloud-environments.md#what-carries-over-from-your-setup) start from a fresh clone of your repository and don’t read `~/.claude/` on your machine. Slack and the Chrome extension are integrations that connect to a surface rather than surfaces themselves. Learn more: [Platforms and integrations](platforms.md)


[​](#system-prompt)

System prompt

The instructions Claude Code sends ahead of your conversation on every request, covering how Claude uses tools, behaves safely, and formats its responses. You can add to the system prompt with `--append-system-prompt` or replace it with `--system-prompt`. The system prompt is the first layer of the [prompt cache](prompt-caching.md#how-the-cache-is-organized). Your [CLAUDE.md](#claude-md) files and the instructions of your [output style](#output-style) aren’t part of the system prompt. Claude Code delivers them in the conversation as [system reminders](#system-reminder). Learn more: [System prompt flags](cli-reference.md#system-prompt-flags)


[​](#system-reminder)

System reminder

A message that Claude Code, as the [harness](#agentic-harness), adds to the conversation to give Claude context. You don’t send system reminders yourself. Claude Code inserts them as a session runs, for example when the session starts, when a hook returns text, or when a file changes on disk. Claude reads them alongside your messages. The following all reach Claude as system reminders:

- Your [CLAUDE.md](#claude-md) files
- The instructions of your [output style](#output-style)
- Text a [hook](#hook) returns as `additionalContext`
- The list of available [skills](#skill)
- A note that a file Claude read earlier has changed on disk
- The commit and pull request attribution lines

In a logged API request, a system reminder appears wrapped in `<system-reminder>` tags inside a user message, or on some models as a separate message with the `system` role. Learn more: [Context Claude Code adds outside the system prompt](../05-Agent-SDK/agent-sdk-modifying-system-prompts.md#context-claude-code-adds-outside-the-system-prompt)


[​](#t)

T


[​](#teleport)

Teleport

A command, `/teleport`, that pulls a cloud Claude Code session into your local terminal. Claude fetches the branch, loads the conversation history, and resumes from the cloud session’s last state. The reverse direction is `--cloud`, which sends a local task to run in the cloud. Learn more: [Continue a cloud session in your terminal](claude-code-on-the-web.md#from-cloud-to-terminal)


[​](#tool)

Tool

An action Claude can take: read a file, edit code, run a shell command, search the web, spawn a subagent. Tools are what make Claude Code agentic. Without them, Claude can only respond with text. Each tool use returns a result that informs Claude’s next decision in the [agentic loop](#agentic-loop). Learn more: [Tools available to Claude](tools-reference.md)


[​](#transcript)

Transcript

The stored record of a [session](#session). The conversation is what you and Claude exchange; the transcript is that conversation kept as a file, by default at `~/.claude/projects/<project>/<session-id>.jsonl`. Claude Code reads the file back when you resume, which is how a conversation continues after the session ends. For the on-screen view of the same conversation, see the [transcript viewer](interactive-mode.md#transcript-viewer). Learn more: [Where transcripts are stored](sessions.md#where-transcripts-are-stored)


[​](#turn)

Turn

One complete response from Claude within a [session](#session). A turn begins when you send a message and ends when Claude finishes responding, with any number of [tool](#tool) calls in between. [Stop hooks](#hook) fire at the end of each turn. A session consists of many turns, and the [agentic loop](#agentic-loop) describes what happens inside one. Learn more: [How Claude Code works](how-claude-code-works.md#the-agentic-loop)


[​](#v)

V


[​](#verification-loop)

Verification loop

How a session knows the work is actually done instead of accepting a result that looks plausible. You give Claude a check it can run, such as a test suite, a build, or a screenshot comparison, and Claude iterates until the check passes instead of stopping after one attempt. A verification loop is the prerequisite for [`/goal`](goal.md), unattended runs, and [dynamic workflows](workflows.md): without one, the only thing deciding the agent is finished is the agent itself. Learn more: [Give Claude a way to verify its work](best-practices.md#give-claude-a-way-to-verify-its-work)


[​](#w)

W


[​](#worktree-isolation)

Worktree isolation

An isolation mode that runs Claude in a separate git worktree under `.claude/worktrees/`, enabled with the `-w` flag or `isolation: worktree` in subagent config. Changes stay on a separate branch in a separate directory, so parallel agents each edit their own copy of the files. Learn more: [Run parallel sessions with git worktrees](worktrees.md)

------------------------------------------------------------------------


[​](#deprecated-and-renamed-terms)

Deprecated and renamed terms

These terms appear in older docs, blog posts, and community content. Use the current name when searching this site.

| Old term                                                                | Now called                                    | Notes                                                                         |
|-------------------------------------------------------------------------|-----------------------------------------------|-------------------------------------------------------------------------------|
| Headless mode                                                           | [Non-interactive mode](#non-interactive-mode) | Same `-p` flag, same behavior                                                 |
| Web session; “Claude Code on the web” as the name for any cloud session | [Cloud session](#cloud-session)               | ”Claude Code on the web” now names only the browser surface at claude.ai/code |
| Custom commands                                                         | [Skills](#skill)                              | `.claude/commands/` files still work                                          |
| Slash commands                                                          | Commands                                      | ”Slash” dropped from product copy                                             |

---

## Keep Claude working toward a goal - Claude Code Docs

Source: https://code.claude.com/docs/en/goal
Path: 02-Claude-Code-CLI/goal.md

## On this page

- [Compare ways to keep a session running](#compare-ways-to-keep-a-session-running)
- [Use /goal](#use-%2Fgoal)
  - [Set a goal](#set-a-goal)
  - [Write an effective condition](#write-an-effective-condition)
  - [Check status](#check-status)
  - [Clear a goal](#clear-a-goal)
  - [Resume with an active goal](#resume-with-an-active-goal)
  - [Run non-interactively](#run-non-interactively)
- [How evaluation works](#how-evaluation-works)
  - [When a turn fails](#when-a-turn-fails)
  - [Errors you have to fix clear the goal](#errors-you-have-to-fix-clear-the-goal)
  - [Other errors retry or pause the goal](#other-errors-retry-or-pause-the-goal)
  - [Background work defers evaluation](#background-work-defers-evaluation)
  - [Evaluation model and cost](#evaluation-model-and-cost)
- [Requirements](#requirements)
- [See also](#see-also)

Automation

# Keep Claude working toward a goal

Copy pageCopy page

Set a completion condition with /goal and Claude keeps working until it’s met, a model judges it impossible, or an error you have to fix clears the goal.

Copy pageCopy page

The `/goal` command sets a completion condition and Claude keeps working toward it without you prompting each step. After each turn, a model checks whether the condition holds. If the model judges it not yet met, Claude starts another turn instead of returning control to you. The goal clears automatically once the condition is met, if the model judges the condition impossible to satisfy, or if a turn fails on [an error you have to fix](#errors-you-have-to-fix-clear-the-goal). Use a goal for substantial work with a verifiable end state:

- Migrating a module to a new API until every call site compiles and tests pass
- Implementing a design doc until all acceptance criteria hold
- Splitting a large file into focused modules until each is under a size budget
- Working through a labeled issue backlog until the queue is empty


[​](#compare-ways-to-keep-a-session-running)

Compare ways to keep a session running

Three approaches keep the current session running between prompts. Pick based on what should start the next turn:

| Approach                                                                 | Next turn starts when                                                                                                                                                                      | Stops when                                                                                                                                                                                      |
|:-------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `/goal`                                                                  | The previous turn finishes, or, in an interactive session, an [idle check-in](#background-work-defers-evaluation) or an [automatic retry](#other-errors-retry-or-pause-the-goal) comes due | A model confirms the condition is met or judges it impossible, or a turn fails on [an error you have to fix](#errors-you-have-to-fix-clear-the-goal), or you run [`/goal clear`](#clear-a-goal) |
| [`/loop`](scheduled-tasks.md#run-a-prompt-repeatedly-with-%2Floop) | A time interval elapses                                                                                                                                                                    | You stop it, or Claude decides the work is done                                                                                                                                                 |
| [Stop hook](../07-Hooks/hooks-guide.md#prompt-based-hooks)                     | The previous turn finishes                                                                                                                                                                 | Your own script or prompt decides                                                                                                                                                               |

`/goal` and a Stop hook both fire after every turn. `/goal` is a session-scoped shortcut: you type a condition and it’s active for the current session only. A Stop hook lives in your settings file, applies to every session in its scope, and can run a script for deterministic checks or a prompt for model-evaluated ones. [Auto mode](auto-mode-config.md) on its own approves tool calls within a single turn but doesn’t start a new one. Claude stops when it judges the work done. `/goal` adds a separate evaluator that checks your condition after every turn, so completion is decided by a fresh model rather than the one doing the work. The two are complementary: auto mode removes per-tool prompts, and `/goal` removes per-turn prompts.

The approaches above keep the current session running. You can also schedule work that runs independent of any open session, such as nightly tests or morning triage. See [scheduling options](scheduled-tasks.md#compare-scheduling-options) for cloud and Desktop scheduled tasks.


[​](#use-/goal)

Use `/goal`

One goal can be active per session. The same command sets, checks, and clears it depending on the argument.


[​](#set-a-goal)

Set a goal

Run `/goal` followed by the condition you want satisfied. If a goal is already active, the new one replaces it.

```python
/goal all tests in test/auth pass and the lint step is clean
```

Setting a goal starts a turn immediately, with the condition itself as the directive. You don’t need to send a separate prompt. While the goal is active, a `◎ /goal active` indicator shows how long the goal has been running. A goal doesn’t change your permission mode. To let goal turns run unattended, run `/goal` in [auto mode](auto-mode-config.md). In [Manual mode](permission-modes.md), Claude still asks before tool calls that your settings don’t already allow, such as the test command above. While the goal is active, the transcript shows each verdict the evaluator returns, and you can press Ctrl+O to see the reason behind it. The status view also shows the most recent reason, so you can see what Claude is working toward next.


[​](#write-an-effective-condition)

Write an effective condition

The [evaluator](#how-evaluation-works) judges your condition against what Claude has surfaced in the conversation. It doesn’t run commands or read files independently, so write the condition as something Claude’s own output can demonstrate. “All tests in `test/auth` pass” works because Claude runs the tests and the result appears in the transcript for the evaluator to read. A condition that holds up across many turns usually has:

- **One measurable end state**: a test result, a build exit code, a file count, an empty queue
- **A stated check**: how Claude should prove it, such as “`npm test` exits 0” or “`git status` is clean”
- **Constraints that matter**: anything that must not change on the way there, such as “no other test file is modified”

The condition can be up to 4,000 characters. To bound how long a goal runs, include a turn or time clause in the condition, such as `or stop after 20 turns`. Claude reports progress against that clause each turn and the evaluator judges it from the conversation.


[​](#check-status)

Check status

Run `/goal` with no arguments to see the current state.

```python
/goal
```

If a goal is active, the status shows:

- The condition
- How long it has been running
- How many turns have been evaluated
- The current token spend
- The evaluator’s most recent reason

The turn count and the most recent reason appear after the first evaluation has run. If no goal is active but one was achieved earlier in the session, the status shows the achieved condition along with its duration, turn count, and token spend.


[​](#clear-a-goal)

Clear a goal

Run `/goal clear` to remove an active goal before it resolves.

```python
/goal clear
```

Claude prints `Goal cleared:` followed by the condition to confirm, or `No goal set` if nothing was active. `stop`, `off`, `reset`, `none`, and `cancel` are accepted as aliases for `clear`. Running `/clear` to start a new conversation also removes any active goal.


[​](#resume-with-an-active-goal)

Resume with an active goal

When you resume a session, Claude Code restores a goal that was still active when the session ended. Claude Code restores it on every resume route: `--continue`, `--resume` with a session ID, name, or [transcript file path](sessions.md#resume-a-session), and the [session picker](sessions.md#use-the-session-picker). Before v2.1.239, Claude Code restored the goal on every route except the `claude --resume` picker. Claude Code carries the condition over but resets the turn count, timer, and token-spend baseline. It doesn’t restore a goal that was already achieved or cleared.


[​](#run-non-interactively)

Run non-interactively

`/goal` works in [non-interactive mode](headless.md), in the [desktop app](../16-Mobile-Desktop/desktop.md), and through [Remote Control](remote-control.md). Setting a goal with `-p` runs the loop to completion in a single invocation:

```python
claude -p "/goal CHANGELOG.md has an entry for every PR merged this week"
```

With the default text output, Claude’s final response prints when the loop ends, so a goal that runs many turns can look stuck. Add `--output-format stream-json --verbose` to emit each message as the loop runs. Interrupt the process with Ctrl+C to stop a non-interactive goal before it resolves.


[​](#how-evaluation-works)

How evaluation works

`/goal` is a wrapper around a session-scoped [prompt-based Stop hook](../07-Hooks/hooks.md#prompt-based-hooks). Each time Claude finishes a turn, Claude Code sends the condition and the conversation so far to your configured [small fast model](model-config.md). The model returns one of three verdicts, each with a short reason:

- **Not yet met**: Claude keeps working and takes the reason as guidance for the next turn.
- **Met**: Claude Code clears the goal and records an achieved entry in the transcript.
- **Impossible**: the evaluator judged that the condition can never be satisfied. Claude Code clears the goal and records a failed entry in the transcript along with the reason. You don’t need to clear it yourself.

If Claude keeps answering the evaluator without making progress (no tool use for several turns in a row), Claude Code stops the loop, prints a warning, and returns control to you with the goal still set. Evaluation resumes after your next prompt. The [hooks guide](../07-Hooks/hooks-guide.md#stop-hook-hits-the-block-cap) explains the underlying mechanism.


[​](#when-a-turn-fails)

When a turn fails

When a turn fails, Claude Code clears the goal if the error is one you have to fix. After any other error the goal stays set.


[​](#errors-you-have-to-fix-clear-the-goal)

Errors you have to fix clear the goal

If a turn fails on an error that won’t clear until you fix it, Claude Code clears the goal and prints a warning naming the cause. The warning starts with `Goal cleared after an unrecoverable error` and ends with `Run /goal again to continue`. Fix the cause, then [set the goal again](#set-a-goal) with `/goal <condition>`. Four kinds of failure clear the goal:

- An authentication failure, when Claude Code manages its own credentials. When a host manages them for you, such as the desktop app or a [cloud session](claude-code-on-the-web.md), Claude Code leaves the goal active because the host restores access on its own.
- An exhausted credit balance
- A context overflow that [auto-compaction](model-config.md#set-the-auto-compact-window) couldn’t clear
- A model that isn’t available


[​](#other-errors-retry-or-pause-the-goal)

Other errors retry or pause the goal

After any other failure the goal stays set. In an interactive session on Claude Code v2.1.269 or later, Claude Code also prints a line naming the cause and either retries on its own or waits for you:

- **Retry**: after a failure that tends to clear on its own, such as an overloaded server or a dropped connection, a notice starting with `Goal still active` shows the wait before the next attempt. After three automatic retries, the goal pauses instead.
- **Pause**: after a failure that a retry would only repeat, such as an API rate limit, a claude.ai [usage limit](errors.md#youve-hit-your-session-limit), or a hook that ended the turn, a notice starting with `Goal paused` names the cause. If the session is [waiting to continue automatically when a usage limit resets](interactive-mode.md#wait-for-a-usage-limit-to-reset), Claude resumes work toward the goal then.

Send a message at any time to start the next turn immediately. To turn automatic retries off, set [`CLAUDE_CODE_GOAL_CHECKIN_MINUTES`](env-vars.md) to `0`, which also turns [check-ins](#background-work-defers-evaluation) off.


[​](#background-work-defers-evaluation)

Background work defers evaluation

If a subagent or a background shell command is still running when a turn ends, Claude Code skips the evaluation for that turn. It evaluates at the end of the next turn that finishes with no background work running. When the background work finishes, Claude Code delivers the result to Claude as a new turn, so you don’t have to prompt. Once background work has kept the goal waiting for 30 minutes, a check-in is due. In the check-in, Claude Code lists the running tasks and asks Claude to read their output, keep waiting if they’re progressing, and fix or stop any that are stuck. After the first check-in, Claude Code waits twice as long before each later check-in, up to four times the first interval: with the default, 1 hour after the first check-in, then every 2 hours. Claude Code delivers a due check-in, the first one included, in one of two ways:

- **When a turn ends**: Claude Code delivers the check-in at the end of the next turn that finishes with the work still running. In a non-interactive session, such as one started with `-p`, this is the only way Claude Code delivers check-ins.
- **While the session is idle**: in an interactive session, Claude Code also starts a turn on its own to deliver the check-in instead of waiting for your next prompt. If the background work has stopped without reporting a result, Claude Code asks Claude to continue toward the goal. Claude Code starts at most three idle check-ins per goal between your prompts. In the third idle check-in, Claude Code says that idle check-ins are paused until you send another prompt. Before v2.1.246, idle check-ins were uncapped. Idle check-ins require Claude Code v2.1.236 or later.

Before v2.1.239, only idle check-ins backed off this way; a check-in delivered at a turn end recurred at the first interval. To change the first interval, set [`CLAUDE_CODE_GOAL_CHECKIN_MINUTES`](env-vars.md). Claude Code uses your value in place of the 30-minute interval and scales the later intervals with it. Set it to `0` to turn off check-ins and [automatic retries](#other-errors-retry-or-pause-the-goal). Check-ins require Claude Code v2.1.234 or later.


[​](#evaluation-model-and-cost)

Evaluation model and cost

To evaluate on a different model, set [`ANTHROPIC_DEFAULT_HAIKU_MODEL`](model-config.md#environment-variables).

Claude Code reads `ANTHROPIC_DEFAULT_HAIKU_MODEL` everywhere it uses the small fast model, not only for `/goal` evaluation. When you set it, Claude Code also resolves the [`haiku` alias](model-config.md#model-aliases) to that model and runs [background functionality](../17-Billing-Plans/costs.md#background-token-usage), such as conversation summarization, on it.

The evaluator runs on whichever provider your session is configured for. It does not call tools, so it can only judge what Claude has already surfaced in the conversation.

Evaluation tokens are billed on the small fast model configured for your provider and are typically negligible compared to main-turn spend.


[​](#requirements)

Requirements

Claude Code makes `/goal` available under the same [workspace trust rule as hooks in settings files](permissions.md#what-runs-before-you-trust-a-folder), because the evaluator is part of the hooks system. `/goal` is also unavailable when [`disableAllHooks`](../07-Hooks/hooks.md#disable-or-remove-hooks) is `true` after settings precedence applies, or when [`allowManagedHooksOnly`](settings-reference.md#allowmanagedhooksonly) is set in managed settings. In each case, the command tells you why instead of silently doing nothing.


[​](#see-also)

See also

- [Run a prompt repeatedly with `/loop`](scheduled-tasks.md#run-a-prompt-repeatedly-with-%2Floop): re-run on a time interval instead of toward a condition
- [Prompt-based hooks](../07-Hooks/hooks-guide.md#prompt-based-hooks): write your own Stop hook when you need custom evaluation logic
- [Auto mode](auto-mode-config.md): approve tool calls automatically so each goal turn runs unattended
- [Scheduling comparison](scheduled-tasks.md#compare-scheduling-options): run work on a schedule independent of any open session

---

## Claude Code on Google Cloud's Agent Platform - Claude Code Docs

Source: https://code.claude.com/docs/en/google-vertex-ai
Path: 02-Claude-Code-CLI/google-vertex-ai.md

## On this page

- [Prerequisites](#prerequisites)
- [Sign in with Agent Platform](#sign-in-with-agent-platform)
- [Region configuration](#region-configuration)
- [Set up manually](#set-up-manually)
  - [1. Enable Agent Platform API](#1-enable-agent-platform-api)
  - [2. Request model access](#2-request-model-access)
  - [3. Configure GCP credentials](#3-configure-gcp-credentials)
  - [Advanced credential configuration](#advanced-credential-configuration)
  - [4. Configure Claude Code](#4-configure-claude-code)
  - [5. Pin model versions](#5-pin-model-versions)
  - [6. Verify your configuration](#6-verify-your-configuration)
- [Startup model checks](#startup-model-checks)
  - [When your organization enforces a model allowlist](#when-your-organization-enforces-a-model-allowlist)
  - [When a model is disabled mid-session](#when-a-model-is-disabled-mid-session)
- [IAM configuration](#iam-configuration)
- [1M token context window](#1m-token-context-window)
- [Troubleshooting](#troubleshooting)
- [Additional resources](#additional-resources)

Deployment

# Claude Code on Google Cloud's Agent Platform

Copy pageCopy page

Learn about configuring Claude Code through Google Cloud’s Agent Platform, formerly Vertex AI, including setup, IAM configuration, and troubleshooting.

Copy pageCopy page


[​](#prerequisites)

Prerequisites

Before configuring Claude Code with Google Cloud’s Agent Platform, formerly Vertex AI, ensure you have:

- A Google Cloud Platform (GCP) account with billing enabled
- A GCP project with Google Cloud’s Agent Platform API enabled
- Access to desired Claude models (for example, Claude Sonnet 4.6)
- Google Cloud SDK (`gcloud`) installed and configured
- Quota allocated in desired GCP region

To sign in with your own Google Cloud’s Agent Platform credentials, follow [Sign in with Google Cloud’s Agent Platform](#sign-in-with-agent-platform) below. To deploy Claude Code across a team, use the [manual setup](#set-up-manually) steps and [pin your model versions](#5-pin-model-versions) before rolling out.


[​](#sign-in-with-agent-platform)

Sign in with Agent Platform

If you have Google Cloud credentials and want to start using Claude Code through Google Cloud’s Agent Platform, the login wizard walks you through it. You complete the GCP-side prerequisites once per project; the wizard handles the Claude Code side.

1

Enable Claude models in your GCP project

[Enable Google Cloud’s Agent Platform API](#1-enable-agent-platform-api) for your project, then request access to the Claude models you want in the [Google Cloud’s Agent Platform Model Garden](https://console.cloud.google.com/vertex-ai/model-garden). See [IAM configuration](#iam-configuration) for the permissions your account needs.

2

Start Claude Code and choose Google Cloud's Agent Platform

Run `claude`. At the login prompt, select **3rd-party platform**, then **Google Vertex AI**, the label the login prompt still uses for Google Cloud’s Agent Platform. If you’re already signed in, run `/login` to open the same menu.

3

Follow the wizard prompts

Choose how you authenticate to Google Cloud: Application Default Credentials from `gcloud`, a service account key file, or credentials already in your environment. The wizard asks for your project and region, verifies which Claude models your project can invoke, and lets you pin them. It saves the result to the `env` block of your [user settings file](settings.md), so you don’t need to export environment variables yourself.

After you’ve signed in, run `/setup-vertex` any time to reopen the wizard and change your credentials, project, region, or model pins. The model pin step starts from your currently pinned models. The wizard writes to `~/.claude/settings.json`, or to `$CLAUDE_CONFIG_DIR/settings.json` when [`CLAUDE_CONFIG_DIR`](env-vars.md#variables) is set.


[​](#region-configuration)

Region configuration

Claude Code supports Google Cloud’s Agent Platform [global](https://cloud.google.com/blog/products/ai-machine-learning/global-endpoint-for-claude-models-generally-available-on-vertex-ai), multi-region, and regional endpoints. Set `CLOUD_ML_REGION` to `global`, a multi-region location such as `eu` or `us`, or a specific region such as `us-east5`. Claude Code selects the correct Google Cloud’s Agent Platform hostname for each form, including the `aiplatform.eu.rep.googleapis.com` and `aiplatform.us.rep.googleapis.com` hosts for multi-region locations.

Google Cloud’s Agent Platform may not support the Claude Code default models on every endpoint type. Model availability varies across [specific regions](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/locations#genai-partner-models), multi-region locations, and [global endpoints](https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-partner-models#supported_models). You may need to switch to a supported location or specify a supported model.


[​](#set-up-manually)

Set up manually

To configure Google Cloud’s Agent Platform through environment variables instead of the wizard, for example in CI or a scripted enterprise rollout, follow the steps below.


[​](#1-enable-agent-platform-api)

1. Enable Agent Platform API

Enable Google Cloud’s Agent Platform API in your GCP project. Replace `YOUR-PROJECT-ID` with your GCP project ID here and in the configuration step below:

```python
# Set your project ID
gcloud config set project YOUR-PROJECT-ID

# Enable Agent Platform API
gcloud services enable aiplatform.googleapis.com
```


[​](#2-request-model-access)

2. Request model access

Request access to Claude models in Google Cloud’s Agent Platform:

1.  Go to the [Google Cloud’s Agent Platform Model Garden](https://console.cloud.google.com/vertex-ai/model-garden)
2.  Search for “Claude” models
3.  Request access to desired Claude models (for example, Claude Sonnet 4.6)
4.  Wait for approval (may take 24-48 hours)


[​](#3-configure-gcp-credentials)

3. Configure GCP credentials

Claude Code uses standard Google Cloud authentication. For more information, see [Google Cloud authentication documentation](https://cloud.google.com/docs/authentication). Claude Code supports [X.509 certificate-based Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation-with-x509-certificates) through the same Application Default Credentials chain. Set `GOOGLE_APPLICATION_CREDENTIALS` to the path of your credential configuration file.

Claude Code addresses Google Cloud’s Agent Platform requests to the project in `ANTHROPIC_VERTEX_PROJECT_ID`, even when `GCLOUD_PROJECT`, `GOOGLE_CLOUD_PROJECT`, or the credential file referenced by `GOOGLE_APPLICATION_CREDENTIALS` carries a different project.


[​](#advanced-credential-configuration)

Advanced credential configuration

Claude Code supports automatic credential refresh for GCP through the `gcpAuthRefresh` setting. Add it to your Claude Code [settings file](settings.md), for example `~/.claude/settings.json`. When Claude Code detects that your GCP credentials are expired or cannot be loaded, it runs the configured command to obtain new credentials before retrying the request.

```python
{
  "gcpAuthRefresh": "gcloud auth application-default login",
  "env": {
    "ANTHROPIC_VERTEX_PROJECT_ID": "your-project-id"
  }
}
```

Before running the command, Claude Code requests an access token with your current credentials to confirm they’re actually expired, and skips the command when they still work. If the check doesn’t finish within five seconds, Claude Code also skips the command and runs it only after a request fails with a credential error. Before v2.1.261, a check that timed out counted as an expired credential, so the command could open your browser at startup even though your credentials were still valid. Claude Code shows you the command’s output, but can’t send the command interactive input. This works well for browser-based authentication flows where the CLI shows a URL and you complete authentication in the browser. The refresh command times out after three minutes if authentication does not complete. If you set `gcpAuthRefresh` in project settings such as `.claude/settings.json`, Claude Code runs it under the same [workspace trust rule as hooks in settings files](permissions.md#what-runs-before-you-trust-a-folder), which includes `-p` sessions in folders you’ve never trusted.


[​](#4-configure-claude-code)

4. Configure Claude Code

Set the following environment variables:

```python
# Enable Agent Platform integration
export CLAUDE_CODE_USE_VERTEX=1
export CLOUD_ML_REGION=global
export ANTHROPIC_VERTEX_PROJECT_ID=YOUR-PROJECT-ID

# Optional: Override the Agent Platform endpoint URL for custom endpoints or gateways
# export ANTHROPIC_VERTEX_BASE_URL=https://aiplatform.googleapis.com

# When CLOUD_ML_REGION=global, override region for models that don't support global endpoints
export VERTEX_REGION_CLAUDE_HAIKU_4_5=us-east5
export VERTEX_REGION_CLAUDE_4_6_SONNET=europe-west1
```

Most model versions have a corresponding `VERTEX_REGION_CLAUDE_*` variable. See the [Environment variables reference](env-vars.md#variables) for the full list. Check [Google Cloud’s Agent Platform Model Garden](https://console.cloud.google.com/vertex-ai/model-garden) to determine which models support global endpoints versus regional only. If a region value isn’t shaped like a region or location name, Claude Code treats it as unset. For example, Claude Code treats a value containing a slash, dot, or space as unset. Claude Code falls back to a different source for each variable:

- `VERTEX_REGION_CLAUDE_*`: Claude Code falls back to `CLOUD_ML_REGION`.
- `CLOUD_ML_REGION`: Claude Code falls back to `us-east5`.

[Prompt caching](prompt-caching.md) is enabled automatically. To disable it, set `DISABLE_PROMPT_CACHING=1`. To request a 1-hour cache TTL instead of the 5-minute default, set `ENABLE_PROMPT_CACHING_1H=1`; cache writes with a 1-hour TTL are billed at a higher rate. To set different TTLs for your main conversation and for the requests Claude Code makes outside it, [choose the TTL yourself](prompt-caching.md#choose-the-ttl-yourself). To raise your rate limits, contact Google Cloud support. When using Google Cloud’s Agent Platform, the `/logout` command is unavailable since authentication is handled through Google Cloud credentials. Claude Code decides between [MCP tool search](../06-MCP-Tools/General/mcp.md#scale-with-mcp-tool-search) and upfront loading by model generation:

- **Claude Opus 4.5, Sonnet 4.5, Haiku 4.5, and later**: Claude Code enables tool search by default.
- **Earlier models**: Claude Code loads MCP tool definitions upfront, because their Agent Platform serving stacks reject the required beta header. Setting `ENABLE_TOOL_SEARCH=true` doesn’t override this.

Set `ENABLE_TOOL_SEARCH=false` to disable tool search on every model. Before v2.1.221, Claude Code disabled tool search for all models on Google Cloud’s Agent Platform unless you set `ENABLE_TOOL_SEARCH=true`.


[​](#5-pin-model-versions)

5. Pin model versions

Pin specific model versions when deploying to multiple users. Without pinning, model aliases such as `sonnet` and `opus` resolve to Claude Code’s built-in default for Google Cloud’s Agent Platform, which can lag the newest release and may not yet be enabled in your project. Claude Code [falls back](#startup-model-checks) to an earlier or lower-tier model at startup when the default is unavailable, but pinning lets you control when your users move to a new model.

Set these environment variables to specific Google Cloud’s Agent Platform model IDs. Without `ANTHROPIC_DEFAULT_OPUS_MODEL`, the `opus` alias on Google Cloud’s Agent Platform resolves to Opus 5.5, and without `ANTHROPIC_DEFAULT_SONNET_MODEL`, the `sonnet` alias resolves to Sonnet 4.5. This example pins each alias to a specific version:

```python
export ANTHROPIC_DEFAULT_OPUS_MODEL='claude-opus-4-8'
export ANTHROPIC_DEFAULT_SONNET_MODEL='claude-sonnet-5'
export ANTHROPIC_DEFAULT_HAIKU_MODEL='claude-haiku-4-5@20251001'
```

For current and legacy model IDs, see [Models overview](../20-Models/about-claude-models-overview.md). See [Model configuration](model-config.md#pin-models-for-third-party-deployments) for the full list of environment variables. Claude Code uses these default models when no pinning variables are set:

| Model type       | Default value                |
|:-----------------|:-----------------------------|
| Primary model    | `claude-opus-5-5`            |
| Small/fast model | `claude-sonnet-4-5@20250929` |

Background tasks such as session title generation use the small/fast model, normally a Haiku-class model. On Google Cloud’s Agent Platform, Claude Code uses the default Sonnet model for background tasks because Haiku may not be enabled in every project or region. Two selections change which model carries them:

- When you select a primary model with `--model`, `ANTHROPIC_MODEL`, or the `model` setting, background tasks use that model. When Claude Code starts the session on the model you set with [`ANTHROPIC_DEFAULT_MODEL`](model-config.md#set-a-default-model-for-new-sessions), background tasks use that model too. Setting `ANTHROPIC_DEFAULT_OPUS_MODEL` without `ANTHROPIC_DEFAULT_SONNET_MODEL` also counts as a selection, because the built-in Sonnet model may not be enabled in a project that steers its own Opus.
- To use Haiku for background tasks, set `ANTHROPIC_DEFAULT_HAIKU_MODEL` to a model ID that is available in your project.

Opus models have a higher per-token price than Sonnet models, so if you don’t pin a primary model, you’re billed at the Opus rate. To use Sonnet 4.5 as the primary model, set `ANTHROPIC_MODEL` to its full model ID. A deployment that steers the default with `ANTHROPIC_DEFAULT_SONNET_MODEL` and doesn’t set `ANTHROPIC_DEFAULT_OPUS_MODEL` keeps its steered Sonnet model as the default.

Before v2.1.280, the primary model on Google Cloud’s Agent Platform defaulted to Opus 5 and the `opus` alias resolved to Opus 5 from v2.1.219. On v2.1.207 through v2.1.218, the primary model on Google Cloud’s Agent Platform defaulted to Opus 4.8 and the `opus` alias resolved to Opus 4.8. To customize models further:

```python
export ANTHROPIC_MODEL='claude-opus-4-8'
export ANTHROPIC_DEFAULT_HAIKU_MODEL='claude-haiku-4-5@20251001'
```


[​](#6-verify-your-configuration)

6. Verify your configuration

Start Claude Code and run `/status` to confirm the setup. The `API provider` line shows `Google Vertex AI`, and the `GCP project`, `Default region`, and `Model` lines show your project ID, region, and resolved model. If the provider line is missing, the environment variables aren’t reaching the process. Confirm they are exported in the shell where you launched `claude`, or set them in the `env` block of your [settings file](settings.md).


[​](#startup-model-checks)

Startup model checks

When Claude Code starts with Google Cloud’s Agent Platform configured, it verifies that the models it intends to use are accessible in your project. If you have pinned a model version that is older than the current Claude Code default, and your project can invoke the newer version, Claude Code prompts you to update the pin. Accepting writes the new model ID to your [user settings file](settings.md) and restarts Claude Code. Declining is remembered until the next default version change. If you have not pinned a model and the current default is unavailable in your project, Claude Code falls back for the current session and shows a notice. It tries earlier versions of the default model first and, when the default is an Opus model and no Opus version is available, falls back to the default Sonnet model. The fallback is not persisted. Enable the newer model in [Model Garden](https://console.cloud.google.com/vertex-ai/model-garden) or [pin a version](#5-pin-model-versions) to make the choice permanent. When you start the session on a specific Sonnet or Opus version, for example with `--model`, `ANTHROPIC_MODEL`, or the [`model` setting](settings-reference.md#model), that version acts as the session’s pinned default for the matching `sonnet` or `opus` alias. Claude Code skips the availability check for the built-in default your model replaces and starts on the model you configured, with no fallback notice. Model aliases such as `opus` don’t act as pins, and neither does a model ID Claude Code doesn’t recognize. When these checks find a model your project can’t invoke, Claude Code remembers the refusal on this machine for up to a day, and launches during that time skip the remembered model without asking Agent Platform again. Claude Code checks a remembered refusal of a current default model again at launch once ten minutes have passed since the last check, so a default your administrator re-enables comes back. To turn the memory off, set [`CLAUDE_CODE_SKIP_MODEL_ACCESS_MEMORY=1`](env-vars.md).


[​](#when-your-organization-enforces-a-model-allowlist)

When your organization enforces a model allowlist

If you set [`enforceAvailableModels`](model-config.md#enforce-the-allowlist-for-the-default-model) in managed settings, the startup model checks use only models your `availableModels` list permits. This requires Claude Code v2.1.287 or later. A list without `enforceAvailableModels` doesn’t restrict these checks. The checks compare each entry with the model ID they would send to Agent Platform, so write the list in those IDs. This example permits Opus 4.8 and Sonnet 4.5:

```python
{
  "availableModels": ["claude-opus-4-8", "claude-sonnet-4-5@20250929"],
  "enforceAvailableModels": true
}
```

For aliases, version prefixes, and `modelOverrides` entries, see [Pin models for third-party deployments](model-config.md#pin-models-for-third-party-deployments).


[​](#when-a-model-is-disabled-mid-session)

When a model is disabled mid-session

If 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. The 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](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. A [fallback model chain](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`](env-vars.md). A fallback chain you configured still switches on these refusals; remove the chain as well if you want every refused request to fail.


[​](#iam-configuration)

IAM configuration

Assign the `roles/aiplatform.user` role, which includes the required permissions:

- `aiplatform.endpoints.predict` - Required for model invocation and token counting

For more restrictive permissions, create a custom role with only the permissions above. For details, see [Google Cloud’s Agent Platform IAM documentation](https://cloud.google.com/vertex-ai/docs/general/access-control).

Create a dedicated GCP project for Claude Code to simplify cost tracking and access control.


[​](#1m-token-context-window)

1M token context window

Fable models, Sonnet 5 and later, and Opus 4.7 and later run with the [1M token context window](../04-API-Reference/Guides/build-with-claude-context-windows.md#context-window-sizes-by-model) by default on Google Cloud’s Agent Platform, with no `[1m]` suffix needed. To keep a 200K window instead, set [`CLAUDE_CODE_DISABLE_1M_CONTEXT=1`](model-config.md#turn-off-1m-context). Opus 4.6 and Sonnet 4.6 reach the 1M window when you select their `[1m]` variant. The [setup wizard](#sign-in-with-agent-platform) offers a 1M context option when it pins models. To enable it for a manually pinned model instead, append `[1m]` to the model ID. See [Pin models for third-party deployments](model-config.md#pin-models-for-third-party-deployments) for details, including how to use the 1M window without changing the pin. Before v2.1.287, the Fable models and Opus 4.7 and later ran with a 200K window by default on Google Cloud’s Agent Platform and reached the 1M window through a `[1m]` suffix.


[​](#troubleshooting)

Troubleshooting

If you encounter “Could not load the default credentials” errors:

- Run `gcloud auth application-default login` to set up Application Default Credentials
- Set `GOOGLE_APPLICATION_CREDENTIALS` to a service account key file path
- See [Configure GCP credentials](#3-configure-gcp-credentials) for all options

If you encounter quota issues:

- Check current quotas or request quota increase through [Cloud Console](https://cloud.google.com/docs/quotas/view-manage)

If you encounter “model not found” 404 errors:

- Confirm model is Enabled in [Model Garden](https://console.cloud.google.com/vertex-ai/model-garden)
- Verify the model is available in the location you specified. Some models are offered only on `global` or multi-region locations such as `eu` and `us`, not in specific regions
- If using `CLOUD_ML_REGION=global`, check that your models support global endpoints in [Model Garden](https://console.cloud.google.com/vertex-ai/model-garden) under “Supported features”. For models that don’t support global endpoints, either:
  - Specify a supported model via `ANTHROPIC_MODEL` or `ANTHROPIC_DEFAULT_HAIKU_MODEL`, or
  - Set a region or multi-region location using the model’s `VERTEX_REGION_CLAUDE_*` variable, listed in the [environment variables reference](env-vars.md#variables)

If you encounter 429 errors:

- For regional endpoints, ensure the primary model and small/fast model are supported in your selected region
- Consider switching to `CLOUD_ML_REGION=global` for better availability


[​](#additional-resources)

Additional resources

- [Google Cloud’s Agent Platform documentation](https://cloud.google.com/vertex-ai/docs)
- [Google Cloud’s Agent Platform pricing](https://cloud.google.com/vertex-ai/pricing)
- [Google Cloud’s Agent Platform quotas and limits](https://cloud.google.com/vertex-ai/docs/quotas)

---

## Run Claude Code programmatically - Claude Code Docs

Source: https://code.claude.com/docs/en/headless
Path: 02-Claude-Code-CLI/headless.md

## On this page

- [Basic usage](#basic-usage)
  - [Start faster with bare mode](#start-faster-with-bare-mode)
  - [Background tasks at exit](#background-tasks-at-exit)
  - [Stop a run with SIGTERM](#stop-a-run-with-sigterm)
  - [If the working directory is deleted](#if-the-working-directory-is-deleted)
- [Examples](#examples)
  - [Pipe data through Claude](#pipe-data-through-claude)
  - [Add Claude to a build script](#add-claude-to-a-build-script)
  - [Get structured output](#get-structured-output)
  - [Stream responses](#stream-responses)
  - [Follow subagent messages](#follow-subagent-messages)
  - [Handle API retries](#handle-api-retries)
  - [Read session metadata](#read-session-metadata)
  - [Fail CI when a plugin or MCP server doesn’t load](#fail-ci-when-a-plugin-or-mcp-server-doesn%E2%80%99t-load)
  - [Track plugin installs](#track-plugin-installs)
  - [Auto-approve tools](#auto-approve-tools)
  - [Turn off permission prompts in unattended runs](#turn-off-permission-prompts-in-unattended-runs)
  - [Create a commit](#create-a-commit)
  - [Customize the system prompt](#customize-the-system-prompt)
  - [Continue conversations](#continue-conversations)
- [Next steps](#next-steps)

Automation

# Run Claude Code programmatically

Copy pageCopy page

Use the Agent SDK to run Claude Code programmatically from the CLI, Python, or TypeScript.

Copy pageCopy page

The [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) gives you the same tools, agent loop, and context management that power Claude Code. It’s available as a CLI for scripts and CI/CD, or as [Python](../05-Agent-SDK/agent-sdk-python.md) and [TypeScript](../05-Agent-SDK/agent-sdk-typescript.md) packages for full programmatic control. To run Claude Code in non-interactive mode, pass `-p` with your prompt and the [CLI options](cli-reference.md) you need:

```python
claude -p "Find and fix the bug in auth.py" --allowedTools "Read,Edit,Bash"
```

This page covers using the Agent SDK via the CLI (`claude -p`). For the Python and TypeScript SDK packages with structured outputs, tool approval callbacks, and native message objects, see the [full Agent SDK documentation](../05-Agent-SDK/agent-sdk-overview.md).


[​](#basic-usage)

Basic usage

Add the `-p` (or `--print`) flag to any `claude` command to run it non-interactively. Not every [CLI option](cli-reference.md) combines with `-p`. Claude Code rejects `--bg`, and rejects `--cloud` with a task description, with an error naming the conflict; `--cloud` with a session ID and `-p` instead [queues a message into that cloud session](claude-code-on-the-web.md#send-follow-ups-from-the-cli) and exits. Options you’ll combine with `-p` often include:

- `--continue` for [continuing conversations](#continue-conversations)
- `--allowedTools` for [auto-approving tools](#auto-approve-tools)
- `--output-format` for [structured output](#get-structured-output)

This example asks Claude a question about your codebase and prints the response:

```python
claude -p "What does the auth module do?"
```

Claude Code exits with code 0 on success and a non-zero code when the run fails, so your scripts can branch on the exit status. If you pass an invalid flag, Claude Code reports the error to stderr before the run starts. When a failure happens inside the run, such as missing authentication, Claude Code prints the failure as the result on stdout.


[​](#start-faster-with-bare-mode)

Start faster with bare mode

Add `--bare` to reduce startup time by skipping auto-discovery of hooks, skills, custom commands, [subagents](../09-Agents-Patterns/sub-agents.md), installed plugins, MCP servers, auto memory, and CLAUDE.md. Without it, `claude -p` discovers and loads them as an interactive session would, including anything configured in the working directory or `~/.claude`. Bare mode is useful for CI and scripts where you need the same result on every machine. A hook in a teammate’s `~/.claude` or an MCP server in the project’s `.mcp.json` won’t run, because bare mode never reads them. A directory you name with `--add-dir` is a partial exception: bare mode loads skills from its `.claude/skills/` folder, but still skips its `.claude/commands/` and `.claude/agents/` folders. [Skills from additional directories](../08-Plugins-Skills/skills.md#skills-from-additional-directories) covers what does and doesn’t load. Without `--bare`, a `-p` session runs the hooks in a project’s `.claude/settings.json` and connects the servers in its `.mcp.json`, even in a folder you’ve never trusted. A `-p` session shows no workspace trust dialog and no per-server approval prompt. [What runs before you trust a folder](permissions.md#what-runs-before-you-trust-a-folder) covers each kind of repository content under `-p` and how to keep it out. This example runs a one-off summarize task in bare mode and pre-approves the Read tool so the call completes without a permission prompt. Set `ANTHROPIC_API_KEY` before running it, because bare mode doesn’t use your subscription login:

```python
claude --bare -p "Summarize README.md" --allowedTools "Read"
```

In bare mode, Claude Code never reads OAuth credentials or the system keychain. For the Anthropic API, set `ANTHROPIC_API_KEY` in the environment, with a key created in the [Claude Console](../04-API-Reference/Other/playground.md), or supply an `apiKeyHelper` in the `--settings` JSON. Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry continue to read their own provider credentials as usual. In bare mode Claude has access to the Bash, file read, and file edit tools. Pass any context you need with a flag:

| To load                                                        | Use                                                     |
|----------------------------------------------------------------|---------------------------------------------------------|
| System prompt additions                                        | `--append-system-prompt`, `--append-system-prompt-file` |
| Settings                                                       | `--settings <file-or-json>`                             |
| MCP servers                                                    | `--mcp-config <file-or-json>`                           |
| [Custom agents](../09-Agents-Patterns/sub-agents.md#choose-the-subagent-scope) | `--agents <file-or-json>`                               |
| A plugin                                                       | `--plugin-dir <path>`, `--plugin-url <url>`             |

Bare mode also limits what happens while the session runs:

- **MCP servers**: only servers supplied on the command line connect, for example with `--mcp-config`. In an interactive session, Claude Code also skips the automatic IDE connection unless you pass `--ide`.
- **System reminders**: Claude gets your prompts and the tool results without the [system reminders](glossary.md#system-reminder) Claude Code would add alongside them. For example, Claude isn’t told when a file it read earlier changes on disk, and it doesn’t get the list of available skills, including skills from an `--add-dir` folder.
- **Background tasks**: none run. A command that reaches its [timeout](tools-reference.md#timeout-and-output-limits) stops instead of [moving to the background](tools-reference.md#background-commands).

Before v2.1.286, these limits held only partly: an interactive `--bare` session connected the MCP servers that a normal session would, every `--bare` session sent system reminders, and background tasks stayed available.

`--bare` is the recommended mode for scripted and SDK calls, and will become the default for `-p` in a future release.


[​](#background-tasks-at-exit)

Background tasks at exit

After Claude finishes its turn and stdin has closed, a `claude -p` run can stay open to wait for background work that Claude started. Unless a background command that the main conversation started is still running, Claude Code stops whatever is still running after 10 minutes of continuous idle waiting by default and drops its partial result. To change the 10-minute cap, set [`CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS`](env-vars.md), or set it to `0` to wait without one. The run waits for background work such as background commands, subagents and workflows, Monitor watches, and pending `/loop` wakeups:

- **[Background commands](tools-reference.md#background-commands)**: for a command that the main conversation started, for example a dev server or a watch build, the run waits until the command exits or reaches its [time limit](tools-reference.md#time-limit-for-background-commands). Claude then takes one more turn with the outcome. While the command runs, the 10-minute cap doesn’t end the wait.
- **Background [subagents](../09-Agents-Patterns/sub-agents.md) and workflows**: the run stays open until that work completes, because its result is part of the final output.
- **[Monitor](tools-reference.md#monitor-tool) watches**: the run waits until the watch times out or the 10-minute cap ends the wait, whichever comes first. While it waits, Claude keeps responding to what the watch reports. By default, a watch times out five minutes after Claude starts it.
- **Pending wakeups**: in a run whose prompt you passed as text rather than with `--input-format stream-json`, when Claude has scheduled a [self-paced `/loop` wakeup](scheduled-tasks.md#let-claude-choose-the-interval), the run waits for each wakeup to fire and runs its iteration until the [loop ends](scheduled-tasks.md#stop-a-loop), even past the 10-minute cap.

When stderr is a terminal and the run has waited five seconds, Claude Code prints a line to stderr that starts with `Waiting for background work to finish` and names the work. With [`json` or `stream-json` output](#get-structured-output), the line prints only when stdout isn’t a terminal, so the JSON your script reads never carries it. If the run reaches its [`--max-budget-usd`](cli-reference.md#cli-flags) cap, Claude Code stops the remaining background work instead of waiting. When background work starts another turn, the run prints each turn’s result with the default `text` output and the last turn’s result with `json` output. Before v2.1.295, the run printed only the last turn’s result with `text` output too.


[​](#stop-a-run-with-sigterm)

Stop a run with SIGTERM

If you stop a `claude -p` run with SIGTERM, for example with `kill` or from a process supervisor, Claude Code exits with code 143. Claude Code leaves the turn that was in progress unfinished and records no result for it. To end the turn instead, send SIGINT, or call the Agent SDK’s `interrupt()`, before you stop the process. On SIGTERM, Claude Code terminates the process tree of any Bash command that is still running. Claude Code then runs [`SessionEnd` hooks](../07-Hooks/hooks.md#sessionend) and exits. While exiting, Claude Code starts no new tool call, sends no new model request, and runs no hook other than `SessionEnd`. If the run was in the middle of a command or waiting on a permission prompt when the signal arrived, Claude Code handles that step as follows:

- **Running a command**: Claude Code records the command as killed in the session.
- **Waiting for an answer to a permission prompt**: if you send SIGTERM to the process, Claude Code leaves the prompt unanswered. If your program closes the session through the Agent SDK, the SDK ends Claude Code’s input before sending any signal, and Claude Code cancels the prompt as soon as the input ends.

When you [resume the session](#continue-conversations), Claude Code leaves the interrupted turn as it is, and your next prompt drives the conversation. To have Claude Code continue the interrupted turn on resume instead, set [`CLAUDE_CODE_RESUME_INTERRUPTED_TURN=1`](env-vars.md).


[​](#if-the-working-directory-is-deleted)

If the working directory is deleted

If the working directory of a `claude -p` or Agent SDK session is deleted mid-session, the session keeps running. When a turn starts while the directory is missing, Claude Code emits a [warning message](../05-Agent-SDK/agent-sdk-typescript.md#sdkinformationalmessage) in `stream-json` output, and shell commands fail until the directory exists again.


[​](#examples)

Examples

These examples highlight common CLI patterns. Where a command names a file such as `auth.py` or `build-error.txt`, substitute a file from your own project. In CI or other scripted environments, add [`--bare`](#start-faster-with-bare-mode) so Claude Code starts without loading the host’s hooks, plugins, auto memory, or `CLAUDE.md`.


[​](#pipe-data-through-claude)

Pipe data through Claude

Non-interactive mode reads stdin, so you can pipe data in and redirect the response out like any other command-line tool. This example pipes a build log into Claude and writes the explanation to a file:

```python
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt
```

With `--output-format json`, the response payload includes `total_cost_usd` and a per-model cost breakdown, so scripted callers can track spend without consulting the [usage dashboard](../17-Billing-Plans/costs.md). When you continue an earlier conversation with `--continue` or `--resume`, the run reports the conversation’s whole total, [earlier runs’ spend included](../05-Agent-SDK/agent-sdk-cost-tracking.md#accumulate-costs-across-multiple-calls). Both figures are [client-side estimates](../05-Agent-SDK/agent-sdk-cost-tracking.md) and can differ from your actual bill.

Piped stdin is capped at 10MB. If you exceed the cap, Claude Code exits with a clear error and a non-zero status. To work with larger inputs, write the content to a file and reference the file path in your prompt instead of piping it.

If Claude Code can’t read stdin, for example because the process that started it disconnected its end, Claude Code prints a warning to stderr and continues with the prompt from the command line.


[​](#add-claude-to-a-build-script)

Add Claude to a build script

You can wrap a non-interactive call in a script to use Claude as a project-specific linter or reviewer. This `package.json` script pipes the diff against `main` into Claude and asks it to report typos. Piping the diff means Claude doesn’t need Bash permission to read it, and the escaped double quotes keep the script portable to Windows:

```python
{
  "scripts": {
    "lint:claude": "git diff main | claude -p \"you are a typo linter. for each typo in this diff, report filename:line on one line and the issue on the next. return nothing else.\""
  }
}
```

Run it with `npm run lint:claude`.


[​](#get-structured-output)

Get structured output

Use `--output-format` to control how responses are returned:

- `text` (default): plain text output
- `json`: structured JSON with result, session ID, and metadata
- `stream-json`: newline-delimited JSON for real-time streaming

This example returns a project summary as JSON with session metadata, with the text result in the `result` field:

```python
claude -p "Summarize this project" --output-format json
```

To get output conforming to a specific schema, use `--output-format json` with `--json-schema` and a [JSON Schema](https://json-schema.org/) definition. The response includes metadata about the request (session ID, usage, etc.) with the structured output in the `structured_output` field. This example extracts function names and returns them as an array of strings:

```python
claude -p "Extract the main function names from auth.py" \
  --output-format json \
  --json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}'
```

If the value isn’t a valid JSON Schema, `claude` exits with `Error: --json-schema is not a valid JSON Schema` followed by the validator’s diagnostic. Claude Code accepts schemas that use the `format` keyword, such as `"format": "email"`, but treats `format` as an annotation and doesn’t enforce it. If a run ends without valid structured output, for example because Claude declined the request, the response has no `structured_output` field. Before your script uses `structured_output`, check that the field is present.

Use a tool like [jq](https://jqlang.org/) to parse the response and extract specific fields:

```python
# Extract the text result
claude -p "Summarize this project" --output-format json | jq -r '.result'

# Extract structured output
claude -p "Extract function names from auth.py" \
  --output-format json \
  --json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
  | jq '.structured_output'
```


[​](#stream-responses)

Stream responses

Use `--output-format stream-json` with `--verbose` and `--include-partial-messages` to receive tokens as they’re generated. Each line is a JSON object representing an event:

```python
claude -p "Explain recursion" --output-format stream-json --verbose --include-partial-messages
```

The last line of the stream is a `result` message with the final response text, cost, and session metadata. If your consumer reads the stream slowly, Claude Code waits for the queued output to drain before exiting, scaling the wait with how much is still queued, capped at 30 seconds. The following example uses [jq](https://jqlang.org/) to filter for text deltas and display only the streaming text. The `-r` flag outputs raw strings (no quotes) and `-j` joins without newlines so tokens stream continuously:

```python
claude -p "Write a poem" --output-format stream-json --verbose --include-partial-messages | \
  jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'
```

For programmatic streaming with callbacks and message objects, see [Stream responses in real-time](../05-Agent-SDK/agent-sdk-streaming-output.md) in the Agent SDK documentation.


[​](#follow-subagent-messages)

Follow subagent messages

Messages from [subagents](../09-Agents-Patterns/sub-agents.md) and from skills that [run in a subagent](../08-Plugins-Skills/skills.md#run-skills-in-a-subagent) appear in the stream as `assistant` and `user` messages. Their `parent_tool_use_id` field says which run each one belongs to. Messages from the main conversation carry `null` in that field. The first message from a forked skill, or from a subagent running in the [foreground](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background), is a `user` message carrying the prompt or skill content that drives it. After that first message, Claude Code emits:

- **By default**: the run’s `tool_use` and `tool_result` blocks.
- **With [`--forward-subagent-text`](cli-reference.md#cli-flags) or [`CLAUDE_CODE_FORWARD_SUBAGENT_TEXT`](env-vars.md)**: the run’s text and thinking blocks too, so you can reconstruct each run’s transcript.

When you enable either option, Claude Code forwards messages from [subagents at every nesting depth](../09-Agents-Patterns/sub-agents.md#let-subagents-spawn-their-own-subagents), whether each one was spawned with the Agent tool or started as a forked skill. In `parent_tool_use_id`, the nested subagent’s messages carry the ID of the Agent or Skill tool call that started it, so you can rebuild the full nesting tree by following those IDs. A run that Claude starts with a tool call carries that tool call’s ID. A forked skill that you start by passing `/<skill-name>` as the prompt has no tool call, so its messages carry a `forked-command-` value instead and arrive after it finishes. Find how the run started in the first column:

| How the run starts                                                        | `parent_tool_use_id`                       | When its messages arrive                              |
|:--------------------------------------------------------------------------|:-------------------------------------------|:------------------------------------------------------|
| Claude calls the Agent tool from the main conversation                    | The ID of that Agent `tool_use` block      | While the subagent works                              |
| Claude calls the Skill tool for a forked skill from the main conversation | The ID of that Skill `tool_use` block      | While the forked skill works                          |
| You pass `/<skill-name>` as the prompt                                    | A value that starts with `forked-command-` | Together and in order after the forked skill finishes |

For a forked skill started from the prompt, match `parent_tool_use_id` on the `forked-command-` prefix, because the name after it can differ from the one you typed. If some of these messages are missing from your stream, check your Claude Code version against these minimums:

- **Forwarding at every nesting depth**: v2.1.219 or later
- **A forked skill that Claude starts with the Skill tool from the main conversation**: v2.1.86 or later for its `tool_use` and `tool_result` blocks, and v2.1.265 or later for its first `user` message and its text and thinking blocks
- **Messages of subagents that a forked skill spawns, and of forked skills started inside a subagent or another forked skill**: v2.1.275 or later
- **Messages of a forked skill you start by passing `/<skill-name>` as the prompt**: v2.1.287 or later


[​](#handle-api-retries)

Handle API retries

When an API request fails with a retryable error, Claude Code emits a `system/api_retry` event before retrying. On v2.1.246 or later, when a `401` or `403` rejects an [`apiKeyHelper`](settings-reference.md#apikeyhelper) credential, Claude Code makes the first two retries quietly with no event, then emits the event as usual from the third consecutive retry onward. The quiet retries still count toward `attempt`. You can use the event to show retry progress in your own interface.

| Field            | Type             | Description                                                                                                                                                                                                                                           |
|------------------|------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `type`           | `"system"`       | message type                                                                                                                                                                                                                                          |
| `subtype`        | `"api_retry"`    | identifies this as a retry event                                                                                                                                                                                                                      |
| `attempt`        | integer          | current attempt number, starting at 1                                                                                                                                                                                                                 |
| `max_retries`    | integer          | total retries permitted for this failure’s cause                                                                                                                                                                                                      |
| `retry_delay_ms` | integer          | milliseconds until the next attempt                                                                                                                                                                                                                   |
| `error_status`   | integer or null  | HTTP status code of the failed attempt, or `null` when the attempt got no HTTP response from the API                                                                                                                                                  |
| `no_response`    | object, optional | present only when the failed attempt got [no response headers in time](errors.md#no-response-from-api). `waited_ms` is how long that attempt waited and `retry_wait_ms` is how long the retry will wait. Requires Claude Code v2.1.261 or later |
| `error`          | string           | error category: `authentication_failed`, `oauth_org_not_allowed`, `account_on_hold`, `billing_error`, `rate_limit`, `overloaded`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `cloud_credential_error`, or `unknown`   |
| `uuid`           | string           | unique event identifier                                                                                                                                                                                                                               |
| `session_id`     | string           | session the event belongs to                                                                                                                                                                                                                          |


[​](#read-session-metadata)

Read session metadata

The `system/init` event reports session metadata including the model, tools, MCP servers, and loaded plugins. It is the first event in the stream unless startup events precede it:

- `plugin_install` events, when [`CLAUDE_CODE_SYNC_PLUGIN_INSTALL`](env-vars.md) is set.
- [`hook_started`, `hook_progress`, and `hook_response` events](../05-Agent-SDK/agent-sdk-typescript.md#sdkhookstartedmessage), while a configured [`SessionStart`](../07-Hooks/hooks.md#sessionstart) or [`Setup`](../07-Hooks/hooks.md#setup) hook runs. These stream as the hook produces them.

The event also carries an optional `capabilities` array of strings naming the protocol behaviors this Claude Code version implements, such as `interrupt_receipt_v1` or `interrupt_cancel_queued_v1`. Check it to feature-detect instead of comparing version strings, and ignore values you don’t recognize. See [`SDKSystemMessage`](../05-Agent-SDK/agent-sdk-typescript.md#sdksystemmessage) for the capability list.


[​](#fail-ci-when-a-plugin-or-mcp-server-doesn’t-load)

Fail CI when a plugin or MCP server doesn’t load

Use the plugin fields in the `system/init` event to catch a plugin that didn’t load:

| Field           | Type  | Description                                                                                                                                                                                                                                                                              |
|-----------------|-------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `plugins`       | array | plugins that loaded successfully, each with `name` and `path`                                                                                                                                                                                                                            |
| `plugin_errors` | array | plugin load-time errors, each with `plugin`, `type`, and `message`. Includes unsatisfied dependency versions and `--plugin-dir` load failures such as a missing path or invalid archive. A plugin that didn’t load is absent from `plugins`. The key is omitted when there are no errors |

When a `--plugin-dir` directory or archive itself fails to load, its `plugin_errors` entry includes the resolved absolute path as `path`. Use it to tell which of several `--plugin-dir` values failed. The `path` field requires Claude Code v2.1.283 or later. Use the MCP server fields the same way. When you pass [`--mcp-config`](cli-reference.md#cli-flags) with `-p`, Claude Code waits for still-pending servers before running the first turn, up to the [`MCP_TIMEOUT`](env-vars.md) startup timeout, 30 seconds by default. A remote server with a [cached tool list](../05-Agent-SDK/agent-sdk-mcp.md#connection-timing) skips the wait, shows `pending` in `system/init`, and connects on its first tool call. In a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments-configuration.md#connection-timing), a shorter wait applies instead. The wait requires Claude Code v2.1.221 or later. Claude Code validates each `--mcp-config` entry at startup and skips entries that fail validation, for example a `url` entry with no `type`. The run continues and exits cleanly, so check these fields to catch a server that never loaded:

| Field               | Type  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                   |
|---------------------|-------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `mcp_servers`       | array | MCP servers in the session, each with `name` and `status`                                                                                                                                                                                                                                                                                                                                                                                     |
| `mcp_server_errors` | array | `--mcp-config` entries skipped by config validation, each with `name`, `type`, and `message`. `type` is a skip category such as `unknown_type`, `url_missing_type`, `invalid_config`, or `reserved_name`; treat values you don’t recognize as a generic skip. Affected servers are absent from `mcp_servers`. The key is omitted when there are no errors, so a CI gate can fail on a non-empty array. Requires Claude Code v2.1.219 or later |

When you run the command by hand in a terminal, Claude Code also prints a startup warning to stderr, such as `Warning: 1 MCP server skipped due to invalid config:`, followed by the reason for each skipped entry. When you redirect stderr, or when a program such as a CI runner or an SDK host captures it, Claude Code prints no warning and reports the skipped entries only in the `mcp_server_errors` field. The warning requires Claude Code v2.1.219 or later.


[​](#track-plugin-installs)

Track plugin installs

When [`CLAUDE_CODE_SYNC_PLUGIN_INSTALL`](env-vars.md) is set, Claude Code emits `system/plugin_install` events while marketplace plugins install before the first turn. Use these to surface install progress in your own UI.

| Field        | Type                                                     | Description                                                                                                    |
|--------------|----------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|
| `type`       | `"system"`                                               | message type                                                                                                   |
| `subtype`    | `"plugin_install"`                                       | identifies this as a plugin install event                                                                      |
| `status`     | `"started"`, `"installed"`, `"failed"`, or `"completed"` | `started` and `completed` bracket the overall install; `installed` and `failed` report individual marketplaces |
| `name`       | string, optional                                         | marketplace name, present on `installed` and `failed`                                                          |
| `error`      | string, optional                                         | failure message, present on `failed`                                                                           |
| `uuid`       | string                                                   | unique event identifier                                                                                        |
| `session_id` | string                                                   | session the event belongs to                                                                                   |


[​](#auto-approve-tools)

Auto-approve tools

Use `--allowedTools` to let Claude use certain tools without prompting. Listing `Read` and `Edit` lets Claude read and edit files without asking for permission, apart from reads from [network paths](permissions.md#network-paths). Listing `Bash` does the same for shell commands, except in a run that starts in [auto mode](permission-modes.md#how-auto-mode-evaluates-actions), where Claude Code drops a bare `Bash` entry as a broad allow rule and auto mode evaluates each command instead. This example runs a test suite and fixes failures with those three tools listed:

```python
claude -p "Run the test suite and fix any failures" \
  --allowedTools "Bash,Read,Edit"
```

Calls to tools you didn’t list run if they need no approval. In a [Manual mode](permission-modes.md#available-modes) `claude -p` run, a call that needs approval is denied unless something approves it, such as a [`PermissionRequest` hook](../07-Hooks/hooks.md#permissionrequest) or a [`--permission-prompt-tool`](cli-reference.md#cli-flags). With Claude Code v2.1.302 or later, `claude -p` runs start in Manual mode when [nothing sets a permission mode](permission-modes.md#which-mode-a-non-interactive-run-starts-in). To set a baseline for the whole session instead of listing individual tools, pass a [permission mode](permission-modes.md) with `--permission-mode`, such as `auto`, `dontAsk`, or `acceptEdits`:

- **`auto`**: pass `--permission-mode auto` to have a classifier review most actions instead of you
- **`dontAsk`**: Claude Code denies every call that would otherwise prompt, which is useful for locked-down CI runs, though a [mod](../08-Plugins-Skills/plugins-mods-overview.md) you installed can still approve some of those calls. To check which calls a mod can approve, see [Extend permissions with hooks](permissions.md#precedence-among-rules-hooks-and-mods). Actions that need no approval in Manual mode still run, such as file reads in your working directories and the [read-only command set](permissions.md#read-only-commands). Actions covered by your `--allowedTools` entries or `permissions.allow` rules also run. `AskUserQuestion`, connector tools [your organization set to `ask`](../06-MCP-Tools/General/mcp.md#organization-controls-on-connector-tools), MCP tools marked [`requiresUserInteraction`](../06-MCP-Tools/General/mcp.md#require-approval-for-a-specific-tool), and [reads from network paths](permissions.md#network-paths) are denied even when an allow rule matches
- **`acceptEdits`**: Claude writes files without prompting, and Claude Code auto-approves common filesystem commands such as `mkdir`, `touch`, `mv`, and `cp`. The [actions no mode auto-approves](permission-modes.md#actions-no-mode-auto-approves) still apply. Apart from the read-only command set, other shell commands and network requests still need an `--allowedTools` entry or a `permissions.allow` rule. See [what `acceptEdits` auto-approves](permission-modes.md#auto-approve-file-edits-with-acceptedits-mode) for the full list

This example applies lint fixes with `acceptEdits` as the baseline:

```python
claude -p "Apply the lint fixes" --permission-mode acceptEdits
```


[​](#turn-off-permission-prompts-in-unattended-runs)

Turn off permission prompts in unattended runs

Pass `--permission-prompts none` when nobody is available to answer permission prompts, for example in a scheduled job. The flag matters most when your run has a permission host: an Agent SDK app with a [`canUseTool` callback](../05-Agent-SDK/agent-sdk-user-input.md), or an MCP tool you pass with [`--permission-prompt-tool`](cli-reference.md#cli-flags). Without the flag, your run waits for that host to answer each permission request. With the flag, your run doesn’t consult the host or wait on it. Anything that would prompt is denied unless a `PermissionRequest` hook allows it, Claude is told that nobody can approve the request and not to retry it, and the run continues. In a `-p` run with no host, these requests are denied either way, and the flag also tells Claude not to retry them. Permission rules, [`PermissionRequest` hooks](../07-Hooks/hooks.md#permissionrequest), and the permission mode you set still decide every call first; Claude Code denies only the requests that nothing else resolves. This example runs an unattended task in [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode). The classifier reviews each action as usual, and Claude Code denies anything that would have fallen back to a prompt:

```python
claude -p "Update the dependency pins and run the tests" --permission-mode auto --permission-prompts none
```

With `--permission-prompts none`, Claude Code removes the tools that need an answer from a person, such as [`AskUserQuestion`](tools-reference.md#askuserquestion-tool-behavior), so Claude can’t call them. Any [MCP elicitation request](../06-MCP-Tools/General/mcp.md#respond-to-mcp-elicitation-requests) that no [`Elicitation` hook](../07-Hooks/hooks.md#elicitation) answers is cancelled. With `--output-format stream-json`, denials appear as `permission_denied` system messages, and the final result message lists them in `permission_denials`.

The `--permission-prompts` flag requires Claude Code v2.1.259 or later. Earlier versions reject it with an unknown-option error.


[​](#create-a-commit)

Create a commit

This example reviews staged changes and creates a commit with an appropriate message:

```python
claude -p "Look at my staged changes and create an appropriate commit" \
  --allowedTools "Bash(git diff *),Bash(git log *),Bash(git status *),Bash(git commit *)"
```

The `--allowedTools` flag uses [permission rule syntax](settings-reference.md#permission-rule-syntax). The trailing ` *` enables prefix matching, so `Bash(git diff *)` allows any command starting with `git diff`. The space before `*` is important: without it, `Bash(git diff*)` would also match `git diff-index`.

Command support differs in `-p` mode:

- User-invoked [skills](../08-Plugins-Skills/skills.md) and custom commands work. Include `/skill-name` in the prompt string and Claude Code expands it before running.
- Built-in commands that only run in the terminal interface, such as `/login`, aren’t available.
- `/model`, `/effort`, `/fast`, `/color`, and `/rename` accept the value as an argument, for example `/model sonnet`, and `/mcp` with no argument prints a text summary of server status. These forms follow each command’s [availability notes](commands.md#all-commands).
- To change a setting, pass `key=value` to `/config`, for example `/config thinking=false`.
- `/output-style <style>` switches [output styles](output-styles.md) and `/output-style` alone lists them. Requires Claude Code v2.1.269 or later.


[​](#customize-the-system-prompt)

Customize the system prompt

Use `--append-system-prompt` to add instructions while keeping Claude Code’s default behavior. This example pipes a PR diff to Claude and instructs it to review for security vulnerabilities. Save it as a shell script, for example `review.sh`:

```python
gh pr diff "$1" | claude -p \
  --append-system-prompt "You are a security engineer. Review for vulnerabilities." \
  --output-format json
```

In the script, `"$1"` stands for the first argument you pass on the command line. Run `bash review.sh 123` and the shell replaces `"$1"` with `123`, so the script fetches the diff for PR 123. Claude Code prints the review as JSON, with the text in the `result` field. See [system prompt flags](cli-reference.md#system-prompt-flags) for more options including `--system-prompt` to fully replace the default prompt. If you replace it, the run also starts without the [git status snapshot](settings-reference.md#includegitinstructions).


[​](#continue-conversations)

Continue conversations

Use `--continue` to continue the most recent conversation, or `--resume` with a session ID to continue a specific conversation. On Claude Code v2.1.257 or later, when you pass `--continue`, Claude Code opens a [background session](sessions.md#where-the-session-picker-looks) that has finished, but not one that is still running. This example runs a review, then sends follow-up prompts:

```python
# First request
claude -p "Review this codebase for performance issues"

# Continue the most recent conversation
claude -p "Now focus on the database queries" --continue
claude -p "Generate a summary of all issues found" --continue
```

If you’re running multiple conversations, capture the session ID to resume a specific one:

```python
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"
```

You can run the two commands from different directories: Claude Code [finds the session by its ID](sessions.md#where-the-session-picker-looks) in any project on this machine. In place of the session ID, you can pass `--resume` the absolute path to a session’s `.jsonl` [transcript file](sessions.md#where-transcripts-are-stored), and Claude Code continues the conversation stored in that file.


[​](#next-steps)

Next steps

- [Agent SDK quickstart](../05-Agent-SDK/agent-sdk-quickstart.md): build your first agent with Python or TypeScript
- [CLI reference](cli-reference.md): all CLI flags and options
- [GitHub Actions](github-actions.md): use the Agent SDK in GitHub workflows
- [GitLab CI/CD](gitlab-ci-cd.md): use the Agent SDK in GitLab pipelines

---

## Set up Claude Code (local mode) for a HIPAA-ready organization - Claude Code Docs

Source: https://code.claude.com/docs/en/hipaa-setup
Path: 02-Claude-Code-CLI/hipaa-setup.md

## On this page

- [Prepare computers before the HIPAA configuration is applied](#prepare-computers-before-the-hipaa-configuration-is-applied)
  - [Check how developers sign in and connect](#check-how-developers-sign-in-and-connect)
  - [Check how a computer connects](#check-how-a-computer-connects)
  - [Update Claude Code and Claude Desktop](#update-claude-code-and-claude-desktop)
  - [What developers see on an older version](#what-developers-see-on-an-older-version)
  - [Allow network access](#allow-network-access)
  - [Deploy managed settings](#deploy-managed-settings)
  - [What each key does](#what-each-key-does)
  - [Confirm the settings loaded](#confirm-the-settings-loaded)
  - [Sessions the managed settings keys don’t block](#sessions-the-managed-settings-keys-don%E2%80%99t-block)
- [Confirm the configuration on a computer](#confirm-the-configuration-on-a-computer)
- [What developers see in Claude Code](#what-developers-see-in-claude-code)
  - [Anthropic credentials in commands, hooks, and MCP servers](#anthropic-credentials-in-commands-hooks-and-mcp-servers)
- [Manage local session data](#manage-local-session-data)
  - [Claude Code data](#claude-code-data)
  - [Code tab data](#code-tab-data)
  - [Cowork data](#cowork-data)
  - [Delete session data right away](#delete-session-data-right-away)
  - [Offboard a developer](#offboard-a-developer)
- [Related resources](#related-resources)

Security and data

# Set up Claude Code (local mode) for a HIPAA-ready organization

Copy pageCopy page

Prepare developers’ computers to run Claude Code (local mode) under the HIPAA configuration. Covers versions, network access, managed settings, and local data.

Copy pageCopy page

The HIPAA configuration is an organization setting on Claude Enterprise plans, for organizations that handle protected health information (PHI) and have a [Business Associate Agreement (BAA)](../13-Enterprise-Admin/business-associate-agreements-baa-for-commercial-customers.md) with Anthropic. It applies to Claude Code (local mode) and Cowork (local mode), and it restricts features in both products.

“(local mode)” means a local session, not a [cloud session](claude-code-on-the-web.md). Local sessions run in one of these places:

- Claude Code in the terminal
- Claude Code in the Code tab of Claude Desktop
- Cowork in Claude Desktop

The Claude Code extensions for VS Code and JetBrains aren’t part of (local mode). They keep working with the HIPAA configuration applied, but your BAA doesn’t cover them. See the [Implementation Guide](https://trust.anthropic.com/resources?s=l1wrssd9hsbi4gak0tp5a6&name=%5Banthropic%5D-hipaa-ready-offering-implementation-guide) for the full list of Eligible Services.

This page is for the IT or security administrator who prepares developers’ computers. The Primary Owner of your Claude organization applies the configuration itself. [Use Claude Code (local mode) and Cowork (local mode) on a HIPAA-ready Enterprise plan](https://support.claude.com/en/articles/17318731) explains what your BAA includes, how the configuration is applied, and how to schedule the date it’s applied. If members of your organization also use Cowork, follow [Set up Cowork (local mode) for a HIPAA-ready organization](https://claude.com/docs/cowork/hipaa-setup) as well. It covers the Claude Desktop policy and Cowork’s local data. The table shows when to do each part of the setup:

| When                                | What to do                                                                                                                                                                          |
|:------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Before the configuration is applied | [Prepare computers](#prepare-computers-before-the-hipaa-configuration-is-applied): check how developers connect, update the apps, allow network access, and deploy managed settings |
| After it’s applied                  | The Code tab is off until an Owner turns it back on. [Confirm the configuration on a computer](#confirm-the-configuration-on-a-computer)                                            |
| Ongoing                             | [Manage local session data](#manage-local-session-data)                                                                                                                             |


[​](#prepare-computers-before-the-hipaa-configuration-is-applied)

Prepare computers before the HIPAA configuration is applied

We recommend you start with the tasks in this section and complete them before the configuration is applied.


[​](#check-how-developers-sign-in-and-connect)

Check how developers sign in and connect

The HIPAA configuration takes effect only in sessions where a developer signs in with a Claude Enterprise account and Claude Code connects directly to the Claude API. On any other connection, developers can keep using Claude Code, but it doesn’t apply the [HIPAA configuration](#what-developers-see-in-claude-code). The table shows which connections are eligible. To find out whether your BAA covers a session in a “No” row, see [Use Claude Code (local mode) and Cowork (local mode) on a HIPAA-ready Enterprise plan](https://support.claude.com/en/articles/17318731).

| How Claude Code connects                                                                                                                           | Eligible for the HIPAA configuration                                                                 |
|:---------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------|
| A Claude Enterprise account, connecting directly to the Claude API                                                                                 | Yes                                                                                                  |
| Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, Claude Platform on AWS, or a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) | No                                                                                                   |
| An [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) or any other custom `ANTHROPIC_BASE_URL`                                                                    | No                                                                                                   |
| `ANTHROPIC_AUTH_TOKEN` or `apiKeyHelper`, on a computer with no Claude Enterprise sign-in                                                          | No                                                                                                   |
| A Claude Console API key or [federation credentials](authentication.md#anthropic-profiles-and-federation-credentials)                        | No. These sessions belong to a Claude Console organization, which has its own agreement and settings |


[​](#check-how-a-computer-connects)

Check how a computer connects

Open a terminal on the computer, run `claude`, and enter `/status` at the prompt. The **Status** tab shows these lines:

| Line                              | When it appears                                                                                                                                                                 |
|:----------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `Login method` and `Organization` | The session is signed in with a claude.ai account. For a Claude Enterprise account, `Login method` reads `Claude Enterprise account` and `Organization` shows your organization |
| `API provider`                    | Only when the session uses a cloud provider or a Claude apps gateway                                                                                                            |
| `Anthropic base URL`              | Only when `ANTHROPIC_BASE_URL` is set                                                                                                                                           |

If a computer uses a connection that isn’t eligible for the HIPAA configuration, you can use [managed settings](#deploy-managed-settings) to block cloud providers, gateways, and credentials set with `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper`.


[​](#update-claude-code-and-claude-desktop)

Update Claude Code and Claude Desktop

The HIPAA configuration requires Claude Code v2.1.285 or later and Claude Desktop v2.19675.0 or later. If your organization uses both the terminal and the [Claude Desktop app](../16-Mobile-Desktop/desktop.md), update both. To read the installed Claude Code version, run this command in a terminal. It’s the same in Bash, Zsh, and PowerShell:

```python
claude --version
```

A supported installation prints `2.1.285 (Claude Code)` or a higher number. To read the installed Claude Desktop version, see [Check your version](../16-Mobile-Desktop/desktop.md#check-your-version).


[​](#what-developers-see-on-an-older-version)

What developers see on an older version

For organizations with the HIPAA configuration, Anthropic’s servers reject requests from versions older than the minimum version. Anthropic raises the minimum version over time, and there’s nothing for you to configure.

| App            | What a developer sees on an older version                                                                                                                                                     |
|:---------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Claude Code    | Each request fails with an [`API Error`](errors.md#claude-code-does-not-support-this-model) that says the version is older than the minimum version your organization’s policy requires |
| Claude Desktop | An **Update required** dialog that tells the developer to update Claude Desktop to continue using the **Code** tab                                                                            |

To keep developers on a supported version, [keep Claude Code updated](../01-Getting-Started/setup.md#update-claude-code). For Claude Desktop, see [Update Claude Desktop](https://claude.com/docs/cowork/hipaa-setup#update-claude-desktop).


[​](#allow-network-access)

Allow network access

Allow the hosts in this table through your proxy and firewall, over HTTPS on port 443. Allow each whole host, not individual paths.

| Host                                             | Needed for                                                                                                       |
|:-------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------|
| `api.anthropic.com`                              | Claude API requests, telemetry, and the organization policy that tells Claude Code the HIPAA configuration is on |
| `claude.ai`, `claude.com`, `platform.claude.com` | Sign-in and token refresh                                                                                        |
| `sso.claude.com`                                 | Sign-in, when your organization uses single sign-on                                                              |
| `downloads.claude.ai`                            | The native installer and its updates                                                                             |
| `mcp-proxy.anthropic.com`                        | [Connectors from claude.ai](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai)                                         |

This table lists the hosts a native install of Claude Code needs in the terminal to sign in, run, and update. These pages list the rest:

- **Other install methods and optional features**: [Network access requirements](../13-Enterprise-Admin/network-config.md#network-access-requirements) lists the hosts that npm and Homebrew installs check for updates, and the hosts for features such as plugin installs
- **The Code tab and Cowork**: [Desktop network access requirements](../16-Mobile-Desktop/desktop.md#network-access-requirements) lists the additional hosts Claude Desktop needs
- **Proxies that inspect TLS**: [Custom CA certificates](../13-Enterprise-Admin/network-config.md#custom-ca-certificates) shows how to trust your proxy’s certificate

Sessions that go through a corporate HTTPS proxy are still eligible for the HIPAA configuration, as long as the proxy can reach the hosts in the table. Claude Code learns that your organization has the HIPAA configuration by fetching your organization’s policy from `api.anthropic.com`, when it starts and again about every hour while the session is in use. The policy is a record of your organization’s HIPAA status and the feature restrictions that follow from it. To check whether one computer has fetched the policy, see [Confirm the configuration on a computer](#confirm-the-configuration-on-a-computer).


[​](#deploy-managed-settings)

Deploy managed settings

You can use [managed settings](../13-Enterprise-Admin/managed-settings.md) to direct developers to sign in with a Claude Enterprise account, to block cloud providers and gateways, and to set how many days every computer keeps local session data. The settings apply whether or not the HIPAA configuration is in effect. The settings in this section are a sample that we recommend as a starting point. Your organization is responsible for deciding what its own environment needs and for confirming that its configuration meets those needs. The following sample sets four keys that you could add to the [managed settings](../13-Enterprise-Admin/managed-settings.md#choose-a-delivery-mechanism) your organization deploys:

```python
{
  "forceLoginMethod": "claudeai",
  "forceLoginOrgUUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "allowedProviders": ["anthropic"],
  "cleanupPeriodDays": 30
}
```

For a fuller `managed-settings.json` with sandboxing, a network allowlist, credential protections, and local data retention, see `settings-hipaa.json` and `README-hipaa.md` in the [settings examples repository](https://github.com/anthropics/claude-code/tree/main/examples/settings).


[​](#what-each-key-does)

What each key does

The table shows what to set each key to and what Claude Code enforces for it.

| Key                                                                  | Set it to                                                                                                                                                                       | What Claude Code enforces                                                               |
|:---------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------|
| [`forceLoginMethod`](settings-reference.md#forceloginmethod)   | `"claudeai"`                                                                                                                                                                    | Claude Code directs developers to claude.ai sign-in instead of Claude Console           |
| [`forceLoginOrgUUID`](settings-reference.md#forceloginorguuid) | Your organization ID, which an [Owner](../13-Enterprise-Admin/server-managed-settings.md#access-control) can copy from [claude.ai admin settings](https://claude.ai/admin-settings/organization) | Claude Code exits at startup when the claude.ai sign-in belongs to another organization |
| [`allowedProviders`](settings-reference.md#allowedproviders)   | `["anthropic"]`                                                                                                                                                                 | Claude Code refuses to start on a cloud provider or a gateway                           |
| [`cleanupPeriodDays`](settings-reference.md#cleanupperioddays) | The number of days your records policy lets a computer keep session data                                                                                                        | Every computer deletes old session data after the same number of days                   |

Check the `forceLoginOrgUUID` value before you deploy it. If it doesn’t match your organization ID, Claude Code exits at startup for every developer who signs in with a claude.ai account.

The HIPAA configuration doesn’t limit `cleanupPeriodDays`, so a developer can raise it in their own settings. When you set it in managed settings, Claude Code ignores the developer’s value. With `forceLoginMethod` or `forceLoginOrgUUID` set, Claude Code also refuses sessions that authenticate with `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper`.


[​](#confirm-the-settings-loaded)

Confirm the settings loaded

On a computer that has the settings, run `claude`, sign in with a Claude Enterprise account, and enter `/status`. The `Setting sources` line lists `Enterprise managed settings` followed by the source in parentheses, such as `(file)`, and the `Allowed providers` line reads `Anthropic API (managed allowedProviders)`. If `Setting sources` doesn’t list it, or the `Allowed providers` line is missing, see [Check that a policy is in force](../13-Enterprise-Admin/managed-settings.md#check-that-a-policy-is-in-force).


[​](#sessions-the-managed-settings-keys-don’t-block)

Sessions the managed settings keys don’t block

Even with these keys deployed, some sessions can still run without the HIPAA configuration:

- **Claude Console sign-ins and federation credentials**: `forceLoginOrgUUID` checks only claude.ai sign-ins. [Restrict login to your organization](authentication.md#restrict-login-to-your-organization) lists what Claude Code checks for each sign-in path and credential.
- **Server-managed settings**: if your organization also uses [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md), have an Owner add the same keys there. [How Claude Code combines managed sources](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) explains which source applies.
- **Versions older than v2.1.285**: these versions ignore `allowedProviders`, so they can still start on a cloud provider or a gateway. To make v2.1.163 through v2.1.284 refuse to start, you can add [`requiredMinimumVersion`](settings-reference.md#requiredminimumversion) set to `"2.1.285"` to the same managed settings as the [sample keys](#deploy-managed-settings). Versions before v2.1.163 ignore `requiredMinimumVersion` as well as `allowedProviders`, so [update those computers](#update-claude-code-and-claude-desktop).

To find out whether your BAA covers a session that runs without the HIPAA configuration, see [Use Claude Code (local mode) and Cowork (local mode) on a HIPAA-ready Enterprise plan](https://support.claude.com/en/articles/17318731).


[​](#confirm-the-configuration-on-a-computer)

Confirm the configuration on a computer

Run this check on one managed computer after the configuration is applied to your organization.

1

Restart Claude Code

Quit any running session, open a terminal, and run `claude`. A running session that’s in use picks up the configuration within about an hour without a restart. When you restart, Claude Code fetches it right away.

2

Check the startup notice

Confirm that Claude Code prints `Per your organization's policy, some features are limited · /status for details` when it starts.

3

Check the footer

Confirm that a `HIPAA configured` tag appears at the right of the footer, below the prompt. Before v2.1.286, the tag read `HIPAA`.

4

Run /status

Enter `/status` at the prompt. Confirm that the **Status** tab lists `HIPAA` on the `Organization configuration` line.

5

Check Claude Desktop

Applying the HIPAA configuration turns the Code tab off for your organization. If your organization uses it, ask an Owner to go to [**Organization settings \> Claude Code**](https://claude.ai/admin-settings/claude-code) and turn on the **Desktop** toggle. For Cowork, see [Confirm the HIPAA configuration in Claude Desktop](https://claude.com/docs/cowork/hipaa-setup#confirm-the-hipaa-configuration-in-claude-desktop).Reload Claude Desktop or sign in again. Confirm that the title bar shows a **HIPAA configured** label. On a Mac, open the sidebar to see it.

If `HIPAA` is missing from `/status`, check these causes in order:

1.  **The wrong account or connection**: confirm that `/status` shows your organization on the `Organization` line, and shows no `API provider` or `Anthropic base URL` line. [Check how developers sign in and connect](#check-how-developers-sign-in-and-connect) lists which sign-in and connection methods aren’t eligible for the configuration.
2.  **A blocked policy fetch**: look for an `Organization policy` line in `/status`, which gives the cause. Outside a session, run `claude doctor` and read the same line, which says where Claude Code loaded the policy from or why the policy didn’t load. Allow `api.anthropic.com` through your proxy, then restart Claude Code.
3.  **The configuration isn’t applied yet**: ask the Primary Owner whether they have applied the configuration.


[​](#what-developers-see-in-claude-code)

What developers see in Claude Code

With the HIPAA configuration applied, some Claude Code features are off or behave differently in the terminal. The table lists the changes developers are most likely to ask you about. The [HIPAA feature availability table](../13-Enterprise-Admin/business-associate-agreements-baa-for-commercial-customers.md) lists every Claude Code and Cowork feature, including the ones an Owner can turn back on.

| What a developer notices                                                          | Why                                                                                                                                |
|:----------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------|
| The WebFetch tool is unavailable                                                  | WebFetch is off. Web search still works                                                                                            |
| `--cloud`, `/teleport`, and [Remote Control](remote-control.md) are refused | [Cloud sessions](claude-code-on-the-web.md) and Remote Control are off                                                       |
| `/feedback` and `/bug` are unavailable                                            | Feedback submission is off                                                                                                         |
| Claude can’t publish an [artifact](artifacts.md)                            | Artifact publishing is off                                                                                                         |
| MCP tools load into context upfront                                               | [MCP tool search](../06-MCP-Tools/General/mcp.md#configure-tool-search) is off. Neither `ENABLE_TOOL_SEARCH` nor managed settings turns it back on   |
| An MCP server or hook that reads `ANTHROPIC_API_KEY` stops authenticating         | Claude Code [removes Anthropic credentials](#anthropic-credentials-in-commands-hooks-and-mcp-servers) from the processes it starts |
| Restrictions remain after `/login` to a different organization                    | The HIPAA status lasts until Claude Code restarts                                                                                  |


[​](#anthropic-credentials-in-commands-hooks-and-mcp-servers)

Anthropic credentials in commands, hooks, and MCP servers

With the HIPAA configuration applied, Claude Code removes the credentials it uses to reach Anthropic, such as `ANTHROPIC_API_KEY` and `ANTHROPIC_AUTH_TOKEN`, from the environment of the shell commands, hooks, and MCP servers it starts. The HIPAA configuration doesn’t remove cloud provider or GitHub credentials, so a command that pushes to GitHub or calls another service still works with that developer’s access. Your BAA with Anthropic doesn’t cover the data it sends there. See the [Implementation Guide](https://trust.anthropic.com/resources?s=l1wrssd9hsbi4gak0tp5a6&name=%5Banthropic%5D-hipaa-ready-offering-implementation-guide) for the full list of Eligible Services. To limit which commands and hosts Claude can use, see [permission rules](permissions.md) and the [sandbox](sandboxing.md).


[​](#manage-local-session-data)

Manage local session data

Claude Code (local mode) and Cowork (local mode) store session data on each developer’s computer. Securing and deleting that data is your organization’s responsibility.


[​](#claude-code-data)

Claude Code data

[Application data](claude-directory.md#application-data) lists what Claude Code (local mode) stores on a computer, what its retention sweep deletes after `cleanupPeriodDays`, and what stays until someone deletes it. The same page states what differs in an organization with the HIPAA configuration applied. The retention sweep runs only when someone starts Claude Code, so a computer where nobody starts it keeps its data.


[​](#code-tab-data)

Code tab data

The Code tab stores data in these places:

- **Transcripts**: in `~/.claude/projects/`, alongside terminal transcripts. [Cleaned up automatically](claude-directory.md#cleaned-up-automatically) states when the retention sweep deletes them.
- **The Claude Desktop data folder**: `~/Library/Application Support/Claude` on macOS. On Windows, `%APPDATA%\Claude`, or `%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude` for the installer downloaded from Anthropic, so check both. With the HIPAA configuration applied, Claude Desktop deletes local Code tab sessions that have been inactive for longer than `cleanupPeriodDays`, including starred ones. It deletes them only while it’s running. Claude Desktop handles a deleted session’s worktree in one of these ways:
  - **No uncommitted changes, the session isn’t starred or pinned, and no other session is using the worktree**: Claude Desktop removes the worktree
  - **Any other case**: the worktree stays on the computer

On Windows, `~` means `%USERPROFILE%`.


[​](#cowork-data)

Cowork data

[Manage Cowork data on each computer](https://claude.com/docs/cowork/hipaa-setup#manage-cowork-data-on-each-computer) lists where Cowork (local mode) stores data and what Claude Desktop deletes.


[​](#delete-session-data-right-away)

Delete session data right away

If your organization needs a developer’s session data removed before the retention sweep deletes it, you can remove most of it with one command. Sign in to the computer as that developer, open any shell, and run the command for the installed Claude Code version. On Claude Code v2.1.288 or later, run `claude purge`:

```python
claude purge --all --yes
```

On v2.1.126 through v2.1.287, run `claude project purge`, which takes the same flags:

```python
claude project purge --all --yes
```

Either command deletes every project’s transcripts and auto memory, the entries in `tasks/`, `debug/`, and `file-history/`, `history.jsonl`, and the project entries in `~/.claude.json`. Without `--yes`, it prints the plan and asks first. The purge leaves other paths that can hold session content, such as pasted text in `paste-cache/`. [Clear local data](claude-directory.md#clear-local-data) lists the paths you can delete by hand. To clear a computer completely, for example before you reassign it, [wipe it](#offboard-a-developer).


[​](#offboard-a-developer)

Offboard a developer

Removing a developer’s seat or account deletes nothing on their computer, and `/logout` doesn’t delete session data either. To remove all of it, you can wipe the computer with your device management tool.


[​](#related-resources)

Related resources

- [Set up Cowork (local mode) for a HIPAA-ready organization](https://claude.com/docs/cowork/hipaa-setup)
- [Deploy managed settings](../13-Enterprise-Admin/managed-settings.md)
- [HIPAA settings example](https://github.com/anthropics/claude-code/tree/main/examples/settings)
- [Enterprise network configuration](../13-Enterprise-Admin/network-config.md)
- [Zero data retention](zero-data-retention.md)
- [Legal and compliance](../13-Enterprise-Admin/legal-and-compliance.md)
- [Data usage](../13-Enterprise-Admin/data-usage.md)

---

## How Claude Code works - Claude Code Docs

Source: https://code.claude.com/docs/en/how-claude-code-works
Path: 02-Claude-Code-CLI/how-claude-code-works.md

## On this page

- [The agentic loop](#the-agentic-loop)
  - [Models](#models)
  - [Tools](#tools)
- [What Claude can access](#what-claude-can-access)
- [Environments and interfaces](#environments-and-interfaces)
  - [Execution environments](#execution-environments)
  - [Interfaces](#interfaces)
- [Work with sessions](#work-with-sessions)
  - [Work across branches](#work-across-branches)
  - [Resume or fork sessions](#resume-or-fork-sessions)
  - [The context window](#the-context-window)
  - [Context Claude Code adds on its own](#context-claude-code-adds-on-its-own)
  - [When context fills up](#when-context-fills-up)
  - [Manage context with skills and subagents](#manage-context-with-skills-and-subagents)
- [Stay safe with checkpoints and permissions](#stay-safe-with-checkpoints-and-permissions)
  - [Undo changes with checkpoints](#undo-changes-with-checkpoints)
  - [Control what Claude can do](#control-what-claude-can-do)
- [Work effectively with Claude Code](#work-effectively-with-claude-code)
  - [Ask Claude Code for help](#ask-claude-code-for-help)
  - [It’s a conversation](#it%E2%80%99s-a-conversation)
  - [Interrupt and steer](#interrupt-and-steer)
  - [Delegate, don’t dictate](#delegate-don%E2%80%99t-dictate)
- [What’s next](#what%E2%80%99s-next)

Core concepts

# How Claude Code works

Copy pageCopy page

Understand the agentic loop, built-in tools, and how Claude Code interacts with your project.

Copy pageCopy page

Claude Code is an agentic assistant that runs in your terminal. While it excels at coding, it can help with anything you can do from the command line: writing docs, running builds, searching files, researching topics, and more. This guide covers the core architecture, built-in capabilities, and [tips for working effectively](#work-effectively-with-claude-code). For step-by-step walkthroughs, see [Common workflows](common-workflows.md). For extensibility features like skills, MCP, and hooks, see [Extend Claude Code](features-overview.md).


[​](#the-agentic-loop)

The agentic loop

When you give Claude a task, it works through three phases: **gather context**, **take action**, and **verify results**. These phases blend together. Claude uses tools throughout, whether searching files to understand your code, editing to make changes, or running tests to check its work.

The loop adapts to what you ask. A question about your codebase might only need context gathering. A bug fix cycles through all three phases repeatedly. A refactor might involve extensive verification. Claude decides what each step requires based on what it learned from the previous step, chaining dozens of actions together and course-correcting along the way. You’re part of this loop too. You can interrupt at any point to steer Claude in a different direction, provide additional context, or ask it to try a different approach. Claude works autonomously but stays responsive to your input. The agentic loop is powered by two components: [models](#models) that reason and [tools](#tools) that act. Claude Code is the layer around the model that provides the tools and manages the context the model sees. This surrounding layer is what the term agentic harness refers to.


[​](#models)

Models

Claude Code uses Claude models to understand your code and reason about tasks. Claude can read code in any language, understand how components connect, and figure out what needs to change to accomplish your goal. For complex tasks, it breaks work into steps, executes them, and adjusts based on what it learns. [Multiple models](model-config.md) are available with different tradeoffs. Sonnet handles most coding tasks well. Opus provides stronger reasoning for complex architectural decisions. Switch with `/model` during a session or start with `claude --model <name>`. When this guide says “Claude chooses” or “Claude decides,” it’s the model doing the reasoning.


[​](#tools)

Tools

Tools are what make Claude Code agentic. Without tools, Claude can only respond with text. With tools, Claude can act: read your code, edit files, run commands, search the web, and interact with external services. Each tool use returns information that feeds back into the loop, informing Claude’s next decision. The built-in tools generally fall into five categories, each representing a different kind of agency.

| Category              | What Claude can do                                                                                                                                        |
|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| **File operations**   | Read files, edit code, create new files, rename and reorganize                                                                                            |
| **Search**            | Find files by pattern, search content with regex, explore codebases                                                                                       |
| **Execution**         | Run shell commands, start servers, run tests, use git                                                                                                     |
| **Web**               | Search the web, fetch documentation, look up error messages                                                                                               |
| **Code intelligence** | See type errors and warnings after edits, jump to definitions, find references (requires [code intelligence plugins](../08-Plugins-Skills/plugins-code-intelligence.md)) |

These are the primary capabilities. Claude also has tools for spawning subagents, asking you questions, and other orchestration tasks. See [Tools available to Claude](tools-reference.md) for the complete list. Claude chooses which tools to use based on your prompt and what it learns along the way. When you say “fix the failing tests,” Claude might:

1.  Run the test suite to see what’s failing
2.  Read the error output
3.  Search for the relevant source files
4.  Read those files to understand the code
5.  Edit the files to fix the issue
6.  Run the tests again to verify

Each tool use gives Claude new information that informs the next step. This is the agentic loop in action. **Extending the base capabilities:** The built-in tools are the foundation. You can extend what Claude knows with [skills](../08-Plugins-Skills/skills.md), connect to external services with [MCP](../06-MCP-Tools/General/mcp.md), automate workflows with [hooks](../07-Hooks/hooks.md), and offload tasks to [subagents](../09-Agents-Patterns/sub-agents.md). These extensions form a layer on top of the core agentic loop. See [Extend Claude Code](features-overview.md) for guidance on choosing the right extension for your needs.


[​](#what-claude-can-access)

What Claude can access

When you run `claude` in a directory, Claude Code gains access to:

- **Your project.** Files in your directory and subdirectories, plus files elsewhere with your permission.
- **Your terminal.** Any command you could run: build tools, git, package managers, system utilities, scripts. If you can do it from the command line, Claude can too.
- **Your git state.** Current branch, uncommitted changes, and recent commit history.
- **Your [CLAUDE.md](memory.md).** A markdown file where you store project-specific instructions, conventions, and context that Claude should know every session. If your repository has an AGENTS.md for other coding agents, Claude [can read that](memory.md#agents-md) in place of a CLAUDE.md.
- **[Auto memory](memory.md#auto-memory).** Learnings Claude saves automatically as you work, like your preferences. The first 200 lines or 25KB of MEMORY.md, whichever comes first, load at the start of each session.
- **Extensions you configure.** [MCP servers](../06-MCP-Tools/General/mcp.md) for external services, [skills](../08-Plugins-Skills/skills.md) for workflows, [subagents](../09-Agents-Patterns/sub-agents.md) for delegated work, and [Claude in Chrome](../03-IDE-Integrations/chrome.md) for browser interaction.

Because Claude sees your whole project, it can work across it. When you ask Claude to “fix the authentication bug,” it searches for relevant files, reads multiple files to understand context, makes coordinated edits across them, runs tests to verify the fix, and commits the changes if you ask. This is different from inline code assistants that only see the current file.


[​](#environments-and-interfaces)

Environments and interfaces

The [agentic loop](#the-agentic-loop), [tools](#tools), and capabilities are the same everywhere you use Claude Code. What changes is where the code executes and how you interact with it.


[​](#execution-environments)

Execution environments

Claude Code runs in three environments, each with different tradeoffs for where your code executes.

| Environment        | Where code runs                                                                                                    | Use case                                                   |
|--------------------|--------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------|
| **Local**          | Your machine                                                                                                       | Default. Full access to your files, tools, and environment |
| **Cloud**          | Anthropic-managed VMs, or [self-hosted environments](../13-Enterprise-Admin/self-hosted-environments.md) your organization operates | Offload tasks, work on repos you don’t have locally        |
| **Remote Control** | Your machine, controlled from a browser                                                                            | Use the web UI while execution and your files stay local   |


[​](#interfaces)

Interfaces

You can access Claude Code through the terminal, the [desktop app](../16-Mobile-Desktop/desktop.md), [IDE extensions](../03-IDE-Integrations/vs-code.md), [claude.ai/code](https://claude.ai/code), [Remote Control](remote-control.md), [Slack](../14-Connectors/slack.md), and [CI/CD pipelines](github-actions.md). The interface determines how you see and interact with Claude, but the underlying agentic loop is identical. See [Use Claude Code everywhere](code-home.md#use-claude-code-everywhere) for the full list.


[​](#work-with-sessions)

Work with sessions

Claude Code saves your conversation locally as you work. Each message, tool use, and result is written to a plaintext JSONL file under `~/.claude/projects/`, which enables [rewinding](#undo-changes-with-checkpoints), [resuming, and forking](#resume-or-fork-sessions) sessions. Before Claude makes code changes, it also snapshots the affected files so you can revert if needed. For paths, retention, and how to clear this data, see [application data in `~/.claude`](claude-directory.md#application-data). **Sessions are independent.** Each new session starts with a fresh context window, without the conversation history from previous sessions. Claude can persist learnings across sessions using [auto memory](memory.md#auto-memory), and you can add your own persistent instructions in [CLAUDE.md](memory.md).


[​](#work-across-branches)

Work across branches

Each Claude Code conversation is a session tied to your current directory. The `/resume` picker shows sessions from the current worktree by default, with keyboard shortcuts to widen the list to other worktrees or projects. See [Manage sessions](sessions.md#use-the-session-picker) for the full list of picker shortcuts and how name resolution works. Claude sees your current branch’s files. When you switch branches, Claude sees the new branch’s files, but your conversation history stays the same. Claude remembers what you discussed even after switching. Since sessions are tied to directories, you can run parallel Claude sessions by using [git worktrees](worktrees.md), which create separate directories for individual branches.


[​](#resume-or-fork-sessions)

Resume or fork sessions

Resuming a session with `claude --continue` or `claude --resume` reopens it under the same session ID and appends new messages to the existing conversation. Forking with `--fork-session` or `/branch` copies the history into a new session ID, leaving the original unchanged.

For the resume flags, the `/resume` picker, naming, and what happens when the same session is open in two terminals, see [Manage sessions](sessions.md).


[​](#the-context-window)

The context window

Claude’s context window holds your conversation history, file contents, command outputs, [CLAUDE.md](memory.md), [auto memory](memory.md#auto-memory), loaded skills, and system instructions. As you work, context fills up. Claude compacts automatically, but instructions from early in the conversation can get lost. Put persistent rules in CLAUDE.md, and run `/context` to see what’s using space. For an interactive walkthrough of what loads and when, see [Explore the context window](context-window.md).


[​](#context-claude-code-adds-on-its-own)

Context Claude Code adds on its own

If Claude follows a rule you didn’t write, such as adding a `Co-Authored-By` trailer to a commit, the rule may have come from a [system reminder](glossary.md#system-reminder). As you work, Claude Code adds its own context to the conversation alongside your messages:

- Your CLAUDE.md files
- The instructions of your [output style](output-styles.md)
- A note when a file Claude read earlier changes on disk
- The commit and pull request attribution lines

To change or remove the attribution lines, set [`attribution`](settings-reference.md#attribution). To remove Claude Code’s built-in commit and pull request instructions, set [`includeGitInstructions`](settings-reference.md#includegitinstructions) to `false`. For the other switches, see [Turn off the context your agent replaces](../05-Agent-SDK/agent-sdk-modifying-system-prompts.md#turn-off-the-context-your-agent-replaces).


[​](#when-context-fills-up)

When context fills up

Claude Code manages context automatically as you approach the limit. It clears older tool outputs first, then summarizes the conversation if needed. Your requests and key code snippets are preserved; detailed instructions from early in the conversation may be lost. Put persistent rules in CLAUDE.md rather than relying on conversation history. To control what’s preserved during compaction, add a “Compact Instructions” section to CLAUDE.md or run `/compact` with a focus (like `/compact focus on the API changes`). If a single file or tool output is so large that context refills immediately after each summary, Claude Code stops auto-compacting after a few attempts and shows an error instead of looping. See [Auto-compaction stops with a thrashing error](troubleshooting.md#auto-compaction-stops-with-a-thrashing-error) for recovery steps. Run `/context` to see what’s using space. MCP tool definitions are deferred by default and loaded on demand via [tool search](../06-MCP-Tools/General/mcp.md#scale-with-mcp-tool-search), so only tool names and server instructions consume context until Claude uses a specific tool.


[​](#manage-context-with-skills-and-subagents)

Manage context with skills and subagents

Beyond compaction, you can use other features to control what loads into context. [Skills](../08-Plugins-Skills/skills.md) load on demand. Claude sees skill descriptions at session start, but the full content only loads when a skill is used. For skills you invoke manually, set `disable-model-invocation: true` to keep descriptions out of context until you need them. For skills you didn’t write, use [`skillOverrides`](../08-Plugins-Skills/skills.md#override-skill-visibility-from-settings) to do the same from settings. [Subagents](../09-Agents-Patterns/sub-agents.md) work in their own context window. A subagent starts fresh unless it’s a [fork](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation), which starts with a copy of your conversation so far. Either way, the subagent’s tool calls stay out of your context, and Claude gets back a summary when the subagent finishes. See [context costs](features-overview.md#understand-context-costs) for what each feature costs, and [reduce token usage](../17-Billing-Plans/costs.md#reduce-token-usage) for tips on managing context.


[​](#stay-safe-with-checkpoints-and-permissions)

Stay safe with checkpoints and permissions

Claude has two safety mechanisms: checkpoints let you undo file changes, and permissions control what Claude can do without asking.


[​](#undo-changes-with-checkpoints)

Undo changes with checkpoints

**File edits are reversible.** Before Claude edits a file, it snapshots the current contents. If something goes wrong, press `Esc` twice to rewind to a previous state, or ask Claude to undo. Checkpoints are separate from git and remain available when you resume a conversation. They only cover file changes, and a restore [skips symlinked and hard-linked files](checkpointing.md#symlinked-and-hard-linked-paths-not-restored). Actions that affect remote systems (databases, APIs, deployments) can’t be checkpointed. You control those with your permission mode and permission rules.


[​](#control-what-claude-can-do)

Control what Claude can do

Choose a permission mode to set what Claude can do without asking you. Press `Shift+Tab` to cycle through the permission modes:

- **Auto**: a classifier reviews most actions in the background and blocks the risky ones instead of asking you. With Claude Code v2.1.283 or later, it’s the [built-in starting permission mode](permission-modes.md#which-mode-a-session-starts-in) for interactive terminal and VS Code sessions, and on earlier versions only on Pro, Max, and Team plans
- **Manual**: Claude asks before file edits and shell commands
- **Accept edits**: Claude edits files and runs common filesystem commands like `mkdir` and `mv` without asking, still asks for other commands
- **Plan**: Claude explores and proposes a plan without editing your source files

You can also allow specific commands in `.claude/settings.json` so Claude doesn’t ask each time. This is useful for trusted commands like `npm test` or `git status`. Settings can be scoped from organization-wide policies down to personal preferences. See [Permissions](permissions.md) for details.

------------------------------------------------------------------------


[​](#work-effectively-with-claude-code)

Work effectively with Claude Code

These tips help you get better results from Claude Code. For more on specific prompts, verification, and planning, see [Best practices](best-practices.md).


[​](#ask-claude-code-for-help)

Ask Claude Code for help

Claude Code can teach you how to use it. Ask questions like “how do I set up hooks?” or “what’s the best way to structure my CLAUDE.md?” and Claude will explain. Built-in commands also guide you through setup:

- `/init` generates a starter CLAUDE.md for your project
- `/doctor` runs a setup checkup that diagnoses installation and configuration issues and can fix them


[​](#it’s-a-conversation)

It’s a conversation

Claude Code is conversational. You don’t need perfect prompts. Start with what you want, then refine:

```python
Fix the login bug
```

\[Claude investigates, tries something\]

```python
That's not quite right. The issue is in the session handling.
```

\[Claude adjusts approach\] When the first attempt isn’t right, you don’t start over. You iterate.


[​](#interrupt-and-steer)

Interrupt and steer

You can redirect Claude at any point without starting over. Do either of these:

- **Press `Esc`** to stop Claude immediately. The running tool call is canceled and Claude waits for your next instruction. If you have messages queued, Claude Code [sends them next](interactive-mode.md#queue-messages-while-claude-works).
- **Type a correction and press `Enter`** without stopping Claude. The message shows as queued in the conversation. If Claude is running tool calls, it reads the message as soon as those calls finish, within the same turn, and adjusts before its next step. [Queue messages while Claude works](interactive-mode.md#queue-messages-while-claude-works) covers when other queued entries are sent.


[​](#delegate-don’t-dictate)

Delegate, don’t dictate

Think of delegating to a capable colleague. Give context and direction, then trust Claude to figure out the details:

```python
The checkout flow is broken for users with expired cards.
The relevant code is in src/payments/. Can you investigate and fix it?
```

You don’t need to specify which files to read or what commands to run. Claude figures that out.


[​](#what’s-next)

What’s next

## Extend with features

Add skills and MCP connections

## Common workflows

Step-by-step guides for typical tasks

---

## How to create custom skills | Claude Help Center

Source: https://support.claude.com/en/articles/12512198-how-to-create-custom-skills
Path: 02-Claude-Code-CLI/how-to-create-custom-skills.md

# How to create custom skills


Skills are available for users on Free, Pro, Max, Team, and Enterprise plans. This feature requires **[code execution to be enabled](../15-Claude-AI-Features/create-and-edit-files-with-claude.md#h_1c99382190)**. Skills are also available in beta for Claude Code users and for all API users using the code execution tool.

Custom skills let you enhance Claude with specialized knowledge and workflows specific to your organization or personal work style. This article explains how to create, structure, and test your own skills.

Skills can be as simple as a few lines of instructions or as complex as multi-file packages with executable code. The best skills:

- Solve a specific, repeatable task

- Have clear instructions that Claude can follow

- Include examples when helpful

- Define when they should be used

- Are focused on one workflow rather than trying to do everything

------------------------------------------------------------------------

## Record a skill

Recording a skill is available on Pro, Max, and Team plans, in Cowork in Claude for Mac. It isn't available in chat, on Windows, or on Free and Enterprise plans.

Instead of writing a skill by hand, you can record yourself doing a task and let Claude build the skill from what it observes. You send Claude a video of your screen, clicks, typing, and voice, and Claude proposes a skill for you to review before you save it.

### Before you record

1.  Update to the latest version of Claude for Mac.

2.  Grant the macOS permissions Claude asks for the first time you record: **Accessibility** for mouse and keyboard tracking, and **Screen recording** for screen visibility. macOS may ask you to restart Claude.

3.  Close any files, apps, or conversations you don't want captured.

**Warning:** Don't type passwords or secrets, or display sensitive information or private conversations while recording. Everything on your screen is captured for the length of the session, along with anything you say.

### Record your workflow

1.  Open Cowork in Claude for Mac.

2.  Start a recording one of two ways:

    1.  Click the "+" button in the composer, then select "Record a skill."

    2.  Go to **[Customize \> Skills](https://claude.ai/customize/skills)**, click "Add," then select "Record your screen."

3.  Click "Start recording." To narrate as you work, leave the microphone on. Use the microphone control to mute it or choose a different input.

4.  Do the task the way you normally would. The capture bar shows that recording is in progress and counts the steps it's captured.

5.  Click "Done" when you're finished, or "Discard" to throw the recording away without creating anything.

A recording can run for about 10 minutes. A countdown appears in the capture bar when you have about a minute left. When it reaches zero, recording stops and everything you've captured up to that point is sent to Claude, the same as if you'd clicked "Done."

**Tip:** Talk through what you're doing while you record. Narration gives Claude context it can't get from your screen alone, like why you skip a step or how you choose between two options.

### What happens after you click Done

Claude starts a Cowork task and reviews the recording, then proposes a skill. Depending on what it finds, you'll see one of two things:

- **A new skill,** marked **NEW** on the proposal card. Click "Save" to keep it, or "Dismiss" to discard the proposal.

- **An update to an existing skill.** If the recording overlaps a skill you already have, Claude proposes changes to that skill instead. The card shows which skill the proposal is based on. Click "Update" to apply the changes, or "Dismiss" to discard them.

Expand **Content** on the proposal card to read the skill before you decide.

Skills you save from a recording appear in **[Customize \> Skills](https://claude.ai/customize/skills)** and work like any other skill. You can edit them, share them, and delete them on the same terms.

### What's kept from a recording

The video and audio from your recording aren't retained. After you send your recording to Claude, Claude reviews the recording to build the skill. What's saved afterward is a set of screenshots from the session, which you can view by expanding the **Recorded demonstration** step in the task.

Because those screenshots live in the Cowork task, deleting the task removes them. See **[Get started with Claude Cowork](https://support.claude.com/en/articles/13345190-get-started-with-claude-cowork)** for how task deletion and retention work.

------------------------------------------------------------------------

## Create a skill.md file

Every skill consists of a directory containing at minimum a skill.md file, which is the core of the skill. This file must start with a YAML frontmatter to hold name and description fields, which are required metadata. It can also contain additional metadata, instructions for Claude or reference files, executable scripts, or tools.

### Required metadata fields

**name:** A human-friendly name for your skill (64 characters maximum)

- **Example:** Brand Guidelines

**description:** A clear description of what the skill does and when to use it.

- This is critical—Claude uses this to determine when to invoke your skill (200 characters maximum).

- **Example:** Apply Acme Corp brand guidelines to presentations and documents, including official colors, fonts, and logo usage.

### Optional metadata fields

**dependencies:** Software packages required by your skill.

- **Example:** python\>=3.8, pandas\>=1.5.0

The metadata in the skill.md file serves as the first level of a progressive disclosure system, providing just enough information for Claude to know when the skill should be used without having to load all of the content.

### Markdown body

The markdown body is the second level of detail after the metadata, so Claude will access this if needed after reading the metadata. Depending on your task, Claude can access the skill.md file and use the skill.

### Example skill.md

**Brand guidelines skill**

    ## Metadata
    name: Brand Guidelines
    description: Apply Acme Corp brand guidelines to all presentations and documents

    ## Overview
    This skill provides Acme Corp's official brand guidelines for creating consistent, professional materials. When creating presentations, documents, or marketing materials, apply these standards to ensure all outputs match Acme's visual identity. Claude should reference these guidelines whenever creating external-facing materials or documents that represent Acme Corp.

    ## Brand Colors

    Our official brand colors are:
    - Primary: #FF6B35 (Coral)
    - Secondary: #004E89 (Navy Blue)
    - Accent: #F7B801 (Gold)
    - Neutral: #2E2E2E (Charcoal)

    ## Typography

    Headers: Montserrat Bold
    Body text: Open Sans Regular
    Size guidelines:
    - H1: 32pt
    - H2: 24pt
    - Body: 11pt

    ## Logo Usage

    Always use the full-color logo on light backgrounds. Use the white logo on dark backgrounds. Maintain minimum spacing of 0.5 inches around the logo.

    ## When to Apply

    Apply these guidelines whenever creating:
    - PowerPoint presentations
    - Word documents for external sharing
    - Marketing materials
    - Reports for clients

    ## Resources

    See the resources folder for logo files and font downloads.

## Add resources

If you have too much information to add to a single skill.md file (e.g., sections that only apply to specific scenarios), you can add more content by adding files within your skill directory. For example, add a REFERENCE.md file containing supplemental and reference information to your skill directory. Referencing it in skill.md will help Claude decide if it needs to access that resource when executing the skill.

## Add scripts

For more advanced skills, attach executable code files to skill.md, allowing Claude to run code. For example, our document skills use the following programming languages and packages:

- Python (pandas, numpy, matplotlib)

- JavaScript/Node.js

- Packages to help with file editing

- Visualization tools

**Note:** Claude and Claude Code can install packages from standard repositories (Python PyPI, JavaScript npm) when loading skills. It’s not possible to install additional packages at runtime with API Skills—all dependencies must be pre-installed in the container.

------------------------------------------------------------------------

## Package your skill

Once your skill folder is complete:

1.  Ensure the folder name matches your skill's name.

2.  Create a ZIP file of the folder.

3.  The ZIP should contain the skill folder as its root (not a subfolder).

**Correct structure:**

my-skill.zip

└── my-skill/

├── skill.md

└── resources/

**Incorrect structure:**

my-skill.zip

└── (files directly in ZIP root)

------------------------------------------------------------------------

## Test your skill

### Before uploading

1\. Review your skill.md for clarity.

2\. Check that the description accurately reflects when Claude should use the skill.

3\. Verify all referenced files exist in the correct locations.

4\. Test with example prompts to ensure Claude invokes it appropriately.

### After uploading to Claude

1\. Enable the skill in **[Customize \> Skills](https://claude.ai/customize/skills)**.

2\. Try several different prompts that should trigger it.

3\. Review Claude's thinking to confirm it's loading the skill.

4\. Iterate on the description if Claude isn't using it when expected.

When you're iterating on a skill with Claude in chat, you can edit the skill files directly where they open beside the conversation. Highlight the text you want changed, click "Edit with Claude," and type your request. For skills with multiple files, leave edit requests across the files and send them together, and Claude applies them in one pass. Learn more about **[editing artifacts](https://support.claude.com/en/articles/9487310-what-are-artifacts-and-how-do-i-use-them#h_9cbf05e668)**.

**Note for Team and Enterprise plans:** To make a skill available to all users in your organization, see **[Provision and manage skills for your organization](../15-Claude-AI-Features/provisioning-and-managing-skills-for-your-organization.md)**.

------------------------------------------------------------------------

## Best practices

**Keep it focused:** Create separate skills for different workflows. Multiple focused skills compose better than one large skill.

**Write clear descriptions:** Claude uses descriptions to decide when to invoke your skill. Be specific about when it applies.

**Start simple:** Begin with basic instructions in Markdown before adding complex scripts. You can always expand on the skill later.

**Use examples:** Include example inputs and outputs in your skill.md file to help Claude understand what success looks like.

**Test incrementally:** Test after each significant change rather than building a complex skill all at once.

**Skills can build on each other:** While skills can't explicitly reference other skills, Claude can use multiple skills together automatically. This composability is one of the most powerful parts of the skills feature.

**Review the open Agent Skills specification:** Follow the guidelines at **[agentskills.io](https://agentskills.io)**, so skills you create can work across platforms that adopt the standard.

For a more in-depth guide to skill creation, refer to **[Skill authoring best practices](../04-API-Reference/Agents-Tools/agents-and-tools-agent-skills-best-practices.md)** in our Claude Docs.

------------------------------------------------------------------------

## Security considerations

- Exercise caution when adding scripts to your skill.md file.

- Don't hardcode sensitive information (API keys, passwords).

- Review any skills you download before enabling them.

- Use appropriate MCP connections for external service access.

------------------------------------------------------------------------

## Example skills to reference

Visit our repository on GitHub for example skills you can use as templates: **[https://github.com/anthropics/skills/tree/main/skills](https://github.com/anthropics/skills/tree/main/skills)**.

---

## Interactive mode - Claude Code Docs

Source: https://code.claude.com/docs/en/interactive-mode
Path: 02-Claude-Code-CLI/interactive-mode.md

## On this page

- [Keyboard shortcuts](#keyboard-shortcuts)
  - [General controls](#general-controls)
  - [Text editing](#text-editing)
  - [Word boundaries in editing shortcuts](#make-ctrl-w-delete-back-to-whitespace)
  - [Theme and display](#theme-and-display)
  - [Multiline input](#multiline-input)
  - [Quick commands](#quick-commands)
  - [Transcript viewer](#transcript-viewer)
  - [Voice input](#voice-input)
- [Commands](#commands)
  - [Complete a command mid-prompt](#complete-a-command-mid-prompt)
- [Vim editor mode](#vim-editor-mode)
  - [Mode switching](#mode-switching)
  - [Remap INSERT-mode key sequences](#remap-insert-mode-key-sequences)
  - [Navigation (NORMAL mode)](#navigation-normal-mode)
  - [Editing (NORMAL mode)](#editing-normal-mode)
  - [Text objects (NORMAL mode)](#text-objects-normal-mode)
  - [Visual mode](#visual-mode)
  - [Cancel a question in vim mode](#cancel-a-question-in-vim-mode)
- [Command history](#command-history)
  - [Bring back a cleared draft](#bring-back-a-cleared-draft)
  - [Reverse search with Ctrl+R](#reverse-search-with-ctrl%2Br)
- [Background Bash commands](#background-bash-commands)
  - [How backgrounding works](#how-backgrounding-works)
  - [Shell mode with ! prefix](#shell-mode-with-prefix)
- [Queue messages while Claude works](#queue-messages-while-claude-works)
  - [When Claude Code sends what you queued](#when-claude-code-sends-what-you-queued)
  - [Background a session with messages queued](#background-a-session-with-messages-queued)
  - [Take back what you queued](#take-back-what-you-queued)
- [Prompt suggestions](#prompt-suggestions)
  - [When Claude Code skips suggestions](#when-claude-code-skips-suggestions)
  - [Turn prompt suggestions off](#turn-prompt-suggestions-off)
- [You should know suggestions](#you-should-know-suggestions)
  - [Cost of checks](#cost-of-checks)
  - [Answer a note](#answer-a-note)
  - [Turn off You should know](#turn-off-you-should-know)
- [Emoji shortcodes](#emoji-shortcodes)
- [Check spelling as you type](#check-spelling-as-you-type)
  - [Prerequisites](#prerequisites)
  - [Turn spell checking on or off](#turn-spell-checking-on-or-off)
  - [What Claude Code underlines](#what-claude-code-underlines)
  - [When Claude Code underlines nothing](#when-claude-code-underlines-nothing)
- [Invisible characters in prompts](#invisible-characters-in-prompts)
- [Review changes with /diff](#review-changes-with-%2Fdiff)
  - [Diff panel](#diff-panel)
  - [Diff dialog](#diff-dialog)
- [Side questions with /btw](#side-questions-with-%2Fbtw)
- [Task list](#task-list)
- [Session recap](#session-recap)
- [Wait for a usage limit to reset](#wait-for-a-usage-limit-to-reset)
  - [Cancel the wait](#cancel-the-wait)
  - [Start a wait yourself](#start-a-wait-yourself)
  - [Turn automatic continue off](#turn-automatic-continue-off)
- [PR review status](#pr-review-status)
  - [GitLab merge requests](#gitlab-merge-requests)
- [Issue reference links](#issue-reference-links)
- [See also](#see-also)

Reference

# Interactive mode

Copy pageCopy page

Complete reference for keyboard shortcuts, input modes, and interactive features in Claude Code sessions.

Copy pageCopy page


[​](#keyboard-shortcuts)

Keyboard shortcuts

Keyboard shortcuts may vary by platform and terminal. In [fullscreen rendering](fullscreen.md), press `?` in the transcript viewer to see available shortcuts there.**macOS users**: Option/Alt key shortcuts (`Alt+B`, `Alt+F`, `Alt+D`, `Alt+Y`, `Alt+P`) require configuring Option as Meta in your terminal. See [Enable Option key shortcuts on macOS](terminal-config.md#enable-option-key-shortcuts-on-macos) for the setting in each terminal.


[​](#general-controls)

General controls

| Shortcut                                                                                     | Description                                                                                                                                                                                                                                                                                                                                                    | Context                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
|:---------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `Ctrl+C`                                                                                     | Interrupt, or clear input                                                                                                                                                                                                                                                                                                                                      | Interrupts a running operation. If nothing is running, the first press clears the prompt input and a second press exits Claude Code. To get a cleared draft back, see [Bring back a cleared draft](#bring-back-a-cleared-draft)                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `Ctrl+X Ctrl+K`                                                                              | Stop all running [background subagents](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) in this session, and turn off [artifact auto-replies](artifacts.md#let-claude-reply-to-comments-on-its-own) for the rest of it. Press twice within 3 seconds to confirm. You can press it while a background subagent’s permission prompt is open | Subagent control                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `Ctrl+D`                                                                                     | Exit Claude Code session                                                                                                                                                                                                                                                                                                                                       | The first press shows a confirmation hint and a second press within 800ms exits. When the prompt has text, `Ctrl+D` deletes the character after the cursor instead                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `Ctrl+G` or `Ctrl+X Ctrl+E`                                                                  | Open in default text editor                                                                                                                                                                                                                                                                                                                                    | Edit your prompt or custom response in your default text editor. `Ctrl+X Ctrl+E` is the readline-native binding. Turn on **Show last response in external editor** in `/config` to prepend Claude’s previous reply as `#`-commented context above your prompt; Claude Code strips the comment block when you save                                                                                                                                                                                                                                                                                                                                                    |
| `Ctrl+L`                                                                                     | Redraw the screen                                                                                                                                                                                                                                                                                                                                              | Forces a full terminal redraw, keeping input and conversation history. Use this to recover if the display becomes garbled or partially blank. See [Clear the conversation](fullscreen.md#clear-the-conversation) for fullscreen rendering                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `Ctrl+O`                                                                                     | Toggle transcript viewer                                                                                                                                                                                                                                                                                                                                       | Shows detailed tool usage and execution, with a timestamp and the model used on each assistant message. Also expands lines that collapse by default, such as MCP calls, shown as a single `Called slack 3 times` line, and [messages from your other sessions](cross-session-messaging.md#what-a-message-looks-like), shown as a one-line `Message from @<sender>` preview                                                                                                                                                                                                                                                                                     |
| `Ctrl+R`                                                                                     | Reverse search command history                                                                                                                                                                                                                                                                                                                                 | Search through previous commands interactively                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `Ctrl+V` or `Cmd+V` (iTerm2) or `Alt+V` (Windows and WSL)                                    | Paste image from clipboard                                                                                                                                                                                                                                                                                                                                     | Inserts an `[Image #N]` chip at the cursor so you can reference it positionally in your prompt. On WSL, both `Ctrl+V` and `Alt+V` are bound; use `Alt+V` if your terminal intercepts `Ctrl+V`                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `Ctrl+B`                                                                                     | Background running tasks                                                                                                                                                                                                                                                                                                                                       | Backgrounds Bash commands and agents. Tmux users press twice                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `Ctrl+T`                                                                                     | Toggle Claude’s task checklist                                                                                                                                                                                                                                                                                                                                 | Show or hide [Claude’s to-do checklist](#task-list) in the status area. This is not the background-task view; use [`/tasks`](commands.md) to see running shells and subagents                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `Ctrl+S`                                                                                     | Stash or restore prompt                                                                                                                                                                                                                                                                                                                                        | With text in the input, stashes it and clears the prompt. Pressed again on an empty prompt, restores the stashed text, cursor position, pasted content, and input mode, so a stashed `!` [shell command](#shell-mode-with-prefix) comes back in shell mode                                                                                                                                                                                                                                                                                                                                                                                                           |
| `Ctrl+Z`                                                                                     | Suspend Claude Code                                                                                                                                                                                                                                                                                                                                            | Unix only. Suspends the process to your shell; run `fg` to resume                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `Left/Right arrows`                                                                          | Cycle through dialog tabs                                                                                                                                                                                                                                                                                                                                      | Navigate between tabs in permission dialogs and menus. In a tabbed dialog, the keys switch tabs while the tab row has focus. See [Tabs actions](keybindings.md#tabs-actions) for how focus moves                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `Tab`                                                                                        | Accept an autocomplete suggestion, or add a comment to a permission answer                                                                                                                                                                                                                                                                                     | While autocomplete suggestions are showing in the prompt input, accepts the selected suggestion. On most permission prompts, with **Yes** or **No** focused, opens a comment field on that option, and pressing it again closes the field. See [add a comment when you answer a permission prompt](permissions.md#add-a-comment-when-you-answer-a-permission-prompt)                                                                                                                                                                                                                                                                                           |
| `Up/Down arrows` or `Ctrl+P`/`Ctrl+N`                                                        | Move cursor or navigate command history                                                                                                                                                                                                                                                                                                                        | When the input spans more than one visual row, whether wrapped or multiline, first moves the cursor within the prompt. Once the cursor is on the first or last visual row, pressing again navigates command history. While you have messages queued, `Up` from the first row instead [takes them back](#take-back-what-you-queued)                                                                                                                                                                                                                                                                                                                                   |
| `Esc`                                                                                        | Interrupt Claude, or close a dialog                                                                                                                                                                                                                                                                                                                            | Stop the current response or tool call mid-turn so you can redirect. Claude keeps the work done so far. If you have [messages queued](#queue-messages-while-claude-works), Claude Code sends them next. When a dialog is open, `Esc` closes the dialog. While a footer item is selected, such as a row in the [subagent panel](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) below the prompt, `Esc` [deselects it](keybindings.md#footer-actions) instead of interrupting. On a permission prompt, `Esc` declines the action, the same as [**No** without a comment](permissions.md#add-a-comment-when-you-answer-a-permission-prompt) |
| `Esc` + `Esc`                                                                                | Clear input draft, or rewind                                                                                                                                                                                                                                                                                                                                   | When the prompt input contains text, double `Esc` clears it and saves the draft to history so `Up` recalls it. When the input is empty, double `Esc` opens the [rewind menu](checkpointing.md) to restore or summarize code and conversation from a previous point                                                                                                                                                                                                                                                                                                                                                                                             |
| `Ctrl+Enter` or `Ctrl+X Ctrl+S`                                                              | Send queued messages now                                                                                                                                                                                                                                                                                                                                       | Sends your [queued messages](#queue-messages-while-claude-works), and your draft with them, right away. [When Claude Code sends what you queued](#when-claude-code-sends-what-you-queued) covers what happens to the turn Claude is working on. In [shell mode](#shell-mode-with-prefix), the key only queues your command. In terminals that don’t report extended keys, `Ctrl+Enter` arrives as plain `Enter`; `Ctrl+X Ctrl+S` works in any terminal. Requires Claude Code v2.1.275 or later                                                                                                                                                                       |
| `Shift+Tab`, or `Alt+M` on Windows when the Node or Bun runtime doesn’t enable VT input mode | Cycle permission modes                                                                                                                                                                                                                                                                                                                                         | Cycle through `default` (labeled Manual in the mode indicator), `acceptEdits`, `plan`, and, when available, `bypassPermissions` and then `auto`. From `auto`, the first press switches to `default`. See [permission modes](permission-modes.md). On a file permission prompt, the same key closes an open [comment field](permissions.md#add-a-comment-when-you-answer-a-permission-prompt). With no field open, it selects the option that allows the action for the rest of the session, when the prompt offers that option                                                                                                                           |
| `Option+P` (macOS) or `Alt+P` (Windows/Linux)                                                | Switch model                                                                                                                                                                                                                                                                                                                                                   | Switch models without clearing your prompt                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `Option+T` (macOS) or `Alt+T` (Windows/Linux)                                                | Toggle extended thinking                                                                                                                                                                                                                                                                                                                                       | Enable or disable extended thinking mode. Has no effect on Opus 5.5, Sonnet 5.5, Haiku 5.5, or the Fable models, which always use extended thinking. Works on macOS without configuring Option as Meta                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `Option+O` (macOS) or `Alt+O` (Windows/Linux)                                                | Toggle fast mode                                                                                                                                                                                                                                                                                                                                               | Enable or disable [fast mode](fast-mode.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |


[​](#text-editing)

Text editing

| Shortcut                   | Description                          | Context                                                                                                                                                                                           |
|:---------------------------|:-------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `Ctrl+A`                   | Move cursor to start of current line | In multiline input, moves to the start of the current logical line                                                                                                                                |
| `Ctrl+E`                   | Move cursor to end of current line   | In multiline input, moves to the end of the current logical line                                                                                                                                  |
| `Ctrl+K`                   | Delete to end of line                | Stores deleted text for pasting                                                                                                                                                                   |
| `Ctrl+U`                   | Delete from cursor to line start     | Stores deleted text for pasting. Repeat to clear across lines in multiline input. On macOS, terminal emulators including iTerm2 and Terminal.app map `Cmd+Backspace` to this shortcut             |
| `Ctrl+W`                   | Delete back to previous whitespace   | Stores deleted text for pasting. One press removes a whole path or `--flag=value`. To delete only the previous word, press `Option+Delete` on macOS or `Ctrl+Backspace` on Windows                |
| `Ctrl+Y`                   | Paste deleted text                   | Pastes the text you last deleted with one of the word or line deletion shortcuts, such as `Ctrl+K`, `Ctrl+U`, or `Ctrl+W`                                                                         |
| `Alt+Y` (after `Ctrl+Y`)   | Cycle paste history                  | After pasting, cycle through previously deleted text. Requires [Option as Meta](#keyboard-shortcuts) on macOS                                                                                     |
| `Alt+B`                    | Move cursor back one word            | Word navigation. Requires [Option as Meta](#keyboard-shortcuts) on macOS                                                                                                                          |
| `Alt+F`                    | Move cursor forward one word         | Moves to the end of the current word, or to the end of the next word when the cursor is between words. Requires [Option as Meta](#keyboard-shortcuts) on macOS                                    |
| `Alt+D`                    | Delete to end of word                | Deletes to the end of the current word, or to the end of the next word when the cursor is between words. Stores deleted text for pasting. Requires [Option as Meta](#keyboard-shortcuts) on macOS |
| `Ctrl+_` or `Ctrl+Shift+-` | Undo last input edit                 | Restores the previous input text and cursor position                                                                                                                                              |


[​](#make-ctrl-w-delete-back-to-whitespace)

Word boundaries in editing shortcuts

The word shortcuts `Alt+B`, `Alt+F`, `Alt+D`, `Option+Delete`, and `Ctrl+Backspace` treat a word as a run of letters and digits, so punctuation such as `_`, `.`, and `/` separates words. With `src/utils/foo.ts` in the prompt, repeated presses of `Alt+B` stop at the start of `ts`, `foo`, `utils`, and `src`. `Ctrl+W` is different: it ignores punctuation and deletes back to the previous whitespace, so one press removes all of `src/utils/foo.ts`. In text written without spaces, such as Chinese or Japanese, the word shortcuts still move or delete one word at a time. These readline conventions apply in Claude Code v2.1.261 and later. The [`keybindingFlavor`](settings-reference.md#keybindingflavor) setting that turned them on in earlier versions is deprecated and has no effect. You can’t remap these shortcuts in the [keybindings configuration file](keybindings.md), which has no actions for them.


[​](#theme-and-display)

Theme and display

| Shortcut | Description                                | Context                                                                                                      |
|:---------|:-------------------------------------------|:-------------------------------------------------------------------------------------------------------------|
| `Ctrl+T` | Toggle syntax highlighting for code blocks | Only works inside the `/theme` picker menu. Controls whether code in Claude’s responses uses syntax coloring |


[​](#multiline-input)

Multiline input

| Method           | Shortcut       | Context                                                                                                                                                                                 |
|:-----------------|:---------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Quick escape     | `\` + `Enter`  | Works in all terminals                                                                                                                                                                  |
| Option key       | `Option+Enter` | After enabling [Option as Meta](terminal-config.md#enable-option-key-shortcuts-on-macos) on macOS                                                                                 |
| Shift+Enter      | `Shift+Enter`  | Native in iTerm2, WezTerm, Ghostty, Kitty, Warp, Apple Terminal, Windows Terminal. For other terminals, see [Enter multiline prompts](terminal-config.md#enter-multiline-prompts) |
| Control sequence | `Ctrl+J`       | Works in any terminal without configuration                                                                                                                                             |
| Paste mode       | Paste directly | For code blocks, logs                                                                                                                                                                   |


[​](#quick-commands)

Quick commands

| Shortcut           | Description                    | Notes                                                                                                                                                                                                                                                                                                                                                 |
|:-------------------|:-------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `/` at start       | Command or skill               | See [commands](#commands) and [skills](../08-Plugins-Skills/skills.md)                                                                                                                                                                                                                                                                                               |
| `!` at start       | Shell mode                     | Run a command directly, add its output to the session, and have Claude respond to it                                                                                                                                                                                                                                                                  |
| `@`                | File path mention              | Trigger file path autocomplete. In sessions with [cross-session messaging](cross-session-messaging.md#message-another-session), when you type at least one letter after the `@`, Claude Code also suggests your other live sessions on this machine, so you can tell Claude to message the one you pick. Requires Claude Code v2.1.232 or later |
| `:`                | Emoji shortcode                | Type a full `:name:` to insert the emoji, or two or more characters for suggestions. See [Emoji shortcodes](#emoji-shortcodes). Requires Claude Code v2.1.217 or later                                                                                                                                                                                |
| `?` on empty input | Toggle the shortcut help panel | Typing `?` when the input already contains text inserts the character                                                                                                                                                                                                                                                                                 |


[​](#transcript-viewer)

Transcript viewer

When the transcript viewer is open (toggled with `Ctrl+O`), these shortcuts are available. Run `/tui` with no argument to check which renderer is active. `Ctrl+E` can be rebound via [`transcript:toggleShowAll`](keybindings.md).

| Shortcut             | Description                                                                                                                                                                                                                |
|:---------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `?`                  | Toggle the keyboard shortcut help panel. Requires [fullscreen rendering](fullscreen.md)                                                                                                                              |
| `{` / `}`            | Jump to the previous or next user prompt, like vim paragraph motion. Requires [fullscreen rendering](fullscreen.md)                                                                                                  |
| `Ctrl+E`             | Toggle show all content. Available in the classic renderer only, not in [fullscreen rendering](fullscreen.md)                                                                                                        |
| `[`                  | Write the full conversation to your terminal’s native scrollback so `Cmd+F`, tmux copy mode, and other native tools can search it. Requires [fullscreen rendering](fullscreen.md#search-and-review-the-conversation) |
| `v`                  | Write the conversation to a temporary file and open it in `$VISUAL` or `$EDITOR`. Requires [fullscreen rendering](fullscreen.md)                                                                                     |
| `q`, `Ctrl+C`, `Esc` | Exit transcript view. All three can be rebound via [`transcript:exit`](keybindings.md)                                                                                                                               |


[​](#voice-input)

Voice input

| Shortcut            | Description     | Notes                                                                                                                                                                                      |
|:--------------------|:----------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Hold or tap `Space` | Voice dictation | Requires [voice dictation](voice-dictation.md) to be enabled. Hold to record, or run `/voice tap` for tap-to-toggle. [Rebindable](voice-dictation.md#rebind-the-dictation-key) |


[​](#commands)

Commands

Type `/` in Claude Code to see the commands available to you, or type `/` followed by any letters to filter. The `/` menu lists built-in commands, bundled and user-authored [skills](../08-Plugins-Skills/skills.md), and commands contributed by [plugins](../08-Plugins-Skills/plugins.md) and [MCP servers](../06-MCP-Tools/General/mcp.md#use-mcp-prompts-as-commands). Not all built-in commands are visible to every user since some depend on your platform or plan, and [a few available commands are hidden from the menu by design](commands.md#how-the-command-menu-matches-what-you-type) and run when you type their full name. In [fullscreen rendering](fullscreen.md#use-the-mouse), the `/` command and `@` file suggestion lists also respond to the mouse: hovering highlights a row and clicking accepts it. See the [commands reference](commands.md) for the full list of commands included in Claude Code.


[​](#complete-a-command-mid-prompt)

Complete a command mid-prompt

Command completion also works partway through a prompt: type `/` after a space, then the first letters of a name, as in `run the tests, then /com`. Only commands whose names start with those letters match, so a file path such as `/tmp/notes.md` doesn’t keep a list open. Claude Code runs a command itself only when the command [starts your message](commands.md).

- **In [fullscreen rendering](fullscreen.md)**: the matches open as a list while you type, with no row highlighted, so `Enter` still sends your prompt as typed. Press `Tab` to insert the top match, or pick a row with the arrow keys and `Enter`.
- **Outside fullscreen**: the rest of the top match appears as ghost text at your cursor, with a count such as `+2` when more commands match. Press `Tab` to insert the only match, or to open the list when several match, then pick a row with the arrow keys and `Enter`.

In both renderers, press `Tab` on a bare mid-prompt `/` to list every command. A plugin skill matches on its bare name too, so `/deploy` finds a skill named `myplugin:deploy-app`. When you insert the match, Claude Code writes the full `/myplugin:deploy-app`.


[​](#vim-editor-mode)

Vim editor mode

Enable vim-style editing via `/config` → Editor mode. Claude 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.


[​](#mode-switching)

Mode switching

| Command           | Action                                                                                                    | From mode      |
|:------------------|:----------------------------------------------------------------------------------------------------------|:---------------|
| `Esc` or `Ctrl+[` | Enter NORMAL mode. In terminals that use the Kitty keyboard protocol, `Ctrl+[` requires v2.1.242 or later | INSERT, VISUAL |
| `i`               | Insert before cursor                                                                                      | NORMAL         |
| `I`               | Insert at beginning of line                                                                               | NORMAL         |
| `a`               | Insert after cursor                                                                                       | NORMAL         |
| `A`               | Insert at end of line                                                                                     | NORMAL         |
| `o`               | Open line below                                                                                           | NORMAL         |
| `O`               | Open line above                                                                                           | NORMAL         |
| `v`               | Start character-wise visual selection                                                                     | NORMAL         |
| `V`               | Start line-wise visual selection                                                                          | NORMAL         |


[​](#remap-insert-mode-key-sequences)

Remap INSERT-mode key sequences

The [`vimInsertModeRemaps`](settings-reference.md#viminsertmoderemaps) setting maps a two-key INSERT-mode sequence to Escape, so a mapping like `jj` returns you to NORMAL mode. The following `~/.claude/settings.json` example turns on vim mode and maps `jj` to Escape:

```python
{
  "editorMode": "vim",
  "vimInsertModeRemaps": { "jj": "<Esc>" }
}
```

Each key is exactly two printable characters typed in sequence, and `"<Esc>"` is the only supported target. Entries with a different length or target are ignored. Typing the first character of a sequence inserts it normally. Pressing the second character within one second removes that pending character and switches to NORMAL mode, leaving neither character in your input. After the one-second window, or if a different key follows, both characters stay as literal text, so you can still type a word containing the sequence by pausing between the two keys. Claude Code reads this setting from your user settings file, the `--settings` flag, and [managed settings](../13-Enterprise-Admin/managed-settings.md) only. Entries in a project’s `.claude/settings.json` or `.claude/settings.local.json` are ignored, so a checked-out repository can’t remap your keystrokes.


[​](#navigation-normal-mode)

Navigation (NORMAL mode)

| Command         | Action                                                                                                                                                                          |
|:----------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `h`/`j`/`k`/`l` | Move left/down/up/right                                                                                                                                                         |
| `Space`         | Move right                                                                                                                                                                      |
| `w`             | Next word                                                                                                                                                                       |
| `e`             | End of word                                                                                                                                                                     |
| `b`             | Previous word                                                                                                                                                                   |
| `0`             | Beginning of line                                                                                                                                                               |
| `$`             | End of line                                                                                                                                                                     |
| `^`             | First non-blank character                                                                                                                                                       |
| `gg`            | Beginning of input                                                                                                                                                              |
| `G`             | Beginning of last line                                                                                                                                                          |
| `f{char}`       | Jump to next occurrence of character on the current line                                                                                                                        |
| `F{char}`       | Jump to previous occurrence of character on the current line                                                                                                                    |
| `t{char}`       | Jump to just before next occurrence of character on the current line                                                                                                            |
| `T{char}`       | Jump to just after previous occurrence of character on the current line                                                                                                         |
| `;`             | Repeat last f/F/t/T motion                                                                                                                                                      |
| `,`             | Repeat last f/F/t/T motion in reverse                                                                                                                                           |
| `%`             | Jump to the matching `()`, `[]`, or `{}` bracket, starting from the next bracket on the current line when the cursor isn’t on a bracket. Requires Claude Code v2.1.301 or later |
| `/`             | Open reverse history search, same as `Ctrl+R`. The empty search prompt shows a hint: press `Esc` then `i` then `/` to open the command menu instead                             |

In vim NORMAL mode, if the cursor is at the beginning or end of input and can’t move further, `j`/`k` and `↑`/`↓` navigate command history instead. `←` on an empty prompt opens [agent view](../09-Agents-Patterns/agent-view.md) from NORMAL mode as well as INSERT; before v2.1.219, `←` on an empty prompt did nothing in NORMAL mode.


[​](#editing-normal-mode)

Editing (NORMAL mode)

| Command               | Action                                                                                                                |
|:----------------------|:----------------------------------------------------------------------------------------------------------------------|
| `x`                   | Delete character                                                                                                      |
| `r{char}`             | Replace character under cursor with `{char}`                                                                          |
| `dd`                  | Delete line                                                                                                           |
| `D`                   | Delete to end of line                                                                                                 |
| `dw`/`de`/`db`        | Delete word/to end/back                                                                                               |
| `df{char}`/`dt{char}` | Delete to and including, or up to, the next occurrence of a character on the current line                             |
| `dj`/`dk`             | Delete the current line and the line below or above                                                                   |
| `dgg`/`dG`            | Delete from the current line to the first or last line                                                                |
| `d0`/`c0`/`y0`        | Delete, change, or yank from the cursor back to the beginning of the line. Requires Claude Code v2.1.281 or later     |
| `d%`/`c%`/`y%`        | Delete, change, or yank from the cursor through the bracket that `%` jumps to. Requires Claude Code v2.1.301 or later |
| `cc`                  | Change line                                                                                                           |
| `C`                   | Change to end of line                                                                                                 |
| `cw`/`ce`/`cb`        | Change word/to end/back                                                                                               |
| `s`                   | Substitute character: delete the character under the cursor and enter INSERT mode                                     |
| `S`                   | Substitute line: clear the line and enter INSERT mode                                                                 |
| `yy`/`Y`              | Yank (copy) line                                                                                                      |
| `yw`/`ye`/`yb`        | Yank word/to end/back                                                                                                 |
| `p`                   | Paste after cursor                                                                                                    |
| `P`                   | Paste before cursor                                                                                                   |
| `>>`                  | Indent line                                                                                                           |
| `<<`                  | Dedent line                                                                                                           |
| `J`                   | Join lines                                                                                                            |
| `u`                   | Undo                                                                                                                  |
| `.`                   | Repeat last change                                                                                                    |


[​](#text-objects-normal-mode)

Text objects (NORMAL mode)

Text objects work with operators like `d`, `c`, and `y`:

| Command   | Action                                   |
|:----------|:-----------------------------------------|
| `iw`/`aw` | Inner/around word                        |
| `iW`/`aW` | Inner/around WORD (whitespace-delimited) |
| `i"`/`a"` | Inner/around double quotes               |
| `i'`/`a'` | Inner/around single quotes               |
| `i(`/`a(` | Inner/around parentheses                 |
| `i[`/`a[` | Inner/around brackets                    |
| `i{`/`a{` | Inner/around braces                      |


[​](#visual-mode)

Visual mode

Press `v` for character-wise selection or `V` for line-wise selection. Motions extend the selection, and operators act on it directly.

| Command          | Action                                               |
|:-----------------|:-----------------------------------------------------|
| `d`/`x`          | Delete selection                                     |
| `y`              | Yank selection                                       |
| `c`/`s`          | Change selection                                     |
| `p`              | Replace selection with register contents             |
| `r{char}`        | Replace every selected character with `{char}`       |
| `~`/`u`/`U`      | Toggle, lowercase, or uppercase selection            |
| `>`/`<`          | Indent or dedent selected lines                      |
| `J`              | Join selected lines                                  |
| `o`              | Swap cursor and anchor                               |
| `iw`/`aw`/`i"`/… | Select a text object                                 |
| `v`/`V`          | Toggle between character-wise and line-wise, or exit |

Block-wise visual mode with `Ctrl+V` is not supported.


[​](#cancel-a-question-in-vim-mode)

Cancel a question in vim mode

When you’re typing your own answer in the `Other` row of a [question Claude asks](tools-reference.md#askuserquestion-tool-behavior), press `Esc` twice to cancel the question. To cancel with a single key press instead, [bind another key to cancel the question](keybindings.md#cancel-a-question-with-one-key-press).


[​](#command-history)

Command history

Claude Code keeps a history of the prompts you type, and Up-arrow recall reaches prompts from past sessions of the same project:

- Input history is stored per working directory
- Running `/clear` starts a new session: recall then lists the new session’s prompts first, with earlier sessions’ prompts after them. The previous session’s conversation is preserved and can be resumed.
- Submitting the same prompt twice in a row records one history entry, so pressing Up steps to the previous distinct prompt
- When you recall a prompt that included pasted text, Claude Code sends the full pasted content again when you resubmit. If the content has since been [cleaned up](claude-directory.md#cleaned-up-automatically), Claude Code doesn’t send the literal `[Pasted text #N]` string; see [Paste large content](terminal-config.md#paste-large-content) for what happens to the prompt
- History expansion with `!` is disabled by default


[​](#bring-back-a-cleared-draft)

Bring back a cleared draft

To get back a draft you cleared with `Ctrl+C`, press `Up`, either right away or after you’ve sent a message or command:

- **Right after clearing the draft**: press `Up` once while the prompt is still empty. Requires Claude Code v2.1.288 or later.
- **After sending a message or command**: press `Up` to step back to the draft. Claude Code keeps the ten most recent cleared drafts for the current session, with their pasted text and images, and discards them when you exit. Requires Claude Code v2.1.292 or later.


[​](#reverse-search-with-ctrl+r)

Reverse search with Ctrl+R

Press `Ctrl+R` to interactively search through your command history. In [fullscreen rendering](fullscreen.md), `Ctrl+R` opens a search dialog instead: type to filter, press `Up` and `Down` to move through matches, and press `Ctrl+S` to cycle the scope through this session, this project, and all projects. Press `Enter` or `Tab` to place a match in the prompt input, or `Esc` to cancel. The steps below describe the classic renderer’s inline search:

1.  **Start search**: press `Ctrl+R` to activate reverse history search
2.  **Type query**: enter text to search for in previous commands. The search term is highlighted in matching results
3.  **Navigate matches**: press `Ctrl+R` again to cycle through older matches
4.  **Search scope**: the inline search always searches prompts from all projects
5.  **Accept match**:
    - Press `Tab` or `Esc` to accept the current match and continue editing
    - Press `Enter` to accept and execute the command immediately
6.  **Cancel search**:
    - Press `Ctrl+C` to cancel and restore your original input
    - Press `Backspace` on empty search to cancel

The inline search scans your full prompt history, newest first, with duplicates collapsed to the newest occurrence. The fullscreen dialog searches your whole prompt history in the selected scope, newest first, with duplicates collapsed to the newest occurrence: the most recent prompts appear immediately, and matches from older prompts fill in as Claude Code loads the rest. Matching prompts display with the search term highlighted, so you can find and reuse previous inputs. Accepting a match or canceling the search takes effect immediately, even while Claude Code is still loading the history.


[​](#background-bash-commands)

Background Bash commands

Claude Code supports running Bash commands in the background, allowing you to continue working while long-running processes execute.


[​](#how-backgrounding-works)

How backgrounding works

When Claude Code runs a command in the background, it runs the command asynchronously and immediately returns a background task ID. Claude Code can respond to new prompts while the command continues executing in the background. To run commands in the background, you can either:

- Prompt Claude Code to run a command in the background
- Press `Ctrl+B` to move a regular Bash tool invocation to the background. Tmux users must press `Ctrl+B` twice due to tmux’s prefix key.

When a command reaches its timeout before it finishes, Claude Code automatically [moves it to the background](tools-reference.md#foreground-commands-that-move-to-the-background) instead of stopping it, unless the command starts with `sleep`. If you’ve turned background tasks off with [`CLAUDE_CODE_DISABLE_BACKGROUND_TASKS`](env-vars.md#variables) or by starting in [bare mode](headless.md#start-faster-with-bare-mode), the command stops at its timeout. To change the timeout, set the [Bash timeout environment variables](tools-reference.md#timeout-and-output-limits). **Key features:**

- Output is written to a file and Claude can retrieve it using the Read tool
- Background tasks have unique IDs for tracking and output retrieval
- Background tasks are automatically cleaned up when Claude Code exits. On macOS and Linux, when you stop a background task from [`/tasks`](commands.md) or Claude Code stops it at exit, processes that detached from the task’s shell, such as ones started under `setsid` or `timeout`, stop too
- If you background the session instead of exiting it, your background tasks keep running in the background session. See [background a running session](../09-Agents-Patterns/agent-view.md#from-inside-a-session)
- Background tasks are automatically terminated if output exceeds 5GB, with a note in stderr explaining why
- On macOS and Linux, Claude Code stops your running background tasks when the operating system reports critical memory pressure, provided the session has been idle for at least 30 minutes and no turn or subagent is running
  - The [debug log](debug-your-config.md) says why tasks were stopped, or why a pressure event left them running
  - Set [`CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP`](env-vars.md) to `1` to turn off memory-pressure stops
- Background commands in a local session you work in from a terminal, the desktop app, or the VS Code extension have no time limit. In a session that runs unattended, such as a `-p` run or a cloud session, Claude Code stops a background command at its [time limit](tools-reference.md#time-limit-for-background-commands)
- A background command that a foreground [subagent](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) started ends when that subagent’s run ends, whether it finished, failed, or was interrupted; see [When a background command stops](tools-reference.md#when-a-background-command-stops) in the tools reference

To disable all background task functionality, set the [`CLAUDE_CODE_DISABLE_BACKGROUND_TASKS`](env-vars.md#variables) environment variable to `1`. Starting in [bare mode](headless.md#start-faster-with-bare-mode) turns it off as well. **Common backgrounded commands:**

- Build tools (webpack, vite, make)
- Package managers (npm, yarn, pnpm)
- Test runners (jest, pytest)
- Development servers
- Long-running processes (docker, terraform)


[​](#shell-mode-with-prefix)

Shell mode with `!` prefix

Run shell commands directly without going through Claude by prefixing your input with `!`:

```python
! npm test
! git status
! ls -la
```

Shell mode:

- Adds the command and its output to the conversation context
- Shows real-time progress and output
- Supports the same `Ctrl+B` backgrounding for long-running commands
- Doesn’t require Claude to interpret or approve the command
- Supports history-based autocomplete: type a partial command and press `Tab` to complete from previous `!` commands in the current project
- Supports live file path autocomplete: type a token containing a forward slash, such as `./src/` or `~/`, to see a dropdown of matching files and directories, then press `Tab` to accept. Use forward slashes on Windows too; the dropdown is triggered by `/`, not `\`
- Exit with `Escape`, `Backspace`, or `Ctrl+U` on an empty prompt
- Pasting text that starts with `!` into an empty prompt enters shell mode automatically, matching typed `!` behavior

Unless your session is one of those listed under [strict sandbox mode](sandboxing.md#turn-off-the-retry-with-strict-sandbox-mode), commands you type in shell mode run outside the [sandbox](sandboxing.md) even when you’ve enabled sandboxing, because the sandbox applies to the commands Claude runs. Claude responds to the command output automatically once it lands in the transcript, so you can run `! npm test` and get an explanation of the failures without a second prompt. The response costs the same as sending a normal prompt. To add the output to context without a response instead, set [`respondToBashCommands`](settings-reference.md#respondtobashcommands) to `false` in `settings.json`.


[​](#queue-messages-while-claude-works)

Queue messages while Claude works

Type a message and press `Enter` while Claude is working. Claude Code queues the message instead of interrupting the turn, and lists the queued entries in the conversation until it sends them. You can queue `!` [shell commands](#shell-mode-with-prefix) and most [commands](commands.md) the same way, apart from the commands, such as `/status`, that Claude Code runs as soon as you send them. Sent and queued messages show in gray until Claude starts responding to them, so you can tell which messages Claude hasn’t started on yet. If you queue a message with a selection attached from a [connected IDE](../03-IDE-Integrations/vs-code.md#the-built-in-ide-mcp-server), it keeps the selection you had when you pressed `Enter`, whatever you select afterward.


[​](#when-claude-code-sends-what-you-queued)

When Claude Code sends what you queued

When a queued entry reaches Claude depends on what you queued.

- Messages: if you queue a message while Claude is running tool calls, Claude Code passes it to Claude as soon as those tool calls finish, within the same turn. When the turn ends with messages still queued, they go out without another key press, in the order you typed them
- Commands and shell commands: Claude Code holds them until the turn ends, then runs them one at a time, keeping the order you queued them in

To send what you queued without waiting, press `Ctrl+Enter`. Your queued messages go out right away, with your draft queued behind them if you had typed one. Requires Claude Code v2.1.275 or later. If you queued a `!` shell command ahead of your messages, the key interrupts the turn. Otherwise, what happens to the turn depends on what Claude is doing when you press the key:

- Running shell commands, subagents, or other work that can move to the [background](#background-bash-commands): that work moves to the background and keeps running, and Claude reads your messages in the same turn
- Only writing a response, or running something that can’t move to the background: Claude Code interrupts the turn and sends your messages next. Before v2.1.281, the key interrupted the turn in both cases

In [shell mode](#shell-mode-with-prefix), the key only queues your command. In terminals that don’t report extended keys, `Ctrl+Enter` arrives as plain `Enter` and queues the draft instead; `Ctrl+X Ctrl+S` works in any terminal. Both keys are bindings of the [`chat:sendNow` action](keybindings.md#chat-actions). Press `Esc` to interrupt the turn without submitting your draft. Claude Code keeps what you queued and sends it right away. Claude Code runs some commands as soon as you send them instead of queueing them, among them `/model`, `/effort`, and `/fast`. Each of the three changes a setting: the model, the effort level, or fast mode. Whether Claude Code applies the new setting to the turn Claude is already working on, or only from your next turn, differs by command:

- [`/model`](model-config.md#setting-your-model): once you confirm the [cache warning](prompt-caching.md#switching-models), if Claude Code shows one, Claude Code applies your change to the next request it makes in that turn
- [`/effort`](model-config.md#adjust-effort-level): once you confirm the [cache warning](prompt-caching.md#changing-effort-level), if Claude Code shows one, Claude Code applies your change to the next request it makes in that turn
- [`/fast`](fast-mode.md#toggle-fast-mode): Claude Code keeps the fast mode setting that was active when the turn started, so your speed change applies from your next turn. If your current model doesn’t support fast mode, turning it on also [switches your model](prompt-caching.md#turning-on-fast-mode), and Claude Code uses the new model from its next request in that turn


[​](#background-a-session-with-messages-queued)

Background a session with messages queued

When the session moves to the background after you [press `←`](../09-Agents-Patterns/agent-view.md#switch-sessions-without-leaving-the-terminal), the messages you had queued move with it. Claude reads them there in the order you sent them. Commands and `!` shell commands can’t move, and neither can some messages, such as one with an [IDE selection](../03-IDE-Integrations/vs-code.md#the-built-in-ide-mcp-server) attached. If you press `←` while one of them is queued, the session stays in the foreground and a notice that begins `Cannot open agents` appears. To background the session, get the entry out of the queue and then press `←` again:

- **Commands and `!` shell commands**: wait for them to run at the end of the turn, or [take them back](#take-back-what-you-queued) and clear the input box. While anything else is queued, you can’t take `!` shell commands back, so wait for them to run.
- **Messages that can’t move**: wait until Claude has read them


[​](#take-back-what-you-queued)

Take back what you queued

Press `Up` from the first line of the input box to take back the queued messages and commands. Claude Code removes them from the queue and puts them in the input box, one per line, ahead of any text you had typed. Edit the text and press `Enter` to queue it again as one entry, or clear the input box to drop it. Claude Code takes back queued shell commands only when the input box is empty and you have nothing else queued, and it switches the input box to shell mode when it does. Otherwise it leaves them in the queue, listed with their `!` prefix, and runs them after the turn ends. If you take back queued text while `←` [waits to background the session](../09-Agents-Patterns/agent-view.md#switch-sessions-without-leaving-the-terminal), the text stays in the input box and Claude Code cancels the switch. If you take it back at the moment the session moves, the text disappears with the foreground screen: it wasn’t sent. Each message you took back is saved as its own entry in [command history](#command-history). To recover one, reopen the session and press `Up` on an empty prompt with nothing queued.


[​](#prompt-suggestions)

Prompt suggestions

When you first open a session, Claude Code shows a grayed-out example command in the prompt input to help you get started. It picks this from your project’s git history, so the example reflects files you’ve been working on recently. After Claude responds, Claude Code can suggest your next prompt based on your conversation history, such as a follow-up step from a multi-part request or a natural continuation of your workflow.

- Press `Tab` or `Right arrow` to place the suggestion in the prompt input, then `Enter` to submit
- Start typing to dismiss it

Claude Code generates each of these next-prompt suggestions with a short background request to the same model your session is using. The request counts toward your plan’s usage limits or your API costs. Because it reuses the conversation’s prompt cache, it is mostly cache reads plus a few output tokens, so the added cost is small.


[​](#when-claude-code-skips-suggestions)

When Claude Code skips suggestions

In interactive mode, Claude Code leaves prompt suggestions off by default and hides the **Prompt suggestions** toggle in `/config` in a [session that doesn’t fetch feature flags](env-vars.md#features-that-need-feature-flag-fetching), such as one on a third-party provider or through a Claude apps gateway, and in a [first session after an install or upgrade](env-vars.md#first-session-after-an-install-or-upgrade) whose flags haven’t arrived yet. Claude Code also skips individual suggestions in several situations, including:

- The prompt cache is cold, to avoid unnecessary cost
- After the first turn of a conversation, in some sessions
- The previous response ended in an error
- While you’re in plan mode
- Your account is close to or at its usage limit. To keep this skip from applying until you reach the limit, set [`CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION`](env-vars.md) to `true`. Before v2.1.238, Claude Code skipped suggestions near the limit even with the variable set to `true`
- In an [agent team](../09-Agents-Patterns/agent-teams.md), in teammates’ sessions by default. The lead’s session shows suggestions

The notice `Showing fewer prompt suggestions · use one to bring them back` means Claude Code is showing suggestions less often because you left many in a row unused. To return to the usual frequency, use a suggestion or set [`CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION`](env-vars.md) to `true`. In print mode, Claude Code doesn’t generate suggestions by default. Pass [`--prompt-suggestions`](cli-reference.md#cli-flags) with `-p "<prompt>" --output-format stream-json --verbose` to have Claude Code emit a `prompt_suggestion` message after each turn that generates one. The generator skips very short conversations and cold prompt caches here too, so a single short `-p` query can emit none.


[​](#turn-prompt-suggestions-off)

Turn prompt suggestions off

To disable prompt suggestions entirely, use any of the following:

- Turn off **Prompt suggestions** in `/config`
- Set [`promptSuggestionEnabled`](settings-reference.md#promptsuggestionenabled) to `false` in your settings file
- Set the [`CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION`](env-vars.md) environment variable to `false`, which takes precedence over the setting:

  ``` shiki
  export CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=false
  ```

To turn prompt suggestions off across an organization, set `promptSuggestionEnabled` to `false` in [managed settings](../13-Enterprise-Admin/managed-settings.md). Also set `CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION` to `false` under the managed [`env`](settings-reference.md#env) key so that users can’t re-enable them with their own environment variable.


[​](#you-should-know-suggestions)

You should know suggestions

“You should know” looks for one thing you should know but might have missed, such as a tradeoff Claude chose without calling it out or a result that may be off. When it finds one, it shows a short note above the prompt input:

```python
✦ Heads up · There was a change to how folder sharing starts in June, which may have bumped usage metrics artificially.
  1: Learn more   2: Knew this already   0: Dismiss
```

It’s one of Claude Code’s [built-in mods](../08-Plugins-Skills/plugins-mods-overview.md#mods-built-into-claude-code), a plugin built into Claude Code that is off by default. Requires Claude Code v2.1.287 or later. While it’s on, a side agent rereads the conversation from time to time as Claude works through a longer task. The side agent is a separate request to the same model and has no tools, so it can’t read files, run commands, or change what Claude does. If the mod is available for your organization, `/plugin` lists it when you connect to the Claude API directly with a claude.ai account or a Console API key. It doesn’t when you connect through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) or a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md), or get your key from an [`apiKeyHelper`](settings-reference.md#apikeyhelper). Even with a direct connection, these sessions don’t list it:

- A session that [doesn’t fetch the feature flags](env-vars.md#features-that-need-feature-flag-fetching) the mod depends on, such as one with `DISABLE_TELEMETRY` set
- A [first session after an install or upgrade](env-vars.md#first-session-after-an-install-or-upgrade) whose flags haven’t arrived yet

To turn it on, run this at the Claude Code prompt:

```python
/plugin enable cc-plugin-you-should-know@builtin
```

Where `/plugin` doesn’t list the mod, the enable command answers `Plugin "cc-plugin-you-should-know@builtin" is not installed in this project`.


[​](#cost-of-checks)

Cost of checks

While the mod is on, checks are background requests to the same model your session is using, and they count toward your plan’s usage limits or your API costs. Each check sends what’s already in Claude’s context, meaning the conversation so far with its tool results, followed by the mod’s own instructions and the text of your recent notes. The conversation part is read from the session’s [prompt cache](prompt-caching.md) on the same terms as Claude’s own next request. The instructions, several thousand tokens of them, and the side agent’s reply are billed in full on every check. To watch the checks happen, set [`CLAUDE_CODE_YOU_SHOULD_KNOW_DEBUG=1`](env-vars.md) in your shell before you start Claude Code.


[​](#answer-a-note)

Answer a note

Type the choice’s digit on its own into an empty prompt input. A note offers these choices:

- **Learn more**: opens a short explanation under the note, with its own choices:
  - **Understood**: closes it and marks the topic as known
  - **Chat in main session**: quotes the note into your prompt input so you can add a question and send it to Claude
  - **Dismiss**: closes it without marking the topic as known
- **Knew this already**: closes the note and marks the topic as known.
- **Dismiss**: closes the note.

The main agent doesn’t see a note unless you send it with **Chat in main session**. Claude Code keeps your recent notes and the topics you marked as known in a file whose name starts with `cc-plugin-you-should-know` under `~/.claude/plugins/store/`. Each check, in this session and later ones, lists them to the side agent as ones not to repeat. Claude Code deletes the file once it has gone [`cleanupPeriodDays`](settings-reference.md#cleanupperioddays) without a session reading or writing it. To clear them sooner, delete that file while no session is running.


[​](#turn-off-you-should-know)

Turn off You should know

To turn off You should know, use either of the following:

- At the Claude Code prompt, run `/plugin disable cc-plugin-you-should-know@builtin`, or turn it off from the **Installed** tab of `/plugin`
- After you choose **Dismiss** on a note without opening **Learn more** first, choose **Turn off suggestions** on the `Dismissed.` line, which clears after 20 seconds


[​](#emoji-shortcodes)

Emoji shortcodes

Type a `:` followed by an emoji shortcode in the prompt input to insert the emoji. Requires Claude Code v2.1.217 or later.

- Type a complete shortcode such as `:heart:` and Claude Code replaces it with ❤️ as soon as you type the closing `:`
- Type `:` plus at least two characters of a name, such as `:hea`, to open a suggestion popup, then press `Tab` or `Enter` to insert the highlighted emoji

The shortcode must start the input or follow a space, so a `:` inside a word or URL doesn’t open suggestions. To turn the feature off, set [`emojiCompletionEnabled`](settings-reference.md#emojicompletionenabled) to `false` in `settings.json`. This disables both the suggestion popup and the inline replacement.


[​](#check-spelling-as-you-type)

Check spelling as you type

Claude Code can underline misspelled words in the prompt input while you type. It checks only the text in the input box, never Claude’s replies or your files. It also checks nothing while the input box is in [shell mode](#shell-mode-with-prefix), `Ctrl+R` history search, or [voice dictation](voice-dictation.md). Spell checking is off by default, and Claude Code checks nothing in [screen reader mode](accessibility.md). Requires Claude Code v2.1.235 or later.


[​](#prerequisites)

Prerequisites

- Install [aspell](https://github.com/GNUAspell/aspell), [hunspell](https://github.com/hunspell/hunspell), or [ispell](https://en.wikipedia.org/wiki/Ispell) and make sure it’s on your `PATH`. Claude Code runs the first of the three it finds, in that order, on every platform, including a `.cmd` shim a package manager installs on Windows.
- To check that the program is on your `PATH`, run `aspell --version`, `hunspell --version`, or `ispell -v` in your terminal. A “command not found” error means it isn’t on your `PATH` yet.


[​](#turn-spell-checking-on-or-off)

Turn spell checking on or off

Claude Code reads the [`spellcheck`](settings-reference.md#spellcheck) setting from three places, and ignores it in a project’s `.claude/settings.json` and `.claude/settings.local.json`. Turn it on from whichever one you use:

- User settings

- Command line

- Managed settings

Add `spellcheck` to `~/.claude/settings.json`. It applies in every project you open, like the rest of your [user settings](settings.md#where-settings-live):

```python
{
  "spellcheck": { "enabled": true }
}
```

Save `spellcheck` in a JSON file, such as `spellcheck.json`:

```python
{
  "spellcheck": { "enabled": true }
}
```

Then pass the file to `--settings`. It applies to that session only:

```python
claude --settings spellcheck.json
```

Add `spellcheck` to one of your organization’s [managed settings sources](permissions.md#managed-settings). It applies to every user who receives those settings, and they can’t turn it off:

```python
{
  "spellcheck": { "enabled": true }
}
```

To check that spell checking is on, type a misspelled word and a space. Claude Code underlines the word. If it doesn’t, see [When Claude Code underlines nothing](#when-claude-code-underlines-nothing). To turn spell checking off again, set `enabled` to `false` in the same place, or remove `spellcheck`. To choose which of the three programs Claude Code runs, which dictionary it uses, or the underline color, add any of these fields next to `enabled`, in the same place:

- `checker`: `aspell`, `hunspell`, or `ispell`. Claude Code doesn’t fall back from a checker you name, and treats any other value as `auto`.
- `language`: a dictionary name in your checker’s form, such as `en_GB`. Claude Code ignores any value that isn’t a plain dictionary name, such as a path or a name with spaces, and the checker uses its default dictionary.
- `color`: a color name such as `yellow`, or a `#rrggbb`, `#rgb`, `rgb(r,g,b)`, `ansi256(n)`, or `ansi:<name>` value. Claude Code uses your theme’s error color by default and for any value it doesn’t recognize.

For example, this `spellcheck` setting runs hunspell with its `en_GB` dictionary and underlines words in yellow. It works the same in `~/.claude/settings.json`, in the file you pass to `--settings`, and in managed settings:

```python
{
  "spellcheck": {
    "enabled": true,
    "checker": "hunspell",
    "language": "en_GB",
    "color": "yellow"
  }
}
```

If more than one of the three places has a `spellcheck` setting, Claude Code uses only one of them: managed settings first, then `--settings`, then user settings. It doesn’t combine fields from two places. For example, when `--settings` sets `spellcheck`, a `language` in your user settings has no effect.


[​](#what-claude-code-underlines)

What Claude Code underlines

Shortly 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:

- Commands such as `/help`, `@` mentions, URLs, file paths, and flags such as `--verbose`
- Words with digits, underscores, or a capital letter after the first, and text in backticks

Claude Code also skips Chinese, Japanese, Korean, Thai, Lao, Khmer, and Myanmar text. Claude Code has no word list of its own: a word is misspelled when your checker says so. To stop Claude Code from underlining a word, add the word to your checker’s personal dictionary, following the checker’s own documentation. Claude Code picks up the new word after you restart it.


[​](#when-claude-code-underlines-nothing)

When Claude Code underlines nothing

Claude Code underlines nothing when it can’t keep a checker running:

- No checker is installed, or the one you named in `checker` is missing
- The checker fails twice in a row, at startup or later in the session. Claude Code restarts it after the first failure and stops checking after the second, until you restart Claude Code
- The checker takes more than 15 seconds to answer, three times. Each time, Claude Code leaves the words it was waiting on unmarked; after the third, it stops checking until you restart Claude Code

To find out which of these happened, start `claude --debug` with spell checking on and type a word. Then look for the `[spellcheck]` lines in the debug log at `~/.claude/debug/<session-id>.txt`. One line names the program Claude Code started, or lists the ones it looked for and didn’t find. Later lines say why it stopped. A missing-dictionary error there means the checker has no dictionary for your `language` value, or no default one when `language` is unset. Install one, or set `language` to a dictionary you have.


[​](#invisible-characters-in-prompts)

Invisible characters in prompts

Pasted text can carry Unicode characters that a terminal draws as nothing at all, such as tag characters, bidirectional controls, and zero-width spaces, so a prompt can contain text you never see. To keep copied text from carrying instructions your terminal doesn’t draw, Claude Code removes those characters when you press Enter, before sending anything. It cleans both the prompt and the contents of any collapsed [pasted-text reference](terminal-config.md#paste-large-content) the prompt includes. Claude Code keeps the joiners that Persian and Indic scripts write and the selectors inside emoji sequences. If Claude Code removed anything, that Enter sends nothing. The cleaned prompt goes back into the input box with a notice such as `Removed 3 invisible characters · review and press Enter to send`, and pressing Enter again sends the text as shown. When you pass a prompt on the command line, as in `claude "fix the login bug"`, Claude Code doesn’t wait for a second Enter. It removes the characters, shows a notice, and sends the cleaned prompt. If the cleaned prompt would begin with `/`, Claude Code puts it in the input box for you to review and send instead.


[​](#review-changes-with-/diff)

Review changes with /diff

Run `/diff` to look over the changes in your working tree without leaving Claude Code. You see the edits Claude has made so far alongside anything else you haven’t committed. What `/diff` opens depends on which renderer is active:

- **[Fullscreen rendering](fullscreen.md)**: the [diff panel](#diff-panel) opens beside the conversation. It stays open and updates while you keep working.
- **Classic renderer**: the [diff dialog](#diff-dialog) opens above the prompt, and you close it when you’re done reading.

The panel and the dialog both come from `cc-plugin-diff`, one of the [mods built into Claude Code](../08-Plugins-Skills/plugins-mods-overview.md#mods-built-into-claude-code). If you disable that mod in `/plugin`, `/diff` opens Claude Code’s earlier panel and [diff viewer](keybindings.md#diff-actions) instead. In the changes `/diff` reads from git, a submodule appears as a single entry, and only when the commit it points to changes; edits to files inside the submodule don’t appear there. The panel and the dialog also offer a view of each turn’s edits once Claude has edited files. These turn views come from Claude’s file edits rather than from git, so a change Claude makes through a shell command appears only under `Current`, the working-tree view.


[​](#diff-panel)

Diff panel

The diff panel lists the changed files with their added and removed line counts, and shows each file’s diff under the list. Claude Code refreshes it each time Claude edits a file or runs a shell command. To close the panel, run `/diff` again or click the `✕` in its header. To use the panel you need:

- [Fullscreen rendering](fullscreen.md)
- A git repository
- A terminal at least 110 columns wide
- Claude Code v2.1.287 or later

The panel also opens on its own once Claude starts editing files, if your terminal is at least 144 columns wide. After you’ve opened it yourself with `/diff`, later sessions open it as soon as Claude edits a file in any terminal wide enough to fit it. Close the panel and it stays closed, in this session and later ones, until you run `/diff` again. While the panel is open, you can:

- **Jump to a file**: click its row in the list. Scroll the panel with the mouse wheel. When the file list itself is too long to fit, scroll it with `Alt+Up` and `Alt+Down`, or `Ctrl+Up` and `Ctrl+Down`.
- **Ask Claude about a file’s changes**: click `ask`, at the right of the file’s name above its diff. Claude Code attaches that file’s diff to your next prompt, and the button reads `asked ✓` until you send that prompt. Asking on a second file replaces the first.
- **Show one turn’s edits**: click the `source` picker in the panel’s header, then choose a turn with `Up` and `Down` and press `Enter`. Turns are labeled `T1`, `T2`, and so on. The picker appears once Claude has edited files, and `Current` returns you to the working tree.
- **Show the files the panel leaves out**: the list skips test files and generated files, and collapses changes from before this session into one line at the bottom. Click either count line to expand it.
- **Change what the panel compares against**: press `Ctrl+X B` to cycle from this session’s changes, to your uncommitted changes as one list, to everything since your branch split from the default branch. Claude Code remembers the choice for each repository.

To rebind the keys that scroll the file list or change the comparison, see [Diff panel actions](keybindings.md#diff-panel-actions).


[​](#diff-dialog)

Diff dialog

The diff dialog opens as a bordered block above the prompt and lists your changed files with their added and removed line counts. It compares them against `HEAD`, or against whatever you last [chose in the diff panel](#diff-panel) for this repository. Once Claude has edited files, a `source` picker appears above the list. It offers one turn view, labeled `T1`, `T2`, and so on, for each of your prompts that led Claude to edit files. A turn view shows only that turn’s edits, and `Current` returns you to the working tree. Use these keys in the dialog:

- **Up and Down**: select a file.
- **Enter**: open the selected file’s diff. Scroll it with Up and Down, or PageUp and PageDown.
- **Esc**: return from a file’s diff to the list, or close the dialog from the list.
- **Tab**: move to the `source` picker, then choose `Current` or a turn view with Up and Down and press Enter. In a file’s diff, Tab moves to the `ask` button. Press Enter to attach that file’s diff to your next prompt.


[​](#side-questions-with-/btw)

Side questions with /btw

Use `/btw` to ask a question about your current work without adding to the conversation history.

```python
/btw what was the name of that config file again?
```

Claude answers a side question from what’s already in the conversation: your messages, its replies, and the tool results it has gathered. You can ask about code Claude has already read, decisions it made earlier, or anything else from the session. A later side question also sees your earlier side questions: Claude Code replays the newest 20 exchanges with each ask, until you clear them. The question and answer never enter the conversation history. In the terminal, they appear in a dismissible overlay. The terminal keeps the thread in memory: press `x` to clear the earlier exchanges, and it’s gone when you exit Claude Code. In the [VS Code extension](../03-IDE-Integrations/vs-code.md#use-the-prompt-box)’s chat panel, `/btw` opens a panel rather than the overlay this section describes, and you ask follow-up questions right in the panel. The panel’s thread survives window reloads, on the retention schedule that page describes. You need the extension at v2.1.227 or later. Earlier extension versions don’t offer `/btw`.

- **Available while Claude is working**: you can run `/btw` even while Claude is processing a response. The side question runs independently and doesn’t interrupt the main turn. It sees everything in the conversation so far, except the reply Claude is still writing.
- **No tool access**: side questions answer only from what is already in context. Claude can’t read files, run commands, or search when answering a side question. If Claude writes out tool calls as text anyway, the answer ends with a note that nothing was executed.
- **Single response**: there are no follow-up turns in the overlay. To continue the thread, ask another `/btw` question. To continue with full tool access in a local session, press `f` to fork this question and answer into a [background subagent](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation).
- **Low cost**: while the conversation’s [prompt cache](prompt-caching.md) is warm, a side question costs little beyond the answer itself.

Your five newest earlier side questions appear as a dimmed list above the current answer, with a count of any older ones. They stay out of the conversation history. To return to the overlay after dismissing it, run `/btw` with no question. The overlay reopens on your most recent exchange. Once the answer appears, the overlay accepts these keys.

| Key                          | Action                                                                                                                                                                                                                                                                                                                                                                                            |
|:-----------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `Space`, `Enter`, `Escape`   | Dismiss the answer and return to the prompt                                                                                                                                                                                                                                                                                                                                                       |
| `Up` / `Down`                | Scroll the answer                                                                                                                                                                                                                                                                                                                                                                                 |
| `Shift+Left` / `Shift+Right` | Step between this answer and your earlier `/btw` answers. `Shift+Left` moves to older answers and `Shift+Right` returns toward the current one. `[` and `]` do the same, for terminals that don’t report `Shift` with arrow keys. `Tab` / `Shift+Tab` cycle through the same answers. Requires Claude Code v2.1.257 or later. Between v2.1.187 and v2.1.256, the keys were plain `Left` / `Right` |
| `c`                          | Copy the answer to your clipboard as raw Markdown. Use this instead of mouse selection, which captures the hard-wrapped terminal rendering rather than the source text                                                                                                                                                                                                                            |
| `f`                          | Start a [forked subagent](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation) that inherits the parent conversation plus this question and answer, so it can continue with full tool access. You stay in the current session and find the fork in the [panel below your prompt](../09-Agents-Patterns/sub-agents.md#observe-and-steer-running-forks). Available in local sessions only                             |
| `x`                          | Clear the list of earlier `/btw` exchanges shown above the current answer                                                                                                                                                                                                                                                                                                                         |

In an attached [background session](../09-Agents-Patterns/agent-view.md#attach-to-a-session), `Left` detaches and returns you to agent view, even while the answer is still arriving. The side question keeps running while you’re away. The next time you attach to the session, the overlay reopens with the side question, or with its answer. Before v2.1.257, `Left` didn’t detach there. `/btw` sees your full conversation but has no tools. A [subagent](../09-Agents-Patterns/sub-agents.md) has tools and starts from the prompt it receives, or, for a [fork](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation), from a copy of this conversation. Use `/btw` to ask about what Claude already knows from this session; use a subagent to go find out something new.


[​](#task-list)

Task list

The task list is Claude’s to-do checklist: items Claude created to plan multi-step work, with indicators showing what’s pending, in progress, or complete. It’s separate from the background-task view. To see running shells and subagents, use [`/tasks`](commands.md) instead. The list fills only in sessions that have the task-tracking tools, which Claude Code provides by default on [Opus 4.7, Sonnet 4.6, Haiku 4.5, and earlier models](tools-reference.md#task-tool-availability). On any other model, including a model ID Claude Code doesn’t recognize, the list stays empty unless you opt in with `CLAUDE_CODE_ENABLE_TODO_TOOLS=1` or one of the other ways under [Task tool availability](tools-reference.md#task-tool-availability). When the session has the tools, the task list works as follows:

- Press `Ctrl+T` to toggle the task list view. The display shows up to five tasks at a time. When Claude hasn’t created any checklist items yet, the toggle has no visible effect because there’s nothing to display
- If you leave the list expanded, Claude Code restores the expanded view the next time you launch into a session that still has tasks, such as with `--resume` or `--continue`. When the task list is empty, Claude Code starts it collapsed
- To see all tasks or clear them, ask Claude directly: “show me all tasks” or “clear all tasks”
- Tasks persist across context compactions, helping Claude stay organized on larger projects
- To share a task list across sessions, set `CLAUDE_CODE_TASK_LIST_ID` to use a named directory in `~/.claude/tasks/`: `CLAUDE_CODE_TASK_LIST_ID=my-project claude`


[​](#session-recap)

Session recap

When you return to the terminal after stepping away, Claude Code shows a one-line recap of what happened in the session so far. The recap generates in the background once at least three minutes have passed since the last completed turn and the terminal is unfocused, so it’s ready when you switch back. Recaps only appear once the session has at least three turns, and never twice in a row. Run `/recap` to generate a summary on demand. It runs only when you ask for it yourself. When it arrives in a message relayed from a Slack, Teams, or project thread, you get a [notice](errors.md#recap-only-runs-when-you-ask-for-it-yourself) instead of a recap. You also get the notice when `/recap` arrives in a prompt a cloud scheduled task sent. Session recap is on by default for every plan and provider. To turn automatic recaps off, open `/config` and turn off **Session recap**. The automatic recap never appears in non-interactive mode. Claude Code caps both automatic recaps and `/recap` output at 400 characters.


[​](#wait-for-a-usage-limit-to-reset)

Wait for a usage limit to reset

When a claude.ai [usage limit](errors.md#youve-hit-your-session-limit) stops Claude mid-task, Claude Code waits in the open session and continues the task on its own after the limit resets. Automatic continue is on by default in interactive sessions signed in with a claude.ai subscription. Requires Claude Code v2.1.234 or later. While Claude Code waits, the lines at the bottom of the session show when your limit resets and when Claude will continue:

```python
Usage limit reached · limit resets 3:45pm
Continuing automatically at 3:45pm · esc to cancel
```

Either line can carry more after these words, such as a help link on the first or `/usage-credits to continue now` on the second. When the wait starts on its own, the conversation also records it with a line that reads `Usage limit reached · continuing automatically at 3:45pm · esc to cancel`. Keep the session open. What happens next depends on how the wait ends:

- **At the reset**: the second line changes to `Continuing shortly · esc to cancel`. Then `Usage limit reset · continuing automatically` appears in the conversation, and Claude Code prompts Claude to pick the task up where it stopped. It doesn’t resend your last message.
- **After your computer slept**: if it slept for more than about 30 minutes and the limit reset while it slept, the first line reads `Your usage limit has reset` and the second reads `Press enter to continue`. Press `Enter` to continue. After a shorter sleep, or one that ended before the reset, Claude Code continues on its own.
- **Early**: when you finish adding [usage credits](../17-Billing-Plans/costs.md#add-usage-credits-to-your-subscription) with `/usage-credits`, sign back in after `/upgrade`, or switch models with `/model` during the wait, Claude Code checks whether usage is available again and continues right away if it is. It doesn’t check after an upgrade or purchase you make in a browser on your own. Under [`opusplan`](model-config.md#opusplan-model-setting) and other model settings that run plan mode on a different model, Claude Code waits for the reset instead.

The continued task runs like any other turn. Claude Code still asks for [permissions](permissions.md) as usual, so the task can stop on a prompt while you’re away. If it hits the limit again, Claude Code re-arms the wait on its own at most twice in a row, then stops and shows `Automatic continue stopped after repeated usage-limit hits · /rate-limit-options to try again`.


[​](#cancel-the-wait)

Cancel the wait

Press `Esc` at an empty prompt, or `Ctrl+C`, while the lines show, or run [`/rate-limit-options`](commands.md#all-commands) and pick **Don’t continue automatically**. Claude Code confirms with a line that starts `Automatic continue cancelled`. After a cancel, nothing continues until you send a prompt or pick the row that starts **Wait here, then continue automatically** from `/rate-limit-options` again. Claude Code doesn’t start a wait on its own again for that reset window; the next reset window starts fresh. The wait also ends without continuing the task in these cases:

- **You send a prompt**: Claude Code sends your prompt instead of waiting. If your prompt hits the limit too, it stays in the conversation and Claude Code starts the wait again.
- **You exit Claude Code**: the wait doesn’t restart when you resume the session.
- **The conversation changes hands**: you switch accounts with `/login`, clear or rewind the conversation, `/resume` another session, pull one with `/teleport`, relaunch with `/tui`, or hand the session to Claude Desktop, a background session, or the cloud.
- **The setting turns off, or the reset moves past 24 hours**: this ends only a wait Claude Code started on its own. A wait you picked from `/rate-limit-options` keeps counting down.
- **The continuation is blocked**: a [`UserPromptSubmit` hook](../07-Hooks/hooks.md#userpromptsubmit) that blocks the continuation prompt, or a failure before it reaches the model, ends the wait. Claude Code tells you the continuation didn’t run. Send a prompt to continue.


[​](#start-a-wait-yourself)

Start a wait yourself

Claude Code doesn’t start the wait on its own in these cases:

- **Remote Control and agent team teammate sessions**: a person at that terminal can still start one.
- **A reset more than 24 hours away**: a weekly limit can reset days out.
- **An Opus or Sonnet limit while you run a model outside that family**: your next turn may not hit that limit. [`opusplan`](model-config.md#opusplan-model-setting) and other model settings that run plan mode on the limited family don’t get this exception.

In those cases, and whenever automatic continue is off, Claude Code opens the usage-limit options menu once per reset window when you hit a limit at your own terminal. Pick the row that starts **Wait here, then continue automatically** to start the wait. In a [Remote Control](remote-control.md) or [agent team](../09-Agents-Patterns/agent-teams.md) teammate session, run `/rate-limit-options` yourself to open the menu. Claude Code doesn’t offer the wait at all in these cases:

- **Background sessions and `-p` runs**: the menu row isn’t available.
- **API keys, cloud providers, and usage-based billing**: usage there is metered per request, so there is no reset to wait for.
- **An [LLM gateway](../13-Enterprise-Admin/llm-gateway.md#subscriptions-and-gateways) without a saved claude.ai login**: Claude Code offers the wait only while a saved claude.ai login is the active credential.


[​](#turn-automatic-continue-off)

Turn automatic continue off

In `/config`, turn off **Continue automatically at usage limit**, or set [`autoContinueAtUsageLimit`](settings-reference.md#autocontinueatusagelimit) to `false` in your user settings. `/config autoContinueAtUsageLimit=false` also works, including with `-p`, but the `key=value` form can’t turn it back on, because the setting grants unattended execution. Which settings files Claude Code reads for this key is in the [settings reference](settings-reference.md#autocontinueatusagelimit).


[​](#pr-review-status)

PR review status

When working on a branch with an open pull request, Claude Code displays a clickable PR link in the footer, such as “PR \#446”. The link has a colored underline indicating the review state:

- Green: approved
- Yellow: pending review
- Red: changes requested
- Gray: draft

The badge disappears once the pull request merges or closes. `Cmd+click` (macOS) or `Ctrl+click` (Windows/Linux) the link to open the pull request in your browser. The status refreshes as soon as a `git push`, or a `gh pr` command that changes the pull request, such as `gh pr create` or `gh pr merge`, succeeds in the session. Claude Code renders the badge as a hyperlink even when it can’t detect hyperlink support in your terminal, which commonly happens over SSH or in tmux. Set [`FORCE_HYPERLINK=0`](env-vars.md) to render the badge as plain text. When you set [`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`](env-vars.md), Claude Code doesn’t check pull request or merge request status.

PR status for GitHub repositories needs a GitHub token. Claude Code finds one based on the remote’s host:

- **github.com**: `GH_TOKEN` or `GITHUB_TOKEN`, or the token saved by `gh auth login`. Without one, the footer shows `install gh for PR status` when the `gh` CLI isn’t installed, or `gh auth login for PR status` when it is
- **A GitHub Enterprise host set as `GH_HOST`**: `GH_ENTERPRISE_TOKEN` or `GITHUB_ENTERPRISE_TOKEN`, or the token saved by `gh auth login --hostname <host>`. Without one, the footer shows the same hints
- **Any other GitHub host**: the token saved by `gh auth login --hostname <host>`. Without one, Claude Code shows no badge and no hint


[​](#gitlab-merge-requests)

GitLab merge requests

When you work on a branch with an open GitLab merge request, Claude Code shows a clickable `MR !N` badge in the footer slot that otherwise holds the GitHub PR link. `!N` is GitLab’s own reference syntax for merge request number N. The colored underline shows the merge request’s state:

- Green: GitLab reports the merge request as mergeable
- Yellow: any other open state
- Gray: draft

The badge disappears once the merge request merges or closes. It refreshes as soon as a `git push`, or a `glab mr` command that changes the merge request, such as `glab mr create` or `glab mr merge`, succeeds in the session. To get the badge, you need:

- Claude Code v2.1.234 or later
- A repository remote that points at your GitLab host, either gitlab.com or a self-managed instance
- The [`glab` CLI](https://gitlab.com/gitlab-org/cli) on your `PATH`, authenticated with `glab auth login`

Claude Code ignores `glab`’s token environment variables, such as `GITLAB_TOKEN`, when it checks status, so you get no badge from an exported token alone. Claude Code also looks for `glab` and for its login once per session, so restart Claude Code after you install `glab` or run `glab auth login`.


[​](#issue-reference-links)

Issue reference links

When Claude mentions an issue as `owner/repo#123`, you can click the reference to open it, as long as your terminal supports hyperlinks. If Claude Code doesn’t detect hyperlink support in your terminal, set [`FORCE_HYPERLINK`](env-vars.md) to `1` to turn the links on, or to `0` to keep references as plain text. You get a link only for the two-part `owner/repo#123` form. These stay plain text:

- A bare `#123`
- A nested GitLab path such as `group/subgroup/project#123`
- Any reference inside a code span or code block
- Any reference in a reply longer than about 1,000 lines or 100,000 characters

Claude Code builds the link for the host of the repository it identifies from your git remote, not for the repository the reference names:

| Your repository’s host                                             | Where `owner/repo#123` links                 |
|:-------------------------------------------------------------------|:---------------------------------------------|
| github.com, a GitHub Enterprise host, or any host not listed below | `https://<host>/owner/repo/issues/123`       |
| gitlab.com                                                         | `https://gitlab.com/owner/repo/-/issues/123` |
| bitbucket.org, codeberg.org, or gitea.com                          | No link; the reference stays plain text      |


[​](#see-also)

See also

- [Skills](../08-Plugins-Skills/skills.md) - Custom prompts and workflows
- [Checkpointing](checkpointing.md) - Rewind Claude’s edits and restore previous states
- [CLI reference](cli-reference.md) - Command-line flags and options
- [Settings](settings.md) - Configuration options
- [Memory management](memory.md) - Managing CLAUDE.md files

---

## Customize keyboard shortcuts - Claude Code Docs

Source: https://code.claude.com/docs/en/keybindings
Path: 02-Claude-Code-CLI/keybindings.md

## On this page

- [Configuration file](#configuration-file)
- [Contexts](#contexts)
- [Available actions](#available-actions)
  - [App actions](#app-actions)
  - [History actions](#history-actions)
  - [Chat actions](#chat-actions)
  - [Autocomplete actions](#autocomplete-actions)
  - [Confirmation actions](#confirmation-actions)
  - [Permission actions](#permission-actions)
  - [Transcript actions](#transcript-actions)
  - [History search actions](#history-search-actions)
  - [Task actions](#task-actions)
  - [Theme actions](#theme-actions)
  - [Help actions](#help-actions)
  - [Tabs actions](#tabs-actions)
  - [Attachments actions](#attachments-actions)
  - [Footer actions](#footer-actions)
  - [Message selector actions](#message-selector-actions)
  - [Diff actions](#diff-actions)
  - [Diff panel actions](#diff-panel-actions)
  - [Model picker actions](#model-picker-actions)
  - [Effort slider actions](#effort-slider-actions)
  - [Select actions](#select-actions)
  - [Plugin actions](#plugin-actions)
  - [Above-prompt actions](#above-prompt-actions)
  - [Pane actions](#pane-actions)
  - [Settings actions](#settings-actions)
  - [Agents actions](#agents-actions)
  - [Voice actions](#voice-actions)
  - [Scroll actions](#scroll-actions)
- [Keystroke syntax](#keystroke-syntax)
  - [Modifiers](#modifiers)
  - [Uppercase letters](#uppercase-letters)
  - [Non-US keyboard layouts](#non-us-keyboard-layouts)
  - [Chords](#chords)
  - [Special keys](#special-keys)
- [Unbind default shortcuts](#unbind-default-shortcuts)
- [Reserved shortcuts](#reserved-shortcuts)
- [Terminal conflicts](#terminal-conflicts)
- [Text fields](#text-fields)
- [Vim mode interaction](#vim-mode-interaction)
  - [Cancel a question with one key press](#cancel-a-question-with-one-key-press)
- [Validation](#validation)

Interface

# Customize keyboard shortcuts

Copy pageCopy page

Customize keyboard shortcuts in Claude Code with a keybindings configuration file.

Copy pageCopy page

Claude Code supports customizable keyboard shortcuts. Run `/keybindings` to create or open your configuration file at `~/.claude/keybindings.json`.


[​](#configuration-file)

Configuration file

The keybindings configuration file is an object with a `bindings` array. Each block specifies a context and a map of keystrokes to actions.

Changes to the keybindings file are automatically detected and applied without restarting Claude Code.

| Field      | Description                                        |
|:-----------|:---------------------------------------------------|
| `$schema`  | Optional JSON Schema URL for editor autocompletion |
| `$docs`    | Optional documentation URL                         |
| `bindings` | Array of binding blocks by context                 |

This example binds `Ctrl+E` to open an external editor in the chat context, and unbinds `Ctrl+S`:

```python
{
  "$schema": "https://www.schemastore.org/claude-code-keybindings.json",
  "$docs": "https://code.claude.com/docs/en/keybindings",
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "ctrl+e": "chat:externalEditor",
        "ctrl+s": null
      }
    }
  ]
}
```


[​](#contexts)

Contexts

Each binding block specifies a **context** where the bindings apply:

| Context             | Description                                                                                                      |
|:--------------------|:-----------------------------------------------------------------------------------------------------------------|
| `Global`            | Applies everywhere in the app                                                                                    |
| `Chat`              | Main chat input area                                                                                             |
| `Autocomplete`      | Autocomplete menu is open                                                                                        |
| `Settings`          | Settings menu                                                                                                    |
| `Confirmation`      | Permission and confirmation dialogs                                                                              |
| `Tabs`              | Tab navigation components                                                                                        |
| `Help`              | Help menu is visible                                                                                             |
| `Transcript`        | Transcript viewer                                                                                                |
| `HistorySearch`     | History search mode (Ctrl+R)                                                                                     |
| `Task`              | A task is running in the foreground                                                                              |
| `ThemePicker`       | Theme picker dialog                                                                                              |
| `Attachments`       | Image attachment navigation in select dialogs                                                                    |
| `Footer`            | Footer indicator navigation (tasks, teams, diff, artifacts)                                                      |
| `MessageSelector`   | Rewind and summarize dialog message selection                                                                    |
| `DiffDialog`        | [Diff viewer](#diff-actions) navigation                                                                          |
| `DiffPanel`         | The [diff panel](interactive-mode.md#diff-panel) is open                                                   |
| `ModelPicker`       | Model picker effort level                                                                                        |
| `EffortSlider`      | Effort slider opened by `/effort`                                                                                |
| `Select`            | Generic select/list components                                                                                   |
| `Plugin`            | Plugin dialog (browse, discover, manage)                                                                         |
| `AbovePrompt`       | The [band above the prompt](#above-prompt-actions), or a button in it, has keyboard focus                        |
| `AbovePromptInput`  | An input field in the band above the prompt or in a mod’s pane has keyboard focus                                |
| `AbovePromptSelect` | A select in the band above the prompt or in a mod’s pane has keyboard focus                                      |
| `Pane`              | A pane drawn by a [mod](../08-Plugins-Skills/plugins-mods-interface.md#know-which-keys-your-mod-can-receive) has keyboard focus |
| `PaneField`         | An input field or select in a mod’s pane has keyboard focus                                                      |
| `Agents`            | [Agent view](../09-Agents-Patterns/agent-view.md) (`claude agents`)                                                              |
| `Scroll`            | Conversation scrolling and text selection in fullscreen mode                                                     |

Before v2.1.205, a `Doctor` context and a `doctor:fix` action existed for the `/doctor` diagnostics screen.


[​](#available-actions)

Available actions

Actions follow a `namespace:action` format, such as `chat:submit` to send a message or `app:toggleTodos` to show the task list. Each context has specific actions available.


[​](#app-actions)

App actions

Actions available in the `Global` context:

| Action                 | Default   | Description                                                                                                       |
|:-----------------------|:----------|:------------------------------------------------------------------------------------------------------------------|
| `app:interrupt`        | Ctrl+C    | Cancel current operation                                                                                          |
| `app:exit`             | Ctrl+D    | Exit Claude Code. Press twice within 800ms to confirm                                                             |
| `app:redraw`           | (unbound) | Force terminal redraw                                                                                             |
| `app:toggleTodos`      | Ctrl+T    | Toggle visibility of Claude’s to-do checklist. This is not the [`/tasks`](commands.md) background-task view |
| `app:toggleTranscript` | Ctrl+O    | Toggle verbose transcript                                                                                         |


[​](#history-actions)

History actions

Actions for navigating command history:

| Action             | Default | Description           |
|:-------------------|:--------|:----------------------|
| `history:search`   | Ctrl+R  | Open history search   |
| `history:previous` | Up      | Previous history item |
| `history:next`     | Down    | Next history item     |


[​](#chat-actions)

Chat actions

Actions available in the `Chat` context:

| Action                | Default                           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
|:----------------------|:----------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `chat:cancel`         | Escape                            | Cancel current input                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `chat:clearInput`     | Ctrl+L                            | Force a full screen redraw, preserving input and conversation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `chat:clearScreen`    | Cmd+K                             | Same as `chat:clearInput`. See [Clear the conversation](fullscreen.md#clear-the-conversation) for how Cmd+K behaves on iTerm2 and Terminal.app                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `chat:killAgents`     | Ctrl+X Ctrl+K                     | Stop all running [background subagents](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) in this session and turn off [artifact auto-replies](artifacts.md#let-claude-reply-to-comments-on-its-own) for the rest of it. Press the shortcut twice within 3 seconds to confirm. You can press it while a background subagent’s permission prompt is open                                                                                                                                                                                                                                                       |
| `chat:cycleMode`      | Shift+Tab\*                       | Cycle permission modes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `chat:modelPicker`    | Meta+P                            | Open model picker                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `chat:fastMode`       | Meta+O                            | Toggle fast mode                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `chat:thinkingToggle` | Meta+T                            | Toggle extended thinking                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `chat:submit`         | Enter                             | Submit message                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `chat:queueSubmit`    | Ctrl+X Enter                      | Submit the message, marked to wait its turn: while Claude is working, Claude Code [queues it](interactive-mode.md#queue-messages-while-claude-works) and never interrupts the turn. Unlike `chat:submit`, it submits the draft even while an autocomplete suggestion is highlighted. Requires v2.1.247 or later                                                                                                                                                                                                                                                                                                            |
| `chat:sendNow`        | Ctrl+Enter, Ctrl+X Ctrl+S         | Send your [queued messages](interactive-mode.md#queue-messages-while-claude-works), and your draft with them, right away. [When Claude Code sends what you queued](interactive-mode.md#when-claude-code-sends-what-you-queued) covers what happens to the turn Claude is working on. When nothing is running, the key submits the draft, and in [shell mode](interactive-mode.md#shell-mode-with-prefix) it only queues the command. Terminals that don’t report extended keys deliver `Ctrl+Enter` as plain `Enter`, so `Ctrl+X Ctrl+S` is the binding that works in any terminal. Requires v2.1.275 or later |
| `chat:newline`        | Ctrl+J                            | Insert a newline without submitting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `chat:undo`           | Ctrl+\_, Ctrl+Shift+-             | Undo last action                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `chat:externalEditor` | Ctrl+G, Ctrl+X Ctrl+E             | Open in external editor. The [agent view dispatch input](../09-Agents-Patterns/agent-view.md#keyboard-shortcuts) follows this action’s single-keystroke bindings too                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `chat:stash`          | Ctrl+S                            | Stash current prompt                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `chat:imagePaste`     | Ctrl+V (Alt+V on Windows and WSL) | Paste image from clipboard. On WSL, both shortcuts are bound by default                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `command:<name>`      | (unbound)                         | Run the [command](commands.md) `/<name>`. For example, `"meta+g": "command:compact"` in a `Chat` block makes `Meta+G` run `/compact`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |

\*On Windows without VT mode (Node \<24.2.0/\<22.17.0, Bun \<1.2.23), defaults to Meta+M.


[​](#autocomplete-actions)

Autocomplete actions

Actions available in the `Autocomplete` context:

| Action                  | Default | Description         |
|:------------------------|:--------|:--------------------|
| `autocomplete:accept`   | Tab     | Accept suggestion   |
| `autocomplete:dismiss`  | Escape  | Dismiss menu        |
| `autocomplete:previous` | Up      | Previous suggestion |
| `autocomplete:next`     | Down    | Next suggestion     |


[​](#confirmation-actions)

Confirmation actions

Actions available in the `Confirmation` context:

| Action                  | Default     | Description                                                                                                                                                                                                                                                        |
|:------------------------|:------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `confirm:yes`           | Enter       | Confirm action                                                                                                                                                                                                                                                     |
| `confirm:no`            | Escape      | Decline action                                                                                                                                                                                                                                                     |
| `confirm:previous`      | Up          | Previous option                                                                                                                                                                                                                                                    |
| `confirm:next`          | Down        | Next option                                                                                                                                                                                                                                                        |
| `confirm:nextField`     | Tab         | In the `/fast` dialog, turn fast mode on or off                                                                                                                                                                                                                    |
| `confirm:previousField` | (unbound)   | Claude Code doesn’t respond to this action, and a `keybindings.json` that names it remains valid                                                                                                                                                                   |
| `confirm:toggle`        | Space       | Toggle selection                                                                                                                                                                                                                                                   |
| `confirm:cycleMode`     | Shift+Tab\* | On a file permission prompt, closes an open [comment field](permissions.md#add-a-comment-when-you-answer-a-permission-prompt); with no field open, selects the option that allows the action for the rest of the session, when the prompt offers that option |

\*On Windows without VT mode (Node \<24.2.0/\<22.17.0, Bun \<1.2.23), defaults to Meta+M. Before v2.1.257, a `confirm:toggleExplanation` action, bound to `Ctrl+E` by default, showed a model-generated explanation of the command on Bash and PowerShell permission prompts. Dialogs use `confirm:yes` and `confirm:no` to accept and cancel even when they don’t ask a yes-or-no question. If you bind a bare letter such as `y` or `n` in this context, the letter also acts on dialogs that never show it as a key. A dialog that shows `y` and `n` as its keys reads those letters itself and needs no binding. In most dialogs, pressing `Ctrl+C` or `Ctrl+D` twice closes the dialog instead of exiting Claude Code. The hint after the first press says whether the second press closes the dialog or exits. Both keys are [reserved](#reserved-shortcuts) and can’t be rebound. This example binds `y` to `confirm:yes` and `n` to `confirm:no`:

```python
{
  "bindings": [
    {
      "context": "Confirmation",
      "bindings": {
        "y": "confirm:yes",
        "n": "confirm:no"
      }
    }
  ]
}
```

With these bindings, `y` and `n` still type as letters while a [text field](#text-fields) has focus. Before v2.1.280, `y` was also bound to `confirm:yes` and `n` to `confirm:no` by default. If you created your `keybindings.json` with `/keybindings` before v2.1.280, the file lists both bindings and they stay in effect until you delete those two lines.


[​](#permission-actions)

Permission actions

Actions available in the `Confirmation` context for permission dialogs:

| Action                   | Default   | Description                                                                                      |
|:-------------------------|:----------|:-------------------------------------------------------------------------------------------------|
| `permission:toggleDebug` | (unbound) | Claude Code doesn’t respond to this action, and a `keybindings.json` that names it remains valid |


[​](#transcript-actions)

Transcript actions

Actions available in the `Transcript` context:

| Action                     | Default           | Description             |
|:---------------------------|:------------------|:------------------------|
| `transcript:toggleShowAll` | Ctrl+E            | Toggle show all content |
| `transcript:exit`          | q, Ctrl+C, Escape | Exit transcript view    |

`transcript:toggleShowAll` applies in the classic renderer only; in [fullscreen rendering](fullscreen.md), the transcript viewer doesn’t offer a show-all toggle.


[​](#history-search-actions)

History search actions

Actions available in the `HistorySearch` context:

| Action                     | Default     | Description                               |
|:---------------------------|:------------|:------------------------------------------|
| `historySearch:next`       | Ctrl+R      | Next match                                |
| `historySearch:accept`     | Escape, Tab | Accept selection                          |
| `historySearch:cancel`     | Ctrl+C      | Cancel search                             |
| `historySearch:execute`    | Enter       | Execute selected command                  |
| `historySearch:cycleScope` | Ctrl+S      | Cycle scope: session, project, everywhere |

The `historySearch:next`, `historySearch:accept`, `historySearch:cancel`, and `historySearch:execute` defaults apply to the inline history search in the classic renderer, which always searches prompts from all projects. `historySearch:cycleScope` takes effect only in [fullscreen rendering](fullscreen.md), where `Ctrl+R` opens a search dialog instead and `Ctrl+S` cycles its scope. The dialog’s other keys are fixed and can’t be rebound: `Enter` or `Tab` places the highlighted match in the prompt input and `Esc` cancels.


[​](#task-actions)

Task actions

Actions available in the `Task` context:

| Action            | Default               | Description             |
|:------------------|:----------------------|:------------------------|
| `task:background` | Ctrl+B, Ctrl+X Ctrl+B | Background current task |


[​](#theme-actions)

Theme actions

Actions available in the `ThemePicker` context:

| Action                           | Default | Description                |
|:---------------------------------|:--------|:---------------------------|
| `theme:toggleSyntaxHighlighting` | Ctrl+T  | Toggle syntax highlighting |


[​](#help-actions)

Help actions

Actions available in the `Help` context:

| Action         | Default | Description     |
|:---------------|:--------|:----------------|
| `help:dismiss` | Escape  | Close help menu |


[​](#tabs-actions)

Tabs actions

Actions available in the `Tabs` context:

| Action          | Default         | Description  |
|:----------------|:----------------|:-------------|
| `tabs:next`     | Tab, Right      | Next tab     |
| `tabs:previous` | Shift+Tab, Left | Previous tab |

In a tabbed dialog, `tabs:next` and `tabs:previous` switch tabs while the tab row has focus. In some dialogs, such as `/help` and `/sandbox`, the tab-switching keys also work from inside the tab’s content. `Up` and `Down` move focus between the tab row and the tab’s content, and a list in the content responds to keys only while it has focus.


[​](#attachments-actions)

Attachments actions

Actions available in the `Attachments` context:

| Action                 | Default           | Description                |
|:-----------------------|:------------------|:---------------------------|
| `attachments:next`     | Right             | Next attachment            |
| `attachments:previous` | Left              | Previous attachment        |
| `attachments:remove`   | Backspace, Delete | Remove selected attachment |
| `attachments:exit`     | Down, Escape      | Exit attachment navigation |


[​](#footer-actions)

Footer actions

Actions available in the `Footer` context:

| Action                  | Default      | Description                                                                                                                                                                                                        |
|:------------------------|:-------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `footer:next`           | Right        | Next footer item                                                                                                                                                                                                   |
| `footer:previous`       | Left         | Previous footer item                                                                                                                                                                                               |
| `footer:up`             | Up, Ctrl+P   | Navigate up in footer (deselects at top)                                                                                                                                                                           |
| `footer:down`           | Down, Ctrl+N | Navigate down in footer                                                                                                                                                                                            |
| `footer:openSelected`   | Enter        | Open selected footer item                                                                                                                                                                                          |
| `footer:clearSelection` | Escape       | Clear footer selection                                                                                                                                                                                             |
| `footer:close`          | x            | Stop the selected [agent](../09-Agents-Patterns/sub-agents.md#observe-and-steer-running-forks) or [workflow](workflows.md#manage-runs), or dismiss its row if it’s no longer running                                         |
| `footer:dismiss`        | (unbound)    | Binding a key to this action has no effect, and a `keybindings.json` that names it remains valid. Before v2.1.281, Backspace and Delete were bound to it and dismissed the selected artifact link from the footer. |

While a footer item is selected, such as a row in the agent panel below the prompt, `Enter` opens it even when you rebind `Enter` in the `Chat` context to `chat:queueSubmit` or `chat:newline`. `Chat` bindings on keys the `Footer` context doesn’t bind, such as `Shift+Tab` for `chat:cycleMode`, keep working while an item is selected.


[​](#message-selector-actions)

Message selector actions

In the message list of the [rewind menu](checkpointing.md), you move through messages and pick one with the [Select actions](#select-actions) and their default keys. Your `Select` bindings for those actions apply there too. The `MessageSelector` context has no actions or default bindings of its own. Use it to change a key for this list alone, by binding a Select action such as `select:accept` in a `MessageSelector` block. This example binds `o` to pick the highlighted message in the rewind menu, without changing any other list:

```python
{
  "bindings": [
    {
      "context": "MessageSelector",
      "bindings": {
        "o": "select:accept"
      }
    }
  ]
}
```

Before v2.1.283, this list ignored `Select` bindings and had its own actions: `messageSelector:up`, `messageSelector:down`, `messageSelector:top`, `messageSelector:bottom`, and `messageSelector:select`. If your `keybindings.json` binds one of those names, the binding keeps working in this list as the Select action that does the same thing. `Home` and `End` jump to either end of the list; before v2.1.283, keys such as `Shift+K` and `Shift+J` did that by default.


[​](#diff-actions)

Diff actions

These actions reach only Claude Code’s earlier diff viewer, which `/diff` opens outside [fullscreen rendering](fullscreen.md) after you disable the [`cc-plugin-diff` mod](../08-Plugins-Skills/plugins-mods-overview.md#mods-built-into-claude-code) in `/plugin`. While that mod is enabled, `/diff` opens the [diff dialog](interactive-mode.md#diff-dialog) instead. A `keybindings.json` that names these actions loads without errors either way. Actions available in the `DiffDialog` context:

| Action                | Default   | Description                                                                                                                                         |
|:----------------------|:----------|:----------------------------------------------------------------------------------------------------------------------------------------------------|
| `diff:dismiss`        | Escape    | Close diff viewer; from the detail view, returns to the file list instead                                                                           |
| `diff:previousSource` | Left      | Previous diff source                                                                                                                                |
| `diff:nextSource`     | Right     | Next diff source                                                                                                                                    |
| `diff:previousFile`   | Up, K     | Previous file in the file list; scroll up one line in the detail view                                                                               |
| `diff:nextFile`       | Down, J   | Next file in the file list; scroll down one line in the detail view                                                                                 |
| `diff:back`           | (unbound) | Go back in diff viewer. Escape performs the back action via `diff:dismiss`. The previous default of Left in the detail view was removed in v2.1.203 |

The file list also responds to the [Select actions](#select-actions), through their default keys and your `Select` bindings. `select:previous` and `select:next` move to the previous and next file, and `Enter` opens the selected file’s diff through `select:accept`. To change one of those keys for the file list alone, bind the Select action in a `DiffDialog` block. Before v2.1.283, the file list ignored `Select` bindings, and `Enter` opened the selected file’s diff through a separate `diff:viewDetails` action. If your `keybindings.json` binds `diff:viewDetails`, the binding keeps working in the file list as `select:accept`. The diff detail view also binds pager-style keys to the standard [scroll actions](#scroll-actions). These bindings are part of the `DiffDialog` context and apply only in the detail view; the `Scroll` context defaults listed under [Scroll actions](#scroll-actions) are unchanged.

| Action                | Default        | Description                 |
|:----------------------|:---------------|:----------------------------|
| `scroll:pageUp`       | PageUp         | Scroll up half a viewport   |
| `scroll:pageDown`     | PageDown       | Scroll down half a viewport |
| `scroll:fullPageUp`   | Shift+Space, B | Scroll up a full viewport   |
| `scroll:fullPageDown` | Space          | Scroll down a full viewport |
| `scroll:top`          | G, Home        | Jump to the top             |
| `scroll:bottom`       | Shift+G, End   | Jump to the bottom          |


[​](#diff-panel-actions)

Diff panel actions

Actions for the [diff panel](interactive-mode.md#diff-panel) that `/diff` opens in fullscreen rendering. `app:cycleDiffBase` is in the `DiffPanel` context, which is active while the panel is open; the others are `Global`. The built-in [`cc-plugin-diff` mod](../08-Plugins-Skills/plugins-mods-overview.md#mods-built-into-claude-code) draws this panel and handles `app:cycleDiffBase`, `app:diffFileListUp`, and `app:diffFileListDown`. `app:toggleReplTab`, `app:toggleDiffNoiseFilter`, and `app:toggleDiffPreSession` reach only Claude Code’s earlier panel, which `/diff` opens after you disable `cc-plugin-diff` in `/plugin`.

| Action                      | Default              | Description                                                               |
|:----------------------------|:---------------------|:--------------------------------------------------------------------------|
| `app:toggleReplTab`         | (unbound)            | Open or close the diff panel                                              |
| `app:cycleDiffBase`         | Ctrl+X B             | Cycle the panel’s comparison base: this session, uncommitted, then branch |
| `app:diffFileListUp`        | Ctrl+Up, Meta+Up     | Scroll the panel’s file list up when it overflows                         |
| `app:diffFileListDown`      | Ctrl+Down, Meta+Down | Scroll the panel’s file list down when it overflows                       |
| `app:toggleDiffNoiseFilter` | (unbound)            | Show or hide test and generated files in the panel                        |
| `app:toggleDiffPreSession`  | (unbound)            | Expand or collapse the changes from before this session                   |


[​](#model-picker-actions)

Model picker actions

Actions available in the `ModelPicker` context:

| Action                        | Default | Description                                  |
|:------------------------------|:--------|:---------------------------------------------|
| `modelPicker:decreaseEffort`  | Left    | Decrease effort level                        |
| `modelPicker:increaseEffort`  | Right   | Increase effort level                        |
| `modelPicker:thisSessionOnly` | s       | Apply highlighted model to this session only |


[​](#effort-slider-actions)

Effort slider actions

Actions available in the `EffortSlider` context, the slider that opens when you run `/effort` with no arguments. The slider’s Enter and Escape keys can’t be rebound.

| Action                         | Default | Description                                                                                                                                                                                                  |
|:-------------------------------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `effortSlider:decreaseEffort`  | Left    | Move the slider to the next lower effort level. Requires v2.1.284 or later                                                                                                                                   |
| `effortSlider:increaseEffort`  | Right   | Move the slider to the next higher effort level. Requires v2.1.284 or later                                                                                                                                  |
| `effortSlider:toggleUltracode` | Tab     | Turn [ultracode](workflows.md#let-claude-decide-with-ultracode) on or off for this session, when the slider [offers it](model-config.md#when-ultracode-is-available). Requires v2.1.284 or later |
| `effortSlider:thisSessionOnly` | s       | Apply the focused [effort level](model-config.md#adjust-effort-level) to this session only. Requires v2.1.257 or later                                                                                 |


[​](#select-actions)

Select actions

Actions available in the `Select` context:

| Action            | Default         | Description                   |
|:------------------|:----------------|:------------------------------|
| `select:next`     | Down, J, Ctrl+N | Next option                   |
| `select:previous` | Up, K, Ctrl+P   | Previous option               |
| `select:pageUp`   | PageUp          | Move up one page of options   |
| `select:pageDown` | PageDown        | Move down one page of options |
| `select:first`    | Home            | First option                  |
| `select:last`     | End             | Last option                   |
| `select:accept`   | Enter           | Accept selection              |
| `select:cancel`   | Escape          | Cancel selection              |

In list panels such as `/skills`, `/mcp`, and `/tasks`, Claude Code applies your `select:pageUp`, `select:pageDown`, `select:first`, and `select:last` bindings. In most other lists, such as the `/model` picker, your `select:first` and `select:last` bindings apply. PageUp and PageDown page through the options in those lists regardless of your bindings. Before v2.1.280, those other lists ignored Home, End, and your `select:first` and `select:last` bindings. Before v2.1.283, the `/mcp` tool list paged with fixed PageUp and PageDown keys regardless of your bindings.


[​](#plugin-actions)

Plugin actions

Actions available in the `Plugin` context:

| Action            | Default | Description                                                                |
|:------------------|:--------|:---------------------------------------------------------------------------|
| `plugin:toggle`   | Space   | Toggle plugin selection                                                    |
| `plugin:install`  | I       | Install selected plugins                                                   |
| `plugin:favorite` | F       | Favorite the selected plugin so it sorts near the top of the Installed tab |


[​](#above-prompt-actions)

Above-prompt actions

Actions for the band above the prompt, the shared strip where [mods](../08-Plugins-Skills/plugins-mods-interface.md#pick-where-to-draw) draw buttons, input fields, and selects. `abovePrompt:toggle` and `abovePrompt:focus` apply in the `Chat` context. The other actions apply in the [context](#contexts) of whatever has keyboard focus in the band or a pane.

| Action                          | Default       | Description                                                                                                           |
|:--------------------------------|:--------------|:----------------------------------------------------------------------------------------------------------------------|
| `abovePrompt:toggle`            | Ctrl+X Ctrl+A | Collapse the band to a one-row hint, or expand it again                                                               |
| `abovePrompt:focus`             | Ctrl+X Tab    | Move keyboard focus into the band, then to each open [pane](#pane-actions), and from the last pane back to the prompt |
| `abovePrompt:next`              | Tab           | Focus the next control                                                                                                |
| `abovePrompt:previous`          | Shift+Tab     | Focus the previous control                                                                                            |
| `abovePrompt:press`             | Enter         | Press the focused button, submit the focused input field, or pick the highlighted option in a select                  |
| `abovePrompt:leave`             | Escape        | Return keyboard focus to the prompt                                                                                   |
| `abovePrompt:highlightNext`     | Down          | Highlight the next option in a focused select                                                                         |
| `abovePrompt:highlightPrevious` | Up            | Highlight the previous option in a focused select                                                                     |

In the [`AbovePrompt` context](#contexts), Right and Left also run `abovePrompt:next` and `abovePrompt:previous` by default, and Space also runs `abovePrompt:press`. The `AbovePrompt` context also binds Up, Down, PageUp, PageDown, Home, and End to the [pane scroll actions](#pane-actions) `pane:scrollUp` through `pane:bottom`, so to change one of those keys for the band, bind the scroll action in an `AbovePrompt` block.


[​](#pane-actions)

Pane actions

Actions for a pane drawn by a [mod](../08-Plugins-Skills/plugins-mods-interface.md#know-which-keys-your-mod-can-receive). The scroll, resize, and close actions apply in the `Pane` [context](#contexts). `pane:close` also applies in the `PaneField` context, so it works while one of the pane’s fields has focus. `pane:next` and `pane:previous` apply in the `Global` context while more than one pane is open.

| Action            | Default                   | Description                                                                                             |
|:------------------|:--------------------------|:--------------------------------------------------------------------------------------------------------|
| `pane:scrollUp`   | Up                        | Scroll the pane up when it has more rows than it can show                                               |
| `pane:scrollDown` | Down                      | Scroll the pane down when it has more rows than it can show                                             |
| `pane:pageUp`     | PageUp                    | Scroll the pane up a page                                                                               |
| `pane:pageDown`   | PageDown                  | Scroll the pane down a page                                                                             |
| `pane:top`        | Home                      | Jump to the top of the pane                                                                             |
| `pane:bottom`     | End                       | Jump to the bottom of the pane                                                                          |
| `pane:grow`       | Ctrl+X Left, Ctrl+X Up    | Give the pane more room: width when it sits beside the transcript, height when it sits above the prompt |
| `pane:shrink`     | Ctrl+X Right, Ctrl+X Down | Give the pane less room: width when it sits beside the transcript, height when it sits above the prompt |
| `pane:close`      | Ctrl+X X                  | Close the pane                                                                                          |
| `pane:next`       | (unbound)                 | Show the next open pane                                                                                 |
| `pane:previous`   | (unbound)                 | Show the previous open pane                                                                             |

The `Pane` context also binds Tab, Shift+Tab, Enter, and Escape to the same [above-prompt actions](#above-prompt-actions) as the band, and a pane’s input fields and selects use the `AbovePromptInput` and `AbovePromptSelect` contexts. [Keyboard focus and hotkeys](../08-Plugins-Skills/plugins-mods-interface.md#know-which-keys-your-mod-can-receive) lists what each key does in a pane.


[​](#settings-actions)

Settings actions

Actions available in the `Settings` context. The `select:accept` and `confirm:no` actions are reused from the [Select](#select-actions) and [Confirmation](#confirmation-actions) contexts with Settings-specific behavior: changes apply to each setting as soon as you change it, so Escape closes the panel with your changes saved rather than declining.

| Action              | Default      | Description                                                                                                                                                                                           |
|:--------------------|:-------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `settings:search`   | /            | Enter search mode                                                                                                                                                                                     |
| `settings:retry`    | R            | Retry loading usage data on error                                                                                                                                                                     |
| `settings:fixUsage` | F            | Send your session the [`/usage` recommendations](../17-Billing-Plans/costs.md#apply-recommendations-with-the-fix-shortcut) Claude Code can apply, when the `/usage` footer offers a fix. Requires v2.1.305 or later |
| `select:accept`     | Enter, Space | Change the selected setting or open its submenu                                                                                                                                                       |
| `confirm:no`        | Escape       | Close the panel. Changes are already saved                                                                                                                                                            |


[​](#agents-actions)

Agents actions

Actions available in the `Agents` context, which applies in [agent view](../09-Agents-Patterns/agent-view.md), opened with `claude agents`. Requires v2.1.257 or later.

| Action                 | Default              | Description                                                                                                    |
|:-----------------------|:---------------------|:---------------------------------------------------------------------------------------------------------------|
| `agents:switchView`    | Ctrl+S               | Switch [session grouping](../09-Agents-Patterns/agent-view.md#organize-the-list) between state and directory                   |
| `agents:togglePin`     | Ctrl+T               | [Pin or unpin](../09-Agents-Patterns/agent-view.md#organize-the-list) the selected session                                     |
| `agents:find`          | Ctrl+F               | Find sessions by name, with the [`n:` filter](../09-Agents-Patterns/agent-view.md#filter-sessions). Requires v2.1.288 or later |
| `agents:rename`        | Ctrl+R               | [Rename](../09-Agents-Patterns/agent-view.md#organize-the-list) the selected session. Requires v2.1.288 or later               |
| `agents:previousGroup` | Ctrl+Up, Meta+Up     | Jump to the previous [group header](../09-Agents-Patterns/agent-view.md#organize-the-list). Requires v2.1.288 or later         |
| `agents:nextGroup`     | Ctrl+Down, Meta+Down | Jump to the next group header. Requires v2.1.288 or later                                                      |

While agent view is open, Claude Code uses the `Agents` binding for any key the `Agents` context binds, and it ignores a `Chat` or `Global` binding on the same key. For example, pressing Ctrl+S in agent view switches the session grouping rather than triggering the default `chat:stash`. The dispatch input’s external-editor shortcut isn’t an `Agents` action. Agent view follows the `Chat` context’s `chat:externalEditor` binding, Ctrl+G by default. Bindings fire on single keystrokes in agent view, so the Ctrl+X Ctrl+E chord bound to `chat:externalEditor` doesn’t open the editor there.


[​](#voice-actions)

Voice actions

Actions available in the `Chat` context when [voice dictation](voice-dictation.md) is enabled:

| Action             | Default | Description                                              |
|:-------------------|:--------|:---------------------------------------------------------|
| `voice:pushToTalk` | Space   | Dictate a prompt. Hold or tap depending on `/voice` mode |


[​](#scroll-actions)

Scroll actions

Actions available in the `Scroll` context when [fullscreen rendering](fullscreen.md) is enabled:

| Action                      | Default              | Description                                                                                               |
|:----------------------------|:---------------------|:----------------------------------------------------------------------------------------------------------|
| `scroll:lineUp`             | `wheelup`            | Scroll up one line. Mouse wheel scrolling triggers this action                                            |
| `scroll:lineDown`           | `wheeldown`          | Scroll down one line. Mouse wheel scrolling triggers this action                                          |
| `scroll:pageUp`             | PageUp               | Scroll up half the viewport height                                                                        |
| `scroll:pageDown`           | PageDown             | Scroll down half the viewport height                                                                      |
| `scroll:top`                | Ctrl+Home            | Jump to the start of the conversation                                                                     |
| `scroll:bottom`             | Ctrl+End             | Jump to the latest message and re-enable auto-follow                                                      |
| `scroll:halfPageUp`         | (unbound)            | Scroll up half the viewport height. Same behavior as `scroll:pageUp`, provided for vi-style rebinds       |
| `scroll:halfPageDown`       | (unbound)            | Scroll down half the viewport height. Same behavior as `scroll:pageDown`, provided for vi-style rebinds   |
| `scroll:fullPageUp`         | (unbound)            | Scroll up the full viewport height                                                                        |
| `scroll:fullPageDown`       | (unbound)            | Scroll down the full viewport height                                                                      |
| `selection:copy`            | Ctrl+Shift+C / Cmd+C | Copy the selected text to the clipboard                                                                   |
| `selection:clear`           | (unbound)            | Clear the active text selection. Requires v2.1.234 or later                                               |
| `selection:extendLeft`      | Shift+Left           | Extend the active selection one column left                                                               |
| `selection:extendRight`     | Shift+Right          | Extend the active selection one column right                                                              |
| `selection:extendUp`        | Shift+Up             | Extend the active selection one row up. Scrolls the viewport when the selection reaches the top edge      |
| `selection:extendDown`      | Shift+Down           | Extend the active selection one row down. Scrolls the viewport when the selection reaches the bottom edge |
| `selection:extendLineStart` | Shift+Home           | Extend the active selection to the start of the line                                                      |
| `selection:extendLineEnd`   | Shift+End            | Extend the active selection to the end of the line                                                        |


[​](#keystroke-syntax)

Keystroke syntax


[​](#modifiers)

Modifiers

Use modifier keys with the `+` separator:

- `ctrl` or `control` - Control key
- `shift` - Shift key
- `alt`, `opt`, `option`, or `meta` - Alt key on Windows and Linux, Option key on macOS
- `cmd`, `command`, `super`, or `win` - Command key on macOS, Windows key on Windows, Super key on Linux

The `cmd` group is only detected in terminals that report the Super modifier, such as those supporting the Kitty keyboard protocol or xterm’s `modifyOtherKeys` mode. Most terminals do not send it, so use `ctrl` or `meta` for bindings you want to work everywhere. For example:

```python
ctrl+k          Ctrl + K
shift+tab       Shift + Tab
meta+p          Option + P on macOS, Alt + P elsewhere
ctrl+shift+c    Multiple modifiers
```


[​](#uppercase-letters)

Uppercase letters

Claude Code parses key names case-insensitively, so `K` is the same binding as `k` and `ctrl+K` is the same as `ctrl+k`. To bind Shift and a letter, write `shift+k`.


[​](#non-us-keyboard-layouts)

Non-US keyboard layouts

Write the key names of Ctrl shortcuts as Latin characters even when your active keyboard layout types other characters. How Claude Code matches the key you press to a binding depends on the kind of layout:

- Under a non-Latin layout such as Cyrillic, Claude Code matches Ctrl shortcuts by the key’s US-layout position when the terminal uses the Kitty keyboard protocol and reports that position. In such a terminal, with a Russian layout active, pressing Ctrl and the physical W key triggers `ctrl+w`. In a terminal that doesn’t report the position, Claude Code matches whatever the terminal sends for the keypress: an ASCII control code triggers the Latin shortcut, and a keypress that arrives as the Cyrillic character matches no binding
- Under layouts that rearrange Latin letters, such as AZERTY, Claude Code matches the letter that the key types, so pressing Ctrl and the key labeled A triggers `ctrl+a`


[​](#chords)

Chords

Chords are sequences of keystrokes separated by spaces:

```python
ctrl+k ctrl+s   Press Ctrl+K, release, then Ctrl+S
```

Press each keystroke within 3 seconds of the one before it. If you wait longer, Claude Code cancels the chord and shows a brief notice saying so.


[​](#special-keys)

Special keys

- `escape` or `esc` - Escape key
- `enter` or `return` - Enter key
- `tab` - Tab key
- `space` - Space bar
- `up`, `down`, `left`, `right` - Arrow keys
- `pageup`, `pagedown` - Page Up and Page Down keys
- `home`, `end` - Home and End keys
- `backspace`, `delete` - Delete keys
- `wheelup`, `wheeldown` - Mouse wheel scroll events


[​](#unbind-default-shortcuts)

Unbind default shortcuts

Set an action to `null` to unbind a default shortcut:

```python
{
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "ctrl+s": null
      }
    }
  ]
}
```

This also works for chord bindings. Unbinding every chord that shares a prefix frees that prefix for use as a single-key binding. A chord in any active context keeps its prefix reserved, so you must unbind each chord in the context that defines it. Claude Code binds these default chords on the `ctrl+x` prefix, by context:

- `Chat`: `ctrl+x ctrl+k`, `ctrl+x ctrl+e`, `ctrl+x enter`, `ctrl+x ctrl+a`, `ctrl+x ctrl+s`, and `ctrl+x tab`
- `Task`: `ctrl+x ctrl+b`
- `DiffPanel`: `ctrl+x b`
- `Pane`: `ctrl+x left`, `ctrl+x right`, `ctrl+x up`, `ctrl+x down`, and `ctrl+x x`
- `PaneField`: `ctrl+x x`

The `ctrl+x enter` chord requires v2.1.247 or later, `ctrl+x b`, `ctrl+x ctrl+a`, and `ctrl+x tab` require v2.1.260 or later, and `ctrl+x ctrl+s` requires v2.1.275 or later. To reclaim `ctrl+x` itself as a single-key binding, unbind all of them:

```python
{
  "bindings": [
    {
      "context": "Task",
      "bindings": {
        "ctrl+x ctrl+b": null
      }
    },
    {
      "context": "DiffPanel",
      "bindings": {
        "ctrl+x b": null
      }
    },
    {
      "context": "Pane",
      "bindings": {
        "ctrl+x left": null,
        "ctrl+x right": null,
        "ctrl+x up": null,
        "ctrl+x down": null,
        "ctrl+x x": null
      }
    },
    {
      "context": "PaneField",
      "bindings": {
        "ctrl+x x": null
      }
    },
    {
      "context": "Chat",
      "bindings": {
        "ctrl+x ctrl+k": null,
        "ctrl+x ctrl+e": null,
        "ctrl+x enter": null,
        "ctrl+x ctrl+a": null,
        "ctrl+x ctrl+s": null,
        "ctrl+x tab": null,
        "ctrl+x": "chat:newline"
      }
    }
  ]
}
```

If you unbind some but not all chords on a prefix, pressing the prefix still enters chord-wait mode for the remaining bindings.


[​](#reserved-shortcuts)

Reserved shortcuts

These shortcuts cannot be rebound:

| Shortcut  | Reason                                                                                                                                                                                                                                                       |
|:----------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Ctrl+C    | Hardcoded interrupt/cancel                                                                                                                                                                                                                                   |
| Ctrl+D    | Hardcoded exit                                                                                                                                                                                                                                               |
| Ctrl+M    | Claude Code always receives it as Enter                                                                                                                                                                                                                      |
| Ctrl+\[   | Claude Code always receives it as Escape. In terminals that use the Kitty keyboard protocol, this requires v2.1.242 or later                                                                                                                                 |
| Ctrl+I    | Claude Code always receives it as Tab                                                                                                                                                                                                                        |
| Ctrl+H    | Sends the ASCII backspace byte. [How Claude Code reads it on Windows](terminal-config.md#fix-backspace-deleting-a-whole-word-on-windows) depends on your terminal and the [`CLAUDE_CODE_BS_AS_CTRL_BACKSPACE`](env-vars.md) environment variable |
| Caps Lock | Not delivered to terminal applications                                                                                                                                                                                                                       |


[​](#terminal-conflicts)

Terminal conflicts

Some shortcuts may conflict with terminal multiplexers:

| Shortcut | Conflict                          |
|:---------|:----------------------------------|
| Ctrl+B   | tmux prefix (press twice to send) |
| Ctrl+A   | GNU screen prefix                 |
| Ctrl+Z   | Unix process suspend (SIGTSTP)    |


[​](#text-fields)

Text fields

If you bind a bare letter, digit, or Space, you can still type that character in a text field inside a dialog or panel. One such field is the `Other` answer to a question Claude asks. While the field has focus, a printable key you press without Ctrl, Alt, or Cmd goes to the field, and Claude Code doesn’t match it against your bindings. These keys still run their bindings while the field has focus:

- Keys that don’t type a character, such as Enter, Escape, Tab, and the arrow keys
- Any key pressed with Ctrl, Alt, or Cmd
- The second keystroke of a [chord](#chords) already in progress

At the main prompt, Claude Code matches every key against the active contexts, such as `Chat`, and types the key only when no binding takes it.


[​](#vim-mode-interaction)

Vim mode interaction

When vim mode is enabled via `/config` → Editor mode, keybindings and vim mode operate independently:

- **Vim mode** handles input at the text input level (cursor movement, modes, motions)
- **Keybindings** handle actions at the component level (toggle todos, submit, etc.)
- The Escape key in vim mode switches INSERT to NORMAL mode; it does not trigger `chat:cancel`
- Most Ctrl+key shortcuts pass through vim mode to the keybinding system
- Vim keys aren’t remappable through the keybindings file. To map a two-key INSERT-mode sequence such as `jj` to Escape, use the [`vimInsertModeRemaps`](interactive-mode.md#remap-insert-mode-key-sequences) setting
- In vim NORMAL mode, `?` shows the help menu (vim behavior)
- In vim NORMAL mode, `/` opens history search, the same as Ctrl+R in standard mode

In the `Other` row of a question Claude asks, Escape doesn’t cancel the question right away in vim mode. Except in [screen reader mode](accessibility.md), the row starts in INSERT mode each time you focus it. When you press Escape in the `Other` row, the row switches to NORMAL mode or drops a half-typed vim command, and the question stays open. Press Escape again in NORMAL mode to cancel the question.


[​](#cancel-a-question-with-one-key-press)

Cancel a question with one key press

To cancel a question with one key press in vim mode, bind another key to `select:cancel` in the `Select` context. You can cancel this way from the `Other` row of a question where you select one option. In [screen reader mode](accessibility.md) or in a question where you can select several options, the bound key doesn’t cancel, so cancel with Escape instead. Pick a key that you press with Ctrl or Alt. A bare letter or digit [goes to the `Other` row](#text-fields) instead and doesn’t reach your bindings. For example, to bind `Ctrl+Q`, add this to `~/.claude/keybindings.json`:

```python
{
  "bindings": [
    {
      "context": "Select",
      "bindings": {
        "ctrl+q": "select:cancel"
      }
    }
  ]
}
```

After you save the file, press `Ctrl+Q` in the `Other` row of a question where you select one option. The question closes whether the row is in INSERT or NORMAL mode.


[​](#validation)

Validation

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

- Parse errors (invalid JSON or structure)
- 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.
- 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.
- Invalid context names
- Invalid action values, such as an action that isn’t a string or `null`
- Unknown action names, such as a typo of a registered action. Claude Code skips the binding and keeps any default binding for that key in effect.
- Reserved shortcut conflicts
- Duplicate bindings in the same context

Start Claude Code with [`--debug`](cli-reference.md#cli-flags) to see the details.

---

## Set up Claude Code in a monorepo or large codebase - Claude Code Docs

Source: https://code.claude.com/docs/en/large-codebases
Path: 02-Claude-Code-CLI/large-codebases.md

## On this page

- [What this guide covers](#what-this-guide-covers)
  - [Settings on this page](#settings-on-this-page)
  - [The example monorepo](#the-example-monorepo)
- [Choose where to start Claude](#choose-where-to-start-claude)
- [Layer CLAUDE.md files by directory](#layer-claude-md-files-by-directory)
  - [Choose between per-directory CLAUDE.md and path-scoped rules](#choose-between-per-directory-claude-md-and-path-scoped-rules)
  - [Exclude irrelevant CLAUDE.md files](#exclude-irrelevant-claude-md-files)
- [Reduce what Claude reads](#reduce-what-claude-reads)
  - [Block reads of generated and vendored code](#block-reads-of-generated-and-vendored-code)
  - [Reduce file reads with code intelligence](#reduce-file-reads-with-code-intelligence)
- [Scope worktrees and file access](#scope-worktrees-and-file-access)
  - [Check out only the directories you need](#check-out-only-the-directories-you-need)
  - [Grant access across packages or repositories](#grant-access-across-packages-or-repositories)
- [Add per-directory skills](#add-per-directory-skills)
  - [Keep skills discoverable](#keep-skills-discoverable)
- [Centralize conventions when layering stops scaling](#centralize-conventions-when-layering-stops-scaling)
  - [Recommend the right plugin at session start](#recommend-the-right-plugin-at-session-start)
- [Put it together](#put-it-together)
- [Scope and plan changes that span packages](#scope-and-plan-changes-that-span-packages)
- [Next steps](#next-steps)

Guides

# Set up Claude Code in a monorepo or large codebase

Copy pageCopy page

Configure Claude Code for monorepos and large single-tree codebases with nested CLAUDE.md files, sparse worktrees, code intelligence, and per-package skills so Claude stays focused on the code you’re working in.

Copy pageCopy page

A large codebase can be one repository with millions of lines or a monorepo with many packages. Claude Code works at any size, but as the codebase grows, the defaults tuned for smaller projects can fill the context window with instructions and file reads unrelated to the task, costing tokens and degrading Claude’s performance. This guide shows individual developers and engineering teams how to scope Claude to the part of the codebase a task touches. Each section notes whether a setting is personal to your machine or committed to the repository.


[​](#what-this-guide-covers)

What this guide covers

The [table below](#settings-on-this-page) lists each setting and what it accomplishes. The [file tree after it](#the-example-monorepo) is the example monorepo every code sample on this page refers to.


[​](#settings-on-this-page)

Settings on this page

Each setting below is independent. They layer rather than replace each other, so apply whichever fit your repository. [Choose where to start Claude](#choose-where-to-start-claude) determines where your settings files live, so read it first. [Put it together](#put-it-together) shows all of them combined.

| I want to                                                                                           | Use                                                                                        |
|:----------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------|
| Load only the conventions for the code you touch, instead of one root file covering every subsystem | Per-directory [CLAUDE.md files](#layer-claude-md-files-by-directory)                       |
| Exclude CLAUDE.md files for packages you never work in                                              | [`claudeMdExcludes`](#exclude-irrelevant-claude-md-files)                                  |
| Block Claude from opening build output, generated code, and vendored dependencies                   | [`Read` deny rules](#block-reads-of-generated-and-vendored-code) in `permissions.deny`     |
| Find a symbol’s definition or callers through the language server instead of scanning files         | A [code intelligence plugin](#reduce-file-reads-with-code-intelligence)                    |
| Check out only the directories a task needs when Claude creates a worktree                          | [`worktree.sparsePaths`](#check-out-only-the-directories-you-need)                         |
| Read and edit a sibling package or another repository from the same session                         | [`--add-dir`](#grant-access-across-packages-or-repositories) or `additionalDirectories`    |
| Give Claude procedures specific to one area that load only when relevant                            | Per-directory [skills](#add-per-directory-skills)                                          |
| Replace many per-directory CLAUDE.md files with one set of conventions everyone installs            | A [plugin](#centralize-conventions-when-layering-stops-scaling) in an internal marketplace |

For workflow techniques that keep context small in any repository, such as [running exploration in a subagent](best-practices.md#use-subagents-for-investigation) so file reads stay out of the main conversation, see [Best practices for Claude Code](best-practices.md). To roll out a baseline configuration to every developer in your organization, see [Set up Claude Code for your organization](../13-Enterprise-Admin/admin-setup.md).


[​](#the-example-monorepo)

The example monorepo

The examples throughout this page refer to a monorepo with three packages. The same patterns work in a large single-tree codebase: where an example uses `packages/api/`, substitute your own subsystem directory such as `src/backend/` or `lib/core/`.

```python
monorepo/
  CLAUDE.md                     # root instructions
  packages/
    api/
      CLAUDE.md                 # API-specific instructions
      .claude/skills/
      src/
    web/
      CLAUDE.md                 # frontend-specific instructions
      .claude/skills/
      src/
    shared/
      CLAUDE.md                 # shared library instructions
      src/
```


[​](#choose-where-to-start-claude)

Choose where to start Claude

Where you launch `claude` determines which files Claude can read and edit without an additional permission grant, which CLAUDE.md files load into context at startup, and which project settings apply.

| Start from      | File access                             | CLAUDE.md loaded at launch                   | Use when                                   |
|:----------------|:----------------------------------------|:---------------------------------------------|:-------------------------------------------|
| Repository root | Every file                              | Root only; subdirectory files load on demand | Tasks span multiple packages or subsystems |
| A subdirectory  | That subtree only, until you grant more | That directory’s plus every ancestor’s       | Work is scoped to one package or subsystem |

Project settings in `.claude/settings.json` aren’t inherited from parent directories the way CLAUDE.md files are. For which directory’s `.claude/settings.json` a session reads, see [where Claude Code looks for each file](settings.md#where-claude-code-looks-for-each-file). Each section below states whether its settings file belongs at the repository root or in the subdirectory you start from, and whether it is committed or kept local.


[​](#layer-claude-md-files-by-directory)

Layer CLAUDE.md files by directory

In a large codebase, a single CLAUDE.md at the repository root tends to either grow to cover every subsystem’s conventions, costing context on instructions unrelated to the current task, or stay too generic to be useful. Splitting instructions across per-directory files means Claude loads repository-wide rules plus only the conventions for the code you’re working in. Claude Code loads every [CLAUDE.md](memory.md) file from your working directory and every parent directory at launch, then loads each subdirectory’s file [on demand](memory.md#how-claude-md-files-load). A root file sets repository-wide rules and each subdirectory adds its own. A common split is two levels:

- **Root `CLAUDE.md`**: instructions that apply everywhere, such as coding standards and commit conventions
- **Per-subdirectory `CLAUDE.md`**: conventions specific to that area’s stack. In a monorepo that’s one per package. In a large single tree it’s one per subsystem such as `src/db/` or `src/api/`

Commit these files to the repository so teammates inherit them. Each directory’s owner typically maintains its file. To trim a file that is already checked in, run the [`/doctor` checkup](memory.md#my-claude-md-is-too-large). The root `CLAUDE.md` holds the rules that apply in every package:

CLAUDE.md

```python
Run package scripts from the package directory, not the monorepo root.
Prefix commit subjects with the package name, for example `api: add rate limiting`.
Never edit files under packages/*/generated/. Run `npm run codegen` in the package instead.
```

Each subdirectory’s `CLAUDE.md`, here `packages/api/CLAUDE.md`, adds the conventions specific to that area:

packages/api/CLAUDE.md

```python
Copy `.env.example` to `.env` before running anything. Tests and the dev server fail without it.
Write database queries with the Knex query builder. Never put raw SQL strings in route handlers.
Never edit a migration after it has merged. Add a new migration instead.
```

When you start Claude from `packages/api/`, it loads both `packages/api/CLAUDE.md` and the root `CLAUDE.md`. Claude sees the local instructions alongside the repository-wide rules, with no instructions from `packages/web/` in context. The same holds for any subdirectory in a non-monorepo tree. To confirm which files loaded, run `/context` and check the list under **Memory files**. A few ways to keep the files current as the codebase and models change:

- **Review in pull requests**: treat CLAUDE.md edits like any other documentation change so conventions track the code
- **Revisit after major model releases**: instructions that worked around an older model’s limitation may become overhead once a newer model handles the case on its own. For example, a rule that forces single-file refactors can be deleted once the limitation is gone
- **Add a Stop hook that proposes updates**: a [`Stop` hook](../07-Hooks/hooks.md#stop) receives the path to the session transcript when Claude finishes responding, so a script can review the session and propose CLAUDE.md updates while the gap it exposed is fresh

For more on how CLAUDE.md files load and interact, see [Memory and project instructions](memory.md).


[​](#choose-between-per-directory-claude-md-and-path-scoped-rules)

Choose between per-directory CLAUDE.md and path-scoped rules

Per-directory `CLAUDE.md` files and [path-scoped rules](memory.md#path-specific-rules) under `.claude/rules/` both let you target instructions to part of the tree. They differ in where the file lives and when it loads.

| Approach                             | File location                            | Loads when                                                      | Use when                                                                                  |
|:-------------------------------------|:-----------------------------------------|:----------------------------------------------------------------|:------------------------------------------------------------------------------------------|
| Per-directory `CLAUDE.md`            | Inside the directory, alongside its code | At launch when started from that directory, or on demand        | Directory owners maintain their own conventions; instructions are versioned with the code |
| Path-scoped rule in `.claude/rules/` | Central `.claude/` at the repo root      | When Claude works with a file matching the rule’s `paths:` glob | You want all conventions in one place, or the same rule applies to many scattered paths   |

For a comparison that also covers skills, see [Compare similar features](features-overview.md#compare-similar-features).


[​](#exclude-irrelevant-claude-md-files)

Exclude irrelevant CLAUDE.md files

When you start Claude from the repository root, each subdirectory’s CLAUDE.md can [load on demand](memory.md#how-claude-md-files-load) during the session. The `claudeMdExcludes` setting skips specific files by path or glob pattern so they never load. Use this for directories you never work in, such as other teams’ packages, legacy code, or vendored subtrees. The exclusion list is static, not a per-task switch. To focus on one package today and another tomorrow, [start Claude from that package’s directory](#choose-where-to-start-claude) instead of editing exclusions. If you only want these exclusions for yourself, put the setting in `.claude/settings.local.json`. Claude Code adds that file to your global gitignore when it saves a setting there. Since you are creating it by hand here, add it to your gitignore yourself. Patterns use glob syntax matched against absolute file paths, so start relative-style patterns with `**/` to match anywhere in the tree. The example below excludes a package owned by another team:

.claude/settings.local.json

```python
{
  "claudeMdExcludes": [
    "**/packages/web/**"
  ]
}
```

This skips every CLAUDE.md and rules file under that package. The root CLAUDE.md and the packages you do work in still load normally. These patterns cover other common cases:

- `"**/packages/*/CLAUDE.md"`: excludes every package’s CLAUDE.md while keeping the root
- `"**/packages/legacy-*/**"`: excludes every package whose name matches the glob, including rules
- `"/home/user/monorepo/legacy/CLAUDE.md"`: excludes one specific file by absolute path

You can set `claudeMdExcludes` at any [settings scope](settings.md#where-settings-live): user, project, local, or managed. Arrays merge across scopes, so a team can set project-level defaults while individuals add local overrides. If your organization deploys a [managed CLAUDE.md file](memory.md#deploy-organization-wide-claude-md), a pattern that matches it doesn’t skip it, whichever scope sets the pattern. For the full exclusion documentation, see [Exclude specific CLAUDE.md files](memory.md#exclude-specific-claude-md-files).


[​](#reduce-what-claude-reads)

Reduce what Claude reads

Instructions are only part of what ends up in Claude’s context. File reads are another cost that grows with the codebase. The settings below block reads of irrelevant paths and replace exhaustive file scans with language-server lookups.


[​](#block-reads-of-generated-and-vendored-code)

Block reads of generated and vendored code

Claude’s content searches respect `.gitignore` by default, so paths already listed there, such as `node_modules/`, `dist/`, and `build/`, stay out of search results without additional configuration. For paths that are checked in, such as a vendored SDK or committed generated code, add `Read` deny rules in `permissions.deny` to block Claude from opening those files. The deny rules can cover everyone working in the repository, only you, or every session on the machine, depending on which settings file you put them in:

- **Everyone working in the repository**: commit the rules to `.claude/settings.json`, at the repository root if you start Claude there, or in each package’s `.claude/` if you start from subdirectories. Like other project settings on this page, that file isn’t inherited from parent directories.
- **Yourself only**: use `.claude/settings.local.json` at the repository root, which loads in every CLI session inside the repository regardless of starting directory, except in the cases where Claude Code [doesn’t use the repository root](settings.md#where-claude-code-looks-for-each-file), such as on Windows. Relative patterns like the example’s `Read(./**/vendor/**/*)` still [anchor at the session’s current working directory](permissions.md#read-and-edit) rather than the repository root, so if you start sessions from subdirectories, write the rules in this file as `//`-absolute paths, such as `Read(//absolute/path/to/repo/**/vendor/**/*)`. Before v2.1.211, `.claude/settings.local.json` also loaded only from the starting directory.
- **Everyone, enforced in every session**: set the rules in [managed settings](../13-Enterprise-Admin/managed-settings.md), which user and project settings cannot override.

The example below blocks build artifacts and a vendored SDK. Its directory patterns end with `/**/*` rather than `/**` so that each rule covers everything inside the directory but not the directory itself. Claude can then still list those directories or change into them, for example with `ls dist` or `cd build`.

.claude/settings.json

```python
{
  "permissions": {
    "deny": [
      "Read(./**/dist/**/*)",
      "Read(./**/build/**/*)",
      "Read(./**/*.generated.*)",
      "Read(./**/vendor/**/*)"
    ]
  }
}
```

Deny rules cover Claude’s built-in file tools. In Bash, they cover the file commands Claude Code recognizes, such as `cat`, `head`, `grep`, and `find`, when a denied path appears as an argument, and the target of a [redirection](permissions.md#redirections) such as `< file`. Claude Code also makes a best-effort attempt to leave denied paths out of the results of the built-in Grep and Glob tools. A Bash search such as `grep -r` or `find` over a directory that contains denied files still includes them in its output. Deny rules don’t cover subprocesses that open files themselves. For the full pattern syntax, see [Read and Edit permission rules](permissions.md#read-and-edit).


[​](#reduce-file-reads-with-code-intelligence)

Reduce file reads with code intelligence

In a large codebase, finding where a symbol is defined or used can cost many file reads and grep calls. [Code intelligence plugins](../08-Plugins-Skills/plugins-code-intelligence.md) connect Claude to a language server so it can jump to definitions, find references, and surface type errors directly instead of scanning the tree. The official marketplace has plugins for TypeScript, Python, Go, Rust, and other common languages. In the VS Code extension or the desktop app, install one by following [Install a plugin](../08-Plugins-Skills/discover-plugins.md#install-a-plugin). In a terminal, start Claude Code by running `claude`, then enter this at its prompt to install the TypeScript plugin:

```python
/plugin install typescript-lsp@claude-plugins-official
```

If the install fails, match the message Claude Code reports:

- `Marketplace "claude-plugins-official" not found`: add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`, then retry the install.
- `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](../08-Plugins-Skills/plugins-troubleshooting.md#plugin-not-found-in-marketplace).

To enable a plugin for everyone in the repository rather than installing it yourself, add it to the [`enabledPlugins` project setting](settings-reference.md#plugin-settings). Code intelligence plugins require the language’s language server binary on each developer’s machine. See [which binary each language requires](../08-Plugins-Skills/plugins-code-intelligence.md). Installing from the official marketplace requires network access to GitHub, where the marketplace is hosted. On a restricted network, [add the marketplace from an internal Git host or local path](../08-Plugins-Skills/discover-plugins.md#add-a-marketplace) instead. This pairs well with `claudeMdExcludes` and the `Read` deny rules above. Those keep irrelevant content out of context, and code intelligence keeps Claude from reading through what remains to locate a definition.


[​](#scope-worktrees-and-file-access)

Scope worktrees and file access

These settings control what’s on disk in worktrees and which directories Claude can read and write beyond your starting point.


[​](#check-out-only-the-directories-you-need)

Check out only the directories you need

The `--worktree` flag starts a session in a new git worktree so changes stay isolated from your main checkout. By default it checks out the entire repository. In a large repository, the `worktree.sparsePaths` setting uses git sparse-checkout to write only the listed directories plus root-level files to disk, so worktrees start faster and use less space. If everyone working in this directory needs the same paths, commit the setting to `.claude/settings.json`. To add paths for yourself, use `.claude/settings.local.json`: the lists merge across scopes, so a local file can add paths to the committed list but not remove them. The JSON examples on this page show one setting at a time. If your `.claude/settings.json` already contains other keys, such as the `permissions.deny` rules above, add the `worktree` key alongside them rather than replacing the file. [Put it together](#put-it-together) shows the combined result. The example below shows the committed file:

.claude/settings.json

```python
{
  "worktree": {
    "sparsePaths": [
      ".claude",
      "packages/api",
      "packages/shared"
    ]
  }
}
```

When Claude creates a worktree, it checks out only `.claude/`, `packages/api/`, and `packages/shared/` instead of the full tree. Paths in `sparsePaths` are relative to the repository root, regardless of which subdirectory you start Claude from. Any directory paths work here, not only package roots. This is particularly useful for [subagent worktree isolation](worktrees.md#isolate-subagents-with-worktrees). Subagents are parallel Claude instances spawned for subtasks, and each one that runs in a worktree gets a lightweight checkout instead of the full tree. All worktrees in a session share the same `sparsePaths`, so if one subagent needs `packages/api/` and another needs `packages/web/`, list both. List directories in `sparsePaths`, not individual files. Root-level files like `package.json`, `tsconfig.base.json`, and lock files are always checked out alongside the directories you list. Root-level directories are not, so include `.claude` in the list if you want the repository root’s `.claude/settings.json` or `.claude/rules/` available inside the worktree. For project skills, agents, and commands, see [What worktrees share with the main checkout](worktrees.md#what-worktrees-share-with-the-main-checkout). Sparse checkout requires git to enable `extensions.worktreeConfig` in the repository’s shared `.git/config` while a sparse worktree exists. Claude Code removes that entry after the last worktree is removed, but only if Claude Code added it. It never removes a value you set yourself. To avoid duplicating large directories like `node_modules` across worktrees, pair `sparsePaths` with `symlinkDirectories` in the same `.claude/settings.json`:

.claude/settings.json

```python
{
  "worktree": {
    "sparsePaths": [
      ".claude",
      "packages/api",
      "packages/shared"
    ],
    "symlinkDirectories": [
      "node_modules"
    ]
  }
}
```

This creates a symlink from each worktree’s `node_modules/` back to the main repository’s copy rather than duplicating it on disk.

The `sparsePaths` and `symlinkDirectories` settings are read from your starting directory before the worktree is created. After creation, the session’s working directory is the worktree root, not the subdirectory you launched from. Project settings inside the worktree therefore load from the worktree root’s `.claude/settings.json`, the checked-out copy of the repository root’s file. Put any other settings you need inside worktrees, such as permission rules or hooks, in the repository root’s `.claude/settings.json`.

For the full worktree settings reference, see [Worktree settings](settings-reference.md#worktree).


[​](#grant-access-across-packages-or-repositories)

Grant access across packages or repositories

This section applies when you start Claude from a subdirectory, or when a task spans multiple checkouts. If you start from the repository root in a single large tree, Claude already has access to every file and you can skip this. When you start Claude from `packages/api/`, it can read and write files within that directory. If a task requires changes across packages, such as updating a shared type that both `api` and `web` import, you need to grant access to the sibling directory. The same mechanism grants access to a separately checked-out repository. The `additionalDirectories` setting in `.claude/settings.json` gives Claude access to directories outside the working directory. The example below grants access to two sibling packages:

packages/api/.claude/settings.json

```python
{
  "permissions": {
    "additionalDirectories": [
      "../shared",
      "../web"
    ]
  }
}
```

Relative paths resolve against the directory you start Claude from. With this configuration, Claude can read and edit files in `packages/shared/` and `packages/web/` while working from `packages/api/`. You can also grant access at runtime without editing settings by passing `--add-dir` when you start Claude:

```python
claude --add-dir ../shared
```

However you add a directory, Claude can read and edit files in it. Whether the directory’s CLAUDE.md, `.claude/rules/` files, and skills also load depends on how you added it:

| Added with                             | Loads CLAUDE.md and rules                | Loads skills |
|:---------------------------------------|:-----------------------------------------|:-------------|
| `additionalDirectories` setting        | Never                                    | Never        |
| `--add-dir` flag or `/add-dir` command | Only with the environment variable below | Yes          |

To load CLAUDE.md and rules files from a directory added with `--add-dir` or `/add-dir`, set the `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD` environment variable:

```python
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 claude --add-dir ../shared
```

The environment variable has no effect on directories listed in the `additionalDirectories` setting. See [Load from additional directories](memory.md#load-from-additional-directories) for details. For sibling directories that everyone in this area needs, commit `additionalDirectories` to `.claude/settings.json`. For a personal selection or one-off access, use `.claude/settings.local.json` or pass `--add-dir` at launch.


[​](#add-per-directory-skills)

Add per-directory skills

Any subdirectory can define [skills](../08-Plugins-Skills/skills.md) scoped to its own stack. A skill loads on demand when Claude determines it’s relevant, so API-specific tooling doesn’t consume context during frontend work. Skills live under `.claude/skills/` inside the directory. Commit them alongside that area’s code so anyone who clones the repository gets them. In a monorepo this can be one set of skills per package. In a large single-tree codebase it’s one set per subsystem such as `src/db/.claude/skills/`. Create a skill directory inside the subdirectory:

```python
mkdir -p packages/api/.claude/skills/api-testing
```

Then write `SKILL.md` inside that directory, here `packages/api/.claude/skills/api-testing/SKILL.md`. This example teaches Claude the API package’s testing patterns:

packages/api/.claude/skills/api-testing/SKILL.md

```python
---
name: api-testing
description: Testing patterns for the API package. Use when writing or modifying tests in packages/api/.
---

## Test structure

Tests are in `src/__tests__/` mirroring the `src/` directory structure.
Each route file has a corresponding `.test.ts` file.

## Running tests

- All tests: `npm test`
- Single file: `npm test -- src/__tests__/routes/users.test.ts`
- Watch mode: `npm test -- --watch`

## Test utilities

- `src/__tests__/helpers/db.ts`: provides `setupTestDb()` and `teardownTestDb()` for database tests
- `src/__tests__/helpers/auth.ts`: provides `createTestUser()` and `getAuthToken()` for authenticated endpoints

## Patterns

- Use `supertest` for HTTP assertions, not raw fetch
- Always wrap database tests in a transaction that rolls back
- Mock external services in `src/__tests__/mocks/`
```

A different subdirectory holds different skills the same way: `packages/web/.claude/skills/component-patterns/` describes the frontend’s component conventions instead of testing. When Claude works on a file in `packages/api/`, it loads the api-testing skill. When it works in `packages/web/`, it loads component-patterns instead. Neither directory’s skills load during the other’s tasks. You can also scope a skill by file pattern instead of by placement. The [`paths` frontmatter field](../08-Plugins-Skills/skills.md#frontmatter-reference) takes glob patterns, and Claude loads the skill automatically only when it works with matching files. Use this for a skill that lives in the repository root’s `.claude/skills/` but applies only to certain files, such as a database-migration skill scoped to `**/migrations/**`. For more on creating and organizing skills, see [Skills](../08-Plugins-Skills/skills.md).


[​](#keep-skills-discoverable)

Keep skills discoverable

With skills spread across many directories, the list Claude chooses from can grow large. Claude picks a skill by reading every discovered skill’s name and description, and only the chosen skill’s full content loads into context. This section covers how to keep that list small. Which skills are in scope depends on where you start Claude:

- **From a subdirectory such as `packages/api/`**: skills from that directory, every parent up to the repository root, and the user and enterprise levels
- **From the repository root**: root skills, plus skills from every subdirectory Claude touches during the session, which can accumulate into the hundreds
- **After adding a sibling with [`--add-dir`](#grant-access-across-packages-or-repositories)**: that sibling’s skills load too. The `additionalDirectories` setting grants file access only and does not load skills

Names always load, but [when there are many, some skills lose their descriptions entirely](../08-Plugins-Skills/skills.md#skill-descriptions-are-cut-short), which can strip the keywords Claude uses to decide whether a skill applies. Keep descriptions short and lead with words a request would contain, like “writing or modifying tests in `packages/api/`”. For skills that many directories share, such as PR conventions or a deploy checklist, place them in the repository root’s `.claude/skills/` so they load from any starting directory. When shared skills need their own version history or must work across repositories, package them as a [plugin](../08-Plugins-Skills/plugins.md) instead. Plugin skills use a `plugin-name:skill-name` namespace, so they never collide with per-directory skills. A platform team can version and update them in one place. To find which skills go unused, enable the OpenTelemetry [logs exporter](../13-Enterprise-Admin/monitoring-usage.md) and set `OTEL_LOG_TOOL_DETAILS=1` so skill names are recorded verbatim instead of redacted. The [`skill_activated` event](../13-Enterprise-Admin/monitoring-usage.md#skill-activated-event) records every invocation in its `skill.name` attribute, and `invocation_trigger` records whether a command, Claude, or a nested skill invoked it, which tells you what to consolidate or retire.


[​](#centralize-conventions-when-layering-stops-scaling)

Centralize conventions when layering stops scaling

Per-directory CLAUDE.md files can become hard to govern as the codebase grows. Conventions drift, files go stale, and no one owns the root. Solving that typically falls to the team that maintains the repository’s Claude Code setup rather than to each developer working in their own area. Move conventions and reference content out of always-loaded CLAUDE.md and into mechanisms that load on demand:

- [Skills](../08-Plugins-Skills/skills.md): reference material Claude loads only when relevant to the task
- [Plugins](../08-Plugins-Skills/plugins.md): versioned bundles of skills, hooks, and commands that a platform team owns centrally
- [MCP servers](../06-MCP-Tools/General/mcp.md): if your organization already runs a code search or RAG index over the repository, expose it as an MCP tool so Claude queries it instead of reading files directly

See [server-managed or endpoint-managed settings](../13-Enterprise-Admin/server-managed-settings.md#choose-between-server-managed-and-endpoint-managed-settings) for how platform teams can enforce these centrally.


[​](#recommend-the-right-plugin-at-session-start)

Recommend the right plugin at session start

Once conventions live in plugins, a teammate starting Claude in an unfamiliar part of the tree has no signal about which plugin that area’s owners maintain. A [`SessionStart` hook](../07-Hooks/hooks.md#sessionstart) can close that gap, since Claude Code adds plain text the hook prints to stdout to Claude’s context before the first prompt. For example, you can write a script that reads the launch directory from the [hook input](../07-Hooks/hooks.md#common-input-fields), looks it up in a path-to-plugin map committed to the repository, and prints the recommendation for Claude to relay in its first reply. See [Automate actions with hooks](../07-Hooks/hooks-guide.md) to write and register the hook.


[​](#put-it-together)

Put it together

The combined configuration below uses the monorepo layout. The same files work for any subdirectory in a large single tree. Each subdirectory’s `.claude/settings.json` must be self-contained rather than layered on a root file. The example commits `worktree`, `additionalDirectories`, and the `Read` deny rules in `.claude/settings.json` so every developer in `packages/api/` gets the same sibling access, sparse paths, and exclusions. The file below is the committed per-area settings for `packages/api/`:

packages/api/.claude/settings.json

```python
{
  "worktree": {
    "sparsePaths": [
      ".claude",
      "packages/api",
      "packages/shared"
    ],
    "symlinkDirectories": [
      "node_modules"
    ]
  },
  "permissions": {
    "additionalDirectories": [
      "../shared"
    ],
    "deny": [
      "Read(./**/dist/**/*)",
      "Read(./**/build/**/*)"
    ]
  }
}
```

Because this session starts from `packages/api/`, sibling packages’ CLAUDE.md files are already out of scope, so `claudeMdExcludes` is not needed here. Add it to the repository root’s `.claude/settings.local.json` instead if you also start sessions from the root. The `additionalDirectories` entry applies when you start Claude from `packages/api/` directly. Inside a worktree created from this session, the working directory is the worktree root, so this settings file does not load. The sibling packages are already reachable inside the worktree without it, but the deny rules need a second copy in the repository root’s `.claude/settings.json` so worktree sessions pick them up, as the [worktree settings note](#check-out-only-the-directories-you-need) describes:

.claude/settings.json

```python
{
  "permissions": {
    "deny": [
      "Read(./**/dist/**/*)",
      "Read(./**/build/**/*)"
    ]
  }
}
```

After setup, the repository has this layout:

```python
monorepo/
  CLAUDE.md
  .claude/settings.json                           # deny rules for worktree sessions
  packages/
    api/
      CLAUDE.md
      .claude/settings.json                       # worktree, additionalDirectories, deny rules
      .claude/skills/api-testing/SKILL.md
    web/
      CLAUDE.md
      .claude/skills/component-patterns/SKILL.md
    shared/
      CLAUDE.md
```

With this setup, starting Claude from `packages/api/`:

- Loads the root CLAUDE.md and `packages/api/CLAUDE.md`, skips `packages/web/CLAUDE.md`
- Can read and edit files in `packages/api/` and `packages/shared/`
- Skips reads of build output under `dist/` and `build/` in `packages/api/`
- Has the api-testing skill available on demand
- Creates worktrees containing `.claude/`, `packages/api/`, `packages/shared/`, and root-level files, with the deny rules applied across the worktree from the root settings file


[​](#scope-and-plan-changes-that-span-packages)

Scope and plan changes that span packages

The configuration above controls what Claude sees. When a single change touches several packages, such as updating a shared type along with every call site that uses it, how you scope and sequence the task also affects the result. Two techniques help keep a cross-package change consistent:

- **Give Claude the whole change in one session**: handing over the shared edit and its call sites together keeps the decisions behind each edit consistent, rather than re-deriving them per package
- **Plan before editing**: [plan first](best-practices.md#explore-first-then-plan-then-code) in [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode), and Claude writes the plan to a file. A long cross-package session [compacts its context](context-window.md#what-survives-compaction) along the way. Claude Code re-injects the plan file after each compaction, so the plan survives where conversation history may not


[​](#next-steps)

Next steps

Once this configuration is in place, you can refine it:

- Use [hooks](../07-Hooks/hooks-guide.md) to run per-directory linters or type-checkers after Claude edits files
- Review [Manage costs effectively](../17-Billing-Plans/costs.md) to understand how codebase size affects token usage and how to set spend limits before a wider rollout
- Read [How Claude Code works in large codebases](https://claude.com/blog/how-claude-code-works-in-large-codebases-best-practices-and-where-to-start) on the Claude blog for organizational rollout patterns and ownership models that sit above the per-repository configuration on this page

---

## Docs Llms Txt Cc59D2A156

Source: https://code.claude.com/docs/llms.txt
Path: 02-Claude-Code-CLI/llms.md

\# Claude Code Docs \> Official documentation for Claude Code, Anthropic's agentic coding tool available in the terminal, IDE, desktop app, and browser. Covers installation, configuration, skills, subagents, hooks, MCP, the Agent SDK, and reference material. \## Getting started \### Overview \#### Getting started - \[Overview\](code-home.md): Claude Code is an agentic coding tool that reads your codebase, edits files, runs commands, and integrates with your development tools. Available in your terminal, IDE, desktop app, and browser. - \[Quickstart\](../01-Getting-Started/quickstart.md): Install Claude Code in your terminal, sign in, and use the CLI to explore your codebase and make your first code change. - \[Claude Code changelog\](changelog.md): Release notes for Claude Code, including new features, improvements, and bug fixes by version. \#### Core concepts - \[How Claude Code works\](how-claude-code-works.md): Understand the agentic loop, built-in tools, and how Claude Code interacts with your project. - \[Extend Claude Code\](features-overview.md): Understand when to use CLAUDE.md, Skills, subagents, hooks, MCP, and plugins. - \[Explore the .claude directory\](claude-directory.md): Where Claude Code reads CLAUDE.md, settings.json, hooks, skills, commands, subagents, workflows, rules, and auto memory. Explore the .claude directory in your project and ~/.claude in your home directory. - \[Explore the context window\](context-window.md): An interactive simulation of how Claude Code's context window fills during a session. See what loads automatically, what each file read costs, and when rules and hooks fire. - \[How Claude Code uses prompt caching\](prompt-caching.md): Claude Code manages prompt caching automatically. See why a model switch triggers a slow uncached turn, what \`/compact\` costs, why CLAUDE.md edits don't apply mid-session, and how to check your cache hit rate. \#### Use Claude Code - \[How Claude remembers your project\](memory.md): Give Claude persistent instructions with CLAUDE.md or AGENTS.md files, and let Claude accumulate learnings automatically with auto memory. - \[Manage sessions\](sessions.md): Name, resume, branch, and switch between Claude Code conversations. Covers \`--continue\`, \`--resume\`, \`--from-pr\`, the \`/resume\` picker, session naming, exporting transcripts, and where transcripts are stored. - \[Common workflows\](common-workflows.md): Step-by-step guides for exploring codebases, fixing bugs, refactoring, testing, and other everyday tasks with Claude Code. - \[Prompt library\](prompt-library.md): Copy-paste prompts for Claude Code, tagged by task and role. - \[Best practices for Claude Code\](best-practices.md): Tips and patterns for getting the most out of Claude Code, from configuring your environment to scaling across parallel sessions. \#### Platforms and integrations - \[Platforms and integrations\](platforms.md): Choose where to run Claude Code and what to connect it to. Compare the CLI, Desktop, VS Code, JetBrains, web, mobile, and integrations like Chrome, Slack, and CI/CD. - \[Continue local sessions from any device with Remote Control\](remote-control.md): Continue a local Claude Code session from your phone, tablet, or any browser using Remote Control. Works with claude.ai/code and the Claude mobile app. - \[Let Claude coordinate ongoing work with Projects\](claude-projects.md): Hand Claude a stream of related tasks in one conversation and let it run them as parallel cloud sessions that share repositories, instructions, and memory. - \[Claude Code on mobile\](../16-Mobile-Desktop/mobile.md): Start, monitor, and steer Claude Code tasks from your phone with the Claude app for iOS and Android. - \[Use Claude Code with Chrome\](../03-IDE-Integrations/chrome.md): Connect Claude Code to your Chrome browser to test web apps, debug with console logs, automate form filling, and extract data from web pages. - \[Let Claude use your computer from the CLI\](computer-use.md): Enable computer use in the Claude Code CLI so Claude can open apps, click, type, and see your screen on macOS. Test native apps, debug visual issues, and automate GUI-only tools without leaving your terminal. - \[Use Claude Code in VS Code\](../03-IDE-Integrations/vs-code.md): Install and configure the Claude Code extension for VS Code. Get AI coding assistance with inline diffs, @-mentions, plan review, and keyboard shortcuts. - \[JetBrains IDEs\](../03-IDE-Integrations/jetbrains.md): Use Claude Code with JetBrains IDEs including IntelliJ, PyCharm, WebStorm, and more - \[Claude Code in Slack\](../14-Connectors/slack.md): Delegate coding tasks from Slack. This earlier version answers channel mentions only from Pro and Max accounts in workspaces not connected to Claude Tag. - \[Claude Tag\](claude-tag.md): Bring Claude into your team's Slack channels with Claude Tag and find its setup and usage documentation on claude.com. \##### Claude Code in the cloud - \[Get started with Claude Code in the cloud\](web-quickstart.md): Run Claude Code in the cloud from your browser or phone. Connect a GitHub repository, submit a task, and review the PR without local setup. - \[Use Claude Code in the cloud\](claude-code-on-the-web.md): Run Claude Code sessions in the cloud from your browser, phone, Desktop app, or terminal, move them with \`--cloud\` and \`--teleport\`, and auto-fix pull requests. - \[Automate work with scheduled tasks\](web-scheduled-tasks.md): Put Claude Code on autopilot. Create scheduled tasks, formerly routines, that run in the cloud on a schedule, on API calls, or on GitHub events. \##### Claude Code on desktop - \[Get started with the desktop app\](../16-Mobile-Desktop/desktop-quickstart.md): Install the Claude desktop app, open the Code tab, and start your first Claude Code session on a project folder on your computer. - \[Desktop application\](../16-Mobile-Desktop/desktop.md): Get more out of Claude Code Desktop: parallel sessions with Git isolation, drag-and-drop pane layout, integrated terminal and file editor, side chats, computer use, Dispatch sessions from your phone, visual diff review, app previews, PR monitoring, connectors, and enterprise configuration. - \[Claude Desktop on Linux (beta)\](../16-Mobile-Desktop/desktop-linux.md): Install and update the Claude desktop app on Ubuntu and Debian - \[Claude Code Desktop in WSL\](../16-Mobile-Desktop/desktop-wsl.md): Run Code sessions inside a WSL 2 distribution on Windows - \[Schedule recurring tasks in Claude Code Desktop\](../16-Mobile-Desktop/desktop-scheduled-tasks.md): Set up scheduled tasks in Claude Code Desktop to run Claude automatically on a recurring basis for daily code reviews, dependency audits, or morning briefings. - \[Test iOS apps in the simulator\](../16-Mobile-Desktop/desktop-ios-simulator.md): Claude Code Desktop opens your app in the iOS Simulator pane when Claude builds, runs, or checks it, with a separate simulator for each session. \#### Code review and pull requests - \[Review locally with /code-review\](code-review-local.md): Run \`/code-review\` in a Claude Code session to find bugs in your branch's changes, point the review at a pull request or path, and have Claude apply the fixes. - \[Find bugs with ultrareview\](ultrareview.md): Run a deep, multi-agent code review in the cloud with /code-review ultra to find and verify bugs before you merge. - \[Claude Code with GitHub Enterprise Server\](github-enterprise-server.md): Connect Claude Code to your self-hosted GitHub Enterprise Server instance for cloud sessions, code review, and plugin marketplaces. \##### Code Review - \[Code Review\](code-review.md): Catch bugs in GitHub pull requests with Code Review: Claude reviews each change, verifies its findings, and comments inline. For Team and Enterprise plans - \[Set up Code Review\](code-review-setup.md): Turn on Code Review for your Claude organization: connect GitHub, install the Claude GitHub App, choose repositories, and set when reviews run - \[Customize Code Review\](code-review-customize.md): Tune what Code Review flags on your pull requests with REVIEW.md and CLAUDE.md: recalibrate severity, skip paths, add checks, and see which copy applies. - \[Read and request reviews on a pull request\](code-review-pull-requests.md): Read Code Review findings on your GitHub pull request, respond to or dismiss them, and request a review with \`@claude review\`. - \[Code Review costs and usage\](code-review-costs.md): Estimate and cap what your organization spends on Claude Code Review: how reviews are billed through usage credits, what drives cost, and where to track usage. - \[Troubleshoot Code Review\](code-review-troubleshooting.md): Fix a Code Review that didn't start, failed, or was skipped for budget, find missing findings, and resolve setup and \`REVIEW.md\` problems. \##### Security scans - \[Catch security issues as Claude writes code\](security-guidance.md): Install the security-guidance plugin to have Claude review its own code changes for vulnerabilities and fix them in the same session. - \[Scan your codebase for vulnerabilities\](claude-security.md): Install the Claude Security plugin to scan your codebase for vulnerabilities in a Claude Code session and turn findings into patches you review and apply. \##### Run Claude in your own CI - \[Claude Code GitHub Actions\](github-actions.md): Run Claude Code in GitHub Actions workflows to respond to @claude mentions, automate tasks, and turn issues into pull requests - \[Use Claude Code GitHub Actions with cloud providers\](github-actions-cloud-providers.md): Run Claude Code GitHub Actions through Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry instead of the Claude API - \[Claude Code GitLab CI/CD\](gitlab-ci-cd.md): Learn about integrating Claude Code into your development workflow with GitLab CI/CD \### Quickstart - \[Quickstart\](../01-Getting-Started/quickstart.md): Install Claude Code in your terminal, sign in, and use the CLI to explore your codebase and make your first code change. \### Core concepts - \[How Claude Code works\](how-claude-code-works.md): Understand the agentic loop, built-in tools, and how Claude Code interacts with your project. \### Use Claude Code - \[How Claude remembers your project\](memory.md): Give Claude persistent instructions with CLAUDE.md or AGENTS.md files, and let Claude accumulate learnings automatically with auto memory. \### Platforms and integrations - \[Platforms and integrations\](platforms.md): Choose where to run Claude Code and what to connect it to. Compare the CLI, Desktop, VS Code, JetBrains, web, mobile, and integrations like Chrome, Slack, and CI/CD. \### Code review and pull requests - \[Code Review\](code-review.md): Catch bugs in GitHub pull requests with Code Review: Claude reviews each change, verifies its findings, and comments inline. For Team and Enterprise plans \## Build with Claude Code \### Agents and parallel work \#### Agents and parallel work - \[Run agents in parallel\](../09-Agents-Patterns/agents.md): Compare the ways Claude Code can take on multiple tasks at once: subagents, agent view, agent teams, dynamic workflows, and projects. - \[Create custom subagents\](../09-Agents-Patterns/sub-agents.md): Create and use specialized AI subagents in Claude Code for task-specific workflows and improved context management. - \[Manage multiple agents with agent view\](../09-Agents-Patterns/agent-view.md): Dispatch and manage many Claude Code sessions from one screen. Agent view shows what every session is doing and which ones need your input. - \[Orchestrate teams of Claude Code sessions\](../09-Agents-Patterns/agent-teams.md): Coordinate multiple Claude Code instances working together as a team, with shared tasks, inter-agent messaging, and centralized management. - \[Message your other Claude Code sessions\](cross-session-messaging.md): Let Claude list and message your other Claude Code sessions on this machine, and reach your sessions on other machines or in the cloud. - \[Orchestrate subagents at scale with dynamic workflows\](workflows.md): Dynamic workflows orchestrate many subagents from a script Claude writes and you can rerun. Use them for codebase audits, large migrations, and cross-checked research. - \[Run parallel sessions with worktrees\](worktrees.md): Isolate parallel Claude Code sessions in separate git worktrees so changes don't collide. Covers the \`--worktree\` flag, subagent isolation, \`.worktreeinclude\`, cleanup, and non-git VCS hooks. \#### MCP - \[Connect to MCP servers\](../06-MCP-Tools/General/mcp-quickstart.md): Add an MCP server to Claude Code, verify the connection, and find the configuration on disk. - \[Connect Claude Code to tools via MCP\](../06-MCP-Tools/General/mcp.md): Learn how to connect Claude Code to your tools with the Model Context Protocol. \#### Skills - \[Extend Claude with skills\](../08-Plugins-Skills/skills.md): Create, manage, and share skills to extend Claude's capabilities in Claude Code. Includes custom commands and bundled skills. \#### Artifacts - \[Share session output as artifacts\](artifacts.md): Artifacts turn Claude Code's work into live, interactive pages on claude.ai that you can keep private, share with your organization, or publish to a public link. \#### Automation - \[Automate actions with hooks\](../07-Hooks/hooks-guide.md): Run shell commands automatically when Claude Code edits files, finishes tasks, or needs input. Format code, send notifications, validate commands, and enforce project rules. - \[Push events into a running session with channels\](channels.md): Use channels to push messages, alerts, and webhooks into your Claude Code session from an MCP server. Forward CI results, chat messages, and monitoring events so Claude can react while you're away. - \[Run prompts on a schedule\](scheduled-tasks.md): Use /loop and the cron scheduling tools to run prompts repeatedly, poll for status, or set one-time reminders within a Claude Code session. - \[Keep Claude working toward a goal\](goal.md): Set a completion condition with /goal and Claude keeps working until it's met, a model judges it impossible, or an error you have to fix clears the goal. - \[Run Claude Code programmatically\](headless.md): Use the Agent SDK to run Claude Code programmatically from the CLI, Python, or TypeScript. - \[Launch sessions from links\](deep-links.md): Open a Claude Code terminal session from a URL. Embed \`claude-cli://\` links in runbooks, alerts, and dashboards so a click opens Claude Code in the right repo with the right prompt. \#### Guides - \[Set up Claude Code in a monorepo or large codebase\](large-codebases.md): Configure Claude Code for monorepos and large single-tree codebases with nested CLAUDE.md files, sparse worktrees, code intelligence, and per-package skills so Claude stays focused on the code you're working in. \#### Troubleshooting - \[Troubleshoot installation and login\](troubleshoot-install.md): Fix command not found, PATH, permission, network, and authentication errors when installing or signing in to Claude Code. - \[Troubleshooting\](troubleshooting.md): Fix high CPU or memory usage, hangs, auto-compact thrashing, and search problems in Claude Code, and find the right page for other issues. - \[Debug your configuration\](debug-your-config.md): Diagnose why CLAUDE.md, settings, hooks, MCP servers, or skills aren't taking effect. Use /context, /doctor, /hooks, and /mcp to see what actually loaded. - \[Error reference\](errors.md): Look up Claude Code runtime error messages with what each one means and how to fix it. \### MCP - \[Connect to MCP servers\](../06-MCP-Tools/General/mcp-quickstart.md): Add an MCP server to Claude Code, verify the connection, and find the configuration on disk. \### Skills - \[Extend Claude with skills\](../08-Plugins-Skills/skills.md): Create, manage, and share skills to extend Claude's capabilities in Claude Code. Includes custom commands and bundled skills. \### Artifacts - \[Share session output as artifacts\](artifacts.md): Artifacts turn Claude Code's work into live, interactive pages on claude.ai that you can keep private, share with your organization, or publish to a public link. \### Automation - \[Automate actions with hooks\](../07-Hooks/hooks-guide.md): Run shell commands automatically when Claude Code edits files, finishes tasks, or needs input. Format code, send notifications, validate commands, and enforce project rules. \### Guides - \[Set up Claude Code in a monorepo or large codebase\](large-codebases.md): Configure Claude Code for monorepos and large single-tree codebases with nested CLAUDE.md files, sparse worktrees, code intelligence, and per-package skills so Claude stays focused on the code you're working in. \### Troubleshooting - \[Troubleshoot installation and login\](troubleshoot-install.md): Fix command not found, PATH, permission, network, and authentication errors when installing or signing in to Claude Code. \## Plugins \### Plugins \#### Plugins - \[Plugins overview\](../08-Plugins-Skills/plugins.md): Understand what a Claude Code plugin is, when you need one instead of a standalone skill or MCP server, and which page to read to install or create one. \#### Use plugins - \[Install and manage plugins\](../08-Plugins-Skills/discover-plugins.md): Install Claude Code plugins from a marketplace on any surface you use, choose an install scope, and update or remove them later. - \[Anthropic's marketplaces\](../08-Plugins-Skills/plugins-anthropic-marketplaces.md): Anthropic's official, community, and demo plugin marketplaces for Claude Code: their names, repositories, how you add each, and where to browse their plugins. - \[Code intelligence plugins\](../08-Plugins-Skills/plugins-code-intelligence.md): Install a language server plugin so Claude sees type errors after edits and navigates code by symbol, and answer the LSP plugin recommendation dialog. - \[Plugin security and trust\](../08-Plugins-Skills/plugins-security.md): Decide whether to trust a plugin before you install it, from what a plugin can do on your machine to how to review one and remove it. \#### Create plugins - \[Create a Claude Code plugin\](../08-Plugins-Skills/plugins-create.md): Build your first Claude Code plugin from an empty directory, test it without a marketplace, and convert an existing .claude/ setup. - \[Add components to a plugin\](../08-Plugins-Skills/plugins-components.md): Add skills, hooks, MCP servers, and every other component type to a Claude Code plugin, with an example that validates for each. - \[Plugin dependencies\](../08-Plugins-Skills/plugins-dependencies.md): Declare the plugins your plugin depends on, with version ranges such as ^1.2, and see how Claude Code installs, resolves, and prunes them. - \[Test plugins with evals\](../08-Plugins-Skills/plugin-evals.md): Write eval cases for your Claude Code plugin, run them with claude plugin eval, grade the results, compare against a no-plugin baseline, and gate CI on the score. - \[Publish and distribute a plugin\](../08-Plugins-Skills/plugins-publish.md): Publish a Claude Code plugin through your own marketplace or Anthropic's directory, with a pre-release checklist and how users get updates. - \[Measure plugin cost and usage\](../08-Plugins-Skills/plugins-measure.md): Measure a Claude Code plugin's token cost, find out whether people still use it, and pick the telemetry events for organization-wide plugin questions. - \[Recommend your plugin from your CLI\](../08-Plugins-Skills/plugins-cli-hints.md): Prompt Claude Code users to install your official-marketplace plugin by emitting a claude-code-hint tag from your CLI or SDK. \#### Mods - \[Mods overview\](../08-Plugins-Skills/plugins-mods-overview.md): Add panes, commands, and tool call rules to Claude Code with a mod. See what a mod can do, how to make or install one, and where mods run. - \[Create a mod\](../08-Plugins-Skills/plugins-mods-create.md): Have Claude write a Claude Code mod from a description, or write one yourself that counts tool calls and adds a command. Learn the reload and validate loop. - \[Mods reference\](../08-Plugins-Skills/plugins-mods-reference.md): Complete reference for Claude Code mods: hooks module layout, events, mods API methods, render sites, elements by surface, limits, and settings. \##### Build - \[Draw in the interface with a mod\](../08-Plugins-Skills/plugins-mods-interface.md): Draw panes, a band above the prompt, buttons, and text fields from a Claude Code mod, handle presses and input, and keep state between redraws and sessions. - \[Interface gallery for mods\](../08-Plugins-Skills/plugins-mods-gallery.md): See the interface elements a Claude Code mod can draw, such as text, buttons, fields, Markdown, code, and diffs, with sample code and terminal screenshots. - \[React to events with a mod\](../08-Plugins-Skills/plugins-mods-events.md): Handle Claude Code events from a mod: observe, rewrite, or answer tool calls, prompts, and turns, filter which events a hook handles, and plan for other mods. - \[Use the mods API\](../08-Plugins-Skills/plugins-mods-api.md): Call the mods API from a Claude Code mod to add commands and tools, call a model, run work on a timer, message other sessions, and reach files and the network. \##### Test and troubleshoot - \[Test a mod\](../08-Plugins-Skills/plugins-mods-test.md): Write automated tests for a Claude Code mod that fire events, stub Claude Code's answers, and press buttons, with no session, sign-in, or network. - \[Troubleshoot a mod\](../08-Plugins-Skills/plugins-mods-troubleshoot.md): Find out why a Claude Code mod does nothing: match the symptom or message to its cause, look up refusal messages, and read the debug log. \#### Run a marketplace - \[Create a marketplace\](../08-Plugins-Skills/plugin-marketplaces.md): Build a plugin marketplace from a marketplace.json file and test it locally before you host it. - \[Host and maintain a marketplace\](../08-Plugins-Skills/plugins-host-marketplace.md): Publish a plugin marketplace where users can reach it, grant access to a private one, and release updates and renames without breaking installs. - \[Recommend plugins for your org\](../08-Plugins-Skills/plugins-relevance.md): Add a relevance block to marketplace plugin entries so Claude Code suggests them when a user's work matches, and allowlist the marketplace in managed settings. \#### Manage plugins for your organization - \[Manage Claude Code plugins for your organization\](../08-Plugins-Skills/plugins-org.md): Control which plugins Claude Code installs and allows across your organization through managed settings. - \[Manage mods for your organization\](../08-Plugins-Skills/plugins-mods-admin.md): Control Claude Code mods with managed settings: stop user-installed mods, allow only your own, review what a mod can do, and enforce policy with your own mod. \#### Troubleshooting - \[Troubleshoot plugins\](../08-Plugins-Skills/plugins-troubleshooting.md): Fix plugin errors in Claude Code. Find the exact message you saw, grouped by stage from where /plugin runs through install and org policy. - \[Plugin loading reference\](../08-Plugins-Skills/plugins-loading.md): Trace where Claude Code loads each plugin from, which settings file decides whether it loads, and why an update changed nothing. \#### Reference - \[Plugin manifest reference\](../08-Plugins-Skills/plugins-reference.md): Complete reference for plugin.json: every field with its type and default, accepted path forms, and the userConfig and environment variable schemas. - \[Marketplace reference\](../08-Plugins-Skills/plugins-marketplace-reference.md): Complete reference for marketplace.json fields, plugin entries, and the plugin and marketplace source objects, with where each is valid. - \[Plugin commands reference\](../08-Plugins-Skills/plugins-cli-reference.md): Reference for the claude plugin shell commands, /plugin and /reload-plugins in a session, and the flags that load a plugin for one session. \### Use plugins - \[Install and manage plugins\](../08-Plugins-Skills/discover-plugins.md): Install Claude Code plugins from a marketplace on any surface you use, choose an install scope, and update or remove them later. \### Create plugins - \[Create a Claude Code plugin\](../08-Plugins-Skills/plugins-create.md): Build your first Claude Code plugin from an empty directory, test it without a marketplace, and convert an existing .claude/ setup. \### Mods - \[Mods overview\](../08-Plugins-Skills/plugins-mods-overview.md): Add panes, commands, and tool call rules to Claude Code with a mod. See what a mod can do, how to make or install one, and where mods run. \### Run a marketplace - \[Create a marketplace\](../08-Plugins-Skills/plugin-marketplaces.md): Build a plugin marketplace from a marketplace.json file and test it locally before you host it. \### Manage plugins for your organization - \[Manage Claude Code plugins for your organization\](../08-Plugins-Skills/plugins-org.md): Control which plugins Claude Code installs and allows across your organization through managed settings. \### Troubleshooting - \[Troubleshoot plugins\](../08-Plugins-Skills/plugins-troubleshooting.md): Fix plugin errors in Claude Code. Find the exact message you saw, grouped by stage from where /plugin runs through install and org policy. \### Reference - \[Plugin manifest reference\](../08-Plugins-Skills/plugins-reference.md): Complete reference for plugin.json: every field with its type and default, accepted path forms, and the userConfig and environment variable schemas. \## Administration \### Setup and access \#### Setup and access - \[Set up Claude Code for your organization\](../13-Enterprise-Admin/admin-setup.md): A decision map for administrators deploying Claude Code, covering API providers, managed settings, policy enforcement, usage monitoring, and data handling. - \[Advanced setup\](../01-Getting-Started/setup.md): System requirements, platform-specific installation, version management, and uninstallation for Claude Code. - \[Authentication\](authentication.md): Log in to Claude Code and configure authentication for individuals, teams, and organizations. - \[Deploy managed settings\](../13-Enterprise-Admin/managed-settings.md): Deploy managed settings to every developer's machine: delivery mechanisms per OS, how Claude Code combines managed sources, and how to verify enforcement. - \[Configure server-managed settings\](../13-Enterprise-Admin/server-managed-settings.md): Centrally configure Claude Code for your organization through server-delivered settings, without requiring device management infrastructure. - \[Control MCP server access for your organization\](../06-MCP-Tools/General/managed-mcp.md): Restrict which MCP servers users can add or connect to, or provide servers to every user, with managed configuration files, managed settings, allowlists, and denylists. - \[Configure auto mode\](auto-mode-config.md): Tell the auto mode classifier which repos, buckets, and domains your organization trusts. Set environment context, override the default block and allow rules, and inspect your effective config with the auto-mode CLI subcommands. \#### Deployment - \[Enterprise deployment overview\](third-party-integrations.md): Learn how Claude Code can integrate with various third-party services and infrastructure to meet enterprise deployment requirements. - \[Feature availability\](feature-availability.md): Compare which Claude Code features are available across Anthropic subscription plans, the Anthropic Console, Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform, and Microsoft Foundry. - \[Claude Code on Amazon Bedrock\](amazon-bedrock.md): Learn about configuring Claude Code through Amazon Bedrock, including setup, IAM configuration, and troubleshooting. - \[Claude Code on Claude Platform on AWS\](claude-platform-on-aws.md): Configure Claude Code to use the Anthropic-operated Claude API with AWS authentication, IAM access control, and AWS Marketplace billing. - \[Claude Code on Google Cloud's Agent Platform\](google-vertex-ai.md): Learn about configuring Claude Code through Google Cloud's Agent Platform, formerly Vertex AI, including setup, IAM configuration, and troubleshooting. - \[Claude Code on Microsoft Foundry\](microsoft-foundry.md): Learn about configuring Claude Code through Microsoft Foundry, including setup, configuration, and troubleshooting. - \[Enterprise network configuration\](../13-Enterprise-Admin/network-config.md): Configure Claude Code for enterprise environments with proxy servers, custom Certificate Authorities (CA), and mutual Transport Layer Security (mTLS) authentication. - \[Run Claude Code behind a corporate launcher\](../13-Enterprise-Admin/corporate-launcher.md): Route the processes Claude Code starts from its own binary, including the background service and every agent view session, through a required launcher with CLAUDE_CODE_PROCESS_WRAPPER or the processWrapper setting. - \[Development containers\](devcontainer.md): Run Claude Code inside a dev container for consistent, isolated environments across your team. \#### Gateways - \[Run Claude Code through a gateway\](../13-Enterprise-Admin/gateways.md): Route Claude Code through a self-hosted gateway for centralized credentials, usage tracking, and cost controls. Covers the architecture, Anthropic's Claude apps gateway, and using other gateway products. \##### Claude apps gateway - \[Claude apps gateway for Amazon Bedrock, Claude Platform on AWS, Google Cloud, and Microsoft Foundry\](../13-Enterprise-Admin/claude-apps-gateway.md): Run Claude Code through Amazon Bedrock, Claude Platform on AWS, Google Cloud, or Microsoft Foundry behind a self-hosted gateway with SSO sign-in, per-group model access, and OTLP telemetry. - \[Claude apps gateway configuration\](../13-Enterprise-Admin/claude-apps-gateway-config.md): Reference for every gateway.yaml option: listener and TLS, OIDC, session, Postgres store, Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform, and Microsoft Foundry upstreams, model routing, managed policies, and telemetry. - \[Claude apps gateway spend limits\](../13-Enterprise-Admin/claude-apps-gateway-spend-limits.md): Cap each developer's spend through the Claude apps gateway by day, week, or month. Set limits with an Admin API and the gateway enforces them live on every request. - \[Claude apps gateway deployment and operations\](../13-Enterprise-Admin/claude-apps-gateway-deploy.md): Register the gateway with your IdP, build the container, deploy on Kubernetes or Cloud Run, and operate it: health checks, secret rotation, upgrades, and security. - \[Deploy Claude apps gateway on AWS\](../13-Enterprise-Admin/claude-apps-gateway-on-aws.md): A worked example of running Claude apps gateway on AWS: ECS Fargate or EKS, Amazon RDS for PostgreSQL, AWS Secrets Manager, and IAM-role auth to Amazon Bedrock. - \[Deploy Claude apps gateway on Google Cloud\](../13-Enterprise-Admin/claude-apps-gateway-on-gcp.md): A worked example of running Claude apps gateway on Google Cloud: Cloud Run or GKE, Cloud SQL for PostgreSQL, Secret Manager, and service-account auth to Google Cloud's Agent Platform. \##### Other gateways - \[Other LLM gateways\](../13-Enterprise-Admin/llm-gateway.md): Route Claude Code through an LLM gateway your organization already runs. Covers connecting Claude Code to a gateway, rolling one out for your organization, and what Claude Code sends to a gateway. - \[Connect Claude Code to an LLM gateway\](../13-Enterprise-Admin/llm-gateway-connect.md): Point Claude Code at your organization's LLM gateway. Check whether your admin already configured it, or set the base URL and credential yourself, then verify the connection and fix gateway errors. - \[Roll out an LLM gateway for your organization\](../13-Enterprise-Admin/llm-gateway-rollout.md): Deploy a gateway product for Claude Code: configure it to forward what Claude Code sends, issue developer credentials, distribute the configuration through managed settings, and verify the rollout. - \[Claude Code gateway compatibility guide\](../13-Enterprise-Admin/llm-gateway-protocol.md): Keep an LLM gateway compatible with Claude Code: the endpoints it calls, the headers and body fields to forward, and what breaks when they're stripped. \#### Usage and costs - \[Monitoring\](../13-Enterprise-Admin/monitoring-usage.md): Learn how to enable and configure OpenTelemetry for Claude Code. - \[Manage costs effectively\](../17-Billing-Plans/costs.md): Track token usage, set team spend limits, and reduce Claude Code costs with context management, model selection, extended thinking settings, and preprocessing hooks. - \[Track team usage with analytics\](../13-Enterprise-Admin/analytics.md): View Claude Code usage metrics, track adoption, and measure engineering velocity in the analytics dashboard. \#### Security and data - \[Security\](../13-Enterprise-Admin/security.md): Learn about Claude Code's security safeguards and best practices for safe usage. - \[Data usage\](../13-Enterprise-Admin/data-usage.md): Learn about Anthropic's data usage policies for Claude - \[Zero data retention\](zero-data-retention.md): Learn about Zero Data Retention (ZDR) for Claude Code, available to qualified accounts on Claude for Enterprise, including scope, disabled features, and how to request enablement. - \[Set up Claude Code (local mode) for a HIPAA-ready organization\](hipaa-setup.md): Prepare developers' computers to run Claude Code (local mode) under the HIPAA configuration. Covers versions, network access, managed settings, and local data. \#### Adoption - \[Communications kit\](../13-Enterprise-Admin/communications-kit.md): Launch announcements, drip-campaign messages, and FAQ responses for rolling Claude Code out to your engineering organization. - \[Champion kit\](../13-Enterprise-Admin/champion-kit.md): A playbook for engineers advocating Claude Code internally: what to share, how to answer questions, and how to grow adoption on your team. \### Deployment - \[Enterprise deployment overview\](third-party-integrations.md): Learn how Claude Code can integrate with various third-party services and infrastructure to meet enterprise deployment requirements. \### Gateways - \[Run Claude Code through a gateway\](../13-Enterprise-Admin/gateways.md): Route Claude Code through a self-hosted gateway for centralized credentials, usage tracking, and cost controls. Covers the architecture, Anthropic's Claude apps gateway, and using other gateway products. \### Usage and costs - \[Monitoring\](../13-Enterprise-Admin/monitoring-usage.md): Learn how to enable and configure OpenTelemetry for Claude Code. \### Security and data - \[Security\](../13-Enterprise-Admin/security.md): Learn about Claude Code's security safeguards and best practices for safe usage. \### Adoption - \[Communications kit\](../13-Enterprise-Admin/communications-kit.md): Launch announcements, drip-campaign messages, and FAQ responses for rolling Claude Code out to your engineering organization. \## Configuration \### Settings \#### Settings - \[Settings files and precedence\](settings.md): Change Claude Code settings, pick the scope a key belongs in, verify the change, and learn which value Claude Code uses when a key is set in several places. - \[All settings\](settings-reference.md): Complete reference for every Claude Code settings.json key: where each one goes, its type and default, and a paste-ready example, with an index of every key. - \[Example settings files\](settings-example.md): Realistic settings.json files for a developer, a team, and an organization: copy one, keep the keys you want, and change the values. \#### Permissions and sandboxing - \[Configure permissions\](permissions.md): Control what Claude Code can access and do with fine-grained permission rules, modes, and managed policies. - \[Choose a permission mode\](permission-modes.md): Control whether Claude asks before acting. Switch permission modes with Shift+Tab in the CLI, the mode indicator in VS Code, or the mode selector in Desktop. - \[Auto mode classifier request charges\](../17-Billing-Plans/auto-mode-classifier-billing.md): Resolve the Claude Code notice saying this session isn't eligible for auto mode's no-charge classifier requests: what it means, why it appears, and what to do. - \[Configure the sandboxed Bash tool\](sandboxing.md): Restrict the files and network hosts Claude Code's shell commands can reach with the built-in sandbox. Turn it on, set the boundary, and fix what it breaks. - \[Choose a sandbox environment\](sandbox-environments.md): Compare Claude Code sandbox options: the built-in sandboxed Bash tool, sandbox runtime, dev containers, Docker, and VMs. Choose the right isolation for your threat model. \#### Environments - \[Configure cloud environments\](cloud-environments.md): Configure cloud environments for Claude Code cloud sessions: network access levels, environment variables, setup scripts, and environment caching. \##### Self-hosted environments - \[Self-hosted environments\](../13-Enterprise-Admin/self-hosted-environments.md): Run Claude Code cloud sessions on infrastructure you control: set up a self-hosted environment, deploy runners, and route sessions to your own compute. - \[Self-hosted environments quickstart\](../13-Enterprise-Admin/self-hosted-environments-quickstart.md): Set up your first self-hosted environment: install Claude Code, create the environment, start a runner, and route a session to it. - \[Deploy self-hosted environments to production\](../13-Enterprise-Admin/self-hosted-environments-deploy.md): Run self-hosted runners in production: security hardening, network egress control, git credentials, Kubernetes and Compose recipes, and troubleshooting. - \[Customize sessions in self-hosted environments\](../13-Enterprise-Admin/self-hosted-environments-configuration.md): Customize self-hosted environment sessions with wrapper scripts for per-session credentials, lifecycle hooks, and on-demand runner spawning. - \[Test self-hosted environments end to end\](../13-Enterprise-Admin/self-hosted-environments-testing.md): Verify a self-hosted runner image from CI: dispatch a session with the CLI, read Claude's replies through a Stop hook, and script the full loop. - \[Self-hosted environments reference\](../13-Enterprise-Admin/self-hosted-environments-reference.md): Complete reference for the self-hosted runner and orchestrator: CLI flags, environment variables, and Prometheus metrics. - \[Verify session identity in self-hosted environments\](../13-Enterprise-Admin/self-hosted-environments-identity.md): Verify the CLAUDE_CODE_SESSION_ACCESS_TOKEN JWT so services on your network can trust requests from sessions in your self-hosted environment. \#### Model and responses - \[Model configuration\](model-config.md): Configure which model Claude Code uses, effort levels, extended context, and the auto-compact window - \[Speed up responses with fast mode\](fast-mode.md): Get faster Opus responses in Claude Code by toggling fast mode. - \[Escalate hard decisions with the advisor tool\](advisor.md): Pair your main model with a stronger advisor model that Claude consults at key moments during a task. - \[Output styles\](output-styles.md): Change Claude Code's role, tone, and response format with a built-in output style such as Concise or Explanatory, or write a custom style. \#### Interface - \[Configure your terminal for Claude Code\](terminal-config.md): Fix Shift+Enter for newlines, get a terminal bell when Claude finishes, configure tmux, match the color theme, and enable Vim mode in the Claude Code CLI. - \[Fullscreen rendering\](fullscreen.md): Enable a smoother, flicker-free rendering mode with mouse support and stable memory usage in long conversations. - \[Use Claude Code with a screen reader\](accessibility.md): Set up Claude Code for screen readers such as VoiceOver and NVDA, plus settings for screen magnifiers, reduced motion, and colorblind-friendly themes. - \[Voice dictation\](voice-dictation.md): Speak your prompts in the Claude Code CLI with hold-to-record or tap-to-record voice dictation. - \[Customize your status line\](statusline.md): Configure a custom status bar to monitor context window usage, costs, and git status in Claude Code - \[Customize keyboard shortcuts\](keybindings.md): Customize keyboard shortcuts in Claude Code with a keybindings configuration file. \### Permissions and sandboxing - \[Configure permissions\](permissions.md): Control what Claude Code can access and do with fine-grained permission rules, modes, and managed policies. \### Environments - \[Configure cloud environments\](cloud-environments.md): Configure cloud environments for Claude Code cloud sessions: network access levels, environment variables, setup scripts, and environment caching. \### Model and responses - \[Model configuration\](model-config.md): Configure which model Claude Code uses, effort levels, extended context, and the auto-compact window \### Interface - \[Configure your terminal for Claude Code\](terminal-config.md): Fix Shift+Enter for newlines, get a terminal bell when Claude finishes, configure tmux, match the color theme, and enable Vim mode in the Claude Code CLI. \## Reference \### Reference \#### Reference - \[CLI reference\](cli-reference.md): Complete reference for Claude Code command-line interface, including commands and flags. - \[Commands\](commands.md): Complete reference for commands available in Claude Code, including built-in commands and bundled skills. - \[Environment variables\](env-vars.md): Reference for environment variables that control Claude Code behavior. - \[Tools reference\](tools-reference.md): Complete reference for the tools Claude Code can use, including permission requirements and per-tool behavior. - \[Interactive mode\](interactive-mode.md): Complete reference for keyboard shortcuts, input modes, and interactive features in Claude Code sessions. - \[Checkpointing\](checkpointing.md): Track, rewind, and summarize Claude's edits and conversation to manage session state. - \[Hooks reference\](../07-Hooks/hooks.md): Reference for Claude Code hook events, configuration schema, JSON input/output formats, exit codes, async hooks, HTTP hooks, prompt hooks, and MCP tool hooks. - \[Channels reference\](channels-reference.md): Build an MCP server that pushes webhooks, alerts, and chat messages into a Claude Code session. Reference for the channel contract: capability declaration, notification events, reply tools, sender gating, and permission relay. \#### Glossary - \[Glossary\](glossary.md): Definitions for Claude Code terminology. Learn what agentic loop, compaction, CLAUDE.md, hooks, subagents, MCP, and other core concepts mean. \### Glossary - \[Glossary\](glossary.md): Definitions for Claude Code terminology. Learn what agentic loop, compaction, CLAUDE.md, hooks, subagents, MCP, and other core concepts mean. \## Agent SDK \### Agent SDK \#### Agent SDK - \[Agent SDK overview\](../05-Agent-SDK/agent-sdk-overview.md): Build production AI agents with Claude Code as a library - \[Quickstart\](../05-Agent-SDK/agent-sdk-quickstart.md): Get started with the Python or TypeScript Agent SDK to build AI agents that work autonomously - \[Migrate to Claude Agent SDK\](../05-Agent-SDK/agent-sdk-migration-guide.md): Guide for migrating the Claude Code TypeScript and Python SDKs to the Claude Agent SDK - \[Troubleshoot the Agent SDK\](../05-Agent-SDK/agent-sdk-troubleshooting.md): Fix Agent SDK errors when the Claude Code CLI fails to start, the CLI process exits, or a successful result arrives without structured output. \#### Build agents - \[Configure your agent\](../05-Agent-SDK/agent-sdk-configuration.md): Configure Agent SDK sessions: compose the options object, set the model, environment, and limits, and find each feature option's page. - \[Examples\](../05-Agent-SDK/agent-sdk-examples.md): Find a complete, runnable Agent SDK project or a guided recipe in the Claude Cookbook that matches what you want to build. \#### Core concepts - \[How the agent loop works\](../05-Agent-SDK/agent-sdk-agent-loop.md): Understand the message lifecycle, tool execution, context window, and architecture that power your SDK agents. - \[Use Claude Code features in the SDK\](../05-Agent-SDK/agent-sdk-claude-code-features.md): Load project instructions, skills, hooks, and other Claude Code features into your SDK agents. - \[Work with sessions\](../05-Agent-SDK/agent-sdk-sessions.md): How sessions persist agent conversation history, and when to use continue, resume, and fork to return to a prior run. - \[Persist sessions to external storage\](../05-Agent-SDK/agent-sdk-session-storage.md): Mirror Agent SDK session transcripts to your own object store, key-value store, or database so other hosts can resume your sessions. \#### Input and output - \[Streaming Input\](../05-Agent-SDK/agent-sdk-streaming-vs-single-mode.md): Understanding the two input modes for Claude Agent SDK and when to use each - \[Handle approvals and user input\](../05-Agent-SDK/agent-sdk-user-input.md): Surface Claude's approval requests and clarifying questions to users, then return their decisions to the SDK. - \[Stream responses in real-time\](../05-Agent-SDK/agent-sdk-streaming-output.md): Get real-time responses from the Agent SDK as text and tool calls stream in - \[Get structured output from agents\](../05-Agent-SDK/agent-sdk-structured-outputs.md): Return validated JSON from agent workflows using JSON Schema, Zod, or Pydantic. Get type-safe, structured data after multi-turn tool use. \#### Extend with tools - \[Give Claude custom tools\](../05-Agent-SDK/agent-sdk-custom-tools.md): Define custom tools with the Claude Agent SDK's in-process MCP server so Claude can call your functions, hit your APIs, and perform domain-specific operations. - \[Connect to external tools with MCP\](../05-Agent-SDK/agent-sdk-mcp.md): Configure MCP servers to extend your agent with external tools. Covers transport types, tool search for large tool sets, authentication, and error handling. - \[Scale to many tools with tool search\](../05-Agent-SDK/agent-sdk-tool-search.md): Scale your agent to thousands of tools by discovering and loading only what's needed, on demand. - \[Subagents in the SDK\](../05-Agent-SDK/agent-sdk-subagents.md): Define and invoke subagents to isolate context, run tasks in parallel, and apply specialized instructions in your Claude Agent SDK applications. \#### Customize behavior - \[Modifying system prompts\](../05-Agent-SDK/agent-sdk-modifying-system-prompts.md): Choose between the \`claude_code\` preset and a custom system prompt, and customize behavior with CLAUDE.md, output styles, append, or a fully custom prompt. - \[Extend agents with skills\](../05-Agent-SDK/agent-sdk-skills.md): Control which skills Claude can invoke in Claude Agent SDK sessions, dispatch commands by name, and author skills your sessions discover - \[Plugins in the SDK\](../05-Agent-SDK/agent-sdk-plugins.md): Load custom plugins to extend Claude Code with skills, agents, hooks, and MCP servers through the Agent SDK \#### Control and observability - \[Configure permissions\](../05-Agent-SDK/agent-sdk-permissions.md): Control how your agent uses tools with permission modes, hooks, and declarative allow/deny rules. - \[Intercept and control agent behavior with hooks\](../05-Agent-SDK/agent-sdk-hooks.md): Intercept and customize agent behavior at key execution points with hooks - \[Rewind file changes with checkpointing\](../05-Agent-SDK/agent-sdk-file-checkpointing.md): Track file changes during agent sessions and restore files to any previous state - \[Track cost and usage\](../05-Agent-SDK/agent-sdk-cost-tracking.md): Learn how to track token usage, estimate costs, and configure prompt caching with the Claude Agent SDK. - \[Observability with OpenTelemetry\](../05-Agent-SDK/agent-sdk-observability.md): Export traces, metrics, and events from the Agent SDK to your observability backend using OpenTelemetry. - \[Track todos\](../05-Agent-SDK/agent-sdk-todo-tracking.md): Track todos in Agent SDK sessions and render Claude's progress in your application from structured tool calls \#### Deployment - \[Hosting the Agent SDK\](../05-Agent-SDK/agent-sdk-hosting.md): Deploy the Agent SDK in production: subprocess architecture, session persistence, scaling, observability, and multi-tenant isolation for Docker, Kubernetes, and sandbox providers. - \[Securely deploying AI agents\](../05-Agent-SDK/agent-sdk-secure-deployment.md): A guide to securing Claude Code and Agent SDK deployments with isolation, credential management, and network controls \#### SDK references - \[Agent SDK reference - TypeScript\](../05-Agent-SDK/agent-sdk-typescript.md): Complete API reference for the TypeScript Agent SDK, including all functions, types, and interfaces. - \[TypeScript SDK V2 session API (removed)\](../05-Agent-SDK/agent-sdk-typescript-v2-preview.md): Reference for the removed V2 TypeScript Agent SDK session API, with session-based send/stream patterns for multi-turn conversations. - \[Agent SDK reference - Python\](../05-Agent-SDK/agent-sdk-python.md): Complete API reference for the Python Agent SDK, including all functions, types, and classes. \### Build agents - \[Configure your agent\](../05-Agent-SDK/agent-sdk-configuration.md): Configure Agent SDK sessions: compose the options object, set the model, environment, and limits, and find each feature option's page. \### Core concepts - \[How the agent loop works\](../05-Agent-SDK/agent-sdk-agent-loop.md): Understand the message lifecycle, tool execution, context window, and architecture that power your SDK agents. \### Input and output - \[Streaming Input\](../05-Agent-SDK/agent-sdk-streaming-vs-single-mode.md): Understanding the two input modes for Claude Agent SDK and when to use each \### Extend with tools - \[Give Claude custom tools\](../05-Agent-SDK/agent-sdk-custom-tools.md): Define custom tools with the Claude Agent SDK's in-process MCP server so Claude can call your functions, hit your APIs, and perform domain-specific operations. \### Customize behavior - \[Modifying system prompts\](../05-Agent-SDK/agent-sdk-modifying-system-prompts.md): Choose between the \`claude_code\` preset and a custom system prompt, and customize behavior with CLAUDE.md, output styles, append, or a fully custom prompt. \### Control and observability - \[Configure permissions\](../05-Agent-SDK/agent-sdk-permissions.md): Control how your agent uses tools with permission modes, hooks, and declarative allow/deny rules. \### Deployment - \[Hosting the Agent SDK\](../05-Agent-SDK/agent-sdk-hosting.md): Deploy the Agent SDK in production: subprocess architecture, session persistence, scaling, observability, and multi-tenant isolation for Docker, Kubernetes, and sandbox providers. \### SDK references - \[Agent SDK reference - TypeScript\](../05-Agent-SDK/agent-sdk-typescript.md): Complete API reference for the TypeScript Agent SDK, including all functions, types, and interfaces. \## What's New \### What's New - \[What's new\](whats-new-index.md): A weekly digest of notable Claude Code features, with code snippets, demos, and context on why they matter. - \[Week 37 · September 7–11, 2026\](whats-new-2026-w37.md): Test your plugins with claude plugin eval and pop Claude Code Desktop panes out into their own windows. - \[Week 36 · August 31 – September 4, 2026\](whats-new-2026-w36.md): Switch to Claude Fable 5.1, let computer use run in the background on Desktop, and watch Claude's edits in a live /diff panel. - \[Week 35 · August 24–28, 2026\](whats-new-2026-w35.md): Resume terminal sessions in the Claude Code Desktop app, review feedback reports that Claude drafts for you, and start a session in restricted mode. - \[Week 34 · August 17–21, 2026\](whats-new-2026-w34.md): Draft editable UI artboards with the /design skill, set the Concise output style, and start a Claude Code session on your machine from your phone. - \[Week 33 · August 10–14, 2026\](whats-new-2026-w33.md): Claude Code Desktop auto-continues after a usage limit resets, fork mode turns on by default, and GitLab merge requests and marketplaces join GitHub. - \[Week 32 · August 3–7, 2026\](whats-new-2026-w32.md): Claude Code sessions message each other, self-hosted environments run cloud sessions on your infrastructure, and auto mode becomes the default permission mode. - \[Week 30 · July 20–24, 2026\](whats-new-2026-w30.md): Opus 5 becomes the default Opus model, Claude Code Desktop adds an iOS Simulator pane, and the Claude Security plugin scans your code for vulnerabilities. - \[Week 29 · July 13–17, 2026\](whats-new-2026-w29.md): Pull live data into published artifacts through MCP connectors, and use Claude Code with a screen reader in the new screen reader mode. - \[Week 28 · July 6–10, 2026\](whats-new-2026-w28.md): Browse external sites from the Desktop app's built-in browser, run a full setup checkup with /doctor, and pick up auto mode transcript protections and agent view upgrades. - \[Week 27 · June 29 – July 3, 2026\](whats-new-2026-w27.md): Claude Sonnet 5 becomes the default model, Claude in Chrome reaches general availability, subagents run in the background by default, Claude Desktop arrives on Linux in beta, and /radio tunes into Claude FM. - \[Week 26 · June 22–26, 2026\](whats-new-2026-w26.md): Authenticate MCP servers from your shell with claude mcp login, get a response to shell mode command output with the ! prefix, and resume a conversation from before /clear with /rewind. - \[Week 25 · June 15–19, 2026\](whats-new-2026-w25.md): Publish a live, shareable page from your session with Artifacts, match tool parameters in deny and ask rules, and set any setting from the prompt with /config. - \[Week 24 · June 8–12, 2026\](whats-new-2026-w24.md): Move a session to a new directory with /cd, let subagents spawn their own subagents, and troubleshoot a broken configuration with safe mode. - \[Week 23 · June 1–5, 2026\](whats-new-2026-w23.md): Run auto mode on Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry, prompt before writing files that can run code in acceptEdits mode, list installed plugins with /plugin list, and require an approved version range for managed deployments. - \[Week 22 · May 25–29, 2026\](whats-new-2026-w22.md): Run Claude Code on Claude Opus 4.8, orchestrate large tasks with dynamic workflows, catch security issues with the security-guidance plugin, and use fast mode on Opus 4.8 at a lower price. - \[Week 21 · May 18–22, 2026\](whats-new-2026-w21.md): Use auto mode on the Pro plan and with Sonnet 4.6, see which skills, subagents, and MCP servers drive your plan limits in /usage, and review diffs with the new /code-review command. - \[Week 20 · May 11–15, 2026\](whats-new-2026-w20.md): Manage every Claude Code session from one screen with agent view, keep Claude working toward a goal until a condition holds, and run fast mode on Opus 4.7 by default. - \[Week 19 · May 4–8, 2026\](whats-new-2026-w19.md): Load plugins from .zip archives and URLs, search command history across every project with Ctrl+R, branch new worktrees from local HEAD or the remote default, and block actions unconditionally with auto mode hard deny rules. - \[Week 18 · April 27 – May 1, 2026\](whats-new-2026-w18.md): Claude Code on Windows runs without Git Bash, claude auth login accepts a pasted OAuth code when the browser callback can't reach localhost, claude project purge cleans up local state per project, and pasting a PR URL into /resume finds the session that created it. - \[Week 17 · April 20–24, 2026\](whats-new-2026-w17.md): /ultrareview opens as a research preview, automatic session recaps when you return to a terminal, custom color themes you can build and ship in plugins, and a redesigned Claude Code on the web. - \[Week 16 · April 13–17, 2026\](whats-new-2026-w16.md): Claude Opus 4.7 with the new xhigh effort level, Routines on Claude Code on the web, mobile push notifications that ping your phone when Claude needs you, a /usage breakdown that shows what's driving your limits, and native binaries replacing the bundled JavaScript. - \[Week 15 · April 6–10, 2026\](whats-new-2026-w15.md): Ultraplan cloud planning, the Monitor tool with self-pacing /loop, /team-onboarding for packaging your setup, and /autofix-pr from your terminal. - \[Week 14 · March 30 – April 3, 2026\](whats-new-2026-w14.md): Computer use in the CLI, interactive in-product lessons, flicker-free rendering, per-tool MCP result-size overrides, and plugin executables on PATH. - \[Week 13 · March 23–27, 2026\](whats-new-2026-w13.md): Auto mode for hands-off permissions, computer use built in, PR auto-fix in the cloud, transcript search, and a PowerShell tool for Windows. \## Resources \### Resources - \[Legal and compliance\](../13-Enterprise-Admin/legal-and-compliance.md): Legal agreements, compliance certifications, and security information for Claude Code. \> The links below point to documentation indexes. Follow each \`/\_llms/\` index recursively until you reach documentation pages. \## Indexes - \[French (228 pages)\](https://code.claude.com/docs/\_llms/fr.txt): Documentation for French. - \[German (228 pages)\](https://code.claude.com/docs/\_llms/de.txt): Documentation for German. - \[Italian (228 pages)\](https://code.claude.com/docs/\_llms/it.txt): Documentation for Italian. - \[Japanese (228 pages)\](https://code.claude.com/docs/\_llms/jp.txt): Documentation for Japanese. - \[Spanish (228 pages)\](https://code.claude.com/docs/\_llms/es.txt): Documentation for Spanish. - \[Korean (228 pages)\](https://code.claude.com/docs/\_llms/ko.txt): Documentation for Korean. - \[Simplified Chinese (228 pages)\](https://code.claude.com/docs/\_llms/zh-cn.txt): Documentation for Simplified Chinese. - \[Traditional Chinese (228 pages)\](https://code.claude.com/docs/\_llms/zh-tw.txt): Documentation for Traditional Chinese. - \[Russian (228 pages)\](https://code.claude.com/docs/\_llms/ru.txt): Documentation for Russian. - \[Indonesian (228 pages)\](https://code.claude.com/docs/\_llms/id.txt): Documentation for Indonesian. - \[Brazilian Portuguese (228 pages)\](https://code.claude.com/docs/\_llms/pt-br.txt): Documentation for Brazilian Portuguese.

---

## Manage API key environment variables in Claude Code | Claude Help Center

Source: https://support.claude.com/en/articles/12304248-managing-api-key-environment-variables-in-claude-code
Path: 02-Claude-Code-CLI/managing-api-key-environment-variables-in-claude-code.md

# Manage API key environment variables in Claude Code

May 5, 2026


When using Claude Code, it's important to understand how authentication methods are prioritized to avoid unexpected API charges and ensure you're using your intended account.

## How authentication works

- Claude Code prioritizes environment variable API keys over authenticated subscriptions.

- This is intentional behavior designed to give you flexibility in choosing your authentication method.

- When an API key is set as an environment variable, you'll be charged via API pay-as-you-go rates using the API account associated with that key.

- This happens even if you're logged into Claude Code with a claude.ai subscription or a different Console account.

## Best practices

**To use Claude Code with your Claude subscription:** Keep the ANTHROPIC_API_KEY environment variable unset.

- This prevents unexpected API charges and ensures you're using your subscription's included usage.

- If you need to use a specific API key occasionally, set it temporarily only when needed.

- Run /status in Claude Code periodically to verify your current authentication method.

## Authentication conflict warnings

Claude Code will notify you when there's a conflict between your authenticated subscription and an environment variable API key:

1.  During initial setup, if an API key is detected in your environment variables, Claude Code will ask you to confirm which authentication method you want to use.

2.  After successful login, you'll see a notification if both credentials are active, alerting you to the potential for unexpected API charges.

## Check your current configuration

To verify if an API key is set as an environment variable, run /status in Claude Code. This will show you which authentication method is currently active.

To check your environment variable directly, run one of these commands in a terminal (outside of Claude Code):

macOS/Linux:

    echo $ANTHROPIC_API_KEY

Windows CMD:

    echo %ANTHROPIC_API_KEY%

Windows PowerShell:

    echo $env:ANTHROPIC_API_KEY

## Set an API key temporarily

If you need to use an API key for the current terminal session only:

macOS/Linux:

    export ANTHROPIC_API_KEY='your-api-key-here'

Windows CMD:

    set ANTHROPIC_API_KEY=your-api-key-here

Windows PowerShell:

    $env:ANTHROPIC_API_KEY="your-api-key-here"

## Set an API key environment variable permanently

macOS/Linux:

    For zsh (default on macOS):
    bash
    # Add to shell config file
    echo 'export ANTHROPIC_API_KEY="your-api-key-here"' >> ~/.zshrc

    # Apply changes
    source ~/.zshrc
    For bash:
    bash
    # Add to shell config file
    echo 'export ANTHROPIC_API_KEY="your-api-key-here"' >> ~/.bash_profile

    # Apply changes
    source ~/.bash_profile

Windows:

1.  Open System Properties → Advanced → Environment Variables

2.  Under "User variables", click "New"

3.  Variable name: ANTHROPIC_API_KEY

4.  Variable value: your-api-key-here

5.  Click OK and restart your terminal

## Remove an API key environment variable

macOS/Linux (temporary):

    unset ANTHROPIC_API_KEY

macOS (permanent):

    # Remove from config file
    sed -i '' '/ANTHROPIC_API_KEY/d' ~/.zshrc
    source ~/.zshrc

Linux (permanent)

    sed -i '/ANTHROPIC_API_KEY/d' ~/.zshrc

Windows CMD:

    set ANTHROPIC_API_KEY=

Windows PowerShell:

    Remove-Item Env:ANTHROPIC_API_KEY

Windows (permanent): Delete the variable from System Environment Variables settings.

## Common issues to avoid

- Setting environment variables in shell configuration files and forgetting about them.

- Not restarting your terminal after changing environment variables.

- Assuming you're using your subscription when an API key is configured in your environment.

If you have any questions, please **[contact our Support team](../15-Claude-AI-Features/how-to-get-support.md)**.

---

## How Claude remembers your project - Claude Code Docs

Source: https://code.claude.com/docs/en/memory
Path: 02-Claude-Code-CLI/memory.md

## On this page

- [CLAUDE.md vs auto memory](#claude-md-vs-auto-memory)
- [CLAUDE.md files](#claude-md-files)
  - [When to add to CLAUDE.md](#when-to-add-to-claude-md)
  - [Choose where to put CLAUDE.md files](#choose-where-to-put-claude-md-files)
  - [Set up a project CLAUDE.md](#set-up-a-project-claude-md)
  - [Write effective instructions](#write-effective-instructions)
  - [Audit your instruction files](#audit-your-instruction-files)
  - [Import additional files](#import-additional-files)
  - [How CLAUDE.md files load](#how-claude-md-files-load)
  - [Load from additional directories](#load-from-additional-directories)
  - [Organize rules with .claude/rules/](#organize-rules-with-claude%2Frules%2F)
  - [Set up rules](#set-up-rules)
  - [Path-specific rules](#path-specific-rules)
  - [Rule frontmatter reference](#rules-frontmatter-reference)
  - [Share rules across projects with symlinks](#share-rules-across-projects-with-symlinks)
  - [User-level rules](#user-level-rules)
  - [Manage CLAUDE.md for large teams](#manage-claude-md-for-large-teams)
  - [Deploy organization-wide CLAUDE.md](#deploy-organization-wide-claude-md)
  - [Exclude specific CLAUDE.md files](#exclude-specific-claude-md-files)
- [AGENTS.md](#agents-md)
  - [When Claude Code reads AGENTS.md](#when-claude-code-reads-agents-md)
  - [Choose which instruction files load](#choose-which-instruction-files-load)
  - [When AGENTS.md support is unavailable](#when-agents-md-support-is-unavailable)
  - [Where AGENTS.md differs from CLAUDE.md](#where-agents-md-differs-from-claude-md)
  - [Remove an earlier AGENTS.md workaround](#remove-an-earlier-agents-md-workaround)
  - [Share one file with other coding tools](#share-one-file-with-other-coding-tools)
  - [Migrate instructions from other tools](#migrate-instructions-from-other-tools)
- [Auto memory](#auto-memory)
  - [Enable or disable auto memory](#enable-or-disable-auto-memory)
  - [Storage location](#storage-location)
  - [How it works](#how-it-works)
  - [Audit and edit your memory](#audit-and-edit-your-memory)
- [View and edit with /memory](#view-and-edit-with-%2Fmemory)
- [Troubleshoot memory issues](#troubleshoot-memory-issues)
  - [Claude isn’t following my CLAUDE.md](#claude-isn%E2%80%99t-following-my-claude-md)
  - [My AGENTS.md isn’t loading](#my-agents-md-isn%E2%80%99t-loading)
  - [I don’t know what auto memory saved](#i-don%E2%80%99t-know-what-auto-memory-saved)
  - [My CLAUDE.md is too large](#my-claude-md-is-too-large)
  - [Claude ignores the end of my subdirectory CLAUDE.md](#claude-ignores-the-end-of-my-subdirectory-claude-md)
  - [Instructions seem lost after /compact](#instructions-seem-lost-after-%2Fcompact)
- [Related resources](#related-resources)

Use Claude Code

# How Claude remembers your project

Copy pageCopy page

Give Claude persistent instructions with CLAUDE.md or AGENTS.md files, and let Claude accumulate learnings automatically with auto memory.

Copy pageCopy page

Each Claude Code session begins with a fresh context window. Two mechanisms carry knowledge across sessions:

- **CLAUDE.md files**: instructions you write to give Claude persistent context. Claude can also read a repository’s [`AGENTS.md` files](#agents-md) in place of CLAUDE.md
- **Auto memory**: notes Claude writes itself based on your corrections and preferences

This page covers how to:

- [Write and organize CLAUDE.md files](#claude-md-files)
- [Use an existing AGENTS.md](#agents-md) as your project instructions
- [Scope rules to specific file types](#organize-rules-with-claude/rules/) with `.claude/rules/`
- [Configure auto memory](#auto-memory) so Claude takes notes automatically
- [Troubleshoot](#troubleshoot-memory-issues) when instructions aren’t being followed


[​](#claude-md-vs-auto-memory)

CLAUDE.md vs auto memory

Claude Code has two complementary memory systems. Both are loaded at the start of every conversation. Claude treats them as context, not enforced configuration. To block an action regardless of what Claude decides, use a [PreToolUse hook](../07-Hooks/hooks-guide.md) instead. The more specific and concise your instructions, the more consistently Claude follows them.

|                      | CLAUDE.md files                                   | Auto memory                                                                                      |
|:---------------------|:--------------------------------------------------|:-------------------------------------------------------------------------------------------------|
| **Who writes it**    | You                                               | Claude                                                                                           |
| **What it contains** | Instructions and rules                            | Learnings and patterns                                                                           |
| **Scope**            | Project, user, or org                             | Per repository, shared across worktrees                                                          |
| **Loaded into**      | Every session                                     | Every session (first 200 lines or 25KB)                                                          |
| **Use for**          | Coding standards, workflows, project architecture | Your preferences, corrections you give Claude, project context Claude can’t derive from the code |

Use CLAUDE.md files when you want to guide Claude’s behavior. Auto memory lets Claude learn from your corrections without manual effort. Subagents can also maintain their own auto memory. See [subagent configuration](../09-Agents-Patterns/sub-agents.md#enable-persistent-memory) for details.


[​](#claude-md-files)

CLAUDE.md files

CLAUDE.md files are markdown files that give Claude persistent instructions for a project, your personal workflow, or your entire organization. You write these files in plain text; Claude reads them at the start of every session. If your repository uses `AGENTS.md` instead, see [AGENTS.md](#agents-md).


[​](#when-to-add-to-claude-md)

When to add to CLAUDE.md

Treat CLAUDE.md as the place you write down what you’d otherwise re-explain. Add to it when:

- Claude makes the same mistake a second time
- A code review catches something Claude should have known about this codebase
- You type the same correction or clarification into chat that you typed last session
- A new teammate would need the same context to be productive

Keep it to facts Claude should hold in every session: build commands, conventions, project layout, “always do X” rules. If an entry is a multi-step procedure or only matters for one part of the codebase, move it to a [skill](../08-Plugins-Skills/skills.md) or a [path-scoped rule](#organize-rules-with-claude/rules/) instead. The [extension overview](features-overview.md#build-your-setup-over-time) covers when to use each mechanism.


[​](#choose-where-to-put-claude-md-files)

Choose where to put CLAUDE.md files

CLAUDE.md files can live in several locations, each with a different scope. The table below lists them in load order, from broadest scope to most specific, so a project instruction appears in context after a user instruction.

[TABLE]

CLAUDE.md and CLAUDE.local.md files in the directory hierarchy above the working directory are loaded at launch. Files in subdirectories load on demand. See [How CLAUDE.md files load](#how-claude-md-files-load) for when they load and the full resolution order. For large projects, you can break instructions into topic-specific files using [project rules](#organize-rules-with-claude/rules/). Rules let you scope instructions to specific file types or subdirectories.


[​](#set-up-a-project-claude-md)

Set up a project CLAUDE.md

A project CLAUDE.md can be stored in either `./CLAUDE.md` or `./.claude/CLAUDE.md`. Create this file and add instructions that apply to anyone working on the project: build and test commands, coding standards, architectural decisions, naming conventions, and common workflows. These instructions are shared with your team through version control, so focus on project-level standards rather than personal preferences. To confirm the file loaded, run `/context` in a session and check the list under **Memory files**.

Run `/init` to generate a starting CLAUDE.md automatically. Claude analyzes your codebase and creates a file with build commands, test instructions, and project conventions it discovers. If a CLAUDE.md already exists, `/init` suggests improvements rather than overwriting it. Refine from there with instructions Claude wouldn’t discover on its own.For an interactive multi-phase flow instead, set the `CLAUDE_CODE_NEW_INIT` environment variable to `1` before you run `/init`. Set it in your shell or in the `env` block of a settings file, as shown in [Set environment variables](env-vars.md#set-environment-variables). With it set, `/init` asks which artifacts to set up: CLAUDE.md files, skills, and hooks. It then explores your codebase with a subagent, fills in gaps via follow-up questions, and presents a reviewable proposal before writing any files. The variable only changes how `/init` runs, so you can leave it set.


[​](#write-effective-instructions)

Write effective instructions

Claude treats CLAUDE.md files as context, not enforced configuration, so how you write instructions affects how reliably Claude follows them. Write instructions that are concrete enough to verify:

- “Use 2-space indentation” instead of “Format code properly”
- “Run `npm test` before committing” instead of “Test your changes”
- “API handlers live in `src/api/handlers/`” instead of “Keep files organized”

Keep your files short, organized, and consistent:

- **Size**: target under 200 lines per CLAUDE.md file. Longer files consume more context and reduce adherence. Move instructions that matter for only part of the codebase into [path-scoped rules](#path-specific-rules), which load only when Claude works with matching files. [Imports](#import-additional-files) help you organize a long file but don’t reduce its context cost, because imported files load together with the CLAUDE.md that imports them.
- **Structure**: group related instructions under markdown headers and bullets. Organized sections are easier for Claude to follow than dense paragraphs.
- **Consistency**: if two instructions contradict each other, Claude may pick one arbitrarily. Review your CLAUDE.md files, nested CLAUDE.md files in subdirectories, and [`.claude/rules/`](#organize-rules-with-claude/rules/) periodically to remove outdated or conflicting instructions. To have Claude find them for you, [run a prompt audit](#audit-your-instruction-files).


[​](#audit-your-instruction-files)

Audit your instruction files

To have Claude check your instruction files for outdated or conflicting content, run `/doctor prompt-audit` in a session. Claude looks for problems such as instructions written for older models, references to files or commands that don’t exist, and files that contradict each other. You get a report of findings with proposed edits, and nothing in your files changes until you ask Claude to apply them. By default, the audit covers your CLAUDE.md, CLAUDE.local.md, and AGENTS.md files, plus the rules, skills, commands, subagents, and output styles under `.claude/` and `~/.claude/`. To audit one file or directory instead, pass its path, for example `/doctor prompt-audit .claude/skills/deploy`. The audit runs through the bundled `/claude-api` skill. It’s unavailable while that skill is turned off in [`skillOverrides`](../08-Plugins-Skills/skills.md#override-skill-visibility-from-settings) or with [`disableBundledSkills`](settings-reference.md#disablebundledskills). `/doctor prompt-audit` requires Claude Code v2.1.283 or later.


[​](#import-additional-files)

Import additional files

CLAUDE.md files can import additional files using `@path/to/import` syntax. Imported files are expanded and loaded into context alongside the CLAUDE.md that references them. Both relative and absolute paths are allowed. Relative paths resolve relative to the file containing the import, not the working directory. Imported files can recursively import other files, with a maximum depth of four hops. To import a file whose path contains spaces, put a backslash before each space. Without the backslashes, the path ends at the first space, even when the import is on a line of its own. A path wrapped in quotes isn’t imported at all, with or without the backslashes. This import loads a file from a folder named `Design Docs`:

```python
- API conventions @Design\ Docs/api-conventions.md
```

Import parsing skips Markdown code spans and fenced code blocks. To mention a path in your CLAUDE.md without importing it, wrap it in backticks: writing `` `@README` `` keeps the text literal, while `@README` outside backticks imports the file. To pull in a README, package.json, and a workflow guide, reference them with `@` syntax anywhere in your CLAUDE.md:

```python
See @README for project overview and @package.json for available npm commands for this project.

# Additional Instructions
- git workflow @docs/git-instructions.md
```

For private per-project preferences that shouldn’t be checked into version control, create a `CLAUDE.local.md` at the project root. It loads alongside `CLAUDE.md` and is treated the same way. Add `CLAUDE.local.md` to your `.gitignore` so it isn’t committed. With `CLAUDE_CODE_NEW_INIT=1` set, running `/init` and choosing the personal option does this for you. If you work across multiple git worktrees of the same repository, a gitignored `CLAUDE.local.md` only exists in the worktree where you created it. To share personal instructions across worktrees, import a file from your home directory instead:

```python
# Individual Preferences
- @~/.claude/my-project-instructions.md
```

An import in a project-level memory file is external when its path resolves outside your working directory, like the home directory import above. The first time Claude Code encounters external imports in a project, it shows an approval dialog listing the files. If you decline, the imports stay disabled and the dialog doesn’t appear again.Claude Code shows the dialog to protect you from files other people commit to a shared project. User-scope memory files, such as `~/.claude/CLAUDE.md` and `~/.claude/rules/`, are files you wrote yourself. Except in [Cowork](../15-Claude-AI-Features/product-cowork.md) sessions on your desktop, Claude Code loads their imports without the dialog and trusts them like the rest of your personal configuration.In Cowork sessions on your desktop, Claude Code skips any import in a user-scope file that resolves to a path outside the session’s working directory and loads the rest of the file. In those sessions it also skips a `~/.claude/CLAUDE.md` that is itself a symlink or hard link, and a symlinked `~/.claude/rules/` directory or rule file that points outside the working directory.


[​](#how-claude-md-files-load)

How CLAUDE.md files load

Claude Code loads `CLAUDE.md` and `CLAUDE.local.md` from your current working directory and every directory above it. Run Claude Code in `foo/bar/` and it loads instructions from `foo/bar/CLAUDE.md`, `foo/CLAUDE.md`, and any `CLAUDE.local.md` files alongside them. All discovered files are concatenated into context rather than overriding each other. Across the directory tree, content is ordered from the filesystem root down to your working directory. For the `foo/bar/` example, `foo/CLAUDE.md` appears in context before `foo/bar/CLAUDE.md`, so instructions closer to where you launched Claude are read last. Within each directory, `CLAUDE.local.md` is appended after `CLAUDE.md`, so your personal notes are the last thing Claude reads at that level. Claude also discovers `CLAUDE.md` and `CLAUDE.local.md` files in subdirectories under your current working directory. Instead of loading them at launch, Claude Code loads each one once Claude reads, writes, or edits another file in that subdirectory. Reading includes viewing the file with a Bash command that [counts as a read](tools-reference.md#edit-tool-behavior), such as `cat` or `head` on a single file. For files inside a worktree under `.claude/worktrees/`, see [Isolate subagents with worktrees](worktrees.md#isolate-subagents-with-worktrees). If you work in a large monorepo where other teams’ CLAUDE.md files get picked up, use [`claudeMdExcludes`](#exclude-specific-claude-md-files) to skip them. For the full layout of root and per-directory CLAUDE.md files and rules, see [Monorepos and large repos](large-codebases.md). Block-level HTML comments (`<!-- maintainer notes -->`) in CLAUDE.md files are stripped before the content is injected into Claude’s context. Use them to leave notes for human maintainers without spending context tokens on them. Comments inside code blocks are preserved. When you open a CLAUDE.md file directly with the Read tool, comments remain visible.


[​](#load-from-additional-directories)

Load from additional directories

The `--add-dir` flag gives Claude access to additional directories outside your main working directory. By default, CLAUDE.md files from these directories are not loaded. To also load memory files from additional directories, set the `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD` environment variable:

```python
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 claude --add-dir ../shared-config
```

The inline form sets the variable for that one launch in Bash or Zsh. To keep it on for every session, add it to the `env` block in `~/.claude/settings.json` as shown in [Set environment variables](env-vars.md#set-environment-variables). This loads `CLAUDE.md`, `.claude/CLAUDE.md`, `.claude/rules/*.md`, and `CLAUDE.local.md` from the additional directory. `CLAUDE.local.md` is skipped if you exclude `local` from [`--setting-sources`](cli-reference.md).


[​](#organize-rules-with-claude/rules/)

Organize rules with `.claude/rules/`

For larger projects, you can organize instructions into multiple files using the `.claude/rules/` directory. This keeps instructions modular and easier for teams to maintain. Rules can also be [scoped to specific file paths](#path-specific-rules), so they only load into context when Claude works with matching files, reducing noise and saving context space.

Rules load into context every session or when matching files are opened. For task-specific instructions that don’t need to be in context all the time, use [skills](../08-Plugins-Skills/skills.md) instead, which only load when you invoke them or when Claude determines they’re relevant to your prompt.


[​](#set-up-rules)

Set up rules

Place markdown files in your project’s `.claude/rules/` directory. Each file should cover one topic, with a descriptive filename like `testing.md` or `api-design.md`. All `.md` files are discovered recursively, so you can organize rules into subdirectories like `frontend/` or `backend/`:

```python
your-project/
├── .claude/
│   ├── CLAUDE.md           # Main project instructions
│   └── rules/
│       ├── code-style.md   # Code style guidelines
│       ├── testing.md      # Testing conventions
│       └── security.md     # Security requirements
```

Rules without [`paths` frontmatter](#path-specific-rules) are loaded at launch with the same priority as `.claude/CLAUDE.md`. Project rules are skipped if you exclude `project` from [`--setting-sources`](cli-reference.md). Before v2.1.211, rules that load on demand, including path-scoped rules and rules in nested `.claude/rules/` directories, loaded even when `project` was excluded.


[​](#path-specific-rules)

Path-specific rules

Rules can be scoped to specific files using YAML frontmatter with the `paths` field. These conditional rules only apply when Claude is working with files matching the specified patterns.

```python
---
paths:
  - "src/api/**/*.ts"
---

# API Development Rules

- All API endpoints must include input validation
- Use the standard error response format
- Include OpenAPI documentation comments
```

Rules without a `paths` field are loaded unconditionally and apply to all files. A path-scoped rule loads when Claude uses the Read, Write, or Edit tool on a matching file. It also loads when Claude views a matching file with a Bash command that [counts as a read](tools-reference.md#edit-tool-behavior), such as `cat` or `head` on a single file. Matching also works when Claude reaches a file through a symlinked path to the project directory, for example in a symlinked checkout. Each pattern is relative to the rule’s base directory:

- **Project rules**: the directory that contains the rule’s `.claude` folder
- **[User-level rules](#user-level-rules)**: the session’s [primary working directory](permissions.md#working-directories)

To have path-scoped rules load for files in a sibling git worktree, start Claude Code in that worktree or [move the session there with `/cd`](permissions.md#move-the-session-to-another-directory). Use glob patterns in the `paths` field to match files by extension, directory, or any combination:

| Pattern                | Matches                                  |
|------------------------|------------------------------------------|
| `**/*.ts`              | All TypeScript files in any directory    |
| `src/**/*`             | All files under `src/` directory         |
| `*.md`                 | Markdown files in the project root       |
| `src/components/*.tsx` | React components in a specific directory |

You can specify multiple patterns and use brace expansion to match multiple extensions in one pattern:

```python
---
paths:
  - "src/**/*.{ts,tsx}"
  - "lib/**/*.ts"
  - "tests/**/*.test.ts"
---
```

Each brace group multiplies the number of expanded patterns: `src/*.{ts,tsx}` expands to two patterns, and `{a,b}/{c,d}/*.{ts,tsx}` to eight. To keep expansion bounded, a rule’s whole `paths` list shares one budget of 1,000 expanded patterns and 4 MiB, and patterns without braces don’t count against it. Claude Code uses any pattern that would exceed the budget unexpanded, and its literal braces match no files. Before v2.1.217, a `paths` value with many brace groups stalled or crashed the CLI at startup. Glob syntax treats `[` as the start of a bracket expression such as `[abc]`. A pattern with a `[` that can’t be read as a bracket expression, such as `photos [2024/**`, is invalid: it matches nothing, and the rule’s other patterns keep working. To match a literal `[` in a file name, escape it as `photos \[2024/**`.


[​](#rules-frontmatter-reference)

Rule frontmatter reference

Configure a rule with YAML [frontmatter](glossary.md#frontmatter) between `---` markers at the top of the file. `paths` is the only field Claude Code reads from a rule; any other field is ignored without an error. Claude Code removes the frontmatter before loading the rule into context.

| Field   | Required | Description                                                                                                                  |
|:--------|:---------|:-----------------------------------------------------------------------------------------------------------------------------|
| `paths` | No       | Glob patterns that [scope the rule to matching files](#path-specific-rules). Accepts a YAML list or a comma-separated string |

If the YAML between the markers doesn’t parse, Claude Code ignores the frontmatter and loads the rule as if it had no `paths`. Run `claude --debug` to see the parse error.


[​](#share-rules-across-projects-with-symlinks)

Share rules across projects with symlinks

The `.claude/rules/` directory supports symlinks, so you can maintain a shared set of rules and link them into multiple projects. Circular symlinks are detected and handled gracefully. Claude Code treats a symlink whose target is outside your working directory like an [external import](#import-additional-files). The linked rules don’t load until you approve external imports for the project, and after that only the ones without a [`paths` field](#path-specific-rules) load. Claude Code asks for that approval once per project, in a dialog at the start of an interactive session. The dialog lists the linked rule files alongside any external `@path` imports. To load shared rules without that approval, keep them in [`~/.claude/rules/`](#user-level-rules), where they apply to every project on your machine. This example links both a shared directory and an individual file:

```python
ln -s ~/shared-claude-rules .claude/rules/shared
ln -s ~/company-standards/security.md .claude/rules/security.md
```

If you point a `.claude/rules/` or `CLAUDE.md` symlink at a network path such as the UNC share `\\server\share` or a path under `/net` or `/Network`, the linked instructions don’t load. Claude Code doesn’t follow the link, because looking up such a path can contact the host it names. `\\wsl$` paths don’t count as network paths.


[​](#user-level-rules)

User-level rules

Personal rules in `~/.claude/rules/` apply to every project on your machine. Use them for preferences that aren’t project-specific:

```python
~/.claude/rules/
├── preferences.md    # Your personal coding preferences
└── workflows.md      # Your preferred workflows
```

Claude Code loads user-level rules before project rules, so a project rule appears later in Claude’s context than a user rule. Neither set overrides the other: if a user rule and a project rule conflict, Claude may follow either one, so keep the two consistent.


[​](#manage-claude-md-for-large-teams)

Manage CLAUDE.md for large teams

For organizations deploying Claude Code across teams, you can centralize instructions and control which CLAUDE.md files are loaded.


[​](#deploy-organization-wide-claude-md)

Deploy organization-wide CLAUDE.md

Organizations can deploy a centrally managed CLAUDE.md that applies to all users on a machine. Developers can [exclude other CLAUDE.md files](#exclude-specific-claude-md-files) with the `claudeMdExcludes` setting, but not this one. If a developer starts a session with CLAUDE.md loading turned off altogether, that session doesn’t load the managed content either. Use the file for guidance, and enforce rules with [managed settings](../13-Enterprise-Admin/managed-settings.md) such as `permissions.deny`.

1

Create the file at the managed policy location

- macOS: `/Library/Application Support/ClaudeCode/CLAUDE.md`
- Linux and WSL: `/etc/claude-code/CLAUDE.md`
- Windows: `C:\Program Files\ClaudeCode\CLAUDE.md`

2

Deploy with your configuration management system

Use MDM, Group Policy, Ansible, or similar tools to distribute the file across developer machines. See [managed settings](../13-Enterprise-Admin/managed-settings.md) for other organization-wide configuration options.

The `claudeMd` key lets you put managed CLAUDE.md content directly inside `managed-settings.json` instead of deploying a separate file. **Scope**: all users on the machine, in any repository. For repository-specific guidance, commit a project CLAUDE.md instead. **Precedence**: same as a managed CLAUDE.md file. Loads before user and project CLAUDE.md. **Where it’s honored**: managed and policy settings only. Setting `claudeMd` in user, project, or local settings has no effect. The example below adds behavioral instructions directly in a managed settings file:

```python
{
  "claudeMd": "Always run `make lint` before committing.\nNever push directly to main."
}
```

A managed CLAUDE.md and [managed settings](../13-Enterprise-Admin/managed-settings.md) serve different purposes. Use settings for technical enforcement and CLAUDE.md for behavioral guidance:

| Concern                                        | Configure in                                              |
|:-----------------------------------------------|:----------------------------------------------------------|
| Block specific tools, commands, or file paths  | Managed settings: `permissions.deny`                      |
| Enforce sandbox isolation                      | Managed settings: `sandbox.enabled`                       |
| Environment variables and API provider routing | Managed settings: `env`                                   |
| Login method and organization restrictions     | Managed settings: `forceLoginMethod`, `forceLoginOrgUUID` |
| Code style and quality guidelines              | Managed CLAUDE.md                                         |
| Data handling and compliance reminders         | Managed CLAUDE.md                                         |
| Behavioral instructions for Claude             | Managed CLAUDE.md                                         |

Settings rules are enforced by the client regardless of what Claude decides to do. CLAUDE.md instructions shape Claude’s behavior but are not a hard enforcement layer.


[​](#exclude-specific-claude-md-files)

Exclude specific CLAUDE.md files

In large monorepos, ancestor CLAUDE.md files may contain instructions that aren’t relevant to your work. The `claudeMdExcludes` setting lets you skip specific files by path or glob pattern. You can’t exclude a [managed CLAUDE.md file](#deploy-organization-wide-claude-md) with `claudeMdExcludes`. This example excludes a top-level CLAUDE.md and a rules directory from a parent folder. Add it to `.claude/settings.local.json` so the exclusion stays local to your machine:

```python
{
  "claudeMdExcludes": [
    "**/monorepo/CLAUDE.md",
    "/home/user/monorepo/other-team/.claude/rules/**"
  ]
}
```

Patterns are matched against absolute file paths using glob syntax. You can configure `claudeMdExcludes` at any [settings layer](settings.md#where-settings-live): user, project, local, or managed policy. Arrays merge across layers. To exclude a rules file you reach through a [symlink](#share-rules-across-projects-with-symlinks), whether the file or its directory is the link, write the pattern against either path: the file’s path under `.claude/rules/` or its link target. A pattern that matches either path excludes the file. Before v2.1.239, only a pattern that matched the link target excluded the file.


[​](#agents-md)

AGENTS.md

Claude Code can read [`AGENTS.md`](glossary.md#agents-md) as your project instructions, so a repository already set up for other coding agents works without adding a `CLAUDE.md`, an import, or a setting. This table shows what Claude reads by default for each combination of instruction files in your repository:

| Your repository has                                                                           | Claude reads                                                   |
|:----------------------------------------------------------------------------------------------|:---------------------------------------------------------------|
| An `AGENTS.md`, and no `CLAUDE.md` or `CLAUDE.local.md` in your working directory or above it | Your `AGENTS.md`                                               |
| An `AGENTS.md` and a `CLAUDE.md` or `CLAUDE.local.md` in your working directory or above it   | Your `CLAUDE.md` files only                                    |
| A `CLAUDE.md` that already [imports `AGENTS.md`](#share-one-file-with-other-coding-tools)     | Your `CLAUDE.md`, with `AGENTS.md` included through the import |

To change the default, for example to have Claude always read both files, read only `CLAUDE.md`, or read only your organization’s managed instructions, [change the **Project instructions** setting](#choose-which-instruction-files-load).

Reading `AGENTS.md` directly requires Claude Code v2.1.277 or later. In some sessions Claude [can’t read `AGENTS.md`](#when-agents-md-support-is-unavailable), so [import it from a `CLAUDE.md`](#share-one-file-with-other-coding-tools) there instead.


[​](#when-claude-code-reads-agents-md)

When Claude Code reads AGENTS.md

By default, Claude reads `AGENTS.md` only when you have no `CLAUDE.md` in your working directory or above it. Here’s which of your files count for that check:

- **Count, so Claude reads them instead of `AGENTS.md`**: a `CLAUDE.md`, `.claude/CLAUDE.md`, or `CLAUDE.local.md` in your working directory or any directory above it
- **Don’t count, and keep loading alongside `AGENTS.md`**: your `~/.claude/CLAUDE.md`, your organization’s managed `CLAUDE.md`, and `.claude/rules/` files

When none count, here’s what Claude reads and how you can tell:

- **At session start**: every `AGENTS.md` and `.claude/AGENTS.md` in your working directory and the directories above it. In an interactive session you see a line such as `no CLAUDE.md found; AGENTS.md loaded: /home/you/repo/AGENTS.md` in the conversation
- **As Claude works in subdirectories**: a subdirectory’s `AGENTS.md`, when Claude opens a file there with the Read tool and that subdirectory has none of the three `CLAUDE.md` files of its own
- **Inside each `AGENTS.md`**: [`@path` imports](#import-additional-files) are expanded, [`claudeMdExcludes`](#exclude-specific-claude-md-files) patterns apply, and subagents that [start without project instructions](../09-Agents-Patterns/sub-agents.md#what-loads-at-startup) start without these files too
- **Not read**: `AGENTS.local.md`, `AGENTS.override.md`, or anything under a `.agents/` directory

Because `CLAUDE.local.md` counts, adding one to keep your own uncommitted instructions in a project that relies on `AGENTS.md` stops Claude from reading `AGENTS.md` for you. To keep your `CLAUDE.local.md` and still have Claude read `AGENTS.md`, set **Project instructions** to [`claude-md-and-agents-md`](#choose-which-instruction-files-load).


[​](#choose-which-instruction-files-load)

Choose which instruction files load

To change which files Claude reads, type `/config` in a Claude Code session to open the settings panel, then set **Project instructions** to one of these values:

| Value                     | What Claude reads                                                                                                                                                                                                                                                                                                                      |
|:--------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `claude-md-or-agents-md`  | Your `CLAUDE.md` files, or your `AGENTS.md` files when you have no `CLAUDE.md` or `CLAUDE.local.md` in your working directory or above it. This is the default                                                                                                                                                                         |
| `claude-md-and-agents-md` | Your `CLAUDE.md` and `AGENTS.md` files together, each directory’s `CLAUDE.md` files first and its `AGENTS.md` after them. Claude Code skips an `AGENTS.md` it has already loaded, so one that your `CLAUDE.md` imports or symlinks to isn’t read twice                                                                                 |
| `claude-md`               | Your `CLAUDE.md` files only                                                                                                                                                                                                                                                                                                            |
| `managed-only`            | Only your organization’s managed `CLAUDE.md` and [auto memory](#auto-memory) at launch. Your project, local, and user `CLAUDE.md` files, your `.claude/rules/` files, and every `AGENTS.md` are left out. A subdirectory’s `CLAUDE.md` and `.claude/rules/` files, and [path-scoped rules](#path-specific-rules), still load on demand |

You can also set the value in a settings file instead of `/config`. Add it to [`pluginConfigs`](settings-reference.md#pluginconfigs) under `cc-plugin-agents-md@builtin`, the ID of the built-in plugin that reads `AGENTS.md`. Claude Code reads the entry from `~/.claude/settings.json`, a `--settings` file, or [managed settings](../13-Enterprise-Admin/managed-settings.md), and ignores it in project and local settings files. This example has Claude read both files:

settings.json

```python
{
  "pluginConfigs": {
    "cc-plugin-agents-md@builtin": {
      "options": { "instructionFiles": "claude-md-and-agents-md" }
    }
  }
}
```

Before v2.1.285, the plugin’s ID was `agents-md@builtin`, and Claude Code ignored an entry under `cc-plugin-agents-md@builtin`. If earlier versions also read your settings file, use `agents-md@builtin` there. Claude Code v2.1.285 and later reads an entry under either ID. Your change applies from the next message you send and in every new session.


[​](#when-agents-md-support-is-unavailable)

When AGENTS.md support is unavailable

In these sessions Claude reads `CLAUDE.md` files only, and **Project instructions** doesn’t appear in the `/config` settings panel:

- You’re on a Claude Code version before v2.1.277
- You used `/plugin` to disable the built-in plugin that reads `AGENTS.md`
- In some cases, it’s your [first session after you upgrade](env-vars.md#first-session-after-an-install-or-upgrade) from v2.1.276 or earlier. Claude reads `AGENTS.md` from your next session on

Before v2.1.281, some sessions, such as those on Amazon Bedrock or with telemetry disabled, read `CLAUDE.md` files only. On those versions, update Claude Code. To give Claude your `AGENTS.md` in any of these sessions, [import it from a `CLAUDE.md`](#share-one-file-with-other-coding-tools).


[​](#where-agents-md-differs-from-claude-md)

Where AGENTS.md differs from CLAUDE.md

An `AGENTS.md` that Claude reads through the **Project instructions** setting differs from a `CLAUDE.md` in these places:

|                                                                                                                                       | `CLAUDE.md`                                                                  | `AGENTS.md` read through the setting                                                        |
|:--------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------|
| [`InstructionsLoaded` hooks](../07-Hooks/hooks.md#instructionsloaded)                                                                       | Fire                                                                         | Don’t fire. They fire as usual for an `AGENTS.md` that a `CLAUDE.md` imports or symlinks to |
| Directories you add with `--add-dir` while [`CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD`](#load-from-additional-directories) is set | Their `CLAUDE.md` loads                                                      | Their `AGENTS.md` doesn’t load                                                              |
| An `@path` import of a file outside your working directory                                                                            | Claude Code asks you to approve [external imports](#import-additional-files) | Loads only if you already approved external imports for this project, with no prompt        |


[​](#remove-an-earlier-agents-md-workaround)

Remove an earlier AGENTS.md workaround

If you set Claude Code up to read `AGENTS.md` before it did so on its own, here’s what to do with each common setup:

- **A `CLAUDE.md` containing `@AGENTS.md`**: you can leave it. Keeping the import never makes Claude read `AGENTS.md` twice, whichever **Project instructions** value you use. Remove the `CLAUDE.md` if it holds nothing else, or keep it if some of your sessions [can’t load `AGENTS.md` directly](#when-agents-md-support-is-unavailable).
- **A `CLAUDE.md` that tells Claude in words to read `AGENTS.md`**: Claude sees `AGENTS.md` only if it decides to open the file. Delete the `CLAUDE.md` so Claude reads `AGENTS.md` directly, or replace the sentence with an `@AGENTS.md` import.
- **A `CLAUDE.md` symlinked to `AGENTS.md`**: nothing, or delete the symlink. Either way Claude reads the content once.
- **A `SessionStart` hook that prints `AGENTS.md`**: remove it. Once Claude reads `AGENTS.md` directly, the hook adds a second copy to the context.


[​](#share-one-file-with-other-coding-tools)

Share one file with other coding tools

When Claude isn’t reading your `AGENTS.md` directly, you can still keep it as the one file every tool shares by putting an `@AGENTS.md` import in a `CLAUDE.md` next to it. Do this when your project also has a `CLAUDE.md`, when you’ve set **Project instructions** to `claude-md`, or in sessions that [can’t load `AGENTS.md`](#when-agents-md-support-is-unavailable). Add any Claude-specific instructions below the import, and Claude reads the imported file first, then the rest:

CLAUDE.md

```python
@AGENTS.md

## Claude Code

Use plan mode for changes under `src/billing/`.
```

If you don’t need Claude-specific content, a symlink also works:

```python
ln -s AGENTS.md CLAUDE.md
```

The command prints no output on success. Before you choose the symlink over the import, check these constraints:

- **Editing**: Claude reads `CLAUDE.md` through the link, but the Edit and Write tools [refuse to write through a symlink](errors.md#refusing-after-a-symlink-changed), and the refusal directs Claude to edit the link’s target, `AGENTS.md`, instead
- **Windows**: if you or anyone who clones the repository works on Windows, use the `@AGENTS.md` import instead. Creating a symlink there needs Administrator privileges or Developer Mode, and Git checks a committed symlink out as a plain text file unless `core.symlinks` is enabled, which leaves that clone with a one-line `CLAUDE.md` in place of your instructions

With either approach, run `/context` in your next session and confirm `CLAUDE.md` appears under **Memory files**.


[​](#migrate-instructions-from-other-tools)

Migrate instructions from other tools

Running [`/init`](commands.md) reads other tools’ instruction files and incorporates the relevant parts into the generated `CLAUDE.md`:

- Cursor rules in `.cursor/rules/` or `.cursorrules`
- Copilot rules in `.github/copilot-instructions.md`
- With `CLAUDE_CODE_NEW_INIT=1` set: `AGENTS.md`, `.devin/rules/`, `.windsurf/rules/` or `.windsurfrules`, and `.clinerules`

You can also run [`/import`](commands.md) to bring a supported coding agent’s configuration into Claude Code, which appends a one-time copy of instruction files such as `AGENTS.md` to the matching `CLAUDE.md` and carries over MCP servers, commands, subagents, and skills.


[​](#auto-memory)

Auto memory

Auto memory lets Claude accumulate knowledge across sessions without you writing anything. As it works, Claude saves four kinds of notes for itself. Claude records the kind as a `type` field in the memory file’s frontmatter:

- `user`: your role, expertise, and working preferences
- `feedback`: corrections you give Claude and approaches you confirm
- `project`: ongoing work, deadlines, and decisions that Claude can’t derive from the code or git history
- `reference`: where to find information outside the project, such as an issue tracker or dashboard

Claude skips anything it can derive from the codebase, such as architecture, file paths, or debugging fixes. It also skips anything your CLAUDE.md files already say. Claude doesn’t save something every session. It decides what’s worth remembering based on whether the information would be useful in a future conversation.


[​](#enable-or-disable-auto-memory)

Enable or disable auto memory

Auto memory is on by default in local sessions. Outside [Claude Tag](https://claude.com/docs/claude-tag/overview) sessions, a session in a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments-configuration.md#how-each-session%E2%80%99s-config-is-assembled) runs with auto memory off by default. To toggle it, open `/memory` in a session and use the auto memory toggle, which saves `autoMemoryEnabled` to your user settings at `~/.claude/settings.json`. The toggle turns auto memory off but doesn’t turn it back on in these sessions:

- A [background session](../09-Agents-Patterns/agent-view.md)
- A session that another Claude Code session started, such as when Claude runs `claude` through its Bash tool

While auto memory is off there, the toggle reads `off · can't be turned on here; use a session started outside Claude Code`. To turn auto memory back on, run `claude` directly in your terminal and use the `/memory` toggle in that session. To turn it off for a single project, set `autoMemoryEnabled` in that project’s settings:

```python
{
  "autoMemoryEnabled": false
}
```

To disable auto memory via environment variable, set `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1`.


[​](#storage-location)

Storage location

Each project gets its own memory directory at `~/.claude/projects/<project>/memory/`. The `<project>` path is derived from the git repository, so all worktrees and subdirectories within the same repo share one auto memory directory. Outside a git repo, the project root is used instead. If you set [`CLAUDE_CODE_PROJECT_DIR_NAME`](sessions.md#name-the-project-directory-yourself) beside `CLAUDE_CONFIG_DIR`, Claude Code uses that name as the `<project>` directory under `<config dir>/projects/` instead, whichever repository you launch it in, so projects launched with that config directory share one auto memory directory. Requires Claude Code v2.1.234 or later. To store auto memory in a different location, set `autoMemoryDirectory` in your `settings.json`. It is read from any [settings scope](settings.md#settings-precedence): user, project, local, policy, or `--settings`.

```python
{
  "autoMemoryDirectory": "~/my-custom-memory-dir"
}
```

The value must be an absolute path or start with `~/`. When you set it in a project’s `.claude/settings.json` or `.claude/settings.local.json`, Claude Code honors it under the same [workspace trust rule as hooks in settings files](permissions.md#what-runs-before-you-trust-a-folder). While [`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) is on, Claude Code loads no auto memory from a directory that a [repository-supplied settings file](permissions.md#when-your-local-settings-file-needs-trust) chooses and saves none to it, wherever that directory sits. The directory contains a `MEMORY.md` index and one topic file per memory:

```python
~/.claude/projects/<project>/memory/
├── MEMORY.md           # Index, one line per memory, loaded into every session
├── user_role.md        # One memory
├── feedback_testing.md # One memory
└── ...                 # Any other topic files Claude creates
```

`MEMORY.md` acts as an index of the memory directory. Claude reads and writes files in this directory throughout your session, using `MEMORY.md` to keep track of what’s stored where. Auto memory is machine-local. All worktrees and subdirectories within the same git repository share one auto memory directory. Files are not shared across machines or cloud environments. Claude Code deletes old session transcripts after the [`cleanupPeriodDays`](settings-reference.md#cleanupperioddays) retention period, but excludes the memory files in the memory directory from that [retention sweep](claude-directory.md#cleaned-up-automatically). `MEMORY.md` and topic files stay until you or Claude edits or deletes them.


[​](#how-it-works)

How it works

The first 200 lines of `MEMORY.md`, or the first 25KB, whichever comes first, are loaded at the start of every conversation. Content beyond that threshold is not loaded at session start. Claude keeps `MEMORY.md` concise by moving detailed notes into separate topic files. After Claude writes to `MEMORY.md`, Claude Code measures the file against the 200-line and 25KB read limits. If the file is near a limit, Claude Code reminds Claude to shorten it: keep one line per entry, move detail into topic files, and merge or drop stale entries. If the file is over a limit, the write still succeeds, but Claude Code returns an [error telling Claude to rewrite the index](errors.md#memory-index-is-over-its-read-limit), because everything past the limit is dropped on the next load.

This limit applies only to `MEMORY.md`. Claude gets the whole of each CLAUDE.md file that loads at launch, as long as the file is 4 MiB or smaller. Claude Code skips a file over 4 MiB and loads none of it. Path-scoped rules and CLAUDE.md files in subdirectories have [a smaller per-file limit of their own](#claude-ignores-the-end-of-my-subdirectory-claude-md).

Claude Code doesn’t load topic files such as `user_role.md` or `feedback_testing.md` at startup. Claude reads them on demand using its standard file tools when it needs the information. The main conversation’s auto memory isn’t loaded into [subagents](../09-Agents-Patterns/sub-agents.md#what-loads-at-startup); the exception is a [fork](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation), which inherits the parent conversation and system prompt. A subagent’s own auto memory, enabled with the subagent `memory` field, is a separate directory. Claude reads and writes memory files during your session. When you see messages like “Saved 2 memories” or “Recalled 2 memories” in the Claude Code interface, Claude is actively updating or reading from `~/.claude/projects/<project>/memory/`. When Claude writes a memory file that begins with YAML frontmatter, Claude Code records the write time in a `modified` frontmatter field as an ISO 8601 timestamp. The timestamp shows how current the fact is, both to you and to Claude when it reads the memory back.


[​](#audit-and-edit-your-memory)

Audit and edit your memory

Auto memory files are plain markdown you can edit or delete at any time. Run [`/memory`](#view-and-edit-with-%2Fmemory) to browse and open memory files from within a session.


[​](#view-and-edit-with-/memory)

View and edit with `/memory`

The `/memory` command lists your CLAUDE.md, CLAUDE.local.md, and other memory file locations across user and project scopes, including user and project CLAUDE.md entries for files that don’t exist yet. It also lets you toggle auto memory on or off and provides an option to open the auto memory folder. Select any file to open it in your editor; selecting one that doesn’t exist yet creates it first. To check which `CLAUDE.md` and rules files loaded at launch, run `/context`. GUI editors such as VS Code open the file in a separate window, and you can keep using the session while it’s open. Before v2.1.216, `/memory` waited for you to close the file before responding. Terminal editors such as Vim take over the terminal until you exit. When you ask Claude to remember something, like “always use pnpm, not npm” or “remember that the API tests require a local Redis instance,” Claude saves it to auto memory. To add instructions to CLAUDE.md instead, ask Claude directly, like “add this to CLAUDE.md,” or edit the file yourself via `/memory`.


[​](#troubleshoot-memory-issues)

Troubleshoot memory issues

These are the most common issues with CLAUDE.md and auto memory, along with steps to debug them.


[​](#claude-isn’t-following-my-claude-md)

Claude isn’t following my CLAUDE.md

CLAUDE.md content is delivered as a user message after the system prompt, not as part of the system prompt itself. Claude reads it and tries to follow it, but there’s no guarantee of strict compliance, especially for vague or conflicting instructions. To debug:

- Run `/context` and check the list under **Memory files** to verify the CLAUDE.md and CLAUDE.local.md files that should load at launch. If one is missing there, Claude can’t see it. Use `/memory` to open and edit the files.
- If an `Instruction file not loaded` notice appears, see [what it means and what to do about it](errors.md#instruction-file-not-loaded).
- A `CLAUDE.md` in a subdirectory of your working directory doesn’t appear under **Memory files**, because it loads on demand rather than at launch. When it loads, a `Loaded` line with its path appears in the terminal. To test a new one, create it from your shell rather than asking Claude to write it, then ask Claude to read a file in that subdirectory.
- Check that the relevant CLAUDE.md is in a location that gets loaded for your session (see [Choose where to put CLAUDE.md files](#choose-where-to-put-claude-md-files)).
- Make instructions more specific. “Use 2-space indentation” works better than “format code nicely.”
- Look for conflicting instructions across CLAUDE.md files. If two files give different guidance for the same behavior, Claude may pick one arbitrarily.
- Check whether your instruction competes with guidance Claude Code adds on its own. If your CLAUDE.md sets commit or pull request rules, turn off the built-in ones with [`includeGitInstructions`](settings-reference.md#includegitinstructions) and set the attribution text with [`attribution`](settings-reference.md#attribution).

If the instruction is something that must run at a specific point, such as before every commit or after each file edit, write it as a [hook](../07-Hooks/hooks-guide.md) instead. Hooks execute as shell commands at fixed lifecycle events and apply regardless of what Claude decides to do. For instructions you want at the system prompt level, use [`--append-system-prompt`](cli-reference.md#system-prompt-flags). You pass it at launch, so it’s better suited to scripts and automation than interactive use. For how it behaves when you resume a conversation, see [System prompt flags in resumed conversations](cli-reference.md#system-prompt-flags-in-resumed-conversations).

Use the [`InstructionsLoaded` hook](../07-Hooks/hooks.md#instructionsloaded) to log which `CLAUDE.md` and rules files are loaded, when they load, and why. This is useful for debugging path-specific rules or lazy-loaded files in subdirectories.


[​](#my-agents-md-isn’t-loading)

My AGENTS.md isn’t loading

If your repository has an `AGENTS.md` and Claude doesn’t seem to know what it says, the usual cause is a `CLAUDE.md` somewhere on the project path. By default Claude reads `AGENTS.md` only when you have no `CLAUDE.md` or `CLAUDE.local.md` in your working directory or above it. Check these in order:

1.  Look for a `CLAUDE.md`, `.claude/CLAUDE.md`, or `CLAUDE.local.md` in your working directory or any directory above it, other than your `~/.claude/CLAUDE.md`. If you find one, Claude reads it instead of `AGENTS.md` unless you set **Project instructions** to `claude-md-and-agents-md`.
2.  Run `claude --version` and confirm v2.1.277 or later. Before v2.1.281, some sessions, such as those on Amazon Bedrock or with telemetry disabled, [couldn’t load `AGENTS.md`](#when-agents-md-support-is-unavailable) either, so on those versions update to v2.1.281 or later.
3.  Type `/config` in your session to open the settings panel and confirm **Project instructions** isn’t set to `claude-md` or `managed-only`. If you don’t see the setting there at all, your session is one that [can’t load `AGENTS.md`](#when-agents-md-support-is-unavailable).

To check whether Claude read your `AGENTS.md`, run `/memory` and look for its path in the list. Before v2.1.280, `/memory` and `/context` didn’t list an `AGENTS.md` that Claude read directly. On those versions, ask Claude what its project instructions say instead. If you want to keep the `CLAUDE.md` you found, or your session can’t load `AGENTS.md`, [add a `CLAUDE.md` next to your `AGENTS.md` that imports it](#share-one-file-with-other-coding-tools).


[​](#i-don’t-know-what-auto-memory-saved)

I don’t know what auto memory saved

Run `/memory` and select the auto memory folder to browse what Claude has saved. Everything is plain markdown you can read, edit, or delete.


[​](#my-claude-md-is-too-large)

My CLAUDE.md is too large

Files over 200 lines consume more context and may reduce adherence. Claude Code skips a file over 4 MiB. Use [path-scoped rules](#path-specific-rules) to load instructions only when Claude works with matching files, or trim content that isn’t needed in every session. Splitting into [`@path` imports](#import-additional-files) helps organization but doesn’t reduce context, since imported files load with the CLAUDE.md importing them. If one of your instruction files is over the recommended length, you see a warning at startup and when you run `/status`. You also see a warning when files that are each within that length add up past a combined limit at session start. Each CLAUDE.md, rules file, and `@path` import counts as a separate file. The [`/doctor`](commands.md#all-commands) checkup proposes trims for a checked-in CLAUDE.md: it cuts content Claude can derive from the codebase, such as directory layouts, dependency lists, and architecture overviews, and keeps pitfalls, rationale, and conventions that differ from tool defaults.

Keep each path-scoped rules file within [its own per-file size limit](#claude-ignores-the-end-of-my-subdirectory-claude-md), because Claude receives only the start of a file that’s over it.


[​](#claude-ignores-the-end-of-my-subdirectory-claude-md)

Claude ignores the end of my subdirectory CLAUDE.md

When a subdirectory `CLAUDE.md` or a rules file that loads on demand is over a per-file size limit, Claude receives only the start of it. That part ends with a note telling Claude to read the rest with the Read tool, and until Claude chooses to, the later instructions aren’t in its context. Check whether your file is over the limit, and shrink it if it is:

1.  Confirm that the limit applies to your file. The limit applies to these files, which load on demand:
    - `CLAUDE.md` and `CLAUDE.local.md` in a subdirectory of the directory where you started Claude Code, and the files they [import](#import-additional-files) with `@path`
    - Rules files in a subdirectory’s `.claude/rules/`
    - [Path-scoped rules](#path-specific-rules) in your project’s `.claude/rules/` or in `~/.claude/rules/`
2.  Find the limit for your session’s [context window](model-config.md#extended-context):
    - **200K context window**: 40,000 characters
    - **1M context window**: 200,000 characters on Claude Opus 4.6 and Claude Sonnet 4.6, and 150,000 characters on later models
3.  In Bash or Zsh, run `wc -m path/to/CLAUDE.md` to print your file’s character count.
4.  Compare the count with your limit:
    - **Over the limit**: trim the file, or move part of it into one or more rules files, which each count against the limit on their own
    - **Under the limit**: look for another cause under [Claude isn’t following my CLAUDE.md](#claude-isn%E2%80%99t-following-my-claude-md)

Before v2.1.309, Claude Code didn’t apply this limit to files that load on demand.


[​](#instructions-seem-lost-after-/compact)

Instructions seem lost after `/compact`

Project-root CLAUDE.md survives compaction: after `/compact`, Claude re-reads it from disk and re-injects it into the session. Nested CLAUDE.md files in subdirectories and rules with [`paths:` frontmatter](#path-specific-rules) load again on demand. If an instruction disappeared after compaction, it was given only in conversation, lives in a nested CLAUDE.md that hasn’t reloaded yet, or is a path-scoped rule that hasn’t matched a file since. Add conversation-only instructions to CLAUDE.md to make them persist. See [What survives compaction](context-window.md#what-survives-compaction) for the full breakdown. See [Write effective instructions](#write-effective-instructions) for guidance on size, structure, and specificity.


[​](#related-resources)

Related resources

- [Debug your configuration](debug-your-config.md): diagnose why CLAUDE.md or settings aren’t taking effect
- [Skills](../08-Plugins-Skills/skills.md): package repeatable workflows that load on demand
- [Settings](settings.md): configure Claude Code behavior with settings files
- [Subagent memory](../09-Agents-Patterns/sub-agents.md#enable-persistent-memory): let subagents maintain their own auto memory

---

## Claude Code on Microsoft Foundry - Claude Code Docs

Source: https://code.claude.com/docs/en/microsoft-foundry
Path: 02-Claude-Code-CLI/microsoft-foundry.md

## On this page

- [Prerequisites](#prerequisites)
- [Setup](#setup)
  - [1. Provision Microsoft Foundry resource](#1-provision-microsoft-foundry-resource)
  - [2. Configure Azure credentials](#2-configure-azure-credentials)
  - [Use an API key](#use-an-api-key)
  - [Use Microsoft Entra ID](#use-microsoft-entra-id)
  - [Use a bearer token](#use-a-bearer-token)
  - [3. Configure Claude Code](#3-configure-claude-code)
  - [4. Pin model versions](#4-pin-model-versions)
  - [5. Run Claude Code](#5-run-claude-code)
- [Azure RBAC configuration](#azure-rbac-configuration)
- [1M token context window](#1m-token-context-window)
- [Troubleshooting](#troubleshooting)
- [Additional resources](#additional-resources)

Deployment

# Claude Code on Microsoft Foundry

Copy pageCopy page

Learn about configuring Claude Code through Microsoft Foundry, including setup, configuration, and troubleshooting.

Copy pageCopy page


[​](#prerequisites)

Prerequisites

Before configuring Claude Code with Microsoft Foundry, ensure you have:

- An Azure subscription with access to Microsoft Foundry
- RBAC permissions to create Microsoft Foundry resources and deployments
- Azure CLI installed and configured (optional - only needed if you don’t have another mechanism for getting credentials)

If you are deploying Claude Code to multiple users, [pin your model versions](#4-pin-model-versions) before rolling out.


[​](#setup)

Setup


[​](#1-provision-microsoft-foundry-resource)

1. Provision Microsoft Foundry resource

First, create a Claude resource in Azure:

1.  Go to the [Microsoft Foundry portal](https://ai.azure.com/)
2.  Create a new resource, noting your resource name
3.  Create deployments for the Claude models, noting the deployment name you give each; you’ll set these names as the model variables in step 4:
    - Claude Opus
    - Claude Sonnet
    - Claude Haiku

    When you configure a deployment, you also choose its [hosting option](../04-API-Reference/Guides/build-with-claude-claude-in-microsoft-foundry.md#hosting-options), which determines whether inference runs on Azure or on Anthropic infrastructure.


[​](#2-configure-azure-credentials)

2. Configure Azure credentials

Claude Code supports three authentication methods for Microsoft Foundry. Choose the method that best fits your security requirements:

- [API key](#use-an-api-key): you copy a key from the Microsoft Foundry portal and set it as `ANTHROPIC_FOUNDRY_API_KEY`
- [Microsoft Entra ID](#use-microsoft-entra-id): Claude Code gets tokens through the Azure SDK default credential chain, for example from an `az login` session, so there’s no API key to store
- [Bearer token](#use-a-bearer-token): another process obtains a Microsoft Entra ID access token and you pass it in `ANTHROPIC_FOUNDRY_AUTH_TOKEN`

When using Microsoft Foundry, the `/logout` command is unavailable since authentication is handled through Azure credentials.


[​](#use-an-api-key)

Use an API key

Copy a key from the Microsoft Foundry portal, then set it as an environment variable:

1.  Go to your resource in the Microsoft Foundry portal
2.  Open the **Endpoints and keys** section
3.  Copy **API Key**
4.  Set the environment variable, replacing `your-azure-api-key` with the key you copied:

```python
export ANTHROPIC_FOUNDRY_API_KEY=your-azure-api-key
```


[​](#use-microsoft-entra-id)

Use Microsoft Entra ID

Leave `ANTHROPIC_FOUNDRY_API_KEY` and `ANTHROPIC_FOUNDRY_AUTH_TOKEN` unset. Claude Code then uses the Azure SDK [default credential chain](https://learn.microsoft.com/en-us/azure/developer/javascript/sdk/authentication/credential-chains#defaultazurecredential-overview). This supports a variety of methods for authenticating local and remote workloads. On a local machine, sign in with the Azure CLI:

```python
az login
```

For the roles your identity needs, see [Azure RBAC configuration](#azure-rbac-configuration).


[​](#use-a-bearer-token)

Use a bearer token

Claude Code sends the value of `ANTHROPIC_FOUNDRY_AUTH_TOKEN` on every request as the `Authorization: Bearer` header. Use this option when another process, such as a host application or a sign-in script, has already obtained an access token for you. Set the variable to a bearer token that Microsoft Entra ID issued for your resource:

```python
export ANTHROPIC_FOUNDRY_AUTH_TOKEN=your-entra-access-token
```

`ANTHROPIC_FOUNDRY_AUTH_TOKEN` takes precedence over `ANTHROPIC_FOUNDRY_API_KEY` and over the default credential chain.


[​](#3-configure-claude-code)

3. Configure Claude Code

Set the following environment variables to enable Microsoft Foundry:

```python
# Enable Microsoft Foundry integration
export CLAUDE_CODE_USE_FOUNDRY=1

# Azure resource name (replace {resource} with your resource name)
export ANTHROPIC_FOUNDRY_RESOURCE={resource}
# Or provide the full base URL:
# export ANTHROPIC_FOUNDRY_BASE_URL=https://{resource}.services.ai.azure.com/anthropic
```

Set `ANTHROPIC_FOUNDRY_RESOURCE` to the resource name alone, such as `my-resource`. Claude Code [refuses a URL or host name](errors.md#anthropic-foundry-resource-must-be-a-foundry-resource-name) when you send a message.


[​](#4-pin-model-versions)

4. Pin model versions

Pin specific model versions for every deployment. Without pinning, model aliases such as `sonnet` and `opus` resolve to Claude Code’s built-in default for Microsoft Foundry, which can lag the newest release and may not yet be available in your account. Microsoft Foundry has no startup model check, so requests fail when the default is unavailable. When you create Azure deployments, select a specific model version rather than “auto-update to latest.”

Set the model variables to match the deployment names you created in step 1. Without `ANTHROPIC_DEFAULT_OPUS_MODEL`, the `opus` alias on Microsoft Foundry resolves to Opus 4.6. Set it to the ID of a newer Opus model, such as Opus 4.8:

```python
export ANTHROPIC_DEFAULT_OPUS_MODEL='claude-opus-4-8'
export ANTHROPIC_DEFAULT_SONNET_MODEL='claude-sonnet-5'
export ANTHROPIC_DEFAULT_HAIKU_MODEL='claude-haiku-4-5'
```

Background tasks such as session title generation use the small/fast model, normally a Haiku-class model. On Microsoft Foundry, Claude Code defaults this to the primary model because not every account has a Haiku deployment. To use Haiku for background tasks, set `ANTHROPIC_DEFAULT_HAIKU_MODEL` to a Haiku deployment that is available in your account, as shown above. For current and legacy model IDs, see [Models overview](../20-Models/about-claude-models-overview.md). See [Model configuration](model-config.md#pin-models-for-third-party-deployments) for the full list of environment variables. [Prompt caching](prompt-caching.md) is enabled automatically. To request a 1-hour cache TTL instead of the 5-minute default, set the following variable; cache writes with a 1-hour TTL are billed at a higher rate:

```python
export ENABLE_PROMPT_CACHING_1H=1
```

To set different TTLs for your main conversation and for the requests Claude Code makes outside it, [choose the TTL yourself](prompt-caching.md#choose-the-ttl-yourself).


[​](#5-run-claude-code)

5. Run Claude Code

With the environment variables set, start Claude Code from your project directory:

```python
claude
```

Claude Code reads `CLAUDE_CODE_USE_FOUNDRY` and the other Microsoft Foundry variables from the environment and connects to your Azure resource on the first prompt. Unlike Amazon Bedrock and Google Cloud’s Agent Platform, Microsoft Foundry has no interactive setup wizard, so the environment variables in steps 3 and 4 are the only configuration path. To verify your setup, run `/status` inside Claude Code. The API provider line shows `Microsoft Foundry`, along with the resource name or base URL you configured.


[​](#azure-rbac-configuration)

Azure RBAC configuration

The `Azure AI User` and `Cognitive Services User` default roles include all required permissions for invoking Claude models. For more restrictive permissions, create a custom role with the following:

```python
{
  "permissions": [
    {
      "dataActions": [
        "Microsoft.CognitiveServices/accounts/providers/*"
      ]
    }
  ]
}
```

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


[​](#1m-token-context-window)

1M token context window

On Microsoft Foundry, when Claude Code can tell which model your deployment serves, Fable models, Sonnet 5 and later, and Opus 4.7 and later run with the [1M token context window](../04-API-Reference/Guides/build-with-claude-context-windows.md#context-window-sizes-by-model) by default, with no `[1m]` suffix needed. Claude Code reads the model from the deployment name in your model variables. Name each deployment with its model ID, such as `claude-opus-4-8`, or map the model to your deployment name with [`modelOverrides`](model-config.md#override-model-ids-per-version). For a deployment name it can’t match to a model, Claude Code assumes a 200K window unless you [declare a different one](model-config.md#correct-the-window-for-a-gateway-or-custom-model-id). This `settings.json` entry tells Claude Code that a deployment named `team-opus-prod` serves Opus 4.8:

```python
{
  "modelOverrides": {
    "claude-opus-4-8": "team-opus-prod"
  }
}
```

To keep a 200K window instead, set [`CLAUDE_CODE_DISABLE_1M_CONTEXT=1`](model-config.md#turn-off-1m-context). Opus 4.6 and Sonnet 4.6 reach the 1M window when you append `[1m]` to the deployment name in `ANTHROPIC_DEFAULT_OPUS_MODEL` or `ANTHROPIC_DEFAULT_SONNET_MODEL`, as [Pin models for third-party deployments](model-config.md#pin-models-for-third-party-deployments) describes. Before v2.1.287, the Fable models and Opus 4.7 and later also needed that suffix on Microsoft Foundry and ran with a 200K window by default without it.


[​](#troubleshooting)

Troubleshooting

If you receive an error “Failed to get token from azureADTokenProvider: ChainedTokenCredential authentication failed”:

- Configure Entra ID on the environment, or set `ANTHROPIC_FOUNDRY_API_KEY`.

If requests fail with repeated connection errors on the first prompt:

- Check that `ANTHROPIC_FOUNDRY_RESOURCE` is set to your actual resource name rather than a placeholder. Claude Code builds the endpoint URL from this value, so an incorrect name points at a host that doesn’t exist.


[​](#additional-resources)

Additional resources

- [Microsoft Foundry documentation](https://learn.microsoft.com/en-us/azure/ai-foundry/what-is-azure-ai-foundry)
- [Microsoft Foundry models](https://ai.azure.com/explore/models)
- [Microsoft Foundry pricing](https://azure.microsoft.com/en-us/pricing/details/ai-foundry/)

---

## Model configuration - Claude Code Docs

Source: https://code.claude.com/docs/en/model-config
Path: 02-Claude-Code-CLI/model-config.md

## On this page

- [Available models](#available-models)
  - [Model aliases](#model-aliases)
  - [Work with Fable](#work-with-fable)
  - [Fable and usage credits](#fable-and-usage-credits)
  - [Setting your model](#setting-your-model)
  - [Set a default model for new sessions](#set-a-default-model-for-new-sessions)
  - [A new session starts on a different model than you picked](#a-new-session-starts-on-a-different-model-than-you-picked)
- [Restrict model selection](#restrict-model-selection)
  - [Surface coverage](#surface-coverage)
  - [Default model behavior](#default-model-behavior)
  - [Enforce the allowlist for the Default model](#enforce-the-allowlist-for-the-default-model)
  - [Control the model users run on](#control-the-model-users-run-on)
  - [Merge behavior](#merge-behavior)
  - [Mantle model IDs](#mantle-model-ids)
  - [Block specific models or versions](#block-specific-models-or-versions)
  - [Organization model restrictions](#organization-model-restrictions)
- [Organization default model](#organization-default-model)
- [Organization effort limits](#organization-effort-limits)
- [Special model behavior](#special-model-behavior)
  - [default model setting](#default-model-setting)
  - [opusplan model setting](#opusplan-model-setting)
  - [Fallback model chains](#fallback-model-chains)
  - [Automatic model fallback](#automatic-model-fallback)
  - [Effort level after a fallback](#effort-level-after-a-fallback)
  - [Check what triggered fallback](#check-what-triggered-fallback)
  - [Ask before switching](#ask-before-switching)
  - [Enable fallback on Bedrock, Agent Platform, and Foundry](#enable-fallback-on-bedrock-agent-platform-and-foundry)
  - [Security research and biology workloads](#security-research-and-biology-workloads)
  - [Adjust effort level](#adjust-effort-level)
  - [Choose an effort level](#choose-an-effort-level)
  - [Use ultrathink for one-off deep reasoning](#use-ultrathink-for-one-off-deep-reasoning)
  - [Set the effort level](#set-the-effort-level)
  - [Adaptive reasoning and fixed thinking budgets](#adaptive-reasoning-and-fixed-thinking-budgets)
  - [Extended thinking](#extended-thinking)
  - [Extended context](#extended-context)
  - [Select 1M context for Opus 4.6 or Sonnet 4.6](#select-1m-context-for-opus-4-6-or-sonnet-4-6)
  - [Context window behind an LLM gateway](#context-window-behind-an-llm-gateway)
  - [Turn off 1M context](#turn-off-1m-context)
  - [Haiku 5.5 context window and pricing](#haiku-5-5-context-window-and-pricing)
- [Context window and auto-compaction](#context-window-and-auto-compaction)
  - [Set the auto-compact window](#set-the-auto-compact-window)
  - [Values and warnings for CLAUDE_CODE_AUTO_COMPACT_WINDOW](#claude_code_auto_compact_window-values)
  - [Default auto-compact thresholds](#default-auto-compact-thresholds)
  - [Correct the window for a gateway or custom model ID](#correct-the-window-for-a-gateway-or-custom-model-id)
  - [Which IDs CLAUDE_CODE_MAX_CONTEXT_TOKENS applies to](#which-ids-claude_code_max_context_tokens-applies-to)
- [Checking your current model](#checking-your-current-model)
- [Add a custom model option](#add-a-custom-model-option)
- [Environment variables](#environment-variables)
  - [Pin models for third-party deployments](#pin-models-for-third-party-deployments)
  - [Customize pinned model display and capabilities](#customize-pinned-model-display-and-capabilities)
  - [Override model IDs per version](#override-model-ids-per-version)
  - [Prompt caching configuration](#prompt-caching-configuration)
- [Version history](#version-history)

Model and responses

# Model configuration

Copy pageCopy page

Configure which model Claude Code uses, effort levels, extended context, and the auto-compact window

Copy pageCopy page


[​](#available-models)

Available models

For the `model` setting in Claude Code, you can configure either:

- A **model alias**
- A **model name**
  - Anthropic API: a full **[model name](../20-Models/about-claude-models-overview.md)**
  - Amazon Bedrock: an inference profile ARN
  - Microsoft Foundry: a deployment name
  - Google Cloud’s Agent Platform: a version name

For guidance on which model and effort level fit different kinds of work, see [Choosing a Claude model and effort level in Claude Code](https://claude.com/blog/claude-model-and-effort-level-in-claude-code) on the blog.

`ANTHROPIC_BASE_URL` changes where requests are sent, not which model answers them. To route Claude through an LLM gateway, see [LLM gateways](../13-Enterprise-Admin/llm-gateway.md).


[​](#model-aliases)

Model aliases

Use a model alias to select model settings without remembering exact version numbers:

| Model alias      | Behavior                                                                                                                                                                                                                                                                   |
|------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`default`**    | Special value that clears any model override and reverts to the [runtime default for your account](#default-model-setting). Not itself a model alias                                                                                                                       |
| **`best`**       | Uses the model the [`fable` alias resolves to](#fable-alias-resolution) where Fable is available to you, otherwise the same model as `opus`                                                                                                                                |
| **`fable`**      | Uses the [Fable model for your provider](#fable-alias-resolution) for your hardest and longest-running tasks                                                                                                                                                               |
| **`sonnet`**     | Uses the latest Sonnet model for daily coding tasks                                                                                                                                                                                                                        |
| **`opus`**       | Uses the latest Opus model for complex reasoning tasks                                                                                                                                                                                                                     |
| **`haiku`**      | Uses the fast and efficient Haiku model for simple tasks                                                                                                                                                                                                                   |
| **`sonnet[1m]`** | Uses Sonnet with a [1 million token context window](../04-API-Reference/Guides/build-with-claude-context-windows.md#context-window-sizes-by-model) for long sessions. No effect when `sonnet` already resolves to Sonnet 5.5 or Sonnet 5 with their native 1M window |
| **`opus[1m]`**   | Uses Opus with a [1 million token context window](../04-API-Reference/Guides/build-with-claude-context-windows.md#context-window-sizes-by-model) for long sessions. No effect when `opus` already resolves to Opus 4.7 or later with its native 1M window            |
| **`opusplan`**   | Special mode that uses `opus` during plan mode, then switches to `sonnet` for execution                                                                                                                                                                                    |

The `opus`, `sonnet`, and `haiku` aliases resolve to the newest version on the Anthropic API and to an earlier version on some other providers:

| Provider                                                  | `opus`   | `sonnet`   | `haiku`   |
|:----------------------------------------------------------|:---------|:-----------|:----------|
| Anthropic API                                             | Opus 5.5 | Sonnet 5.5 | Haiku 5.5 |
| [Claude Platform on AWS](claude-platform-on-aws.md) | Opus 5.5 | Sonnet 4.6 | Haiku 4.5 |
| Amazon Bedrock, Google Cloud’s Agent Platform             | Opus 5.5 | Sonnet 4.5 | Haiku 4.5 |
| Microsoft Foundry                                         | Opus 4.6 | Sonnet 4.5 | Haiku 4.5 |

Unless you set `ANTHROPIC_DEFAULT_FABLE_MODEL`, the `fable` alias resolves to Fable 5.1, except in [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sessions, where `fable` and `best` resolve to Fable 5. A gateway that isn’t configured to serve `claude-fable-5-1` rejects requests for that model. To use Fable 5.1 through a gateway that serves it, select it with `/model claude-fable-5-1`. Where `opus` or `sonnet` resolves to an older model, newer models are available by selecting the full model name explicitly or setting `ANTHROPIC_DEFAULT_OPUS_MODEL` or `ANTHROPIC_DEFAULT_SONNET_MODEL`. Earlier versions resolve these aliases to older models. For the version at which each alias changed, see [Version history](#version-history). Aliases point to the recommended version for your provider and update over time. To pin to a specific version, use the full model name, for example `claude-opus-5-5`, or set the corresponding environment variable like `ANTHROPIC_DEFAULT_OPUS_MODEL`.

Sonnet 5.5 requires Claude Code v2.1.284 or later, and Opus 5.5 requires v2.1.280 or later. If a request for one of them from an older version fails, see [Claude Code does not support this model](errors.md#claude-code-does-not-support-this-model). Use v2.1.293 or later with Haiku 5.5. Run `claude update` to upgrade.


[​](#work-with-fable)

Work with Fable

[Claude Fable 5.1](../20-Models/about-claude-models-overview.md) and Claude Fable 5 are the most capable models in Claude Code, suited to tasks larger than a single sitting. They sustain long autonomous sessions, investigate before acting, and verify their work more often than smaller models. Fable 5.1 is the newer release. Neither Fable model is the account-type default on any plan or provider. Select one explicitly:

- **Fable 5.1**: run `/model fable`, or launch with `claude --model fable`. In [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sessions, where the alias resolves to Fable 5, run `/model claude-fable-5-1` instead.
- **Fable 5**: select it by model ID. On the Anthropic API, run `/model claude-fable-5` or launch with `claude --model claude-fable-5`. On other providers, use your provider’s Fable 5 model ID or [pin it](#pin-models-for-third-party-deployments) with `ANTHROPIC_DEFAULT_FABLE_MODEL`.

If you connect to the Anthropic API directly and your user settings hold `claude-fable-5` or `claude-fable-5[1m]` as the model, for example because you selected Fable in the `/model` picker before v2.1.257, Claude Code changes that saved value to the `fable` or `fable[1m]` alias the first time you run v2.1.257 or later. The startup model line shows `(auto-updated)` once. A `claude-fable-5` value in project, local, or managed settings stays as it is. Requests that a Fable model’s safety classifiers flag, most often in cybersecurity and biology domains, trigger [automatic model fallback](#automatic-model-fallback). To get the most from Fable:

- **Describe the outcome, not the steps**: hand it the result you want and let it plan the path. To keep it working toward that outcome, [set a goal](goal.md).
- **Hand it ambiguous problems**: root-cause investigations, outage debugging, and architecture decisions are where the extra investigation and verification pay off.
- **Skip the verification reminders**: it verifies its own work with less prompting, so reminders to test or check are usually unnecessary.
- **Size up larger tasks**: give it work you would normally break into pieces. It holds long sessions without losing the thread.

Fable 5.1 requires Claude Code v2.1.257 or later. If a request for it from an older version fails, see [Claude Code does not support this model](errors.md#claude-code-does-not-support-this-model). Run `claude update` to upgrade. For availability under zero data retention, see [Model availability under ZDR](zero-data-retention.md#model-availability-under-zdr).

On the Anthropic API, a Fable model appears in the `/model` picker unless [`availableModels`](#restrict-model-selection) or [organization model restrictions](#organization-model-restrictions) exclude it. When your organization can’t use Fable at all, for example under [zero data retention](zero-data-retention.md#model-availability-under-zdr), the row stays in the picker grayed out, with a note on why.


[​](#fable-and-usage-credits)

Fable and usage credits

Depending on your plan and seat tier, Fable usage can bill to [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md) instead of drawing on your plan’s included limits. When it does, the `/model` picker shows “Requires usage credits” on the Fable row. To manage usage credits, see [Add usage credits to your subscription](../17-Billing-Plans/costs.md#add-usage-credits-to-your-subscription). In interactive sessions, Claude Code shows a consent prompt before a Fable request bills usage credits. Members of Enterprise plans with organization billing don’t see the prompt. You can continue on Fable using usage credits or switch to your default model. You can also dismiss the prompt:

- When you select a Fable model with `/model`, you keep your current model.
- Mid-session, Claude Code continues the turn on your default model.

After you choose to continue on Fable using usage credits, Claude Code doesn’t show the prompt again. In a session with [Remote Control](remote-control.md) connected, a [background session](../09-Agents-Patterns/agent-view.md), or an [agent team](../09-Agents-Patterns/agent-teams.md) teammate’s session, nobody may be at the terminal, so Claude Code holds the mid-session consent prompt for the [`dialogExpiry`](settings-reference.md#dialogexpiry) deadline, five minutes by default. If nobody has answered by the deadline, Claude Code ends the turn without sending the request and adds a notice to the transcript, which the Remote Control client also shows. Your model selection is unchanged, and Claude Code asks for consent again on your next message. What you can do while the prompt is waiting depends on the session:

- With Remote Control connected or in a teammate’s session, press any key at the terminal to cancel the deadline, and Claude Code waits for your answer.
- In a background session, answer before the deadline.
- If you send a new message from the remote client before anyone has typed at the terminal, Claude Code ends the turn the same way, and your new message starts the next turn. After someone types at the terminal, Claude Code keeps waiting for the answer and queues your new message behind it.

In a session another application hosts through the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md), whether the prompt appears is up to that application. If it appears and nobody answers before the same [`dialogExpiry`](settings-reference.md#dialogexpiry) deadline, Claude Code ends the turn without sending the request. In [non-interactive mode](headless.md) with the `-p` flag, and in an Agent SDK application that doesn’t show the prompt, Claude Code never asks for consent. When a Fable request there would bill to usage credits, Claude Code bills it without asking.


[​](#setting-your-model)

Setting your model

You can configure your model in several ways, listed in order of priority:

1.  **During session**: use `/model <alias|name>` to switch immediately, or run `/model` with no argument to open the picker. See [when Claude Code asks you to confirm the switch](prompt-caching.md#switching-models)
2.  **At startup**: launch with `claude --model <alias|name>`
3.  **Environment variable**: set `ANTHROPIC_MODEL=<alias|name>`
4.  **Settings**: configure permanently in your settings file using the `model` field
5.  **[Default for new sessions](#set-a-default-model-for-new-sessions)**: set `ANTHROPIC_DEFAULT_MODEL=<alias|name>`

`/model` saves your choice as the default for new sessions by writing the `model` field in your user settings. In the picker:

- `Enter`: switch model and save as your default
- `s`: switch model for this session only and leave your default unchanged. To use a different key, rebind [`modelPicker:thisSessionOnly`](keybindings.md#model-picker-actions)

Typing `/model <name>` directly behaves like `Enter`. To switch for this session only, open the picker with `/model` and press `s` on the model’s row. On an Enterprise plan, when you’re logged in with your claude.ai account and save a default with `/model`, Claude Code also records the choice on that account. This requires Claude Code v2.1.280 or later.

- When your admin hasn’t set an [organization default model](#organization-default-model), the [Default option](#default-model-setting) can resolve to the recorded model, and when it does, the picker’s Default row shows that model’s name.
- If [model restrictions](#restrict-model-selection) exclude the recorded model or it isn’t available to your account, and your admin hasn’t set an organization default model, the Default option resolves as if nothing were recorded.
- If you choose Default or `opusplan` in `/model`, the recorded choice doesn’t change.

If you switch models with `/model`, the switch also reaches [subagents that inherit the main conversation’s model](../09-Agents-Patterns/sub-agents.md#choose-a-model), because Claude Code resolves their model from the one your session is using when Claude starts them. Switch to Opus before Claude delegates research or test runs to one of them, and that work runs on Opus too. To keep a custom subagent on a smaller model, set `model` in its definition. If you set a model with `/model` in [non-interactive mode](headless.md), with the `-p` flag, your choice applies to the current session only and isn’t saved as your default; `/model` in that mode requires Claude Code v2.1.205 or later. Project and managed settings still take precedence and reapply on the next launch. An [organization default model](#organization-default-model) that your admin has configured to override user selection also reapplies on the next launch. In v2.1.144 through v2.1.152, `/model` applied to the current session only and `d` in the picker saved a default. The `--model` flag and `ANTHROPIC_MODEL` environment variable apply only to the session you launch with them. To run different models in different terminals at the same time, launch each one with its own `--model` flag rather than switching with `/model`. Prices in the `/model` picker appear when Claude Code talks to the Anthropic API, directly or through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) that proxies it, and the price on a row is the price of the model that row selects. On [third-party providers](third-party-integrations.md) such as Amazon Bedrock and on the [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md), your provider or gateway determines what you pay, so picker rows show no price. The price is a display label only; it doesn’t affect which model a row selects or what your provider bills. Before v2.1.206, [Claude Platform on AWS](claude-platform-on-aws.md) and gateway sessions showed Anthropic list prices, and a row could show the price of a different model than the one it selected. Resumed sessions started with `claude --resume`, `--continue`, or the `/resume` picker keep the model they were using when the transcript was saved. If the restored model has been retired or is excluded by [`availableModels`](#restrict-model-selection), the session falls through to the normal precedence order. On providers that use provider-specific deployment IDs rather than Anthropic model IDs, such as Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry, the transcript model isn’t restored at all and the session resolves its model through the normal precedence order. If your `model` setting is `haiku`, a session saved on a Haiku model resumes on the model that `haiku` resolves to now. For example, once `haiku` resolves to Haiku 5.5, a session saved on Haiku 4.5 resumes on Haiku 5.5. A model you pick for the new launch with `--model` or `ANTHROPIC_MODEL` still takes precedence over the restored model. As of v2.1.195, so does an [`ANTHROPIC_DEFAULT_OPUS_MODEL`](#environment-variables) family variable. [`ANTHROPIC_DEFAULT_MODEL`](#set-a-default-model-for-new-sessions) can too, under the conditions listed in its section. When 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`](env-vars.md), 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](settings.md#exceptions-to-managed-settings-precedence) says which keys and variables the host overrides. If you or your organization configure [PreModelSwitch hooks](../07-Hooks/hooks.md#premodelswitch), they run before a requested switch applies and can block it or ask you to confirm. When Claude Code can’t tell which PreModelSwitch hooks your organization’s [managed plugins](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](errors.md#model-switch-was-blocked-by-a-premodelswitch-hook) for the message and recovery. When you switch models through the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) `setModel()` method, through an app such as the [Desktop app](../16-Mobile-Desktop/desktop.md), or from a device connected through [Remote Control](remote-control.md), Claude Code checks the value at the switch:

- **Agent SDK or an app**: with Claude Code v2.1.268 or later, unless Claude Code accepts a model ID locally, as it does for your [custom model option](#add-a-custom-model-option), it confirms the ID with your provider the first time the session switches to it. The confirmation runs on every provider, and an ID your provider doesn’t offer is refused at the switch instead of failing on your next request.
- **Remote Control**: on the Anthropic API, Claude Code checks the value locally and sends no request.

See [Model is not a recognized model id](errors.md#model-is-not-a-recognized-model-id) and [Model not found](errors.md#model-not-found) for the messages. If you set the model with the `--model` flag, the `ANTHROPIC_MODEL` environment variable, or the `model` setting, Claude Code doesn’t check it up front, and a mistyped value produces [There’s an issue with the selected model](errors.md#theres-an-issue-with-the-selected-model) on the first request. When the requested model has a scheduled retirement date or is automatically remapped to a newer version, Claude Code shows a warning that names the requested model. Interactive sessions show it as a startup notice. From v2.1.182, the same warning is written to stderr in [non-interactive mode](headless.md) when using the default text output format. The check also covers a `model` set in [subagent frontmatter](../09-Agents-Patterns/sub-agents.md). The stderr warning is suppressed for `--output-format json` and `stream-json`; read the actual model from the `modelUsage` field of the [result message](headless.md#get-structured-output) instead. For example, start a session on Opus:

```python
claude --model opus
```

Then switch models from within the session:

```python
/model sonnet
```

Example settings file:

```python
{
    "permissions": {
        "allow": ["Bash(npm run lint)"]
    },
    "model": "opus"
}
```


[​](#set-a-default-model-for-new-sessions)

Set a default model for new sessions

Set `ANTHROPIC_DEFAULT_MODEL=<alias|name>` to choose the model your sessions start on by default. Requires Claude Code v2.1.236 or later. Claude Code starts a new session on the variable’s model only when none of these selects a model:

- The `--model` flag
- `ANTHROPIC_MODEL`
- A `model` value in any settings file, including the choice you save with `/model`
- An [organization default model](#organization-default-model)

A choice you save with `/model` takes precedence over the variable on later launches too. With `ANTHROPIC_MODEL` set instead, Claude Code returns to that variable’s model on the next launch, whatever you saved with `/model`. Claude Code also resolves the Default option to the variable’s model, unless an organization default model applies. When the Default option resolves to the variable’s model, the Default row in the `/model` picker shows the label Set by ANTHROPIC_DEFAULT_MODEL. Claude Code ignores the variable in these cases, and the Default option resolves as if you hadn’t set it:

- You set it to `default`, `inherit`, `opusplan`, or `haiku`
- [`enforceAvailableModels`](#enforce-the-allowlist-for-the-default-model) is on
- Your organization’s [model restrictions](#restrict-model-selection) exclude the model
- The model isn’t available to your account

When a new session would start on the variable’s model, a session you resume with `claude --resume`, `--continue`, or the `/resume` picker starts on it too. Claude Code doesn’t restore the model saved in that session’s transcript. Otherwise Claude Code doesn’t use the variable when you [resume a session](#setting-your-model).


[​](#a-new-session-starts-on-a-different-model-than-you-picked)

A new session starts on a different model than you picked

When you pick a model with `/model` and your next session starts on something else, these are the usual causes:

- **You chose it for one session.** Pressing `s` in the picker, launching with `--model`, and running `/model` in non-interactive mode all apply to the current session and leave your saved default alone.
- **Something with higher priority sets the model.** A `model` value in project or managed settings, `ANTHROPIC_MODEL` in your shell, or an [organization default](#organization-default-model) your admin set to override user choices applies again at every launch. Your `/model` choice is still saved; it’s outranked. When project or managed settings set the model, the startup header names the file.
- **Claude Code couldn’t save your choice.** `/model` writes `model` to `~/.claude/settings.json`. If you can’t write to that file, for example because another tool generates it or links it to a read-only copy, the model you chose lasts for the session and the next launch reads the old value. Set `model` in the tool that generates the file, or make the file writable. See [A change you made in Claude Code is lost in new sessions](settings.md#a-change-you-made-in-claude-code-is-lost-in-new-sessions).
- **You resumed a session.** A session you resume with `claude --resume` or `--continue` usually [keeps the model it was using](#setting-your-model) rather than your current default.


[​](#restrict-model-selection)

Restrict model selection

Administrators can use `availableModels` in [managed or policy settings](../13-Enterprise-Admin/managed-settings.md) to restrict which models users can select. Entries match a model family such as `sonnet`, a version prefix such as `claude-sonnet-4-5`, or a full model ID such as `claude-sonnet-4-5-20250929`. A version prefix also matches later model IDs that extend it with another segment, so `claude-fable-5` permits both Fable 5 and Fable 5.1, while `claude-fable-5-1` permits Fable 5.1 only. To block a model the list permits, or to make each model ID entry permit only the version it names, see [Block specific models or versions](#block-specific-models-or-versions). On platforms that embed Claude Code and set [`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`](env-vars.md), 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](settings.md#exceptions-to-managed-settings-precedence) says which keys and variables the host overrides. When `availableModels` is set, the allowlist applies everywhere a user can specify a model:

- **Main session model**: `/model`, the `--model` flag, the `ANTHROPIC_MODEL` environment variable, the `model` setting, [`ANTHROPIC_DEFAULT_MODEL`](#set-a-default-model-for-new-sessions), and the model restored when [resuming a session](#setting-your-model)
- **Alias resolution**: the `ANTHROPIC_DEFAULT_OPUS_MODEL`, `ANTHROPIC_DEFAULT_SONNET_MODEL`, `ANTHROPIC_DEFAULT_HAIKU_MODEL`, and `ANTHROPIC_DEFAULT_FABLE_MODEL` environment variables cannot redirect an allowed alias to a model outside the list
- **Fast mode**: `/fast` refuses to toggle when it would implicitly switch to an Opus model outside the list, with the message “is not in your organization’s allowed models”
- **Subagent and teammate models**: the `model` field in [subagent](../09-Agents-Patterns/sub-agents.md#choose-a-model) frontmatter, the Agent tool’s `model` parameter, [agent team](../09-Agents-Patterns/agent-teams.md#specify-teammates-and-models) teammate models, `CLAUDE_CODE_SUBAGENT_MODEL`, and, on v2.1.197 and earlier, the model picker in the `/agents` wizard
- **Skill and command models**: the `model` frontmatter in [skills and commands](../08-Plugins-Skills/skills.md)
- **Advisor model**: the configured [`advisorModel`](advisor.md) setting and the `--advisor` flag
- **Background agent model**: the model selected in the [dispatch picker](../09-Agents-Patterns/agent-view.md)

On the Anthropic API and [Claude Platform on AWS](claude-platform-on-aws.md), a model family alias, `opus`, `sonnet`, `haiku`, or `fable`, resolves to its usual model when the allowlist permits that model. When the allowlist blocks that model, Claude Code substitutes the newest version of the family that the allowlist permits and shows a notice naming both the requested and substituted models. With `["sonnet", "claude-opus-4-6"]`, for example, both `/model opus` and `--model opus` select Claude Opus 4.6, the newest permitted Opus. Before v2.1.205, an alias whose newest released version was outside the list was rejected or replaced like any other blocked selection, even when the list permitted an older version. The substitution needs a permitted version to land on: when the allowlist permits no version of the alias’s family, the alias follows the rejection and replacement behavior below like any other blocked value. Claude Code handles any other blocked selection according to where the model was set:

- **`/model`**: Claude Code rejects the switch with an error
- **`--model` flag, `ANTHROPIC_MODEL`, or the `model` setting**: Claude Code replaces the value at startup with a warning naming both the requested and substituted models, and the session starts on the default model
- **[`ANTHROPIC_DEFAULT_MODEL`](#set-a-default-model-for-new-sessions)**: Claude Code ignores the variable
- **Subagent or teammate override**: Claude Code runs the subagent or teammate on a fallback model rather than failing the request. See [Choose a model](../09-Agents-Patterns/sub-agents.md#choose-a-model) for the subagent fallback and [Specify teammates and models](../09-Agents-Patterns/agent-teams.md#specify-teammates-and-models) for the teammate fallback. In interactive sessions, Claude Code warns you when it substitutes a subagent’s model, by this fallback or by the newest-permitted-version substitution above, naming the requested and substituted models; it doesn’t report a teammate’s fallback. Where the newest-permitted-version substitution above operates, a blocked family alias follows it instead. Before v2.1.222, an alias fell back like any other blocked value on every provider
- **Skill or command override**: Claude Code ignores the override, including a blocked family alias, and the skill or command runs on the session model. A skill or command that [runs in a subagent](../08-Plugins-Skills/skills.md#run-skills-in-a-subagent) follows the subagent behavior above instead
- **`advisorModel` setting**: the advisor is disabled for the session
- **`--advisor` flag**: Claude Code exits with an error at launch. In a [background session](../09-Agents-Patterns/agent-view.md), it starts the session without the advisor instead of exiting
- **`CLAUDE_CODE_AUTO_MODE_MODEL`**: Claude Code ignores the variable and picks the model for its [auto mode classifier requests](permission-modes.md#default-classifier-model) as if you hadn’t set it

Claude Code hides excluded models from the `/model` picker. Whether a model ID you list also gets a row of its own differs by provider:

- **Anthropic API, [Claude Platform on AWS](claude-platform-on-aws.md), [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md), or an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) set through `ANTHROPIC_BASE_URL`**: an Anthropic model ID you list that has no built-in picker row appears as its own labeled row. Claude Code adds such a row for Opus, Sonnet, and Haiku versions, such as an older version that the list pins. If you set `replaceBuiltInOptions` in a [`modelPicker`](settings-reference.md#modelpicker) lineup, that row doesn’t appear. Before v2.1.199, such an ID was selectable only by typing `/model <id>`.
- **Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry**: unless a model ID you list starts with `anthropic.`, Claude Code doesn’t add a row for it, whether it’s an Anthropic model ID or a provider-specific one. [Mantle model IDs](#mantle-model-ids) carry that prefix. To show a listed version that has no built-in row, also add it to a [`modelPicker`](settings-reference.md#modelpicker) lineup, which accepts IDs in your provider’s format.

Model changes that Claude Code makes on your behalf are checked the same way:

- **[Fallback model chains](#fallback-model-chains)**: entries outside the allowlist are dropped
- **Plan-mode upgrades**: on the Anthropic API and Claude Platform on AWS, an upgrade such as [`opusplan`](#opusplan-model-setting) to an excluded model uses the newest permitted version of the upgrade family. On providers with provider-specific model IDs, and when no version is permitted, the upgrade is skipped and planning continues on the session’s model
- **[Automatic model fallback](#automatic-model-fallback)**: a fallback whose target is excluded does not run, so the flagged request ends with a refusal instead
- **[Auto mode classifier](permission-modes.md#eliminate-prompts-with-auto-mode)**: when the allowlist excludes the [default classifier model](permission-modes.md#default-classifier-model), classifier requests that would use that model run on the session model, or an Opus model in [Fable](#work-with-fable) sessions. On providers other than the Anthropic API, that Opus fallback runs on the model you set in `ANTHROPIC_DEFAULT_OPUS_MODEL` or otherwise on Opus 5, without consulting the allowlist. Requires Claude Code v2.1.210 or later
- **[Fast mode](fast-mode.md)**: enabling fast mode is refused when the model the session would run on afterward is outside the allowlist
- **Availability fallback on Amazon Bedrock and Google Cloud’s Agent Platform**: when your account loses access to a model mid-session, the switch to another model skips excluded models. The startup model checks on [Amazon Bedrock](amazon-bedrock.md#when-your-organization-enforces-a-model-allowlist) and [Google Cloud’s Agent Platform](google-vertex-ai.md#when-your-organization-enforces-a-model-allowlist) skip excluded models only when managed settings also set [`enforceAvailableModels`](#enforce-the-allowlist-for-the-default-model)

```python
{
  "availableModels": ["sonnet", "haiku"]
}
```


[​](#surface-coverage)

Surface coverage

Every surface enforces the allowlist it receives. Which delivery mechanism reaches each surface differs:

| Delivery mechanism                                                                 | CLI and IDE | Desktop local sessions | Web, mobile, and cloud sessions                                                                                                                                                                                                                                     | Agent SDK and non-interactive | Cowork                                                                                     |
|:-----------------------------------------------------------------------------------|:------------|:-----------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------|:-------------------------------------------------------------------------------------------|
| [Server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) from the admin console | Enforced    | Enforced               | Enforced, except in [Claude Tag](https://claude.com/docs/claude-tag/overview) sessions                                                                                                                                                                              | Enforced                      | Remote Cowork sessions: the server checks the model. On the user’s machine: not delivered. |
| [MDM or managed settings files](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms)     | Enforced    | Enforced               | Not delivered in Anthropic-hosted environments; in [self-hosted environments](../13-Enterprise-Admin/self-hosted-environments.md), enforced from the runner image per [how Claude Code combines managed sources](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) | Enforced                      | Enforced where deployed                                                                    |

- [Cloud sessions](claude-code-on-the-web.md), including those you start from the Desktop app, run on Anthropic-managed VMs by default: settings deployed to your device do not reach them, so deliver the allowlist through server-managed settings. Sessions your organization routes to a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) run on your own compute and also read the managed settings file in the runner image. [How Claude Code combines managed sources](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) says when that file applies. A mid-session model switch in a cloud session is rejected when the requested model is excluded by the allowlist. When the `availableModels` list in your server-managed settings is non-empty, the server rejects a request to start a cloud session at claude.ai/code or from the Desktop app on a model the list excludes.
- [Claude Tag](https://claude.com/docs/claude-tag/overview) sessions run in cloud environments but don’t receive server-managed settings; in a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md), they still read the managed settings file in the runner image. To set the model for those sessions, see [Choose the model for a scope](https://claude.com/docs/claude-tag/admins/customize#choose-the-model-for-a-scope) in the Claude Tag admin guide.
- Cowork, the agentic-work tab in the Claude Desktop app, runs its sessions on Claude Code but, by design, does not receive server-managed settings from the claude.ai admin console. When the `availableModels` list in your server-managed settings is non-empty and a user picks a model outside it, the server rejects that model for a remote Cowork session. A managed settings file applies to Cowork sessions when it is present where the session runs; remote Cowork sessions run on Anthropic-managed VMs, where a device-deployed file is not present.
- Sessions on [third-party providers](../13-Enterprise-Admin/server-managed-settings.md#platform-availability) such as Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and [Claude Platform on AWS](claude-platform-on-aws.md) do not receive server-managed settings, so deliver the allowlist through MDM or managed settings files there.
- Delivery from the admin console also requires the session to fetch with an [eligible login](../13-Enterprise-Admin/server-managed-settings.md#platform-availability) to your organization or an OAuth token issued for it. For fleets that authenticate with API keys, whether configured directly or generated by an [`apiKeyHelper`](settings-reference.md#apikeyhelper) script, deliver the allowlist through MDM or managed settings files.
- The Desktop Code tab also hosts [SSH sessions](../16-Mobile-Desktop/desktop.md#ssh-sessions), which read the managed settings file from the remote host they run on. See [Desktop managed settings](../16-Mobile-Desktop/desktop.md#managed-settings).
- The model pickers on claude.ai and in the Desktop app hide or grey out models excluded by your organization’s allowlist. The picker state is a convenience for users; it doesn’t enforce the allowlist.


[​](#default-model-behavior)

Default model behavior

With the default prefix matching, `availableModels` on its own leaves the Default option on the system’s [runtime default](#default-model-setting) for the account until you also set [`enforceAvailableModels`](#enforce-the-allowlist-for-the-default-model). If that default is a model you intend to restrict, set `enforceAvailableModels` as well, or [block that model](#block-specific-models-or-versions). With `availableModels: []`, named model selections are blocked and `enforceAvailableModels` has no effect.


[​](#enforce-the-allowlist-for-the-default-model)

Enforce the allowlist for the Default model

Set `enforceAvailableModels: true` alongside a non-empty `availableModels` in managed settings to extend the allowlist to the Default option. This requires Claude Code v2.1.175 or later.

```python
{
  "availableModels": ["sonnet", "haiku"],
  "enforceAvailableModels": true
}
```

For a member with no model [recorded on their account](#setting-your-model), the Default option resolves to the account-type default, or to the [organization default model](#organization-default-model) when an admin has set one. When that model is not in the allowlist, the Default option instead resolves to the first `availableModels` entry that names an allowed, available model, and the `/model` picker’s Default row shows that model. This applies everywhere the default is reached: session startup, selecting Default in `/model`, the `"default"` keyword in [fallback model chains](#fallback-model-chains), and the fallback used when an excluded selection is dropped. A model recorded on a member’s account is checked against `availableModels` too; [Setting your model](#setting-your-model) describes how the Default option treats it. `enforceAvailableModels` remaps the Default option only when `availableModels` is non-empty. When `availableModels` is non-empty but no entry resolves to an allowed and available model, enforcement is skipped with a warning visible only under `--debug`. Keep at least one guaranteed-available entry in the list to avoid this. Deploy both keys together in the highest-ranked managed source you deliver. By default Claude Code reads only that source, so a pair placed in a managed settings file is ignored when the admin console delivers any settings; under the opt-in merge in [how Claude Code combines managed sources](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources), Claude Code still ignores a `modelOverrides` map from a source ranked below the one that sets `availableModels`.


[​](#control-the-model-users-run-on)

Control the model users run on

The `model` setting is an initial selection, not enforcement. It sets which model is active when a session starts, but users can still open `/model` and pick Default, which resolves to the system’s [runtime default](#default-model-setting) regardless of what `model` is set to, unless [`enforceAvailableModels`](#enforce-the-allowlist-for-the-default-model) or the [keys that block specific versions](#block-specific-models-or-versions) apply to it. To fully control the model experience, combine these settings:

- **`availableModels`**: restricts which named models users can switch to
- **`enforceAvailableModels`**: extends the `availableModels` allowlist to the Default option, so Default cannot resolve to a model outside the list
- **`deniedModels`** and **`availableModelsMatch`**: [block specific versions](#block-specific-models-or-versions) that an `availableModels` entry would otherwise permit
- **`model`**: sets the initial model selection when a session starts
- **`ANTHROPIC_DEFAULT_SONNET_MODEL`** / **`ANTHROPIC_DEFAULT_OPUS_MODEL`** / **`ANTHROPIC_DEFAULT_HAIKU_MODEL`** / **`ANTHROPIC_DEFAULT_FABLE_MODEL`**: control what the `sonnet`, `opus`, `haiku`, and `fable` aliases resolve to, and which version the [account-type default](#default-model-setting) uses

This example starts users on Sonnet 4.5, limits the picker to Sonnet and Haiku, and ensures Default resolves to a model on the allowlist rather than the tier default:

```python
{
  "model": "claude-sonnet-4-5",
  "availableModels": ["claude-sonnet-4-5", "haiku"],
  "enforceAvailableModels": true,
  "env": {
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-4-5"
  }
}
```

Without `enforceAvailableModels` or the `env` block, a user who selects Default in the picker gets the [runtime default](#default-model-setting) rather than the version pinned in `model`. The two settings cover different scopes: `enforceAvailableModels` makes Default obey the allowlist, while the `env` block pins which version a permitted alias such as `sonnet` resolves to. Use `enforceAvailableModels` alone when restricting model families is enough; add the `env` block when you also need to pin a specific version.


[​](#merge-behavior)

Merge behavior

When the managed settings Claude Code applies define `availableModels`, that list alone applies, apart from a [host platform that supplies its own](settings.md#exceptions-to-managed-settings-precedence): entries in user, project, or local settings cannot extend it, and Claude Code never merges `availableModels` across managed sources either; [how Claude Code combines managed sources](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) says which source’s list applies. Otherwise, lists from user, project, and local settings are [concatenated and deduplicated](settings.md#settings-precedence) like other array settings. Before Claude Code v2.1.175, entries from lower-precedence scopes merged into the managed list instead of being replaced by it. Within the effective list, an entry naming a specific model in a family, whether a version prefix or a full model ID, disables that family’s wildcard entry: `["sonnet", "claude-sonnet-4-5"]` allows only Sonnet 4.5 versions, not every Sonnet model.


[​](#mantle-model-ids)

Mantle model IDs

Entries in `availableModels` that start with `anthropic.` are added to the `/model` picker as custom options. This is an exception to the alias matching described in [Pin models for third-party deployments](#pin-models-for-third-party-deployments). With the [Amazon Bedrock Mantle endpoint](amazon-bedrock.md#use-the-mantle-endpoint) enabled, Claude Code routes the entries that match the Mantle format to that endpoint. The setting still restricts the picker to listed entries, and a Mantle ID embeds a family name, so it counts as a specific entry and disables that family’s wildcard: alongside any Mantle IDs, list the version prefixes or full IDs you want to keep selectable. See [Merge behavior](#merge-behavior).


[​](#block-specific-models-or-versions)

Block specific models or versions

An `availableModels` entry such as `claude-opus-5` also permits later releases that extend it, such as Opus 5.5, as soon as Claude Code supports them. Two managed settings let you hold a release back, and both require Claude Code v2.1.283 or later:

- [`deniedModels`](settings-reference.md#deniedmodels): list the models to block. A listed model is blocked even when `availableModels` permits it, and the key also works with no allowlist at all. A release that no entry blocks stays permitted
- [`availableModelsMatch`](settings-reference.md#availablemodelsmatch): set it to `"exact"` so that each model ID in `availableModels` permits only the version it names. A newer version of a listed model ID then stays blocked until you add it to the list

Earlier versions ignore both keys, so also set [`requiredMinimumVersion`](settings-reference.md#requiredminimumversion) to keep those versions from starting. This example permits Opus and Sonnet models and blocks Opus 5.5 in every spelling, including dated and provider-specific IDs:

```python
{
  "availableModels": ["opus", "sonnet"],
  "deniedModels": ["claude-opus-5-5"]
}
```

A blocked model, whether `deniedModels` names it or an `"exact"` list omits it, is treated as a blocked selection everywhere [the allowlist applies](#restrict-model-selection). It is hidden from the `/model` picker, and `/model <name>` rejects it. If you name a blocked model ID with `--model`, `ANTHROPIC_MODEL`, or the `model` setting, Claude Code drops it at startup and resolves the Default option instead. If a [hook](../07-Hooks/hooks.md) or background request names a model that `deniedModels` blocks, such as an agent hook’s `model` field, that request runs on the session’s model instead. The Default option follows both keys too, whether or not you set [`enforceAvailableModels`](#enforce-the-allowlist-for-the-default-model). If you set it with a non-empty `availableModels`, a blocked default counts as a model outside the allowlist. Otherwise, a Default option that would resolve to a blocked model steps down in this order:

1.  The newest permitted version of the same family
2.  The newest permitted model of each lower-cost family in turn: Sonnet, then Haiku
3.  The first `availableModels` entry that names a permitted model

If none of those is permitted, a session starting on the Default option [refuses to start](errors.md#managed-settings-block-the-default-model) with an error that names the key to fix. An `"exact"` list affects the Default option only when the managed `availableModels` list names at least one model or family. Claude Code reads both keys from managed settings only. If you set either one in user, project, or local settings or with `--settings`, Claude Code ignores it with a warning.


[​](#organization-model-restrictions)

Organization model restrictions

Organization admins on Claude Enterprise plans restrict which models members can run by disabling individual models in the claude.ai admin console. This restriction is delivered with the account’s entitlements when Claude Code authenticates, separate from any `availableModels` list in settings, and the server enforces the same restriction independently when a session is created. Requires Claude Code v2.1.187 or later. The restriction applies when a member signs in or uses their own API key. Organization-scoped credentials, such as organization service keys, are not tied to a user, so the restriction does not apply to them. The Claude Console has no model restriction control. Organizations without a Claude Enterprise plan, including those whose members authenticate through the Anthropic API, restrict models with [`availableModels`](#restrict-model-selection) in [managed settings](../13-Enterprise-Admin/managed-settings.md) instead, adding [`enforceAvailableModels`](#enforce-the-allowlist-for-the-default-model) to cover the Default option. [Surface coverage](#surface-coverage) says how each surface receives and enforces these settings. A restricted model is hidden from the `/model` picker. Selecting it by name with `--model`, the `ANTHROPIC_MODEL` environment variable, or the `model` setting shows the notice `Model "<name>" is restricted by your organization's settings. Using <model> instead.` and the session starts on an allowed model. Typing `/model <name>` for a restricted model is rejected with `Model '<name>' is restricted by your organization's settings. Run /model to choose a different model.` and the session keeps its current model. A [model family alias](#restrict-model-selection) such as `opus` resolves to its usual model when the organization permits it. When the organization restricts that model, Claude Code substitutes the newest version of the family that the organization permits, with the same substitution notice. `/model <alias>` is rejected only when every version of its family is restricted; an alias set with `--model`, `ANTHROPIC_MODEL`, or the `model` setting is still replaced at startup in that case. Before v2.1.205, a family alias was substituted or rejected based on its newest released version alone, even when an older version was allowed. Restrictions apply org-wide or per role:

- Disabling a model at the organization level removes it for every member.
- Role-level access grants different models to different custom roles, and a member who holds several roles can use any model that one of their roles grants.
- Haiku models are always available and can’t be disabled, so every member keeps at least one usable model.
- An access change takes effect on new requests within about a minute; the `/model` picker reflects it the next time a session starts.

Both restrictions apply together: a model is selectable only when it is permitted by `availableModels` and not restricted by the organization. Organization restrictions reach sessions on the Anthropic API and [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) deployments only; on any other provider, use `availableModels` instead.


[​](#organization-default-model)

Organization default model

Organization admins on Claude Enterprise plans can set a default model for Claude Code members from the claude.ai admin console, for the whole organization or per custom role. When one is set, the Default option resolves to that model. Requires Claude Code v2.1.196 or later. The Default row in the `/model` picker shows the organization default’s name with the label Org default. The label reads Org default whether the admin set the default for the whole organization or for your role. A role default covers members of that custom role and takes precedence over the organization-wide default; when several of your roles set different defaults, the most capable model applies. The organization default is a starting point, not a restriction. These selections take precedence over it:

- the `--model` flag and the `ANTHROPIC_MODEL` environment variable
- a `model` value in [managed settings](../13-Enterprise-Admin/managed-settings.md) or supplied through `--settings`
- a `model` value in your user, project, or local settings, including a model you save with `/model`

Admins can also configure the organization default to override user selection. With override on, it takes precedence over the `model` value in user, project, and local settings, so a model you save with `/model` applies for the current session and the organization default returns on the next launch. When your selection differs, `/model` shows `Your organization's default (<model>) applies on restart`. The `--model` flag, `ANTHROPIC_MODEL`, managed settings, and `--settings` still take precedence even with override on. To limit which models members can select, use [organization model restrictions](#organization-model-restrictions) or [`availableModels`](#restrict-model-selection) instead. Claude Code reads the organization default once at startup, so a default the admin changes mid-session takes effect on the next launch. When the organization default doesn’t override user selection, the first interactive launch after the admin changes it clears the `model` key from your user settings once, so the new default applies. It changes nothing else in the file, and a model you save with `/model` after that launch is kept. The organization default passes through these restriction checks before it is adopted:

- With the default prefix matching, [`availableModels`](#restrict-model-selection) on its own doesn’t apply to the organization default, so an organization default outside the allowlist still applies. When [`enforceAvailableModels`](#enforce-the-allowlist-for-the-default-model) is also set, an organization default outside the allowlist is remapped to the first allowlist entry as well
- an organization default that [organization model restrictions](#organization-model-restrictions) deny for your account is replaced by the newest allowed model in its family, or a lower-cost family when every version of it is restricted
- for an organization default that `deniedModels` or an `"exact"` list blocks, see [Block specific models or versions](#block-specific-models-or-versions)
- an organization default that isn’t available to your account at all is skipped, and the Default option resolves as it would [without an organization default](#default-model-setting)

As of v2.1.199, when the organization default is a different model family from your account type’s usual default, the `/model` picker keeps a separate row for that usual family, so you can still switch to it for a session. In v2.1.196 through v2.1.198 that row is missing from the picker. The organization default reaches only sessions authenticated with the Anthropic API. To set a default anywhere else, including [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) deployments, use the `model` key in [managed settings](../13-Enterprise-Admin/managed-settings.md) instead.


[​](#organization-effort-limits)

Organization effort limits

Your organization can cap the [effort level](#adjust-effort-level) in two ways. On a Claude Enterprise plan, organization admins set per-role effort limits, described below. On any plan and any provider, including Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry, the [`maxEffortLevel`](settings-reference.md#maxeffortlevel) managed setting caps effort on the client instead. When both apply to a model, the lower cap applies. Organization admins on Claude Enterprise plans can set a maximum [effort level](#adjust-effort-level) per model for each custom role, alongside role-level [organization model restrictions](#organization-model-restrictions). Requires Claude Code v2.1.195 or later.

- Levels above the cap aren’t offered in the `/effort` picker, and naming a higher level with `--effort` or `/effort` runs at the cap instead. If you start a plain-text `--print` run with `--effort` above the cap, a warning on stderr names the requested and applied levels. In interactive sessions, with `json` or `stream-json` output, or in background agents, that warning goes to the [debug log](errors.md#configuration-warnings) instead.
- Caps are per model, so switching models can change which levels are available.
- When several of your roles grant the same model, the least restrictive cap applies.

Effort limits are delivered together with [organization model restrictions](#organization-model-restrictions) and reach the same sessions.


[​](#special-model-behavior)

Special model behavior


[​](#default-model-setting)

`default` model setting

The behavior of `default` depends on your account type:

- **Pro, Max, Team, Enterprise, and Anthropic API**: defaults to Opus 5.5
- **Claude Platform on AWS, Amazon Bedrock, and Google Cloud’s Agent Platform**: defaults to Opus 5.5
- **Microsoft Foundry**: defaults to Sonnet 4.5

Before v2.1.280, `default` resolved to Sonnet 5 on Pro and Team Standard, and to Opus 5 on Max, Team Premium, Enterprise, the Anthropic API, Claude Platform on AWS, Amazon Bedrock, and Google Cloud’s Agent Platform from v2.1.219. Before v2.1.219, `default` resolved to Opus 4.8 on the Anthropic API, Max, Team Premium, and Enterprise pay-as-you-go from v2.1.154, and on Claude Platform on AWS, Amazon Bedrock, and Google Cloud’s Agent Platform from v2.1.207. Before v2.1.207, `default` resolved to Opus 4.7 on Claude Platform on AWS and to Sonnet 4.5 on Amazon Bedrock and Google Cloud’s Agent Platform. When an admin has set an [organization default model](#organization-default-model), `default` resolves to that model instead of the account-type default above. Requires Claude Code v2.1.196 or later. `default` can also resolve to the model you set with [`ANTHROPIC_DEFAULT_MODEL`](#set-a-default-model-for-new-sessions), under the conditions listed in its section, or to the model [recorded on your account](#setting-your-model). When nothing is recorded on your account, managed settings [enforce the allowlist for the Default model](#enforce-the-allowlist-for-the-default-model), and the account-type default is not in `availableModels`, `default` resolves to the enforced Default instead of the account-type default above. When an organization default and enforcement both apply, the organization default replaces the account-type default first and enforcement then applies to it: an allowlisted organization default is kept, while one outside the list resolves to the enforced Default. Fable models are not the account-type default on any plan or provider. Choosing one with `/model` saves it as the selected model in your user settings, so later sessions start on it. For the one-time change Claude Code makes to a saved Fable 5 selection in v2.1.257, see [Work with Fable](#work-with-fable).


[​](#opusplan-model-setting)

`opusplan` model setting

The `opusplan` model alias provides an automated hybrid approach:

- **In plan mode**: uses `opus` for complex reasoning and architecture decisions
- **In execution mode**: automatically switches to `sonnet` for code generation and implementation

This pairs Opus’s reasoning for planning with Sonnet’s efficiency for execution. The plan-mode Opus phase uses the same context window as the `opus` model setting, and the execution phase uses the same window as `sonnet`. When `opus` and `sonnet` resolve to models that run with the [1M context window](#extended-context) by default, as the current models do on the Anthropic API, both phases run with it. To request 1M context for both phases where they don’t, [set the model](#setting-your-model) to `opusplan[1m]`, for example with `/model opusplan[1m]`. Setting it with `/model` requires Claude Code v2.1.265 or later; on earlier versions, use the `--model` flag or the `model` setting instead. When [`availableModels`](#restrict-model-selection) excludes the newest Opus but permits an older version, for example `["sonnet", "claude-opus-4-6"]`, `opusplan` uses the newest permitted Opus for planning and stays on Sonnet only when every Opus is excluded. A Haiku session that would normally upgrade to Sonnet in plan mode likewise uses the newest permitted Sonnet, and stays on Haiku only when every Sonnet is excluded. Before v2.1.205, plan mode stayed on the session’s model whenever the newest version of the upgrade family was excluded, even when the allowlist permitted an older one. The substitution of an older permitted version applies on the Anthropic API and [Claude Platform on AWS](claude-platform-on-aws.md). On Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and Mantle, whose deployments use provider-specific model IDs, plan mode stays on the session’s model whenever the upgrade model is excluded. For a hybrid approach where Claude decides mid-task when to consult a second model rather than switching at the plan boundary, see the [advisor tool](advisor.md).


[​](#fallback-model-chains)

Fallback model chains

When the primary model is overloaded, unavailable, or returns another non-retryable server error, Claude Code can switch to a fallback model instead of failing the request. Authentication, billing, rate-limit, request-size, and transport errors, and a [denial by your organization’s policy check](errors.md#automatic-retries), never trigger a switch; those follow their normal retry and error handling. It does switch when [Amazon Bedrock](amazon-bedrock.md#when-a-model-is-disabled-mid-session) or [Google Cloud’s Agent Platform](google-vertex-ai.md#when-a-model-is-disabled-mid-session) refuses a model your account can’t invoke, which Claude Code treats as the model being unavailable rather than as an authentication error. Configure one or more fallback models and Claude Code tries them in order, showing a notice when it switches. The switch lasts for the current turn only, so your next message tries the primary model first again. Claude Code caps chains at three models after duplicate removal and ignores extra entries. Set a chain for one session with the `--fallback-model` flag, which accepts a comma-separated list:

```python
claude --fallback-model sonnet,haiku
```

To persist a chain across sessions, set `fallbackModel` in [settings](settings.md) as an array:

```python
{
  "fallbackModel": ["claude-sonnet-5", "claude-haiku-4-5"]
}
```

The `--fallback-model` flag takes precedence over the `fallbackModel` setting. Each entry accepts a model name or alias, and `"default"` expands to the default model. Claude Code doesn’t confirm the chain at startup and `/status` doesn’t display it. The notice shown when a switch happens is the first visible sign that a fallback is configured. When a request fails over, Claude Code tries each entry in order until one accepts it. An entry that can’t be reached either, such as a retired model pinned in settings, fails over to the next one the same way. Claude Code removes two kinds of entry before that walk starts:

- **Outside the allowlist**: Claude Code drops any entry not permitted by [`availableModels`](#restrict-model-selection) when it reads the chain.
- **Smaller context window during compaction**: the chain also covers [compaction](context-window.md#what-survives-compaction), but Claude Code won’t fall back to a model with a smaller context window than the primary’s, since summarizing there would cut off part of the conversation first. If every fallback is smaller, compaction shows the original error and you can retry.

Claude Code also applies the chain to [subagents](../09-Agents-Patterns/sub-agents.md). When a subagent’s request fails over, Claude Code tries your configured fallback models in order, and the subagent continues on the model that accepts the request. Your session’s model is unchanged. Before v2.1.247, a failure the chain covers ended the subagent instead.


[​](#automatic-model-fallback)

Automatic model fallback

This section covers content-based fallback from Fable models, Opus 5.5, Sonnet 5.5, and Opus 5. For availability-based fallback when a model is overloaded or unavailable, see [Fallback model chains](#fallback-model-chains). Fable models, Opus 5.5, Sonnet 5.5, and Opus 5 run with safety classifiers, which most often flag cybersecurity and biology content. For those two categories, the fallback model depends on which model refused:

- **Fable 5.1, Fable 5, and Opus 5.5**: biology-flagged requests re-run on Opus 5, and cybersecurity-flagged requests re-run on Opus 4.8.
- **Sonnet 5.5**: cybersecurity-flagged requests re-run on Sonnet 5. Biology-flagged requests end with a refusal instead, because Sonnet 5.5 has no biology fallback model.
- **Opus 5**: cybersecurity-flagged requests re-run on Opus 4.8. Biology-flagged requests end with a refusal instead, because Opus 5 runs its own biology classifiers with no fallback model.

On Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry, Claude Code resolves these targets through your deployment’s model IDs instead. See [Enable fallback on Bedrock, Agent Platform, and Foundry](#enable-fallback-on-bedrock-agent-platform-and-foundry). When Claude Code switches a flagged request to the fallback model for its category, it re-runs the request on that model. In your main conversation, it shows a notice in the transcript. To be asked first, see [Ask before switching](#ask-before-switching). After a fallback, the session continues on the fallback model. To return to your original model, run [`/model`](#setting-your-model). Category-based fallback requires Claude Code v2.1.219 or later. Before v2.1.219, every flagged Fable 5 request re-ran on your provider’s default Opus model, and Opus 5 was not a fallback source. The fallback model is checked against [`availableModels`](#restrict-model-selection). When it is blocked, no fallback occurs. The refusal is shown as a normal error and the session’s model is unchanged.


[​](#effort-level-after-a-fallback)

Effort level after a fallback

When Claude Code switches your session to the fallback model, it keeps the effort level the flagged request ran at. For example, a session on Opus 5.5 at its default `medium` that falls back to Opus 4.8 stays at `medium`, although Opus 4.8 defaults to `high`. A different level applies in cases such as these:

- **Your own change**: once you choose an effort level, pick a model in `/model`, or resume the session later, the flagged request’s level no longer carries over.
- **Skill effort**: a level that a skill’s `effort` frontmatter set for the flagged request applies to that turn, and later turns run at the level the [effort resolution order](#adjust-effort-level) gives the fallback model.

In the session, run `/effort status` to see the level in effect, or `/effort` to change it.


[​](#check-what-triggered-fallback)

Check what triggered fallback

Fallback can trigger on the first request of a session, before you send anything unusual, because the first request carries workspace context such as your CLAUDE.md content and git status. A repository that contains security or biology material can trip the classifier on that context alone. To check whether customizations are the trigger, start a session with `claude --safe-mode`, which disables customizations such as CLAUDE.md, skills, MCP servers, and hooks. Git status and directory names are not customizations and are still included.


[​](#ask-before-switching)

Ask before switching

To decide what happens each time a request is flagged, run `/config`, select **Switch models when a message is flagged**, and choose **Ask each time**. You can also set [`switchModelsOnFlag`](settings-reference.md#switchmodelsonflag) to `false` in your settings file. Claude Code then pauses at a flagged request that would switch models and gives you two options: switch to the fallback model, or edit the prompt and retry. The first time a flagged request would switch models in an interactive session, Claude Code may ask whether to switch automatically from then on. It asks only if you haven’t set `switchModelsOnFlag`, and it saves your choice as that key in your user settings. If you choose to stay on the current model instead, the saved value is `false`, the same as **Ask each time**. If you dismiss the question, Claude Code saves nothing and asks again the next time a flagged request would switch models. When you’ve chosen **Ask each time**, some cases behave differently:

- When the flagged category has no fallback model, such as a biology flag on Opus 5 or Sonnet 5.5, Claude Code doesn’t show the prompt and the request ends with the refusal.
- If both models flag the same request, you can edit the prompt and retry, or start a new session.
- In [cloud sessions](claude-code-on-the-web.md) on the mobile app, editing and retrying is not supported. Switch models, or continue the session from a desktop browser or the desktop app.
- In [non-interactive mode](cli-reference.md#cli-flags) and SDK integrations that can’t show the prompt, a flagged request ends the turn with a refusal instead.
- In a [subagent](../09-Agents-Patterns/sub-agents.md), Claude Code doesn’t show the prompt, and a flagged request that would switch models re-runs on the fallback model.
- When the fallback target is blocked by [`availableModels`](#restrict-model-selection), Claude Code doesn’t show the prompt. The flagged request ends with the refusal, the same as automatic fallback when the target is blocked.


[​](#enable-fallback-on-bedrock-agent-platform-and-foundry)

Enable fallback on Bedrock, Agent Platform, and Foundry

On [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), and [Microsoft Foundry](microsoft-foundry.md), model IDs are provider-specific, so automatic fallback only operates when Claude Code can identify each model involved:

- Claude Code must recognize the current model as a fallback source. Fable 5.1 and Fable 5 are recognized when the model ID contains `claude-fable-5`, matches the value of `ANTHROPIC_DEFAULT_FABLE_MODEL`, or is mapped with [`modelOverrides`](#override-model-ids-per-version). Opus 5.5, Sonnet 5.5, and Opus 5 are recognized by their provider model ID or a [`modelOverrides`](#override-model-ids-per-version) mapping.
- An Opus target must resolve in your deployment, whichever model refused: set `ANTHROPIC_DEFAULT_OPUS_MODEL`, or keep an Opus 4.8 entry in the provider’s model list. Without one, fallback stays off for every source model, including Sonnet 5.5, and flagged requests end with a refusal.
- The flagged category’s fallback model must resolve in your deployment. From a Fable model, Opus 5.5, or Opus 5, if you set `ANTHROPIC_DEFAULT_OPUS_MODEL`, flagged requests re-run on that model for every category that has a fallback; a biology flag on Opus 5 still ends with a refusal. If you don’t set it, cybersecurity-flagged requests re-run on the Opus 4.8 entry, and biology-flagged requests from a Fable model or Opus 5.5 on an Opus 5 entry. From Sonnet 5.5, cybersecurity-flagged requests re-run on the model you set in `ANTHROPIC_DEFAULT_SONNET_MODEL`, or on a Sonnet 5 entry in the provider’s model list if you don’t set it.

If either model can’t be identified, Claude Code doesn’t switch. The flagged request ends with a refusal message, and you can switch models with [`/model`](#setting-your-model) and retry. To make both models identifiable, set the pins for your source model:

- **Fable models**: set `ANTHROPIC_DEFAULT_FABLE_MODEL` to your Fable model ID so Claude Code recognizes it as a fallback source.
- **Every source model**: set `ANTHROPIC_DEFAULT_OPUS_MODEL` to an Opus model ID to turn fallback on and give the flagged categories a target. A pin that names a model outside the Opus family, or the model that refused, leaves the refusal standing.
- **Sonnet 5.5**: in addition to the Opus pin, set `ANTHROPIC_DEFAULT_SONNET_MODEL` or keep a Sonnet 5 entry in the provider’s model list to supply the model the request re-runs on. A Sonnet pin that names a model outside the Sonnet family, or Sonnet 5.5 itself, leaves the refusal standing.

The fallback model must also have a context window at least as large as the session’s, or Claude Code doesn’t switch and the flagged request ends with the same refusal. On these providers the source models run with the [1M context window](#extended-context) by default. Pin a model that also does, such as Opus 4.8 in `ANTHROPIC_DEFAULT_OPUS_MODEL` or Sonnet 5 in `ANTHROPIC_DEFAULT_SONNET_MODEL`, by an ID Claude Code [can match to that model](#pin-models-for-third-party-deployments).


[​](#security-research-and-biology-workloads)

Security research and biology workloads

Workloads in offensive security or biology, including penetration testing, Capture the Flag (CTF) exercises, and biology-adjacent codebases, trigger fallback frequently, often on the first request. For substantive biology work on Fable 5.1, Fable 5, or Opus 5.5, the first flagged request that switches models moves the session to Opus 5, and later biology-flagged requests end in refusals there, because Opus 5 has no biology fallback. On Opus 5 and Sonnet 5.5, you get those refusals from the first flagged request. This is expected routing for these domains, not an account flag. If your organization needs Fable-class capability for this work, ask your Anthropic account team about trusted access programs.


[​](#adjust-effort-level)

Adjust effort level

[Effort levels](../04-API-Reference/Guides/build-with-claude-effort.md) control adaptive reasoning, which lets the model decide whether and how much to think on each step based on task complexity. Lower effort is faster and cheaper for straightforward tasks, while higher effort provides deeper reasoning for complex problems. The available effort levels depend on the model. Models not listed here do not support effort:

| Model                                                                     | Levels                                  |
|:--------------------------------------------------------------------------|:----------------------------------------|
| Fable 5.1 and Fable 5                                                     | `low`, `medium`, `high`, `xhigh`, `max` |
| Opus 5.5, Sonnet 5.5, Haiku 5.5, Opus 5, Sonnet 5, Opus 4.8, and Opus 4.7 | `low`, `medium`, `high`, `xhigh`, `max` |
| Opus 4.6 and Sonnet 4.6                                                   | `low`, `medium`, `high`, `max`          |

If you set a level the active model does not support, Claude Code falls back to the highest supported level at or below the one you set. For example, `xhigh` runs as `high` on Opus 4.6. Your organization or your own settings can also cap the levels a model offers; see [Organization effort limits](#organization-effort-limits). Claude Code resolves the session’s effort level in this order, taking the first that applies:

1.  An explicit choice: the [`CLAUDE_CODE_EFFORT_LEVEL`](env-vars.md#variables) environment variable, launching with `--effort`, or `/effort` in the session ([a non-interactive `/effort` has narrower effect](#non-interactive-effort))
2.  Your settings: the level you saved for the model or an [`effortLevel`](settings-reference.md#effortlevel) key, with the precedence between them and across settings files stated at [`modelSettings`](settings-reference.md#modelsettings)
3.  The model’s default effort: `high` on every model that supports effort, except that Opus 5.5, Sonnet 5.5, and Haiku 5.5 default to `medium`, Opus 4.7 defaults to `xhigh`, and, when your organization sets a default effort level for its [organization default model](#organization-default-model), that level is the default when you run that model

After an automatic model fallback, see [Effort level after a fallback](#effort-level-after-a-fallback) for the level that applies. Opus 5.5 starts at `medium` unless one of the sources above sets a level for it, and a top-level `effortLevel` in your user settings file doesn’t count for Opus 5.5. That key is the older form `/effort` wrote before Claude Code saved levels per model: it keeps applying where it applied before, on Opus 5, Fable 5.1, and earlier models, while Opus 5.5 and models released after it start at their own default until you choose a level for them with `/effort` or the `/model` picker. A top-level `effortLevel` in project, local, or managed settings, or one passed with `--settings`, applies to every model. When you set `low`, `medium`, `high`, or `xhigh` in an interactive session on your machine, you choose how long it lasts by how you confirm it:

- `Enter` in the `/effort` slider or the `/model` picker, or a level typed after `/effort`: save the level as your default and apply it in later sessions
- `s` in the `/effort` slider or the `/model` picker: apply the level to this session only. Requires Claude Code v2.1.257 or later

Claude Code saves the level per model, under the [`modelSettings`](settings-reference.md#modelsettings) key in your user settings, so each model keeps its own saved level. `max` is the deepest reasoning level. Unless you set it through the `CLAUDE_CODE_EFFORT_LEVEL` environment variable, Claude Code applies `max` to the current session only.

A level you pick from the effort control on a phone or browser connected through [Remote Control](remote-control.md#what-connected-devices-see) applies to that session only.

When you set a level with `/effort` in a [`-p` run](headless.md), Claude Code applies it to that session only and doesn’t save it as your default. The `/effort` slider also has an **Ultracode** toggle. Ultracode is a Claude Code setting rather than a model effort level: with it on, Claude orchestrates [dynamic workflows](workflows.md) for substantive tasks, at whichever effort level the session runs at. For where it can be set persistently, see the [`ultracode`](settings-reference.md#ultracode) setting. Turning ultracode on or off with `/effort` or the `ultracode` setting leaves the effort level unchanged. The `--effort ultracode` flag and the Agent SDK `effortLevel: "ultracode"` value turn it on and also set the level to `xhigh`. Picking a level in the `/effort` slider or the `/model` picker leaves ultracode as it was. You can turn on ultracode through any of the following:

- **`/effort`**: run `/effort ultracode` to turn it on for the current session or `/effort ultracode off` to turn it off. In the `/effort` slider, press `Tab` to flip the **Ultracode** toggle, then `Enter` to apply it
- **`--effort` flag**: launch with `claude --effort ultracode`, which starts the session at `xhigh` effort with ultracode on
- **`ultracode` setting**: set [`"ultracode": true`](settings-reference.md#ultracode) in a settings file, with `--settings`, or in an Agent SDK control request. An [`applyFlagSettings()`](../05-Agent-SDK/agent-sdk-typescript.md#applyflagsettings) request also accepts `effortLevel: "ultracode"`, which turns it on and sets the effort level to `xhigh`

The `/effort ultracode off` form, the slider toggle, and keeping ultracode on at effort levels other than `xhigh` require Claude Code v2.1.284 or later. Before v2.1.284, turning on ultracode set the session to `xhigh` effort, picking another level turned it off, and an effort cap below `xhigh` made it unavailable. Passing `ultracode` to the `--effort` flag or the Agent SDK `effortLevel` value requires Claude Code v2.1.203 or later. Before v2.1.203, `--effort ultracode` printed `Unknown --effort value 'ultracode'` and the session started at the default effort. The persisted `effortLevel` setting and the `CLAUDE_CODE_EFFORT_LEVEL` environment variable don’t accept `ultracode`. If `CLAUDE_CODE_EFFORT_LEVEL` or an [effort cap](#organization-effort-limits) sets the session’s level, ultracode stays on at that level. Ultracode is unavailable when:

- [Workflows are turned off](workflows.md#turn-workflows-off)
- The model doesn’t support `xhigh` effort

In those cases `--effort ultracode` starts the session with ultracode off, at the highest effort level the model and any cap allow, up to `xhigh`.


[​](#choose-an-effort-level)

Choose an effort level

Each level trades token spend against capability. The default suits most coding tasks; adjust when you want a different balance.

| Level       | When to use it                                                                                                                                                                                                                                                                                |
|:------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `low`       | Quick exchanges where you review each result, such as brainstorming, a first sketch, or a small change like a rename                                                                                                                                                                          |
| `medium`    | The default on Opus 5.5, Sonnet 5.5, and Haiku 5.5. On Opus 5.5 and Sonnet 5.5, it fits day-to-day engineering work with a clear scope, such as implementing a new feature. On models with a higher default, reduces token usage for cost-sensitive work that can trade off some intelligence |
| `high`      | Work where verification matters or edge cases are likely, such as fixing a bug in an existing codebase. The default on every model except Opus 5.5, Sonnet 5.5, Haiku 5.5, and Opus 4.7                                                                                                       |
| `xhigh`     | Deeper reasoning at higher token spend. The default on Opus 4.7                                                                                                                                                                                                                               |
| `max`       | Hard problems you want Claude to work through without you, such as finding security vulnerabilities. `max` may show diminishing returns and is prone to overthinking, so test before adopting it broadly                                                                                      |
| `ultracode` | A Claude Code setting rather than a level: plans a [dynamic workflow](workflows.md) for each substantive task at any effort level                                                                                                                                                       |

In tests on Opus 5.5 and Fable 5.1, Claude at a higher level tested more edge cases and verified more of its work before answering. It also made more choices on its own. At a lower level, Claude returned a starting point sooner, which fits work where you review each result and steer the next step. To see the same tasks run at each level, read [Using Claude Code: Spending your effort](https://claude.dev/blog/spending-your-effort/) on the blog. The effort scale is calibrated per model, so the same level name does not represent the same underlying value across models. Opus 5.5 [defaults to `medium`](#adjust-effort-level), one level below Opus 5’s default of `high`. In Anthropic’s testing, Opus 5.5 at `medium` matches or exceeds Opus 5 at `high` on coding and knowledge-work evaluations. At a given level, Opus 5.5 tends to think more per turn than Opus 5. When you move from Opus 5 to Opus 5.5, start at `medium` rather than carrying over the level you used on Opus 5. To test levels against your own work, see [Calibrate effort](../10-Prompting-Guides/build-with-claude-prompt-engineering-prompting-claude-opus-5-5.md#calibrate-effort) in the Opus 5.5 prompting guide.


[​](#use-ultrathink-for-one-off-deep-reasoning)

Use ultrathink for one-off deep reasoning

Include `ultrathink` anywhere in your prompt to request deeper reasoning on that turn without changing your session effort setting. Claude Code recognizes the keyword and adds an in-context instruction. The effort level sent to the API is unchanged. Claude Code passes other phrases such as “think”, “think hard”, and “think more” through as ordinary prompt text and doesn’t recognize them as keywords.


[​](#set-the-effort-level)

Set the effort level

You can change effort through any of the following:

- **`/effort`**: run `/effort` with no arguments to open an interactive slider, `/effort` followed by a level name to set it directly, or `/effort auto` to clear your saved level for the active model. You can run it while Claude is working, and once you confirm the [cache warning](prompt-caching.md#changing-effort-level), if Claude Code shows one, Claude Code applies the new level to the next request in the turn
- **In `/model`**: use left/right arrow keys to adjust the effort slider when selecting a model
- **`--effort` flag**: pass a level name to set it for a single session when launching Claude Code
- **Environment variable**: set `CLAUDE_CODE_EFFORT_LEVEL` to a level name or `auto`
- **Settings**: set a per-model level in [`modelSettings`](settings-reference.md#modelsettings), or set [`effortLevel`](settings-reference.md#effortlevel) to `low`, `medium`, `high`, or `xhigh` as the default for models without one. `max` isn’t accepted as a level in either key, and `ultracode` has its own [`ultracode`](settings-reference.md#ultracode) key
- **From a connected device**: in a [Remote Control](remote-control.md#what-connected-devices-see) session, pick a level from the effort control on your phone or in your browser. The level applies to the current session only. Requires Claude Code v2.1.234 or later
- **Skill and subagent frontmatter**: set `effort` in a [skill](../08-Plugins-Skills/skills.md#frontmatter-reference) or [subagent](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields) markdown file to override the effort level when that skill or subagent runs

Frontmatter effort applies when that skill or subagent is active, overriding the session level but not the environment variable. A [`maxEffortLevel`](settings-reference.md#maxeffortlevel) or [organization effort cap](#organization-effort-limits) still limits the level the skill or subagent runs at. If you set `effortLevel` in [managed settings](../13-Enterprise-Admin/managed-settings.md), Claude Code applies it at the settings step of the [effort resolution order](#adjust-effort-level), and users can still change the level with `/effort` or `--effort`. To keep users at or below a level, set [`maxEffortLevel`](settings-reference.md#maxeffortlevel). The effort slider appears in `/model` when a supported model is selected. The current effort level is also shown in the session header next to the model name, for example “with low effort”, so you can confirm which setting is active without opening `/model`. The footer also briefly shows the effort level at startup and when it changes.


[​](#adaptive-reasoning-and-fixed-thinking-budgets)

Adaptive reasoning and fixed thinking budgets

Adaptive reasoning makes thinking optional on each step, so Claude can respond faster to routine prompts and reserve deeper thinking for steps that benefit from it. If you want Claude to think more or less often than the current level produces, you can say so directly in your prompt or in `CLAUDE.md`; the model responds to that guidance within its effort setting. Fable models, Sonnet 5 and later, Haiku 5.5, and Opus 4.7 and later always use adaptive reasoning. The fixed thinking budget mode and `CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING` don’t apply to them. On Opus 4.6 and Sonnet 4.6, you can set `CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1` to revert to the previous fixed thinking budget controlled by `MAX_THINKING_TOKENS`. See [environment variables](env-vars.md).


[​](#extended-thinking)

Extended thinking

Extended thinking is the reasoning Claude emits before responding. On models that support [adaptive reasoning](#adjust-effort-level), the effort level is the primary control for how much thinking happens; the settings below turn thinking on or off and control how it displays. With thinking turned off on the Anthropic API, Claude Code sends effort `high` instead of a higher level to models it knows [don’t accept that combination](errors.md#effort-isnt-available-with-thinking-turned-off), such as Opus 5.

| Control                                 | How to set it                                                                                                                                                                                                                                                                                                                 |
|:----------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Toggle for the current session          | Press `Option+T` on macOS or `Alt+T` on Windows and Linux                                                                                                                                                                                                                                                                     |
| Set the global default                  | Run `/config` and toggle thinking mode. Saved as `alwaysThinkingEnabled` in `~/.claude/settings.json`                                                                                                                                                                                                                         |
| Disable through an environment variable | Set [`MAX_THINKING_TOKENS=0`](env-vars.md), which turns thinking off on the Anthropic API except on Opus 5.5, Sonnet 5.5, Haiku 5.5, and Fable models. On [third-party providers](third-party-integrations.md), Claude Code omits the `thinking` parameter instead, and adaptive-reasoning models may still think |

You can’t turn thinking off on Opus 5.5, Sonnet 5.5, Haiku 5.5, or the Fable models. The session toggle and the `/config` row show `Thinking can't be turned off` for these models instead of offering the switch, and a saved `alwaysThinkingEnabled: false` or `MAX_THINKING_TOKENS=0` has no effect there. On these models, the model decides per step how much to think based on the effort level. The saved setting applies again when you switch to a model that accepts it. Claude Code collapses thinking output by default. Press `Ctrl+O` to toggle verbose mode and see the reasoning as gray italic text. Interactive sessions on the Anthropic API receive redacted thinking blocks by default, so set `showThinkingSummaries: true` in [settings](settings.md) if you want the full summaries available when you expand. You are charged for all thinking tokens generated, even when collapsed or redacted.


[​](#extended-context)

Extended context

Fable 5.1, Fable 5, Sonnet 5 and later, Haiku 5.5, Opus 4.6 and later, and Sonnet 4.6 support a [1 million token context window](../04-API-Reference/Guides/build-with-claude-context-windows.md#context-window-sizes-by-model) for long sessions with large codebases. Fable 5.1, Fable 5, Sonnet 5 and later, Haiku 5.5, and Opus 4.7 and later run with the 1M window by default, with no `[1m]` suffix needed. That includes sessions on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry, and [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sessions. To run them with a 200K window instead, see [Turn off 1M context](#turn-off-1m-context). Opus 4.6 and Sonnet 4.6 reach 1M only through their `[1m]` variant, and access to that variant depends on your plan. On Max, Team, and Enterprise plans, including both Team Standard and Team Premium seats, Opus 4.6 with 1M context is included with your subscription. Sonnet 4.6 with 1M context requires [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md) on every subscription plan, including Max.

| Plan                      | Opus 4.6 with 1M context                                                                                    | Sonnet 4.6 with 1M context                                                                                  |
|---------------------------|-------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------|
| Max, Team, and Enterprise | Included with subscription                                                                                  | Requires [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md) |
| Pro                       | Requires [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md) | Requires [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md) |
| API and pay-as-you-go     | Full access                                                                                                 | Full access                                                                                                 |

Claude Code checks these plan requirements only when it connects to the Anthropic API directly. If you point `ANTHROPIC_BASE_URL` at an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md#subscriptions-and-gateways) and your saved claude.ai login stays the active credential, Claude Code doesn’t check your plan’s usage credits. The `[1m]` options stay available in `/model`, and the gateway decides whether the request succeeds. Before v2.1.229, Claude Code rejected `/model sonnet[1m]` in that configuration when it couldn’t confirm usage credits on the account. On the Anthropic API, the 1M context window uses standard model pricing with no premium for tokens beyond 200K, except on Haiku 5.5, which [costs more on prompts longer than 100K tokens](#haiku-5-5-context-window-and-pricing). For plans where extended context is included with your subscription, usage remains covered by your subscription. For plans that access extended context through usage credits, tokens are billed to usage credits.


[​](#select-1m-context-for-opus-4-6-or-sonnet-4-6)

Select 1M context for Opus 4.6 or Sonnet 4.6

To select a 1M variant by name, append the `[1m]` suffix to a model alias or a full model name:

```python
# Append [1m] to a full model name
/model claude-opus-4-6[1m]
/model claude-sonnet-4-6[1m]

# Or to an alias: the suffix applies to the model the alias resolves to
/model opus[1m]
```


[​](#context-window-behind-an-llm-gateway)

Context window behind an LLM gateway

If you set `ANTHROPIC_BASE_URL` to an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) or another proxy, Claude Code gives each model it recognizes the same context window the model has on the Anthropic API. Fable 5.1, Fable 5, Sonnet 5 and later, Haiku 5.5, and Opus 4.7 and later get the 1M window with no `[1m]` variant to select, and a model that reaches 1M only through its `[1m]` variant, such as Opus 4.6, runs at 200K without it. Claude Code can’t detect a lower limit that the gateway or the server behind it enforces. If your gateway rejects requests above 200K tokens, set [`CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000`](env-vars.md) in the environment that starts Claude Code, so sessions on every model [compact at that boundary](#set-the-auto-compact-window).


[​](#turn-off-1m-context)

Turn off 1M context

To keep sessions at a 200K window, set `CLAUDE_CODE_DISABLE_1M_CONTEXT=1` in your shell or in a [settings file](env-vars.md#set-environment-variables). Claude Code removes the `[1m]` model variants from the model picker. On models that run with the 1M window by default, such as the Fable models, Sonnet 5 and later, and Opus 4.7 and later, it also treats the model as having a 200K context window:

- With auto-compaction on, sessions compact at the 200K boundary through [auto-compaction](#set-the-auto-compact-window). Setting the auto-compact window above 200K doesn’t lift the hold, because Claude Code caps that window at the model’s context window.
- With auto-compaction off, sessions stop at the 200K boundary with the [context-limit error](errors.md#prompt-is-too-long) instead of compacting.


[​](#haiku-5-5-context-window-and-pricing)

Haiku 5.5 context window and pricing

On the Anthropic API, Haiku 5.5 runs with the 1M context window on every plan, with no `[1m]` suffix to select. Its model ID is `claude-haiku-5-5`. To use it, run `/model claude-haiku-5-5` in a session, or start Claude Code from your shell with `claude --model claude-haiku-5-5`. A Haiku 5.5 request costs more per token when its prompt is longer than 100K tokens. See [Anthropic pricing](../17-Billing-Plans/about-claude-pricing.md) for both rates. Sessions auto-compact at about 967K tokens by default. To compact earlier, [set a smaller auto-compact window](#set-the-auto-compact-window) for the model.


[​](#context-window-and-auto-compaction)

Context window and auto-compaction

The auto-compact window is how full the context window can get before Claude Code compacts the conversation. For what compaction keeps and drops per mechanism, see [What survives compaction](context-window.md#what-survives-compaction).


[​](#set-the-auto-compact-window)

Set the auto-compact window

If Claude Code warned about the value of `CLAUDE_CODE_AUTO_COMPACT_WINDOW`, see [the variable’s values and warnings](#claude_code_auto_compact_window-values).

You can set the auto-compact window in these places:

- **For the current model, in this session and later ones**: run `/autocompact` with a value, like `/autocompact 500k`. Claude Code saves it to your user settings under the current model in [`modelSettings`](settings-reference.md#modelsettings) and applies it to the current session. If a higher-priority [settings scope](settings.md#settings-precedence) such as managed settings sets its own window for that model or for every model, the command saves your value but the session keeps that scope’s window, and the command says so. Run `/autocompact auto` to return to the window tuned for your model. Before v2.1.288, the command saved one window for every model, as the top-level `autoCompactWindow`.
- **For every model**: set [`autoCompactWindow`](settings-reference.md#autocompactwindow) in a settings file, such as `"autoCompactWindow": 200000` in `~/.claude/settings.json`. A window you saved for a model with `/autocompact` takes precedence over this key in the same file for that model.
- **For one launch**: pass [`--autocompact`](cli-reference.md#cli-flags) when starting Claude Code. The flag overrides your saved setting for that launch without changing it, and `claude --autocompact auto` runs the session at the tuned window even if your saved setting has a value. Unlike `/autocompact`, the flag isn’t preempted by a higher-priority settings scope such as managed settings.
- **In scripts and cloud environments**: set [`CLAUDE_CODE_AUTO_COMPACT_WINDOW`](env-vars.md) to a token count such as `200000`. Unless Claude Code [ignores the value](#claude_code_auto_compact_window-values), the variable takes precedence over the command, the flag, and the `autoCompactWindow` setting. `/autocompact` then reports the override without saving. The status line’s `used_percentage` measures against the model’s full context window, so while the variable is set, that percentage doesn’t indicate when compaction will run.
- **For one subagent**: see [Set the auto-compact window for one subagent](../09-Agents-Patterns/sub-agents.md#subagent-auto-compact-window).

The command and the flag accept a window size from 100K to 1M tokens, in any of these forms:

- A plain token count, such as `200000`
- A `k` or `M` suffix, such as `500k` or `1M`
- A bare number from 100 to 1000, meaning thousands, so `200` sets 200,000

Whichever way you set the window, Claude Code caps it at the model’s context window.


[​](#claude_code_auto_compact_window-values)

Values and warnings for `CLAUDE_CODE_AUTO_COMPACT_WINDOW`

A warning that quotes your `CLAUDE_CODE_AUTO_COMPACT_WINDOW` value means the value falls outside 100,000 to 1,000,000 or isn’t a token count. To stop the warning, set a number in that range, such as `CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000`. On Claude Code v2.1.304 or later, you can also write the number with `k` for thousands or `M` for millions, as in `200k` or `1M`. Find your warning’s wording in the first column, then read across for the window your session uses and what to change:

| Your warning contains                                               | Window the session uses                                                                                                                      | What to change                                                                     |
|:--------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------|
| `reads as <N> tokens, so Claude Code treats it as the 100k minimum` | The smaller of 100,000 tokens and your model’s context window                                                                                | Set at least `100000`, such as `200000`, or `200k` if you meant `200` as thousands |
| `is too large, so Claude Code treats it as the 1M maximum`          | The smaller of 1,000,000 tokens and your model’s context window                                                                              | You already have the largest window. To stop the warning, set `1M` or `1000000`    |
| `isn't a usable size, so Claude Code ignores it`                    | The window from `--autocompact`, `/autocompact`, or `autoCompactWindow`, or the [default](#default-auto-compact-thresholds) when none is set | Set a number such as `200000`, or unset the variable                               |

A number with no suffix is read as that many tokens, so `CLAUDE_CODE_AUTO_COMPACT_WINDOW=200` means 200 tokens even though `/autocompact 200` means 200,000.


[​](#default-auto-compact-thresholds)

Default auto-compact thresholds

If you don’t set an auto-compact window, Claude Code compacts when the conversation reaches the model’s context limit, except in these sessions:

- [Cloud sessions](claude-code-on-the-web.md) compact as the conversation approaches the model’s limit
- Sonnet 4.6 and Opus 4.6 without [extended context](#extended-context) compact at the 200K boundary
- When you set [`CLAUDE_CODE_DISABLE_1M_CONTEXT=1`](env-vars.md), models with a native 1M window, such as Sonnet 5 and the Fable models, compact at the 200K boundary
- Models running with a native 1M window compact before the window fills, at about 967K tokens by default. These include the Fable models, Sonnet 5 and later, Haiku 5.5, and Opus 4.7 and later. Behind a custom `ANTHROPIC_BASE_URL`, see [the context window behind a gateway](#context-window-behind-a-gateway)
- Sessions on a model ID Claude Code doesn’t recognize, such as an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) alias, compact at the context window Claude Code assumes for the ID; see [Correct the window for a gateway or custom model ID](#correct-the-window-for-a-gateway-or-custom-model-id)

See the [`idleCompaction`](settings-reference.md#idlecompaction) setting for when Claude Code also compacts a conversation you leave idle.


[​](#correct-the-window-for-a-gateway-or-custom-model-id)

Correct the window for a gateway or custom model ID

Either 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:

```python
⚠ Model "my-gateway-opus" isn't recognized · context assumed to be 200k tokens · ...
Claude Code doesn't recognize the model "my-gateway-opus", so it assumes a context window of 200k tokens. Update Claude Code, or see https://code.claude.com/docs/en/model-config#correct-the-window-for-a-gateway-or-custom-model-id to set the window.
```

Claude Code [auto-compacts](#default-auto-compact-thresholds) the conversation at the assumed 200K, so if the model’s real context window is 200K, there is nothing to correct. Otherwise, give Claude Code the real window in whichever of these ways fits your ID:

- **A model newer than your Claude Code version**: run `claude update` in your shell. If Claude Code recognizes the ID after the update, you don’t need to configure anything else.
- **Your gateway’s or provider’s name for a model Claude Code knows**: add a [`modelOverrides`](#override-model-ids-per-version) entry that maps the Anthropic model ID to your ID, such as `"claude-opus-4-8": "my-gateway-opus"`. You can instead list your ID in a [`modelPicker`](settings-reference.md#fields-for-modelpicker) row with `behavesAs` set to that model. Either way, Claude Code then treats the ID as that model.
- **A model with a 1M window**: append `[1m]` to the ID where you set the model, such as `claude --model 'my-gateway-opus[1m]'` in your shell. If you [turned off 1M context](#turn-off-1m-context), you get the same window with or without the suffix.
- **Any other window**: set [`CLAUDE_CODE_MAX_CONTEXT_TOKENS`](env-vars.md) to the window size in tokens in the environment that starts Claude Code, such as `CLAUDE_CODE_MAX_CONTEXT_TOKENS=400000`. For an unrecognized ID that doesn’t start with `claude-` and has no `[1m]` suffix, the variable takes effect on its own. For any other ID, check [which IDs it applies to](#which-ids-claude_code_max_context_tokens-applies-to) first.

Once Claude Code recognizes the ID or uses the window you gave it, the warning no longer appears when you start a session on that ID.


[​](#which-ids-claude_code_max_context_tokens-applies-to)

Which IDs `CLAUDE_CODE_MAX_CONTEXT_TOKENS` applies to

On an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) or other custom deployment, Claude Code can assume a context window for the model ID that differs from the model’s real window, whether or not it resolves the ID to a Claude model. Set [`CLAUDE_CODE_MAX_CONTEXT_TOKENS`](env-vars.md) to the window Claude Code should assume instead. How the variable applies depends on the ID. Claude Code treats an ID as a provider or custom spelling when it doesn’t start with `claude-`, in any casing, or when it carries a suffix that Claude Code strips when reading the ID, such as the `@YYYYMMDD` date used on Google Cloud’s Agent Platform. Before v2.1.259, Claude Code didn’t count a stripped suffix, so an unrecognized `claude-` ID with a date suffix was treated as a bare `claude-` name. An unrecognized provider or custom spelling, the same spelling with `[1m]`, and every other ID are three separate cases:

- If Claude Code can’t resolve a provider or custom spelling to a model it recognizes and the ID doesn’t contain `[1m]`, the variable applies directly and proactive compaction continues at the declared window.
- If Claude Code can’t resolve a provider or custom spelling to a model it recognizes and the ID contains `[1m]`, in any casing, Claude Code assumes a 1M window for it and the variable doesn’t apply on its own. To correct the window while keeping proactive compaction, also set [`CLAUDE_CODE_DISABLE_1M_CONTEXT=1`](env-vars.md). With that variable set, Claude Code sizes the ID like the same spelling without `[1m]`, so `CLAUDE_CODE_MAX_CONTEXT_TOKENS` applies when it would apply to that untagged spelling. With a declared window above 200K, the warning that [the 200K limit isn’t enforced](errors.md#the-200k-limit-isnt-enforced) is expected in this configuration.
- If the ID resolves to a model Claude Code recognizes, or the ID is a bare `claude-` name with no suffix for Claude Code to strip, in any casing, the variable takes effect only when you also set [`DISABLE_COMPACT`](env-vars.md), which disables all compaction. For example, an ID that contains a Claude model name that Claude Code knows, such as `anthropic/claude-opus-4-8`, `us.anthropic.claude-…-v1:0`, or the dated `claude-sonnet-4-5@20250929`, resolves to that model. This includes IDs that also contain `[1m]`: Claude Code resolves `claude-opus-4-8[1m]` to Opus 4.8 even with `CLAUDE_CODE_DISABLE_1M_CONTEXT` set.

For a model ID Claude Code doesn’t recognize, set [`CLAUDE_CODE_DISABLE_UNKNOWN_MODEL_WINDOW_ENFORCEMENT=1`](env-vars.md) to have Claude Code compact only after the API rejects the conversation with a [too-long error Claude Code recognizes](errors.md#prompt-is-too-long). Claude Code doesn’t run that recovery when a gateway [rewrites the error](../13-Enterprise-Admin/llm-gateway-connect.md#troubleshoot-gateway-errors) to wording Claude Code doesn’t recognize.


[​](#checking-your-current-model)

Checking your current model

You can see which model you’re currently using in two places:

- In the [status line](statusline.md), if you have one configured
- In `/status`, which also displays your account information


[​](#add-a-custom-model-option)

Add a custom model option

Use `ANTHROPIC_CUSTOM_MODEL_OPTION` to add a single custom entry to the `/model` picker without replacing the built-in aliases. This is useful for testing model IDs that Claude Code does not list by default. For LLM gateway deployments, Claude Code can populate the picker from the gateway’s `/v1/models` endpoint when `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` is set, so this variable is needed only when discovery is disabled or does not return the model you want. See [gateway model discovery](../13-Enterprise-Admin/llm-gateway-protocol.md#model-discovery). To list several models instead, in your own order and under labels you choose, set [`modelPicker`](settings-reference.md#modelpicker). Its entry says which rows the picker keeps when that lineup replaces the built-in one. This example sets all three variables to make a gateway-routed Opus deployment selectable. Claude Code reads environment variables at startup, so run the exports before launching `claude`, or restart an existing session to pick them up:

```python
export ANTHROPIC_CUSTOM_MODEL_OPTION="my-gateway/claude-opus-5-5"
export ANTHROPIC_CUSTOM_MODEL_OPTION_NAME="Opus via Gateway"
export ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION="Custom deployment routed through the internal LLM gateway"
```

`ANTHROPIC_CUSTOM_MODEL_OPTION_NAME` and `ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION` are optional:

- If you omit the name, the entry shows the model’s name when Claude Code [recognizes the ID](#customize-pinned-model-display-and-capabilities), and the model ID otherwise.
- If you omit the description, Claude Code uses `Custom model (<model-id>)`.

Claude Code lists the custom entry after the built-in entries, and any [`modelPicker`](settings-reference.md#modelpicker) rows you append come after it. Claude Code skips validation for the model ID set in `ANTHROPIC_CUSTOM_MODEL_OPTION`, so you can use any string your API endpoint accepts. When [`availableModels`](#restrict-model-selection) is set, include the custom model ID in the allowlist as well. Otherwise Claude Code filters the custom entry from the picker and rejects a `--model` selection of it like any other excluded model. A custom ID that embeds a family name, such as `my-gateway/claude-opus-5-5`, counts as a specific entry for that family and disables its wildcard, so also list the versions you intend to keep selectable. See [Merge behavior](#merge-behavior).


[​](#environment-variables)

Environment variables

Use the following environment variables to control the model names that the aliases map to. Each value must be a full model name, or the equivalent identifier for your API provider. To choose the model your sessions start on, set [`ANTHROPIC_DEFAULT_MODEL`](#set-a-default-model-for-new-sessions), which this table omits.

| Environment variable             | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
|----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `ANTHROPIC_DEFAULT_FABLE_MODEL`  | The model to use for `fable`, and the model ID Claude Code recognizes as a Fable model for [automatic model fallback](#automatic-model-fallback) on third-party providers                                                                                                                                                                                                                                                                                                                                 |
| `ANTHROPIC_DEFAULT_OPUS_MODEL`   | The model to use for `opus`, or for `opusplan` when Plan Mode is active.                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `ANTHROPIC_DEFAULT_SONNET_MODEL` | The model to use for `sonnet`, or for `opusplan` when Plan Mode is not active.                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `ANTHROPIC_DEFAULT_HAIKU_MODEL`  | The model to use for `haiku`, or [background functionality](../17-Billing-Plans/costs.md#background-token-usage)                                                                                                                                                                                                                                                                                                                                                                                                        |
| `CLAUDE_CODE_SUBAGENT_MODEL`     | The default model for [subagents](../09-Agents-Patterns/sub-agents.md#choose-a-model), [agent team](../09-Agents-Patterns/agent-teams.md#specify-teammates-and-models) teammates, and [workflow](workflows.md) agents that aren’t assigned a model another way. Accepts an alias such as `haiku` or a full model name. A per-invocation model or a definition’s `model` field, including `inherit`, takes precedence. To change that, set [`CLAUDE_CODE_SUBAGENT_MODEL_FORCE`](../09-Agents-Patterns/sub-agents.md#run-every-subagent-on-one-model) |

On third-party providers, [Customize pinned model display and capabilities](#customize-pinned-model-display-and-capabilities) describes what a pinned model’s row in the `/model` picker shows. Note: `ANTHROPIC_SMALL_FAST_MODEL` is deprecated in favor of `ANTHROPIC_DEFAULT_HAIKU_MODEL`.


[​](#pin-models-for-third-party-deployments)

Pin models for third-party deployments

When deploying Claude Code through [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), [Microsoft Foundry](microsoft-foundry.md), or [Claude Platform on AWS](claude-platform-on-aws.md), pin model versions before rolling out to users. Without pinning, Claude Code uses model aliases such as `fable`, `opus`, `sonnet`, and `haiku` that resolve to a built-in default model ID for each provider. That default can lag the newest Anthropic release, and the model it points to may not yet be enabled in a user’s account. When the default is unavailable, Amazon Bedrock and Google Cloud’s Agent Platform users see a notice and the session falls back to an earlier version of the default model, or to the default Sonnet model when the default is an Opus model and no Opus version is available. Microsoft Foundry users see errors instead, because Microsoft Foundry has no equivalent startup check. On Amazon Bedrock and Google Cloud’s Agent Platform, a user who starts the session on a specific Sonnet or Opus version, for example with `--model`, `ANTHROPIC_MODEL`, or the `model` setting, pins that version as the session’s default for the matching alias: the startup check skips the built-in default it replaces and shows no fallback notice. Before v2.1.211, the check ran and could show a notice even when a session model was explicitly configured.

Set the model environment variables to specific version IDs as part of your initial setup. Pinning lets you control when your users move to a new model.

Use the following environment variables with version-specific model IDs for your provider:

| Provider                      | Example                                                              |
|:------------------------------|:---------------------------------------------------------------------|
| Amazon Bedrock                | `export ANTHROPIC_DEFAULT_OPUS_MODEL='us.anthropic.claude-opus-4-8'` |
| Google Cloud’s Agent Platform | `export ANTHROPIC_DEFAULT_OPUS_MODEL='claude-opus-4-8'`              |
| Microsoft Foundry             | `export ANTHROPIC_DEFAULT_OPUS_MODEL='claude-opus-4-8'`              |

Apply the same pattern for `ANTHROPIC_DEFAULT_FABLE_MODEL`, `ANTHROPIC_DEFAULT_SONNET_MODEL`, and `ANTHROPIC_DEFAULT_HAIKU_MODEL`. For current and legacy model IDs across all providers, see [Models overview](../20-Models/about-claude-models-overview.md). To upgrade users to a new model version, update these environment variables and redeploy. A pinned model with a native 1M window, such as Opus 4.8 or Sonnet 5, runs with the [1M context window](#extended-context) without any suffix when Claude Code can match the pinned ID to that model. The ID matches when it contains the model’s Anthropic API ID, as `us.anthropic.claude-opus-4-8` contains `claude-opus-4-8`, or when a [`modelOverrides`](#override-model-ids-per-version) entry maps the model to it. On a pinned ID that Claude Code can’t match to a model, sessions run with a 200K window by default unless the ID carries the `[1m]` suffix. For a model that reaches 1M through its `[1m]` variant, such as Opus 4.6 or Sonnet 4.6, enable extended context by appending `[1m]` to the model ID in `ANTHROPIC_DEFAULT_OPUS_MODEL` or `ANTHROPIC_DEFAULT_SONNET_MODEL`:

```python
export ANTHROPIC_DEFAULT_OPUS_MODEL='claude-opus-4-6[1m]'
```

With the `[1m]` suffix, the 1M context window applies to all usage of the pinned alias, including the plan-mode Opus phase of [`opusplan`](#opusplan-model-setting) and [subagents](../09-Agents-Patterns/sub-agents.md#choose-a-model) whose `model` frontmatter names the alias.

- Claude Code strips the suffix before sending the model ID to your provider.
- Only append `[1m]` when the underlying model [supports 1M context](../04-API-Reference/Guides/build-with-claude-context-windows.md#context-window-sizes-by-model).
- The suffix is read per variable, not per model. On Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry, an Opus 4.6 or Sonnet 4.6 ID without `[1m]` in one variable uses 200K context even if another variable sets the same model with the suffix.

When you set an `ANTHROPIC_DEFAULT_*_MODEL` variable, the `/model` picker shows one row for that model in place of the family’s built-in rows, including any 1M context rows. To reach the 1M window without adding the suffix to that variable, your users run `/model opus[1m]`, and Claude Code applies the suffix to the model the variable names. `/model sonnet[1m]` works the same way.

An `availableModels` allowlist delivered through [MDM or a managed settings file](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms) still applies when using third-party providers; [server-managed settings are not delivered there](../13-Enterprise-Admin/server-managed-settings.md#platform-availability).Filtering matches on a model alias such as `opus`, a version prefix such as `claude-opus-4-8`, or the full provider-form model ID. Provider-specific prefixes such as `us.anthropic.` are not stripped, so to allow a specific model, list its full provider-form ID, or map it through [`modelOverrides`](#override-model-ids-per-version). For a pinned model, that ID is the value you set in its `ANTHROPIC_DEFAULT_*_MODEL` variable. Any `[1m]` suffix is stripped from both the allowlist entry and the requested model before matching.


[​](#customize-pinned-model-display-and-capabilities)

Customize pinned model display and capabilities

When you pin a model on a third-party provider, its row in the `/model` picker shows the model’s name by default if Claude Code recognizes the pinned ID, and the raw ID otherwise:

- **Recognized**: the exact ID of a model Claude Code knows, such as its Anthropic API ID or your provider’s or gateway’s form of it, with or without the `[1m]` suffix. Pin `us.anthropic.claude-sonnet-4-5-20250929-v1:0` and the row reads `Sonnet 4.5`.
- **Not recognized**: any other ID, such as an application inference profile ARN or a model version Claude Code doesn’t know, unless a [`modelOverrides`](#override-model-ids-per-version) entry maps a model to that ID. On Microsoft Foundry, deployment names are user-defined, so Claude Code never recognizes a pinned ID there, mapped or not, and the row shows the deployment name by default.

When a row shows the model’s name, its default description includes the pinned ID so you can still see which ID is pinned. Claude Code may also not recognize which features a pinned model supports. You can set the display name and description yourself and declare capabilities with companion environment variables for each pinned model. These variables take effect on third-party providers such as Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry. The `_NAME` and `_DESCRIPTION` variables also take effect when `ANTHROPIC_BASE_URL` points to an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md). They have no effect when connecting directly to `api.anthropic.com`.

| Environment variable                                  | Description                                                                                                                                                                      |
|-------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `ANTHROPIC_DEFAULT_OPUS_MODEL_NAME`                   | Display name for the pinned Opus model in the `/model` picker. When not set, the row shows the model’s name if Claude Code recognizes the pinned ID, and the pinned ID otherwise |
| `ANTHROPIC_DEFAULT_OPUS_MODEL_DESCRIPTION`            | Display description for the pinned Opus model in the `/model` picker. When not set, the row shows a default description that begins `Custom Opus model`                          |
| `ANTHROPIC_DEFAULT_OPUS_MODEL_SUPPORTED_CAPABILITIES` | Comma-separated list of capabilities the pinned Opus model supports                                                                                                              |

The same `_NAME`, `_DESCRIPTION`, and `_SUPPORTED_CAPABILITIES` suffixes are available for `ANTHROPIC_DEFAULT_SONNET_MODEL`, `ANTHROPIC_DEFAULT_HAIKU_MODEL`, `ANTHROPIC_DEFAULT_FABLE_MODEL`, and `ANTHROPIC_CUSTOM_MODEL_OPTION`. Claude Code enables features like [effort levels](#adjust-effort-level) and [extended thinking](#extended-thinking) by matching the model ID against known patterns. Provider-specific IDs such as Amazon Bedrock ARNs or custom deployment names often don’t match these patterns, leaving supported features disabled. Set `_SUPPORTED_CAPABILITIES` to tell Claude Code which features the model actually supports:

| Capability value       | Enables                                                                         |
|------------------------|---------------------------------------------------------------------------------|
| `effort`               | [Effort levels](#adjust-effort-level) and the `/effort` command                 |
| `xhigh_effort`         | The `xhigh` effort level                                                        |
| `max_effort`           | The `max` effort level                                                          |
| `thinking`             | [Extended thinking](#extended-thinking)                                         |
| `adaptive_thinking`    | Adaptive reasoning that dynamically allocates thinking based on task complexity |
| `interleaved_thinking` | Thinking between tool calls                                                     |

When `_SUPPORTED_CAPABILITIES` is set, Claude Code enables the listed capabilities and disables the unlisted ones for the matching pinned model. When the variable is unset, Claude Code falls back to built-in detection based on the model ID. This example pins Opus to an Amazon Bedrock custom model ARN, sets a friendly name, and declares its capabilities:

```python
export ANTHROPIC_DEFAULT_OPUS_MODEL='arn:aws:bedrock:us-east-1:123456789012:custom-model/abc'
export ANTHROPIC_DEFAULT_OPUS_MODEL_NAME='Opus via Bedrock'
export ANTHROPIC_DEFAULT_OPUS_MODEL_DESCRIPTION='Opus 4.7 routed through a Bedrock custom endpoint'
export ANTHROPIC_DEFAULT_OPUS_MODEL_SUPPORTED_CAPABILITIES='effort,xhigh_effort,max_effort,thinking,adaptive_thinking,interleaved_thinking'
```


[​](#override-model-ids-per-version)

Override model IDs per version

On platforms that embed Claude Code and set [`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`](env-vars.md), 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](settings.md#exceptions-to-managed-settings-precedence) says which keys and variables the host overrides. The family-level environment variables above configure one model ID per family alias. If you need to map several versions within the same family to distinct provider IDs, use the `modelOverrides` setting instead. `modelOverrides` maps individual Anthropic model IDs to the provider-specific strings that Claude Code sends to your provider’s API. When a user selects a mapped model in the `/model` picker, Claude Code uses your configured value instead of the built-in default. This lets enterprise administrators route each model version to a specific Amazon Bedrock inference profile ARN, Google Cloud’s Agent Platform version name, or Microsoft Foundry deployment name for governance, cost allocation, or regional routing. Set `modelOverrides` in your [settings file](settings.md#where-settings-live):

```python
{
  "modelOverrides": {
    "claude-opus-4-7": "arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/opus-prod",
    "claude-opus-4-6": "arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/opus-46-prod",
    "claude-sonnet-4-6": "arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/sonnet-prod"
  }
}
```

Keys must be Anthropic model IDs as listed in the [Models overview](../20-Models/about-claude-models-overview.md). For dated model IDs, include the date suffix exactly as it appears there. Unknown keys are ignored. To stop the `[claude-code:unrecognized_model]` [diagnostic line](errors.md#unrecognized-model-id-on-a-request) for an ID such as a gateway alias, add an entry with that ID as its value. Overrides replace the built-in model IDs that back each entry in the `/model` picker. On Amazon Bedrock, `modelOverrides` entries take precedence over any inference profiles that Claude Code discovers automatically at startup. Claude Code passes values that are already provider-native, such as Amazon Bedrock inference profile ARNs or Microsoft Foundry deployment names, to the provider as-is. Overrides also apply when you pass an Anthropic model ID directly through `--model`, the `ANTHROPIC_MODEL` environment variable, or an `ANTHROPIC_DEFAULT_*_MODEL` environment variable. On Amazon Bedrock, Google Cloud’s Agent Platform, and [Mantle](amazon-bedrock.md#use-the-mantle-endpoint), an Anthropic model ID with no `modelOverrides` entry resolves to the same provider-specific ID as the `/model` picker row for that version, when the provider supports that version. Mantle supports a subset of versions. For an Anthropic model ID outside that subset, Claude Code sends the raw ID to Mantle without mapping it, unless a `modelOverrides` entry covers it. Before v2.1.200, `--model` and the environment-variable values reached the provider as-is without going through the override map. `modelOverrides` works alongside `availableModels`. The allowlist is evaluated against the Anthropic model ID, not the override value, so an entry like `"opus"` in `availableModels` continues to match even when Opus versions are mapped to ARNs. When `enforceAvailableModels` is set in managed settings, the enforced Default resolves through `modelOverrides` from [managed settings](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) only. An admin’s mapping, such as a version pinned to an inference profile ARN, is honored in the enforced Default. Overrides from user or project settings do not affect it. When `availableModels` is set in [managed settings](../13-Enterprise-Admin/managed-settings.md), only `modelOverrides` from managed settings apply to an Anthropic model ID passed directly through `--model` or the environment variables above. Claude Code ignores overrides in user or project settings for those IDs, and never resolves an ID the managed list excludes through `modelOverrides` from any settings source. This managed-source restriction requires Claude Code v2.1.200 or later. See [Restrict model selection](#restrict-model-selection) for how blocked IDs are handled.


[​](#prompt-caching-configuration)

Prompt caching configuration

Claude Code automatically uses [prompt caching](prompt-caching.md) to optimize performance and reduce costs. You can disable prompt caching globally or for specific model tiers:

| Environment variable            | Description                                                                                                         |
|---------------------------------|---------------------------------------------------------------------------------------------------------------------|
| `DISABLE_PROMPT_CACHING`        | Set to `1` to disable prompt caching for all models. Takes precedence over the per-model settings                   |
| `DISABLE_PROMPT_CACHING_HAIKU`  | Set to `1` to disable prompt caching for the [default Haiku model](prompt-caching.md#disable-prompt-caching)  |
| `DISABLE_PROMPT_CACHING_SONNET` | Set to `1` to disable prompt caching for the [default Sonnet model](prompt-caching.md#disable-prompt-caching) |
| `DISABLE_PROMPT_CACHING_OPUS`   | Set to `1` to disable prompt caching for the [default Opus model](prompt-caching.md#disable-prompt-caching)   |
| `DISABLE_PROMPT_CACHING_FABLE`  | Set to `1` to disable prompt caching for Fable models only                                                          |

To choose the cache TTL for the main conversation and for subagents separately, see [choose the TTL yourself](prompt-caching.md#choose-the-ttl-yourself). For what triggers a cache miss, see [How Claude Code uses prompt caching](prompt-caching.md).


[​](#version-history)

Version history

This table lists the Claude Code version at which each model alias changed the model it resolves to, newest first.

| Version  | Change                                                                                                                                                                                      |
|:---------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| v2.1.293 | `haiku` resolves to Haiku 5.5 on the Anthropic API                                                                                                                                          |
| v2.1.284 | `sonnet` resolves to Sonnet 5.5 on the Anthropic API                                                                                                                                        |
| v2.1.280 | `opus` resolves to Opus 5.5 on the Anthropic API, Claude Platform on AWS, Amazon Bedrock, and Google Cloud’s Agent Platform                                                                 |
| v2.1.257 | `fable` resolves to Fable 5.1, except in Claude apps gateway sessions                                                                                                                       |
| v2.1.219 | `opus` resolves to Opus 5 on the Anthropic API, Claude Platform on AWS, Amazon Bedrock, and Agent Platform                                                                                  |
| v2.1.207 | `opus` resolves to Opus 4.8 on Claude Platform on AWS, Amazon Bedrock, and Agent Platform                                                                                                   |
| v2.1.197 | `sonnet` resolves to Sonnet 5 on the Anthropic API                                                                                                                                          |
| v2.1.154 | `opus` resolves to Opus 4.8 on the Anthropic API                                                                                                                                            |
| Earlier  | `opus` resolves to Opus 4.7 on Claude Platform on AWS and to Opus 4.6 on Amazon Bedrock and Agent Platform. `fable` resolves to Fable 5 and `haiku` resolves to Haiku 4.5 on every provider |

---

## Output styles - Claude Code Docs

Source: https://code.claude.com/docs/en/output-styles
Path: 02-Claude-Code-CLI/output-styles.md

## On this page

- [Built-in output styles](#built-in-output-styles)
  - [Default](#default)
  - [Proactive](#proactive)
  - [Concise](#concise)
  - [Explanatory](#explanatory)
  - [Learning](#learning)
- [Change your output style](#change-your-output-style)
- [Create a custom output style](#create-a-custom-output-style)
  - [Frontmatter reference](#frontmatter)
- [Choose between an output style and other features](#choose-between-an-output-style-and-other-features)
- [How output styles work](#how-output-styles-work)
- [Related resources](#related-resources)

Model and responses

# Output styles

Copy pageCopy page

Change Claude Code’s role, tone, and response format with a built-in output style such as Concise or Explanatory, or write a custom style.

Copy pageCopy page

An output style is a set of instructions that sets Claude’s role, tone, and response format for every response in a session. Claude Code includes four built-in styles besides its default, and you can write your own. Use an output style to change the way Claude responds and works with you for a whole session, so you don’t repeat the request in each prompt. For example, a built-in style can make responses shorter, add an explanation of each change, or have Claude start work without asking routine questions. A custom style can also turn Claude into something other than a software engineer, such as a writing assistant or a data analyst.

- To use a built-in style, pick one from the [built-in output styles](#built-in-output-styles) and [switch to it](#change-your-output-style).
- To write your own instructions, [create a custom output style](#create-a-custom-output-style).

An output style gives Claude instructions to follow. It doesn’t guarantee that something always happens or never happens. Some needs fit a different feature:

- For what Claude should know about your project, use [CLAUDE.md](memory.md).
- For something that has to happen every time, such as formatting after each edit or blocking a command, use a [hook](../07-Hooks/hooks-guide.md).
- For skills, subagents, and the other options, see [Choose between an output style and other features](#choose-between-an-output-style-and-other-features).


[​](#built-in-output-styles)

Built-in output styles

Claude Code starts in the [**Default**](#default) style, its standard instructions for completing software engineering tasks. Each of the four other built-in styles keeps those instructions and adds its own. This table shows what each style changes about a session and when it fits:

| Style                       | What changes                                                                                              | Use it when                                                                                                    |
|:----------------------------|:----------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------|
| [Proactive](#proactive)     | Claude starts work right away and makes reasonable assumptions rather than asking about routine decisions | You want Claude to keep working through routine decisions, and you’ll correct course if an assumption is wrong |
| [Concise](#concise)         | Responses lead with the result and leave out preamble, narration, and recaps                              | Default responses are longer than you want                                                                     |
| [Explanatory](#explanatory) | Claude adds short `Insight` blocks that explain the choices behind the code it writes                     | You’re getting to know a codebase or want the reasoning along with the change                                  |
| [Learning](#learning)       | Claude explains its choices and leaves small pieces of code for you to write yourself                     | You want hands-on coding practice while the task still gets done                                               |


[​](#default)

Default

Default means no output style is selected. Claude Code adds no style instructions, and Claude works from Claude Code’s standard system prompt, which is written for software engineering tasks. `default` appears in the `/output-style` list with the other styles, so you [select it the same way](#change-your-output-style).


[​](#proactive)

Proactive

In the Proactive style, Claude starts implementing as soon as you send a task. It makes reasonable assumptions about routine decisions rather than stopping to ask, and it doesn’t switch to plan mode unless you ask for a plan. You can redirect it at any point. The style’s instructions also tell Claude to check with you in the conversation before an action that deletes data or changes a shared or production system. That check is an instruction Claude follows and is separate from permission prompts. Switching to the Proactive style doesn’t change your [permission mode](permission-modes.md). Your permission mode still decides which tool calls run without asking you, so permission prompts appear the same way they did before you switched.


[​](#concise)

Concise

In the Concise style, the first sentence of a response states what happened or what the answer is. Claude leaves out the lead-in, the step-by-step narration, and the closing recap, and answers a simple question in one to three sentences. It does the engineering work as thoroughly as in the Default style. Requires Claude Code v2.1.237 or later. Claude still writes at full length in these cases:

- **Anything you ask for**: when you ask for an explanation or more detail, Claude answers in full.
- **Anything you need in order to act safely**: error reports, failing test output, security warnings, and confirmations for destructive actions keep their complete content.


[​](#explanatory)

Explanatory

In the Explanatory style, Claude does the task the way it does in the Default style and adds short explanations of why it made the choices it made. Each explanation appears in the conversation, before or after the code it’s about, in a block labeled `Insight`. The explanations aren’t written into your files as comments. An `Insight` block carries two or three points about your codebase or the code Claude wrote, such as this one after adding an API endpoint:

```python
★ Insight ─────────────────────────────────────
- Every route in this repo goes through the withAuth wrapper, so the new endpoint gets session checks without its own middleware.
- Rate limits are set per route in limits.ts, which is why this change adds an entry there rather than a global default.
─────────────────────────────────────────────────
```


[​](#learning)

Learning

In the Learning style, Claude adds the same `Insight` blocks as the [Explanatory style](#explanatory) and also asks you to write some of the code. Claude handles routine implementation itself. When it reaches a piece with a real design decision, such as error handling, a data structure, or business logic with more than one valid approach, it leaves a few lines for you. Claude marks the spot with a `TODO(human)` comment in the file, then sends a request that says what’s already built, what to write, and what to weigh:

```python
● Learn by Doing

Context: The upload form is in place and calls validateFile() before accepting a file. Size and type checks work for images, but the switch statement has no handling for documents yet.

Your Task: In upload.js, implement the case "document" branch inside validateFile(). Look for TODO(human).

Guidance: Decide on a size limit for documents and whether the file extension has to match the MIME type. Return {valid: boolean, error?: string}.
```

Claude then stops and waits. Write your code at the `TODO(human)` comment and tell Claude when you’re done. Claude responds with one `Insight` about your code and continues the task.


[​](#change-your-output-style)

Change your output style

Pick a style with the command, a menu, or a settings file. The command and both menus save your choice to `.claude/settings.local.json` at the [local project level](settings.md).

- **`/output-style` command**: run `/output-style <style>` to switch, for example `/output-style concise`. With no argument, the command lists the styles you can pick and marks the current one. The command also works in [non-interactive mode](headless.md) and Agent SDK sessions, and from the mobile app or web via [Remote Control](remote-control.md#limitations), where you can list and select only [built-in styles](#built-in-output-styles). Requires Claude Code v2.1.269 or later.
- **Terminal menu**: run `/config` and select **Output style** to pick a style from a menu.
- **VS Code extension**: open the [command menu](../03-IDE-Integrations/vs-code.md#use-the-prompt-box) with `/` and select **Output styles** to pick a style, including your custom styles. Requires Claude Code v2.1.257 or later.
- **Desktop app**: set the `outputStyle` field in a settings file, for example `.claude/settings.local.json`, the file the terminal menu writes. When you run `/config` there, Claude Code [opens **Settings \> Claude Code**](../16-Mobile-Desktop/desktop.md#what%E2%80%99s-not-available-in-desktop) rather than a menu.

To set a style without the menu, edit the `outputStyle` field directly in a settings file:

```python
{
  "outputStyle": "Explanatory"
}
```

The value is case-sensitive, so write the built-in names as `Proactive`, `Concise`, `Explanatory`, and `Learning`. A value that doesn’t match a style name exactly, such as `explanatory`, gives you the Default style. The `/output-style` command ignores case. To make a style your default across projects, set `outputStyle` in `~/.claude/settings.json`. A project’s own settings files [take precedence](settings.md#settings-precedence) over that value. When you switch styles mid-session, Claude uses the new style starting with your next message. For what that first message costs in prompt caching, see [Changing output style](prompt-caching.md#changing-output-style). Before v2.1.251, the new style applied only after you ran `/clear` or started a new session.


[​](#create-a-custom-output-style)

Create a custom output style

A custom output style is a Markdown file: frontmatter for metadata, then the instructions for Claude. In the VS Code extension, you can also create the file from the [**Output styles** menu](../03-IDE-Integrations/vs-code.md#use-the-prompt-box) rather than writing it by hand. This requires Claude Code v2.1.261 or later.

1

Create a Markdown file

Save it at one of three levels. The file name becomes the style name unless you set `name` in the frontmatter.

- User: `~/.claude/output-styles`
- Project: `.claude/output-styles`
- Managed policy: `.claude/output-styles` inside the [managed settings directory](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms)

Project output styles load from every `.claude/output-styles/` between the working directory and the repository root. When more than one of these nested directories defines a style with the same name, Claude Code uses the one closest to the working directory.

2

Add frontmatter and instructions

Decide whether to keep Claude Code’s software engineering instructions. Set `keep-coding-instructions: true` if you’re changing how Claude communicates but still want it coding the same way. Leave it out if Claude won’t be doing software engineering.This example leads every explanation with a diagram while keeping Claude’s coding behavior:

```python
---
name: Diagrams first
description: Lead every explanation with a diagram
keep-coding-instructions: true
---

When explaining code, architecture, or data flow, start with a Mermaid diagram showing the structure, then explain in prose.

## Diagram conventions

Use `flowchart TD` for control flow and `sequenceDiagram` for request paths. Keep diagrams under 15 nodes.
```

3

Switch to your style

Run `/output-style <style>` in the terminal, or run `/config` and select your style under **Output style**. Claude uses the new style starting with your next message. In the terminal, Claude Code reads style files when it starts, so if you create or edit one during a running session, restart Claude Code to pick up the change.

[Plugins](../08-Plugins-Skills/plugins-reference.md) can also ship output styles in an `output-styles/` directory.


[​](#frontmatter)

Frontmatter reference

Configure an output style with YAML [frontmatter](glossary.md#frontmatter) between `---` markers at the top of the file. All fields are optional, and field names use lowercase words separated by hyphens. A misspelled field is ignored without an error. If the YAML doesn’t parse, the style still loads under its file name with no fields set; run `claude --debug` to see the parse error.

| Field                      | Required | Description                                                                                                                                                                                                                                                                                |
|:---------------------------|:---------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `name`                     | No       | Name of the output style, shown in the `/config` picker. Default: the file name                                                                                                                                                                                                            |
| `description`              | No       | Description of the output style, shown in the `/config` picker                                                                                                                                                                                                                             |
| `keep-coding-instructions` | No       | Set to `true` to keep Claude Code’s section of built-in software engineering instructions, which only the full system prompt includes, alongside your style. See [How output styles work](#how-output-styles-work). Default: `false`                                                       |
| `force-for-plugin`         | No       | Plugin output styles only. Set to `true` to apply this style automatically whenever the plugin is enabled, without requiring users to select it. Overrides the user’s `outputStyle` setting. If multiple enabled plugins set this, Claude Code uses the first one loaded. Default: `false` |


[​](#choose-between-an-output-style-and-other-features)

Choose between an output style and other features

An output style applies to every response in a session. It’s an instruction Claude follows, so nothing enforces it. When what you want is narrower than every response, or has to happen without fail, another feature fits better. This table matches what you want to the feature that does it:

| You want                                                                                                   | Use                                                                    | Why it fits                                                                                                  |
|:-----------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------|
| Every response in a certain voice, length, or format, or Claude in a different role                        | An output style                                                        | It applies to the whole session, and you switch styles with one command                                      |
| Claude to know your project’s conventions, commands, and structure                                         | [CLAUDE.md](memory.md)                                           | It holds what Claude should know about the codebase, and it stays loaded whichever style you pick            |
| Instructions for one kind of task, such as a release checklist or a review procedure                       | A [skill](../08-Plugins-Skills/skills.md)                                             | Claude loads it only when you invoke it or the task matches, so it doesn’t shape unrelated responses         |
| Something to happen every time without exception, such as formatting after each edit or blocking a command | A [hook](../07-Hooks/hooks-guide.md)                                         | Claude Code runs a hook itself at a lifecycle event, so it doesn’t depend on Claude following an instruction |
| A helper with its own instructions, model, and tools for a focused task                                    | A [subagent](../09-Agents-Patterns/sub-agents.md)                                      | It runs in a separate context with its own system prompt and returns a summary to your conversation          |
| An addition to Claude’s instructions that you pass when you start Claude Code                              | [`--append-system-prompt`](cli-reference.md#system-prompt-flags) | It appends to the system prompt without removing anything                                                    |

These features combine. For example, you can use CLAUDE.md for what Claude should know, an output style for how it responds, and a hook for anything that has to be guaranteed. [Extend Claude Code](features-overview.md) compares the rest of the extension features.


[​](#how-output-styles-work)

How output styles work

An output style changes the instructions Claude Code gives Claude.

- Claude Code sends the active style’s instructions with every request.
- On the full system prompt, custom output styles leave out Claude Code’s section of built-in software engineering instructions, such as how to scope changes, write comments, and verify work, unless `keep-coding-instructions` is set to `true`. The shorter system prompt doesn’t include that section, so the field has no effect there. To rely on the field, set [`CLAUDE_CODE_SIMPLE_SYSTEM_PROMPT`](env-vars.md#variables) to `0`, which selects the full prompt on any model.

Output styles apply to the main conversation and to a [fork](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation), which inherits the parent’s whole conversation and system prompt. Other [subagents run their own system prompt](../09-Agents-Patterns/sub-agents.md#what-loads-at-startup), so styles don’t change how they respond. Token usage depends on the style. A style’s instructions add input tokens, though prompt caching reduces this cost after the first request in a session. The built-in Explanatory and Learning styles produce longer responses than Default by design, which increases output tokens. The Concise style does the opposite by instructing Claude to keep responses short by default. For custom styles, output token usage depends on what your instructions tell Claude to produce.


[​](#related-resources)

Related resources

- [Settings](settings.md): where the `outputStyle` field lives and how settings precedence works
- [Permission modes](permission-modes.md): how the Proactive style compares to auto mode
- [Plugins](../08-Plugins-Skills/plugins.md): package and distribute output styles alongside skills, hooks, and agents
- [Debug your configuration](debug-your-config.md): diagnose why an output style isn’t taking effect

---

## Choose a permission mode - Claude Code Docs

Source: https://code.claude.com/docs/en/permission-modes
Path: 02-Claude-Code-CLI/permission-modes.md

## On this page

- [Available modes](#available-modes)
  - [Actions no mode auto-approves](#actions-no-mode-auto-approves)
- [Common setups](#common-setups)
- [Which mode a session starts in](#which-mode-a-session-starts-in)
  - [Tool calls denied in claude -p and Agent SDK runs](#which-mode-a-non-interactive-run-starts-in)
  - [Start in a different permission mode](#start-in-a-different-mode)
  - [Permission modes with the HIPAA configuration](#hipaa-configuration)
- [Switch permission modes](#switch-permission-modes)
- [Auto-approve file edits with acceptEdits mode](#auto-approve-file-edits-with-acceptedits-mode)
- [Analyze before you edit with plan mode](#analyze-before-you-edit-with-plan-mode)
  - [Review and approve a plan](#review-and-approve-a-plan)
  - [Set plan mode as the default](#set-plan-mode-as-the-default)
- [Eliminate permission prompts with auto mode](#eliminate-prompts-with-auto-mode)
  - [Auto mode on Bedrock, Agent Platform, or Foundry](#enable-auto-mode-on-bedrock-agent-platform-or-foundry)
  - [Server-side classifier review](#server-side-classifier-review)
  - [Default classifier model](#default-classifier-model)
  - [Choose the classifier model](#choose-the-classifier-model)
  - [When your model doesn’t review](#classifier-model-not-reviewing)
  - [Check which model the classifier used](#classifier-model-check)
  - [What the classifier blocks by default](#what-the-classifier-blocks-by-default)
  - [The first read outside the working directories](#first-read-outside-the-working-directories)
  - [Boundaries you state in conversation](#boundaries-you-state-in-conversation)
  - [Approvals you state in conversation](#approvals-you-state-in-conversation)
  - [When auto mode falls back](#when-auto-mode-falls-back)
  - [Repeated-block thresholds](#repeated-block-thresholds)
  - [How auto mode evaluates actions](#how-auto-mode-evaluates-actions)
- [Allow only pre-approved tools with dontAsk mode](#allow-only-pre-approved-tools-with-dontask-mode)
- [Skip all checks with bypassPermissions mode](#skip-all-checks-with-bypasspermissions-mode)
  - [Bypass permissions ignored in a background session](#bypass-permissions-ignored-in-a-background-session)
  - [claude agents shows the bypass permissions warning that interactive sessions skip](#claude-agents-shows-the-bypass-permissions-warning-that-interactive-sessions-skip)
- [Protected paths](#protected-paths)
- [Critical paths](#critical-paths)
  - [Which paths are critical](#which-paths-are-critical)
  - [Other targets that count as critical paths](#other-targets-that-count-as-critical-paths)
  - [Removals inside nested commands and inline scripts](#removals-inside-nested-commands-and-inline-scripts)
  - [Rewrite a flagged command](#rewrite-a-flagged-command)
  - [The mounted drive prompt](#the-mounted-drive-prompt)
  - [Paths that get the mounted drive prompt](#paths-that-get-the-mounted-drive-prompt)
  - [Turn off the mounted drive prompt](#turn-off-the-mounted-drive-prompt)
  - [Removals that still prompt with the mounted drive prompt off](#removals-that-still-prompt-with-the-mounted-drive-prompt-off)
  - [Critical-path removals in each permission mode](#critical-path-removals-in-each-permission-mode)
  - [Time limits and denials in auto and bypassPermissions modes](#time-limits-and-denials-in-auto-and-bypasspermissions-modes)
  - [Remove-Item in PowerShell](#remove-item-in-powershell)
- [See also](#see-also)

Permissions and sandboxing

# Choose a permission mode

Copy pageCopy page

Control whether Claude asks before acting. Switch permission modes with Shift+Tab in the CLI, the mode indicator in VS Code, or the mode selector in Desktop.

Copy pageCopy page

A permission mode sets which actions Claude can take in a session without asking you first. In Manual mode, Claude Code stops and asks you before most actions that edit files, run shell commands, or reach the network. In [auto mode](#eliminate-prompts-with-auto-mode), a second model, the classifier, reviews actions instead of you; [how the classifier evaluates actions](#how-the-classifier-evaluates-actions) lists which actions it reviews and which skip it. With Claude Code v2.1.283 or later, auto mode is the built-in starting permission mode for interactive terminal and VS Code sessions. On earlier versions, it’s the built-in starting permission mode only on Pro, Max, and Team plans. [Which mode a session starts in](#which-mode-a-session-starts-in) covers the surfaces and settings that change the starting permission mode. You can also change a running session’s permission mode at any time.


[​](#available-modes)

Available modes

Each mode makes a different tradeoff between convenience and oversight. The table below shows what Claude can do without a permission prompt in each mode. Manual mode appears under its config value, `default`.

| Mode                                                                | What runs without asking                                                                                                                                                                                    | Best for                                        |
|:--------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------|
| `default`                                                           | Reads only                                                                                                                                                                                                  | Reviewing every action yourself, sensitive work |
| [`acceptEdits`](#auto-approve-file-edits-with-acceptedits-mode)     | Reads, file edits, and common filesystem commands (`mkdir`, `touch`, `mv`, `cp`, etc.)                                                                                                                      | Iterating on code you’re reviewing              |
| [`plan`](#analyze-before-you-edit-with-plan-mode)                   | Reads, plus classifier-approved commands when [auto mode](#eliminate-prompts-with-auto-mode) is available                                                                                                   | Exploring a codebase before changing it         |
| [`auto`](#eliminate-prompts-with-auto-mode)                         | Everything, with background safety checks                                                                                                                                                                   | Long tasks, reducing prompt fatigue             |
| [`dontAsk`](#allow-only-pre-approved-tools-with-dontask-mode)       | File reads inside your working directories and pre-approved tools; anything that would prompt is denied, though a [mod](../08-Plugins-Skills/plugins-mods-overview.md) you installed can still approve some of those calls | Locked-down CI and scripts                      |
| [`bypassPermissions`](#skip-all-checks-with-bypasspermissions-mode) | Everything                                                                                                                                                                                                  | Isolated containers and VMs only                |

The mode that reviews every action is named **Manual** in the CLI, in `claude --help`, in the VS Code and JetBrains extensions, and in the desktop app. Its config value is `default`, which is what hooks and SDK integrations use. The CLI accepts `manual` as an alias wherever you type the value, for example `claude --permission-mode manual` or `"defaultMode": "manual"`. Writes to [protected paths](#protected-paths) are never auto-approved except in `bypassPermissions` mode and in plan-mode sessions where bypass permissions are available, meaning interactive terminal sessions started in a way that [puts `bypassPermissions` in the mode cycle](#switch-permission-modes). Modes set the baseline. Layer [permission rules](permissions.md#manage-permissions) on top to pre-approve or block specific tools. Deny rules block in every mode, including `bypassPermissions`. Deny and ask rules don’t apply to [`EndConversation`](tools-reference.md#endconversation-tool-behavior) as long as Claude still has at least one other tool it can call. Allow rules have no effect in `bypassPermissions`.


[​](#actions-no-mode-auto-approves)

Actions no mode auto-approves

Claude Code doesn’t auto-approve the following in any mode, including `bypassPermissions`. Each bullet links to the section that says what happens instead in each mode:

- Tools matched by an explicit [ask rule](permissions.md#manage-permissions)
- Connector tools your organization [set to `ask`](../06-MCP-Tools/General/mcp.md#organization-controls-on-connector-tools), in sessions where that setting reaches Claude Code
- Tools that require user interaction: the built-in `AskUserQuestion` tool and MCP tools marked [`requiresUserInteraction`](../06-MCP-Tools/General/mcp.md#require-approval-for-a-specific-tool)
- Recognized `rm` and `rmdir` [critical-path removals](#critical-paths), which no allow rule or `PreToolUse` hook `"allow"` approves
- The [cross-session messaging safeguards](#skip-all-checks-with-bypasspermissions-mode)
- Reads outside the working directories while [`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) is on: recognized file-reading Bash commands prompt even in auto mode and `bypassPermissions` mode, and so does any [unsandboxed retry](sandboxing.md#the-unsandboxed-retry-escape-hatch) that needs approval to run outside the sandbox. Requires Claude Code v2.1.257 or later. A command the shell parser can’t trace, such as one that changes directory more than once or runs a subshell, prompts the same way even when it names no outside path. This prompt doesn’t apply when the command runs in the [sandbox](sandboxing.md) and the sandbox enforces the block.


[​](#common-setups)

Common setups

Permission modes decide whether Claude asks before an action, and the [Bash sandbox](sandboxing.md) and outer [isolation boundaries](sandbox-environments.md) decide what an action can reach once it runs. Each row below pairs a goal with the flags or settings that get you there and the isolation it needs, as a starting point. [Available modes](#available-modes) lists what runs without a prompt in each mode.

| You want to                                              | Start with                                                                                                                                                               | Isolation needed                                                                                                                                                                                  | Notes                                                                                                                                                                                                                                                                                                                                  |
|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Review every action yourself                             | Manual mode: `claude --permission-mode default`                                                                                                                          | None                                                                                                                                                                                              | Sensitive work, unfamiliar code                                                                                                                                                                                                                                                                                                        |
| Iterate locally with fewer prompts, without a classifier | Manual mode plus the Bash sandbox in [auto-allow mode](sandboxing.md#sandbox-modes): `claude --permission-mode default`, then run `/sandbox` and select auto-allow | The built-in Bash sandbox, on macOS, Linux, and WSL2                                                                                                                                              | Deny rules still apply, and ask rules that name a command, such as `Bash(git push *)`, still prompt. [Auto-allow mode](sandboxing.md#auto-allow-mode) covers other commands that can prompt. To turn the sandbox on from a settings file instead, set [`sandbox.enabled`](settings-reference.md#sandbox-enabled) to `true` |
| Explore before changing anything                         | `claude --permission-mode plan`                                                                                                                                          | None                                                                                                                                                                                              | Claude Code blocks edits until you [approve a plan](#review-and-approve-a-plan)                                                                                                                                                                                                                                                        |
| Work hands-off in auto mode                              | `claude --permission-mode auto`, the [built-in starting permission mode](#which-mode-a-session-starts-in) with v2.1.283 or later                                         | None; a sandbox or container adds defense in depth                                                                                                                                                | Requires a [supported model](#eliminate-prompts-with-auto-mode), and your organization can [turn auto mode off](#eliminate-prompts-with-auto-mode)                                                                                                                                                                                     |
| Run in CI with an exact allowlist                        | `claude -p "run the test suite" --permission-mode dontAsk --allowedTools "Bash(npm test)" "Read"`                                                                        | None beyond what your CI runner provides                                                                                                                                                          | [Cloud sessions](claude-code-on-the-web.md) ignore `dontAsk` from settings files                                                                                                                                                                                                                                                 |
| Run fully unattended inside a container                  | `claude -p "<prompt>" --dangerously-skip-permissions`                                                                                                                    | Required: a container, VM, or the [sandbox runtime](sandbox-environments.md#sandbox-runtime); on Linux and macOS, run it as a [non-root user](#skip-all-checks-with-bypasspermissions-mode) | Cloud sessions ignore this mode from settings files. In this `-p` run, the [few calls that would still prompt](#skip-all-checks-with-bypasspermissions-mode) are denied instead                                                                                                                                                        |

The Bash sandbox and auto mode work independently and combine, with the exceptions listed under [Sandbox modes](sandboxing.md#sandbox-modes). For the full interaction, see [How sandboxing relates to permissions and permission modes](sandboxing.md#how-sandboxing-relates-to-permissions-and-permission-modes) and [How isolation relates to permission modes](sandbox-environments.md#how-isolation-relates-to-permission-modes).


[​](#which-mode-a-session-starts-in)

Which mode a session starts in

When you start a new session in a terminal, Claude Code takes the permission mode from the first of these that applies:

1.  The `--permission-mode` flag, or `--dangerously-skip-permissions`
2.  `permissions.defaultMode` in a [settings file](settings.md#where-settings-live) If you set `"auto"` in `.claude/settings.json` or `.claude/settings.local.json`, the value doesn’t take effect, and Claude Code then uses the built-in default rather than a `defaultMode` from `~/.claude/settings.json`. If you set `"bypassPermissions"` in those two files, it doesn’t take effect either, and the session starts in Manual mode. The other values apply from any settings file.
3.  The built-in default

Conversations the VS Code extension starts follow the extension’s own list in [Switch permission modes](#switch-permission-modes). For the permission mode Claude Code starts a resumed session in, see [permission mode on resume](sessions.md#permission-mode-on-resume). The built-in `auto` default requires Claude Code v2.1.228 or later on macOS, Linux, and WSL, and v2.1.233 or later on native Windows. On earlier versions, the built-in default is Manual. The built-in default depends on how you run Claude Code. The first row that matches your session applies. The table covers sessions you start in a terminal or through the VS Code extension; for the desktop app and claude.ai, see the Desktop and Web tabs in [Switch permission modes](#switch-permission-modes).

| How you run Claude Code                                                                                                                                                           | Built-in starting permission mode                                                                                                                                                                                             |
|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Any settings file sets `disableAutoMode` to `"disable"`                                                                                                                           | `default`                                                                                                                                                                                                                     |
| `claude -p` or the [Agent SDK](../05-Agent-SDK/agent-sdk-permissions.md#permission-modes)                                                                                                   | `default`                                                                                                                                                                                                                     |
| Your organization has the [HIPAA configuration](#hipaa-configuration) applied and the session is [eligible for it](hipaa-setup.md#check-how-developers-sign-in-and-connect) | `default` with Claude Code v2.1.285 or later; auto mode stays available to switch to                                                                                                                                          |
| In a terminal or through the [VS Code extension](../03-IDE-Integrations/vs-code.md)                                                                                                                | `auto` with Claude Code v2.1.283 or later; on earlier versions, `auto` on Pro, Max, or Team plans in sessions that [fetch feature flags](env-vars.md#features-that-need-feature-flag-fetching), and `default` otherwise |

When the flag, a settings file, or the built-in default selects `auto` but auto mode isn’t available to the session, Claude Code starts the session in Manual instead. Auto mode is unavailable when the session doesn’t meet the [availability requirements](#eliminate-prompts-with-auto-mode), such as a settings file turning it off or a model that doesn’t support it, or when Anthropic has temporarily turned it off server-side. The first time the built-in default starts one of your sessions in auto mode, Claude Code shows a notice that links to this page:

- In a terminal, once, at the top of the session
- In the VS Code extension, as a card on the new-conversation screen that stays until you dismiss it

If your `~/.claude/settings.json` sets a `defaultMode` other than `auto` and no other settings file sets one, your sessions keep starting in that mode. On Pro, Max, and Team plans, and in sessions that [don’t fetch feature flags](env-vars.md#features-that-need-feature-flag-fetching), Claude Code asks once, in the terminal or in the VS Code extension, whether to change the setting to auto mode. If you decline, your setting stays as it is.


[​](#which-mode-a-non-interactive-run-starts-in)

Tool calls denied in `claude -p` and Agent SDK runs

In Claude Code v2.1.302 or later, `claude -p` and [Agent SDK](../05-Agent-SDK/agent-sdk-permissions.md#permission-modes) runs with [no permission mode set](#which-mode-a-session-starts-in) start in Manual mode. This mode appears as `default` in SDK options and settings. Calls needing approval are denied unless you approve them with an allow rule, hook, `canUseTool` callback, or `--permission-prompt-tool`. To get these calls approved, add allow rules or start in auto mode:

- **[Add allow rules](permissions.md#manage-permissions)**: Claude runs the calls you list. Pass [`--allowedTools "Bash(npm test)"`](headless.md#auto-approve-tools) to `claude -p`, or set your SDK’s [allowed-tools option](../05-Agent-SDK/agent-sdk-permissions.md#allow-and-deny-rules).
- **Start in [auto mode](#eliminate-prompts-with-auto-mode)**: a classifier model reviews calls, so you list nothing beforehand. Pass `--permission-mode auto` to `claude -p`, or set your SDK’s [permission mode option](../05-Agent-SDK/agent-sdk-permissions.md#set-permission-mode).

These examples show the auto mode form for the CLI and each SDK:

- CLI

- TypeScript

- Python

```python
claude -p "Run the test suite and fix any failures" --permission-mode auto
```

```python
const options = {
  permissionMode: "auto"
};
```

```python
from claude_agent_sdk import ClaudeAgentOptions

options = ClaudeAgentOptions(permission_mode="auto")
```

Before v2.1.302, these runs could start in auto mode if they didn’t [fetch feature flags](env-vars.md#features-that-need-feature-flag-fetching), for example on a [third-party provider](third-party-integrations.md) or with `DISABLE_TELEMETRY`.


[​](#start-in-a-different-mode)

Start in a different permission mode

You can set the starting permission mode for one session, or as a default for every session on a machine, in a project, or in an organization. When more than one settings file sets `permissions.defaultMode`, [settings precedence](settings.md#settings-precedence) decides, so a project or managed value outranks `~/.claude/settings.json`. To change the permission mode of a session that’s already running, see [Switch permission modes](#switch-permission-modes).

| To set the starting permission mode for          | Do this                                                                                                                                                                                                                                                                                                                                                             |
|:-------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| One session you’re about to start                | Pass the permission mode as a flag, for example `claude --permission-mode default`                                                                                                                                                                                                                                                                                  |
| Every terminal session you start on this machine | Set `permissions.defaultMode` in `~/.claude/settings.json`. For what the VS Code extension reads, see [Switch permission modes](#switch-permission-modes)                                                                                                                                                                                                           |
| Every terminal session you start in one project  | Set `permissions.defaultMode` in the project’s `.claude/settings.json`. Sessions you start in a terminal honor every value except `auto` and `bypassPermissions`; sessions the VS Code extension starts don’t read project settings for the starting permission mode                                                                                                |
| Every terminal session in your organization      | Set `permissions.defaultMode` in [managed settings](../13-Enterprise-Admin/managed-settings.md). Terminal sessions start in that mode and people can still switch to auto mode; for what the VS Code extension reads, see [Switch permission modes](#switch-permission-modes). To remove auto mode so nobody can select it, set `permissions.disableAutoMode` to `"disable"` instead |

This example makes every terminal session on your machine start in Manual mode, whose config value is `default`. Save it in `~/.claude/settings.json`:

```python
{
  "permissions": {
    "defaultMode": "default"
  }
}
```

The next session you start shows `⏸ manual mode on` in the status bar.


[​](#hipaa-configuration)

Permission modes with the HIPAA configuration

In an organization with the [HIPAA configuration](hipaa-setup.md) applied, the built-in `auto` default doesn’t apply. A terminal or VS Code session starts in Manual mode when nothing else chooses its starting permission mode. A terminal session also shows `Auto mode isn't the default for your organization · Shift+Tab to switch`, and the VS Code extension shows no notice. [Check how developers sign in and connect](hipaa-setup.md#check-how-developers-sign-in-and-connect) lists the sessions this applies to. Auto mode and `bypassPermissions` stay available:

- **Switch to auto mode**: press `Shift+Tab`, or use [your interface’s control](#switch-permission-modes)
- **Start in auto mode**: pass `--permission-mode auto`, or set `permissions.defaultMode` to `auto` in your user settings, or in managed settings for your whole organization. See [Start in a different permission mode](#start-in-a-different-mode)
- **Remove auto mode**: set [`permissions.disableAutoMode`](settings-reference.md#disableautomode) to `"disable"` in managed settings
- **Block `bypassPermissions`**: set [`permissions.disableBypassPermissionsMode`](settings-reference.md#permissions-disablebypasspermissionsmode) to `"disable"` in managed settings

Requires Claude Code v2.1.285 or later, the [minimum version for the HIPAA configuration](hipaa-setup.md#update-claude-code-and-claude-desktop).


[​](#switch-permission-modes)

Switch permission modes

Each interface has its own control for switching permission modes during a session and its own way of choosing the permission mode new sessions start in. Select your interface to see its controls.

- CLI

- VS Code

- JetBrains

- Desktop

- Web and mobile

**During a session**: press `Shift+Tab` to cycle permission modes. From `auto`, the first press switches to `default`, and the cycle then runs `default` → `acceptEdits` → `plan`. Optional modes slot in after `plan`. The status bar shows the active mode as a gray `⏸ manual mode on` for `default`, or as `⏵⏵ accept edits on`, `⏸ plan mode on`, `⏵⏵ auto mode on`, `⏵⏵ don't ask on`, or `⏵⏵ bypass permissions on`.Watch the status bar in this clip of a session that started in auto mode. Each time you press `Shift+Tab`, it changes from `auto mode on` to `manual mode on`, `accept edits on`, `plan mode on`, and back to `auto mode on`.

Not every mode is in the default cycle:

- `auto`: appears when [auto mode is available](#eliminate-prompts-with-auto-mode); cycling to it switches permission modes without a confirmation prompt
- `bypassPermissions`: appears after you start with `--permission-mode bypassPermissions`, `--dangerously-skip-permissions`, `--allow-dangerously-skip-permissions`, or `permissions.defaultMode: "bypassPermissions"` in [user, `--settings`, or managed settings](settings-reference.md#permissions-defaultmode). The `--allow-` variant adds the permission mode to the cycle without activating it
- `dontAsk`: never appears in the cycle; set it with `--permission-mode dontAsk`

Enabled optional modes slot in after `plan`, with `bypassPermissions` first and `auto` last. If you have both enabled, you will cycle through `bypassPermissions` on the way to `auto`.**From a Bash permission prompt**: in the Manual and `acceptEdits` permission modes, when [auto mode](#eliminate-prompts-with-auto-mode) is available, Claude Code adds **Yes, and switch to auto mode** to a Bash command’s permission prompt. Select it to approve the command and switch the session to auto mode. [PowerShell tool](tools-reference.md#powershell-tool) prompts don’t offer the option. Requires Claude Code v2.1.247 or later.Claude Code doesn’t add the option to prompts forced by one of your [`ask` rules](permissions.md#manage-permissions) or by a [hook](../07-Hooks/hooks.md#pretooluse-decision-control), because auto mode still shows you those prompts, so switching wouldn’t remove them.**At startup**: pass the permission mode as a flag.

```python
claude --permission-mode plan
```

**As a default**: set `permissions.defaultMode` at the scope you want, as described in [Start in a different permission mode](#start-in-a-different-mode).The same `--permission-mode` flag works with `-p` for [non-interactive runs](headless.md).

**During a session**: click the mode indicator at the bottom of the prompt box. It uses these labels for the modes on this page:

| UI label           | Mode                |
|:-------------------|:--------------------|
| Manual             | `default`           |
| Edit automatically | `acceptEdits`       |
| Plan               | `plan`              |
| Auto               | `auto`              |
| Bypass permissions | `bypassPermissions` |

**As a default**: to pin the permission mode conversations start in, set `claudeCode.initialPermissionMode` in your VS Code user settings to `default`, `manual`, `acceptEdits`, `plan`, or `bypassPermissions`. The setting doesn’t accept `auto`; to start in Auto, leave it unset and pick **Auto** from the mode indicator once, as item 2 below describes. The extension starts each new conversation in the first of these that applies:

1.  `claudeCode.initialPermissionMode`
2.  The mode you last picked from the mode indicator, if it was Manual, Edit automatically, or Auto. Picking Plan or Bypass permissions applies to that conversation only
3.  `permissions.defaultMode` from [managed settings](../13-Enterprise-Admin/managed-settings.md) or `~/.claude/settings.json`
4.  The [built-in default](#which-mode-a-session-starts-in) for your plan, provider, and organization settings

The extension never reads a project’s `.claude/settings.json` or `.claude/settings.local.json` for the starting permission mode. When `claudeCode.claudeProcessWrapper` is set, items 3 and 4 don’t apply: those conversations start in Manual unless item 1 or item 2 sets a permission mode.Before v2.1.283, item 3 applied only on Pro, Max, and Team plans in sessions that [fetch feature flags](env-vars.md#features-that-need-feature-flag-fetching).Auto appears in the mode indicator when [auto mode is available](#eliminate-prompts-with-auto-mode).Bypass permissions requires the **Allow dangerously skip permissions** toggle in the extension settings. Without it, the permission mode doesn’t appear in the indicator, and a `bypassPermissions` value from item 1 or item 3 starts the conversation in Manual instead. Auto from any item likewise starts the conversation in Manual when auto mode isn’t available.See the [VS Code guide](../03-IDE-Integrations/vs-code.md) for extension-specific details.

The JetBrains plugin runs Claude Code in the IDE terminal, so switching permission modes works the same as in the CLI: press `Shift+Tab` to cycle, or pass `--permission-mode` when launching.

**During a session**: in the Code tab, use the mode selector in the row under the prompt box. Not every mode appears in the selector:

- **Auto**: appears when [auto mode is available](#eliminate-prompts-with-auto-mode)
- **Bypass permissions**: requires the **Allow bypass permissions mode** toggle in Desktop settings on Pro and Max plans; on Team and Enterprise plans, organization policy controls it instead

Cowork doesn’t use these modes. It has its own permission modes, enabled separately, and shows no mode selector at all until a mode beyond its default is enabled for your account. See the [Cowork docs](https://claude.com/docs/cowork/overview).For desktop-specific details, see [Choose a permission mode](../16-Mobile-Desktop/desktop.md#choose-a-permission-mode) in the Desktop guide.**As a default**: set `defaultMode` in [settings](settings.md#where-settings-live). The desktop app reads the same settings files as the CLI and applies the permission mode to new local sessions.A mode you pick in the mode selector is remembered per folder and takes precedence over `defaultMode` for that folder. Plan is the exception: picking it applies to the current session only.For where `defaultMode` goes in a settings file, see the example under [Start in a different permission mode](#start-in-a-different-mode).

On [claude.ai/code](https://claude.ai/code), use the mode dropdown next to the prompt box. In the mobile app, tap the **+** button in the prompt box, then **Permission**. Cloud sessions and Remote Control sessions offer different permission modes:

- **[Cloud sessions](claude-code-on-the-web.md)**: Accept edits, Plan, and Auto. Accept edits corresponds to `default` mode: cloud sessions pre-approve file edits regardless of mode, so the dropdown shows Accept edits instead of Manual. Cloud sessions still honor `defaultMode: "acceptEdits"` from settings. Auto mode appears only when your organization allows it and the selected model supports it. Bypass permissions isn’t available.
- **[Remote Control](remote-control.md) sessions** on your local machine: Manual, Accept edits, Plan, and Auto for a session you started yourself, and you can’t select Bypass permissions from the app. To use Auto, the session has to meet the auto mode [availability requirements](#eliminate-prompts-with-auto-mode). For a project thread running on your computer, see [Run a thread on your own computer](claude-projects.md#run-a-thread-on-your-own-computer).
  - Except for Bypass permissions, the dropdown shows the permission mode the local session is in, including one set from the terminal. It updates when the permission mode changes in the app or in the terminal.
  - Sessions hosted by the [desktop app](../16-Mobile-Desktop/desktop.md) or the [VS Code extension](../03-IDE-Integrations/vs-code.md) report permission mode changes to claude.ai as they happen, the same as sessions hosted in a terminal.

For Remote Control, the local machine running the session must be signed in with your claude.ai account; API keys aren’t supported. You can also set the starting permission mode when launching that local session:

```python
claude remote-control --permission-mode acceptEdits
```


[​](#auto-approve-file-edits-with-acceptedits-mode)

Auto-approve file edits with acceptEdits mode

`acceptEdits` mode lets Claude create and edit files in your working directory without prompting. The status bar shows `⏵⏵ accept edits on` while this mode is active. In addition to file edits, `acceptEdits` mode auto-approves common filesystem Bash commands: `mkdir`, `touch`, `rm`, `rmdir`, `mv`, `cp`, and `sed`. These commands are also auto-approved when prefixed with safe environment variables such as `LANG=C` or `NO_COLOR=1`, or process wrappers such as `timeout`, `nice`, or `nohup`. Like file edits, auto-approval applies only to paths inside your working directory or `additionalDirectories`. These still prompt:

- Paths outside that scope
- Writes to [protected paths](#protected-paths)
- Recognized `rm` and `rmdir` [critical-path removals](#critical-paths)
- All other Bash commands except the [built-in read-only set](permissions.md#read-only-commands)

Each path also goes through the [symlink check](permissions.md#symlinks), so a write that resolves outside that scope isn’t auto-approved either. When the [PowerShell tool](tools-reference.md#powershell-tool) is enabled, `acceptEdits` mode also auto-approves `Set-Content`, `Add-Content`, `Clear-Content`, and `Remove-Item` on in-scope paths, along with their common aliases. The same scope and protected-path rules apply, and `Remove-Item` gets [its own check](#remove-item-in-powershell). A positional argument that contains a quote character, such as the apostrophe in `Set-Content .\notes.txt "It's done"`, still prompts even on in-scope paths, because Claude Code can’t statically validate an argument whose quoted and unquoted readings differ. Pass the content through a named parameter such as `-Value` to avoid the prompt. Use `acceptEdits` when you want to review changes in your editor or via `git diff` after the fact rather than approving each edit inline. Press `Shift+Tab` once from Manual mode to enter it, or start with it directly:

```python
claude --permission-mode acceptEdits
```


[​](#analyze-before-you-edit-with-plan-mode)

Analyze before you edit with plan mode

Plan mode tells Claude to research and propose changes without making them. Claude reads files, runs shell commands to explore, and writes a plan, but does not edit your source. Except in interactive terminal sessions with [bypass permissions available](#skip-all-checks-with-bypasspermissions-mode), edits stay blocked until you approve the plan. What happens to a shell command during planning depends on the session, and the first of these cases that matches applies:

- **Interactive terminal sessions with bypass permissions available**: neither the classifier nor a prompt applies to planning commands. [Skip all checks with bypassPermissions mode](#skip-all-checks-with-bypasspermissions-mode) covers the few things that still prompt there.
- **[Auto mode](auto-mode-config.md) available and the `useAutoModeDuringPlan` setting on**, which it is by default: the classifier reviews shell commands other than [critical-path removals](#critical-paths) instead of prompting you. Approved commands run, and rejected ones are blocked.
- **Auto mode not available, or `useAutoModeDuringPlan` off**: commands outside the [built-in read-only set](permissions.md#read-only-commands) prompt for approval, including when the sandbox’s [auto-allow mode](sandboxing.md#sandbox-modes) is enabled.

Enter plan mode by pressing `Shift+Tab` or prefixing a single prompt with `/plan`. You can also start in plan mode from the CLI:

```python
claude --permission-mode plan
```

Press `Shift+Tab` again to leave plan mode without approving a plan.


[​](#review-and-approve-a-plan)

Review and approve a plan

When the plan is ready, Claude presents it and asks how to proceed. From that prompt you can choose:

- **Yes, and use auto mode**: approve and start in [auto mode](#eliminate-prompts-with-auto-mode). If auto mode isn’t [available to your session](#eliminate-prompts-with-auto-mode), for example because your organization turned it off, this option reads **Yes, auto-accept edits**. If you started the session with bypass permissions enabled, the option reads **Yes, and switch to BYPASS PERMISSIONS (no further prompts) for this session** instead.
- **Yes, manually approve edits**: approve and review each edit individually.
- **No, keep planning**: stay in plan mode and tell Claude what to change.

Approving a plan exits plan mode and switches the session to the permission mode each approve option describes, so Claude starts editing. To plan again, cycle back to plan mode with `Shift+Tab`, or prefix your next prompt with `/plan`. Press `Ctrl+G` to open the proposed plan in your default text editor and edit it directly before Claude proceeds. When [`showClearContextOnPlanAccept`](settings-reference.md#showclearcontextonplanaccept) is enabled, the list gains a first option that approves the plan and clears the planning context. Accepting a plan also gives the session a [generated title](sessions.md#name-your-sessions) based on the plan, unless you’ve already named the session.


[​](#set-plan-mode-as-the-default)

Set plan mode as the default

To make plan mode the default for a project’s terminal sessions, set `defaultMode` to `plan` in `.claude/settings.json`, placed as the example under [Start in a different permission mode](#start-in-a-different-mode) shows. Conversations the [VS Code extension](../03-IDE-Integrations/vs-code.md) starts don’t read project settings for the starting permission mode. There, set `claudeCode.initialPermissionMode` to `plan` in your VS Code user settings instead.


[​](#eliminate-prompts-with-auto-mode)

Eliminate permission prompts with auto mode

Auto mode lets Claude execute without routine permission prompts. A separate classifier model reviews actions before they run, blocking anything that escalates beyond your request, targets unrecognized infrastructure, or appears driven by hostile content Claude read. Explicit [ask rules](permissions.md#manage-permissions) still force a prompt. With Claude Code v2.1.283 or later, auto mode is the [built-in starting permission mode](#which-mode-a-session-starts-in) for interactive terminal and VS Code sessions on every plan and provider. On earlier versions, it’s the built-in starting permission mode only on Pro, Max, and Team plans. The classifier also reviews each message Claude sends to another agent with [`SendMessage`](tools-reference.md), whether plain text or a structured [agent team](../09-Agents-Patterns/agent-teams.md) message, before Claude Code delivers it, both in auto mode and in [plan mode while the classifier reviews commands](#analyze-before-you-edit-with-plan-mode); the send review requires Claude Code v2.1.222 or later. By default, the classifier doesn’t review recognized `rm` and `rmdir` critical-path removals, such as `rm -rf /` or `rm -rf ~`. [Critical paths](#critical-paths) covers what happens to them in each permission mode. Auto mode also nudges Claude to keep working without stopping for clarifying questions, though Claude still asks when your prompt or a skill explicitly relies on it. For stronger autonomous behavior in a mode that still prompts you, set the [Proactive output style](output-styles.md) instead.

Auto mode reduces permission prompts but does not guarantee safety. Use it for tasks where you trust the general direction, not as a replacement for review on sensitive operations.

Auto mode is available only when your account meets all of these requirements:

- **Plan**: All plans.
- **Organization**: on Team and Enterprise, auto mode is available by default. Administrators can turn it off for the organization by setting `permissions.disableAutoMode` to `"disable"` in [managed settings](../13-Enterprise-Admin/managed-settings.md).
- **Model**: on the Anthropic API and [Claude Platform on AWS](claude-platform-on-aws.md), Claude Opus 4.6 or later, Sonnet 4.6 or later, Haiku 5.5, or a [Fable model](model-config.md#work-with-fable). On Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and signed-in [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sessions, only Claude Sonnet 5 or later, Opus 4.7 or later, Haiku 5.5, and the Fable models. Older models, including Sonnet 4.5, Opus 4.5, Haiku 4.5, and claude-3 models, are not supported on any provider.
- **Provider**: available by default on the Anthropic API, Claude Platform on AWS, Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and signed-in Claude apps gateway sessions.

If Claude Code reports auto mode as unavailable, first check these requirements and whether any settings file sets [`disableAutoMode`](settings-reference.md#disableautomode). Anthropic may also have turned auto mode off server-side, or the server may have rejected auto mode for your account. A session that received either answer keeps auto mode off until the session ends, so start a new session later. A separate message that names a model and says auto mode “cannot determine the safety” of an action means a classifier request failed. That failure is usually transient, but on Amazon Bedrock it can repeat until your account can invoke the named model. See the [error reference](errors.md#auto-mode-cannot-determine-the-safety-of-an-action) for the causes and what to do. If you set `defaultMode: "auto"` in [settings](settings-reference.md#all-settings) and a terminal session starts in Manual mode with no error, the setting is likely in `.claude/settings.json` or `.claude/settings.local.json`. `auto` doesn’t take effect from those files. Move it to `~/.claude/settings.json`. For a conversation the VS Code extension started, check the extension’s own list in [Switch permission modes](#switch-permission-modes) instead.


[​](#enable-auto-mode-on-bedrock-agent-platform-or-foundry)

Auto mode on Bedrock, Agent Platform, or Foundry

On [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), [Microsoft Foundry](microsoft-foundry.md), and signed-in [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sessions, auto mode is available by default. If you don’t set a permission mode there, interactive sessions start in auto mode, and `claude -p` or Agent SDK runs start in Manual mode, whose config value is `default`:

- **Interactive terminal and VS Code sessions**: to start them in a permission mode other than auto, set `permissions.defaultMode` as [Start in a different permission mode](#start-in-a-different-mode) describes, or pick one from the VS Code extension’s [mode indicator](#switch-permission-modes). [Which mode a session starts in](#which-mode-a-session-starts-in) lists the Claude Code versions that start them in auto mode.
- **`claude -p` and Agent SDK runs**: to start one in auto mode, pass `--permission-mode auto` to `claude -p`, or pass `permissionMode: "auto"` in TypeScript or `permission_mode="auto"` in Python. If you pass no permission mode, see [Tool calls denied in `claude -p` and Agent SDK runs](#which-mode-a-non-interactive-run-starts-in), which also covers earlier Claude Code versions.

Only Claude Sonnet 5 or later, Opus 4.7 or later, Haiku 5.5, and the Fable models are supported on these providers. On any other model, the session starts in Manual instead. Auto mode with Haiku 5.5 on these providers requires Claude Code v2.1.293 or later. To prevent developers from using auto mode, set `disableAutoMode` to `"disable"` in [managed settings](../13-Enterprise-Admin/managed-settings.md). This removes `auto` from the `Shift+Tab` cycle, and a session started with `--permission-mode auto` starts in Manual instead. A session already running in auto mode leaves it when the setting reaches that session from an [admin-deployed source](../13-Enterprise-Admin/managed-settings.md#which-managed-source-claude-code-uses), and shows `auto mode disabled by settings`. Before v2.1.251, a running session kept auto mode until it ended.


[​](#server-side-classifier-review)

Server-side classifier review

In auto mode, Claude Code can ask the server to check the actions that [the decision order](#how-the-classifier-evaluates-actions) sends for review, as part of the session’s model requests, in place of sending its own classifier requests. These sessions ask:

- **A direct connection to the Anthropic API**: in interactive terminal sessions and in `-p`, Agent SDK, [VS Code extension](../03-IDE-Integrations/vs-code.md), and [desktop app](../16-Mobile-Desktop/desktop.md) sessions, whatever your plan or account type, as Anthropic rolls it out. In interactive terminal sessions, this requires Claude Code v2.1.271 or later on Pro, Max, and Team plans, and v2.1.278 or later on Enterprise plans and Claude API accounts. In `-p`, Agent SDK, VS Code extension, and desktop app sessions, this requires Claude Code v2.1.281 or later. From v2.1.282, a session that [doesn’t fetch feature flags](env-vars.md#features-that-need-feature-flag-fetching), for example because you turned telemetry off, asks the server by default in any kind of session.
- **A cloud provider, or an LLM gateway or proxy**: on [Claude Platform on AWS](claude-platform-on-aws.md), Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry, and whenever you point `ANTHROPIC_BASE_URL` at an [LLM gateway or proxy](../13-Enterprise-Admin/llm-gateway.md), whatever your plan. Asking by default requires Claude Code v2.1.278 or later.
- **A signed-in [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md) session**: requires Claude Code v2.1.280 or later

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

- **The server doesn’t review the session**: a response completes with no review results, or the server answers that it doesn’t review this session. The most common causes are an LLM gateway or proxy that drops the request for review or the results, and a platform, region, or credential that doesn’t have server-side checks yet. Claude Code falls back to its own classifier requests. Once that fallback holds for the rest of the session, it shows a [notice about classifier request charges](../17-Billing-Plans/auto-mode-classifier-billing.md) on accounts where those requests are billed.
- **The server gives no verdict for an action**: Claude Code denies the action rather than run it unreviewed. On any connection, this happens when the response ends before the review results arrive or the results arrive in a form Claude Code can’t read. An LLM gateway or proxy that cuts responses short or rewrites the results can cause either. On a direct connection to the Anthropic API, it also happens when the server’s check fails for the action, for example by timing out. [The server returned no safety verdict](errors.md#the-server-returned-no-safety-verdict) covers the denial message, what happens when denials repeat, and what to do.

To skip asking the server and always use Claude Code’s own classifier requests, set [`CLAUDE_CODE_AUTO_MODE_SERVER=0`](env-vars.md). On a direct connection to the Anthropic API, the variable requires Claude Code v2.1.281 or later. Setting it to `1` there turns server review on in a session that doesn’t have it yet, unless you’ve also set `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1`. If you set `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1` and leave `CLAUDE_CODE_AUTO_MODE_SERVER` unset, Claude Code also stops asking the server, except as [Disable pre-release capabilities](../13-Enterprise-Admin/llm-gateway-protocol.md#disable-pre-release-capabilities) describes.


[​](#default-classifier-model)

Default classifier model

By default, classifier requests go to Claude Sonnet 5. If `/status` shows `Auto mode server` as `Enabled`, they’re sent only for calls outside [the server’s review](#server-side-classifier-review). Find the first row in this table that matches your session. You get that row’s model in place of Sonnet 5.

| Your session                                                                            | Classifier model                                                                  |
|-----------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------|
| Has an Anthropic-configured classifier model                                            | The configured model. [Check the debug log](#classifier-model-check) to see which |
| Runs on Claude Sonnet 4.6                                                               | Sonnet 4.6                                                                        |
| Has [`ANTHROPIC_DEFAULT_SONNET_MODEL`](model-config.md#environment-variables) set | Its value, or Sonnet 5 if its value is Claude Sonnet 5.5 or Claude Opus 5.5       |

If Sonnet 5 or the model in `ANTHROPIC_DEFAULT_SONNET_MODEL` is unavailable from your provider or excluded by your organization’s [model policy](model-config.md#restrict-model-selection), Claude Code uses a fallback model. That’s your session’s model, or an Opus model in a [Fable session](model-config.md#work-with-fable).


[​](#choose-the-classifier-model)

Choose the classifier model

With Claude Code v2.1.302 or later, set [`CLAUDE_CODE_AUTO_MODE_MODEL`](env-vars.md) to a full model ID to run the classifier on a model other than the [default](#default-classifier-model). Your cloud provider’s own full model IDs work too. This `~/.claude/settings.json` example sets Claude Sonnet 4.6:

```python
{
  "env": {
    "CLAUDE_CODE_AUTO_MODE_MODEL": "claude-sonnet-4-6"
  }
}
```


[​](#classifier-model-not-reviewing)

When your model doesn’t review

| Situation                                                                                                                                      | What happens                                                                                                                              | What to do                                    |
|------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
| The [debug log](#classifier-model-check) reports an Anthropic-configured classifier model                                                      | That model reviews                                                                                                                        | None needed                                   |
| You set Claude Opus 5, Sonnet 5.5, Opus 5.5 or one your organization’s [model policy](model-config.md#restrict-model-selection) excludes | The [default classifier model](#default-classifier-model) reviews                                                                         | Set another model                             |
| Your provider can’t serve the model                                                                                                            | Classifier checks fail, so Claude Code [denies each action it checks](errors.md#auto-mode-cannot-determine-the-safety-of-an-action) | Set a model it serves, or remove the variable |
| In a session, `/status` shows [`Auto mode server`](#server-side-classifier-review) as `Enabled`                                                | The server reviews without your model                                                                                                     | None needed                                   |

If several situations apply, go by the first listed.


[​](#classifier-model-check)

Check which model the classifier used

From your shell, start an auto mode session with [`--debug-file`](cli-reference.md#cli-flags):

```python
claude --permission-mode auto --debug-file classifier-debug.log
```

Have Claude run a shell command that isn’t read-only, then search the log for `classifier_request_started`:

- **Your model after `model=`**: the variable took effect
- **A different model after `model=`**: search the log for `ignoring CLAUDE_CODE_AUTO_MODE_MODEL`, which gives the reason and any step to take
- **No such line**: read `Auto mode server` in `/status` at the Claude Code prompt:
  - **`Enabled`**: the [server](#server-side-classifier-review) is set to review this session’s calls.
  - **`Disabled`**: make sure the [permission mode](#switch-permission-modes) is auto, then have Claude run another command that isn’t read-only.


[​](#what-the-classifier-blocks-by-default)

What the classifier blocks by default

The classifier trusts your working directory and the remotes that were configured for it when the session started. A remote added or repointed during the session with `git remote add` or `git remote set-url` isn’t trusted, and everything else is treated as external until you [configure trusted infrastructure](auto-mode-config.md). **Blocked by default**:

- Downloading and executing code, like `curl | bash`
- Sending sensitive data to external endpoints
- Production deploys and migrations
- Mass deletion on cloud storage
- Granting IAM or repo permissions
- Modifying shared infrastructure
- Irreversibly destroying files that existed before the session
- Force push
- Committing or pushing a change that would send secrets or sensitive data outside the repository when it runs, or widen what a deploy exposes. This covers a CI workflow or deploy configuration that passes a secret to a destination that doesn’t already receive it, a script or setup step that reads a secret store and sends the data out, and a config change that widens what a deploy publishes, such as a registry, visibility, artifact, or sourcemap setting. The check applies on any branch, applies even when the repository is public, and fires when the change is committed or pushed, whether or not that commit or push triggers the pipeline; clearing it requires naming the execution effect, not only the commit or push
- `git reset --hard`, `git checkout -- .`, `git restore .`, `git clean -fd`, `git stash drop`, or `git stash clear`, which the classifier presumes would discard uncommitted changes
- `git commit --amend` when the commit at HEAD was not created in this session
- From v2.1.198, `git commit --amend` when the commit at HEAD has already been pushed. A message-only reword is not blocked: `--amend -m` with nothing newly staged, on a commit that Claude created during this session
- `terraform destroy`, `pulumi destroy`, `cdk destroy`, or `terragrunt destroy`, and applying a plan that destroys resources
- Writing to a secret manager, or changing DNS records or TLS certificates
- Merging a pull request no human has approved, approving Claude’s own pull request, or disabling CI checks
- Posting a comment that is itself a command to automation, such as `atlantis apply` or a bot’s `/deploy` or `/merge`
- Toggling, ramping, or deleting a production feature flag
- Applying infrastructure changes to a protected IaC scope, or draining and removing cluster nodes
- Writes to a shared compute cluster that reach beyond the resource you named, such as a label selector or `--all` that catches other users’ jobs
- Creating Kubernetes resources that run on every node or intercept cluster traffic, such as DaemonSets and admission webhooks
- Interactive shells or port-forwards into a sensitive remote target
- Opening a tunnel or reverse shell that makes a local service reachable from the public internet
- Printing a live credential or token into the transcript or a file
- Accessing a location listed as a sensitive data location in your [environment](auto-mode-config.md#define-trusted-infrastructure), copying data out of one, or sending data from one to an audience the entry excludes
- Routing a package install around your internal package registry to a public registry. This applies when an internal registry or mirror is listed in your environment or when you’ve told Claude in the conversation that one exists
- Running a command with a flag that disarms a safety guard, like `--insecure`
- Launching an autonomous agent loop that runs without human approval or a sandbox, such as one started with `--dangerously-skip-permissions` or `--no-sandbox`. This includes running a third-party agent or eval harness with isolation and per-action approval disabled, such as a runner started with `--yes-always`
- [Claude in Chrome](../03-IDE-Integrations/chrome.md) browser actions that could send page content, cookies, or credentials off-origin
- Deleting files in `/tmp`, `$TMPDIR`, or another shared scratch or cache directory by wildcard, glob, or age filter rather than by a specific named path
- Including sensitive details in content sent, uploaded, published, or written to other people or shared systems, when your own message didn’t authorize those details for that recipient. PR and issue bodies, commit messages, and comments count as this kind of outbound content when the repository is outside the trust boundary or public, including your organization’s own public repositories; internal file paths, code names, live API response data such as emails or account identifiers, and infrastructure identifiers count as sensitive details. Live personal data from an API response in a PR or issue body, such as an email address, an account or organization identifier, or a usage metric, requires you to name those details and the recipient regardless of the repository’s visibility or trust boundary
- Sending keystrokes to Claude Code’s own tmux pane to drive its own interface, which the classifier treats as Claude changing its own permissions or oversight
- Commenting out, deleting, or force-passing a test or assertion that guards security behavior, such as auth, access control, input validation, or sandboxing
- Deleting or tearing down a stateful resource Claude didn’t create in the session, when no more specific deletion rule applies and you didn’t name that resource
- Repointing an API base URL, proxy endpoint, webhook receiver, or registry mirror at a third-party host that doesn’t fit the task, including in example files like `.env.example`
- Changing where pushes go with `git remote set-url` or `git remote add`, unless you named the new remote
- Pushing secrets or personal or entrusted data to a repository known to be public, or pushing confidential material there that isn’t part of that repository’s own work. A dotfiles repository’s own subject matter is the one exception for personal or entrusted data, and content from a private repository reaching any public surface is blocked the same way. When a repository’s visibility isn’t established, the classifier doesn’t block on that alone; it judges the content against the other rules instead
- Opening a pull request against a different repository or organization, forking with `gh repo fork`, or pushing to a third-party repository, unless you named that external target
- Content from a sensitive local store, or from a file whose name, path, or type marks it as sensitive, entering a commit, a push, PR or issue text, a gist or paste, or a package publish, unless you named both the source and the destination. Session transcripts and conversation logs, credential and configuration dot-folders such as SSH keys, cloud credentials, browser profiles, and shell history, and user-data exports all count, and the repository being private doesn’t clear it
- Writing to Claude Code session transcripts, the `.jsonl` history files under `~/.claude/projects/` or your configured config directory, whether directly or through a shell command. The rule also covers the metadata lines Claude Code appends to each transcript entry for its own checks. Reading a transcript isn’t blocked
- A recursive forced delete such as `rm -rf "$VAR"` or `Remove-Item -Recurse -Force $dir` whose target is a shell variable that isn’t assigned anywhere in the conversation the classifier sees, or a glob rooted at such a variable. The value came only from earlier command output, which the classifier never receives, so the classifier can’t verify the deletion target against the other deletion rules. The block clears when you name the exact path being deleted, or when Claude re-runs the delete with the resolved literal path written into the command. Deletes whose target the classifier can resolve aren’t affected. A glob directly under the variable, as in `rm -rf "$VAR"/*`, is a [critical path](#critical-paths) instead. `Remove-Item` targets that are a bare `*` or end in `/*` or `\*` never reach the classifier: Claude Code [denies them outright](#remove-item-in-powershell).

Several of these categories depend on [environment](auto-mode-config.md#define-trusted-infrastructure) entries, such as sensitive remote targets and protected IaC scopes, that you can narrow to concrete names. Claude Code v2.1.257 and later also block these by default:

- Requesting credentials from the cloud instance-metadata endpoint, such as `169.254.169.254`, or explicitly authenticating a cloud, cluster, or registry call with the machine’s own service-account or node identity
- Reaching a public host by a route other than a direct request, such as a tunnel, a reverse shell, or a resolver or proxy configuration rewritten to point outside
- Reading credentials that belong to the host rather than to your task, such as node certificates or the node’s container-registry auth
- Connecting to or scanning sibling containers, pods, or VMs that Claude didn’t start, or the node beneath the container

If Claude Code runs somewhere that is meant to allow one of these, describe that setup in a [Host containment entry](auto-mode-config.md#define-trusted-infrastructure) in `autoMode.environment`. Claude Code v2.1.261 and later also block these by default:

- Posting or writing a link to a public paste, diagram, or data-sharing service in a message, PR or issue text, a document, or anywhere else the link will be opened or fetched, when the URL itself carries the content being shared, unless you named that service

**Allowed by default**:

- Local file operations in your working directory
- Installing dependencies declared in your lock files or manifests
- Forwarding request-scoped credentials to the matching first-party API endpoint
- Read-only HTTP requests
- Pushing to any branch of the repository you’re working in, including the default branch. A non-default branch whose name marks it as a deploy or publication target, such as `production` or `gh-pages`, isn’t covered: the classifier judges a push there on its own terms. A push’s content is still checked against the classifier’s other rules, and [`permissions.deny` rules](permissions.md#manage-permissions) can still block push commands [as written](permissions.md#bash-rule-limits) in every mode. The remote’s own branch protection still applies. From v2.1.203 until v2.1.211, only routine default-branch pushes and pushes to the branch you started on or to branches Claude created were allowed by default.
- Deleting the exact jobs Claude created earlier in the same session
- Reading, reviewing, or writing security-related code, configs, and threat models as part of your task
- Messages between agents working together in the same multi-agent session
- Sending data to the trusted domains, buckets, and services you list in [`environment`](auto-mode-config.md#define-trusted-infrastructure). This covers data flow only, not destructive or credential operations on the same infrastructure
- [Claude in Chrome](../03-IDE-Integrations/chrome.md) navigation to a trusted internal domain, localhost, or a URL you named

Sandboxed commands don’t get network access by default. Claude names the hosts a command needs on the command itself, the classifier reviews them with the command, and an approved list opens those hosts for that one command alone. [Per-command allowed domains](sandboxing.md#per-command-allowed-domains-in-auto-mode) covers what a list can and can’t open and what happens when a command reaches for an unlisted host. Run `claude auto-mode defaults` to print the full rule lists as JSON. If routine actions get blocked, an administrator can add trusted repos, buckets, and services via the `autoMode.environment` setting: see [Configure auto mode](auto-mode-config.md). Pushing to any branch of the repository you’re working in and creating a pull request that matches your request run without a prompt, unless the push or pull request falls under the [blocked list](#what-the-classifier-blocks-by-default), such as secrets or sensitive data leaving the repository, or a pull request that targets a different repository or organization. To require a human checkpoint before these commands while staying in auto mode, add `permissions.ask` rules, which match the command [as written](permissions.md#bash-rule-limits): see [Common boundaries](auto-mode-config.md#common-boundaries).


[​](#first-read-outside-the-working-directories)

The first read outside the working directories

While [`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) is off, file reads other than [reads from network paths](permissions.md#network-paths) run without a prompt in auto mode, including reads outside the [working directories](permissions.md#working-directories). The first time Claude uses the Read, Grep, or Glob tool on a path outside them, Claude Code asks whether to allow that read. The prompt doesn’t appear in non-interactive `-p` runs or background sessions; reads there run as before. Whatever you answer, Claude keeps working:

- **Yes, and keep allowing any reads outside the working directories**: the read runs, later reads outside the working directories run as before, and Claude Code records your answer so the prompt doesn’t appear again
- **No, and block reads outside the working directories from now on**: the read is refused, and Claude Code sets [`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) to `true` in your user settings, which makes the file tools refuse such reads in every later session and every permission mode. To let Claude read such a path later, add its directory with `/add-dir` or remove the setting.
- **No, and ask again next time**: the read is refused, and the next read outside the working directories prompts again
- **Yes, but ask again next time**: the read runs, nothing is saved, and the next read outside the working directories prompts again


[​](#boundaries-you-state-in-conversation)

Boundaries you state in conversation

The classifier treats boundaries you state in the conversation as a block signal. If you tell Claude “don’t push” or “wait until I review before deploying”, the classifier blocks matching actions even when the default rules would allow them. A boundary stays in force until you lift it in a later message. Claude’s own judgment that a condition was met does not lift it. Boundaries are not stored as rules. The classifier re-reads them from the transcript on each check, so a boundary can be lost if [context compaction](../17-Billing-Plans/costs.md#reduce-token-usage) removes the message that stated it. For a hard guarantee, add a [deny rule](permissions.md#permission-rule-syntax) instead.


[​](#approvals-you-state-in-conversation)

Approvals you state in conversation

If you tell Claude that a blocked action is allowed, the classifier reads that as your approval and can clear the block. How you worded it decides whether the action runs, and how far the approval reaches:

- **Name the action and its specifics**: your message has to name the action and the specific thing that makes it dangerous, such as the branch of a force push. Naming the verb alone clears nothing, so “you can force-push” leaves the block in place.
- **Expect it to cover one action**: an approval covers the destructive action you named, so a later action is blocked again unless you granted the approval as standing. To stop approving a routine pattern one action at a time, add it to [`autoMode.allow`](auto-mode-config.md#override-the-block-and-allow-rules).
- **Some blocks stay in place**: [the classifier’s precedence order](auto-mode-config.md#override-the-block-and-allow-rules) sets out which blocks your approval can reach. To run a step it won’t clear, [leave auto mode](#switch-permission-modes) and answer the permission prompt.


[​](#when-auto-mode-falls-back)

When auto mode falls back

When auto mode can’t approve your session’s actions, what happens depends on the case:

- **A blocked action**: Claude Code shows a notification and lists the action in `/permissions` under the **Recently denied** tab, where you can press `r` to retry it with a manual approval.
- **Repeated blocks**: if the classifier blocks an action 3 times in a row or 20 times total, auto mode pauses and Claude Code resumes prompting. Approving the prompted action resumes auto mode. See [Repeated-block thresholds](#repeated-block-thresholds) for how the blocks are counted.
- **No verdict from the classifier**: when a safety check separate from auto mode refuses the classifier’s own request, or the classifier’s response doesn’t parse, Claude Code denies the action without the notification or the **Recently denied** entry. See [Auto mode cannot determine the safety of an action](errors.md#auto-mode-cannot-determine-the-safety-of-an-action) for the message each case shows and what to do.
- **No verdict from the server**: under [server-side classifier review](#server-side-classifier-review), Claude Code denies an action the server gives no verdict for, and stops the turn after ten responses in a row with no verdict. See [The server returned no safety verdict](errors.md#the-server-returned-no-safety-verdict).
- **A mode switch during a check**: if you switch permission modes while a classifier check is pending, Claude Code discards a verdict the new mode wouldn’t have requested. You’re prompted for approval instead, or the action is auto-denied in [`dontAsk` mode](#allow-only-pre-approved-tools-with-dontask-mode).


[​](#repeated-block-thresholds)

Repeated-block thresholds

The thresholds of 3 blocks in a row and 20 blocks total are not configurable. The total counter persists for the session and resets only when its own limit triggers a fallback. Claude Code doesn’t count a denial toward either threshold when a safety check separate from auto mode refuses the classifier’s own request. A [non-interactive](headless.md) `-p` run without a [`--permission-prompt-tool`](cli-reference.md#cli-flags) has no prompt to fall back to. When repeated blocks reach a threshold, the action doesn’t run and Claude keeps working. Claude Code doesn’t stop the run. Repeated blocks usually mean the classifier is missing context about your infrastructure. Use `/feedback` to report false positives, or have an administrator [configure trusted infrastructure](auto-mode-config.md).


[​](#how-auto-mode-evaluates-actions)

How auto mode evaluates actions

The following sections cover the order Claude Code evaluates an action in, how the classifier reviews subagent work, and what classifier calls add in cost and latency.

How the classifier evaluates actions

Each action goes through a fixed decision order. The first matching step wins:

1.  Actions matching your [allow, ask, or deny rules](permissions.md#manage-permissions) resolve immediately, with these exceptions:
    - Writes to [protected paths](#protected-paths) route to the classifier even when an allow rule matches. When the protected path is the file that a symlinked settings file points to, the write can prompt you instead, as the [protected paths](#protected-paths) list describes
    - No allow rule approves recognized `rm` and `rmdir` [critical-path removals](#critical-paths)
    - MCP tools marked [`requiresUserInteraction`](../06-MCP-Tools/General/mcp.md#require-approval-for-a-specific-tool) prompt you directly even when an allow rule matches, and so do connector tools [your organization set to `ask`](../06-MCP-Tools/General/mcp.md#organization-controls-on-connector-tools) in sessions where that setting reaches Claude Code
    - A shell command that carries [per-command allowed domains](sandboxing.md#per-command-allowed-domains-in-auto-mode) also routes to the classifier even when an allow rule matches, because a rule approves the command, not its hosts
    - Ask rules that match on a command’s content, such as `Bash(git push *)`, fall back to a permission prompt
    - A write that the [symlink check](permissions.md#symlinks) resolves to a protected path prompts you when the path Claude requested isn’t itself protected
    - A read from a [network path](permissions.md#network-paths) prompts you even when an allow rule matches
2.  Read-only actions and file edits in your working directory are auto-approved, except writes to [protected paths](#protected-paths) and [the first read outside the working directories](#first-read-outside-the-working-directories), which prompts you
    - In a session with [server-side classifier review](#server-side-classifier-review), read-only and [sandboxed](sandboxing.md#sandbox-modes) shell commands wait for that review and are blocked if it flags them
    - A write inside your working directory that the [symlink check](permissions.md#symlinks) resolves to a location outside it prompts you
    - When Claude reads an [artifact someone else made](artifacts.md#read-an-artifact-shared-with-you), the approval cases listed in that section apply
    - A read from a [network path](permissions.md#network-paths) prompts you
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
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](auto-mode-config.md#review-denials)

A [mod](../08-Plugins-Skills/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](permissions.md#precedence-among-rules-hooks-and-mods).For how [Claude in Chrome](../03-IDE-Integrations/chrome.md) browser actions get approved in the VS Code extension, see [Permission prompts in VS Code sessions](../03-IDE-Integrations/chrome.md#permission-prompts-in-vs-code-sessions).On entering auto mode, broad allow rules that grant arbitrary code execution are dropped:

- Blanket `Bash(*)` or `PowerShell(*)`
- Wildcarded interpreters like `Bash(python*)`
- Package-manager run commands
- `Agent` allow rules
- [`Monitor`](tools-reference.md#monitor-tool) allow rules, because Claude Code runs Monitor commands through the shell

Narrow rules like `Bash(npm test)` stay in effect. Claude Code restores the dropped rules when you leave auto mode. Before v2.1.236, Claude Code left `Monitor` allow rules in effect in auto mode, so a rule that matched the whole tool approved Monitor commands without classifier review.Claude Code also runs `git status` itself before a command that would discard uncommitted work, such as `git reset --hard` or `rm -rf`, and shows the classifier whether staged, modified, or untracked work is present. Claude Code reports untracked files in that check even when the repository’s git configuration sets `status.showUntrackedFiles=no`.In the classifier requests sent by Claude Code itself, the classifier sees user messages, tool calls other than read-only lookups such as file reads and searches, and your CLAUDE.md content. Tool results are stripped from those requests, so hostile content in a file or web page can’t manipulate the classifier directly.You can annotate a call’s result with a [PostToolUse hook’s `classifierContext` field](../07-Hooks/hooks.md#annotate-a-result-for-the-auto-mode-classifier), which the classifier reads as application-provided context. The field requires Claude Code v2.1.236 or later.A separate server-side probe scans incoming tool results and flags suspicious content before Claude reads it. For more on how these layers work together, see the [auto mode announcement](https://claude.com/blog/auto-mode) and the [engineering deep dive](https://www.anthropic.com/engineering/claude-code-auto-mode).

How auto mode handles subagents

The classifier checks [subagent](../09-Agents-Patterns/sub-agents.md) work at three points:

1.  Before a subagent starts, the delegated task description is evaluated, so a dangerous-looking task is blocked at spawn time.
2.  While the subagent runs, each of its actions goes through the same [decision order](#how-the-classifier-evaluates-actions) as in the parent session, with the same block and allow rules. Any `permissionMode` in the subagent’s frontmatter is ignored.
3.  When the subagent finishes, the classifier reviews its work and its final report before the parent reads the report. When the classifier flags the subagent’s work or report, or a separate API safety check refuses the review, the report is still delivered, prepended with a security warning. When the classifier is unavailable for the review, the report arrives with a note to verify the subagent’s work before acting on it.

Cost and latency

Claude Code’s classifier requests can run on a model other than your `/model` selection. See [which model they run on](#default-classifier-model).On Enterprise plans and on accounts that use the Claude API, [Claude Platform on AWS](claude-platform-on-aws.md), Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry, classifier calls count toward your token usage. Each check sends a portion of the transcript plus the pending action, adding a round-trip before execution. Reads and working-directory edits outside protected paths skip the classifier, so the overhead comes mainly from shell commands and network operations. Where the server reviews the actions as part of the session’s model requests, there are no separate classifier calls to count; see [Server-side classifier review](#server-side-classifier-review).Sandboxed network access adds no per-connection classifier requests. The classifier judges [the hosts a command names](sandboxing.md#per-command-allowed-domains-in-auto-mode) together with the command in one review, and Claude Code checks each connection against the approved list without calling the classifier again.


[​](#allow-only-pre-approved-tools-with-dontask-mode)

Allow only pre-approved tools with dontAsk mode

If you set `dontAsk` mode, Claude Code auto-denies every tool call that would otherwise prompt you, though a [mod](../08-Plugins-Skills/plugins-mods-overview.md) you installed can still approve some of those calls. To check which calls a mod can approve, see [Extend permissions with hooks](permissions.md#precedence-among-rules-hooks-and-mods). Claude still runs actions that need no approval in Manual mode, such as file reads inside your working directories and [read-only Bash commands](permissions.md#read-only-commands). Actions matching your `permissions.allow` rules and calls approved by a [PreToolUse hook](permissions.md#extend-permissions-with-hooks) run too. Use this mode for CI pipelines or restricted environments where you pre-define what Claude may do; the session never waits for input. The status bar shows `⏵⏵ don't ask on` in this mode. Claude Code denies calls matching your explicit [`ask` rules](permissions.md#manage-permissions) rather than prompting. It also denies the built-in `AskUserQuestion` tool even if your allow rules match it, and does the same to connector tools [your organization set to `ask`](../06-MCP-Tools/General/mcp.md#organization-controls-on-connector-tools) in sessions where that setting reaches Claude Code. It denies MCP tools marked [`_meta["anthropic/requiresUserInteraction"]`](../06-MCP-Tools/General/mcp.md#require-approval-for-a-specific-tool) the same way, because their approval card needs an answer this mode never collects. An allow rule or `PreToolUse` hook can’t approve these:

- Recognized `rm` and `rmdir` [critical-path removals](#critical-paths), such as `rm -rf /` and `rm -rf ~`
- Reads from a [network path](permissions.md#network-paths)

[Cloud sessions](claude-code-on-the-web.md) ignore `defaultMode: "dontAsk"`; see [bypassPermissions](#skip-all-checks-with-bypasspermissions-mode) for details. Set it at startup with the flag:

```python
claude --permission-mode dontAsk
```


[​](#skip-all-checks-with-bypasspermissions-mode)

Skip all checks with bypassPermissions mode

`bypassPermissions` mode disables permission prompts and safety checks so tool calls execute immediately, including writes to [protected paths](#protected-paths). The [actions no mode auto-approves](#actions-no-mode-auto-approves) still prompt in this mode. Reading [another organization’s public artifact](artifacts.md#read-an-artifact-shared-with-you) needs your approval, and this mode doesn’t ask for it, so Claude can’t read one. The [Remove-Item in PowerShell](#remove-item-in-powershell) denies also apply in this mode. Two [cross-session messaging](cross-session-messaging.md) safeguards still apply in this mode, and in interactive terminal plan-mode sessions where bypass permissions are available:

- The [`isolatePeerMachines`](settings-reference.md#isolatepeermachines) approval prompt for messages to your sessions beyond this machine still appears.
- When no [`crossSessionInbound`](cross-session-messaging.md#control-inbound-messages) value applies, Claude Code holds an inbound message from another of your sessions for your approval, and delivers without asking only when the sending session identifies itself as also bypassing permission prompts. If you leave the permission mode while messages are held, Claude Code re-applies the inbound rules and delivers any held message they now accept.

In interactive terminal sessions with bypass permissions available, Claude Code also doesn’t enforce [plan mode’s](#analyze-before-you-edit-with-plan-mode) blocks. Claude is still instructed to plan without editing, but a file edit or shell command it attempts during planning runs without prompting. Explicit [ask rules](permissions.md#manage-permissions) and recognized `rm` and `rmdir` [critical-path removals](#critical-paths) still prompt. Plan mode keeps its blocks wherever Claude Code runs without an interactive terminal, including [non-interactive runs](headless.md) with `-p`, [Agent SDK](../05-Agent-SDK/agent-sdk-permissions.md#plan-mode-plan) sessions, and conversations in the [VS Code extension](../03-IDE-Integrations/vs-code.md)’s chat panel. There, `--allow-dangerously-skip-permissions` makes `bypassPermissions` selectable later.

Only use this mode in isolated environments like containers, VMs, or dev containers without internet access, where Claude Code cannot damage your host system.

You can’t enter `bypassPermissions` from a session you started without it enabled. Enable it at launch with [`permissions.defaultMode: "bypassPermissions"`](settings-reference.md#permissions-defaultmode) or with an enabling flag:

```python
claude --permission-mode bypassPermissions
```

The `--dangerously-skip-permissions` flag is equivalent. Claude Code refuses `bypassPermissions` in a session you start with [`--restricted`](cli-reference.md#cli-flags). `--restricted` requires Claude Code v2.1.248 or later. The first time you start an interactive session with this mode enabled, Claude Code shows a warning dialog asking you to accept responsibility for actions taken without permission checks:

- **If you accept**: Claude Code sets `skipDangerousModePermissionPrompt` to `true` in `~/.claude/settings.json`, so later sessions skip the dialog. To see the dialog again, remove the key from that file or set it to `false`. The [`skipDangerousModePermissionPrompt` reference](settings-reference.md#skipdangerousmodepermissionprompt) lists the other settings files where you or your organization can set it.
- **If you decline**: Claude Code exits.

In [non-interactive mode](headless.md) no dialog is shown. A [background session](../09-Agents-Patterns/agent-view.md) honors your acceptance when it’s recorded in user or managed settings:

- With no acceptance recorded, `claude --bg --permission-mode bypassPermissions` is refused. Accept the dialog in an interactive session first.
- With `skipDangerousModePermissionPrompt` set only in `.claude/settings.local.json`, the background session starts with [the bypass request ignored](#bypass-permissions-ignored-in-a-background-session):
  - With `--allow-dangerously-skip-permissions` ignored, `bypassPermissions` is left out of its `Shift+Tab` cycle.
  - With `--permission-mode bypassPermissions` or `--dangerously-skip-permissions` ignored, the session starts in Manual mode instead.

  Add `"skipDangerousModePermissionPrompt": true` to `~/.claude/settings.json`, then start a new background session.

On Linux and macOS, Claude Code refuses to start in `bypassPermissions` mode when running as root or under `sudo`:

```python
--dangerously-skip-permissions cannot be used with root/sudo privileges for security reasons
```

The check is skipped automatically inside a recognized sandbox. To run autonomously in a container, use the [dev container](devcontainer.md) configuration, which runs Claude Code as a non-root user. [Cloud sessions](claude-code-on-the-web.md) don’t honor `defaultMode: "bypassPermissions"` or `"dontAsk"` from your settings files, so a repository’s checked-in settings can’t start a cloud session in bypass-permissions mode. The setting is ignored silently and the session starts in the permission mode shown in the mode dropdown instead. See [Switch permission modes](#switch-permission-modes) for which modes cloud sessions offer.

`bypassPermissions` offers no protection against prompt injection or unintended actions. For background safety checks with far fewer permission prompts, use [auto mode](#eliminate-prompts-with-auto-mode) instead. Administrators can block this mode by setting `permissions.disableBypassPermissionsMode` to `"disable"` in [managed settings](../13-Enterprise-Admin/managed-settings.md).


[​](#bypass-permissions-ignored-in-a-background-session)

Bypass permissions ignored in a background session

This notice means the [background session](../09-Agents-Patterns/agent-view.md) didn’t find your acceptance of the [bypass permissions warning](#bypass-permissions-acceptance) in user or managed settings, so it ignored the bypass request made at launch:

```python
Bypass permissions was requested at launch and ignored · if that was you, ~/.claude/settings.json needs "skipDangerousModePermissionPrompt": true
```

Add `"skipDangerousModePermissionPrompt": true` to `~/.claude/settings.json`, then start a new background session.


[​](#claude-agents-shows-the-bypass-permissions-warning-that-interactive-sessions-skip)

`claude agents` shows the bypass permissions warning that interactive sessions skip

If [`claude agents`](../09-Agents-Patterns/agent-view.md#dispatch-defaults) shows the [bypass permissions warning](#bypass-permissions-acceptance) although your interactive sessions skip it, check whether `skipDangerousModePermissionPrompt` is set in `.claude/settings.local.json` or a `--settings` file. Interactive sessions count the key there as your acceptance of the warning, and `claude agents` doesn’t. Whether or not you find it there, accept the warning to add the key to `~/.claude/settings.json`, where `claude agents` looks for it.


[​](#protected-paths)

Protected paths

Writes to a small set of paths are never auto-approved, except in `bypassPermissions` mode and in interactive terminal sessions in plan mode with [bypass permissions](#skip-all-checks-with-bypasspermissions-mode) available. This prevents accidental corruption of repository state and Claude’s own configuration.

| Mode                     | Protected-path writes                                                                                                                                                                                                                                                        |
|:-------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `default`, `acceptEdits` | Prompted                                                                                                                                                                                                                                                                     |
| `plan`                   | Allowed in interactive terminal sessions with [bypass permissions](#skip-all-checks-with-bypasspermissions-mode) available. Otherwise, routed to the classifier when [auto mode](#eliminate-prompts-with-auto-mode) is available during planning, and prompted when it isn’t |
| `auto`                   | Routed to the classifier                                                                                                                                                                                                                                                     |
| `dontAsk`                | Denied                                                                                                                                                                                                                                                                       |
| `bypassPermissions`      | Allowed                                                                                                                                                                                                                                                                      |

In a session started with [`--restricted`](cli-reference.md#cli-flags), which requires Claude Code v2.1.248 or later, the classifier can’t approve protected-path writes. In the modes that route protected-path writes to the classifier, a write that the [symlink check](permissions.md#symlinks) resolves to a protected path prompts you instead when the path Claude requested isn’t itself protected. [`permissions.allow`](permissions.md#manage-permissions) rules in settings files do not pre-approve protected-path writes. The safety check runs before Claude Code evaluates allow rules from settings, so an entry such as `Edit(.claude/**)` in `~/.claude/settings.json` or `.claude/settings.json` does not change the per-mode outcome in the table above. In permission modes that prompt, the prompt for a write to the project’s `.claude/` folder or to `~/.claude/` can offer one of these session-scoped options:

- For the project’s `.claude/` folder: **Yes, and allow Claude to edit files in this project’s .claude folder for this session**
- For `~/.claude/`: **Yes, and allow Claude to edit files in its ~/.claude folder for this session**

Protected directories:

- `.git`
- `.config/git`
- `.vscode`
- `.idea`
- `.husky`
- `.cargo`
- `.devcontainer`
- `.yarn`
- `.mvn`
- `.claude`, with a few exceptions, such as:
  - Claude’s own git worktrees under `.claude/worktrees/`
  - The current session’s own plan files in `~/.claude/plans/`, or in the [`plansDirectory`](settings-reference.md#plansdirectory) you set
  - A [background session](../09-Agents-Patterns/agent-view.md#where-state-is-stored)’s own scratch directory at `~/.claude/jobs/<id>/tmp/`
  - Markdown files in the project’s [auto memory](memory.md#storage-location) directory, such as `~/.claude/projects/<project>/memory/`, in a session started without `--restricted`
  - Markdown files in a [subagent memory](../09-Agents-Patterns/sub-agents.md#enable-persistent-memory) directory, such as `.claude/agent-memory/`, in a session started without `--restricted`
- A directory you loaded with [`--plugin-dir`](../08-Plugins-Skills/plugins-mods-create.md#change-a-mod-with-claude), because Claude Code reloads and runs a mod’s code from it when a file changes
- `~/.claude/dev-mods/`, or `dev-mods/` in the directory [`CLAUDE_CONFIG_DIR`](env-vars.md) points to, where Claude saves the [mods it writes for you](../08-Plugins-Skills/plugins-mods-create.md#ask-claude-for-a-mod)

Protected files:

- `.gitconfig`, `.gitmodules`
- `.bashrc`, `.bash_profile`, `.bash_login`, `.bash_aliases`, `.bash_logout`, `.zshrc`, `.zprofile`, `.zshenv`, `.zlogin`, `.zlogout`, `.profile`, `.envrc`
- `.npmrc`, `.yarnrc`, `.yarnrc.yml`, `.pnp.cjs`, `.pnp.loader.mjs`, `.pnpmfile.cjs`, `bunfig.toml`, `.bunfig.toml`
- `.bazelrc`, `.bazelversion`, `.bazeliskrc`
- `.pre-commit-config.yaml`, `lefthook.yml`, `lefthook.yaml`, `.lefthook.yml`, `.lefthook.yaml`
- `gradle-wrapper.properties`, `maven-wrapper.properties`
- `.devcontainer.json`
- `.ripgreprc`, `pyrightconfig.json`
- `.mcp.json`, `.claude.json`
- The file that your user, project, or local [settings file](settings.md#settings-files-and-who-they-affect) points to when the settings file is itself a symbolic link, for example into a dotfiles repository. In the modes that route protected-path writes to the classifier, a write to this file prompts you instead, even when an allow rule matches. If the file’s own path is also that of a settings file, such as `.claude/settings.json` in another folder, the write goes to the classifier as other protected-path writes do


[​](#critical-paths)

Critical paths

Critical paths are the directories Claude Code protects from `rm` and `rmdir` commands, such as the filesystem root, your home directory, and your working directory. Claude Code checks these commands before they run, and no [allow rule](permissions.md#manage-permissions) approves one whose target it recognizes as a critical path. The check can miss some commands, so it doesn’t replace an operating-system control such as [sandboxing](sandboxing.md). A critical-path removal is an `rm` or `rmdir` command whose target Claude Code recognizes as a critical path. No [`PreToolUse` hook](permissions.md#extend-permissions-with-hooks) that returns `"allow"` approves one either. An allow rule or `PreToolUse` hook can’t approve one even in the permission modes that skip other prompts.

A command the check misses gets no special handling, so anything that approves Bash commands in your session can approve it with no prompt. That includes an allow rule, `bypassPermissions` mode, and the sandbox’s [auto-allow mode](sandboxing.md#auto-allow-mode). The check applies to `rm` and `rmdir`, so other approved commands can delete critical paths too.

These controls apply whether or not the check recognizes a command:

- **Deny rules**: a [deny rule](permissions.md#manage-permissions) that matches the command blocks it, though a [mod](../08-Plugins-Skills/plugins-mods-overview.md) you installed can still approve [some of those calls](permissions.md#precedence-among-rules-hooks-and-mods)
- **Sandboxing**: [sandboxing](sandboxing.md) has the operating system limit which paths Bash commands can write to. Sandboxed commands can still delete your working directory
- **Strict sandbox mode**: by default a sandboxed command can be [retried outside the sandbox](sandboxing.md#the-unsandboxed-retry-escape-hatch), and an allow rule or `bypassPermissions` mode can approve that retry with no prompt. [Strict sandbox mode](sandboxing.md#turn-off-the-retry-with-strict-sandbox-mode) turns the retry off

What happens to a removal that Claude Code recognizes [depends on your permission mode](#critical-path-removals-in-each-permission-mode). `Remove-Item` and the `cmd` removal built-ins have their own checks, covered in [Remove-Item in PowerShell](#remove-item-in-powershell).


[​](#which-paths-are-critical)

Which paths are critical

Claude Code treats an `rm` or `rmdir` target as a critical path when it is any of the following:

- The filesystem root
- Top-level directories, meaning any direct child of the root, such as `/usr`, `/etc`, or `/data`
- Your home directory. On Windows, its 8.3 short name counts too, such as `C:\Users\LONGNA~1`
- Windows drive roots and their top-level directories, such as `C:\` and `C:\Windows`. Spellings such as `\\?\C:\` and `\\localhost\C$` count as `C:\`
- Your working directory and its parents
- Your additional working directories and their parents, but only when the removal is a glob under one of them, such as `rm -rf <dir>/*`. `rm -rf <dir>` on the directory itself doesn’t trigger this check

For mounted drive paths such as `/mnt/c` or `/Volumes/USB`, see [The mounted drive prompt](#the-mounted-drive-prompt). The checks on the home directory’s 8.3 short name and on the `\\?\C:\` and `\\localhost\C$` spellings require Claude Code v2.1.292 or later.


[​](#other-targets-that-count-as-critical-paths)

Other targets that count as critical paths

Claude Code also treats the following `rm` and `rmdir` targets as critical paths. The last column says why each one counts.

| Target                                                                                                                                  | Example                                                      | Why it counts                                                                                                    |
|:----------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------|
| A glob or trailing slash directly under a shell variable                                                                                | `rm -rf "$DIR"/*`                                            | The command becomes a removal from the filesystem root when the variable is empty                                |
| The same form under a positional parameter such as `$1` or `$@`, when nothing in the command gives it a value                           | `rm -rf "$1"/*`                                              | The command expands to a removal from the root                                                                   |
| A shell variable followed by one common top-level directory name, such as `mnt`, `tmp`, `usr`, or `Users`                               | `rm -rf "$TMPDIR/mnt"`                                       | When the variable expands empty, the command removes `/mnt`                                                      |
| A variable that the same command assigns from a directory-printing substitution, such as `$(pwd)` or `$(git rev-parse --show-toplevel)` | `D=$(pwd); rm -rf "$D"`                                      | The value can name your working directory or repository root                                                     |
| A target that is only the output of a command substitution, when the `rm` is recursive                                                  | `rm -rf "$(pwd)"`                                            | Claude Code can’t check the target before the command runs                                                       |
| A trailing command substitution after a critical path                                                                                   | `rm -rf ~/$(cmd)`                                            | Claude Code checks the path that would remain if the substitution expanded empty, here your home directory       |
| A target that is only backslashes                                                                                                       | `rm -rf "\\"`                                                | Git Bash on Windows reads a lone backslash as the current drive’s root, so the check applies on every platform   |
| A Windows path that names a volume by GUID instead of a drive letter                                                                    | `rm -rf '\\?\Volume{GUID}\work\build'`                       | The path doesn’t say which drive it’s on, so it could be a critical path. Requires Claude Code v2.1.292 or later |
| Some targets that end in `/*` or `/*/`                                                                                                  | `rm -rf logs/*/*`, `rm -rf logs/*/`, `cd logs && rm -rf a/*` | Claude Code can’t tell before the command runs which directories they reach                                      |

To turn off the check on a target that is only command substitution output, set [`CLAUDE_CODE_DISABLE_SUBSTITUTION_RM_PROMPT=1`](env-vars.md#variables) in the environment that launches Claude Code.


[​](#removals-inside-nested-commands-and-inline-scripts)

Removals inside nested commands and inline scripts

Claude Code also looks inside these constructs:

- **Nested commands**: a subshell with `(...)`, a brace group with `{ ...; }`, command substitution with `$(...)` or backticks, or process substitution with `<(...)`. Claude Code finds a critical-path removal whether it sits inside the nested form, as in `(rm -rf ~)` or `echo "$(rm -rf ~)"`, or elsewhere in the same command.
- **Inline scripts**: a script passed to `sh`, `bash`, `zsh`, or a similar POSIX shell with `-c`, as in `bash -c 'rm -rf ~'`.
  - When the script is double-quoted, the invoking shell expands its variables before the inner shell receives the script. In `find . -name '*.tmp' -exec sh -c "rm -rf \"$1\"/*" _ {} \;`, the command expands to a removal from the filesystem root once per match, and Claude Code treats it as a critical-path removal.
  - A single-quoted script that binds `$1` to a real value, as `sh -c 'rm -rf "$1"/*' _ {}` does, isn’t flagged.

To turn off the check on a critical path typed directly in a `-c` script, such as `~`, set [`CLAUDE_CODE_DISABLE_INLINE_SHELL_RM_PROMPT=1`](env-vars.md#variables) in the environment that launches Claude Code.


[​](#rewrite-a-flagged-command)

Rewrite a flagged command

How to rewrite a command so it passes the check depends on which of the [other targets](#other-targets-that-count-as-critical-paths) it uses:

- **A glob or trailing slash under a variable such as `$DIR`**: guard each expansion so the shell stops with an error when the variable is unset or empty, as in `rm -rf "${DIR:?}"/*`, or use a literal path. A removal whose expansions are all guarded that way passes this check, so in `bypassPermissions` mode it runs without a prompt unless another [critical-path](#critical-paths) check flags it.
- **A glob or trailing slash under a variable that is normally set, such as `$HOME`**: use a literal path.
- **A variable assigned from a directory-printing substitution**: use a literal path. A `"${D:?}"` guard doesn’t clear this check, because the variable isn’t empty.
- **A target that is only command substitution output**: run the substitution on its own first, then remove the literal paths it prints. The prompt tells Claude to do the same.

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


[​](#the-mounted-drive-prompt)

The mounted drive prompt

The mounted drive prompt appears on macOS, Linux, and WSL when a recursive `rm` targets a listed [mounted drive path](#paths-that-get-the-mounted-drive-prompt), such as `/mnt/c` or `/Volumes/USB/build`. Its reason reads `Dangerous rm operation on mounted drive path: <path>`. A `/*` target gets the prompt without the recursive flag, since Claude Code reads `rm /Volumes/USB/build/*` as a removal of `/Volumes/USB/build`. Even with an allow rule for `rm`, Claude Code handles the command as a [critical-path removal](#critical-paths): a prompt or a denial [depending on your permission mode](#critical-path-removals-in-each-permission-mode). Approve the prompt to let the `rm` run, or [turn the prompt off](#turn-off-the-mounted-drive-prompt).


[​](#paths-that-get-the-mounted-drive-prompt)

Paths that get the mounted drive prompt

Match the target of your recursive `rm` or `/*` removal against these path shapes, where each placeholder such as `<drive>` or `<name>` stands for exactly one path segment:

| Under             | Path shapes that get the prompt                                                                    | Examples                             |
|:------------------|:---------------------------------------------------------------------------------------------------|:-------------------------------------|
| `/Volumes`        | `/Volumes/<drive>`, `/Volumes/<drive>/<name>`                                                      | `/Volumes/USB`, `/Volumes/USB/build` |
| `/System/Volumes` | `/System/Volumes`, `/System/Volumes/<volume>`, `/System/Volumes/<volume>/<name>`                   | `/System/Volumes/Data`               |
| `/media`          | `/media/<user>`, `/media/<user>/<drive>`, `/media/<user>/<drive>/<name>`                           | `/media/alex`                        |
| `/run/media`      | `/run/media`, `/run/media/<user>`, `/run/media/<user>/<drive>`, `/run/media/<user>/<drive>/<name>` | `/run/media/alex/USB/build`          |
| `/mnt`            | `/mnt/<name>`, and `/mnt/<letter>/<name>` under a one-letter mount such as WSL’s `/mnt/c`          | `/mnt/data`, `/mnt/c/Users`          |

For a recursive or non-recursive `rm` on `/Volumes`, `/media`, or `/mnt` itself, you see the [critical path](#which-paths-are-critical) reason `Dangerous rm operation on critical path: <path>` instead. A relative target counts from your working directory, so `rm -rf build` while you work in `/Volumes/USB` targets `/Volumes/USB/build` and gets the prompt.


[​](#turn-off-the-mounted-drive-prompt)

Turn off the mounted drive prompt

To stop getting the mounted drive prompt while [prompts from other causes](#removals-that-still-prompt-with-the-mounted-drive-prompt-off) stay, start Claude Code with [`CLAUDE_CODE_DISABLE_MOUNTED_DRIVE_RM_PROMPT=1`](env-vars.md#variables) in its environment. For example, set the variable in [your shell](env-vars.md#set-variables-in-your-shell) and start `claude` from it:

```python
export CLAUDE_CODE_DISABLE_MOUNTED_DRIVE_RM_PROMPT=1
claude
```

In a session started that way, the mounted drive prompt stops for a whole drive such as `/Volumes/USB` and for the other [listed paths](#paths-that-get-the-mounted-drive-prompt). If you allow `Bash(rm *)`, use Manual mode, and work in `/Volumes/USB`, then `rm -rf build` runs with no prompt. A prompt that still shows `Dangerous rm operation on mounted drive path` means the variable isn’t reaching the session:

- **Variable in a settings file**: Claude Code [ignores the variable in a settings file’s `env` block](settings-reference.md#variables-claude-code-ignores-in-env), whichever kind of settings file, so set the variable where you start `claude` instead
- **Session started without the variable**: start `claude` again from an environment where the variable is set, since a running session doesn’t pick it up


[​](#removals-that-still-prompt-with-the-mounted-drive-prompt-off)

Removals that still prompt with the mounted drive prompt off

In Manual mode with an allow rule for `rm`, an `rm` on a mounted drive path can still prompt, without the `Dangerous rm operation on mounted drive path` reason:

- **Target outside your working directories**: `rm -rf /Volumes/USB/other` while you work in `/Volumes/USB/project` gets a prompt. To stop that prompt, [add a directory that contains the target](permissions.md#working-directories) to the session
- **Target with a `*`**: `rm -rf build/*` gets a prompt. Approve that prompt to run the command, or ask Claude to name each target without a `*`
- **Target that is a critical path**: `/mnt` itself and your working directory itself stay [critical paths](#which-paths-are-critical), so `rm -rf` on either gets a prompt. Approve that prompt to let the `rm` run


[​](#critical-path-removals-in-each-permission-mode)

Critical-path removals in each permission mode

What Claude Code does with a critical-path removal depends on your permission mode:

| Mode                     | Outcome                                                                                                                                                                                       |
|:-------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `default`, `acceptEdits` | Asks you to approve it                                                                                                                                                                        |
| `plan`                   | Asks you to approve it. When [the classifier reviews commands during planning](#analyze-before-you-edit-with-plan-mode) and no bypass permissions are available, handles it as in `auto` mode |
| `auto`                   | Asks you to approve it in the terminal, with a [time limit](#time-limits-and-denials-in-auto-and-bypasspermissions-modes). Elsewhere, denies it                                               |
| `dontAsk`                | Denies it                                                                                                                                                                                     |
| `bypassPermissions`      | Asks you to approve it, with a time limit in the terminal                                                                                                                                     |

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


[​](#time-limits-and-denials-in-auto-and-bypasspermissions-modes)

Time limits and denials in auto and bypassPermissions modes

In `auto` and `bypassPermissions` modes, the terminal prompt for a critical-path removal shows a two-minute countdown:

- If the countdown runs out before you answer, Claude Code denies the command and tells Claude what to do instead, so an unattended session keeps working.
- Press any key while the prompt is open to stop the countdown and keep the prompt waiting for your answer.
- After three of these prompts run out unanswered in a session, Claude Code stops showing them and denies further critical-path removals immediately. Sending a new message starts the count over.

In `auto` mode, wherever Claude Code can’t show you a terminal prompt, it denies the command immediately, for example in [non-interactive runs](headless.md) with `-p`, in [Agent SDK](../05-Agent-SDK/agent-sdk-permissions.md) sessions, and in the VS Code extension’s chat panel and the Desktop app. The denial tells Claude to report what it wanted to delete and leave the removal to you. The `auto` and `bypassPermissions` handling requires Claude Code v2.1.281 or later. To turn it off, set [`CLAUDE_CODE_DISABLE_DANGEROUS_RM_TIMEOUT=1`](env-vars.md#variables) in the environment that launches Claude Code. In `auto` mode, critical-path removals then go to the classifier instead, and in `bypassPermissions` mode the prompt has no time limit.


[​](#remove-item-in-powershell)

Remove-Item in PowerShell

When you enable the [PowerShell tool](tools-reference.md#powershell-tool), Claude Code gives `Remove-Item` and the `cmd` built-ins `rd`, `rmdir`, `del`, and `erase` their own checks, separate from the `rm` critical-path list. For `Remove-Item`, the outcome depends on the target, and the first matching case applies:

- **System paths**: the filesystem root and its top-level directories, drive roots and their top-level directories, and your home directory. Claude Code denies the command in every mode, without asking you.
- **Wildcards**: a bare `*`, or any target ending in `/*` or `\*`, including a glob under a shell variable such as `$dir/*`. Claude Code denies the command in every mode, without asking you, before the [classifier](#eliminate-prompts-with-auto-mode) sees it.
- **Your working directory or one of its parents, with `-Recurse`**: Claude Code treats the command like any other that needs approval in your permission mode, so it asks you in modes that ask, sends it to the classifier in `auto` mode, and denies it in `dontAsk` mode. `bypassPermissions` mode skips this check.

The system-paths case also applies to `rd`, `rmdir`, `del`, and `erase` when Claude runs them through `cmd`, as in `cmd /c rd /s /q C:\Users`. By default, Claude Code denies such a command in every mode, without asking you. This `cmd` check requires Claude Code v2.1.283 or later. When judging a `cmd` target, Claude Code treats a PowerShell variable that follows literal text as empty. That makes `cmd /c rd /s /q "C:\$name"` a removal of `C:\`, so it is denied too. A trailing wildcard counts as the folder it empties, so `cmd /c del /q C:\*` is denied and `cmd /c del /q dist\*` in your project is not. To turn the `cmd` check off, set [`CLAUDE_CODE_DISABLE_POWERSHELL_CMD_RM_DENY=1`](env-vars.md#variables) in the environment that launches Claude Code. Claude Code ignores this variable in a settings file’s `env` block. `Remove-Item` on a system path stays denied either way.


[​](#see-also)

See also

- [Permissions](permissions.md): allow, ask, and deny rules; managed policies
- [Configure auto mode](auto-mode-config.md): tell the classifier which infrastructure your organization trusts
- [Hooks](../07-Hooks/hooks.md): custom permission logic via `PreToolUse` and `PermissionRequest` hooks
- [Security](../13-Enterprise-Admin/security.md): safeguards and best practices
- [Sandboxing](sandboxing.md): filesystem and network isolation for Bash commands
- [Non-interactive mode](headless.md): run Claude Code with the `-p` flag

---

## Configure permissions - Claude Code Docs

Source: https://code.claude.com/docs/en/permissions
Path: 02-Claude-Code-CLI/permissions.md

## On this page

- [Permission system](#permission-system)
  - [Add a comment when you answer a permission prompt](#add-a-comment-when-you-answer-a-permission-prompt)
- [Manage permissions](#manage-permissions)
- [Permission modes](#permission-modes)
- [Permission rule syntax](#permission-rule-syntax)
  - [Match all uses of a tool](#match-all-uses-of-a-tool)
  - [Use specifiers for fine-grained control](#use-specifiers-for-fine-grained-control)
  - [Match by input parameter](#match-by-input-parameter)
  - [Wildcard patterns](#wildcard-patterns)
  - [Tool name wildcards](#tool-name-wildcards)
- [Tool-specific permission rules](#tool-specific-permission-rules)
  - [Bash](#bash)
  - [Compound commands](#compound-commands)
  - [Wrappers](#process-wrappers)
  - [Exec wrappers and find actions](#exec-wrappers-and-find-actions)
  - [What a Bash rule doesn’t match](#bash-rule-limits)
  - [Read-only commands](#read-only-commands)
  - [Redirections](#redirections)
  - [PowerShell](#powershell)
  - [Read and Edit](#read-and-edit)
  - [What Read and Edit rules cover](#what-read-and-edit-rules-cover)
  - [Write(path), NotebookEdit(path), and Glob(path) rules never match](#path-rules-that-never-match)
  - [How path patterns match](#how-path-patterns-match)
  - [Special characters and ! negation](#special-characters-and-negation)
  - [Symlinks](#symlinks)
  - [Network paths](#network-paths)
  - [WebFetch](#webfetch)
  - [Allow or deny every fetch](#allow-or-deny-every-fetch)
  - [MCP](#mcp)
  - [Agent (subagents)](#agent-subagents)
  - [Cd](#cd)
- [Extend permissions with hooks](#extend-permissions-with-hooks)
  - [Precedence among rules, hooks, and mods](#precedence-among-rules-hooks-and-mods)
  - [Hook approvals in plan mode](#hook-approvals-in-plan-mode)
- [Working directories](#working-directories)
  - [Move the session to another directory](#move-the-session-to-another-directory)
  - [Additional directories grant file access, not configuration](#additional-directories-grant-file-access-not-configuration)
- [How permissions interact with sandboxing](#how-permissions-interact-with-sandboxing)
- [Managed settings](#managed-settings)
- [Settings precedence](#settings-precedence)
- [Project allow rules and workspace trust](#project-allow-rules-and-workspace-trust)
  - [When your local settings file needs trust](#when-your-local-settings-file-needs-trust)
  - [What runs before you trust a folder](#what-runs-before-you-trust-a-folder)
- [Example configurations](#example-configurations)
- [See also](#see-also)

Permissions and sandboxing

# Configure permissions

Copy pageCopy page

Control what Claude Code can access and do with fine-grained permission rules, modes, and managed policies.

Copy pageCopy page

Claude Code supports fine-grained permissions so that you can specify exactly what the agent is allowed to do and what it can’t. You can check permission settings into version control to share them with every developer in your organization, and each developer can customize their own.


[​](#permission-system)

Permission system

Claude Code uses a tiered permission system to balance power and safety. The table shows, for each tool type, whether Manual mode asks before the action runs. The other [permission modes](#permission-modes) change which of these ask you; in auto mode a classifier reviews actions instead of you, and [how the classifier evaluates actions](permission-modes.md#how-the-classifier-evaluates-actions) lists which ones it sees.

| Tool type         | Example          | Approval required                                                                                                  | ”Yes, and don’t ask again” behavior    |
|:------------------|:-----------------|:-------------------------------------------------------------------------------------------------------------------|:---------------------------------------|
| Read-only         | File reads, Grep | No, within the [working directory and additional directories](#working-directories)                                | N/A                                    |
| Bash commands     | Shell execution  | Yes, except a built-in set of [read-only commands](#read-only-commands)                                            | Permanently per repository and command |
| File modification | Edit/write files | Yes                                                                                                                | Until session end                      |
| Web fetch         | WebFetch         | Yes, except a built-in set of [preapproved documentation domains](tools-reference.md#webfetch-tool-behavior) | Permanently per repository and domain  |
| Web search        | WebSearch        | Yes                                                                                                                | Permanently per repository             |

A permission prompt shows what Claude is about to do, followed by your options. This example is the prompt for a Bash command, from a session in Manual mode:

The third option, **Yes, and switch to auto mode**, [doesn’t appear on every prompt](permission-modes.md#switch-permission-modes). When you choose “Yes, and don’t ask again” and the approval saves permanently, such as for a Bash command or a WebFetch domain, Claude Code saves the rule to `.claude/settings.local.json` at the root of the git repository, resolved through [worktrees](worktrees.md) to the main checkout. The rule applies to future sessions anywhere in that repository, including sessions started in subdirectories and in worktrees. A file-modification approval isn’t saved to the file: as the table shows, it lasts until the session ends. In some cases, such as outside a git repository or on Windows, Claude Code doesn’t use the repository root; [Where Claude Code looks for each file](settings.md#where-claude-code-looks-for-each-file) lists those cases and where it saves the rule instead. Before v2.1.211, Claude Code always saved the rule in the starting directory, so an approval granted in a worktree or subdirectory didn’t apply to the rest of the repository. Rules that earlier versions saved in a subdirectory or worktree still apply to sessions started there. Sometimes a permission prompt offers only a one-time approval, with no “don’t ask again” option and no option to allow the action for the rest of the session. Claude Code offers those options only when the prompt can show you everything they would allow, so a rule you save from a prompt covers only what its option named. When a prompt offers only the one-time approval, approve the action once, or add the rule yourself in [`/permissions`](#manage-permissions). To stop the prompts for a command that starts with an exec wrapper such as `watch`, or for a `find` command with an action such as `-delete`, see [Exec wrappers and `find` actions](#exec-wrappers-and-find-actions).


[​](#add-a-comment-when-you-answer-a-permission-prompt)

Add a comment when you answer a permission prompt

You can attach a note to Claude when you approve or deny a single action. On most permission prompts, including Bash, PowerShell, file, and MCP tool prompts, move to **Yes** or **No** and press `Tab` to open a comment field on that option. WebFetch and browser prompts don’t offer the field. The options that allow the action for the rest of the session or save a rule don’t take one either. With the field open, type the comment and then press one of these keys:

- `Enter`: submits your answer with the comment attached. If you leave the field empty, Claude Code submits the answer without a comment.
- `Tab`: closes the field without answering. Claude Code keeps the text you typed and still sends it if you answer with that option.
- `Shift+Tab`: on a file prompt, such as an Edit or Write prompt, closes the field the same as `Tab`. Before v2.1.235, pressing `Shift+Tab` inside the field instead selected the option that allows the action for the rest of the session, so Claude Code approved the action for the rest of the session and discarded the comment.

Claude Code delivers the comment differently depending on how you answered:

- **Yes**: Claude Code runs the action, then sends your comment to Claude after the result.
- **No**: Claude Code sends your comment to Claude as the reason for the denial, and Claude continues working. If you select **No** without a comment on a prompt from the main conversation, Claude Code stops the turn.


[​](#manage-permissions)

Manage permissions

You can view and manage Claude Code’s tool permissions with `/permissions`. The dialog lists all permission rules and the `settings.json` file each rule comes from. You can open the dialog while Claude is working: when you add or remove a rule, Claude Code applies the change starting with Claude’s next tool call in the same turn. Before v2.1.234, Claude Code queued the command until the turn finished.

- **Allow** rules let Claude Code use the specified tool without manual approval.
- **Ask** rules prompt for confirmation whenever Claude Code tries to use the specified tool.
- **Deny** rules prevent Claude Code from using the specified tool.

Rules are evaluated in order: deny, then ask, then allow. The first match in that order determines the outcome, and rule specificity doesn’t change the order. A broad deny rule like `Bash(aws *)` blocks every matching call, including calls that also match a narrower allow rule like `Bash(aws s3 ls)`. An allow rule can’t carve an exception out of a deny rule. The same precedence applies between ask and allow: a matching ask rule prompts even when a more specific allow rule also matches the same call. Deny rules behave differently depending on whether they name a tool or scope a pattern within one. A bare tool name like `Bash` removes the tool from Claude’s context entirely, so Claude never sees it. If you add such a rule mid-session, Claude can’t call the tool from its next tool call on; [Denying an entire tool](prompt-caching.md#denying-an-entire-tool) covers what happens to a definition Claude has already seen. A scoped rule like `Bash(rm *)` leaves the tool available and blocks matching calls when Claude attempts them. Bare-name removal applies to every tool except [`EndConversation`](tools-reference.md#endconversation-tool-behavior): a deny rule can’t remove it while any other tool remains, and an ask rule never prompts for it.

Permission rules are enforced by Claude Code, not by the model. Instructions in your prompt or `CLAUDE.md` shape what Claude tries to do, but they don’t change what Claude Code allows. To grant or revoke access, use `/permissions`, the rules described here, a [permission mode](permission-modes.md), or a [PreToolUse hook](#extend-permissions-with-hooks).

When [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) is available to your session, the dialog also includes the [auto mode classifier rules](auto-mode-config.md#edit-rules-from-permissions). Select the **Auto mode** tab to view them.


[​](#permission-modes)

Permission modes

Claude Code supports several permission modes that control how it approves tool calls. See [Permission modes](permission-modes.md) for when to use each one. To change the mode sessions start in, set `defaultMode` in your [settings files](settings.md#where-settings-live). [Which mode a session starts in](permission-modes.md#which-mode-a-session-starts-in) covers the built-in default for each plan and what the VS Code extension reads.

| Mode                | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
|:--------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `default`           | Prompts for permission on first use of each tool. Labeled Manual in the CLI, the VS Code and JetBrains extensions, and the desktop app, and Claude Code accepts `manual` as an alias                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `acceptEdits`       | Automatically accepts file edits and common filesystem commands such as `mkdir`, `touch`, `mv`, and `cp` for paths in the working directory or `additionalDirectories`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `plan`              | Claude reads files and runs read-only shell commands to explore but doesn’t edit your source files; with [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) available, classifier-approved commands also run. Labeled Plan in the CLI and the VS Code extension                                                                                                                                                                                                                                                                                                                                                                                                              |
| `auto`              | Runs without routine prompts; before actions such as shell commands and network requests run, a background [classifier](permission-modes.md#eliminate-prompts-with-auto-mode) checks that they align with your request                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `dontAsk`           | Auto-denies every call that would otherwise prompt, though a [mod](../08-Plugins-Skills/plugins-mods-overview.md) you installed can still approve some of those calls. File reads in your working directories and other actions that need no approval still run, as do tools pre-approved via `/permissions` or `permissions.allow` rules. `AskUserQuestion`, MCP tools marked [`requiresUserInteraction`](../06-MCP-Tools/General/mcp.md#require-approval-for-a-specific-tool), [reads from network paths](#network-paths), and connector tools [your organization set to `ask`](../06-MCP-Tools/General/mcp.md#organization-controls-on-connector-tools) in sessions where that setting reaches Claude Code are denied even if you’ve allowed them |
| `bypassPermissions` | Skips permission prompts, except for the [actions no mode auto-approves](permission-modes.md#actions-no-mode-auto-approves)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |

In `bypassPermissions` mode, Claude Code skips permission prompts, including for writes to [protected paths](permission-modes.md#protected-paths) such as `.git` and `.claude`. The [cross-session messaging safeguards](permission-modes.md#skip-all-checks-with-bypasspermissions-mode) still apply. Only use this mode in isolated environments like containers or VMs where Claude Code can’t cause damage.

To prevent `bypassPermissions` or `auto` mode from being used, set `permissions.disableBypassPermissionsMode` or `permissions.disableAutoMode` to `"disable"` in any [settings file](settings.md#where-settings-live). These are most useful in [managed settings](#managed-settings) where they can’t be overridden.


[​](#permission-rule-syntax)

Permission rule syntax

Permission rules follow the format `Tool` or `Tool(specifier)`. Parentheses inside the specifier are literal, so a command or path that contains them needs no escaping.


[​](#match-all-uses-of-a-tool)

Match all uses of a tool

To match all uses of a tool, use only the tool name without parentheses:

| Rule       | Effect                         |
|:-----------|:-------------------------------|
| `Bash`     | Matches all Bash commands      |
| `WebFetch` | Matches all web fetch requests |
| `Read`     | Matches all file reads         |

`Bash(*)` is equivalent to `Bash` and matches all Bash commands. As a deny rule, both forms remove the tool from Claude’s context. The label shown for a tool in the transcript and permission dialog can differ from its canonical name. For example, the tool labeled `Stop Task` in the transcript has the canonical name `TaskStop`. Permission rules and [hook matchers](../07-Hooks/hooks.md) don’t match the label, so a rule written as `Stop Task` doesn’t match. For deny and ask rules, a [startup warning](errors.md#matches-no-tool) says so. Use the canonical names listed in the [tools reference](tools-reference.md).


[​](#use-specifiers-for-fine-grained-control)

Use specifiers for fine-grained control

Add a specifier in parentheses to match specific tool uses:

| Rule                           | Effect                                                   |
|:-------------------------------|:---------------------------------------------------------|
| `Bash(npm run build)`          | Matches the exact command `npm run build`                |
| `Read(./.env)`                 | Matches reading the `.env` file in the current directory |
| `WebFetch(domain:example.com)` | Matches fetch requests to example.com                    |


[​](#match-by-input-parameter)

Match by input parameter

Deny and ask rules can match a top-level input parameter on any built-in tool with `Tool(param:value)`. To match a parameter on an MCP tool, pass a deny rule with [`--disallowedTools`](cli-reference.md#cli-flags). When Claude Code loads a settings file, it skips any `mcp__` rule that has parentheses. Claude Code lists the skipped rule in the invalid-settings dialog when an interactive session starts, and in [`claude doctor`](debug-your-config.md#check-resolved-settings) output. A parameter rule matches when Claude calls the tool with that parameter set to that exact value. An allow rule for one parameter value wouldn’t establish that the call is safe overall, so allow rules continue to use each tool’s own specifier syntax. This works for any scalar parameter the tool accepts:

| Rule                           | Matches                                      |
|:-------------------------------|:---------------------------------------------|
| `Agent(model:opus)`            | Agent calls that request the Opus model tier |
| `Agent(isolation:worktree)`    | Agent calls that request a git worktree      |
| `Bash(run_in_background:true)` | Bash calls that run in the background        |

Parameter matching follows these rules:

- The parameter name must be a direct field of the tool’s input, such as `model` on the Agent tool. Fields nested inside an object or array are not matchable
- Each rule names one parameter. To gate on both `model` and `isolation`, write two rules, `Agent(model:opus)` and `Agent(isolation:worktree)`, rather than combining them in one rule
- The value supports `*` as a wildcard that matches any sequence of characters, so `Agent(isolation:*)` matches any explicit isolation value. Without `*` the match is exact
- A parameter the model omits is never matched, so `Agent(model:*)` doesn’t match a call that leaves `model` unset
- The value is compared against the literal input Claude sends, before any normalization. `Agent(model:opus)` matches the alias `opus` but not a full model ID
- A `Skill(skill:<name>)` deny rule instead [matches the skill under any of its names](../08-Plugins-Skills/skills.md#restrict-claude%E2%80%99s-skill-access), such as its alias or display name
- Run with [`--verbose`](cli-reference.md) to see the exact parameter names and values in each tool call
- Whitespace around the colon is ignored

You can’t match a tool’s primary content field this way: `command` for Bash and PowerShell, `file_path` for Read, Edit, and Write, `path` for Grep and Glob, `notebook_path` for NotebookEdit, and `url` for WebFetch. A rule like `Bash(command:rm *)` would be bypassable by a compound command, so Claude Code ignores it and emits a startup warning. Use `Bash(rm *)`, `Read(./path)`, or `WebFetch(domain:host)` instead.


[​](#wildcard-patterns)

Wildcard patterns

A `*` in a Bash rule matches any text, including spaces, so one rule covers a family of commands. A rule with no `*` matches one exact command.

Put the `*` after the subcommand. In `git log --oneline main`, `git` is the program and `log` is the subcommand, the word that determines what the program does. Claude Code matches everything before the first `*` as written, so those words are what limit the rule: `Bash(git log *)` allows only `git log` commands, and `Bash(git *)` allows every git command. Claude Code [warns at startup](errors.md#has-a-wildcard-before-the-rest-of-the-command) about an allow rule with a `*` before the subcommand, such as `Bash(git * main)`.

Write the command you want Claude to run without asking, and replace the parts that vary with `*`. With this configuration, Claude Code runs npm scripts and git commits without asking and refuses commands that begin with `git push`. A push written another way, such as `git -C . push`, isn’t matched; see [what a Bash rule doesn’t match](#bash-rule-limits).

```python
{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git commit *)"
    ],
    "deny": [
      "Bash(git push *)"
    ]
  }
}
```

A `*` can go anywhere in the rule: at the start, in the middle, or at the end. Each row shows a rule, commands it matches, and nearby commands it doesn’t match:

| You write              | Matches                                                                              | Doesn’t match                          |
|:-----------------------|:-------------------------------------------------------------------------------------|:---------------------------------------|
| `Bash(npm run build)`  | `npm run build`                                                                      | `npm run build --watch`                |
| `Bash(npm run *)`      | `npm run build`, `npm run test --watch`, `npm run`                                   | `npm install`                          |
| `Bash(git log * main)` | `git log --oneline main`, `git log -5 main`, `git log --output=<file> main`          | `git log main`, `git push origin main` |
| `Bash(git * main)`     | `git merge main`, `git push origin main`, `git -c core.fsmonitor=<script> diff main` | `git log`                              |
| `Bash(* --version)`    | `node --version`, `bash -c 'echo hi' --version`                                      | `node -v`                              |
| `Bash(ls *)`           | `ls -la`, `ls`                                                                       | `lsof`                                 |
| `Bash(ls*)`            | `ls -la`, `lsof`                                                                     |                                        |
| `Bash(* --help *)`     | `npm --help x`                                                                       | `npm --help`                           |

Three matching rules produce those rows:

- **The `*` stands in for whatever text is in its place.** In `Bash(git * main)`, it stands in for the subcommand, so Claude Code matches every git subcommand and every option before it. That includes `-c`, which makes git run a program you name. In `Bash(* --version)`, the `*` stands in for the program, so any program matches.
- **A `*` at the end, with a space before it, also matches the bare command.** `Bash(ls *)` matches `ls`, and `Bash(git log *)` matches `git log`. That holds only when the trailing `*` is the rule’s only wildcard: `Bash(* --help *)` matches `npm --help x` but not `npm --help`.
- **The space before a trailing `*` is part of the rule.** `Bash(ls *)` requires a space after `ls`, so `lsof` doesn’t match. `Bash(ls*)` has no space, so it matches `lsof` too.

The `:*` suffix is an equivalent way to write a trailing wildcard, so `Bash(ls:*)` matches the same commands as `Bash(ls *)`. The permission dialog writes the space-separated form when you select “Yes, and don’t ask again” for a command prefix. The `:*` form is only recognized at the end of a pattern. In a pattern like `Bash(git:* push)`, the colon is treated as a literal character and won’t match git commands.


[​](#tool-name-wildcards)

Tool name wildcards

Deny and ask rules also accept glob patterns in the tool-name position. The pattern must match the full tool name: `"*"` matches every tool, and `"mcp__*"` matches every MCP tool across all servers. A tool matched by a bare-name glob deny rule is removed from Claude’s context, the same as a bare tool name, including the [`EndConversation`](tools-reference.md#endconversation-tool-behavior) exception: a glob deny can’t remove it while any other tool remains, and a glob ask never prompts for it. This configuration denies every MCP tool:

```python
{
  "permissions": {
    "deny": [
      "mcp__*"
    ]
  }
}
```

Allow rules accept tool-name globs only after a literal `mcp__<server>__` prefix. The server segment must be glob-free so the rule names a specific server you configured. `mcp__puppeteer__*` matches every tool from the `puppeteer` server, and `mcp__github__get_*` matches its `get_` tools. An unanchored allow glob such as `"*"`, `"B*"`, or `"mcp__*"` is skipped and doesn’t auto-approve anything. A deny or ask rule whose tool name matches no known tool produces a [startup warning](errors.md#matches-no-tool) to catch typos. Tool names containing `_` or `*` are exempt from the check, and so are the names of tools Claude Code has removed, such as `TaskOutput`.


[​](#tool-specific-permission-rules)

Tool-specific permission rules


[​](#bash)

Bash

Bash rules match the whole command text, with `*` standing in for any text. [Wildcard patterns](#wildcard-patterns) shows which commands each rule shape matches and where to put the `*`. The rest of this section covers how Claude Code matches compound commands and wrappers, which wrappers and `find` actions a prefix rule can’t approve, what a rule doesn’t match, read-only commands, and redirections.


[​](#compound-commands)

Compound commands

Claude Code is aware of shell operators, so a rule like `Bash(safe-cmd *)` won’t give it permission to run the command `safe-cmd && other-cmd`. The recognized command separators are `&&`, `||`, `;`, `|`, `|&`, `&`, and newlines. A rule must match each subcommand independently.

Deny and ask rules apply when any subcommand matches them, including a command nested inside a subshell, a command substitution, or a control-flow body such as a `for` loop. An ask rule like `Bash(git clean *)` still prompts you for `cd /tmp && git clean -f` or `echo "$(git clean -f)"`, even in [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode). When `&&` or `||` has nothing after it, such as in `npm test &&`, Claude Code treats the command as unparseable and doesn’t split it into subcommands for allow-rule matching, so a rule such as `Bash(npm *)` doesn’t approve it. When you approve a compound command with “Yes, and don’t ask again”, Claude Code saves a separate rule for each subcommand that requires approval, rather than a single rule for the full compound string. For example, approving `git status && npm test` saves a rule for `npm test`, so future `npm test` invocations are recognized regardless of what precedes the `&&`. Subcommands like `cd` into a directory outside your working directories generate their own Read rule for that path. Up to 5 rules may be saved for a single compound command.


[​](#process-wrappers)

Wrappers

Before matching Bash rules, Claude Code strips a fixed set of wrappers, so a rule like `Bash(npm test *)` also matches `timeout 30 npm test`. The stripped wrappers are `timeout`, `time`, `nice`, `nohup`, and `stdbuf`, plus the shell builtins `command` and `builtin`, and zsh’s `noglob`. Each runs its argument as the actual command. Two related forms aren’t stripped: the query form `command -v`, which looks up a command rather than running one, and zsh’s `nocorrect`. Claude Code also strips a leading assignment of certain known-safe environment variables, so `Bash(npm test *)` matches `NODE_ENV=test npm test`. An allow rule won’t match past an assignment of any other variable. A deny or ask rule matches past any leading assignment, so `Bash(rm *)` in deny still matches `FOO=bar rm -rf tmp/`. Bare `xargs` is also stripped, so `Bash(grep *)` matches `xargs grep pattern`. Stripping applies only when `xargs` has no flags: an invocation like `xargs -n1 grep pattern` is matched as an `xargs` command, so rules written for the inner command do not cover it. This wrapper list is built in and is not configurable. Development environment runners such as `direnv exec`, `devbox run`, `mise exec`, `npx`, and `docker exec` are not in the list. Because these tools execute their arguments as a command, a rule like `Bash(devbox run *)` matches whatever comes after `run`, including `devbox run rm -rf .`. To approve work inside an environment runner, write a specific rule that includes both the runner and the inner command, such as `Bash(devbox run npm test)`. Add one rule per inner command you want to allow.


[​](#exec-wrappers-and-find-actions)

Exec wrappers and `find` actions

A prefix rule like `Bash(watch *)` or `Bash(find *)` can’t auto-approve the following commands, so in Manual mode they prompt:

- **Exec wrappers**: such as `watch`, `setsid`, `ionice`, and `flock`
- **`find`**: with an action that runs commands, deletes files, or writes files, such as `-exec`, `-delete`, `-rm`, or `-fprint`, or with `-files0-from`, which takes the paths to search from a file

To approve a specific invocation that has no `*` in it, write an exact-match rule for the full command string, such as `Bash(find build -type f -delete)`. When the command has a `*`, as in `find . -name '*.tmp' -delete`, Claude Code reads the rule as a [wildcard pattern](#wildcard-patterns), not an exact match, so the command still prompts. Approve it each time it prompts, or use a [PreToolUse hook](../07-Hooks/hooks.md#pretooluse-decision-control) that returns `"allow"` for it.


[​](#bash-rule-limits)

What a Bash rule doesn’t match

A Bash rule matches the command text Claude writes, after Claude Code splits [compound commands](#compound-commands) and strips [wrappers](#process-wrappers). It doesn’t match the same program invoked in a different form, so a deny or ask rule covers the invocation Claude usually produces and isn’t a security boundary around the program. These rules in `deny` or `ask` stop the first form and not the others:

| Rule               | Stops                      | Doesn’t stop                                                                                          |
|:-------------------|:---------------------------|:------------------------------------------------------------------------------------------------------|
| `Bash(curl *)`     | `curl https://example.com` | `/usr/bin/curl https://example.com`, `sh -c 'curl https://example.com'`                               |
| `Bash(rm *)`       | `rm -rf build/`            | `/bin/rm -rf build/`, `bash -c 'rm -rf build/'`                                                       |
| `Bash(git push *)` | `git push origin main`     | `git -C . push origin main`, `git -c push.default=current push origin main`, `git 'push' origin main` |

Your other rules and the permission mode decide the commands in the last column. For filesystem and network enforcement that doesn’t depend on the command text, use [sandboxing](sandboxing.md). To inspect the full command text with your own logic before it runs, use a [PreToolUse hook](#extend-permissions-with-hooks).


[​](#read-only-commands)

Read-only commands

Claude Code recognizes a built-in set of Bash commands as read-only and runs them without a permission prompt in every mode, except as [`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) changes for paths outside your working directories. The set includes `ls`, `cat`, `echo`, `pwd`, `head`, `tail`, `grep`, `find`, `wc`, `which`, `diff`, `stat`, `du`, `cd`, and read-only forms of `git`. The set is not configurable; to require a prompt for one of these commands, add an `ask` or `deny` rule for it. In auto mode, these commands can also wait for the classifier’s review; see [how the classifier evaluates actions](permission-modes.md#how-the-classifier-evaluates-actions). A redirect such as `ls > out.txt` adds a check on the target. See [Redirections](#redirections). Unquoted glob patterns are permitted for commands whose every flag is read-only, so `ls *.ts` and `wc -l src/*.py` run without a prompt. In Manual mode, commands from this set still prompt in these cases:

- **Unquoted globs for commands with write-capable flags**: commands with write-capable or exec-capable flags, such as `find`, `sort`, `sed`, and `git`, prompt when an unquoted glob is present, because the glob could expand to a flag like `-delete`.
- **`docker` pointed at another daemon**: read-only forms of `docker` prompt when the command carries a flag that selects a different daemon, such as `-H`, `--context`, or Podman’s `--url` and `--connection`.
- **`file` with path-opening flags**: `file` prompts when it passes `-m`/`--magic-file` or `-f`/`--files-from`, because those flags make `file` open the paths named in the flag’s value.
- **`ps` that could print environment variables**: `ps` prompts when one of its arguments could act as the `e` option, such as in `ps auxe` or `ps aux -e`, because that option prints process environment variables. `ps aux` and `ps -ef` run without a prompt. The check on dashed forms such as `ps aux -e` requires Claude Code v2.1.290 or later.
- **Network paths on Windows**: a command whose arguments include a network (UNC) path, such as `\\server\share\file`, prompts because accessing a network path can send your Windows credentials to the host it names. The same check applies to [PowerShell tool](tools-reference.md#powershell-tool) commands.
- **Writes to special shell variables**: a command that sets, unsets, or loops over certain special shell variables, such as `PATH` or `IFS`, prompts even when the rest of the command is read-only.
- **Commands the analysis can’t parse**: when Claude Code can’t fully parse a command, it asks for approval instead of treating the command as read-only. Commands longer than 10,000 characters always prompt because they exceed what the analysis parses.

A `cd` into a path inside your working directory or an [additional directory](#working-directories) is also read-only, and a compound command like `cd packages/api && ls` runs without a prompt when each part qualifies on its own. These combinations prompt even when each part is read-only:

- **`cd` with `git`**: prompts when the `cd` changes into a different directory, since running `git` in a new directory can execute that directory’s hooks. A `cd` whose target resolves to the current working directory is a no-op and doesn’t trigger the prompt.
- **`cd` with a redirect**: prompts when Claude Code can’t determine which directory the redirect target resolves against after the `cd` runs. A command whose only redirect target is `/dev/null`, such as `cd app; grep -r pattern . 2>/dev/null`, doesn’t prompt, because `/dev/null` doesn’t depend on the working directory.

Bash permission patterns that try to constrain command arguments are fragile. For example, `Bash(curl http://github.com/ *)` intends to restrict curl to GitHub URLs, but won’t match variations like:

- Options before URL: `curl -X GET http://github.com/...`
- Different protocol: `curl https://github.com/...`
- Redirects: `curl -L http://short.example.com/xyz`, which redirects to GitHub
- Variables: `URL=http://github.com && curl $URL`

For more reliable URL filtering, consider:

- **Restrict Bash network tools**: use deny rules to stop `curl`, `wget`, and similar commands, then use the WebFetch tool with `WebFetch(domain:github.com)` permission for allowed domains. A deny rule doesn’t match the same program by path or inside `sh -c`, so pair it with the [sandbox network allowlist](sandboxing.md#network-isolation) when the restriction must hold; see [what a Bash rule doesn’t match](#bash-rule-limits)
- **Use PreToolUse hooks**: implement a hook that validates URLs in Bash commands and blocks disallowed domains
- **Add CLAUDE.md guidance**: describe your allowed curl patterns in `CLAUDE.md`. This shapes what Claude tries but doesn’t enforce a boundary, so pair it with one of the options above

Note that using WebFetch alone doesn’t prevent network access. If Bash is allowed, Claude can still use `curl`, `wget`, or other tools to reach any URL.


[​](#redirections)

Redirections

When a command redirects output or input, Claude Code checks the redirect target against your file rules as if Claude wrote or read that file directly:

- **Output redirects**: for `> file`, `>> file`, or `2> file`, the check covers your `Edit` allow and deny rules, [protected paths](permission-modes.md#protected-paths), and the [working directories](#working-directories). A rule such as `Bash(git commit *)` allows the command, not the target. A target that starts with `~` or contains a glob character needs your approval.
- **Input redirects**: for `< file`, the check covers your `Read` allow and deny rules and the working directories. A target outside the working directories needs your approval unless an allow rule covers it. A target that contains a glob pattern, or a relative path that follows a `cd` in the same command, needs your approval even when an allow rule covers it. Claude Code checks input targets in v2.1.257 and later.

Targets with no file behind them aren’t checked: `/dev/null`, file-descriptor forms such as `2>&1` and `<&3`, and here-docs and here-strings. Claude Code also checks the files a `tee` command writes, including in a pipeline such as `make | tee build.log`. The check covers your `Edit` allow and deny rules, [protected paths](permission-modes.md#protected-paths), and the [working directories](#working-directories). An allow rule such as `Bash(tee *)` doesn’t cover a destination outside the working directories. Claude Code checks `tee` targets in v2.1.269 and later.


[​](#powershell)

PowerShell

PowerShell permission rules use the same shape as Bash rules. Wildcards with `*` match at any position, the `:*` suffix is equivalent to a trailing ` *`, and a bare `PowerShell` or `PowerShell(*)` matches every command. This configuration allows `Get-ChildItem` and `git commit` commands while blocking `Remove-Item`:

```python
{
  "permissions": {
    "allow": [
      "PowerShell(Get-ChildItem *)",
      "PowerShell(git commit *)"
    ],
    "deny": [
      "PowerShell(Remove-Item *)"
    ]
  }
}
```

Common aliases are canonicalized before matching. A rule written for the cmdlet name also matches its aliases, so `PowerShell(Get-ChildItem *)` matches `gci`, `ls`, and `dir` as well. Matching is case-insensitive. Claude Code parses the PowerShell AST and checks each command in a compound command independently. Pipeline operators `|`, statement separators `;`, and on PowerShell 7+ the chain operators `&&` and `||` split a compound command into subcommands. A rule must match every subcommand for the compound command to be allowed.


[​](#read-and-edit)

Read and Edit

To block Claude’s file tools from reading a file or directory, add a `Read` deny rule for its path, such as `Read(./.env)` or `Read(./secrets/**)`; [Exclude sensitive files](settings-reference.md#exclude-sensitive-files) has a paste-ready example. If your project has a `.claudeignore` file, it has no effect, so move its entries into `Read` deny rules.


[​](#what-read-and-edit-rules-cover)

What `Read` and `Edit` rules cover

`Edit` rules apply to all built-in tools that edit files. Claude makes a best-effort attempt to apply `Read` rules to all built-in tools that read files like Grep and Glob, to `@file` mentions in your prompts, and to the selection and open-file context that a connected [IDE](../03-IDE-Integrations/vs-code.md#the-built-in-ide-mcp-server) shares with Claude. A `Read(path)` deny rule also applies to image paths you paste into a prompt and directories you @-mention:

- **Image path**: when you paste an image’s path or drag an image file into your prompt in the terminal and the rule matches that path, Claude Code doesn’t attach the image. If the paste holds no other image, the path stays in your prompt as text.
- **Directory**: the [listing Claude receives](common-workflows.md#reference-files-and-directories) leaves out the file and directory names the rule matches.

Claude Code checks pasted image paths and directory listings in v2.1.290 and later. A `Read` deny rule also blocks the [Edit and Write tools](errors.md#file-is-covered-by-a-read-deny-rule) on the same path, including creating a new file there. NotebookEdit isn’t covered, so add an `Edit` deny rule for paths no tool may change. For the Write tool, the check requires Claude Code v2.1.228 or later.

Read and Edit deny rules apply to Claude’s built-in file tools, to file commands Claude Code recognizes in Bash, such as `cat`, `head`, `tail`, `sed`, and `tee`, and to the targets of Bash [redirections](#redirections) such as `> file` and `< file`. They don’t apply to a command that reads files without naming them, such as `grep -r pattern .` run from the directory that holds the file, or to arbitrary subprocesses that read or write files indirectly, like a Python or Node script that opens files itself. For OS-level enforcement that blocks all processes from accessing a path, [enable the sandbox](sandboxing.md).


[​](#path-rules-that-never-match)

`Write(path)`, `NotebookEdit(path)`, and `Glob(path)` rules never match

Claude Code checks file permissions against `Edit(path)` and `Read(path)` rules only. If you write a path rule for `Write`, `NotebookEdit`, `Glob`, or legacy `MultiEdit`, Claude Code accepts the rule but never matches a read or edit against it. Use `Edit(docs/**)` in place of `Write(docs/**)`, `NotebookEdit(docs/**)`, or `MultiEdit(docs/**)`, and `Read(docs/**)` in place of `Glob(docs/**)`. To match every use of the Write, NotebookEdit, or Glob tool regardless of path, write only the tool name.


[​](#how-path-patterns-match)

How path patterns match

Read and Edit rules both use [gitignore](https://git-scm.com/docs/gitignore) pattern syntax with four distinct pattern types:

| Pattern            | Meaning                              | Example                          | Matches                                                       |
|--------------------|--------------------------------------|----------------------------------|---------------------------------------------------------------|
| `//path`           | Absolute path from filesystem root   | `Read(//Users/alice/secrets/**)` | `/Users/alice/secrets/**`                                     |
| `~/path`           | Path from home directory             | `Read(~/Documents/*.pdf)`        | `/Users/alice/Documents/*.pdf`                                |
| `/path`            | Path relative to the settings source | `Edit(/src/**/*.ts)`             | `<primary working directory>/src/**/*.ts` in project settings |
| `path` or `./path` | Path relative to current directory   | `Read(*.env)`                    | `<cwd>/*.env`                                                 |

A pattern like `/Users/alice/file` isn’t an absolute path. The single leading slash anchors at the settings source, not the filesystem root. Use `//Users/alice/file` for absolute paths.

##### Where a pattern anchors

A `/path` pattern anchors at a directory associated with the settings source that defines it, so the same rule matches different locations depending on where you put it:

| Rule defined in                                 | `/path` resolves to                |
|:------------------------------------------------|:-----------------------------------|
| Project settings at `.claude/settings.json`     | `<primary working directory>/path` |
| Local settings at `.claude/settings.local.json` | `<primary working directory>/path` |
| User settings at `~/.claude/settings.json`      | `~/.claude/path`                   |
| A file passed with `--settings <file>`          | `<directory of file>/path`         |
| CLI flags or session rules                      | `<primary working directory>/path` |

A rule you add through `/permissions` follows the row for the settings file you save it to. Local settings rules anchor at the session’s [primary working directory](#working-directories), not at the repository root where Claude Code [stores the file](#permission-system) in v2.1.211 and later. In a session started at the repository root, the two directories are the same; in a [worktree](worktrees.md) session, a shared rule such as `Edit(/src/**)` matches that worktree’s own `src/` directory. A deny rule such as `Read(/secrets/**)` in user settings blocks `~/.claude/secrets/**`, not a `secrets` directory in your project. To write a rule in user settings that applies inside every project, use a `//` absolute path or a `~/` home-relative path instead. On Windows, paths are normalized to POSIX form before matching. `C:\Users\alice` becomes `/c/Users/alice`, so use `//c/**/.env` to match `.env` files anywhere on that drive. To match across all drives, use `//**/.env`. Examples:

- `Edit(/docs/**)`: edits in `<primary working directory>/docs/`, not `/docs/` or `<primary working directory>/.claude/docs/`
- `Read(~/.zshrc)`: reads your home directory’s `.zshrc`
- `Edit(//tmp/scratch.txt)`: edits the absolute path `/tmp/scratch.txt`
- `Read(src/**)`: as an allow rule, reads from `<current-directory>/src/` only; as a deny or ask rule, matches a `src` directory at any depth under the current directory

##### How deep a pattern matches

A rule only matches files under its anchor; within that bound, matching depth depends on the pattern shape and, for single-segment directory patterns, the rule type, described below. Bare filenames follow gitignore semantics and match at any depth, so `Read(.env)` and `Read(**/.env)` are equivalent:

| Deny rule                       | Blocks                                       | Does not block                                       |
|---------------------------------|----------------------------------------------|------------------------------------------------------|
| `Read(.env)` or `Read(**/.env)` | any `.env` at or under the current directory | `.env` in a parent directory or another project      |
| `Read(//**/.env)`               | any `.env` anywhere on the filesystem        | nothing; the rule is anchored at the filesystem root |

A relative pattern with a single directory segment, such as `src/**`, matches at different depths depending on the rule type:

- **Allow rules**: `Edit(src/**)` matches only `<cwd>/src` and the files under it. To allow a directory name at any depth, write `Edit(**/src/**)`.
- **Deny and ask rules**: `Read(secrets/**)` matches a directory named `secrets` at any depth under the current directory, so the rule also applies to nested copies.

Every other pattern shape matches at the same depth in every rule type: `Edit(/src/**)` and `Edit(src/components/**)` match only at their anchored location, while `Edit(**/src/**)` matches at any depth. The following example shows each pattern shape against a project with a top-level `src/` directory and a nested copy under `vendor/`:

```python
<current-directory>/
├── src/
│   └── app.ts
└── vendor/
    └── pkg/
        └── src/
            └── lib.js
```

| Rule                                 | Matches `src/app.ts` | Matches `vendor/pkg/src/lib.js` |
|:-------------------------------------|:---------------------|:--------------------------------|
| `Edit(src/**)` as an allow rule      | Yes                  | No                              |
| `Edit(src/**)` as a deny or ask rule | Yes                  | Yes                             |
| `Edit(/src/**)` in any rule type     | Yes                  | No                              |
| `Edit(**/src/**)` in any rule type   | Yes                  | Yes                             |

In gitignore patterns, `*` matches within a single path segment and can appear at any position in the pattern, while `**` matches across directories.


[​](#special-characters-and-negation)

Special characters and `!` negation

When you approve a file path with “Yes, and don’t ask again”, Claude Code escapes gitignore pattern characters in that path, such as `[`, `]`, and `*`, so the generated rule matches only the literal path you approved. Rules you write yourself aren’t escaped. You don’t need to escape parentheses in a path, so `Edit(./Finance (2024)/**)` matches the `Finance (2024)` folder as spelled. A deny or ask rule whose path isn’t usable as a gitignore pattern still guards that exact path. An allow rule with an unusable pattern doesn’t approve anything. A deny or ask pattern that starts with `!` is a gitignore negation. It carves the paths it matches out of the `path` or `./path` rules listed before it. In one settings file’s `deny` list, `Read(*.env)` followed by `Read(!sample.env)` blocks every file whose name ends in `.env` at any depth, except files named `sample.env`. A `!` rule listed first carves nothing out. The carve-out reaches only rules from the same source. A `Read(!.env)` in project settings or in `--disallowedTools` doesn’t cancel a `Read(./.env)` deny from managed settings or any other settings file. Two limits narrow what a `!` pattern can carve out:

- Claude Code reads a `!` pattern relative to the current directory even when `/`, `~/`, or `//` follows the `!`, so the pattern can’t reach a rule anchored with one of those prefixes. `Read(!~/notes/public/**)` carves nothing out of `Read(~/notes/**)`.
- A carve-out can’t reopen a file inside a directory that a rule blocks as a whole. With `Read(secrets/**)` and `Read(!secrets/public/**)`, Claude Code still blocks `secrets/public` along with the rest of `secrets`.


[​](#symlinks)

Symlinks

When a file path Claude requests goes through a symlink, the permission check covers two paths: the one Claude requested and the file it resolves to. This applies to symbolic links on macOS, Linux, and Windows, and to directory junctions on Windows.

##### How rules match a symlinked path

Allow and deny rules treat the requested path and the file it resolves to differently:

- **Allow rules**: apply only when both the requested path and the file it resolves to match. A read through a symlink inside an allowed directory that points outside it doesn’t match the rule.
- **Deny rules**: apply when either the requested path or the file it resolves to matches. A symlink that points to a denied file is itself denied. For example, with `Read(./project/**)` allowed and `Read(~/.ssh/**)` denied, a symlink at `./project/key` pointing to `~/.ssh/id_rsa` is blocked: the target fails the allow rule and matches the deny rule.

On macOS and Linux, a deny or ask rule written through a symlinked directory with a `//`, `~/`, or `/` pattern also applies at the directory’s real location. For example, on macOS, where `/etc` resolves to `/private/etc`, `Read(//etc/**)` blocks `/private/etc/hosts` too. Before v2.1.268, a deny or ask rule written through a symlinked directory didn’t apply to a path given by its real location. Grep and Glob search the directory the `path` argument resolves to. Claude Code applies `Read` deny rules to that directory.

##### Attachments through a symlink

A `Read` deny rule also covers these attachments, matching each one on either the named path or the file it resolves to. Claude Code leaves an attachment out of the conversation when a rule matches it:

- **`@`-mentions**: a file or directory you mention in your prompt. A refused file leaves nothing in the conversation, and a [directory’s listing](#read-and-edit) leaves out the names a rule covers.
- **Pasted images**: an image whose path you paste or drag into the prompt in the terminal
- **Changed files**: a file Claude Code re-reads after it changes on disk
- **IDE context**: the selection and open-file context a connected IDE shares

With [`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) on, or in a [`--restricted`](cli-reference.md#cli-flags) session, these attachments are also left out when they come from a path where that setting or flag refuses Claude’s file reads. This line in place of a file you `@`-mentioned means Claude Code couldn’t work out where the path leads, for example because its symlinks form a loop:

```python
Referenced <path> (not read: could not be examined)
```

Claude is told to read the path with its file tools instead, which can succeed when Claude Code only ran out of time to examine the path. When the path’s symlinks don’t resolve, that read is [refused](errors.md#refusing-after-a-symlink-changed) too, so fix the link on disk or `@`-mention the file by a path that resolves.

##### Writes through a symlink

If the path Claude asks to edit or write is itself a symlink, the Edit and Write tools [refuse the write and direct Claude to the link’s target](errors.md#refusing-after-a-symlink-changed). A write can still pass through a symlink when a directory on the way to the file is a symlink, or when a Bash or PowerShell command does the writing. For those writes, what happens depends on where the file the write resolves to sits relative to your [working directories](#working-directories) and the [protected paths](permission-modes.md#protected-paths):

- **Resolves outside the working directories**: when the requested path is inside your working directories and the file it resolves to isn’t, the write isn’t auto-approved in [`acceptEdits` mode](permission-modes.md#auto-approve-file-edits-with-acceptedits-mode). In [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode), unless an allow rule approves the write, you’re prompted for it instead of the classifier deciding. The prompt names the path the write resolves to.
- **Resolves to a protected path that the requested path doesn’t name**: the [protected paths table](permission-modes.md#protected-paths) gives the outcome for each permission mode, except that where the table routes the write to the classifier, this write prompts you instead.

##### Paths that can’t be resolved or that change

When Claude Code can’t determine where a path leads on disk, for example because symlinks on it form a loop, the Read, Edit, and Write tools [refuse the operation](errors.md#refusing-after-a-symlink-changed). When a tool then opens the approved file, it [confirms that the path still resolves to the location the permission check approved](errors.md#refusing-after-a-symlink-changed).


[​](#network-paths)

Network paths

When Claude’s file-reading tools, such as Read, Grep, and Glob, read from a network path, the read gets its own permission check. A network path is one that can reach another computer: on Windows, a UNC path such as `\\server\share\file`, and on macOS and Linux, a `/net` automount path such as `/net/fileserver/notes.txt`. Looking up such a path can contact the host it names, and on Windows that contact can send the host your credentials. Shell commands have their own check: in Manual mode, a read-only Bash or PowerShell command whose arguments include a UNC path [still prompts on Windows](#read-only-commands). In Claude Code v2.1.292 and later, each of these leaves the prompt in place:

- **Allow rules**: a rule doesn’t pre-approve the read, including a rule for the whole tool, such as `Read`
- **PreToolUse hooks**: a [hook](#extend-permissions-with-hooks) that returns `"allow"` doesn’t skip the prompt
- **Auto mode**: the prompt comes to you, and the [classifier](permission-modes.md#eliminate-prompts-with-auto-mode) doesn’t decide the read

In `dontAsk` mode, Claude Code denies the read instead of prompting. In `bypassPermissions` mode, and in interactive terminal sessions in plan mode with [bypass permissions](permission-modes.md#skip-all-checks-with-bypasspermissions-mode) available, the read runs without this prompt. To read files on a network share without this prompt, give the share a local path first:

- **Windows**: map the share to a drive letter and pass the drive with `--add-dir` when you launch Claude Code, as [Working directories](#working-directories) describes. Reads under a drive you add later with `/add-dir`, or list in `additionalDirectories` in a settings file, still prompt. To stop those prompts for a share mapped to `Z:`, start a new session in PowerShell with `claude --add-dir Z:\`.
- **macOS and Linux**: mount the share at a local path, such as a directory under `/mnt` or `/Volumes`, and read the files from there, as [Working directory is a network path](errors.md#working-directory-is-a-network-path) describes


[​](#webfetch)

WebFetch

WebFetch rules use a `domain:` prefix and match against the hostname of the requested URL. Matching is case-insensitive, supports `*` wildcards, and strips a trailing `.` from both the rule and the hostname so `example.com.` and `example.com` are treated the same.

- `WebFetch(domain:example.com)` matches requests to `example.com` only. To also cover subdomains such as `api.example.com`, add a `WebFetch(domain:*.example.com)` rule
- `WebFetch(domain:*.example.com)` matches any subdomain at any depth, such as `api.example.com` or `a.b.example.com`, but not `example.com` itself
- `WebFetch(domain:*)` matches every domain. It isn’t the same as a bare `WebFetch` rule; see [Allow or deny every fetch](#allow-or-deny-every-fetch)

In any position other than a leading `*.` or a bare `*`, the wildcard matches only the text between two dots. `WebFetch(domain:example.*)` matches `example.org`, where `*` becomes `org`, but not `example.evil.com`, where `*` would have to become `evil.com` and cross a dot. This keeps a trailing wildcard from matching domains an attacker could register. Wildcards in `WebFetch` rules require Claude Code v2.1.172 or later to match fetches.


[​](#allow-or-deny-every-fetch)

Allow or deny every fetch

A bare `WebFetch` rule is the tool name with no `domain:` part, such as `"deny": ["WebFetch"]`. Both it and `WebFetch(domain:*)` cover every URL, but Claude Code applies them differently, and only the `domain:` form also adds its domain to the sandbox’s [allowed or denied domain list](sandboxing.md#network-isolation). That section lists the wildcard forms the sandbox honors and the version that added bare `*`. Each row shows what a rule does in the `allow` list and in the `deny` list:

| Rule                 | In `allow`                                                                                     | In `deny`                                                                                                                       |
|:---------------------|:-----------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------|
| `WebFetch`           | Claude fetches without prompting you. Doesn’t change which hosts sandboxed commands can reach. | Claude Code removes the `WebFetch` tool, so Claude can’t fetch at all. Doesn’t change which hosts sandboxed commands can reach. |
| `WebFetch(domain:*)` | Claude fetches without prompting you, and sandboxed commands can reach any host.               | Claude Code keeps the tool and refuses each fetch, and sandboxed commands can’t reach any host.                                 |

The two forms also differ on reads of [artifacts](artifacts.md), the pages the Artifact tool publishes on claude.ai. A bare `WebFetch` deny or ask rule doesn’t apply to those reads. A `domain:` rule covering `claude.ai` or the `*.claudeusercontent.com` content host, such as `WebFetch(domain:claude.ai)` or `WebFetch(domain:*)`, denies each read or prompts before it. An [`Artifact` rule](artifacts.md#disable-artifacts) does the same. When a rule blocks a read, the denial names the rule. Before v2.1.268, a bare `WebFetch` deny rule blocked every artifact read, and a bare ask rule prompted before each one. To let Claude fetch freely while keeping the sandbox allowlist as it is, use the bare form. This `settings.json` does that:

```python
{
  "permissions": {
    "allow": ["WebFetch"]
  }
}
```

When you ask Claude to fetch a page, it fetches without a prompt. When you ask it to run a [sandboxed](sandboxing.md) `curl` against a host outside the sandbox allowlist, Claude Code still prompts you for that host, because the bare rule didn’t add the host to the allowlist. In [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode), Claude instead names the host in the command’s [per-command allowed domains](sandboxing.md#per-command-allowed-domains-in-auto-mode) for the classifier to review.


[​](#mcp)

MCP

To match every tool from an MCP server, write `mcp__<server>__*`. To match one tool, write its full name, `mcp__<server>__<tool>`.

- `mcp__puppeteer` matches any tool provided by the `puppeteer` server
- `mcp__puppeteer__*` uses wildcard syntax and also matches all tools from the `puppeteer` server
- `mcp__puppeteer__puppeteer_navigate` matches the `puppeteer_navigate` tool provided by the `puppeteer` server

For `<server>`, write the server’s name the way it appears in that server’s tool names. These examples show the rule to write for a name with special characters, a server from a plugin, and a name that contains `__` or ends in `_`:

- **Names with characters such as `.` or spaces**: those characters become `_`, so for a server you configured as `my.server`, write `mcp__my_server__*`
- **Servers that a plugin provides**: `<server>` takes the [plugin-scoped form](../06-MCP-Tools/General/mcp.md#plugin-provided-mcp-servers), so for the `database-tools` server in a plugin named `my-plugin`, write `mcp__plugin_my-plugin_database-tools__*`
- **A `<server>` that contains `__` or ends in `_`**: write the wildcard form, `mcp__<server>__*`, with the whole name. For a server named `reports__v2`, write `mcp__reports__v2__*`. The bare `mcp__reports__v2` and the shorter `mcp__reports` don’t match its tools as allow rules, because Claude Code reads both as rules for a server named `reports`. As a deny or ask rule, though, each of those two names also covers every tool of the `reports__v2` server. To cover a server named `reports` alone, write one rule per tool in the `mcp__reports__<tool>` form, or rename one of the servers.

If your organization has set a [claude.ai connector](../06-MCP-Tools/General/mcp.md#organization-controls-on-connector-tools) tool to `ask` and that setting reaches Claude Code in your session, allow rules for that tool don’t take effect: Claude Code prompts on every call, even in `auto` and `bypassPermissions` modes. In `dontAsk` mode, which never prompts, Claude Code denies the call instead. Tools from connectors Claude Code fetches itself appear as `mcp__claude_ai_<server>__<tool>`. In a [Cowork](https://claude.com/docs/cowork/overview) session in the Claude Desktop app, Claude runs shell commands through Cowork’s `mcp__workspace__bash` tool rather than the built-in `Bash` tool, and Cowork likewise provides `mcp__workspace__web_fetch` for web fetches. Claude Code also applies deny rules that name the whole `Bash` or `WebFetch` tool to these Cowork tools, so a managed `Bash` deny rule stops Claude from running shell commands in Cowork. When Claude Code blocks such a call, the message names the Cowork tool: `Permission to use mcp__workspace__bash has been denied.` Allow rules don’t carry over: Claude Code never applies a `Bash` allow rule to `mcp__workspace__bash`.


[​](#agent-subagents)

Agent (subagents)

Use `Agent(AgentName)` rules to control which [subagents](../09-Agents-Patterns/sub-agents.md) Claude can use:

- `Agent(Explore)` matches the Explore subagent
- `Agent(Plan)` matches the Plan subagent
- `Agent(my-custom-agent)` matches a custom subagent named `my-custom-agent`

Add these rules to the `deny` array in your settings or use the `--disallowedTools` CLI flag to disable specific agents. To disable the Explore agent:

```python
{
  "permissions": {
    "deny": ["Agent(Explore)"]
  }
}
```


[​](#cd)

Cd

`Cd` rules control which directories the [`/cd` command](commands.md) can move the session to. `Cd` is not a model-invocable tool: Claude can’t call it, and the rules apply only when you run `/cd` yourself. A bare `Cd` deny rule disables `/cd` entirely. A `Cd(<path-pattern>)` deny rule blocks matching targets. Deny rules check every spelling of the target, including each symlink hop it resolves through, so a rule written for one path also blocks targets that resolve to it. Adding any `Cd` allow rule switches `/cd` to allowlist mode: the resolved target directory must match one of your allow rules, or `/cd` refuses. With no `Cd` rules configured, `/cd` keeps its default behavior and prompts you to trust an unfamiliar directory. Path patterns share the `//`, `~/`, and `/` anchors from [Read and Edit rules](#read-and-edit), but matching is anchored to the whole directory path rather than gitignore-style. `*` matches exactly one path segment and `**` matches across segments. A trailing `/**` also matches its named root.

| Rule                  | Matches                                                               | Does not match               |
|-----------------------|-----------------------------------------------------------------------|------------------------------|
| `Cd(~/code/*)`        | `~/code/app`                                                          | `~/code/app/src`, `~/code`   |
| `Cd(~/code/**)`       | `~/code` and any directory under it                                   | directories outside `~/code` |
| `Cd(**/node_modules)` | any `node_modules` directory at any depth under the current directory | `node_modules/pkg`           |


[​](#extend-permissions-with-hooks)

Extend permissions with hooks

[Claude Code hooks](../07-Hooks/hooks-guide.md) let you register custom shell commands that evaluate permissions at runtime. When Claude Code makes a tool call, PreToolUse hooks run before the permission prompt, for every tool except [`EndConversation`](tools-reference.md#endconversation-tool-behavior). The hook output can deny the tool call, force a prompt, or skip the prompt to let the call proceed.


[​](#precedence-among-rules-hooks-and-mods)

Precedence among rules, hooks, and mods

PreToolUse hook decisions don’t bypass permission rules. Claude Code evaluates deny and ask rules regardless of what a PreToolUse hook returns: a matching deny rule blocks the call, and a matching ask rule still prompts even when the hook returned `"allow"` or `"ask"`. This preserves the deny-first precedence described in [Manage permissions](#manage-permissions), including deny rules set in managed settings. That precedence covers hooks in settings files and in a plugin’s `hooks/hooks.json`. A [mod](../08-Plugins-Skills/plugins-mods-overview.md) you install that handles the [`tool.check`](../08-Plugins-Skills/plugins-mods-events.md#approve-or-refuse-a-tool-call-before-the-user-is-asked) event gives its answer after the `PreToolUse` hooks have run. With [managed settings](settings.md#check-what-your-organization-enforces) on the machine, or a Team or Enterprise [`/login`](authentication.md#authentication-precedence) as the session’s credential, these outcomes stay in place by default when the mod approves a call:

- A call that a deny rule refuses stays refused, and your organization can change that.
- A call that an ask rule would prompt for still prompts you.
- A call that a `PreToolUse` hook or [`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) would prompt for still prompts you.
- A call that a `PreToolUse` hook blocked stays blocked, whichever settings file the hook comes from.
- A call that your [`--permission-prompt-tool`](cli-reference.md#cli-flags) or Agent SDK [`canUseTool` callback](../05-Agent-SDK/agent-sdk-user-input.md#handle-tool-approval-requests) would be asked about is still put to that tool or callback.

With neither managed settings nor a Team or Enterprise `/login` as the session’s credential, the mod can approve a call that a deny rule refuses or a `PreToolUse` hook blocked. A session that runs on an API key or a long-lived [`CLAUDE_CODE_OAUTH_TOKEN`](authentication.md#generate-a-long-lived-token) instead isn’t using that login, even when that login is stored. In that setup you aren’t prompted when the mod approves a call that an ask rule, a `PreToolUse` hook, or `permissions.blockReadsOutsideWorkingDirectories` would prompt for. Your `--permission-prompt-tool` or `canUseTool` callback isn’t asked about a call the mod approves, either. Auto mode, plan mode, and `dontAsk` mode each add an outcome of their own in every setup:

- **[Auto mode](permission-modes.md#eliminate-prompts-with-auto-mode)**: a call the mod approves runs without a classifier check, except where the mod can’t bypass your permission prompt tool or Agent SDK permission callback. There the classifier checks the call first.
- **[Plan mode](#hook-approvals-in-plan-mode)**: the mod can’t approve a call that isn’t read-only, such as a file edit or a shell command that writes.
- **[`dontAsk` mode](permission-modes.md#allow-only-pre-approved-tools-with-dontask-mode)**: the mod can approve a call that nothing but the mode would deny.

See [Decide whether to trust a mod](../08-Plugins-Skills/plugins-mods-overview.md#decide-whether-to-trust-a-mod), or [Manage mods for your organization](../08-Plugins-Skills/plugins-mods-admin.md#know-what-happens-by-default) if you deploy managed settings. For a [tool that requires user interaction](permission-modes.md#actions-no-mode-auto-approves), such as `AskUserQuestion` or an MCP tool marked `requiresUserInteraction`, a mod’s `tool.check` approval doesn’t skip the prompt. Requires Claude Code v2.1.292 or later. MCP tools marked [`requiresUserInteraction`](../06-MCP-Tools/General/mcp.md#require-approval-for-a-specific-tool) also still prompt when a hook returns `"allow"`, as do reads from [network paths](#network-paths) and connector tools [your organization set to `ask`](../06-MCP-Tools/General/mcp.md#organization-controls-on-connector-tools) in sessions where that setting reaches Claude Code. A blocking hook also takes precedence over allow rules. A hook that exits with code 2 stops the tool call before permission rules are evaluated, so the block applies even when an allow rule would otherwise let the call proceed. To run all Bash commands without prompts except for a few you want blocked, add `"Bash"` to your allow list and register a PreToolUse hook that rejects those specific commands. See [Block edits to protected files](../07-Hooks/hooks-guide.md#block-edits-to-protected-files) for a hook script you can adapt.


[​](#hook-approvals-in-plan-mode)

Hook approvals in plan mode

In [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode), apart from `ExitPlanMode`, your `PreToolUse` hook’s `"allow"` has no effect on a file edit or another call that isn’t read-only. You get the same prompt, block, or approval the call would get with no hook, and Claude Code still applies any `updatedInput` the hook returns. If the hook answers [`ExitPlanMode`](../07-Hooks/hooks.md#allow-with-updatedinput) with `"allow"` and `updatedInput`, that tool still runs without a prompt. In plan mode, a mod that handles `tool.check` also can’t approve a file edit or another call that isn’t read-only, though it can still block such a call. To lift this limit on hook and mod approvals, [approve the plan](permission-modes.md#review-and-approve-a-plan) or switch to another permission mode.


[​](#working-directories)

Working directories

By default, Claude has access to files in the directory where you launched it. That directory is the session’s primary working directory until you [move the session with `/cd`](#move-the-session-to-another-directory). You can extend this access:

- **During startup**: use `--add-dir <path>` CLI argument
- **During session**: use `/add-dir` command
- **Persistent configuration**: add to `additionalDirectories` in [settings files](settings.md#where-settings-live)

Files in additional directories follow the same permission rules as the original working directory: they become readable without prompts apart from the [network path](#network-paths) check, and file editing permissions follow the current permission mode. You can’t add most [network paths](errors.md#working-directory-is-a-network-path), such as the UNC share `\\server\share`, as working directories, because looking one up can contact the host it names. On Windows, map the share to a drive letter instead and pass the drive with `--add-dir` at launch. Set [`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) to make the file tools refuse the paths it fences in every permission mode. In auto mode, Claude Code offers to turn it on the first time Claude [reads outside the working directories](permission-modes.md#first-read-outside-the-working-directories). In background sessions on macOS, the session host requests access to protected folders such as `~/Desktop`, `~/Documents`, and `~/Downloads` separately from your terminal when Claude needs to read or write files there; if reads there fail with `Operation not permitted`, see [how to grant folder access to background sessions](../09-Agents-Patterns/agent-view.md#background-sessions-can%E2%80%99t-read-desktop-documents-or-downloads-on-macos).


[​](#move-the-session-to-another-directory)

Move the session to another directory

To move the session to a different primary working directory, rather than [adding a directory](#working-directories) alongside the current one, run `/cd <path>`. Claude Code keeps the conversation, loads the new directory’s `CLAUDE.md`, and prompts you to [trust the workspace](#project-allow-rules-and-workspace-trust) if you haven’t worked in it before. Afterward, Claude Code [finds the moved session](sessions.md#where-the-session-picker-looks) when you run `--resume` from the new directory. As soon as you move, Claude Code applies the new directory’s project configuration:

- Its project settings, including their permission rules and [hooks](../07-Hooks/hooks.md)
- Its [`.mcp.json` servers](../06-MCP-Tools/General/mcp.md#project-scope), subject to the same [server approval](../06-MCP-Tools/General/mcp.md#project-server-approvals-and-workspace-trust) as at startup, and the [local-scope](../06-MCP-Tools/General/mcp.md#local-scope) MCP servers you registered in it
- The [plugins](../08-Plugins-Skills/plugins.md) its settings enable, its [skills](../08-Plugins-Skills/skills.md#discovery-from-parent-and-nested-directories), and its [subagents](../09-Agents-Patterns/sub-agents.md)
- Its [`env`](settings-reference.md#env) values, applied on top of the environment variables from the previous directory’s settings, which stay in effect

Claude Code also disconnects the previous directory’s project and [local-scope](../06-MCP-Tools/General/mcp.md#local-scope) MCP servers, and the servers of [plugins](../06-MCP-Tools/General/mcp.md#plugin-provided-mcp-servers) that are no longer enabled after the move. It takes [additional directories](#working-directories) from the new directory’s settings instead of the previous one’s, and keeps the directories you added with `--add-dir` or `/add-dir`. Hooks the move activates still receive [`${CLAUDE_PROJECT_DIR}`](../07-Hooks/hooks.md#reference-scripts-by-path) set to the project root where the session started. When the new directory isn’t trusted yet, Claude Code lists in the trust prompt the allow rules, additional directories, hooks, and helper commands the directory’s settings would activate, so you can review them before you accept. If you decline, the session stays where it is. Before v2.1.246, `/cd` didn’t apply the new directory’s settings, hooks, MCP servers, or skills until you resumed the session, and its trust prompt didn’t list what the directory’s settings would activate. Restrict or disable `/cd` targets with [`Cd` permission rules](#cd).


[​](#additional-directories-grant-file-access-not-configuration)

Additional directories grant file access, not configuration

Adding a directory extends where Claude can read and edit files. It doesn’t make that directory a full configuration root: most `.claude/` configuration is not discovered from additional directories, though a few types are loaded as exceptions. These exceptions apply only to directories added with the `--add-dir` flag or the `/add-dir` command, including directories the Agent SDK adds through the flag. Directories listed in `permissions.additionalDirectories` in a settings file grant file access only and don’t load any of the configuration below. The Agent SDK’s [`additionalDirectories`](../05-Agent-SDK/agent-sdk-typescript.md#options) option in TypeScript and [`add_dirs`](../05-Agent-SDK/agent-sdk-python.md#claudeagentoptions) option in Python receive the exceptions too, even though the TypeScript option shares its name with the settings key. The SDK passes each entry to Claude Code as `--add-dir`, so those directories behave like flag-added directories. Skills, commands, and subagents from any flag-added directory load through the `project` [setting source](../05-Agent-SDK/agent-sdk-claude-code-features.md#control-filesystem-settings-with-settingsources), so they don’t load when you exclude that source with [`--setting-sources`](cli-reference.md) on the CLI or `settingSources` in the SDK, and [bare mode](headless.md#start-faster-with-bare-mode) skips the commands and subagents among them. The following configuration types are loaded from `--add-dir` directories:

| Configuration                                                                              | Loaded from `--add-dir`                                                                                                                                            |
|:-------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Skills](../08-Plugins-Skills/skills.md) in `.claude/skills/`                                             | Yes, with live reload                                                                                                                                              |
| [Command files](../08-Plugins-Skills/skills.md#where-skills-live) in `.claude/commands/`                  | Yes, without live reload. When the added directory and your project both define a command with the same name, Claude Code runs your project’s command              |
| [Subagents](../09-Agents-Patterns/sub-agents.md) in `.claude/agents/`                                      | Yes, without live reload                                                                                                                                           |
| [Settings](settings.md) in `.claude/settings.json` and `.claude/settings.local.json` | `enabledPlugins` and [`extraKnownMarketplaces`](settings-reference.md#extraknownmarketplaces) keys only                                                      |
| [CLAUDE.md](memory.md) files, `.claude/rules/`, and `CLAUDE.local.md`                | Only when `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1` is set. `CLAUDE.local.md` additionally requires the `local` setting source, which is enabled by default |

To load the skills, commands, and subagents from a subdirectory of your [primary working directory](#working-directories) mid-session, run `/add-dir` with that subdirectory’s path. Claude Code loads them for the rest of the session without prompting you or adding a working directory, because the subdirectory is already readable. This requires Claude Code v2.1.257 or later. Claude Code discovers output styles from the current working directory and its parents, your user directory at `~/.claude/`, and managed settings. Hooks and other `.claude/settings.json` keys load from the current working directory’s `.claude/` folder with no parent-directory fallback, alongside your user `~/.claude/settings.json` and managed settings. `.claude/settings.local.json` loads from the git repository root instead, even when you start Claude Code in a subdirectory, except in the cases where Claude Code [doesn’t use the repository root](settings.md#where-claude-code-looks-for-each-file), such as on Windows; before v2.1.211, it too loaded only from the current working directory. [Agent SDK](../05-Agent-SDK/agent-sdk-claude-code-features.md#control-filesystem-settings-with-settingsources) sessions load it from the working directory in all versions. To share that configuration across projects, use one of these approaches:

- **User-level configuration**: place files in `~/.claude/agents/`, `~/.claude/output-styles/`, or `~/.claude/settings.json` to make them available in every project
- **Plugins**: package and distribute configuration as a [plugin](../08-Plugins-Skills/plugins.md) that teams can install
- **Launch from the config directory**: run Claude Code from the directory containing the `.claude/` configuration you want


[​](#how-permissions-interact-with-sandboxing)

How permissions interact with sandboxing

Permissions and [sandboxing](sandboxing.md) are complementary security layers:

- **Permissions** control which tools Claude Code can use and which files or domains it can access. They apply to Bash, Read, Edit, WebFetch, MCP, and every other tool, except that a deny or ask rule can’t block [`EndConversation`](tools-reference.md#endconversation-tool-behavior) while any other tool remains.
- **Sandboxing** provides OS-level enforcement that restricts shell commands’ filesystem and network access. It applies to Bash, PowerShell, and [Monitor](tools-reference.md#monitor-tool) tool commands and their child processes.

Use both for defense-in-depth, since sandbox restrictions still apply even if a prompt injection bypasses Claude’s decision-making. Paths and domains from both sandbox settings and permission rules are [merged into the final sandbox configuration](sandboxing.md#permission-rules). When you enable sandboxing and leave `autoAllowBashIfSandboxed` at its default of `true`, sandboxed Bash commands run without prompting even if your permissions include a bare `Bash` ask rule, or the [equivalent `Bash(*)` form](#match-all-uses-of-a-tool): the sandbox boundary substitutes for that whole-tool prompt. In [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode), Claude Code skips this substitution. Without an ask rule, the [built-in read-only commands](#read-only-commands) still run without prompting, and any other shell command goes through the regular permission flow while you are still planning; see [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode) for how Claude Code gates commands there. With a bare `Bash` ask rule, every Bash command prompts, including sandboxed read-only commands, the same as outside sandboxing. These checks still apply:

- Content-scoped ask rules like `Bash(git push *)` still force a prompt
- Other sandboxed commands can go through the regular permission flow too, as [Auto-allow mode](sandboxing.md#auto-allow-mode) describes

Commands that won’t run sandboxed, such as excluded commands, respect the bare `Bash` ask rule as usual. See [sandbox modes](sandboxing.md#sandbox-modes) to change this behavior.


[​](#managed-settings)

Managed settings

For organizations that need centralized control, administrators deploy managed settings that user and project settings can’t override, apart from a few [security-sensitive keys](settings.md#exceptions-to-managed-settings-precedence). [Deploy managed settings](../13-Enterprise-Admin/managed-settings.md) covers the delivery mechanisms, precedence within the managed tier, and the [keys that only managed settings can set](../13-Enterprise-Admin/managed-settings.md#managed-only-settings). One of those keys, [`allowManagedPermissionRulesOnly`](settings-reference.md#allowmanagedpermissionrulesonly), makes managed settings the only settings source of permission rules. Its entry lists every source Claude Code then ignores. `disableBypassPermissionsMode` is typically placed in managed settings to enforce organizational policy, but it works from any scope. A user can set it in their own settings to lock themselves out of bypass mode.


[​](#settings-precedence)

Settings precedence

Permission rules follow the same [settings precedence](settings.md#settings-precedence) as all other Claude Code settings, with managed settings highest: no other level, including command line arguments, can override a managed permission rule. If a tool is denied at any level, no other level can allow it. For example, a managed settings deny can’t be overridden by `--allowedTools`, and `--disallowedTools` can add restrictions beyond what managed settings define. The same holds across settings scopes: if user settings allow a permission and project settings deny it, the deny rule blocks it. The reverse is also true: a user-level deny blocks a project-level allow, because deny rules from any scope are evaluated before allow rules. This precedence is between settings files and command line arguments. For whether a deny rule holds over a [mod](../08-Plugins-Skills/plugins-mods-overview.md) you install, see [Extend permissions with hooks](#extend-permissions-with-hooks). Embedding hosts can supply additional managed policy via the SDK `managedSettings` option, including permission allow rules unless the admin sets the `allowManaged*Only` locks; [Deliver policy to Claude Desktop sessions](../13-Enterprise-Admin/claude-apps-gateway.md#deliver-policy-to-claude-desktop-sessions) covers when embedder policy applies at all.


[​](#project-allow-rules-and-workspace-trust)

Project allow rules and workspace trust

`permissions.allow` rules and `permissions.additionalDirectories` entries in a project’s `.claude/settings.json` grant capability, so Claude Code applies them only after you accept the [workspace trust dialog](../13-Enterprise-Admin/security.md#additional-safeguards) for that folder. The dialog lists the rules and directories the folder would grant so you can review them first. `deny` and `ask` rules aren’t affected, since they only restrict. Claude Code keys and stores the trust you accept according to where you start it:

- In a repository, Claude Code keys the trust on the git repository root, so the trust covers the whole repository apart from any git repository nested inside it, such as a submodule. In a [worktree](worktrees.md), it uses the main checkout’s root, as it does for [saved rules](#permission-system).
- 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.
- 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](../13-Enterprise-Admin/security.md#additional-safeguards) note.

Claude 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. Before it starts or restarts a [background session](../09-Agents-Patterns/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`](errors.md#workspace-not-trusted-when-dispatching-a-background-session) error instead.


[​](#when-your-local-settings-file-needs-trust)

When your local settings file needs trust

`.claude/settings.local.json` is normally your own file, so Claude Code applies its allow rules and additional directories without the trust step. When the file is tracked in git, or `.claude` is a symlink, Claude Code treats it as repository-supplied instead and holds its rules until you trust the folder. Claude Code runs git to tell the two apart, and it runs git only once you’ve trusted the folder: you accepted the trust dialog for it or for a parent directory whose trust extends to it, or you’re in a `-p` or SDK session, which counts as accepted. Until then, where you started Claude Code decides what happens to the file’s rules:

- **In your configuration home:** Claude Code applies that folder’s `.claude/settings.local.json` right away without running git. Your configuration home is your home directory, or a directory whose `.claude` subdirectory you’ve set as [`CLAUDE_CONFIG_DIR`](env-vars.md#variables). If that `CLAUDE_CONFIG_DIR` directory sits inside a git repository and Claude Code [keeps your local settings at the repository root](settings.md#where-claude-code-looks-for-each-file) instead, it holds the rules like anywhere else.
- **Anywhere else:** Claude Code holds the file’s rules like project settings. Once the check has run, Claude Code applies the rules of an untracked file, or of a file in a directory outside any git repository, even though you haven’t trusted that exact folder.

The configuration-home exception skips only the trust step. `~/.claude/settings.local.json` is still [local scope](settings.md#compare-the-scope-of-each-settings-file), so Claude Code reads it only in sessions you start in your home directory itself, not in every project. To apply permission rules across all your projects, add them to your user settings instead: `~/.claude/settings.json`, or `$CLAUDE_CONFIG_DIR/settings.json` when `CLAUDE_CONFIG_DIR` is set.


[​](#what-runs-before-you-trust-a-folder)

What runs before you trust a folder

Each row is one kind of content a repository can supply. The columns are the two situations in which you haven’t trusted the folder itself: you trusted only a parent folder, or you ran `claude -p` or the SDK there, which never shows the trust dialog. The parent-folder column doesn’t apply inside a [nested repository](#project-allow-rules-and-workspace-trust): in an interactive session Claude Code shows the trust dialog for it, and a `claude -p` or SDK run there follows the `claude -p` column.

| What the repository supplies                                                                                                                                                                                                                                                                                                             | You trusted only a parent folder                                                                                                                                               | `claude -p` or the SDK, folder never trusted                                                                                                                                                    |
|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Hooks](../07-Hooks/hooks.md) in settings files, the [`env`](settings-reference.md#env) block and helper commands such as [`apiKeyHelper`](settings-reference.md#apikeyhelper), and a project skill’s [hooks](../07-Hooks/hooks.md#hooks-in-skills-and-agents) and [`allowed-tools`](../08-Plugins-Skills/skills.md#pre-approve-tools-for-a-skill)      | Used                                                                                                                                                                           | Used. Workspace trust never gates a skill’s `allowed-tools` in any session                                                                                                                      |
| `permissions.allow` rules and `additionalDirectories` in `.claude/settings.json`                                                                                                                                                                                                                                                         | Not used until you accept the trust dialog, which appears again listing them                                                                                                   | Not used. Claude Code prints a [`this workspace has not been trusted`](errors.md#workspace-has-not-been-trusted) warning to stderr                                                        |
| Frontmatter hooks in a project [subagent](../09-Agents-Patterns/sub-agents.md#hooks-in-subagent-frontmatter), a project [`@skills-dir` plugin](../08-Plugins-Skills/plugins-loading.md#plugins-shared-through-a-repository), and [`extraKnownMarketplaces`](settings-reference.md#extraknownmarketplaces) entries from the repository or an `--add-dir` directory | Not used, and no dialog is offered                                                                                                                                             | Not used                                                                                                                                                                                        |
| Inline [`mcpServers`](../09-Agents-Patterns/sub-agents.md#scope-mcp-servers-to-a-subagent) in the frontmatter of a subagent from the repository or an `--add-dir` directory                                                                                                                                                                              | Not used, and no dialog is offered                                                                                                                                             | Not used                                                                                                                                                                                        |
| Servers in `.mcp.json`, including ones the repository [approves in its own settings](../06-MCP-Tools/General/mcp.md#project-server-approvals-and-workspace-trust)                                                                                                                                                                                          | Claude Code asks you before connecting them. The repository’s own approvals don’t count                                                                                        | Connected without asking, approved or not. The SDK loads them only when `settingSources` includes project settings. `claude mcp list` in the same folder still reports such a server as pending |
| A [`headersHelper`](../06-MCP-Tools/General/mcp.md#trust-a-folder-before-its-headershelper-runs) on a server in `.mcp.json`                                                                                                                                                                                                                                | Not run until you accept the trust dialog, which appears again naming where the helper is declared. Claude Code connects the server with its static `headers` alone until then | Not run. Claude Code connects the server with its static `headers` alone and prints a [`headersHelper not run`](errors.md#headershelper-not-run) line per server to stderr                |

For the rows that need this exact folder trusted, trust it by hand: set `projects["<path>"].hasTrustDialogAccepted` to `true` in `~/.claude.json`, where `<path>` is the repository root, or the folder itself outside a repository. Claude Code prints the exact key in the debug log line for a skipped subagent hook or inline MCP server, in the stderr warning for skipped allow rules, and in the `headersHelper not run` line for a skipped helper. Before you run `claude -p` in a repository you didn’t write, decide what it may run on your machine:

- Pass `--setting-sources user`, or set the SDK’s `settingSources` without project settings, so Claude Code reads neither the project’s settings files nor its `.mcp.json`
- Start with [`--bare`](headless.md#start-faster-with-bare-mode) so Claude Code reads no hooks, skills, custom commands, subagents, plugins, or `.mcp.json` servers from the project. The project’s `env` block and helpers such as `awsAuthRefresh` in its settings files still apply, and Claude Code reads `apiKeyHelper` only from `--settings`
- Pass `--settings '{"disableAllHooks": true}'` to [turn hooks off](../07-Hooks/hooks.md#disable-or-remove-hooks) for that run. Setting it in your user settings alone isn’t enough, because the repository’s project settings take precedence over yours and can set it back to `false`
- Add a [`disabledMcpjsonServers`](settings-reference.md#disabledmcpjsonservers) entry to reject a `.mcp.json` server by name in every session type


[​](#example-configurations)

Example configurations

This [repository](https://github.com/anthropics/claude-code/tree/main/examples/settings) includes starter settings configurations for common deployment scenarios. Use these as starting points and adjust them to fit your needs.


[​](#see-also)

See also

- [All settings](settings-reference.md#permission-settings): every settings key, including the permission keys
- [Configure auto mode](auto-mode-config.md): tell the auto mode classifier which infrastructure your organization trusts
- [Sandboxing](sandboxing.md): OS-level filesystem and network isolation for Bash commands
- [Authentication](authentication.md): set up user access to Claude Code
- [Security](../13-Enterprise-Admin/security.md): security safeguards and best practices
- [Hooks](../07-Hooks/hooks-guide.md): automate workflows and extend permission evaluation

---

## Platforms and integrations - Claude Code Docs

Source: https://code.claude.com/docs/en/platforms
Path: 02-Claude-Code-CLI/platforms.md

## On this page

- [Where to run Claude Code](#where-to-run-claude-code)
- [Connect your tools](#connect-your-tools)
- [Work when you are away from your terminal](#work-when-you-are-away-from-your-terminal)
- [Related resources](#related-resources)
  - [Platforms](#platforms)
  - [Integrations](#integrations)
  - [Remote access](#remote-access)

Platforms and integrations

# Platforms and integrations

Copy pageCopy page

Choose where to run Claude Code and what to connect it to. Compare the CLI, Desktop, VS Code, JetBrains, web, mobile, and integrations like Chrome, Slack, and CI/CD.

Copy pageCopy page

Claude Code runs the same underlying engine everywhere, but each surface is tuned for a different way of working. This page helps you pick the right platform for your workflow and connect the tools you already use.


[​](#where-to-run-claude-code)

Where to run Claude Code

Choose a platform based on how you like to work and where your project lives.

| Platform                               | Best for                                                                                           | What you get                                                                                                                                                                                        |
|:---------------------------------------|:---------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [CLI](../01-Getting-Started/quickstart.md)             | Terminal workflows, scripting, remote servers                                                      | Full feature set, [Agent SDK](headless.md), [computer use](computer-use.md) on macOS (Pro and Max), third-party providers                                                               |
| [Desktop](../16-Mobile-Desktop/desktop.md)            | Visual review, parallel sessions, managed setup                                                    | Diff viewer, app preview, [computer use](../16-Mobile-Desktop/desktop.md#let-claude-use-your-computer) and [Dispatch](../16-Mobile-Desktop/desktop.md#sessions-from-dispatch) on Pro and Max                                      |
| [VS Code](../03-IDE-Integrations/vs-code.md)            | Working inside VS Code without switching to a terminal                                             | Inline diffs, integrated terminal, file context                                                                                                                                                     |
| [JetBrains](../03-IDE-Integrations/jetbrains.md)        | Working inside IntelliJ, PyCharm, WebStorm, or other JetBrains IDEs                                | Diff viewer, selection sharing, terminal session                                                                                                                                                    |
| [Web](claude-code-on-the-web.md) | Long-running tasks that don’t need much steering, or work that should continue when you’re offline | Cloud, Anthropic-managed by default; continues after you disconnect                                                                                                                                 |
| [Mobile](../16-Mobile-Desktop/mobile.md)              | Starting and monitoring tasks while away from your computer                                        | Cloud sessions from the Claude app for iOS and Android, [Remote Control](remote-control.md) for local sessions, [Dispatch](../16-Mobile-Desktop/desktop.md#sessions-from-dispatch) to Desktop on Pro and Max |

The CLI is the most complete surface for terminal-native work: scripting and the Agent SDK are CLI-only. Third-party providers also work in [VS Code](../03-IDE-Integrations/vs-code.md#use-third-party-providers) and in [JetBrains](feature-availability.md#features-available-on-every-provider), which runs the CLI in your IDE’s terminal. Enterprise [Desktop](../16-Mobile-Desktop/desktop.md) deployments support Google Cloud’s Agent Platform, and Desktop supports [gateway providers](../13-Enterprise-Admin/llm-gateway-connect.md#desktop-app); for Amazon Bedrock or Microsoft Foundry, use the CLI or an IDE extension, or [Claude Desktop on 3P](https://claude.com/docs/third-party/claude-desktop/overview), which runs the Code tab on those providers. Desktop and the IDE extensions trade some CLI-only features for visual review and tighter editor integration. The web runs in the cloud, so tasks keep going after you disconnect. Mobile is a thin client into those same cloud sessions or into a local session via Remote Control, and can send tasks to Desktop with Dispatch. You can mix surfaces on the same project. Configuration, project memory, and MCP servers are shared across the local surfaces.


[​](#connect-your-tools)

Connect your tools

Integrations let Claude work with services outside your codebase.

| Integration                                      | What it does                                                                       | Use it for                                                                          |
|:-------------------------------------------------|:-----------------------------------------------------------------------------------|:------------------------------------------------------------------------------------|
| [Chrome](../03-IDE-Integrations/chrome.md)                        | Controls your browser with your logged-in sessions                                 | Testing web apps, filling forms, automating sites without an API                    |
| [GitHub Actions](github-actions.md)        | Runs Claude in your CI pipeline                                                    | Automated PR reviews, issue triage, scheduled maintenance                           |
| [GitLab CI/CD](gitlab-ci-cd.md)            | Same as GitHub Actions for GitLab                                                  | CI-driven automation on GitLab                                                      |
| [Code Review](code-review.md)              | Reviews every PR automatically                                                     | Catching bugs before human review                                                   |
| [Slack](../14-Connectors/slack.md)                          | Responds to `@Claude` mentions in your channels, under your own account            | Turning bug reports into pull requests from team chat on Pro and Max plans          |
| [Claude Tag](https://claude.com/docs/claude-tag) | Runs `@Claude` as your organization’s shared identity with admin-configured access | Shared team access on Team and Enterprise plans, instead of per-user Slack sessions |

For integrations not listed here, [MCP servers](../06-MCP-Tools/General/mcp.md) and [connectors](../16-Mobile-Desktop/desktop.md#connect-external-tools) let you connect almost anything: Linear, Notion, Google Drive, or your own internal APIs.


[​](#work-when-you-are-away-from-your-terminal)

Work when you are away from your terminal

Claude Code offers several ways to work when you’re not at your terminal. They differ in what triggers the work, where Claude runs, and how much you need to set up.

|                                                               | Trigger                                                                                           | Claude runs on                                                                                              | Setup                                                                                                                                                                | Best for                                                      |
|:--------------------------------------------------------------|:--------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------|
| [Dispatch](../16-Mobile-Desktop/desktop.md#sessions-from-dispatch)           | Message a task from the Claude mobile app                                                         | Your machine (Desktop)                                                                                      | [Pair the mobile app with Desktop](https://support.claude.com/en/articles/13947068)                                                                                  | Delegating work while you’re away, minimal setup              |
| [Remote Control](remote-control.md)                     | Drive a running session from [claude.ai/code](https://claude.ai/code) or the Claude mobile app    | Your machine (CLI, Desktop, or VS Code)                                                                     | Run [`claude remote-control` or `/remote-control`](remote-control.md#start-a-remote-control-session)                                                           | Steering in-progress work from another device                 |
| [Channels](channels.md)                                 | Push events from a chat app like Telegram or Discord, or your own server                          | Your machine (CLI)                                                                                          | [Install a channel plugin](channels.md#quickstart) or [build your own](channels-reference.md)                                                            | Reacting to external events like CI failures or chat messages |
| [Slack](../14-Connectors/slack.md)                                       | Mention `@Claude` in a team channel                                                               | Anthropic cloud                                                                                             | [Install the Slack app](../14-Connectors/slack.md#setting-up-claude-code-in-slack) with [Claude Code on the web](claude-code-on-the-web.md) enabled, on Pro and Max plans | PRs and reviews from team chat                                |
| [Self-hosted environments](../13-Enterprise-Admin/self-hosted-environments.md) | Start a [cloud session](claude-code-on-the-web.md) and pick your organization’s environment | Your organization’s infrastructure                                                                          | [Deploy runners](../13-Enterprise-Admin/self-hosted-environments-quickstart.md), on Team and Enterprise plans                                                                         | Cloud sessions that must run inside your network              |
| [Scheduled tasks](scheduled-tasks.md)                   | Set a schedule                                                                                    | [CLI](scheduled-tasks.md), [Desktop](../16-Mobile-Desktop/desktop-scheduled-tasks.md), or [cloud](web-scheduled-tasks.md) | Pick a frequency                                                                                                                                                     | Recurring automation like daily reviews                       |

If you’re not sure where to start, [install the CLI](../01-Getting-Started/quickstart.md) and run it in a project directory. If you’d rather not use a terminal, [Desktop](../16-Mobile-Desktop/desktop-quickstart.md) gives you the same engine with a graphical interface.


[​](#related-resources)

Related resources


[​](#platforms)

Platforms

- [CLI quickstart](../01-Getting-Started/quickstart.md): install and run your first command in the terminal
- [Desktop](../16-Mobile-Desktop/desktop.md): visual diff review, parallel sessions, computer use, and Dispatch
- [VS Code](../03-IDE-Integrations/vs-code.md): the Claude Code extension inside your editor
- [JetBrains](../03-IDE-Integrations/jetbrains.md): the extension for IntelliJ, PyCharm, and other JetBrains IDEs
- [Web](claude-code-on-the-web.md): cloud sessions from your browser at claude.ai/code that keep running when you disconnect
- [Projects](claude-projects.md): one conversation where Claude coordinates many cloud sessions for a body of work and reports back
- [Mobile](../16-Mobile-Desktop/mobile.md): the Claude app for [iOS](https://apps.apple.com/us/app/claude-by-anthropic/id6473753684) and [Android](https://play.google.com/store/apps/details?id=com.anthropic.claude) for starting and monitoring tasks while away from your computer


[​](#integrations)

Integrations

- [Chrome](../03-IDE-Integrations/chrome.md): automate browser tasks with your logged-in sessions
- [Computer use](computer-use.md): let Claude open apps and control your screen on macOS
- [GitHub Actions](github-actions.md): run Claude in your CI pipeline
- [GitLab CI/CD](gitlab-ci-cd.md): the same for GitLab
- [Code Review](code-review.md): automatic review on every pull request
- [Slack](../14-Connectors/slack.md): send tasks from team chat and get PRs back, on Pro and Max plans
- [Claude Tag](https://claude.com/docs/claude-tag): run `@Claude` as your organization’s shared identity on Team and Enterprise plans


[​](#remote-access)

Remote access

- [Dispatch](../16-Mobile-Desktop/desktop.md#sessions-from-dispatch): message a task from your phone and it can spawn a Desktop session
- [Remote Control](remote-control.md): drive a running session from your phone or browser
- [Channels](channels.md): push events from chat apps or your own servers into a session
- [Scheduling options](scheduled-tasks.md#compare-scheduling-options): run prompts on a recurring schedule

---

## How Claude Code uses prompt caching - Claude Code Docs

Source: https://code.claude.com/docs/en/prompt-caching
Path: 02-Claude-Code-CLI/prompt-caching.md

## On this page

- [How the cache is organized](#how-the-cache-is-organized)
  - [Where the cache lives](#where-the-cache-lives)
- [Actions that invalidate the cache](#actions-that-invalidate-the-cache)
  - [Switching models](#switching-models)
  - [Changing effort level](#changing-effort-level)
  - [Turning on fast mode](#turning-on-fast-mode)
  - [Connecting or removing an MCP server](#connecting-or-removing-an-mcp-server)
  - [Enabling or disabling a plugin](#enabling-or-disabling-a-plugin)
  - [Plugin components that keep the cache](#plugin-components-that-keep-the-cache)
  - [Plugins that provide MCP servers](#plugins-that-provide-mcp-servers)
  - [Code intelligence plugins](#code-intelligence-plugins)
  - [When plugin changes apply](#when-plugin-changes-apply)
  - [Plugins you enable and then disable in one session](#plugins-you-enable-and-then-disable-in-one-session)
  - [Denying an entire tool](#denying-an-entire-tool)
  - [Compacting the conversation](#compacting-the-conversation)
  - [Accumulating many images](#accumulating-many-images)
  - [Upgrading Claude Code](#upgrading-claude-code)
- [Actions that keep the cache](#actions-that-keep-the-cache)
  - [Editing files in your repository](#editing-files-in-your-repository)
  - [Editing CLAUDE.md mid-session](#editing-claude-md-mid-session)
  - [Changing permission mode](#changing-permission-mode)
  - [Changing output style](#changing-output-style)
  - [Invoking skills and commands](#invoking-skills-and-commands)
  - [Running /recap](#running-%2Frecap)
  - [Rewinding the conversation](#rewinding-the-conversation)
- [Resuming a session](#resuming-a-session)
- [Cache lifetime](#cache-lifetime)
  - [Which TTL each request gets](#which-ttl-each-request-gets)
  - [Choose the TTL yourself](#choose-the-ttl-yourself)
- [Cache scope](#cache-scope)
- [Check cache performance](#check-cache-performance)
- [Subagents and the cache](#subagents-and-the-cache)
- [Disable prompt caching](#disable-prompt-caching)
- [Related resources](#related-resources)

Core concepts

# How Claude Code uses prompt caching

Copy pageCopy page

Claude Code manages prompt caching automatically. See why a model switch triggers a slow uncached turn, what `/compact` costs, why CLAUDE.md edits don’t apply mid-session, and how to check your cache hit rate.

Copy pageCopy page

Prompt caching makes Claude Code faster and more cost-efficient. Without caching, the API would reprocess your full history on every turn. With caching, it reuses what it already processed, bills the re-read at the [cached token rate](../17-Billing-Plans/about-claude-pricing.md), and fully processes only what changed. Claude Code handles prompt caching for you, unless you [disable it](#disable-prompt-caching). It is still useful to know how prompt caching works, because some actions invalidate the cache and make the next response slower and more expensive while it rebuilds. This page covers which actions those are, why some settings wait for a restart to apply, and how to check cache performance when usage looks high.


[​](#how-the-cache-is-organized)

How the cache is organized

Each time you send a message in Claude Code, it makes a new API request. The model doesn’t remember anything between requests, so Claude Code re-sends the full context: the system prompt, your project context, every prior message and tool result, and your new message. New content is appended at the end, which means most of each request is identical to the one before it. Prompt caching is how the API avoids reprocessing the part that didn’t change. The API caches by matching the start of each request, called the prefix, against content it recently processed. On a normal turn, the prefix is the entire previous request and only the latest exchange is new. The match is exact, so a change anywhere in the prefix recomputes everything after it. There is no per-file or per-segment caching. See [how prompt caching works](../04-API-Reference/Guides/build-with-claude-prompt-caching.md#how-prompt-caching-works) in the API reference for the underlying mechanism.

To get the most out of prefix matching, Claude Code orders each request so content that rarely changes between turns comes first:

| Layer           | Content                                         | Changes when                                    |
|-----------------|-------------------------------------------------|-------------------------------------------------|
| System prompt   | Core instructions, tool definitions             | The set of loaded tool definitions changes      |
| Project context | CLAUDE.md, auto memory, unscoped rules          | Session starts, or after `/clear` or `/compact` |
| Conversation    | Your messages, Claude’s responses, tool results | Every turn                                      |

A change to the conversation layer leaves the system prompt and project context cached. A change to the system prompt invalidates everything, because all later content now sits behind a different prefix. The third column gives common triggers rather than an exhaustive list, and the sections below cover the full set. The prefix-match rule explains most of the behaviors on this page. [Plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode) and [skill loading](../08-Plugins-Skills/skills.md), for example, append their instructions as conversation messages, so the cached prefix stays intact. Two settings don’t appear in the layer table but still affect what stays cached:

- **Model**: each model has its own cache. Switching models recomputes the entire request even when the content is identical. See [Switching models](#switching-models) below.
- **Effort level**: on most models, each effort level has its own cache, so changing effort mid-session recomputes the entire request. On Opus 5.5, Sonnet 5.5, Haiku 5.5, and Fable 5.1 with an API key or a Claude subscription, the cache stays intact by default. See [Changing effort level](#changing-effort-level) below.

Pick your model and effort level at the top of a session, then save `/compact` for natural breaks between tasks. The fewer changes you make mid-task, the higher your cache hit rate.


[​](#where-the-cache-lives)

Where the cache lives

Caching happens server-side, in whichever infrastructure serves your model. Where that is depends on how you authenticate:

- **API key, Claude subscription, or [Claude Platform on AWS](claude-platform-on-aws.md)**: the cache lives in Anthropic’s infrastructure, accessed through the [Claude API](../04-API-Reference/Other/home.md)
- **Amazon Bedrock or Google Cloud’s Agent Platform**: the cache lives in your cloud provider’s serving infrastructure
- **Microsoft Foundry**: depends on the deployment’s [hosting option](../04-API-Reference/Guides/build-with-claude-claude-in-microsoft-foundry.md#hosting-options). Hosted on Azure deployments are served on Azure infrastructure; Hosted on Anthropic deployments are served on Anthropic’s infrastructure
- **Custom `ANTHROPIC_BASE_URL` or [LLM gateway](../13-Enterprise-Admin/llm-gateway.md)**: the cache lives wherever your requests are forwarded, and whether caching works depends on the gateway

Claude Code also appends system context mid-conversation, such as file-change notices, and marks that block for caching on every provider and connection unless you set [`CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS`](../13-Enterprise-Admin/llm-gateway-protocol.md#disable-pre-release-capabilities), in which case that block is sent uncached. At the provider’s own endpoint, Amazon Bedrock and its [Mantle endpoint](amazon-bedrock.md#use-the-mantle-endpoint), Google Cloud’s Agent Platform, and Microsoft Foundry cache the block the same way the Claude API does. When your requests pass through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md), a custom `ANTHROPIC_BASE_URL`, or a cloud provider base-URL override such as [`ANTHROPIC_BEDROCK_BASE_URL`](env-vars.md), what stays cached depends on how the gateway handles the [`cache_control` markers](../04-API-Reference/Guides/build-with-claude-prompt-caching.md#explicit-cache-breakpoints) Claude Code sends:

- **Forwards them unchanged**: the block and your conversation cache the same as at the provider’s own endpoint.
- **Rejects the marked request with a `400` error naming `cache_control`**: Claude Code re-sends the request with the marker moved off the block and onto your last conversation message, and keeps it there until Claude Code exits. The block bills as uncached input; your conversation stays cached.
- **Removes the markers while returning success**: your entire conversation history bills as uncached input on every turn. A gateway that converts block-form system content to a plain string drops the marker the same way.

For what each provider stores and processes, see [data usage](../13-Enterprise-Admin/data-usage.md). Wherever the cache lives, entries expire after a period of inactivity, and [Cache lifetime](#cache-lifetime) below covers the TTL and how to extend it.


[​](#actions-that-invalidate-the-cache)

Actions that invalidate the cache

These actions can cause the next request to miss part or all of the cache. You see a one-time slower, more expensive turn, after which the new prefix is cached. Most of them are avoidable mid-task once you know they have a cost. A model switch can feel free until you notice the slower turn that follows.

- [Switching models](#switching-models)
- [Changing effort level](#changing-effort-level)
- [Turning on fast mode](#turning-on-fast-mode)
- [Connecting or removing an MCP server](#connecting-or-removing-an-mcp-server)
- [Enabling or disabling a plugin](#enabling-or-disabling-a-plugin)
- [Denying an entire tool](#denying-an-entire-tool)
- [Compacting the conversation](#compacting-the-conversation)
- [Accumulating many images](#accumulating-many-images)
- [Upgrading Claude Code](#upgrading-claude-code)


[​](#switching-models)

Switching models

Each model has its own cache. Switching with [`/model`](model-config.md#setting-your-model) means the next request reads the entire conversation history with no cache hits, even though the content is identical. When you run `/model` at the terminal, Claude Code asks you to confirm the switch only while the cache is still warm and the new model isn’t the one that produced the last response. The cache stays warm for one [cache TTL](#cache-lifetime) after Claude Code last sent a request in this conversation or Claude last responded. Once that time passes, the cache has expired, so Claude Code switches without asking. Before v2.1.238, Claude Code didn’t check the cache TTL and asked even after the cache had expired. You can also require this confirmation or skip it with a [PreModelSwitch hook](../07-Hooks/hooks.md#premodelswitch-decision-control). The [`opusplan` model setting](model-config.md#opusplan-model-setting) resolves to Opus during plan mode and Sonnet during execution, so each plan-mode toggle is a model switch and starts a fresh cache. [Automatic model fallback](model-config.md#automatic-model-fallback) on Fable models, Opus 5.5, Sonnet 5.5, and Opus 5 is also a model switch. When a safety classifier flags a request in a category that has a fallback model and Claude Code re-runs the request on that model, the session continues there. When a skill or command’s frontmatter names a [`model`](../08-Plugins-Skills/skills.md#frontmatter-reference) other than the session’s current model, that turn is also a model switch: the next request reads the entire conversation history with no cache hits. The session model resumes on your next prompt. A `context: fork` skill sets the [forked subagent’s model](../08-Plugins-Skills/skills.md#run-skills-in-a-subagent) instead.


[​](#changing-effort-level)

Changing effort level

On most models, changing the [effort level](model-config.md#adjust-effort-level) mid-session means the next request reads the entire conversation history with no cache hits. While the cache is still warm, Claude Code asks you to confirm the change first. On Opus 5.5, Sonnet 5.5, Haiku 5.5, and Fable 5.1 with an API key or a Claude subscription, changing effort keeps the cache, and Claude Code applies the new level without asking. This doesn’t apply on Amazon Bedrock, Google Cloud’s Agent Platform, or a [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md), or when you set [`CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS`](../13-Enterprise-Admin/llm-gateway-protocol.md#disable-pre-release-capabilities) or your organization has a HIPAA configuration. Before v2.1.260, changing effort on Fable 5.1 with an API key or a Claude subscription also invalidated the cache.


[​](#turning-on-fast-mode)

Turning on fast mode

Enabling [fast mode](fast-mode.md) adds a request header that is part of the cache key, so the first request Claude Code sends with fast mode on reads the entire conversation history with no cache hits. Claude Code sets that header once when a turn starts and keeps it for the whole turn, so when you turn fast mode on while Claude is working, the cache miss from the header happens on the first request of your next turn. Those uncached input tokens are billed at [fast mode rates](fast-mode.md#understand-the-cost-tradeoff), which is why turning it on at the start of a session costs less than turning it on deep into a long one. If your current model doesn’t support fast mode, enabling fast mode also [switches your model](#switching-models), and that switch starts a fresh cache on its own from the next request in the running turn. The cost applies once per conversation. After the first fast mode turn, Claude Code keeps sending the header and varies only the request’s speed setting, which is not part of the cache key. Turning fast mode off, the [automatic fallback to standard speed](fast-mode.md#handle-rate-limits) after a rate limit, and turning it back on later all keep the cache. If you [run out of usage credits](fast-mode.md#handle-rate-limits) mid-session, Claude Code retries each rejected fast mode request at standard speed the same way, so this fallback also keeps the cache. `/clear` and `/compact` reset this, since they rebuild the cache at those points anyway.


[​](#connecting-or-removing-an-mcp-server)

Connecting or removing an MCP server

Tool definitions sit in the system prompt layer, so the cache invalidates when the set of tool definitions in the request changes between turns. Toggling the [advisor tool](advisor.md) is an exception: its definition sits after the cache breakpoint, so enabling or disabling `/advisor` keeps the cached prefix intact. Whether an [MCP server](../06-MCP-Tools/General/mcp.md) change does this depends on whether [tool search](../06-MCP-Tools/General/mcp.md#scale-with-mcp-tool-search) defers the session’s MCP tools, the default on supported models:

- **Tools deferred**: Claude Code keeps the tool list from the conversation’s first request for the whole conversation, so a server connecting or disconnecting mid-session doesn’t disturb anything already cached. A server that finishes connecting after the first request supplies its tools as deferred definitions that Claude loads on demand.
- **Tools loaded upfront**: adding a definition invalidates the cache, and so does removing one on purpose. This applies when tool search is [off or unavailable](../06-MCP-Tools/General/mcp.md#configure-tool-search), such as on:
  - Google Cloud’s Agent Platform models earlier than Opus 4.5, Sonnet 4.5, and Haiku 4.5
  - A Microsoft Foundry [deployment hosted on Azure](../04-API-Reference/Guides/build-with-claude-claude-in-microsoft-foundry.md#hosting-options) once Claude Code detects that the deployment rejects tool search

Without tool search, whether a mid-session server change invalidates the cache depends on what changed. For each change, this table gives whether the cache is kept and what happens to the tool definitions in the next request.

| Mid-session change                                                                                                     | Cache                                                                                                                       | Tool definitions in the next request                                                                                                                                                                                        |
|------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| A server connects, or a [dynamic tool update](../06-MCP-Tools/General/mcp.md#dynamic-tool-updates) adds tools                            | Invalidated                                                                                                                 | The new definitions are added                                                                                                                                                                                               |
| A server drops out with no action on your part, such as a stdio server’s process exiting                               | Kept                                                                                                                        | The server’s definitions stay unchanged. A call to one of its tools returns an error instead of running, unless Claude Code [starts the server again](../06-MCP-Tools/General/mcp.md#stdio-servers-that-exit-or-fail-to-start) for that call  |
| A remote server [reconnects automatically](../06-MCP-Tools/General/mcp.md#automatic-reconnection) after its connection drops             | Kept, unless a request sent while the server reconnects adds the `WaitForMcpServers` tool, which invalidates the cache once | The server’s definitions stay unchanged. A request sent while the server reconnects can add `WaitForMcpServers` when the conversation hasn’t listed it yet, and the tool then stays listed for the rest of the conversation |
| You remove a tool on purpose, such as with a [deny rule](#denying-an-entire-tool) or by disabling its server in `/mcp` | Invalidated                                                                                                                 | The definition is removed                                                                                                                                                                                                   |

When you resume a conversation whose tools load into the prefix, one of its MCP servers can still be connecting as the first request goes out. If the transcript recorded that server’s tool definitions, that request includes them as recorded, so it doesn’t change when the server finishes connecting with the same tools. Editing your MCP config does not by itself change the cache. The new config takes effect only after a restart, which is when the server connects or disconnects.


[​](#enabling-or-disabling-a-plugin)

Enabling or disabling a plugin

When you enable or disable a [plugin](../08-Plugins-Skills/plugins.md), what the change costs depends on which component types the plugin provides. The cases below cover each component type, when Claude Code applies the change, and what happens when you disable a plugin again in the same session.


[​](#plugin-components-that-keep-the-cache)

Plugin components that keep the cache

Claude Code never invalidates the cache for a plugin’s skills, commands, agents, hooks, monitors, or themes. It appends their content after the existing conversation, so the next request pays for that content and still reads everything before it from the cache.


[​](#plugins-that-provide-mcp-servers)

Plugins that provide MCP servers

When you enable or disable a plugin that provides [MCP servers](../08-Plugins-Skills/plugins-components.md#mcp-servers), Claude Code follows the same rules as when you [connect or remove an MCP server](#connecting-or-removing-an-mcp-server).


[​](#code-intelligence-plugins)

Code intelligence plugins

When you enable a [code intelligence plugin](../08-Plugins-Skills/plugins-code-intelligence.md), Claude gets the [LSP tool](tools-reference.md#lsp-tool-behavior).


[​](#when-plugin-changes-apply)

When plugin changes apply

A change you make in the `/plugin` menu goes through [`/reload-plugins`](../08-Plugins-Skills/plugins-cli-reference.md#reload-plugins), which Claude Code runs for you when you close the menu. You pay the cost, whether appended announcements or a full re-read, on the first turn after the change applies. Claude Code can also apply a change on its own:

- For a plugin with a `command` source, Claude Code [can reload the plugin itself](../08-Plugins-Skills/plugins-loading.md#when-a-command-source-re-runs).
- When you [install a plugin from the `/plugin` interface](../08-Plugins-Skills/discover-plugins.md#install-a-plugin), Claude Code can activate it during the install. The install summary tells you whether it did.
- When you [move the session with `/cd`](permissions.md#move-the-session-to-another-directory) on v2.1.246 or later, Claude Code applies the plugins the new directory’s settings enable as part of the move, without the full re-read warning that holds a `/reload-plugins`.
- In interactive sessions, when you add or remove a plugin in a [folder of plugins](../08-Plugins-Skills/plugins-create.md#load-a-directory-or-archive-for-one-session) you passed with `--plugin-dir`, the change applies right away. If applying it would trigger a full re-read, Claude Code holds the change instead and shows a notice to run `/reload-plugins`. Requires Claude Code v2.1.265 or later.

When `/reload-plugins` runs and the reload would trigger a full re-read, Claude Code shows a warning and doesn’t apply the reload. Run `/reload-plugins --force` to apply it anyway. `/reload-plugins` also runs in sessions without an interactive terminal, such as the desktop app, the Agent SDK, and [non-interactive mode](headless.md) with `-p`, when you type it into the session directly. Requires Claude Code v2.1.260 or later. In those sessions the reload applies everything except plugin MCP server changes, which [take effect in your next session](../08-Plugins-Skills/plugins-cli-reference.md#reload-plugins) and so never cost a full re-read mid-session.


[​](#plugins-you-enable-and-then-disable-in-one-session)

Plugins you enable and then disable in one session

When you disable a plugin you enabled earlier in the session, Claude Code restores the previous request shape. If that prefix is still within its [cache lifetime](#cache-lifetime), the next request reads the older cache entry instead of rebuilding.


[​](#denying-an-entire-tool)

Denying an entire tool

If you add a bare tool name like `Bash` or `WebFetch` as a [deny rule](permissions.md#manage-permissions), Claude can’t call that tool from your next request on, whether you add the rule through `/permissions` or by [editing a settings file directly](settings.md#when-edits-take-effect). That includes a rule you add through `/permissions` in the middle of a turn. When [tool search](../06-MCP-Tools/General/mcp.md#scale-with-mcp-tool-search) is active, which is the default on supported models, the request’s tool definitions don’t change and the cached prefix survives. When tool search is unavailable or disabled, Claude Code removes the definition from the next request, which invalidates the cache, and so does removing the rule later. Only a deny rule that matches in the tool-name position blocks a tool this way: a bare tool name, the equivalent `Bash(*)` form, or a [tool-name glob](permissions.md#tool-name-wildcards) like `"*"`. A glob that matches only MCP tools, such as `"mcp__*"`, blocks those tools the same way. Scoped deny rules like `Bash(rm *)`, and all allow and ask rules, don’t change which tools Claude sees. Claude Code checks them when Claude attempts a call, leaving the prefix intact.


[​](#compacting-the-conversation)

Compacting the conversation

[Compaction](context-window.md#what-survives-compaction) replaces your message history with a summary. By design, this invalidates the conversation layer: the next request has a new, shorter history that doesn’t share a prefix with the old one. The system prompt and project context layers can stay cached:

- **System prompt**: the next request reads this layer from the cache, unless a [resumed conversation](#resuming-a-session) kept a system prompt that is now out of date. The first time that conversation is compacted, Claude Code switches it to the current prompt, and the next request rebuilds this layer’s cache once.
- **Project context**: Claude Code reloads this layer from disk. The next request reads it from the cache only if CLAUDE.md and memory are unchanged since the session started.

To produce the summary, Claude Code sends a separate request. The request repeats your conversation’s system prompt, tools, and the history being summarized. It ends with a summarization instruction. While the cache is warm, that request reads your prefix from the cache. A mid-session `/compact` then costs a fraction of what the context size suggests and spends most of its time generating the summary. After a break longer than the [cache lifetime](#cache-lifetime), there is no cache left to read, so the summarization request reprocesses that history as uncached input. This is why `/compact` costs the most when you [resume an old session](sessions.md#resume-a-session). In both the warm and cold cases, the turn after compaction rebuilds the conversation cache for only the much shorter summary, so that turn isn’t the slow part.

Compaction works in your favor when the context you discard is content you no longer need. To choose when its overhead happens, run `/compact` at a natural break in your work, such as between tasks, instead of waiting for auto-compaction to trigger mid-task. If you’ve gone down a path you want to abandon entirely, [`/rewind`](#rewinding-the-conversation) to an earlier turn instead. Rewinding truncates back to a prefix that is already cached, rather than building a new one as compaction does.

If you leave a long conversation idle in a terminal session while it is on the [one-hour TTL](#which-ttl-each-request-gets), Claude Code can compact it shortly before the cache expires. To turn idle compaction off, set [`idleCompaction`](settings-reference.md#idlecompaction) to `false`, which requires Claude Code v2.1.290 or later.


[​](#accumulating-many-images)

Accumulating many images

The API limits how many images and PDFs each request can carry. For the current numbers, see [Request limits](../04-API-Reference/Guides/build-with-claude-vision.md#request-limits) in the API docs. Claude Code also caps the total size of the images and PDFs in a request, so large screenshots reach the limit with fewer images than small ones. When the next request would pass either limit, Claude Code removes a batch of the oldest images and PDFs from what it sends, which leaves room for more before it needs to remove any again. Claude can no longer see the removed images. If Claude needs one of them again, share it again. Removing images changes the messages that held them, so the next request reprocesses the conversation from the earliest of those messages onward. Because Claude Code removes a batch at a time, you see one slower turn per batch rather than one with each new screenshot.


[​](#upgrading-claude-code)

Upgrading Claude Code

A new Claude Code version typically updates the system prompt or tool definitions, so the first conversation you start after an upgrade builds its cache from the top. [Auto-update](../01-Getting-Started/setup.md#auto-updates) downloads new versions in the background but applies them on the next launch, never mid-session, so you see this as an uncached first turn after restarting rather than a surprise during a session. Set `DISABLE_AUTOUPDATER=1` to control when upgrades apply.

For what it costs to resume a conversation you started before the upgrade, see [Resuming a session](#resuming-a-session).


[​](#actions-that-keep-the-cache)

Actions that keep the cache

These actions either append to the end of the conversation or don’t touch the request at all. Some of them, such as editing CLAUDE.md, keep the cache for the same reason the change doesn’t reach the running session until `/clear`, `/compact`, or a restart.

- [Editing files in your repository](#editing-files-in-your-repository)
- [Editing CLAUDE.md mid-session](#editing-claude-md-mid-session)
- [Changing permission mode](#changing-permission-mode)
- [Changing output style](#changing-output-style)
- [Invoking skills and commands](#invoking-skills-and-commands)
- [Running `/recap`](#running-%2Frecap)
- [Rewinding the conversation](#rewinding-the-conversation)
- [Spawning a subagent](#subagents-and-the-cache)


[​](#editing-files-in-your-repository)

Editing files in your repository

File contents enter context only when Claude reads them, and reads append to the conversation. Editing a file Claude previously read does not retroactively change the earlier read in history. Instead, Claude Code appends a [`<system-reminder>`](glossary.md#system-reminder) noting the file changed, and Claude re-reads it if needed.


[​](#editing-claude-md-mid-session)

Editing CLAUDE.md mid-session

Your project-root and user-level CLAUDE.md files are read once at session start and held in memory. Editing them mid-session does not invalidate the cache, but the edit also doesn’t apply. Claude keeps working with the version that was loaded at session start. The new content loads on the next `/clear`, `/compact`, or restart. [Nested CLAUDE.md files in subdirectories](memory.md) and [rules with `paths:` frontmatter](memory.md#path-specific-rules) load later, on demand. Editing one yourself before it loads does take effect. After it loads, the content is part of the conversation history, so a mid-session edit doesn’t retroactively change it.


[​](#changing-permission-mode)

Changing permission mode

Switching between [permission modes](permission-modes.md), such as from Manual to accept edits, does not change the system prompt or tool definitions, so mode changes are cache-safe. The exception is plan mode with the [`opusplan`](model-config.md#opusplan-model-setting) model setting, which switches the model between Opus and Sonnet as you enter or leave plan mode. That makes the mode toggle a [model switch](#switching-models).


[​](#changing-output-style)

Changing output style

When you switch [output styles](output-styles.md) mid-session with [`/output-style`](output-styles.md#change-your-output-style), `/config`, or the `outputStyle` setting, Claude uses the new style starting with your next message. Claude Code delivers the new style’s instructions as a message in the conversation, so that request still reads the system prompt and the earlier conversation from the cache. Before v2.1.251, a mid-session style switch kept the cache but didn’t apply until you ran `/clear` or started a new session.


[​](#invoking-skills-and-commands)

Invoking skills and commands

[Skills](../08-Plugins-Skills/skills.md) and [commands](commands.md) inject their instructions as user messages at the point of invocation. Nothing earlier in the conversation changes. A skill or command whose frontmatter names a `model` can be a [model switch](#switching-models) for that turn.


[​](#running-/recap)

Running `/recap`

[`/recap`](interactive-mode.md#session-recap) generates a summary for display in your terminal. Unlike `/compact`, it appends the summary as command output rather than replacing your message history, so the cached prefix stays intact.


[​](#rewinding-the-conversation)

Rewinding the conversation

[`/rewind`](checkpointing.md) truncates your conversation back to an earlier turn. The remaining history is the same content the cache was built from at that point, and the system prompt and project context layers are unchanged, so the next request hits the earlier cache entry. Every turn since then has read through that prefix, which kept the entry warm even if the original turn was longer ago than the TTL. Restoring file checkpoints alongside the conversation has no separate effect on the cache. File contents enter context only when Claude reads them, the same as [editing files in your repository](#editing-files-in-your-repository).


[​](#resuming-a-session)

Resuming a session

When you [resume a session](sessions.md#resume-a-session), Claude Code sends the whole conversation again, and the request reads from the cache whatever part of its prefix is unchanged and still within the [cache lifetime](#cache-lifetime). The layer table at the top of this page says what changes each layer. The system prompt would change after a [Claude Code upgrade](#upgrading-claude-code) or with different [`--append-system-prompt`](cli-reference.md#system-prompt-flags) text on the resume. By default, the resumed conversation keeps the system prompt it started with, so its history still sits behind the same prompt, and the change takes effect once the conversation is compacted or in a new conversation. [System prompt flags in resumed conversations](cli-reference.md#system-prompt-flags-in-resumed-conversations) covers the cases where Claude Code rebuilds the prompt on every request instead.


[​](#cache-lifetime)

Cache lifetime

Cached prefixes expire after a period of inactivity. Each request that hits the cache resets the timer, so the cache stays warm as long as you keep working. After a long enough gap, the next request recomputes the full input and re-establishes the cache, which is why the first turn back after stepping away can be noticeably slower. The time to live (TTL) controls how long a gap the cache survives. The API offers two: a five-minute TTL, and a [one-hour TTL](../04-API-Reference/Guides/build-with-claude-prompt-caching.md#1-hour-cache-duration) that keeps the cache warm through longer breaks but [charges a higher rate for cache writes](../04-API-Reference/Guides/build-with-claude-prompt-caching.md#pricing). The longer TTL helps when you leave a session idle and come back to it, because you skip the reprocessing an expired prefix costs. It costs more on short bursts of work that never idle past five minutes, where the higher write rate applies and the longer cache lifetime goes unused.


[​](#which-ttl-each-request-gets)

Which TTL each request gets

Claude Code decides the TTL per request, and every request falls in one of two fixed buckets:

- **Main conversation**: your interactive turns, non-interactive `-p` runs, and Agent SDK turns, plus the helpers Claude Code runs inline with them
- **Everything else**: the requests Claude Code makes outside that conversation, such as [subagents](../09-Agents-Patterns/sub-agents.md), [workflows](workflows.md), in-process [teammates](../09-Agents-Patterns/agent-teams.md), forks, compaction, and session titles

Unless you choose a TTL yourself, Claude Code requests the one-hour TTL only on a Claude subscription within your plan’s included usage. There it requests the hour for the main conversation, plus a small set of helper requests that Anthropic controls server-side. This table gives each bucket’s default TTL under both kinds of billing.

| Request bucket    | Claude subscription, within plan usage                                         | Usage credits, API key, or cloud provider |
|-------------------|--------------------------------------------------------------------------------|-------------------------------------------|
| Main conversation | One hour                                                                       | Five minutes                              |
| Everything else   | Five minutes, except the server-controlled helper requests, which get one hour | Five minutes                              |

Once you go over your plan’s usage limit and Claude Code draws on [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md), you are billed for that usage, so Claude Code drops the main conversation to the five-minute TTL, which charges a lower rate for cache writes. To keep the one-hour TTL there, [choose the TTL yourself](#choose-the-ttl-yourself).


[​](#choose-the-ttl-yourself)

Choose the TTL yourself

You can set a TTL for either bucket. Each control takes `5m` or `1h`, and Claude Code ignores any other value.

- **Main conversation**: the [`promptCacheTtl`](settings-reference.md#promptcachettl) setting, or the `CLAUDE_CODE_PROMPT_CACHE_TTL` [environment variable](env-vars.md)
- **Everything else**: the [`subagentPromptCacheTtl`](settings-reference.md#subagentpromptcachettl) setting, or the `CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL` environment variable

Both settings and both environment variables require Claude Code v2.1.242 or later. If you sign in with an API key or use a cloud provider, set `promptCacheTtl` to `1h` to give the main conversation a one-hour cache. Requests outside it keep the five-minute default until you choose a TTL for that bucket too. When more than one control applies, Claude Code takes the first match in this order:

1.  `FORCE_PROMPT_CACHING_5M=1`, which forces five minutes for both buckets
2.  The bucket’s environment variable
3.  The bucket’s setting
4.  For a subagent’s requests, the `cacheTtl` value in the subagent’s [`experimental` frontmatter field](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields), which requires Claude Code v2.1.248 or later. Claude Code ignores a `1h` there while your Claude subscription is using usage credits
5.  `ENABLE_PROMPT_CACHING_1H=1`, which requests one hour for both buckets
6.  The [default for the request’s bucket](#which-ttl-each-request-gets)

Set `FORCE_PROMPT_CACHING_5M=1` when you’re debugging cache behavior, comparing the two TTLs, or overriding a longer TTL set in [managed settings](../13-Enterprise-Admin/managed-settings.md). To confirm which TTL your main conversation’s cache writes used, run `claude -p "hello" --output-format json` and read `usage.cache_creation` in the result. Claude Code reports one-hour cache writes under `ephemeral_1h_input_tokens` and five-minute cache writes under `ephemeral_5m_input_tokens`. To get one hour through a gateway or on Amazon Bedrock:

- **LLM gateway you set with `ANTHROPIC_BASE_URL`**: part of the one-hour request travels in the `anthropic-beta` header, so configure the gateway to [forward that header unchanged](../13-Enterprise-Admin/llm-gateway-protocol.md#request-headers)
- **[Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md)**: ask your administrator to request the one-hour TTL in a [gateway policy](../13-Enterprise-Admin/claude-apps-gateway-config.md#one-hour-prompt-cache)
- **Amazon Bedrock**: prompt caching support, minimum cacheable prefix length, and one-hour TTL availability all vary by model. If cache token counts stay at zero, check [supported models, regions, and limits](https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html#prompt-caching-models) in the Amazon Bedrock documentation.


[​](#cache-scope)

Cache scope

In Claude Code, the cache is effectively scoped to one machine and directory. The system prompt embeds your auto memory paths, and the conversation opens with an announcement of the working directory, platform, shell, and OS version. Two sessions in different directories therefore build different prefixes and miss each other’s cache. Sessions you run in parallel in the same directory build matching prefixes and read each other’s cache. Sequential sessions share the prefix only when the git status snapshot taken at startup matches, since each conversation also carries the branch and recent commits from that snapshot. The underlying API cache is broader. Caches are isolated between organizations, and on some providers, [between workspaces within an organization](../04-API-Reference/Guides/build-with-claude-prompt-caching.md#cache-storage-and-sharing). Within those boundaries, any two requests with the same model and prefix read the same cache. For Agent SDK callers running fleets of automated processes, see [improve prompt caching across users and machines](../05-Agent-SDK/agent-sdk-modifying-system-prompts.md#improve-prompt-caching-across-users-and-machines) to move the auto memory location out of the system prompt and share the system prompt’s cache entry across users and machines.


[​](#check-cache-performance)

Check cache performance

Cache performance shows up as two token counts the API reports on every response. The most direct way to watch them live is a [statusline script](statusline.md) that reads the `current_usage` object:

| Field                         | Meaning                                                                                                                                                                   |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `cache_creation_input_tokens` | Tokens written to the cache on this turn, billed at the cache write rate                                                                                                  |
| `cache_read_input_tokens`     | Tokens served from cache on this turn, billed at the model’s [cached token rate](../17-Billing-Plans/about-claude-pricing.md), below the standard input rate |

A high read-to-creation ratio means caching is working well. If creation stays high turn after turn, something is changing in your prefix. The [actions that invalidate the cache](#actions-that-invalidate-the-cache) section lists the usual causes. For a per-session summary, run `/usage`. After the main conversation’s first response, Claude Code adds a [`Prompt cache (main)` line](../17-Billing-Plans/costs.md#prompt-cache-statistics) to the Session block, showing the session’s hit ratio, miss count, and whether the cache is warm right now. A status line script can read the same numbers from the [`prompt_cache` object](statusline.md#prompt-cache-fields). Both require Claude Code v2.1.251 or later. The `Prompt cache (main)` line also names the likely cause of the last miss when Claude Code can identify one, for example `likely cause: tool definitions changed`. The likely-cause text requires Claude Code v2.1.260 or later. For visibility across an organization, the OpenTelemetry exporter reports cache read and creation tokens per user and session. See [Monitor usage](../13-Enterprise-Admin/monitoring-usage.md) for the metric and event attribute reference.


[​](#subagents-and-the-cache)

Subagents and the cache

A [subagent](../09-Agents-Patterns/sub-agents.md) starts its own conversation with its own system prompt and tool set, separate from the parent’s. Its first request doesn’t read the parent’s cache, because the two prefixes differ, and it warms a cache of its own across its turns. Subagents fall outside the main-conversation [TTL bucket](#which-ttl-each-request-gets), so they get five minutes even on a subscription until you [choose a longer one](#choose-the-ttl-yourself). The parent’s cache is unaffected. From the parent’s side, the subagent’s call and result append to the conversation, leaving the parent’s prefix intact. A [fork](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation), by contrast, inherits the parent’s system prompt, tools, and conversation history exactly, so its first request reads the parent’s cache. Other requests can also read a prefix that an earlier request cached:

- **Session copies**: a session you [copy with `/fork`](../09-Agents-Patterns/agent-view.md#copy-the-session-with-%2Ffork) receives its isolation instruction as a message at the end of the copied conversation, so the cache that the original conversation built stays intact.
- **Compaction**: the summarization call described in [Compacting the conversation](#compacting-the-conversation) uses the same prefix-sharing approach.
- **Resumed subagents**: when Claude [resumes a subagent](../09-Agents-Patterns/sub-agents.md#resume-subagents), the resumed run’s first request can read the cache the original run warmed.
- **Workflow fan-outs**: in a [workflow fan-out](workflows.md#prompt-caching-in-a-fan-out) of same-prefix agents, Claude Code holds all but the first for up to 5 seconds by default, so their first requests can read the prefix that the first agent cached.


[​](#disable-prompt-caching)

Disable prompt caching

Disabling caching is occasionally useful when debugging caching behavior with a specific model or provider. To turn it off, set one of these environment variables to `1`:

| Variable                        | Effect                               |
|---------------------------------|--------------------------------------|
| `DISABLE_PROMPT_CACHING`        | Disable for all models               |
| `DISABLE_PROMPT_CACHING_HAIKU`  | Disable for the default Haiku model  |
| `DISABLE_PROMPT_CACHING_SONNET` | Disable for the default Sonnet model |
| `DISABLE_PROMPT_CACHING_OPUS`   | Disable for the default Opus model   |
| `DISABLE_PROMPT_CACHING_FABLE`  | Disable for Fable only               |

`DISABLE_PROMPT_CACHING_HAIKU` applies to the default Haiku model, the model the `haiku` alias resolves to. It disables caching wherever that model runs, including the main conversation when it is your main model. Covering the main conversation requires Claude Code v2.1.283 or later. The variable also covers a background model you set with the deprecated `ANTHROPIC_SMALL_FAST_MODEL` variable, when that model differs from your main model. A different Haiku version that you pin as your main model keeps caching; set `DISABLE_PROMPT_CACHING` to disable caching for it. `DISABLE_PROMPT_CACHING_SONNET` and `DISABLE_PROMPT_CACHING_OPUS` each apply to the model the `sonnet` or `opus` alias resolves to. If you set any other Sonnet or Opus model ID as your main model, that model keeps caching. For example, a session on `claude-sonnet-5` keeps caching while `sonnet` resolves to `claude-sonnet-5-5`. To disable caching for that model, set `DISABLE_PROMPT_CACHING`. To set caching policy across an organization, put any of these or the [TTL variables](#cache-lifetime) in the `env` block of [managed settings](../13-Enterprise-Admin/managed-settings.md). For normal use, leave caching enabled.


[​](#related-resources)

Related resources

- [Lessons from building Claude Code: Prompt caching is everything](https://claude.com/blog/lessons-from-building-claude-code-prompt-caching-is-everything): the design rationale for plan mode, deferred tool loading, and compaction
- [Explore the context window](context-window.md): what loads into context and when
- [Reduce token usage](../17-Billing-Plans/costs.md#reduce-token-usage): strategies beyond caching for managing context size
- [Track and reduce costs](../05-Agent-SDK/agent-sdk-cost-tracking.md): cache token tracking and TTL configuration for Agent SDK callers
- [Prompt caching](../04-API-Reference/Guides/build-with-claude-prompt-caching.md): the underlying API mechanism, breakpoints, and pricing

---

## Prompt library - Claude Code Docs

Source: https://code.claude.com/docs/en/prompt-library
Path: 02-Claude-Code-CLI/prompt-library.md

## On this page

- [What makes these prompts work](#what-makes-these-prompts-work)
- [Where these come from](#where-these-come-from)
- [Related resources](#related-resources)

Use Claude Code

# Prompt library

Copy pageCopy page

Copy-paste prompts for Claude Code, tagged by task and role.

Copy pageCopy page

This is a library of prompts to copy into Claude Code. Use it to explore ways of working you haven’t tried, or when you’re not sure where to start. The prompts are collected from various Anthropic guides, including [Common workflows](common-workflows.md), [Best practices](best-practices.md), and [How Anthropic teams use Claude Code](../19-Reference/how-anthropic-teams-use-claude-code.md). They’re starting points rather than scripts. Open **Why this works** under any prompt to see the pattern behind it so you can write your own.


[​](#what-makes-these-prompts-work)

What makes these prompts work

The prompts above share a few patterns. Recognizing them helps you adapt any prompt here to your own task. **Describe the outcome, not the steps.** Say what you want and let Claude find the files. The prompt below works without naming a single file path.

```python
add rate limiting to the public API and make sure existing tests still pass
```

**Give it a way to check its own work.** Ask for run, test, compare, or verify in the same prompt so Claude iterates instead of stopping after one attempt. To check the finished change against the running app, run [`/verify`](../08-Plugins-Skills/skills.md#run-and-verify-your-app).

```python
write the migration, run it against the dev database, and confirm the schema matches
```

**Point at a reference.** Name an existing file, test, or pattern to match so the new code is consistent with what you already have.

```python
add a settings page that follows the same layout as the profile page
```

**State the measurable target.** When the goal is performance or coverage, give the metric and threshold so completion is unambiguous.

```python
get the bundle size under 200KB and show me what you removed
```

**Give it the artifact.** Paste errors, logs, screenshots, and plan output directly in the prompt, or type `@` to reference a file. Claude reads the source instead of your description of it.

```python
why is the build failing? @build.log
```

**Say how you want the answer.** Name the format, length, or audience so the explanation fits how you’ll use it. To make a format the default for every response, set an [output style](output-styles.md).

```python
explain how the payment retry logic works as an HTML page with a diagram, then open it in my browser
```

For more on each pattern, see [best practices](best-practices.md).


[​](#where-these-come-from)

Where these come from

These prompts are based on patterns from published Anthropic resources. Each card links to its source:

- [Common workflows](common-workflows.md): step-by-step guides for the core tasks
- [Best practices](best-practices.md): prompting patterns and project setup
- [How Anthropic teams use Claude Code](../19-Reference/how-anthropic-teams-use-claude-code.md): real workflows from engineering, product, design, and data teams, with deep dives on [legal](https://claude.com/blog/how-anthropic-uses-claude-legal), [marketing](https://claude.com/blog/how-anthropic-uses-claude-marketing), and [cybersecurity](https://claude.com/blog/how-anthropic-uses-claude-cybersecurity)
- [Scaling agentic coding guide](https://resources.anthropic.com/hubfs/Scaling%20agentic%20coding%20across%20your%20organization.pdf): the enterprise adoption guide

For video walkthroughs of these patterns, see the free [Claude Code in Action](https://academy.claude.com/courses/claude-code-in-action) course on [Claude Academy](https://academy.claude.com/).


[​](#related-resources)

Related resources

The prompts on this page are starting points. Once one works for your project, the next step is making it repeatable: save it as a [skill](../08-Plugins-Skills/skills.md) so anyone on your team can run it as a `/command`, and record the conventions Claude learned in [CLAUDE.md](memory.md) so every session starts with that context instead of Claude relearning it. For larger or riskier changes, [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode) shows you the file list before any edits happen. If you’re introducing Claude Code across a team, see [administration](../13-Enterprise-Admin/admin-setup.md) for managed settings and policy, and [costs and usage](../17-Billing-Plans/costs.md) for how this work is billed on your plan.

---

## Continue local sessions from any device with Remote Control - Claude Code Docs

Source: https://code.claude.com/docs/en/remote-control
Path: 02-Claude-Code-CLI/remote-control.md

## On this page

- [Requirements](#requirements)
- [Start a Remote Control session](#start-a-remote-control-session)
  - [Check connection status](#check-connection-status)
  - [Connect from another device](#connect-from-another-device)
  - [What connected devices see](#what-connected-devices-see)
  - [Enable Remote Control for all sessions](#enable-remote-control-for-all-sessions)
  - [Auto-connect with DISABLE_TELEMETRY or DO_NOT_TRACK set](#auto-connect-with-disable-telemetry-or-do-not-track)
  - [Resume sessions after stopping the server](#resume-sessions-after-stopping-the-server)
  - [Set the default spawn mode for a project](#set-the-default-spawn-mode-for-a-project)
- [Connection and security](#connection-and-security)
- [Trusted Devices](#trusted-devices)
  - [Enable Trusted Devices for a Team or Enterprise organization](#enable-trusted-devices-for-your-organization)
  - [What members see](#what-members-see)
  - [Manage enrolled devices](#manage-enrolled-devices)
- [Remote Control vs cloud sessions](#remote-control-vs-cloud-sessions)
- [Mobile push notifications](#mobile-push-notifications)
- [Limitations](#limitations)
- [Authorize a connector again from your shell](#authorize-a-connector-again-from-your-shell)
- [Troubleshooting](#troubleshooting)
  - [”Remote Control requires a claude.ai subscription”](#%E2%80%9Dremote-control-requires-a-claude-ai-subscription%E2%80%9D)
  - [”Remote Control requires a full-scope login token”](#%E2%80%9Dremote-control-requires-a-full-scope-login-token%E2%80%9D)
  - [”Unable to determine your organization for Remote Control eligibility”](#%E2%80%9Dunable-to-determine-your-organization-for-remote-control-eligibility%E2%80%9D)
  - [”Remote Control isn’t enabled for this account”](#%E2%80%9Dremote-control-isn%E2%80%99t-enabled-for-this-account%E2%80%9D)
  - [”Couldn’t verify Remote Control eligibility”](#%E2%80%9Dcouldn%E2%80%99t-verify-remote-control-eligibility%E2%80%9D)
  - [”Remote Control requires feature-flag evaluation”](#%E2%80%9Dremote-control-requires-feature-flag-evaluation%E2%80%9D)
  - [”Remote Control is only available when using Claude via api.anthropic.com”](#%E2%80%9Dremote-control-is-only-available-when-using-claude-via-api-anthropic-com%E2%80%9D)
  - [“Remote Control is disabled by your organization’s policy”](#remote-control-is-disabled-by-your-organizations-policy)
  - [“Remote Control was turned off by your organization’s policy”](#remote-control-was-turned-off-by-your-organizations-policy)
  - [“Couldn’t verify your organization’s policy for remote control”](#couldnt-verify-your-organizations-policy-for-remote-control)
  - [”Remote credentials fetch failed”](#%E2%80%9Dremote-credentials-fetch-failed%E2%80%9D)
  - [“Couldn’t reconnect to your Remote Control session”](#couldnt-reconnect-to-your-remote-control-session)
  - [“Previous session is unavailable — run /remote-control to start a new one”](#previous-session-is-unavailable)
  - [”Remote Control got an unexpected server response”](#%E2%80%9Dremote-control-got-an-unexpected-server-response%E2%80%9D)
  - [”Your organization requires Trusted Devices for Remote Control, but this device is not enrolled”](#%E2%80%9Dyour-organization-requires-trusted-devices-for-remote-control-but-this-device-is-not-enrolled%E2%80%9D)
  - [”session expired for trusted-device check”](#%E2%80%9Dsession-expired-for-trusted-device-check%E2%80%9D)
- [Related resources](#related-resources)

Platforms and integrations

# Continue local sessions from any device with Remote Control

Copy pageCopy page

Continue a local Claude Code session from your phone, tablet, or any browser using Remote Control. Works with claude.ai/code and the Claude mobile app.

Copy pageCopy page

Remote Control connects [claude.ai/code](https://claude.ai/code) or the Claude app for [iOS](https://apps.apple.com/us/app/claude-by-anthropic/id6473753684) and [Android](https://play.google.com/store/apps/details?id=com.anthropic.claude) to a Claude Code session running on your machine. Start a task at your desk, then pick it up from your phone on the couch or a browser on another computer. When you start a Remote Control session on your machine, Claude keeps running locally the entire time, so your code execution and filesystem access stay on your machine. With Remote Control you can:

- **Use your full local environment remotely**: your filesystem, [MCP servers](../06-MCP-Tools/General/mcp.md), tools, and project configuration all stay available, and typing `@` autocompletes file paths from your local project.
- **Work from both surfaces at once**: the conversation and the progress of [subagents](../09-Agents-Patterns/sub-agents.md) and [dynamic workflows](workflows.md) stay in sync across all connected devices, so you can send messages from your terminal, browser, and phone interchangeably.
- **Send images and files from your phone or browser**: attach a photo or file in the Claude app or at claude.ai/code, with or without a caption. Claude sees attached photos directly as part of your message. Claude Code downloads other files to your machine and passes them to Claude as `@` file references.
- **Survive interruptions**: if your laptop sleeps or your network drops, Claude Code reconnects automatically when your machine comes back online.

Unlike [cloud sessions](claude-code-on-the-web.md), which run on cloud infrastructure, Remote Control sessions run directly on your machine and interact with your local filesystem. The web and mobile interfaces are a window into that local session, so your computer has to stay on and the `claude` process has to keep running.

Remote Control is a Claude Code feature. For conversations in other Claude products, see the [Claude Help Center](https://support.claude.com).


[​](#requirements)

Requirements

Before using Remote Control, confirm that your environment meets these conditions:

- **Subscription**: available on Pro, Max, Team, and Enterprise plans. API keys are not supported. On Team and Enterprise, an Owner must first enable the Remote Control toggle in [Claude Code admin settings](https://claude.ai/admin-settings/claude-code).
- **Custom roles**: if your Enterprise organization manages your access with [custom roles](https://support.claude.com/en/articles/13930452), your roles must give you both the cloud sessions permission and the **Claude Code remote control** permission. If either is missing, starting Remote Control shows [`Remote Control is disabled by your organization's policy`](#remote-control-is-disabled-by-your-organizations-policy). Ask an Owner to check your roles and add what’s missing at [**Organization settings \> Roles**](https://claude.ai/admin-settings/roles).
- **Authentication**: run `claude` and use `/login` to sign in through claude.ai if you haven’t already. Without an eligible login, `claude remote-control` exits with an error, while `claude --remote-control` still starts an interactive session and shows a Remote Control failure notification shortly after launch.
- **API endpoint**: not available in any of these configurations:
  - You use Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry.
  - You point [`ANTHROPIC_BASE_URL`](env-vars.md) at a host other than `api.anthropic.com`, such as an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) or proxy. Unset the variable to use Remote Control.
  - You sign in through an enterprise [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md).
- **Feature-flag evaluation**: if you set an [environment variable that turns off feature-flag evaluation](env-vars.md#features-that-need-feature-flag-fetching), whether Remote Control is available depends on which one:
  - If you set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` or `DISABLE_GROWTHBOOK`, Remote Control is unavailable. Unset the variable wherever it’s set, in your shell environment or in the `env` block of a [`settings.json` file](settings-reference.md#all-settings), to use Remote Control.
  - If you set only `DISABLE_TELEMETRY` or `DO_NOT_TRACK`, Remote Control stays available unless your organization requires [Trusted Devices](#trusted-devices). If it does, unset the variable to use Remote Control. Using Remote Control with either variable set requires Claude Code v2.1.283 or later, or v2.1.304 or later in the Claude Desktop app.
- **Workspace trust**: in a directory you haven’t trusted yet, `claude remote-control` prints what trusting it turns on and asks `Trust <directory>? [y/N]` before it starts. Answering `y` saves the choice, except in your home directory, where trust is never saved and the question returns on every run. When its standard input or output isn’t a terminal, the command can’t ask and exits with a [`Workspace not trusted`](errors.md#workspace-not-trusted-when-starting-remote-control) error.


[​](#start-a-remote-control-session)

Start a Remote Control session

You can start a Remote Control session from the CLI, the [Claude Desktop app](../16-Mobile-Desktop/desktop.md), or the VS Code extension. The CLI offers three invocation modes; the Desktop app and VS Code use the `/remote-control` command.

- Server mode

- Interactive session

- From an existing session

- VS Code

- Desktop app

In your project directory, run:

```python
claude remote-control
```

Until you accept Remote Control’s one-time confirmation, `claude remote-control` explains what it does and asks `Enable Remote Control? (y/n)` before starting the server. Answer `y` to accept and start the server. If you decline, Claude Code exits without starting the server and asks again the next time you run the command.The process stays running in your terminal in server mode, waiting for remote connections. It displays a session URL you can use to [connect from another device](#connect-from-another-device), and you can press spacebar to show a QR code for quick access from your phone. While a remote session is active, the terminal shows connection status and tool activity.Pass any of these flags after `remote-control`:

[TABLE]

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](errors.md#not-carried-over-to-the-sessions-remote-control-starts) and names the flag to remove.To sandbox the sessions the server starts, turn on [sandboxing](sandboxing.md) in a settings file.To print the `remote-control` flags in your terminal, run `claude remote-control --help`. Before v2.1.302, without an eligible sign-in the command returned one of the errors under [Troubleshooting](#troubleshooting) instead.

To start a normal interactive Claude Code session with Remote Control enabled, use the `--remote-control` flag (or `--rc`):

```python
claude --remote-control
```

Optionally pass a name for the session:

```python
claude --remote-control "My Project"
```

This gives you a full interactive session in your terminal that you can also control from claude.ai or the Claude app. Unlike `claude remote-control` (server mode), you can type messages locally while the session is also available remotely.

If you’re already in a Claude Code session and want to continue it remotely, use the `/remote-control` (or `/rc`) command:

```python
/remote-control
```

Pass a name as an argument to set a custom session title:

```python
/remote-control My Project
```

This starts a Remote Control session that carries over your current conversation history.Until you accept Remote Control’s one-time confirmation, a dialog appears before `/remote-control` connects. Select **Enable Remote Control** to accept and connect. If you select **Never mind** or press Esc, Claude Code doesn’t connect and asks again the next time you run `/remote-control`.The `--verbose` flag is not available with this command.

In the [Claude Code VS Code extension](../03-IDE-Integrations/vs-code.md), type `/remote-control` or `/rc` in the prompt box.

```python
/remote-control
```

While Remote Control is on, Claude Code shows a **Remote Control** indicator in the prompt box footer. Once the session connects, click the indicator to go directly to the session, or find it in the session list at [claude.ai/code](https://claude.ai/code). Claude Code also posts the session URL in the conversation. To disconnect, run `/remote-control` again.Unlike the CLI, the VS Code command does not accept a name argument or display a QR code. The session title is derived from your conversation history or first prompt.

In a local session in the [Claude Desktop app’s](../16-Mobile-Desktop/desktop.md) Code tab, type `/remote-control` or `/rc` in the prompt box.

```python
/remote-control
```

Once the session connects, find it in the session list at [claude.ai/code](https://claude.ai/code). To disconnect, run `/remote-control` again.To turn Remote Control on for every session by default instead, see [Enable Remote Control for all sessions](#enable-remote-control-for-all-sessions).


[​](#check-connection-status)

Check connection status

In an interactive session, while Remote Control is connected, the terminal shows an `/rc active` indicator that links to the session on claude.ai. The indicator is hidden when the terminal is too narrow to fit it. To see the session URL and a QR code for [connecting from another device](#connect-from-another-device), run `/remote-control` again to open the status panel. The panel also lets you disconnect Remote Control while your local session keeps running. If the connection fails in an interactive session, the indicator changes to show the failure, and Claude Code shows the reason in a notification and adds it to the conversation. Run `/remote-control` to reconnect, unless the reason says the session changed somewhere else:

- **Another connection took over this session**: another device or Claude Code session has it now. Run `/remote-control` only if you want to take it back.
- **This session was ended or archived from another device or app**: run `/remote-control` only if you want the session back. Claude Code reopens an archived session.
- **The server no longer reports this session**: it may have been deleted from another device or app.


[​](#connect-from-another-device)

Connect from another device

Once a Remote Control session is active, you have a few ways to connect from another device:

- **Open the session URL** in any browser to go directly to the session on [claude.ai/code](https://claude.ai/code).
- **Scan the QR code** shown alongside the session URL to open it directly in the Claude app. With `claude remote-control`, press spacebar to toggle the QR code display.
- **Open [claude.ai/code](https://claude.ai/code) or the Claude app** and find the session by name in the session list. In the Claude mobile app, tap **Code** in the navigation to reach the session list. Remote Control sessions show a computer icon with a green status dot when online.

When you connect, the device shows any subagents and workflows the session already has running in the background. Stop one of them from the device, and Claude Code stops that task on your machine. The remote session title is chosen in this order:

1.  The name you passed to `--name`, `--remote-control`, or `/remote-control`
2.  The title you set with `/rename`
3.  The last meaningful message in existing conversation history
4.  An auto-generated name like `myhost-graceful-unicorn`, where `myhost` is your machine’s hostname or the prefix you set with `--remote-control-session-name-prefix`

If you didn’t set an explicit name, Claude Code updates the title to reflect your prompt once you send one. When you rename a session from claude.ai or the Claude app, Claude Code also updates the local title shown in `claude --resume`. If you don’t have the Claude app yet, run `/mobile` inside Claude Code to show a QR code for [claude.ai/mobile](https://claude.ai/mobile), which opens the right app store for your phone.


[​](#what-connected-devices-see)

What connected devices see

A connected device shows the conversation in your terminal as it happens. These cases go beyond ordinary messages:

- **Compaction and `/clear`**: while Claude Code [compacts the conversation](context-window.md#what-survives-compaction), connected devices show the progress and then where the conversation was compacted. When you run `/clear`, the conversation resets on connected devices too.
- **Switching conversations with `/resume`**: the connected device doesn’t receive the switched-to conversation’s title or earlier history, but new messages in both directions go to and from whichever conversation is open in your terminal. To work on the original conversation from the device again, run `/resume` in your terminal and switch back to it.
- **Pulling a session with `/teleport`**: when you pull a [cloud session](claude-code-on-the-web.md#from-cloud-to-terminal) into your terminal with `/teleport`, the connected device doesn’t receive the pulled conversation’s earlier history. New messages in both directions go to and from the pulled conversation, which is now the one open in your terminal.
- **Messages from your other sessions**: with [cross-session messaging](cross-session-messaging.md), the same connection carries messages between your own sessions on different machines.
- **Diff of your changes**: when the session’s directory is in a git repository, a connected device’s diff pane shows your changes. On a branch that has commits ahead of the repository’s default branch, the pane shows the changes since the branch split from it, including your uncommitted edits. On the default branch itself, or on a branch that isn’t ahead of it, the pane shows only your uncommitted changes.
- **Model**: when you pick a [model](model-config.md) from a connected device, Claude Code runs the session on that model. Requires Claude Code v2.1.238 or later. A model you pick from the device’s model control applies to the current session only. When you send `/model <name>` from the device to an interactive session, Claude Code also sets your default for new sessions.
- **Effort level**: when you set the [effort level](model-config.md#adjust-effort-level) from a connected device, with `/effort` or the device’s effort control, Claude Code applies it to the session on your machine. If you pinned a level with `CLAUDE_CODE_EFFORT_LEVEL`, the session keeps that level, and Claude Code refuses a different pick from the effort control. Picking a level from the effort control requires Claude Code v2.1.234 or later on your machine.
- **Reconnecting after a connection failure**: run `/remote-control` to reconnect. If compaction rewrote the conversation or you switched conversations with `/resume` in the meantime, Claude Code archives the server session it was using instead of leaving it in the session list. You can still find it by [filtering for archived sessions](claude-code-on-the-web.md#archive-sessions). Switching conversations while a device is still connected doesn’t archive the session.


[​](#enable-remote-control-for-all-sessions)

Enable Remote Control for all sessions

Remote Control only activates when you explicitly run `claude remote-control`, `claude --remote-control`, or `/remote-control`, unless auto-connect is turned on. To turn auto-connect on for every interactive session, run `/config` inside Claude Code and set **Enable Remote Control for all sessions**. The toggle takes three values:

- **`true`**: connect automatically when an interactive session starts.
- **`false`**: turn auto-connect off, though a `true` from [managed settings](../13-Enterprise-Admin/managed-settings.md) outranks it, because Claude Code saves the choice to your user settings. A `false` in project or local settings (`.claude/settings.json`, `.claude/settings.local.json`) turns auto-connect off even over a managed `true`.
- **`default`**: clear your choice and follow your organization’s admin default if one is set, otherwise Claude Code’s current default. If you set `DISABLE_TELEMETRY` or `DO_NOT_TRACK`, see [Auto-connect with `DISABLE_TELEMETRY` or `DO_NOT_TRACK` set](#auto-connect-with-disable-telemetry-or-do-not-track).

The VS Code extension and the Desktop app also have an auto-connect toggle:

- **VS Code extension**: **Enable Remote Control for all sessions** in the [command menu’s](../03-IDE-Integrations/vs-code.md#use-the-prompt-box) Settings section.
- **Desktop app**: **Settings \> Claude Code \> Connect new sessions to Remote Control**. See [Control which sessions appear on your other devices](../16-Mobile-Desktop/desktop.md#control-which-sessions-appear-on-your-other-devices).

To turn auto-connect on from a settings file instead, set [`remoteControlAtStartup`](settings-reference.md#remotecontrolatstartup) to `true` in your user `~/.claude/settings.json` or in [managed settings](../13-Enterprise-Admin/managed-settings.md). In project or local settings (`.claude/settings.json`, `.claude/settings.local.json`), Claude Code honors a `false` and turns auto-connect off for that repository, but ignores a `true`, so a checked-in file can’t turn on Remote Control for everyone who opens the repository. Auto-connect signs in with your own claude.ai account, so a session it starts appears only in your own account’s Claude apps and grants no one else access. With this setting on, each interactive Claude Code process registers one remote session. If you run multiple instances, each one gets its own remote session. To run multiple concurrent sessions from a single process, use [server mode](#start-a-remote-control-session) instead.


[​](#auto-connect-with-disable-telemetry-or-do-not-track)

Auto-connect with `DISABLE_TELEMETRY` or `DO_NOT_TRACK` set

With only `DISABLE_TELEMETRY` or `DO_NOT_TRACK` set, your sessions don’t auto-connect through your organization’s admin default or Claude Code’s own default. If something else makes Remote Control unavailable for you, such as `DISABLE_GROWTHBOOK` or an LLM gateway, start with [Requirements](#requirements) instead. Before you turn auto-connect on with only `DISABLE_TELEMETRY` or `DO_NOT_TRACK` set, confirm that your Claude Code version meets the [requirement for these variables](#requirements). Then check whether your organization requires [Trusted Devices](#trusted-devices):

- **Not required**: set **Enable Remote Control for all sessions** to `true` in `/config`.
- **Required**: Remote Control isn’t available while `DISABLE_TELEMETRY` or `DO_NOT_TRACK` is set. Unset whichever of the two variables you set. If your sessions still don’t auto-connect, set **Enable Remote Control for all sessions** to `true` in `/config`.


[​](#resume-sessions-after-stopping-the-server)

Resume sessions after stopping the server

When you stop `claude remote-control` with Ctrl+C, the sessions it was serving stop responding from your phone or browser. As long as you weren’t running another `claude remote-control` in the same directory and didn’t start this one with `--no-create-session-in-dir`, Claude Code doesn’t archive them. To bring them back, run one of these commands in the same directory:

- **`claude remote-control`**: brings back every session the server was serving.
- **`claude remote-control --continue`**: brings back only the session the server started with, and exits when that session ends. If this directory has no record, Claude Code uses the newest one from this repository’s other git worktrees.
- **`claude remote-control --session-id <id>`**: brings back only the session whose ID you pass, and exits when that session ends. The ID is the part of the session’s URL at claude.ai/code between `/code/` and any `?`.

These commands work for about four hours after the server stopped. After that, run `claude remote-control` to start a new session. If you archived a session in the meantime, `--continue` and `--session-id` unarchive it on Claude Code v2.1.228 or later. To bring back a session you started with `claude --remote-control` or `/remote-control`, resume the conversation with `claude --continue` or `claude --resume`. For the permission mode that the resumed conversation starts in, see [permission mode on resume](sessions.md#permission-mode-on-resume). If Remote Control doesn’t reconnect, see [Couldn’t reconnect to your Remote Control session](#couldnt-reconnect-to-your-remote-control-session). If you resume the conversation in a second terminal while the first one still has Remote Control on, Claude Code prints a `Remote Control not started here` notice in the second terminal and leaves Remote Control off there instead of taking the session away from the first. Run `/remote-control` in the second terminal to move Remote Control to it. When you resume a conversation in Claude Desktop or an IDE extension that had Remote Control on, Claude Code reattaches it to the existing claude.ai session instead of adding a new one to the session list.


[​](#set-the-default-spawn-mode-for-a-project)

Set the default spawn mode for a project

If `claude remote-control` prints `Spawn mode: <mode> (saved for this folder; press w to change)` at startup, the server is starting in a spawn mode saved earlier for this project. The saved mode comes from a choice you made in your own terminal. If `claude remote-control` asked `Spawn mode for this project:` there, Claude Code kept what you answered: `1` for `same-dir` or `2` for `worktree`. If you pressed `w` while it ran, Claude Code kept the mode you switched to, even on a run you started with `--spawn same-dir` or `--spawn worktree`.

- While the server runs in `same-dir` or `worktree` mode, press `w` in the server’s terminal to switch to the other one. Switching requires a git repository or a `WorktreeCreate` hook.
- To use a different mode for one run, pass `--spawn <mode>`.


[​](#connection-and-security)

Connection and security

Your local Claude Code session makes outbound HTTPS requests only and never opens inbound ports on your machine. When you start Remote Control, it registers with the Anthropic API and polls for work. When you connect from another device, the server routes messages between the web or mobile client and your local session over a streaming connection. All traffic travels through the Anthropic API over TLS, the same transport security as any Claude Code session. The connection uses multiple short-lived credentials, each scoped to a single purpose and expiring independently. While Remote Control is connected, the session transcript, including your messages, Claude’s responses, and tool activity, is stored on Anthropic servers. The stored transcript keeps the conversation in sync across your devices and lets the session reconnect after a network drop. Execution and filesystem access stay on your machine, and stored transcripts are retained under the [Data usage](../13-Enterprise-Admin/data-usage.md) policy. To turn Remote Control off entirely, use the [`disableRemoteControl`](settings-reference.md#disableremotecontrol) setting. Organizations with [Zero Data Retention](zero-data-retention.md) enabled, or with the [HIPAA configuration](hipaa-setup.md) applied, can’t enable Remote Control.


[​](#trusted-devices)

Trusted Devices

Trusted Devices is currently in beta. Features and functionality may evolve as the experience is refined.Trusted Devices is available on Pro, Max, Team, and Enterprise plans and is off by default. On Team and Enterprise plans, an Owner turns it on for the organization. On Pro and Max plans, you turn on **Require trusted devices** yourself in your settings, on the Cowork or Account page.

Trusted Devices requires each member of your organization, or you alone on a Pro or Max plan, to verify their device before they can view or steer Remote Control sessions from claude.ai, the Claude mobile apps, or Claude Desktop. It ties Remote Control access to a known device and a recent authentication, not just a signed-in account. When the setting is on, interacting with a Remote Control session requires both of the following:

- **An enrolled device**: each browser, phone, or desktop app a member uses for Remote Control enrolls its own credential. Enrollment is only offered shortly after a full sign-in, so a device joins the trusted list as part of a real authentication rather than silently in the background.
- **A recent sign-in**: the member’s sign-in must be no more than 18 hours old. Instead of signing in again each day, members confirm presence with Face ID, Touch ID, Windows Hello, or a passkey. This biometric step-up refreshes the session immediately.

Biometric checks run on the device through the operating system or browser, the same mechanism as passkey sign-in. Anthropic never receives or stores fingerprints, face data, or any other biometric information. Only the device’s public key and basic metadata such as display name, platform, and enrollment time are stored. The setting applies to Remote Control in Claude Code and to Computer access in [Cowork](https://claude.com/docs/cowork/overview). This page covers the Claude Code side. Regular Claude chat, Claude Code in the terminal, and API usage are unaffected.


[​](#enable-trusted-devices-for-your-organization)

Enable Trusted Devices for a Team or Enterprise organization

An Owner enables the setting from the claude.ai organization settings.

1

Go to the Capabilities page

Go to [**Organization settings \> Capabilities \> Remote sessions**](https://claude.ai/admin-settings/capabilities). The **Require trusted devices** toggle appears in that section.

2

Turn on Require trusted devices

The setting applies to every member of the organization and to Remote Control sessions started after you enable it. Sessions that were already running before the toggle was turned on are not retroactively protected and continue without the device requirement until they end. Per-team or per-project scoping is not available.

3

Tell members what to expect

The first time a member views or steers a new Remote Control session from a browser, phone, or desktop app after the setting is enabled, they are prompted to enroll that device. Letting them know ahead of time avoids confusion.


[​](#what-members-see)

What members see

Enrollment is a one-time step per device. After that, the only visible change is an occasional biometric prompt.

- **First use on each device**: the member is asked to enroll. If their sign-in is not recent, they sign in first through your normal flow, including SSO if configured, then confirm enrollment.
- **Day to day**: members with an enrolled device and a recent sign-in see no prompts. When the sign-in ages past 18 hours, the next Remote Control interaction shows a single Face ID, Touch ID, Windows Hello, or passkey prompt.
- **Unenrolled devices**: Remote Control sessions cannot be viewed or steered until the device is enrolled. Regular Claude chat on that device is unaffected.
- **No platform authenticator**: members on a machine without Face ID, Touch ID, or Windows Hello can use a hardware security key, or sign in again instead of stepping up.
- **In the terminal**: the machine running Claude Code receives its own credential automatically when the developer signs in to the CLI. There is no separate enrollment step in the terminal.


[​](#manage-enrolled-devices)

Manage enrolled devices

Members can review and revoke their own devices from account settings. Open [claude.ai/settings/account](https://claude.ai/settings/account#trusted-devices) and find the **Trusted devices** section to see every enrolled device with its name, platform, and enrollment date. Removing a device revokes its credential immediately, and the device can re-enroll later after a fresh sign-in. Credentials also expire on their own if not renewed, so an unused device drops off the trusted list automatically. For a lost or stolen device, the member removes it from this page. If the member cannot sign in, an admin can use **Sign out everywhere** in the admin console to revoke every session and enrolled device for that member, after which the member re-enrolls the devices they still hold.


[​](#remote-control-vs-cloud-sessions)

Remote Control vs cloud sessions

Remote Control and [cloud sessions](claude-code-on-the-web.md) both use the claude.ai/code interface. The key difference is where the session runs: Remote Control executes on your machine, so your local MCP servers, tools, and project configuration stay available. A cloud session executes on cloud infrastructure, Anthropic-managed by default. Use Remote Control when you’re in the middle of local work and want to keep going from another device. Use a cloud session when you want to start a task without any local setup, work on a repo you don’t have cloned, or run multiple tasks in parallel. A [project](claude-projects.md) combines the two: its threads run in the cloud, and it uses Remote Control to [run a thread on your computer](claude-projects.md#run-a-thread-on-your-own-computer) when you ask for one there. Claude Code offers several ways to work when you’re not at your terminal. They differ in what triggers the work, where Claude runs, and how much you need to set up.

|                                                               | Trigger                                                                                           | Claude runs on                                                                                              | Setup                                                                                                                                                                | Best for                                                      |
|:--------------------------------------------------------------|:--------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------|
| [Dispatch](../16-Mobile-Desktop/desktop.md#sessions-from-dispatch)           | Message a task from the Claude mobile app                                                         | Your machine (Desktop)                                                                                      | [Pair the mobile app with Desktop](https://support.claude.com/en/articles/13947068)                                                                                  | Delegating work while you’re away, minimal setup              |
| [Remote Control](remote-control.md)                     | Drive a running session from [claude.ai/code](https://claude.ai/code) or the Claude mobile app    | Your machine (CLI, Desktop, or VS Code)                                                                     | Run [`claude remote-control` or `/remote-control`](remote-control.md#start-a-remote-control-session)                                                           | Steering in-progress work from another device                 |
| [Channels](channels.md)                                 | Push events from a chat app like Telegram or Discord, or your own server                          | Your machine (CLI)                                                                                          | [Install a channel plugin](channels.md#quickstart) or [build your own](channels-reference.md)                                                            | Reacting to external events like CI failures or chat messages |
| [Slack](../14-Connectors/slack.md)                                       | Mention `@Claude` in a team channel                                                               | Anthropic cloud                                                                                             | [Install the Slack app](../14-Connectors/slack.md#setting-up-claude-code-in-slack) with [Claude Code on the web](claude-code-on-the-web.md) enabled, on Pro and Max plans | PRs and reviews from team chat                                |
| [Self-hosted environments](../13-Enterprise-Admin/self-hosted-environments.md) | Start a [cloud session](claude-code-on-the-web.md) and pick your organization’s environment | Your organization’s infrastructure                                                                          | [Deploy runners](../13-Enterprise-Admin/self-hosted-environments-quickstart.md), on Team and Enterprise plans                                                                         | Cloud sessions that must run inside your network              |
| [Scheduled tasks](scheduled-tasks.md)                   | Set a schedule                                                                                    | [CLI](scheduled-tasks.md), [Desktop](../16-Mobile-Desktop/desktop-scheduled-tasks.md), or [cloud](web-scheduled-tasks.md) | Pick a frequency                                                                                                                                                     | Recurring automation like daily reviews                       |


[​](#mobile-push-notifications)

Mobile push notifications

When Remote Control is active, Claude can send push notifications to your phone. Claude decides when to push. It typically sends one when a long-running task finishes or when it needs a decision from you to continue. You can also request a push in your prompt, for example `notify me when the tests finish`. Beyond the two on/off toggles below, there is no per-event configuration. To set up mobile push notifications:

1

Install the Claude mobile app

Download the Claude app for [iOS](https://apps.apple.com/us/app/claude-by-anthropic/id6473753684) or [Android](https://play.google.com/store/apps/details?id=com.anthropic.claude).

2

Sign in with your Claude Code account

Use the same account and organization you use for Claude Code in the terminal.

3

Allow notifications

Accept the notification permission prompt from the operating system.

4

Enable push in Claude Code

In your terminal, run `/config` and enable **Push when Claude decides** for proactive notifications, **Push when actions required** for permission prompts and questions, or both.

If notifications don’t arrive:

- If `/config` shows **No mobile registered**, open the Claude app on your phone so it can refresh its push token. The warning clears the next time Remote Control connects.
- On iOS, Focus modes and notification summaries can suppress or delay pushes. Check Settings → Notifications → Claude.
- On Android, aggressive battery optimization can delay delivery. Exempt the Claude app from battery optimization in system settings.

Claude Code skips mobile push notifications while you are typing in or focused on the connected terminal. To extend this to any time you are at the machine, even in another window, set [`CLAUDE_CLIENT_PRESENCE_FILE`](env-vars.md) to a marker file path: notifications are skipped while the file exists. Configure a screen-lock listener or similar tool to create the file when your screen unlocks and delete it when your screen locks.


[​](#limitations)

Limitations

- **One remote session per interactive process**: outside of server mode, each Claude Code instance supports one remote session at a time. Use [server mode](#start-a-remote-control-session) to run multiple concurrent sessions from a single process.
- **Local process must keep running**: Remote Control runs as a local process. If you close the terminal, quit the Desktop app or VS Code that runs the session on your machine, or otherwise stop the `claude` process, the session goes offline until you [bring it back](#resume-sessions-after-stopping-the-server). If you run `claude` from a terminal on a remote machine, start it inside `tmux` or `screen` to keep the session running after you disconnect from SSH.
- **Crashed sessions in server mode**: if a session served by `claude remote-control` crashes, send it a message from a connected device. Claude Code serves it again. You don’t have to restart the server. Requires Claude Code v2.1.238 or later.
- **HTTP 403 refusals on a connected session**: once an interactive session is connected, Claude Code keeps retrying for up to three minutes when something between your machine and Anthropic’s servers answers with HTTP 403, as can happen after a VPN or network change. If the refusals last longer, Claude Code disconnects, and the reason names what refused: a network edge, or a proxy, VPN, or firewall on your own network.
- **Extended network outage**: if your machine is awake but can’t reach the network, what you do next depends on the mode:
  - **Server mode**: Claude Code gives up after roughly 10 minutes and the `claude remote-control` process exits. Run `claude remote-control` again to start a new session.
  - **Interactive session**: keep working locally. Claude Code retries for as long as the outage lasts and reconnects on its own when the network returns.
- **Attachments that don’t download**: if a file you attach from your phone or browser can’t be downloaded to your machine, Claude still receives your message and the files that were downloaded. In place of the missing files, Claude Code adds a note such as `[1 of 3 attachments did not arrive]` to the message.
- **Presence heartbeats failing**: if an interactive session disconnects with `could not reach the Remote Control server for about 30 minutes`, run `/remote-control` to reconnect.
- **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`](settings-reference.md#dialogexpiry) to adjust or disable the deadline. Requires Claude Code v2.1.224 or later.
- **The Fable usage-credits consent prompt isn’t forwarded**: Claude Code shows the mid-session [Fable usage-credits consent prompt](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](errors.md#the-prompt-to-confirm-went-unanswered).
- **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](../08-Plugins-Skills/skills.md#work-on-claude-api-projects) there. The following work from mobile and web:
  - 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.
  - `/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.
  - `/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](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) instead of returning the summary. The `reconnect`, `enable`, and `disable` [subcommands](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).
  - `/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 the Claude Code section of your settings instead.
  - On Team and Enterprise, `/usage-credits` from mobile or web doesn’t send a [usage-credits request to your admin](../17-Billing-Plans/costs.md#add-usage-credits-to-your-subscription). Sending requires a confirmation that appears only in the interactive CLI, so the command tells you to run it there instead.
  - `/autocompact`, from v2.1.221: pass the window size as an argument, for example `/autocompact 500k`. With no argument, it prints the current window size as text instead of opening the dialog the command shows in a terminal session.
  - `/advisor`, from v2.1.260: pass the model as an argument, for example `/advisor opus`, or pass `off` to turn the advisor off. Both forms apply to the current session only and leave your saved default unchanged. With no argument, it prints the current advisor as text instead of opening the picker.
  - `/output-style`, from v2.1.269: pass the style name as an argument, for example `/output-style concise`, or run it with no argument to list the styles. From mobile and web, you can list and select only [built-in styles](output-styles.md#built-in-output-styles). To use a [custom style](output-styles.md#create-a-custom-output-style), select it in the session itself.
  - `/focus`, from v2.1.281: pass `on` or `off` as an argument, for example `/focus on`, or run it with no argument to toggle the [focus view](commands.md#all-commands). Both forms apply to the current session only and leave your saved selection unchanged.


[​](#authorize-a-connector-again-from-your-shell)

Authorize a connector again from your shell

When a claude.ai connector needs authentication in a session you drive over Remote Control, the `/mcp` panel isn’t available from the mobile app or the web. Get the authorization link from a terminal on the machine where the session runs, then open the link on the device you’re using. You can’t run the command from the mobile app or the web. A line you send from there that starts with `!` goes to Claude as a message and doesn’t run in [shell mode](interactive-mode.md#shell-mode-with-prefix).

1

Get the authorization link

In a terminal on the machine where the session runs, such as over SSH, run `claude mcp login` with the connector’s name in quotes. A connector’s name starts with `claude.ai`, such as `claude.ai Slack` for the Slack connector. The following command gets the link for the Slack connector:

```python
claude mcp login "claude.ai Slack" --no-browser
```

The command prints a claude.ai link and exits. Open the link in your browser and finish authorizing on claude.ai. `--no-browser` keeps the command from opening a browser on that machine, which might not be the device you’re using.

2

Use the connector in a session

Start a new session, or reconnect the connector in the session that’s already running:

- **New session**: a session you start after authorizing connects to the connector without any further step.
- **Running session**: run `/mcp reconnect` with the same name and no quotes, at the Claude Code prompt or from the mobile app or the web. To check that your session accepts the command from there, see the `/mcp` entry under [which commands work from mobile and web](#limitations).

The following command reconnects the Slack connector:

```python
/mcp reconnect claude.ai Slack
```

In the terminal, Claude Code prints `Successfully reconnected to claude.ai Slack`. From the mobile app or the web, the reply is `Reconnected "claude.ai Slack".`


[​](#troubleshooting)

Troubleshooting


[​](#”remote-control-requires-a-claude-ai-subscription”)

”Remote Control requires a claude.ai subscription”

You’re not signed in with a claude.ai account, or another credential is taking precedence over your login. The message takes one of these forms:

- Signed out, from `/remote-control` or `--remote-control`: `Remote Control requires a claude.ai subscription.` or `/remote-control requires a claude.ai subscription.`
- Signed out, from `claude remote-control`: `You must be logged in to use Remote Control. Remote Control is only available with claude.ai subscriptions.`
- Signed in, but an API key or token is in use: `Remote Control requires claude.ai subscription auth.` followed by the credential in use, such as `ANTHROPIC_API_KEY is set, so this session is using API-key auth`. An `apiKeyHelper` setting and `ANTHROPIC_AUTH_TOKEN` are named the same way.

Run `claude auth login` and choose the claude.ai option. If the message names `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`, remove it wherever it’s set: your shell environment or the `env` block of a [settings file](settings-reference.md#env). If it names `apiKeyHelper`, remove that setting.


[​](#”remote-control-requires-a-full-scope-login-token”)

”Remote Control requires a full-scope login token”

You’re authenticated with a long-lived token from `claude setup-token` or the `CLAUDE_CODE_OAUTH_TOKEN` environment variable. These tokens can only make model requests, so they can’t establish Remote Control sessions. Run `claude auth login` to authenticate with a full-scope session token instead.


[​](#”unable-to-determine-your-organization-for-remote-control-eligibility”)

”Unable to determine your organization for Remote Control eligibility”

Your cached account information is stale or incomplete. Run `claude auth login` to refresh it.


[​](#”remote-control-isn’t-enabled-for-this-account”)

”Remote Control isn’t enabled for this account”

Claude Code checked Remote Control availability for the account you’re signed in with and the check came back off. The usual cause is cached entitlements that are out of date after a plan change. Run `claude auth logout` then `claude auth login` to refresh them, and update Claude Code if you’re on an old version. Run `claude doctor` to see which individual eligibility check failed. Environment-variable conflicts, unreachable checks, and your organization’s Remote Control setting each produce their own message, so this error means the account-level check itself. Before v2.1.239, this message read “Remote Control is not yet enabled for your account”.


[​](#”couldn’t-verify-remote-control-eligibility”)

”Couldn’t verify Remote Control eligibility”

Claude Code could not reach the feature-flag service to check whether Remote Control is enabled for your account, typically because you are offline or a proxy is blocking the request. Retry once you have network access, or run `claude doctor` for details. The related message “Couldn’t verify your organization’s Remote Control policy” means Claude Code hit an error reading that policy, and has the same fix.


[​](#”remote-control-requires-feature-flag-evaluation”)

”Remote Control requires feature-flag evaluation”

An [environment variable](env-vars.md#features-that-need-feature-flag-fetching) that turns off feature-flag evaluation is set, and the full message names the variable Claude Code found. On versions before 2.1.154, the same configuration produces “Remote Control is not yet enabled for your account” instead. What to do depends on the variable the message names:

- **`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` or `DISABLE_GROWTHBOOK`**: unset the variable wherever it’s set, in your shell environment or in the `env` block of a [`settings.json` file](settings-reference.md#all-settings).
- **`DISABLE_TELEMETRY` or `DO_NOT_TRACK`**: on a Pro, Max, Team, or Enterprise plan with `DISABLE_GROWTHBOOK` unset, these variables leave Remote Control available unless your organization requires [Trusted Devices](#trusted-devices). If it does, unset the variable wherever it’s set to use Remote Control. On v2.1.154 through v2.1.282, you see this message with either variable set, so update Claude Code to a version that meets the [requirement for these variables](#requirements).


[​](#”remote-control-is-only-available-when-using-claude-via-api-anthropic-com”)

”Remote Control is only available when using Claude via api.anthropic.com”

The session isn’t talking to the Anthropic API directly, which Remote Control requires. This happens on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry. It also happens when [`ANTHROPIC_BASE_URL`](env-vars.md) points at a host other than `api.anthropic.com`, such as an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) or proxy, even if you sign in with claude.ai. See the [error reference](errors.md#remote-control-requires-the-anthropic-api) for the full cause list. The message names what routed the session away from the Anthropic API, such as `CLAUDE_CODE_USE_BEDROCK` or a custom `ANTHROPIC_BASE_URL`. If you have an eligible claude.ai login, unset the named variable, remove it from the `env` key in [settings](settings.md) if you set it there, and restart the session.


[​](#remote-control-is-disabled-by-your-organizations-policy)

“Remote Control is disabled by your organization’s policy”

A policy blocks Remote Control. Check these causes in order:

- **The error mentions `disableRemoteControl`**: your IT administrator has disabled Remote Control on this device through [managed settings](../13-Enterprise-Admin/managed-settings.md), independent of the organization-wide toggle and of how you’re signed in.
- **Your claude.ai plan is Pro or Max**: Claude Code is still signed in under a Team or Enterprise organization from an earlier login, so it checks that organization’s Remote Control policy. Run `/status` to see which plan and organization your sign-in uses. Run `claude auth logout` then `claude auth login` to sign in again under your current plan.
- **The message doesn’t say to contact your organization admin**: your organization has the [HIPAA configuration](hipaa-setup.md) applied, which turns Remote Control off. To confirm, run `/status` and look for `HIPAA` on the `Organization configuration` line. An Owner sees the **Remote Control** toggle grayed out in [admin settings](https://claude.ai/admin-settings/claude-code) and can’t turn it on. If you have questions about the configuration, ask an Owner, who can contact your organization’s Anthropic account team. Before v2.1.267, this case showed “Remote Control isn’t available for your organization due to its compliance policy” instead.
- **Remote Control works for others in your organization but not for you**: if your Enterprise organization manages your access with [custom roles](https://support.claude.com/en/articles/13930452), your roles can be the cause. Remote Control needs both the cloud sessions permission and the **Claude Code remote control** permission. Ask an Owner to check whether your roles include both and add what’s missing at [**Organization settings \> Roles**](https://claude.ai/admin-settings/roles).
- **Otherwise, an Owner hasn’t enabled it for your organization**: Remote Control is off by default on Team and Enterprise plans. An Owner can enable it at [claude.ai/admin-settings/claude-code](https://claude.ai/admin-settings/claude-code) by turning on the **Remote Control** toggle. This toggle is a server-side organization setting.

Before v2.1.281, this message also appeared when Claude Code hadn’t loaded your organization’s policy on this machine, for example after starting offline. Later versions report that state as [`Couldn't verify your organization's policy for remote control`](#couldnt-verify-your-organizations-policy-for-remote-control) instead.


[​](#remote-control-was-turned-off-by-your-organizations-policy)

“Remote Control was turned off by your organization’s policy”

Your organization’s policy stopped allowing Remote Control while a session was connected, so Claude Code disconnected it. What happens to the session depends on how you started Remote Control:

- **With `/remote-control`, `claude --remote-control`, or [auto-connect](#enable-remote-control-for-all-sessions)**: the session keeps running without Remote Control, and Claude Code archives it at claude.ai
- **With `claude remote-control`**: the server stops and archives the sessions it was serving, then exits

You can still find an archived session by [filtering for archived sessions](claude-code-on-the-web.md#archive-sessions). Remote Control doesn’t reconnect on its own. To turn it back on after your organization allows it again, run `/remote-control` in the session or `claude remote-control` in your shell. Either command fails with [`Remote Control is disabled by your organization's policy`](#remote-control-is-disabled-by-your-organizations-policy) until Claude Code on this machine has fetched the changed policy. An open session fetches it about once an hour. To find out what is blocking Remote Control, match the full text the command prints against that entry.


[​](#couldnt-verify-your-organizations-policy-for-remote-control)

“Couldn’t verify your organization’s policy for remote control”

Claude Code couldn’t fetch your organization’s policy and has no saved copy on this machine to use instead, so it keeps Remote Control off until it can confirm that your organization allows it. This usually happens when you start Claude Code offline or before a VPN connects, or when a proxy interferes with the request. On a slow connection it can also appear while the first request is still in flight. The message takes one of these forms:

- From `/remote-control`, `claude remote-control`, or `claude --remote-control`: `Couldn't verify your organization's policy for remote control. Check your network connection and try again.`
- From [auto-connect](#enable-remote-control-for-all-sessions) when a session starts: `couldn't verify your organization's policy — check your network connection and try again`, prefixed with `Remote Control failed` in the notification and `Remote Control disconnected` in the conversation. The session then leaves Remote Control off.

Restore your network connection, then run `/remote-control` or run the command again. Each attempt checks for the policy again, so you don’t need to restart Claude Code. If the message keeps appearing, run `claude doctor` and read its `Organization policy` line, which says why the policy didn’t load. Before v2.1.281, this state showed `Remote Control is disabled by your organization's policy` instead.


[​](#”remote-credentials-fetch-failed”)

”Remote credentials fetch failed”

Claude Code could not obtain a short-lived credential from the Anthropic API to establish the connection. Re-run with `--verbose` to see the full error:

```python
claude remote-control --verbose
```

Common causes:

- Not signed in: run `claude` and use `/login` to authenticate with your claude.ai account. API key authentication is not supported for Remote Control.
- Network or proxy issue: a firewall or proxy may be blocking the outbound HTTPS request. Remote Control requires access to the Anthropic API on port 443.
- Session creation failed: if you also see `Session creation failed — see debug log`, the failure happened earlier in setup. Check that your subscription is active.


[​](#couldnt-reconnect-to-your-remote-control-session)

“Couldn’t reconnect to your Remote Control session”

When you resume a conversation with `claude --resume` or `claude --continue`, Claude Code reconnects to the Remote Control session recorded in that conversation. This message means the reconnection failed for a reason that may be temporary, such as a network interruption or a server error, so Claude Code can’t confirm whether the remote session still exists. Run `/remote-control` to retry the connection, or start a new session with `claude --remote-control` to create a new Remote Control session. Your local session keeps running without Remote Control in the meantime.


[​](#previous-session-is-unavailable)

“Previous session is unavailable — run /remote-control to start a new one”

Claude Code couldn’t bring back the previous Remote Control session and stopped instead of starting a new one on its own. You can see this message after you resume a conversation with `claude --resume` or `claude --continue`, or after Claude Code [reconnects on its own following a disconnect](errors.md#remote-control-couldnt-refresh-your-login). Run `/remote-control` to start a new Remote Control session under the current login; your local session keeps running without Remote Control in the meantime. The related message `Remote Control could not verify the signed-in account — run /remote-control to reconnect` has the same fix. If you run `/remote-control` after `Previous session is unavailable` without restarting Claude Code first, Claude Code leaves the conversation’s earlier messages out of the new session.


[​](#”remote-control-got-an-unexpected-server-response”)

”Remote Control got an unexpected server response”

The Remote Control server accepted a request but replied in a form this version of Claude Code couldn’t read, while creating the remote session or fetching its credentials. Retrying on the same version fails the same way. Run `claude update`, then run `/remote-control` to reconnect.


[​](#”your-organization-requires-trusted-devices-for-remote-control-but-this-device-is-not-enrolled”)

”Your organization requires Trusted Devices for Remote Control, but this device is not enrolled”

Your organization has [Trusted Devices](#trusted-devices) enabled and this machine has not enrolled yet. Run `/login` in Claude Code. Enrollment happens as part of sign-in, and there is no separate enrollment command.


[​](#”session-expired-for-trusted-device-check”)

”session expired for trusted-device check”

Your sign-in is more than 18 hours old. Run `/login` in Claude Code, or confirm with Face ID, Touch ID, Windows Hello, or a passkey when claude.ai or the mobile app prompts you. See [Trusted Devices](#trusted-devices).


[​](#related-resources)

Related resources

- [Use Claude Code in the cloud](claude-code-on-the-web.md): run sessions in the cloud instead of your machine, configured through [cloud environments](cloud-environments.md)
- [Cross-session messaging](cross-session-messaging.md): let Claude message your sessions on other machines or your [cloud sessions](claude-code-on-the-web.md)
- [Channels](channels.md): forward Telegram, Discord, or iMessage into a session so Claude reacts to messages while you’re away
- [Dispatch](../16-Mobile-Desktop/desktop.md#sessions-from-dispatch): message a task from your phone and it can spawn a Desktop session to handle it
- [Authentication](authentication.md): set up `/login` and manage credentials for claude.ai
- [CLI reference](cli-reference.md): full list of flags and commands including `claude remote-control`
- [Security](../13-Enterprise-Admin/security.md): how Remote Control sessions fit into the Claude Code security model
- [Data usage](../13-Enterprise-Admin/data-usage.md): what data flows through the Anthropic API during local, Remote Control, and cloud sessions

---

## Using Claude Code Remote Control · Claude Academy

Source: https://www.claude.com/resources/tutorials/using-claude-code-remote-control
Path: 02-Claude-Code-CLI/resources-tutorials-using-claude-code-remote-control.md

# Using Claude Code Remote Control

Learn more about using Claude Code remote control to access Claude Code sessions on the go.

---

## Choose a sandbox environment - Claude Code Docs

Source: https://code.claude.com/docs/en/sandbox-environments
Path: 02-Claude-Code-CLI/sandbox-environments.md

## On this page

- [Compare sandboxing approaches](#compare-sandboxing-approaches)
- [Choose an approach](#choose-an-approach)
  - [How isolation relates to permission modes](#how-isolation-relates-to-permission-modes)
- [Sandboxed Bash tool](#sandboxed-bash-tool)
- [Sandbox runtime](#sandbox-runtime)
  - [Set up and launch the runtime](#set-up-and-launch-the-runtime)
  - [What the runtime blocks on its own](#what-the-runtime-blocks-on-its-own)
  - [After unattended runs](#after-unattended-runs)
- [Dev containers](#dev-containers)
- [Custom container](#custom-container)
- [Virtual machine](#virtual-machine)
- [Cloud sessions](#cloud-sessions)
- [Enforce isolation across an organization](#enforce-isolation-across-an-organization)
- [See also](#see-also)

Permissions and sandboxing

# Choose a sandbox environment

Copy pageCopy page

Compare Claude Code sandbox options: the built-in sandboxed Bash tool, sandbox runtime, dev containers, Docker, and VMs. Choose the right isolation for your threat model.

Copy pageCopy page

Isolating Claude Code limits what a session can read, write, and reach on the network. This matters most when you let Claude work with fewer permission prompts, run it unattended, or point it at code you do not fully trust. Claude Code can run in several kinds of isolated environments, ranging from a lightweight per-command sandbox to a fully separate virtual machine. This page compares them by what they isolate and what they require, helps you choose one for your threat model, and shows how to enforce that choice across an organization.

For the broader security model, see [Security](../13-Enterprise-Admin/security.md). For Agent SDK deployments, see [Secure deployment](../05-Agent-SDK/agent-sdk-secure-deployment.md).


[​](#compare-sandboxing-approaches)

Compare sandboxing approaches

The first two approaches in the table below run on the host operating system without containers. The rest place Claude Code inside a container or virtual machine.

| Approach                                    | What is isolated                                                            | Requires Docker | Setup effort                                                                                                 |
|:--------------------------------------------|:----------------------------------------------------------------------------|:----------------|:-------------------------------------------------------------------------------------------------------------|
| [Sandboxed Bash tool](#sandboxed-bash-tool) | Bash, PowerShell, and Monitor tool commands and their child processes       | No              | Minimal on macOS; low on Linux and WSL2                                                                      |
| [Sandbox runtime](#sandbox-runtime)         | The whole Claude Code process, including file tools, MCP servers, and hooks | No              | Low                                                                                                          |
| [Dev container](#dev-containers)            | Full development environment                                                | Yes             | Medium                                                                                                       |
| [Custom container](#custom-container)       | Full development environment                                                | Yes             | Medium to high                                                                                               |
| [Virtual machine](#virtual-machine)         | Full operating system                                                       | No              | High                                                                                                         |
| [Cloud sessions](#cloud-sessions)           | Full operating system, hosted by Anthropic                                  | No              | None; requires a Claude subscription, and a connected GitHub account unless you launch with `claude --cloud` |

The [sandboxed Bash tool](sandboxing.md) is built into Claude Code and restricts Bash commands. Built-in file tools, MCP servers, and hooks still run directly on your host. Every other approach in the table puts the whole Claude Code process inside the isolation boundary, so file tools, MCP servers, and hooks are restricted too.

Sandbox isolation reduces the impact of a breach, but it does not eliminate risk. Any approach that allows network egress can still leak data the agent can read, and any approach that mounts your project directory writable can still modify that code. Review the [security limitations](sandboxing.md#security-limitations) before relying on a sandbox as a hard control.Isolation also does not change what is sent to the model. Your prompts and the files Claude reads are transmitted to the Anthropic API or your configured provider with or without a sandbox. See [Data usage](../13-Enterprise-Admin/data-usage.md) for what Claude Code sends and how to reduce it.


[​](#choose-an-approach)

Choose an approach

Match your goal to a row below, then read the detail section that follows.

| You want to                                                                   | Start with                                                                                                                                                                         |
|:------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Reduce permission prompts during everyday work on your own machine            | The [sandboxed Bash tool](sandboxing.md), configured with `/sandbox`                                                                                                         |
| Let Claude work unattended with `--dangerously-skip-permissions` or auto mode | The preconfigured [dev container](devcontainer.md), any container or VM, or the [sandbox runtime](#sandbox-runtime)                                                          |
| Isolate MCP servers and hooks as well as Bash, without Docker                 | The sandbox runtime                                                                                                                                                                |
| Work on an untrusted repository                                               | A dedicated virtual machine, or a [cloud session](claude-code-on-the-web.md) if you have a Claude subscription; GitHub is not required when you launch with `claude --cloud` |
| Standardize a sandboxed environment across a team                             | The preconfigured [dev container](devcontainer.md), copied into your repository                                                                                              |
| Use Claude Code from a device with no local setup                             | A [cloud session](claude-code-on-the-web.md), which requires a Claude subscription and a connected GitHub account                                                            |
| Require isolation for every developer in your organization                    | [Enforce isolation across an organization](#enforce-isolation-across-an-organization)                                                                                              |
| Work on a native Windows host                                                 | A container or VM, or run the Bash sandbox inside WSL2                                                                                                                             |


[​](#how-isolation-relates-to-permission-modes)

How isolation relates to permission modes

[Permission modes](permission-modes.md) decide whether a tool call runs and whether you are prompted first. Isolation restricts what a command can access once it runs. The two work together: when a permission mode lets actions run without asking you, an isolation boundary limits what those actions can reach. When you pass `--dangerously-skip-permissions`, Claude acts without asking you first. The [actions no mode auto-approves](permission-modes.md#actions-no-mode-auto-approves) still apply. With no prompts to catch mistakes, the isolation boundary you choose is what protects your system. Always run `--dangerously-skip-permissions` sessions inside a container, a VM, or the [sandbox runtime](#sandbox-runtime), so that file tools, MCP servers, and hooks are also inside the boundary. On Linux and macOS, Claude Code refuses to start with this flag when running as root, so run the container, VM, or sandbox runtime as a non-root user. [Auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) replaces the prompt with a classifier that reviews actions. The classifier is a per-action control, not an isolation boundary, so an isolation boundary still adds defense in depth for unattended runs, and is not required the way it is for `--dangerously-skip-permissions`. The [sandboxed Bash tool](#sandboxed-bash-tool) on its own constrains only shell commands, so it is not sufficient for fully unattended runs in either mode. You can layer approaches: running the sandboxed Bash tool inside a container or VM gives you OS-level command restrictions on top of the outer environment boundary. For how the Bash sandbox itself interacts with permission rules and modes, see [How sandboxing relates to permissions and permission modes](sandboxing.md#how-sandboxing-relates-to-permissions-and-permission-modes).


[​](#sandboxed-bash-tool)

Sandboxed Bash tool

This option does not support native Windows. On Windows hosts, use WSL2 or one of the container or VM approaches below.

The sandboxed Bash tool is built into Claude Code. It uses operating system primitives to restrict the filesystem and network access of Bash, PowerShell, and Monitor tool commands Claude runs. Run the `/sandbox` command to open the sandbox panel and choose a mode. The [Sandboxing](sandboxing.md) guide covers the approval modes, the default boundary, and how to widen or narrow it. The per-command sandbox does not cover everything that runs in a session:

- Other [built-in tools](tools-reference.md) such as Read, Edit, and WebFetch run inside the Claude Code process and do not spawn arbitrary code. [Permission rules](permissions.md) for path or domain gate them instead.
- [MCP](../06-MCP-Tools/General/mcp.md) servers, [command hooks](../07-Hooks/hooks.md#command-hook-fields), and [plugin monitors](../08-Plugins-Skills/plugins-components.md#monitors) are separate processes that run unconstrained on the host. For other processes that run this way, see [What runs outside the sandbox](sandboxing.md#what-runs-outside-the-sandbox).

To put built-in tools, MCP servers, and hooks all behind one OS boundary, run the whole Claude Code process inside the [sandbox runtime](#sandbox-runtime), the [dev container](#dev-containers), or a [custom container](#custom-container).


[​](#sandbox-runtime)

Sandbox runtime

The [`@anthropic-ai/sandbox-runtime`](https://github.com/anthropics/sandbox-runtime) package wraps an entire process in the same Seatbelt or bubblewrap isolation that the built-in Bash sandbox uses. Running Claude Code through the runtime constrains the session’s tools, hooks, and MCP servers as well as shell commands. The runtime is a beta research preview, and its configuration format may change as the package evolves. This section covers what you configure and what the runtime enforces on its own. For deploying the runtime in Agent SDK applications, see the [secure deployment guide](../05-Agent-SDK/agent-sdk-secure-deployment.md#sandbox-runtime).


[​](#set-up-and-launch-the-runtime)

Set up and launch the runtime

On Linux and WSL2, the runtime relies on the same `bubblewrap` and `socat` packages as the built-in sandbox, plus `ripgrep`, which Claude Code bundles but the standalone runtime resolves from your PATH. Install `bubblewrap` and `socat` as described in [Set up Linux and WSL2](sandboxing.md#set-up-linux-and-wsl2), and `ripgrep` from your distribution’s package manager. On macOS you need no additional packages. The runtime uses the built-in Seatbelt sandbox there. By default the runtime denies network access and confines writes to a small set of built-in runtime paths, so configure it before launching Claude Code through it. Put your configuration in `~/.srt-settings.json`, or in a file you pass with `--settings`. The package [README](https://github.com/anthropics/sandbox-runtime) documents the configuration schema. Allow write access to at least:

- Your project directory.
- Claude Code’s configuration paths `~/.claude` and `~/.claude.json`.
- The directory where Claude Code writes runtime files. Unless you set [`CLAUDE_CODE_TMPDIR`](env-vars.md), that directory is:
  - **Linux and WSL2**: `/tmp`
  - **macOS**: `/private/tmp`. `/tmp` is a symlink to that directory, and Seatbelt checks the resolved path.

Allow the network domains your session needs:

- `api.anthropic.com`, or your configured provider’s endpoint. On a third-party provider, keep `api.anthropic.com` as well: the WebFetch domain safety check still calls it by default unless you set `skipWebFetchPreflight: true`.
- `claude.ai` and `platform.claude.com`, which [OAuth sign-in and token refresh](../13-Enterprise-Admin/network-config.md#network-access-requirements) require. Runs authenticated with an API key can drop these two.

On Linux and WSL2, the runtime applies write grants only to paths that already exist. In a fresh environment, create Claude Code’s configuration paths before the first launch:

```python
mkdir -p ~/.claude && { [ -f ~/.claude.json ] || echo '{}' > ~/.claude.json; }
```

Install the runtime globally, under a prefix outside every path you allow writes to:

```python
npm install -g @anthropic-ai/sandbox-runtime
```

Once the settings file is in place, launch Claude Code through the runtime from your project directory:

```python
srt claude
```

Claude Code starts inside the sandbox with the filesystem and network boundaries you configured. The same `srt` command works for sandboxing standalone MCP servers or other helper processes.


[​](#what-the-runtime-blocks-on-its-own)

What the runtime blocks on its own

The runtime blocks the highest-risk writes without any configuration from you:

- `denyWrite` takes precedence over `allowWrite`.
- At the project root, the runtime denies `.git/hooks`, denies `.git/config` unless you set `filesystem.allowGitConfig: true`, and denies `.mcp.json`, `.claude/commands`, `.claude/agents`, and shell startup files.
- On macOS, these denies are checked when a write happens, so they also cover nested files and repositories created during the session.
- On Linux and WSL2, the runtime builds the deny list once at launch. It reliably covers the project root, makes a best-effort shallow scan for nested copies that exist at that point, and does not cover anything the session creates later, such as `git init`, `git clone`, or scaffolding. The README’s `mandatoryDenySearchDepth` section describes the scan’s exact semantics.
- If `~/.srt-settings.json` doesn’t exist and you don’t pass `--settings`, the runtime starts anyway. It blocks network access and confines writes to built-in runtime paths such as `/tmp/claude`, `~/.npm/_logs`, and `~/.claude/debug`. Don’t take a clean start as proof your settings loaded.
- If the settings file exists but is empty, unreadable, or invalid, the runtime refuses to start, whether it’s `~/.srt-settings.json` or a file you pass with `--settings`. It also refuses to start if the `--settings` file doesn’t exist.

Your write grants still include other paths Claude Code loads configuration from, so deny those with `denyWrite`. A sandboxed session that can write them can persist hooks, permission rules, or MCP servers that run unsandboxed the next time you launch Claude Code.


[​](#after-unattended-runs)

After unattended runs

Review the paths you kept writable. On Linux and WSL2, also review anything the session created.


[​](#dev-containers)

Dev containers

A dev container runs Claude Code inside a Docker container that VS Code or a compatible editor manages, with your project mounted in. You can define your own with a `.devcontainer/` directory in your repository. The claude-code repository publishes an [example dev container](devcontainer.md) with a default-deny iptables firewall as a starting point. Copy it into your repository and adjust the firewall allowlist, base image, and pinned Claude Code version to fit your environment. Because the firewall blocks unapproved egress, a configuration like this supports running Claude Code with `--dangerously-skip-permissions` for unattended work.


[​](#custom-container)

Custom container

You can run Claude Code in any Docker or OCI container image with your own network policies, mounted volumes, and seccomp profiles. This is the most common path for organizations with existing container infrastructure or CI runners. Several managed sandbox and remote execution services can host the container for you. The same checklist applies as for any container you operate: review what is mounted writable, what credentials and tokens are reachable inside it, and what the network egress policy allows. You can layer the built-in Bash sandbox inside the container for per-command restrictions. Unprivileged containers need `enableWeakerNestedSandbox`, described in [Bubblewrap fails to start inside a container](sandboxing.md#bubblewrap-fails-to-start-inside-a-container).


[​](#virtual-machine)

Virtual machine

A dedicated virtual machine provides the strongest separation, with its own kernel and, in cloud or microVM deployments, its own virtualized hardware. Options include cloud instances, local hypervisors, and microVMs such as Firecracker. Use this approach when you are evaluating untrusted code, when your security policy requires kernel-level separation between the agent and the host, or when no host-level approach meets your compliance requirements. [Docker Sandboxes](https://docs.docker.com/ai/sandboxes/) provides a microVM with its own Docker daemon and workspace sync, which can run Claude Code on any host with Docker Sandboxes installed. It is a free, standalone product from Docker that does not require Docker Desktop.


[​](#cloud-sessions)

Cloud sessions

A [cloud session](claude-code-on-the-web.md) runs in an isolated, Anthropic-managed virtual machine. A network proxy enforces a default allowlist, and a separate proxy holds your GitHub token outside the sandbox while issuing scoped credentials for repository access inside it. Sessions your organization routes to a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) run on infrastructure you provision instead, where isolation, egress control, and git credentials are your deployment’s responsibility. Use this approach when you want full VM isolation without provisioning infrastructure yourself, or when you are delegating tasks from a device that does not have a local development environment. It requires a Claude subscription. Unless you launch from the CLI, you also need a connected GitHub account so the sandbox can clone your repository. When you launch from the CLI with `--cloud`, Claude Code can [bundle and upload your local repository](claude-code-on-the-web.md#send-local-repositories-without-github) instead. See [Use Claude Code in the cloud](claude-code-on-the-web.md) for plan availability and GitHub authentication options.


[​](#enforce-isolation-across-an-organization)

Enforce isolation across an organization

Individual developers can opt into any of the sandboxing approaches on this page. What an organization can enforce, and with which tools, depends on the approach:

- **Built-in Bash sandbox**: the only approach Claude Code enforces itself. Deliver the `sandbox` settings keys through [managed settings](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms), either as a file managed by your MDM or through [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) on Claude.ai. See [Enforce sandboxing with managed settings](sandboxing.md#enforce-sandboxing-with-managed-settings) for the keys to deploy and how to keep developers from widening the policy.
- **Dev containers**: commit the [example dev container](devcontainer.md) to your repositories to standardize the environment across a team. This is a convention rather than an enforcement boundary, because Claude Code does not require a container. If developers should not be able to run Claude Code outside it, enforce that with your organization’s device management or software allowlisting tools.
- **Custom containers and VMs**: distribute Claude Code through the approved image and use your organization’s device management or software allowlisting tools to prevent installation outside it.


[​](#see-also)

See also

These pages cover configuration and policy details for the sandboxing approaches on this page.

- [Sandboxing](sandboxing.md): configure the built-in sandboxed Bash tool
- [Dev container](devcontainer.md): the preconfigured Docker development container
- [Security](../13-Enterprise-Admin/security.md): the full Claude Code security model
- [Secure deployment](../05-Agent-SDK/agent-sdk-secure-deployment.md): isolation guidance for Agent SDK applications
- [Settings](settings-reference.md#sandbox-settings): all sandbox configuration keys, including managed settings delivery

---

## Configure the sandboxed Bash tool - Claude Code Docs

Source: https://code.claude.com/docs/en/sandboxing
Path: 02-Claude-Code-CLI/sandboxing.md

## On this page

- [What the sandbox restricts](#what-the-sandbox-restricts)
  - [What runs outside the sandbox](#what-runs-outside-the-sandbox)
- [Get started](#get-started)
  - [Confirm commands run inside the sandbox](#confirm-commands-run-inside-the-sandbox)
  - [Set up Linux and WSL2](#set-up-linux-and-wsl2)
  - [Sandbox modes](#sandbox-modes)
  - [Auto-allow mode](#auto-allow-mode)
  - [Regular permissions mode](#regular-permissions-mode)
  - [The unsandboxed retry escape hatch](#the-unsandboxed-retry-escape-hatch)
  - [Turn off the retry with strict sandbox mode](#turn-off-the-retry-with-strict-sandbox-mode)
  - [Temporary directories](#temporary-directories)
- [Configure sandboxing](#configure-sandboxing)
  - [Run commands outside the sandbox with excludedCommands](#run-commands-outside-the-sandbox-with-excludedcommands)
  - [Disable filesystem isolation](#disable-filesystem-isolation)
  - [Which settings can disable it](#which-settings-can-disable-it)
  - [What changes when filesystem isolation is off](#what-changes-when-filesystem-isolation-is-off)
  - [Protect credentials](#protect-credentials)
  - [Mask credentials](#mask-credentials)
  - [Mask environment variables](#mask-environment-variables)
  - [Re-sign AWS requests](#re-sign-aws-requests)
  - [Mask credential files](#mask-credential-files)
- [How sandboxing works](#how-sandboxing-works)
  - [Filesystem isolation](#filesystem-isolation)
  - [Protected paths](#protected-paths)
  - [Denied paths that pass through a symlink](#denied-paths-that-pass-through-a-symlink)
  - [Network isolation](#network-isolation)
  - [Hosts outside your allowed domains](#hosts-outside-your-allowed-domains)
  - [Hostnames that resolve to local addresses](#hostnames-that-resolve-to-local-addresses)
  - [Per-command allowed domains in auto mode](#per-command-allowed-domains-in-auto-mode)
  - [IPv6 addresses in domain lists](#ipv6-addresses-in-domain-lists)
  - [OS-level enforcement](#os-level-enforcement)
- [How sandboxing relates to permissions and permission modes](#how-sandboxing-relates-to-permissions-and-permission-modes)
  - [Permission rules](#permission-rules)
  - [Permission modes](#permission-modes)
- [Configure the sandbox for your organization](#configure-the-sandbox-for-your-organization)
  - [Enforce sandboxing with managed settings](#enforce-sandboxing-with-managed-settings)
  - [Keep developers from widening the policy](#keep-developers-from-widening-the-policy)
  - [Repository settings under an admin-required sandbox](#repository-settings-under-an-admin-required-sandbox)
  - [Locks that apply without an admin-required sandbox](#locks-that-apply-without-an-admin-required-sandbox)
  - [Custom proxy configuration](#custom-proxy-configuration)
- [Troubleshooting](#troubleshooting)
  - [Commands fail with a host-not-allowed error](#commands-fail-with-a-host-not-allowed-error)
  - [jest hangs or fails](#jest-hangs-or-fails)
  - [Go-based CLIs fail TLS verification on macOS](#go-based-clis-fail-tls-verification-on-macos)
  - [open, osascript, or browser-based auth flows fail with error -600 on macOS](#open-osascript-or-browser-based-auth-flows-fail-with-error-600-on-macos)
  - [docker commands fail](#docker-commands-fail)
  - [Chromium or rootless Podman fails inside the sandbox on Linux](#chromium-or-rootless-podman-fails-inside-the-sandbox-on-linux)
  - [pbcopy, xclip, or wl-copy doesn’t update the clipboard](#pbcopy-xclip-or-wl-copy-doesn%E2%80%99t-update-the-clipboard)
  - [A git command fails with unable to unlink old](#a-git-command-fails-with-unable-to-unlink-old)
  - [Bubblewrap fails to start inside a container](#bubblewrap-fails-to-start-inside-a-container)
  - [0-byte read-only files appear at .claude settings paths, and “Yes, and don’t ask again” doesn’t save](#0-byte-read-only-files-appear-at-claude-settings-paths-and-%E2%80%9Cyes-and-don%E2%80%99t-ask-again%E2%80%9D-doesn%E2%80%99t-save)
  - [git over SSH fails with the sandbox on](#git-over-ssh-fails-with-the-sandbox-on)
  - [A database client or other non-HTTP tool fails to reach an allowed host](#a-database-client-or-other-non-http-tool-fails-to-reach-an-allowed-host)
  - [A command fails to reach a server on localhost](#a-command-fails-to-reach-a-server-on-localhost)
  - [An allowed hostname is refused with resolved to a loopback address](#an-allowed-hostname-is-refused-with-resolved-to-a-loopback-address)
  - [/sandbox fails with Sandbox settings are overridden by a higher-priority configuration](#%2Fsandbox-fails-with-sandbox-settings-are-overridden-by-a-higher-priority-configuration)
  - [/sandbox prints Sandbox settings not changed](#%2Fsandbox-prints-sandbox-settings-not-changed)
- [Limitations](#limitations)
  - [Security limitations](#security-limitations)
  - [Scope](#scope)
- [See also](#see-also)

Permissions and sandboxing

# Configure the sandboxed Bash tool

Copy pageCopy page

Restrict the files and network hosts Claude Code’s shell commands can reach with the built-in sandbox. Turn it on, set the boundary, and fix what it breaks.

Copy pageCopy page

The Bash sandbox is a boundary that the operating system enforces around the shell commands Claude runs on your machine. You set which files and network domains those commands can reach, and the limits apply to Bash, PowerShell, and Monitor commands and the processes they start. Because the operating system applies the limits while a command runs, Claude Code can [run sandboxed commands without asking you](#sandbox-modes) to approve each one. The sandbox covers shell commands only. Claude’s file tools, MCP servers, and hooks [run outside it](#what-runs-outside-the-sandbox). The sandbox runs on macOS, Linux, and WSL2. On native Windows, Claude Code runs commands unsandboxed. To use the sandbox on a Windows machine, run Claude Code inside a WSL2 distribution.

This page covers the sandbox around shell commands on your own machine. Other pages cover related questions:

- For how a cloud session is isolated, see [Security and isolation](claude-code-on-the-web.md#security-and-isolation)
- To compare other isolation approaches such as dev containers, custom containers, and virtual machines, see [Sandbox environments](sandbox-environments.md)
- To reduce permission prompts for tools other than Bash, see [permission modes](permission-modes.md)


[​](#what-the-sandbox-restricts)

What the sandbox restricts

While the sandbox is on, the shell commands Claude runs start inside its boundary, and so do the processes they start. The sandbox is off by default. To turn it on, run `/sandbox` in a session, as [Get started](#get-started) shows, or set [`sandbox.enabled`](settings-reference.md#sandbox-enabled) to `true` in a [settings file](settings.md) such as `~/.claude/settings.json`. The table shows what a sandboxed command can reach by default and the settings that change each default.

| Access                | Default                                                                                                                                                                                                                                    | Change it with                                                                                                                                                               |
|:----------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Writes                | The working directory, a per-user temp directory, and [directories you’ve added](permissions.md#additional-directories-grant-file-access-not-configuration). [Protected paths](#protected-paths) stay write-denied                   | [`filesystem.allowWrite`](settings-reference.md#sandbox-filesystem-allowwrite), [`filesystem.denyWrite`](settings-reference.md#sandbox-filesystem-denywrite)     |
| Reads                 | Most of the machine, including credential files such as `~/.ssh` and `~/.aws/credentials`                                                                                                                                                  | [`filesystem.denyRead`](settings-reference.md#sandbox-filesystem-denyread), [`credentials`](#protect-credentials)                                                      |
| Network               | No direct route out. Connections go through a proxy on your machine that checks each host against your allowed domains, which start empty. Your permission mode decides [what happens to other hosts](#hosts-outside-your-allowed-domains) | [`network.allowedDomains`](settings-reference.md#sandbox-network-alloweddomains), [`network.deniedDomains`](settings-reference.md#sandbox-network-denieddomains) |
| Environment variables | Inherited from Claude Code, including any secrets in its environment                                                                                                                                                                       | [`credentials`](#protect-credentials), [`CLAUDE_CODE_SUBPROCESS_ENV_SCRUB`](env-vars.md)                                                                               |

Claude Code builds the sandbox on the open source [`@anthropic-ai/sandbox-runtime`](https://github.com/anthropics/sandbox-runtime) package.


[​](#what-runs-outside-the-sandbox)

What runs outside the sandbox

The sandbox wraps shell commands. These tools and processes run outside it:

- **Built-in file and web tools**: tools such as Read, Edit, Write, WebFetch, and WebSearch follow [permission rules](permissions.md) instead. A `denyRead` entry doesn’t stop the Read tool, and `allowedDomains` doesn’t limit WebFetch
- **Other processes Claude Code starts**: command [hooks](../07-Hooks/hooks.md), local [MCP servers](../06-MCP-Tools/General/mcp.md), [plugin monitors](../08-Plugins-Skills/plugins-components.md#monitors), [LSP servers](tools-reference.md#lsp-tool-behavior), and helper commands such as your [status line](statusline.md) command and `apiKeyHelper` run with your full access

Some shell commands also run outside the sandbox, depending on your settings:

- **Commands you type yourself**: a command you enter at the [`!` shell-mode prompt](interactive-mode.md#shell-mode-with-prefix) runs unsandboxed in most sessions. [Strict sandbox mode](#turn-off-the-retry-with-strict-sandbox-mode) lists the sessions where a command you type runs sandboxed
- **Excluded commands**: commands that match [`excludedCommands`](#run-commands-outside-the-sandbox-with-excludedcommands) run unsandboxed
- **Unsandboxed retries**: Claude can [ask to run a command unsandboxed](#the-unsandboxed-retry-escape-hatch), usually after it fails in the sandbox

To put the tools, processes, and commands in this section behind one boundary, run the Claude Code process itself in a [container, virtual machine, or the sandbox runtime](sandbox-environments.md).


[​](#get-started)

Get started

The sandbox is built into Claude Code. What you install depends on your platform:

- **macOS**: sandboxing uses the built-in Seatbelt framework, so you can go straight to the steps
- **Linux and WSL2**: the sandbox relies on `bubblewrap` and `socat`, covered in [Set up Linux and WSL2](#set-up-linux-and-wsl2). Even if you haven’t installed them yet, you can start with `/sandbox`, because its panel shows whether anything is missing

1

Run /sandbox

Start a Claude Code session and run the `/sandbox` command:

```python
/sandbox
```

This opens the sandbox panel with three tabs, plus a Dependencies tab on Linux when the optional seccomp filter is missing:

- **Mode**: choose how sandboxed commands are approved, covered in the next step
- **Overrides**: choose whether commands that fail under the sandbox can fall back to running unsandboxed. This is the [`allowUnsandboxedCommands`](settings-reference.md#sandbox-allowunsandboxedcommands) setting
- **Config**: view the resolved sandbox settings

If the panel shows only a Dependencies tab, a required package is missing. Install it as described in [Set up Linux and WSL2](#set-up-linux-and-wsl2), restart Claude Code, and run `/sandbox` again.

2

Choose a mode

On the Mode tab, select auto-allow or regular permissions. Auto-allow runs sandboxed commands without prompting, and regular permissions keeps the regular permission prompts even when commands are sandboxed. See [Sandbox modes](#sandbox-modes) for which commands still prompt in auto-allow mode.

3

Run a Bash command

Ask Claude to run a command, such as a build or a test suite. By default, commands inside the sandbox can write to the working directory, a [per-user temp directory](env-vars.md), and any [directories you’ve added](permissions.md#additional-directories-grant-file-access-not-configuration) with `--add-dir`, `/add-dir`, or `permissions.additionalDirectories`.The first time a command needs a new network domain, Claude Code prompts for approval; in [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode), Claude instead names the hosts a command needs [on the command itself](#per-command-allowed-domains-in-auto-mode) for the classifier to review with it.To widen or narrow what the sandbox allows, see [Configure sandboxing](#configure-sandboxing).If sandboxed commands fail with `Operation not permitted` inside a container, see [Bubblewrap fails to start inside a container](#bubblewrap-fails-to-start-inside-a-container).

When you select a mode in the panel, Claude Code saves it to your project’s local settings at `.claude/settings.local.json`, which apply to the current project. Claude Code adds that file to your global gitignore when it saves a setting there. To enable the sandbox across all of your projects, set [`sandbox.enabled`](settings-reference.md#sandbox-enabled) to `true` in your user settings at `~/.claude/settings.json`. To enforce sandboxing for every developer in an organization, use [managed settings](#enforce-sandboxing-with-managed-settings). To change the sandbox for one session without writing to a settings file, start Claude Code with [`--settings`](settings.md#change-a-setting-for-one-session). For example, this command starts a sandboxed session in which Claude can’t retry a blocked command outside the sandbox:

```python
claude --settings '{"sandbox": {"enabled": true, "allowUnsandboxedCommands": false}}'
```

By default, if the sandbox can’t start because a dependency is missing or the platform is unsupported, Claude Code runs commands without sandboxing. To make Claude Code exit at startup instead, set [`sandbox.failIfUnavailable`](settings-reference.md#sandbox-failifunavailable) to `true`. Managed deployments that require sandboxing as a security gate can use this setting.


[​](#confirm-commands-run-inside-the-sandbox)

Confirm commands run inside the sandbox

To check that the sandbox is working, ask Claude to run each line in the table. What you type at the [`!` prompt](#what-runs-outside-the-sandbox) usually runs outside the sandbox, so typing a line yourself doesn’t test it.

| Command                                  | Result inside the sandbox                                                                      |
|:-----------------------------------------|:-----------------------------------------------------------------------------------------------|
| `touch ~/sandbox-probe`                  | Fails with `Operation not permitted` on macOS, or `Read-only file system` on Linux and WSL2    |
| `curl --noproxy '*' https://example.com` | Fails with `Could not resolve host`, because the command has no route around the sandbox proxy |

If Claude asks to retry a failed command outside the sandbox, decline the retry. If `touch` succeeds and your home directory isn’t one of the directories the sandbox lets commands write to, delete `~/sandbox-probe`. Then run `/sandbox` to check that the sandbox is on and its dependencies are installed.


[​](#set-up-linux-and-wsl2)

Set up Linux and WSL2

On Linux and WSL2, the sandbox relies on these packages:

- [`bubblewrap`](https://github.com/containers/bubblewrap): the unprivileged sandboxing tool that enforces filesystem isolation
- [`socat`](http://www.dest-unreach.org/socat/): the relay used to route network traffic through the sandbox proxy

Install them with your distribution’s package manager:

- Ubuntu/Debian

- Fedora

```python
sudo apt-get install bubblewrap socat
```

```python
sudo dnf install bubblewrap socat
```

When a dependency is missing, the Dependencies tab in `/sandbox` lists which of `ripgrep`, `bubblewrap`, `socat`, and the seccomp filter your platform lacks. If you don’t see the tab after installing and restarting Claude Code, all dependencies are present. Ripgrep is bundled with the native Claude Code binary. The seccomp filter is optional and adds Unix domain socket blocking. Install it with `npm install -g @anthropic-ai/sandbox-runtime` if it is missing. When a required dependency is missing, the Dependencies tab is the only tab shown until you install it. When only the optional seccomp filter is missing, the Dependencies tab appears alongside the other tabs. The dependency check runs at startup, so restart Claude Code after installing packages for `/sandbox` to detect them.

Ubuntu 24.04 and later: allow bubblewrap to create user namespaces

On Ubuntu 24.04 and later, the default AppArmor policy prevents bubblewrap from creating the user namespaces it needs for isolation.To check whether your environment enforces this restriction, including inside WSL2, run `sysctl kernel.apparmor_restrict_unprivileged_userns`. If the command returns `0`, skip this step. If it prints a `No such file or directory` error, the key doesn’t exist and you can skip this step. If it returns `1`, add an AppArmor profile that grants `bwrap` this capability:

```python
sudo tee /etc/apparmor.d/bwrap > /dev/null <<'EOF'
abi <abi/4.0>,
include <tunables/global>

profile bwrap /usr/bin/bwrap flags=(unconfined) {
  userns,
  include if exists <local/bwrap>
}
EOF
```

The profile applies only to `bwrap` itself, not to the commands it runs inside the sandbox. Reload AppArmor to apply it:

```python
sudo systemctl reload apparmor
```

WSL2 notes

Check your WSL version with `wsl -l -v` from PowerShell. If you see `Sandboxing requires WSL2`, your distribution is running WSL1. Upgrade it to WSL2 or run Claude Code without sandboxing.On WSL2, WSL hands a launch of a Windows binary such as `cmd.exe`, `powershell.exe`, or anything under `/mnt/c/` to the Windows host over a Unix socket, so whether a sandboxed command can launch one follows the sandbox’s [Unix-socket settings](settings-reference.md#sandbox-network-allowunixsockets): the optional seccomp filter has to be installed to block the socket in the first place. To allow these launches, set `allowAllUnixSockets`, which opens every Unix socket to sandboxed commands.


[​](#sandbox-modes)

Sandbox modes

Claude Code offers two sandbox modes. In both, the sandbox enforces the same filesystem and network restrictions; the difference is only in whether sandboxed commands are auto-approved or require explicit permission.


[​](#auto-allow-mode)

Auto-allow mode

Claude Code approves a command automatically, with no prompt, when the command runs inside the sandbox. A command goes through the regular [permission flow](permissions.md) when it runs outside the sandbox because it matches [`excludedCommands`](#run-commands-outside-the-sandbox-with-excludedcommands) or because Claude [retries it unsandboxed](#the-unsandboxed-retry-escape-hatch). A sandboxed command that connects to a host you haven’t allowed stays in the sandbox. [Hosts outside your allowed domains](#hosts-outside-your-allowed-domains) covers who decides whether the connection goes through. Even in auto-allow mode, the following still apply:

- A command in a [form that a `Bash` deny rule matches](permissions.md#bash-rule-limits) is still blocked
- `rm` or `rmdir` commands recognized as targeting a [critical path](permission-modes.md#which-paths-are-critical) still go through the regular permission flow
- Content-scoped [ask rules](permissions.md) like `Bash(git push *)` still force a prompt even for sandboxed commands
- A bare `Bash` ask rule, or the equivalent `Bash(*)` form, is skipped for commands that run sandboxed; it still applies to commands that run outside the sandbox. In [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode), the rule isn’t skipped: it prompts for sandboxed commands too, including read-only ones
- [Monitor tool](tools-reference.md#monitor-tool) commands aren’t approved automatically, though they still run in the sandbox. To skip the prompt, add an [allow rule](permissions.md#bash) that matches the command, such as `Bash(npm run *)`

Some sandboxed commands also go through the regular [permission flow](permissions.md) instead of being approved automatically. This happens with commands such as `FOO=bar npm test`, where a variable set in front of a command can change which program runs, and with `make CC=clang` or `eval "ls"`. Your allow rules and permission mode then decide whether you see a prompt, and the command still runs inside the sandbox. For these three commands, an [allow rule](permissions.md#bash) that matches the command stops a recurring prompt. These rules show the pattern:

- `Bash(make *)` approves `make CC=clang`
- `Bash(FOO=bar npm *)` approves `FOO=bar npm test`. When the command starts with a variable assignment, include the assignment in the rule
- `Bash(eval "ls")` approves `eval "ls"`. A wildcard rule such as `Bash(eval *)` doesn’t stop this prompt, so write a rule that matches the whole command

An allow rule that matches a command also approves an [unsandboxed retry](#the-unsandboxed-retry-escape-hatch) of it, so the command can run outside the sandbox with no prompt.

Auto-allow mode works independently of your permission mode setting, with three exceptions: [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode), an auto mode command that carries [per-command allowed domains](#per-command-allowed-domains-in-auto-mode), and [server-side classifier review](permission-modes.md#how-the-classifier-evaluates-actions) of sandboxed commands in auto mode. Even if you’re not in “accept edits” mode, sandboxed Bash commands run automatically when auto-allow is enabled. This means Bash commands that modify files within the sandbox boundaries execute without prompting, even in Manual mode, where the file edit tools would prompt.In plan mode, auto-allow doesn’t widen approvals; see [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode) for how Claude Code gates commands while you plan.


[​](#regular-permissions-mode)

Regular permissions mode

All Bash commands go through the regular permission flow, even when sandboxed. This provides more control but requires more approvals.


[​](#the-unsandboxed-retry-escape-hatch)

The unsandboxed retry escape hatch

The unsandboxed retry is an escape hatch for commands that fail inside the sandbox, such as tools that are incompatible with it. When the sandbox blocks a network connection, Claude Code names the denied host in the command’s result, so Claude sees what was blocked. Claude analyzes the failure and may retry the command with the `dangerouslyDisableSandbox` parameter. The retried command runs unsandboxed. In an interactive terminal session, who approves it depends on your permission mode:

- **`bypassPermissions` mode**: the retry runs without a prompt
- **Manual mode and `acceptEdits` mode**: you get a prompt titled “Bash command (unsandboxed)”
- **[Auto mode](permission-modes.md#eliminate-prompts-with-auto-mode)**: a separate classifier model evaluates the underlying command
- **`dontAsk` mode**: Claude Code denies the retry
- **Plan mode**: see [how Claude Code gates commands while you plan](permission-modes.md#analyze-before-you-edit-with-plan-mode)

These rules and settings change who approves the retry:

- **A matching allow rule**: if an allow rule such as `Bash(curl *)` matches the command, it also approves the retry, so the command runs outside the sandbox with no prompt
- **An ask rule for the parameter**: add an [ask rule](permissions.md#match-by-input-parameter) for `Bash(dangerouslyDisableSandbox:true)` to be prompted on Bash retries. You get the prompt in auto mode and `bypassPermissions` mode too, and the rule takes precedence over a matching allow rule
- **[`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories)**: [Actions no mode auto-approves](permission-modes.md#actions-no-mode-auto-approves) covers the retries that prompt while it’s on


[​](#turn-off-the-retry-with-strict-sandbox-mode)

Turn off the retry with strict sandbox mode

You can disable the unsandboxed retry by setting `"allowUnsandboxedCommands": false` in your [sandbox settings](settings-reference.md#sandbox-settings). With the retry disabled, Claude Code ignores the `dangerouslyDisableSandbox` parameter. While the sandbox is running, commands Claude runs are then sandboxed unless they match an `excludedCommands` entry. To keep Claude Code from running commands unsandboxed when the sandbox can’t start, also set [`failIfUnavailable`](settings-reference.md#sandbox-failifunavailable). The `/sandbox` **Overrides** tab shows this setting as **Strict sandbox mode**. A `false` in your user settings, `--settings`, or managed settings holds even when a project’s settings set `true`. A `false` in your user settings doesn’t make the sandbox admin-required, so a project’s other sandbox settings still apply. Before v2.1.285, a project’s `true` overrode a `false` in your user settings. If you or your administrator disable the retry in managed settings or with the `--settings` flag, the sandbox becomes admin-required. Claude Code then ignores the settings in a repository’s files that loosen the sandbox, `excludedCommands` entries included. [Repository settings under an admin-required sandbox](#repository-settings-under-an-admin-required-sandbox) lists them. Strict sandbox mode applies to the commands Claude runs. Commands you type yourself at the [`!` shell-mode prompt](interactive-mode.md#shell-mode-with-prefix) run outside the sandbox unless the session is one of these:

- **A [background session](../09-Agents-Patterns/agent-view.md)**: strict sandbox mode covers shell-mode commands too
- **A Linux session with [`CLAUDE_CODE_SUBPROCESS_ENV_SCRUB`](env-vars.md#variables) set**: every command runs sandboxed, shell-mode commands included

Before v2.1.260, strict sandbox mode sandboxed shell-mode commands in every session.


[​](#temporary-directories)

Temporary directories

A per-user temp directory is writable inside the sandbox by default, alongside the working directory. Unless you [disable filesystem isolation](#disable-filesystem-isolation), Claude Code sets `$TMPDIR` to this directory for sandboxed commands, so tools that write temporary files work without extra configuration. Unsandboxed commands inherit your shell’s `$TMPDIR` when it is set, so while filesystem isolation is on, sandboxed and unsandboxed commands resolve `$TMPDIR` to different directories. If your shell leaves `$TMPDIR` unset or empty, an unsandboxed command that references `$TMPDIR` receives your [`CLAUDE_CODE_TMPDIR`](env-vars.md) override, or the operating system’s temp directory when you haven’t set one or the override is a long path, so the variable doesn’t expand to an empty string. To pass temporary files between the two, write them under the working directory instead.


[​](#configure-sandboxing)

Configure sandboxing

Customize sandbox behavior through your `settings.json` file. See [Settings](settings-reference.md#sandbox-settings) for the complete configuration reference. By default, sandboxed commands can write to the current working directory, the per-user temp directory, and any [directories you’ve added](permissions.md#additional-directories-grant-file-access-not-configuration) with `--add-dir`, `/add-dir`, or `permissions.additionalDirectories`. If subprocess commands like `kubectl`, `terraform`, or `npm` need to write outside those directories, use `sandbox.filesystem.allowWrite` to grant access to specific paths:

```python
{
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "allowWrite": ["~/.kube", "/tmp/build"]
    }
  }
}
```

These 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`. When you define the same filesystem array in multiple [settings scopes](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. If you exclude a source with [`--setting-sources`](cli-reference.md) on the CLI or [`settingSources`](../05-Agent-SDK/agent-sdk-claude-code-features.md#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. When you edit these filesystem lists during a session, Claude Code [applies the change to the running session](settings.md#when-edits-take-effect), so the next sandboxed command runs under the new paths. Sandbox filesystem paths use standard conventions: `/tmp/build` is absolute and `~/.kube` is relative to your home directory. This differs from [Read and Edit permission rules](permissions.md#read-and-edit), which use `//path` for absolute and `/path` for project-relative. For relative paths, trailing slashes, and wildcards, see [Sandbox path prefixes](settings-reference.md#sandbox-path-prefixes). You can also deny write or read access using `sandbox.filesystem.denyWrite` and `sandbox.filesystem.denyRead`, and re-allow specific paths within a denied region using `sandbox.filesystem.allowRead`. When read rules overlap, the rule with the narrower path applies:

| Example rules                                           | Result                                                                                                                                                                                                        |
|:--------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `"denyRead": ["~/"]` with `"allowRead": ["~/projects"]` | `~/projects` is readable and the rest of the home directory stays blocked. The narrower allow re-opens that part of the denied region                                                                         |
| `"allowRead": ["~/"]` with `"denyRead": ["~/.env"]`     | `~/.env` stays blocked and the rest of the home directory is readable. The deny holds inside a wider allow, so a broad allow can’t silently re-expose a secret                                                |
| `"allowRead": ["~/"]` with `"denyRead": ["~/**/.env"]`  | Every `.env` under the home directory stays blocked and the rest is readable. A [wildcard deny](settings-reference.md#sandbox-path-prefixes) holds inside a wider allow the same way an exact path does |

The example below blocks reading from the entire home directory while still allowing reads from the current project. Place it in your project’s `.claude/settings.json`, because the relative path `.` resolves to the project root when the configuration lives in project settings:

```python
{
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "denyRead": ["~/"],
      "allowRead": ["."]
    }
  }
}
```

If you placed the same configuration in `~/.claude/settings.json`, `.` would resolve to `~/.claude` instead, and project files would remain blocked by the `denyRead` rule. To deny sandboxed commands read access to home directories and mounted volumes while keeping the working directories readable, set [`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) instead of writing path rules.


[​](#run-commands-outside-the-sandbox-with-excludedcommands)

Run commands outside the sandbox with `excludedCommands`

List a command pattern in [`sandbox.excludedCommands`](settings-reference.md#sandbox-excludedcommands) to run matching commands outside the sandbox, which means no filesystem restrictions and no network proxy. Use it for a tool that can’t work inside the sandbox and that you trust with your full access. A tool that needs one more directory or one more host may work with `allowWrite` or `allowedDomains`, which keep the command sandboxed. This example takes `docker compose` commands out of the sandbox. Save it in `~/.claude/settings.json` to apply it to all of your projects:

```python
{
  "sandbox": {
    "enabled": true,
    "excludedCommands": ["docker compose *"]
  }
}
```

Claude Code checks your entries against each Bash and Monitor call. A call is the whole command line Claude sends, which can chain several commands. The following rules decide whether a call leaves the sandbox:

- **End the pattern with ` *`**: entries use the same syntax as a `Bash(...)` [permission rule](permissions.md#permission-rule-syntax), where a pattern with no wildcard is an exact match. `docker` matches only `docker` with no arguments. `docker *` matches `docker` with or without arguments
- **Every command in the call has to match**: `npm ci && docker compose build` stays sandboxed unless another entry covers `npm ci`
- **Claude Code matches the text of the call**: a script or `make` target that calls `docker` internally doesn’t match, and neither does `/usr/local/bin/docker`
- **Some calls stay sandboxed**: a redirect to a file, a `cd`, or a command substitution such as `$(...)` keeps the whole call sandboxed. The [reference entry](settings-reference.md#sandbox-excludedcommands) lists more calls that stay sandboxed
- **Where you save the entry can matter**: while the sandbox is [admin-required](#repository-settings-under-an-admin-required-sandbox), Claude Code ignores entries in `.claude/settings.json` and `.claude/settings.local.json`

An excluded command goes through the regular permission flow:

- [Read-only commands](permissions.md#read-only-commands) and commands your allow rules cover run without a prompt
- In auto mode, the classifier reviews other excluded commands
- In `bypassPermissions` mode, an excluded command runs without a prompt unless an ask rule matches it

To confirm an entry matches, switch to Manual mode and ask Claude to run a matching command that changes something, such as `docker compose up -d`. The permission prompt is titled “Bash command (unsandboxed)”.

An excluded command runs with your full access. A broad entry such as `docker *` covers everything that tool can do. If you write a pattern that covers an interpreter, a script inside your working directory, or a tool that acts on a file there, as `docker compose` does with its compose file, Claude can write that file and then run it outside the sandbox. A narrower pattern leaves less that Claude can run outside the sandbox.


[​](#disable-filesystem-isolation)

Disable filesystem isolation

Set `sandbox.filesystem.disabled` to `true` to skip filesystem isolation while keeping network isolation. The example below turns off filesystem isolation while keeping an allowlist of network domains:

```python
{
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "disabled": true
    },
    "network": {
      "allowedDomains": ["github.com", "*.npmjs.org"]
    }
  }
}
```

The sandbox has two independent layers: [filesystem isolation](#filesystem-isolation) controls which paths sandboxed commands can read and write, and [network isolation](#network-isolation) controls which domains they can reach. With the filesystem layer off, sandboxed commands get unrestricted read and write access to the host filesystem, while their network egress stays confined to your allowed domains. Turn the layer off when you sandbox to control where commands connect rather than what they write. `sandbox.filesystem.disabled` defaults to `false`. Requires Claude Code v2.1.216 or later.

With filesystem isolation off and commands auto-allowed, a sandboxed command can write files that later commands run or read, such as shell startup files, executables on `$PATH`, or `~/.claude/settings.json`, and use them to widen its own access on the next run. Set `filesystem.disabled` to `true` only for workloads you trust not to escalate their own access. Locking network domains with [`allowManagedDomainsOnly`](#keep-developers-from-widening-the-policy) narrows the risk but doesn’t remove it, since that lock applies only to commands running inside the sandbox.


[​](#which-settings-can-disable-it)

Which settings can disable it

Because turning filesystem isolation off widens what sandboxed commands can do, Claude Code honors `filesystem.disabled` from these settings sources only:

- 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.
- 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.
- When [`CLAUDE_CODE_SUBPROCESS_ENV_SCRUB`](env-vars.md) is set, Claude Code ignores `filesystem.disabled` from every source, including managed settings, and keeps filesystem isolation on.

A [valid](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.


[​](#what-changes-when-filesystem-isolation-is-off)

What changes when filesystem isolation is off

Setting `filesystem.disabled` lifts the protections the filesystem layer itself enforces. Protections that other layers enforce keep applying:

| Protection                                                                               | With filesystem isolation off                                                                                                                                |
|------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `filesystem.denyRead` and [`credentials.files`](#protect-credentials) `deny` read blocks | Not enforced. The filesystem layer applies both                                                                                                              |
| `credentials.envVars` `deny` and `mask` entries                                          | Enforced. Environment variable scrubbing is independent of the filesystem layer                                                                              |
| [`credentials.files` `mask` entries](#mask-credential-files) applied as masks            | Enforced: masking is independent of the filesystem layer. An entry that [fell back to `deny`](#mask-credential-files) is not enforced, like any `deny` entry |

Two other things change:

- Sandboxed commands inherit your shell’s `$TMPDIR` instead of the per-user temp directory, because every temp directory is writable and Claude Code no longer redirects commands to the per-user one. On Linux the variable is often unset in the parent shell. The Bash tool guidance tells Claude to create scratch directories with `mktemp -d` instead of relying on `$TMPDIR`.
- [`autoAllowBashIfSandboxed`](settings-reference.md#sandbox-autoallowbashifsandboxed) still defaults to `true`, so sandboxed commands keep running without prompts. Set it to `false` to prompt for sandboxed commands.


[​](#protect-credentials)

Protect credentials

The `sandbox.credentials` setting declares credential files and environment variables to protect from sandboxed commands. Each entry names a file path or an environment variable and a `mode`. The dedicated `credentials` block keeps credential rules grouped together and separate from general filesystem rules. For entries with `"mode": "deny"`, file paths are denied for reads inside the sandbox, the same restriction that `filesystem.denyRead` applies, and environment variables are unset before each sandboxed command runs. The file protection is part of the filesystem layer, so it doesn’t apply if you [disable filesystem isolation](#disable-filesystem-isolation); the environment variable protection still does. The example below blocks reads of the AWS credentials file and the SSH directory and removes `GITHUB_TOKEN` and `NPM_TOKEN` from the environment of sandboxed commands:

```python
{
  "sandbox": {
    "enabled": true,
    "credentials": {
      "files": [
        { "path": "~/.aws/credentials", "mode": "deny" },
        { "path": "~/.ssh", "mode": "deny" }
      ],
      "envVars": [
        { "name": "GITHUB_TOKEN", "mode": "deny" },
        { "name": "NPM_TOKEN", "mode": "deny" }
      ]
    }
  }
}
```

Environment variable entries and file entries also accept `"mode": "mask"`, described under [Mask credentials](#mask-credentials). File paths follow the same [prefix rules](settings-reference.md#sandbox-path-prefixes) as `sandbox.filesystem.*` settings. Claude Code merges the `deny` entries from every [settings scope](settings.md#settings-precedence) the session loads. A `deny` entry only ever narrows access, so any scope can add one, but no scope can remove one that another scope added. When you [exclude a settings source](#configure-sandboxing):

- **Project or local settings**: Claude Code applies none of their `credentials` entries. Requires Claude Code v2.1.246 or later.
- **User settings**: Claude Code still applies the `deny` entries in `~/.claude/settings.json` and keeps its [file `mask` entries](#mask-credential-files) as restrictions that no longer authorize the proxy to substitute the real value, but drops its [environment variable `mask` entries](#mask-environment-variables).

There is no built-in credential deny list, so only the files and variables you list are restricted. `sandbox.credentials` affects sandboxed Bash commands only. To strip credentials from all subprocesses regardless of sandboxing, set [`CLAUDE_CODE_SUBPROCESS_ENV_SCRUB`](env-vars.md).


[​](#mask-credentials)

Mask credentials

When you mask a credential, Claude Code shows sandboxed commands a per-session placeholder called the sentinel, and the [sandbox proxy](#network-isolation) substitutes the real value on outbound requests to hosts you allow. A `deny` entry under [Protect credentials](#protect-credentials) blocks the credential instead. For files on macOS, Claude Code [blocks the file instead](#mask-credential-files) of masking it. The [`sandbox.credentials`](settings-reference.md#sandbox-credentials) reference lists every field. Masking requires the following:

- **TLS termination**: the proxy substitutes the real value inside request contents, so it has to see them. Set [`network.tlsTerminate`](settings-reference.md#sandbox-network-tlsterminate) so the proxy terminates TLS itself. Without it, masking fails without exposing anything: the command still sees only the sentinel, but the sentinel reaches the server unchanged and authentication fails. To check for this misconfiguration, run `claude doctor` in your terminal and look for the `TLS termination is unavailable` warning.
- **An allowed destination**: each `mask` entry can list `injectHosts`, the hosts the real value is allowed to reach. The proxy injects only on connections the [domain allowlist](#network-isolation) admits, so each `injectHosts` host must also be reachable through `network.allowedDomains`. For a `mask` entry with no `injectHosts`, the proxy substitutes the real value on requests to every host in `network.allowedDomains`.
- **A trusted settings scope**: masking authorizes the proxy to send your real credential somewhere, so Claude Code honors `mask` entries, `network.tlsTerminate`, [`credentials.allowPlaintextInject`](settings-reference.md#sandbox-credentials-allowplaintextinject), `awsPairs`, and `sigv4` only from user settings, managed settings, and the `--settings` flag. It ignores them in a repository’s `.claude/settings.json` or `.claude/settings.local.json`. When your administrator delivers `mask` entries, `network.tlsTerminate`, or `credentials.allowPlaintextInject` through server-managed settings, they count as [settings that need approval](../13-Enterprise-Admin/server-managed-settings.md#security-approval-dialogs).


[​](#mask-environment-variables)

Mask environment variables

To mask an environment variable, set `"mode": "mask"` on its `credentials.envVars` entry. The command and anything it logs never hold the real credential, but its requests still authenticate. When the same variable is listed with `deny` in any scope, `deny` takes precedence. This example masks two tokens. `GH_TOKEN` is substituted only on requests to `api.github.com`, while `NPM_TOKEN` has no `injectHosts` and is substituted on requests to every host in `network.allowedDomains`:

```python
{
  "sandbox": {
    "enabled": true,
    "network": {
      "tlsTerminate": {},
      "allowedDomains": ["*.github.com", "registry.npmjs.org"]
    },
    "credentials": {
      "envVars": [
        { "name": "GH_TOKEN", "mode": "mask", "injectHosts": ["api.github.com"] },
        { "name": "NPM_TOKEN", "mode": "mask" }
      ]
    }
  }
}
```

Masking replaces the whole value by default. For a value with structure, such as a `DATABASE_URL` connection string or a JWT, use the [`extract`, `decode`, `maskClaims`, and `onExtractNoMatch` fields](settings-reference.md#sandbox-credentials-envvars) so tools that parse the value keep working. For an IPv6 destination, spell the address differently in the two lists:

- **`network.allowedDomains`**: the bracketed form, such as `"[::1]"`
- **`injectHosts`**: the bare address in its canonical compressed form, such as `"::1"`

The proxy matches each `injectHosts` entry against the connection’s bare destination address, ignoring ports, so a bracketed, zone-ID, or differently compressed spelling never matches. `claude doctor` flags entries that can never match with the warning `Sandbox credential injectHosts entries can never match their destination`. This check requires Claude Code v2.1.229 or later.


[​](#re-sign-aws-requests)

Re-sign AWS requests

AWS requests carry SigV4 signatures over the request contents, so mask `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` together. The proxy detects a SigV4 request by the access key’s [sentinel](#mask-credentials) and re-signs the request with the real values, which requires Claude Code v2.1.221 or later. If you mask only the secret, requests are signed with a placeholder the proxy can’t detect, so they fail at AWS. Claude Code links the conventional `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN` variables into one credential automatically when you mask their whole values. If your AWS credential is in variables with other names, group them with [`credentials.awsPairs`](settings-reference.md#sandbox-credentials-awspairs), which requires Claude Code v2.1.224 or later. Streaming uploads, presigned URLs, and SigV4A requests carry signatures the proxy can’t recompute. When one of these requests is signed with a masked pair’s placeholder, the proxy fails it rather than forward a broken signature. Requests signed with unmasked credentials aren’t affected. Use [`credentials.sigv4`](settings-reference.md#sandbox-credentials-sigv4), which requires Claude Code v2.1.224 or later, to forward one of these request forms instead. AWS still rejects the request, so the calling tool receives AWS’s own rejection response instead of a proxy error.


[​](#mask-credential-files)

Mask credential files

To mask a credential file, set `"mode": "mask"` on its `credentials.files` entry. Masking files requires Claude Code v2.1.221 or later. What a sandboxed command sees depends on the platform:

- **Linux and WSL2**: sandboxed commands read a [sentinel](#mask-credentials) copy of the file, and the proxy substitutes the real value on outbound requests.
- **macOS**: sandboxed commands can’t read the file at all. Claude Code builds no sentinel copy, so tools that authenticate with the file don’t work inside the sandbox, the same effect as `deny`. The read block holds even when you [disable filesystem isolation](#disable-filesystem-isolation).

This example masks a GitHub token stored in `~/.config/gh/hosts.yml`. The `extract` pattern marks which part of the file is the secret, so on Linux and WSL2 `gh` still parses the rest of its config:

```python
{
  "sandbox": {
    "enabled": true,
    "network": {
      "tlsTerminate": {},
      "allowedDomains": ["*.github.com"]
    },
    "credentials": {
      "files": [
        {
          "path": "~/.config/gh/hosts.yml",
          "mode": "mask",
          "extract": "oauth_token:\\s*(\\S+)",
          "injectHosts": ["api.github.com"]
        }
      ]
    }
  }
}
```

To confirm the mask is active, ask Claude to run `cat ~/.config/gh/hosts.yml` in a sandboxed command. On Linux and WSL2 the output shows a sentinel in place of the token, and on macOS the read fails. Without `extract` or `decode`, Claude Code replaces the entire file with one sentinel, which suits a file holding a single bare secret. Use the [`extract`, `decode`, `maskClaims`, `onExtractNoMatch`, and `maskDuplicates` fields](settings-reference.md#sandbox-credentials-files) to control partial masking and what happens when the pattern matches nothing.

When matching finds nothing to mask, the default `onExtractNoMatch` value, `warn`, skips the entry, so sandboxed commands can read the real file unmasked. On macOS, Claude Code applies `mask` entries as `deny` before the pattern runs whenever filesystem isolation is on, so the no-match outcomes take effect there only when [filesystem isolation is off](#disable-filesystem-isolation). The default suits credentials that may be legitimately absent. If the secret might be present but the pattern might miss it, use [`deny`](settings-reference.md#mask-fields-for-files).

`mask` applies to a single file, so list each credential file individually. Claude Code falls back to `deny` for a `mask` entry it can’t mask safely: a directory path, a glob pattern, a file larger than 8 MiB, or a file that isn’t UTF-8 text.


[​](#how-sandboxing-works)

How sandboxing works


[​](#filesystem-isolation)

Filesystem isolation

The sandboxed Bash tool restricts file system access to specific directories:

- **Default write behavior**: read and write access to the current working directory and its subdirectories, any directories you’ve added with `--add-dir`, `/add-dir`, or [`permissions.additionalDirectories`](settings-reference.md#permissions-additionaldirectories), plus the per-user temp directory that `$TMPDIR` points to
- **Default read behavior**: read access to the entire computer, except certain denied directories. This default still allows reading credential files, so [protect credentials](#protect-credentials) you don’t want commands to read.
- **Read block**: with [`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) on, sandboxed commands also lose read access to your home directory and the other directories that hold user files, apart from the paths that [Sandboxed commands under the block](settings-reference.md#sandboxed-commands-under-the-block) lists. That section also says when this part of the block doesn’t apply.
- **Git worktrees**: when the working directory is a [linked git worktree](worktrees.md), the sandbox also allows writes to the main repository’s shared `.git` directory so commands such as `git commit` can update refs and the index. Writes to `hooks/` and `config` inside that directory remain denied.

To skip filesystem isolation entirely while keeping network isolation, set [`sandbox.filesystem.disabled`](#disable-filesystem-isolation).


[​](#protected-paths)

Protected paths

Inside the directories that sandboxed commands can write to, the sandbox still denies writes to the files Claude Code loads configuration and code from. A command that could edit those files could grant itself permissions, or add a hook or MCP server that Claude Code runs outside the sandbox. The permission system has its own [protected paths](permission-modes.md#protected-paths), which control what Claude Code approves before a tool runs; the sandbox’s list applies to a command that is already running. It covers four groups of paths:

- **In your working directory and the directories above it**: the `.claude` settings files, the `.claude/skills`, `.claude/agents`, `.claude/commands`, and `.claude/hooks` directories, `.mcp.json`, and the files Claude Code runs on its own, such as `.claude/workflows` and `.claude/scheduled_tasks.json`
- **In your working directory only**: shell startup files such as `.bashrc` and `.zshrc`, `.gitconfig`, the `.vscode` and `.idea` directories, and `hooks` and `config` inside `.git`
- **Files that would turn your working directory into a bare git repository**: `HEAD`, `objects`, and `refs` at the top level, plus existing `config` and `hooks` entries there when a `HEAD` sits beside them. A file named `config` is denied even with no `HEAD`. On Linux and WSL2, the sandbox deletes a top-level `HEAD` file or `objects` or `refs` directory that appears while a sandboxed command is running
- **In `~/.claude`, or the directory `CLAUDE_CONFIG_DIR` points to**: most of its contents, plus `~/.claude.json` and the `.credentials.json` credential store

If a symlink appears at a protected settings file’s path during the session, the sandbox also denies writes to the file it points to, starting with the next command. If you add an `allowWrite` entry or an `Edit` allow rule that covers one of these paths, the protection still applies. To turn the protection off, set [`filesystem.disabled`](#disable-filesystem-isolation), which also turns off the rest of filesystem isolation.

If you set [`allowNestedUserNamespaces`](settings-reference.md#sandbox-allownestedusernamespaces) to `true` on Linux or WSL2, don’t rely on protected paths: code from a sandboxed command can end up running outside the sandbox.

To see most of these paths resolved for your machine, run `/sandbox` and open the **Config** tab, which lists them under **Denied within allowed**, mixed in with your own `denyWrite` entries. If `git merge` or `git checkout` fails with `unable to unlink old` on one of these paths, see [A git command fails with `unable to unlink old`](#a-git-command-fails-with-unable-to-unlink-old).


[​](#denied-paths-that-pass-through-a-symlink)

Denied paths that pass through a symlink

On macOS, when a denied path passes through a symlink, such as a `~/.claude` that is a link into a dotfiles repository, the sandbox also denies the path’s real location. This covers the sandbox’s own denials and your literal `denyWrite` and `denyRead` entries.


[​](#network-isolation)

Network isolation

A sandboxed command has no direct route to the network:

- **Linux and WSL2**: the command runs in a separate network namespace that has no connection to your network
- **macOS**: the Seatbelt sandbox framework by default blocks connections other than the one to the sandbox proxy

Claude Code runs the sandbox proxy on your machine, outside the sandbox, and directs commands to it with `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, and related environment variables. The proxy checks the hostname of each connection against your allowed and denied domains. What a tool can reach depends on whether it uses the proxy:

- **Tools that read the proxy variables**: `curl`, `npm`, `git` over HTTPS, and similar tools connect once their host is allowed. An `allowedDomains` entry with no port allows every port on that host
- **Tools that ignore the proxy variables**: plain `ssh`, most database drivers, and similar tools can’t connect, even to an allowed host. See [A database client or other non-HTTP tool fails to reach an allowed host](#a-database-client-or-other-non-http-tool-fails-to-reach-an-allowed-host)
- **Anything that isn’t TCP**: UDP, HTTP/3 over QUIC, and ICMP tools such as `ping` can’t leave the sandbox

The following settings and behaviors control which hosts the proxy allows:

- **Domain restrictions**: your allowed domains start empty. [Hosts outside your allowed domains](#hosts-outside-your-allowed-domains) covers what happens the first time a command needs a new domain.
- **Approval choices**: if you choose Yes when prompted, Claude Code allows the host for the rest of the current session. If you choose “Yes, and don’t ask again”, Claude Code saves a `WebFetch(domain:...)` allow rule to your [local settings](permissions.md#permission-system), so the host stays allowed in future sessions. While the sandbox is [admin-required](#repository-settings-under-an-admin-required-sandbox), Claude Code saves the rule to your user settings, where it applies in every project.
- **Pre-allowed domains**: pre-allow domains with [`allowedDomains`](settings-reference.md#sandbox-network-alloweddomains) to avoid the prompt entirely. Claude Code also pre-allows domains from `WebFetch(domain:...)` allow rules, as described in [Permission rules](#permission-rules).
- **Strict allowlist**: if you set [`strictAllowlist`](settings-reference.md#sandbox-network-strictallowlist) to `true` in user, managed, or CLI `--settings` settings, Claude Code denies sandboxed commands access to any host outside the allowlist instead of prompting. The allowlist is `allowedDomains` plus domains from `WebFetch(domain:...)` allow rules, or only the managed settings entries when `allowManagedDomainsOnly` is set. [Locks that apply without an admin-required sandbox](#locks-that-apply-without-an-admin-required-sandbox) covers a repository’s entries. Claude Code enforces this for sandboxed commands only; in-process tools such as `WebFetch` still follow their [permission rules](#permission-rules). Setting it in a repository’s `.claude/settings.json` or `.claude/settings.local.json` has no effect. Requires Claude Code v2.1.219 or later.
- **Managed lockdown**: if [`allowManagedDomainsOnly`](settings-reference.md#sandbox-network-allowmanageddomainsonly) is set in managed settings, non-allowed domains are blocked automatically instead of prompting, and only `allowedDomains` and `WebFetch(domain:...)` allow rules from managed settings are honored.
- **Corporate proxy**: when your network requires outbound traffic to go through a corporate proxy, set `HTTPS_PROXY`, `HTTP_PROXY`, and `NO_PROXY` as [proxy configuration](../13-Enterprise-Admin/network-config.md#proxy-configuration) describes, in the `env` block of your settings so that [background agents](../13-Enterprise-Admin/network-config.md#set-network-variables-in-settings-not-the-shell) get them too, or in the environment you launch Claude Code from. Claude Code enforces the domain allowlist and then tunnels allowed connections through that upstream proxy. `http://` and `https://` proxy URLs work, with basic authentication in the URL if you need it.

In a `WebFetch(domain:...)` rule, the sandbox honors two wildcard forms: a leading `*.`, such as `*.example.com`, and a bare `*`. The bare `*` form requires Claude Code v2.1.186 or later. A wildcard in any other position, such as `WebFetch(domain:example.*)`, still matches fetches but has no effect on sandboxed commands.

The built-in proxy enforces the allowlist based on the requested hostname and, by default, does not terminate or inspect TLS traffic. The experimental [`network.tlsTerminate`](settings-reference.md#sandbox-network-tlsterminate) setting makes the built-in proxy terminate TLS itself, which [`mask` credential entries](#mask-credentials) require. See [Security limitations](#security-limitations) for the implications of the default, and [Custom proxy configuration](#custom-proxy-configuration) if your threat model requires TLS inspection.


[​](#hosts-outside-your-allowed-domains)

Hosts outside your allowed domains

When a sandboxed command connects to a host that isn’t in your allowed domains, the command stays in the sandbox and waits for a decision. In an interactive terminal session, the decision depends on your permission mode:

| Permission mode                                                                                                                                    | What happens to the connection                                                                                               |
|:---------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------|
| `bypassPermissions` mode, and plan mode with [bypass permissions available](permission-modes.md#skip-all-checks-with-bypasspermissions-mode) | Allowed without a prompt                                                                                                     |
| Manual mode, `acceptEdits` mode, and plan mode otherwise                                                                                           | You get a prompt                                                                                                             |
| Auto mode                                                                                                                                          | Refused unless the command [listed the host](#per-command-allowed-domains-in-auto-mode) and the classifier approved the list |
| `dontAsk` mode                                                                                                                                     | Refused                                                                                                                      |

With [`strictAllowlist`](settings-reference.md#sandbox-network-strictallowlist) or [`allowManagedDomainsOnly`](settings-reference.md#sandbox-network-allowmanageddomainsonly) on, the built-in sandbox proxy refuses the connection in every permission mode. In `bypassPermissions` mode, hosts outside your allowed domains are allowed unless one of them is on. [The unsandboxed retry escape hatch](#the-unsandboxed-retry-escape-hatch) covers when a command can leave the sandbox in that mode. A connection to a host in [`deniedDomains`](settings-reference.md#sandbox-network-denieddomains) is refused in every permission mode too.


[​](#hostnames-that-resolve-to-local-addresses)

Hostnames that resolve to local addresses

After a hostname passes the allowlist, the sandbox proxy resolves it and refuses the connection when the name resolves only to local addresses. Local addresses include loopback addresses such as `127.0.0.1`, link-local addresses such as the `169.254.169.254` cloud metadata endpoint, and addresses assigned to your own machine. The names `localhost` and `*.localhost` are allowed to resolve to loopback. An allowed intranet hostname that resolves to a private range such as `10.0.0.0/8` connects. To let a name resolve to a refused address, add that IP address to `allowedDomains`, such as `"127.0.0.1:8080"`. The check applies to hostnames. Your allowed domains and permission mode decide a connection to an IP address. The proxy also skips the check for connections it sends through an upstream corporate proxy, because that proxy resolves the name.


[​](#per-command-allowed-domains-in-auto-mode)

Per-command allowed domains in auto mode

In [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) with sandboxing on, Claude names the hosts a command needs on the command itself instead of triggering a network approval for each connection. Each Bash, PowerShell, or [Monitor](tools-reference.md#monitor-tool) command that runs in the sandbox can carry a list of hosts beyond the sandbox’s allowlist: a domain such as `registry.npmjs.org`, a wildcard such as `*.pythonhosted.org`, or an IP address, each with an optional `:port`. The classifier reviews the hosts together with the command. Requires Claude Code v2.1.271 or later. An approved list opens those hosts for that one command alone, for as long as it runs. Nothing is added to your session’s allowed hosts or your settings; the next command names its own hosts. A command that carries hosts goes to the classifier instead of being approved by a permission rule or the sandbox’s [auto-allow mode](#sandbox-modes). If an [ask rule](permissions.md#manage-permissions) forces a prompt for the command, the permission dialog in your terminal lists the hosts beside it, and approving there covers both. A per-command list widens only what the sandbox denies by default. [`deniedDomains`](settings-reference.md#sandbox-network-denieddomains) entries still block. When [`strictAllowlist`](settings-reference.md#sandbox-network-strictallowlist) or [`allowManagedDomainsOnly`](settings-reference.md#sandbox-network-allowmanageddomainsonly) locks the allowlist, Claude Code refuses per-command lists. While per-command lists apply, Claude Code refuses a connection to a host that no approved command listed, without a prompt or a classifier check. The refusal names the host in the command’s result, and Claude re-runs the command with the host added.


[​](#ipv6-addresses-in-domain-lists)

IPv6 addresses in domain lists

To match an IPv6 address in `allowedDomains`, `deniedDomains`, or a `WebFetch(domain:...)` rule, write the address in brackets: `"[::1]"` matches that address on every port, and `"[::1]:443"` matches it on port 443 only. The bracketed form requires Claude Code v2.1.229 or later. An unbracketed entry such as `::1:443` is ambiguous between an address and an address with a port:

- **Deny lists**: Claude Code denies every reading the entry parses as, so whichever reading you meant is blocked. For an entry with no parseable reading, Claude Code blocks nothing
- **Allow lists**: Claude Code never allows more than you wrote. It rewrites an ambiguous entry to its host-and-port reading when that reading parses cleanly, and may drop the entry entirely rather than widen the allowlist

To find ambiguous entries, run `claude doctor` in your terminal and look for the `Sandbox network domain entries have unreliable spellings` warning. Rewrite each ambiguous entry in the bracketed form.


[​](#os-level-enforcement)

OS-level enforcement

The sandboxed Bash tool uses operating system security primitives:

- **macOS**: uses Seatbelt for sandbox enforcement
- **Linux**: uses [bubblewrap](https://github.com/containers/bubblewrap) for isolation
- **WSL2**: uses bubblewrap, same as Linux

You can also run the [`@anthropic-ai/sandbox-runtime`](https://github.com/anthropics/sandbox-runtime) package on its own to wrap the Claude Code process. See [Sandbox runtime](sandbox-environments.md#sandbox-runtime).


[​](#how-sandboxing-relates-to-permissions-and-permission-modes)

How sandboxing relates to permissions and permission modes

Sandboxing, [permission rules](permissions.md), and [permission modes](permission-modes.md) are complementary layers. The sections below cover how the sandbox interacts with each.


[​](#permission-rules)

Permission rules

Permission rules and sandboxing control different things:

- **Permission rules** control which tools Claude Code can use and are evaluated before any tool runs. They apply to every tool: Bash, Read, Edit, WebFetch, MCP, and others, except that a deny or ask rule can’t block [`EndConversation`](tools-reference.md#endconversation-tool-behavior) while any other tool remains.
- **Sandboxing** provides OS-level enforcement that restricts what shell commands can access at the filesystem and network level. It applies to Bash, PowerShell, and [Monitor](tools-reference.md#monitor-tool) tool commands and their child processes.

The two layers also differ in how they are enforced. Claude Code evaluates permission decisions before a command runs, based on the command string and, in auto mode, a separate classifier’s judgment about whether the command is safe. The operating system enforces the sandbox boundary on the running process, so it holds regardless of what the model chose to run and even if an allowed command does more than its name suggests. Filesystem and network restrictions are configured through both sandbox settings and permission rules:

| Setting or rule                                                  | What it does                                                                                      |
|:-----------------------------------------------------------------|:--------------------------------------------------------------------------------------------------|
| `sandbox.filesystem.allowWrite`                                  | Grants subprocess write access to paths outside the working directory                             |
| `sandbox.filesystem.denyWrite` and `sandbox.filesystem.denyRead` | Block subprocess access to specific paths                                                         |
| `sandbox.filesystem.allowRead`                                   | Re-allows reading specific paths within a `denyRead` region                                       |
| [`sandbox.filesystem.disabled`](#disable-filesystem-isolation)   | Turns the filesystem layer off entirely while keeping network isolation                           |
| `Edit` allow rules                                               | Grant write access to specific paths, the same way `sandbox.filesystem.allowWrite` does           |
| `Read` and `Edit` deny rules                                     | Block access to specific files or directories                                                     |
| `WebFetch(domain:...)` allow and deny rules                      | Control domain access                                                                             |
| Sandbox `allowedDomains`                                         | Controls which domains Bash commands can reach                                                    |
| Sandbox `deniedDomains`                                          | Blocks specific domains even when a broader `allowedDomains` wildcard would otherwise permit them |

Paths and domains from both sandbox settings and permission rules are merged into the final sandbox configuration. The [claude-code repository’s examples directory](https://github.com/anthropics/claude-code/tree/main/examples/settings) includes starter settings configurations for common deployment scenarios, including sandbox-specific examples. Use these as starting points and adjust them to fit your needs.


[​](#permission-modes)

Permission modes

`/sandbox` is not a [permission mode](permission-modes.md). Permission modes decide whether a tool call runs and whether you are prompted first, while the sandbox restricts what a Bash command can access once it runs. They differ in what they control and what replaces the per-action prompt:

|                                                                         | What it controls                            | What replaces the prompt                                                                                                                                                                               |
|:------------------------------------------------------------------------|:--------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `/sandbox`                                                              | What a Bash command can access once it runs | The sandbox boundary itself, in [auto-allow mode](#sandbox-modes)                                                                                                                                      |
| [Auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) | Whether each tool call runs                 | A classifier that reviews actions                                                                                                                                                                      |
| `--dangerously-skip-permissions`                                        | Whether each tool call runs                 | Nothing. [Protected path](permission-modes.md#protected-paths) checks are also skipped; the [actions no mode auto-approves](permission-modes.md#actions-no-mode-auto-approves) still apply |

The sandbox’s [auto-allow mode](#sandbox-modes) is separate from [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode): auto-allow approves Bash commands because the sandbox boundary contains them, while auto mode uses a classifier to review actions. The two work independently and can be combined, with the exceptions listed under [Sandbox modes](#sandbox-modes). To choose an isolation boundary for unattended runs, see [Sandbox environments](sandbox-environments.md#how-isolation-relates-to-permission-modes). For a table of common permission mode and sandbox pairings with the flags that start each one, see [Common setups](permission-modes.md#common-setups).


[​](#configure-the-sandbox-for-your-organization)

Configure the sandbox for your organization

Administrators can require sandboxing for every user, keep developers from widening the policy, and route sandbox traffic through a corporate proxy.


[​](#enforce-sandboxing-with-managed-settings)

Enforce sandboxing with managed settings

To require the sandbox for every developer, deliver the `sandbox` keys through [managed settings](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms), either as a file managed by your MDM or through [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) on claude.ai. The following managed settings configuration enables the sandbox, refuses to start Claude Code when the platform is unsupported or a dependency is missing, and prevents the model from retrying commands outside the sandbox:

```python
{
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true,
    "allowUnsandboxedCommands": false
  }
}
```

The two keys beyond `enabled` control what happens when the sandbox cannot run a command:

- **`failIfUnavailable`**: a missing dependency such as bubblewrap on Linux blocks Claude Code from starting rather than falling back to unsandboxed execution
- **`allowUnsandboxedCommands: false`**: Claude Code ignores the `dangerouslyDisableSandbox` escape hatch, so when a command fails under the sandbox, Claude can’t retry it unsandboxed

Consider these additions alongside them:

- Add `excludedCommands` for any organization-approved tools that must run without isolation, because this configuration [stops a repository’s settings from taking commands out of the sandbox](#repository-settings-under-an-admin-required-sandbox)
- Add [`sandbox.credentials`](#protect-credentials) entries for credential directories such as `~/.aws` and `~/.ssh` and for secret environment variables, since the default read policy still allows them

This configuration sandboxes the commands Claude runs. A developer can still type a command at the [`!` shell-mode prompt](interactive-mode.md#shell-mode-with-prefix) and run it outside the sandbox, with the same access they already have in any terminal outside Claude Code. See [strict sandbox mode](#turn-off-the-retry-with-strict-sandbox-mode) for the sessions where typed commands run sandboxed. The sandbox doesn’t run on native Windows, so with `failIfUnavailable` set, Claude Code exits at startup on those machines. If your fleet includes Windows hosts, you can:

- **Deliver the configuration by operating system**: deploy it through your MDM or as a [managed settings file](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms) on macOS and Linux machines only. [Server-managed settings](../13-Enterprise-Admin/server-managed-settings.md#current-limitations) apply to all users in the organization
- **Move Windows users into a supported environment**: have them run Claude Code inside WSL2 or a container


[​](#keep-developers-from-widening-the-policy)

Keep developers from widening the policy

When managed settings set a Boolean key such as `enabled` or `failIfUnavailable`, Claude Code uses the managed value and ignores anything a developer sets locally. For array keys such as `allowRead`, Claude Code merges entries from the scopes the session loads, so a developer can append entries that widen the policy unless a lock covers that key. Unless managed settings set them, a developer’s user settings or `--settings` can turn on the following keys. A repository’s `.claude/settings.json` can too, unless the sandbox is [admin-required](#repository-settings-under-an-admin-required-sandbox). Each one weakens the sandbox, so set it to `false` in managed settings if you don’t want it used:

- [`enableWeakerNestedSandbox`](settings-reference.md#sandbox-enableweakernestedsandbox)
- [`enableWeakerNetworkIsolation`](settings-reference.md#sandbox-enableweakernetworkisolation)
- [`network.allowAllUnixSockets`](settings-reference.md#sandbox-network-allowallunixsockets)
- [`network.allowLocalBinding`](settings-reference.md#sandbox-network-allowlocalbinding)
- [`allowAppleEvents`](settings-reference.md#sandbox-allowappleevents), which a repository can’t turn on
- [`allowNestedUserNamespaces`](settings-reference.md#sandbox-allownestedusernamespaces), which a repository can’t turn on

Set `allowManagedReadPathsOnly` to `true` in managed settings so that only `allowRead` entries from managed settings are honored. This prevents developers from widening read access beyond the organization-approved paths. To lock network domains to the managed values the same way, set [`allowManagedDomainsOnly`](settings-reference.md#sandbox-network-allowmanageddomainsonly). With `allowManagedDomainsOnly` on, only managed settings can set a [proxy port](#custom-proxy-configuration). When managed settings configure `sandbox.filesystem` or list any `sandbox.credentials.files` entry with `"mode": "deny"`, only managed settings can set [`filesystem.disabled`](#disable-filesystem-isolation), so developers can’t turn filesystem isolation off with that key. A [valid](settings-reference.md#invalid-credential-entries-in-managed-settings) `mask` entry doesn’t lock the key. See [Which settings can disable it](#which-settings-can-disable-it).


[​](#repository-settings-under-an-admin-required-sandbox)

Repository settings under an admin-required sandbox

The sandbox is admin-required while one of these settings is in effect:

- [`allowUnsandboxedCommands`](settings-reference.md#sandbox-allowunsandboxedcommands) set to `false` in managed settings, or with the `--settings` flag unless managed settings set it to `true`
- [`allowManagedDomainsOnly`](settings-reference.md#sandbox-network-allowmanageddomainsonly) set to `true` in managed settings

These settings don’t turn the sandbox on, so set `enabled` as well. While the sandbox is admin-required, Claude Code takes the settings that loosen it only from managed settings, the `--settings` flag, and each developer’s `~/.claude/settings.json`. It ignores these settings in a repository’s `.claude/settings.json` and `.claude/settings.local.json`:

| Repository setting                                                                                                                                                         | What Claude Code ignores                                                                                                                |
|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------|
| `excludedCommands`, `ignoreViolations`, `network.allowedDomains`, `network.allowUnixSockets`, `network.allowMachLookup`, `network.httpProxyPort`, `network.socksProxyPort` | Every entry                                                                                                                             |
| `filesystem.allowWrite`, `Edit(...)` allow rules, `permissions.additionalDirectories`                                                                                      | The write access each entry gives sandboxed commands. Claude’s file tools still follow the `Edit(...)` rules and additional directories |
| `WebFetch(domain:...)` allow rules                                                                                                                                         | The host each rule adds to the sandbox allowlist. The WebFetch tool still follows the rule                                              |
| `enableWeakerNestedSandbox`, `enableWeakerNetworkIsolation`, `network.allowAllUnixSockets`, `network.allowLocalBinding`                                                    | `true`. A `false` still applies                                                                                                         |
| `enabled`, `failIfUnavailable`                                                                                                                                             | `false`, when the developer’s `~/.claude/settings.json` sets `true`                                                                     |
| `filesystem.allowRead`                                                                                                                                                     | An entry at or under a path that managed settings, `--settings`, or user settings deny reading, or a glob that could match one          |

These settings still apply while the sandbox is admin-required:

- **In a repository’s files**: deny entries and the `autoAllowBashIfSandboxed` value. Set the key in managed settings to keep a repository from changing it
- **In a developer’s own settings**: the settings in the table still apply from `~/.claude/settings.json` or `--settings`, unless a managed-only lock such as `allowManagedDomainsOnly` covers them. Most of them, such as `excludedCommands` and `filesystem.allowWrite`, have no managed-only lock

The configuration under [Enforce sandboxing with managed settings](#enforce-sandboxing-with-managed-settings) makes the sandbox admin-required. Add the `excludedCommands`, `allowWrite`, and socket entries that your approved tools need to managed settings, because a repository can’t supply them. Requires Claude Code v2.1.285 or later. From v2.1.282 to v2.1.284, the same settings made Claude Code ignore a repository’s `excludedCommands` entries.


[​](#locks-that-apply-without-an-admin-required-sandbox)

Locks that apply without an admin-required sandbox

Some settings make Claude Code ignore the repository keys that directly override one restriction, even when the sandbox isn’t admin-required. Each one has this effect only when you set it in a file its row names, and the repository’s other sandbox settings still apply. Requires Claude Code v2.1.285 or later.

| Setting                                                                        | Where you set it                              | What Claude Code ignores in a repository’s settings                                                                                                                                                     |
|:-------------------------------------------------------------------------------|:----------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `network.deniedDomains` or a `WebFetch(domain:...)` deny rule                  | Managed settings, `--settings`                | `httpProxyPort` and `socksProxyPort`                                                                                                                                                                    |
| `network.strictAllowlist`                                                      | Managed settings, `--settings`, user settings | The proxy ports, `allowedDomains`, and `WebFetch(domain:...)` allow rules                                                                                                                               |
| `filesystem.denyRead`, a `Read(...)` deny rule, or a `credentials.files` entry | Managed settings, `--settings`                | An `allowRead`, `allowWrite`, `Edit(...)` allow, or `additionalDirectories` entry at or under a path that managed settings, `--settings`, or user settings deny reading, or a glob that could match one |

These locks change what sandboxed commands can reach. The WebFetch tool and Claude’s file tools still follow a repository’s rules and additional directories.


[​](#custom-proxy-configuration)

Custom proxy configuration

To inspect, filter, or log sandbox traffic with your own tooling, replace the built-in sandbox proxy with a proxy you run on the same machine. To route sandbox traffic through a corporate proxy elsewhere on your network, set `HTTPS_PROXY` instead, as the **Corporate proxy** entry under [Network isolation](#network-isolation) describes. That way, Claude Code’s allowlist still applies. To direct sandboxed commands to your proxy, set the localhost ports it listens on in [sandbox settings](settings-reference.md#sandbox-settings):

```python
{
  "sandbox": {
    "network": {
      "httpProxyPort": 8080,
      "socksProxyPort": 8081
    }
  }
}
```

If you set a port and also set `HTTPS_PROXY` or `HTTP_PROXY`, Claude Code doesn’t forward what sandboxed commands send to your proxy on to the proxy those variables name. To reach a corporate proxy, configure your own proxy to forward to it. Which files can set a port depends on your other sandbox settings. The first case that matches applies:

- **`allowManagedDomainsOnly` is on**: managed settings only
- **The sandbox is [admin-required](#repository-settings-under-an-admin-required-sandbox), or a [narrower network lock](#locks-that-apply-without-an-admin-required-sandbox) applies**: managed settings, `--settings`, and user settings
- **Otherwise**: any settings file

Claude Code ignores a port set anywhere else. Before v2.1.285, any settings file could set a port.

Once either port applies, your proxy is responsible for filtering everything sent to it. Claude Code’s own network controls, such as `allowedDomains`, `deniedDomains`, `strictAllowlist`, approval prompts, and the [local-address check](#hostnames-that-resolve-to-local-addresses), stop applying to that traffic. A sandboxed command can connect to either proxy, so if you set only one port, Claude Code’s domain lists on the other proxy don’t limit what the command reaches through yours.


[​](#troubleshooting)

Troubleshooting

Some commands fail inside the sandbox even though they work outside it. Find the heading that matches your symptom or error message. If your organization’s sandbox is [admin-required](#repository-settings-under-an-admin-required-sandbox), Claude Code ignores the settings these fixes name in a project’s settings files, so save them in `~/.claude/settings.json`, where they apply in every project. If a fix still has no effect, your organization’s managed settings may set that key. A fix that adds an `excludedCommands` pattern removes the sandbox from the commands the pattern matches. See [what an excluded command can do](#run-commands-outside-the-sandbox-with-excludedcommands).


[​](#commands-fail-with-a-host-not-allowed-error)

Commands fail with a host-not-allowed error

Many CLI tools need to reach specific hosts. Approve the host when prompted, or add it to [`allowedDomains`](settings-reference.md#sandbox-network-alloweddomains). If your organization locks the allowlist with `allowManagedDomainsOnly`, there’s no prompt, so ask your administrator to add the host.


[​](#jest-hangs-or-fails)

`jest` hangs or fails

`watchman` is incompatible with the sandbox. Run `jest --no-watchman` instead.


[​](#go-based-clis-fail-tls-verification-on-macos)

Go-based CLIs fail TLS verification on macOS

Tools such as `gh`, `gcloud`, and `terraform` may fail TLS verification under [Seatbelt](#os-level-enforcement). To run these tools outside the sandbox, add a pattern for each tool, such as `gh *`, to [`excludedCommands`](#run-commands-outside-the-sandbox-with-excludedcommands). The tool then runs with your full access and its stored credentials. If you are using `httpProxyPort` with a MITM proxy and custom CA, set [`enableWeakerNetworkIsolation`](settings-reference.md#sandbox-enableweakernetworkisolation) to `true` instead.


[​](#open-osascript-or-browser-based-auth-flows-fail-with-error-600-on-macos)

`open`, `osascript`, or browser-based auth flows fail with error `-600` on macOS

The sandbox blocks Apple Events by default. Set [`allowAppleEvents`](settings-reference.md#sandbox-allowappleevents) to `true` in your user, managed, or CLI settings to allow them. Claude Code ignores this key in project settings. Enabling `allowAppleEvents` removes code-execution isolation, since sandboxed commands can then launch other applications unsandboxed with no user prompt, and can send AppleScript commands to running applications, subject to the macOS automation-consent prompt (TCC). Alternatively, add a pattern such as `open *` to [`excludedCommands`](#run-commands-outside-the-sandbox-with-excludedcommands). Each `open` call then goes through the permission flow, and `open` can launch any file or app, including one Claude wrote.


[​](#docker-commands-fail)

`docker` commands fail

`docker` is incompatible with the sandbox. Take the `docker` commands you need out of the sandbox with an `excludedCommands` pattern such as `docker compose *`. [Run commands outside the sandbox with `excludedCommands`](#run-commands-outside-the-sandbox-with-excludedcommands) explains what an excluded `docker` command can reach. A narrower pattern takes fewer commands out of the sandbox.


[​](#chromium-or-rootless-podman-fails-inside-the-sandbox-on-linux)

Chromium or rootless Podman fails inside the sandbox on Linux

On Linux and WSL2, commands in the sandbox can’t create user namespaces by default, so tools that rely on them fail:

- Chromium exits with `No usable sandbox!`
- `unshare -U true` prints `unshare: unshare failed: Operation not permitted`. With [`allowAllUnixSockets`](settings-reference.md#sandbox-network-allowallunixsockets) on, it can print `No space left on device` instead
- Rootless Podman prints `cannot clone: Operation not permitted`, or stops earlier with `read-only file system` on one of its own folders

In a session with [`CLAUDE_CODE_SUBPROCESS_ENV_SCRUB`](env-vars.md#variables) set to `1`, start Chromium or Electron with `--no-sandbox`, and run any other tool yourself outside Claude Code. In that session, [every command runs sandboxed](#turn-off-the-retry-with-strict-sandbox-mode), and the settings that the other fixes below name have no effect. Each fix works for the tools it names and gives up some isolation:

- For Chromium or Electron, start the browser with `--no-sandbox`. The Claude Code sandbox stays as it is, but the browser runs web content without its own sandbox.
- For rootless Podman, Buildah, or a script or test command that runs a browser or `unshare`, add a pattern to [`sandbox.excludedCommands`](#run-commands-outside-the-sandbox-with-excludedcommands), such as `podman *`. Commands that match run outside the sandbox with your full access, and Claude can edit a script in your working directory before running it. The pattern has to match the command Claude runs, so for a browser, match the test command rather than the browser.
- To keep Chromium’s or Electron’s own sandbox, or to run a nested bubblewrap or `unshare`, set [`sandbox.allowNestedUserNamespaces`](settings-reference.md#sandbox-allownestedusernamespaces) to `true` in `~/.claude/settings.json`, not the project’s `.claude/settings.json`. Requires Claude Code v2.1.305 or later. A command that begins with `unshare` stays sandboxed whatever `excludedCommands` pattern you list, because `unshare` can start any other program. This setting alone isn’t enough for rootless Podman or Buildah, which the sandbox stops in other ways too.

If you set `allowNestedUserNamespaces` to `true`, you turn off a security boundary: code from a sandboxed command can end up running outside the sandbox.Don’t rely on any of the sandbox’s restrictions, including [protected paths](#protected-paths) and [`credentials.files`](settings-reference.md#sandbox-credentials-files) entries, to stop a malicious command. In [auto-allow mode](#auto-allow-mode), that command can run without a permission prompt. If your organization has a security team, check with them before you turn this setting on.


[​](#pbcopy-xclip-or-wl-copy-doesn’t-update-the-clipboard)

`pbcopy`, `xclip`, or `wl-copy` doesn’t update the clipboard

The `pbcopy`, `xclip`, and `wl-copy` clipboard utilities can fail to reach the system clipboard from inside the sandbox, in which case the text piped to them doesn’t arrive. To put Claude’s output on your clipboard, ask Claude to print it in its response, then run [`/copy`](commands.md). `/copy` writes to the clipboard from the Claude Code process rather than from a sandboxed command. When Claude pipes text to one of these tools, adding the tool to [`excludedCommands`](settings-reference.md#sandbox-excludedcommands) doesn’t take that call out of the sandbox on its own.


[​](#a-git-command-fails-with-unable-to-unlink-old)

A git command fails with `unable to unlink old`

`git merge`, `git checkout`, and similar commands fail with `unable to unlink old` when they need to replace a file the sandbox denies writes to. On Linux and WSL2 the error ends with `Read-only file system`. The file can be in one of these places:

- Under a [protected path](#protected-paths) such as `.claude/skills`
- Under one of your `denyWrite` entries
- Outside the directories the sandbox lets commands write to at all

After the failure, Claude may [offer to rerun the command outside the sandbox](#the-unsandboxed-retry-escape-hatch). Approve that retry, or run the git command yourself in another terminal. If you’ve set `allowUnsandboxedCommands` to `false`, Claude can’t offer the retry, so run the command yourself.


[​](#bubblewrap-fails-to-start-inside-a-container)

Bubblewrap fails to start inside a container

In an unprivileged container, [bubblewrap](#os-level-enforcement) can’t mount a fresh `/proc` filesystem, so sandboxed commands fail with a `bwrap` error such as `Can't mount proc on /newroot/proc: Operation not permitted`. Set [`enableWeakerNestedSandbox`](settings-reference.md#sandbox-enableweakernestedsandbox) to `true` so the sandbox bind-mounts the container’s existing `/proc` instead. Only use this setting when the outer container already provides the isolation boundary you need, since the setting exposes process information to sandboxed commands that a fresh `/proc` mount would hide.


[​](#0-byte-read-only-files-appear-at-claude-settings-paths-and-“yes-and-don’t-ask-again”-doesn’t-save)

0-byte read-only files appear at `.claude` settings paths, and “Yes, and don’t ask again” doesn’t save

On Linux and WSL2, the sandbox holds a write denial on a file that doesn’t exist yet by creating a 0-byte read-only placeholder there while a sandboxed command runs. The sandbox removes the placeholder afterward. If a session is killed before that cleanup runs, for example by SIGKILL, the placeholders stay behind. Later sessions bind the placeholders read-only again on every start, so a settings write such as saving a permission choice fails at a path where a placeholder remains. Run `claude doctor` in your terminal to list the leftover placeholder files. The [`Sandbox mask files left behind at write-deny paths`](errors.md#stale-sandbox-mask-files-left-by-a-killed-session) warning names some of them and counts the rest. Delete each file with `rm` while no other Claude Code session is running in that project. Before v2.1.257, Claude Code left the same placeholders behind without flagging them.


[​](#git-over-ssh-fails-with-the-sandbox-on)

`git` over SSH fails with the sandbox on

On macOS, `git fetch`, `git pull`, and `git push` against an SSH remote fail inside the sandbox even when the host is allowed. On Linux and WSL2, they work once the host is allowed. Claude Code tunnels git’s SSH connection through the [sandbox proxy](#network-isolation), and the macOS tunnel can’t authenticate to that proxy. On Linux and WSL2, check these if the connection still fails:

- **The host is allowed on port 22**: an `allowedDomains` entry with no port, such as `"git.example.com"`, covers it
- **Your corporate proxy permits port 22**: if your network requires an upstream proxy, the tunnel goes through it too
- **The key is readable as a file**: the sandbox can block the `ssh-agent` socket, and a `denyRead` or `credentials` entry for `~/.ssh` hides your key files

On macOS, switch the remote to HTTPS, which needs HTTPS credentials such as a personal access token:

```python
git remote set-url origin https://git.example.com/example-org/example-repo.git
```

If you have to keep the SSH remote, take git’s network commands out of the sandbox with [`excludedCommands`](#run-commands-outside-the-sandbox-with-excludedcommands):

```python
{
  "sandbox": {
    "excludedCommands": ["git fetch *", "git pull *", "git push *"]
  }
}
```

These entries match `git push origin main`. A call that adds a `cd`, uses `git -C`, or contains a command substitution stays sandboxed. The excluded git commands can reach any host, not only the ones in `allowedDomains`. Plain `ssh`, `scp`, and `rsync` over SSH fail for the reason [the database client entry](#a-database-client-or-other-non-http-tool-fails-to-reach-an-allowed-host) gives.


[​](#a-database-client-or-other-non-http-tool-fails-to-reach-an-allowed-host)

A database client or other non-HTTP tool fails to reach an allowed host

A tool that ignores the proxy environment variables can’t connect from inside the sandbox, even to a host in `allowedDomains`. A sandboxed command has [no direct route to the network](#network-isolation), so a tool that opens its own connection fails. Most database drivers, plain `ssh`, and tools that use UDP behave this way. The failure looks like a network or name resolution error:

- **macOS**: `Operation not permitted`, or a name resolution error such as `Could not resolve host`
- **Linux and WSL2**: `Network is unreachable`, or a name resolution error such as `Temporary failure in name resolution`

A tool that uses the proxy fails differently when its host isn’t allowed. You get a network prompt, or the tool receives a `403` response from the proxy. To let the tool connect, run the command that needs it outside the sandbox with [`excludedCommands`](#run-commands-outside-the-sandbox-with-excludedcommands). This example excludes one script and adds an [ask rule](permissions.md) so that you approve each run:

```python
{
  "sandbox": {
    "excludedCommands": ["python scripts/load_orders.py *"]
  },
  "permissions": {
    "ask": ["Bash(python scripts/load_orders.py *)"]
  }
}
```

The script runs with your full access, and Claude can edit a script that’s inside your working directory, so review it when the prompt appears.


[​](#a-command-fails-to-reach-a-server-on-localhost)

A command fails to reach a server on localhost

By default, a sandboxed command can’t connect directly to a server that’s running on your machine outside the sandbox, such as a dev server or a database in a container. What you can change depends on your platform:

- **macOS**: set [`network.allowLocalBinding`](settings-reference.md#sandbox-network-allowlocalbinding) to `true`. Sandboxed commands can then listen on network ports and connect to any port on localhost, which includes every other service listening there. A localhost service that doesn’t require authentication, such as a debugger, can then act for the command outside the sandbox, and a command that listens on a non-loopback address accepts connections from other machines
- **Linux and WSL2**: a sandboxed command’s `localhost` is private to that command. The command can listen on a port and reach servers it started itself. A direct connection to `localhost` or `127.0.0.1` doesn’t reach servers on the host, and `allowLocalBinding` has no effect. Run the command that needs the host’s server outside the sandbox with [`excludedCommands`](#run-commands-outside-the-sandbox-with-excludedcommands), where it has no filesystem or network limits. For connections that go through the sandbox proxy, see [Hostnames that resolve to local addresses](#hostnames-that-resolve-to-local-addresses)

This example turns the setting on for macOS:

```python
{
  "sandbox": {
    "network": {
      "allowLocalBinding": true
    }
  }
}
```

An `allowedDomains` entry for `localhost` applies to connections that go through the proxy, so it doesn’t change a direct connection. Claude Code sets `NO_PROXY` for sandboxed commands so that they connect to `localhost` directly instead of through the proxy. The entry also exposes every port on your machine’s localhost to a command that does use the proxy. For a development hostname that points at `127.0.0.1`, see [An allowed hostname is refused with `resolved to a loopback address`](#an-allowed-hostname-is-refused-with-resolved-to-a-loopback-address).


[​](#an-allowed-hostname-is-refused-with-resolved-to-a-loopback-address)

An allowed hostname is refused with `resolved to a loopback address`

The sandbox proxy refuses an allowed hostname that [resolves to a local address](#hostnames-that-resolve-to-local-addresses), which affects development names such as `myapp.test` that point at `127.0.0.1`. The command sees a `403` response whose body names the kind of address, such as `Connection to myapp.test blocked: resolved to a loopback address`. Add the IP address the name resolves to alongside the hostname in `allowedDomains`, each with the port your server listens on:

```python
{
  "sandbox": {
    "network": {
      "allowedDomains": ["myapp.test:3000", "127.0.0.1:3000"]
    }
  }
}
```

An IP address entry with no port lets sandboxed commands reach every service listening on that address. Before v2.1.284, the proxy connected to whatever address an allowed hostname resolved to.


[​](#/sandbox-fails-with-sandbox-settings-are-overridden-by-a-higher-priority-configuration)

`/sandbox` fails with `Sandbox settings are overridden by a higher-priority configuration`

`/sandbox` prints `Error: Sandbox settings are overridden by a higher-priority configuration and cannot be changed locally.` instead of opening its panel when a higher [settings level](settings.md#settings-precedence) sets `sandbox.enabled`, `sandbox.autoAllowBashIfSandboxed`, or `sandbox.allowUnsandboxedCommands`. The panel saves your choices to `.claude/settings.local.json`, and a value saved there can’t override those levels. Managed settings and `--settings` rank above local settings. To see which of them this session loaded, run `/status` and read the `Setting sources` line:

- **`Command line arguments`**: if you started Claude Code with [`--settings`](settings.md#change-a-setting-for-one-session), check whether the file or JSON you passed sets one of those keys. If it does, change the value there, or start Claude Code again without those keys.
- **`Enterprise managed settings`**: your organization’s managed settings are loaded. If they set one of those keys, you can’t change that key from `/sandbox` or from any settings file you control, so ask your administrator.


[​](#/sandbox-prints-sandbox-settings-not-changed)

`/sandbox` prints `Sandbox settings not changed`

This line means `/sandbox` couldn’t save the choice you made in its panel to your project’s `.claude/settings.local.json`:

```python
✗ Sandbox settings not changed: /home/you/project/.claude/settings.local.json couldn't be updated (EACCES). Start Claude Code in a project folder you can write to.
```

If the reason in parentheses is `EACCES`, `EPERM`, or `EROFS`, start Claude Code in a project folder you can write to, then run `/sandbox` again in that session. If the reason begins with `Invalid JSON syntax in settings file`, correct the JSON in your project’s `.claude/settings.local.json`, then run `/sandbox` again. If no writable project folder is available to you, turn the sandbox on from your user settings instead. Add this to `~/.claude/settings.json`:

```python
{
  "sandbox": {
    "enabled": true
  }
}
```

This turns on [auto-allow mode](#sandbox-modes). For regular permissions mode, also set [`sandbox.autoAllowBashIfSandboxed`](settings-reference.md#sandbox-autoallowbashifsandboxed) to `false`. The change takes effect in your running session at the next shell command Claude runs, and the **Mode** tab of `/sandbox` then marks the mode in effect.


[​](#limitations)

Limitations

Sandboxing reduces risk but is not a complete isolation boundary. Review the limitations below before relying on it as a hard security control.


[​](#security-limitations)

Security limitations

- **Network filtering**: the sandbox restricts which domains processes can connect to. By default the built-in proxy does not terminate or inspect TLS on outbound traffic, so the contents of encrypted connections are not examined. The experimental [`network.tlsTerminate`](settings-reference.md#sandbox-network-tlsterminate) setting terminates TLS at the proxy for [`mask` credential substitution](#mask-credentials) but does not add content filtering. You are responsible for ensuring that only trusted domains are allowed in your policy.

Allowing broad domains such as `github.com` can create paths for data exfiltration. Because the proxy makes its allow decision from the client-supplied hostname without inspecting TLS, code running inside the sandbox can potentially reach hosts outside the allowlist through traffic-shaping techniques. If your threat model requires stronger guarantees, configure a [custom proxy](#custom-proxy-configuration) that terminates TLS and inspects traffic, and install its CA certificate inside the sandbox. Stronger TLS-aware network isolation is an active area of development.

- **Privilege escalation via Unix sockets**: the `allowUnixSockets` configuration can inadvertently grant access to system services that could lead to sandbox bypasses. For example, allowing access to `/var/run/docker.sock` effectively grants access to the host system through the Docker socket. Consider carefully any Unix sockets that you allow through the sandbox.
- **Filesystem permission escalation**: overly broad filesystem write permissions can enable privilege escalation attacks. Allowing writes to directories containing executables in `$PATH`, system configuration directories, or user shell configuration files such as `.bashrc` or `.zshrc` can lead to code execution in different security contexts when other users or system processes access these files.
- **Linux sandbox strength**: the Linux implementation provides strong filesystem and network isolation but includes an `enableWeakerNestedSandbox` mode that enables it to work inside Docker environments without privileged namespaces. This option considerably weakens security and should only be used when additional isolation is otherwise enforced.
- **Apple Events on macOS**: the macOS sandbox blocks Apple Events by default. The `allowAppleEvents` setting lifts this restriction so tools such as `open` and `osascript` work, but it removes code-execution isolation: sandboxed commands can launch other applications unsandboxed with no user prompt, and can send AppleScript commands to running applications, subject to the per-app macOS automation-consent prompt (TCC). It is only honored from user, managed, or CLI settings. Project settings cannot enable it.
- **User namespaces on Linux and WSL2**: by default, sandboxed commands can’t create user namespaces. If you set [`allowNestedUserNamespaces`](settings-reference.md#sandbox-allownestedusernamespaces) to `true`, you turn off a security boundary: code from a sandboxed command can end up running outside the sandbox. Before you turn this setting on, read the warning in [Chromium or rootless Podman fails inside the sandbox on Linux](#chromium-or-rootless-podman-fails-inside-the-sandbox-on-linux).


[​](#scope)

Scope

The sandbox isolates shell commands and their child processes. [What runs outside the sandbox](#what-runs-outside-the-sandbox) lists the tools and helper processes it doesn’t cover. Computer use and subagents relate to the sandbox as follows:

- **Computer use**: when Claude opens apps and controls your screen, it runs on your actual desktop rather than in an isolated environment. Per-app permission prompts gate each application. See [computer use in the CLI](computer-use.md) or [computer use in Desktop](../16-Mobile-Desktop/desktop.md#let-claude-use-your-computer).
- **Subagents**: [subagents](../09-Agents-Patterns/sub-agents.md) run in the same process as the parent session and use the same sandbox configuration. Bash commands inside a subagent are sandboxed when sandboxing is enabled in the parent session.
- **Background sessions**: a [background session](../09-Agents-Patterns/agent-view.md) runs in its own process, and its Bash commands are sandboxed when [its settings](../09-Agents-Patterns/agent-view.md#settings-and-provider) enable sandboxing.
- **A boundary around the whole process**: to put the processes in [What runs outside the sandbox](#what-runs-outside-the-sandbox) behind a boundary too, run Claude Code (local mode) inside the [sandbox runtime](sandbox-environments.md#sandbox-runtime) with a network allowlist limited to the hosts you approve, or in the [dev container](devcontainer.md) with its firewall script. For the background service and the sessions it hosts, see [Run Claude Code behind a corporate launcher](../13-Enterprise-Admin/corporate-launcher.md).
- **Mods**: a [mod](../08-Plugins-Skills/plugins-mods-overview.md) is a plugin that runs its own code inside Claude Code, and a process that a mod starts runs outside the sandbox. See [What a mod can reach](../08-Plugins-Skills/plugins-mods-overview.md#what-a-mod-can-reach).

Effective sandboxing requires both filesystem and network isolation. Without network isolation, a compromised agent could exfiltrate sensitive files like SSH keys. Without filesystem isolation, whether from a permissive policy or from [disabling the filesystem layer](#disable-filesystem-isolation), a compromised agent could backdoor system resources to gain network access. When you widen the defaults, check that an `allowWrite` path, a broad `allowedDomains` entry, or an `excludedCommands` exception does not undo a restriction on the other side.


[​](#see-also)

See also

- [Sandbox environments](sandbox-environments.md): compare the built-in sandbox with dev containers, containers, and VMs
- [Security](../13-Enterprise-Admin/security.md): security features and best practices
- [Permissions](permissions.md): permission configuration and access control
- [All settings](settings-reference.md): every settings key
- [CLI reference](cli-reference.md): command-line options

---

## Run prompts on a schedule - Claude Code Docs

Source: https://code.claude.com/docs/en/scheduled-tasks
Path: 02-Claude-Code-CLI/scheduled-tasks.md

## On this page

- [Compare scheduling options](#compare-scheduling-options)
- [Run a prompt repeatedly with /loop](#run-a-prompt-repeatedly-with-%2Floop)
  - [Run on a fixed interval](#run-on-a-fixed-interval)
  - [Let Claude choose the interval](#let-claude-choose-the-interval)
  - [Run the built-in maintenance prompt](#run-the-built-in-maintenance-prompt)
  - [Customize the default prompt with loop.md](#customize-the-default-prompt-with-loop-md)
  - [Stop a loop](#stop-a-loop)
  - [Detach without stopping a loop](#detach-without-stopping-a-loop)
- [Set a one-time reminder](#set-a-one-time-reminder)
- [Manage session-scoped scheduled tasks](#manage-session-scoped-scheduled-tasks)
- [How session-scoped scheduled tasks run](#how-session-scoped-scheduled-tasks-run)
  - [Jitter](#jitter)
  - [How late a recurring task runs](#how-late-a-recurring-task-runs)
  - [When a one-shot task runs early](#when-a-one-shot-task-runs-early)
  - [Seven-day expiry](#seven-day-expiry)
- [Cron expression reference](#cron-expression-reference)
- [Disable session-scoped scheduled tasks](#disable-session-scoped-scheduled-tasks)
- [Limitations](#limitations)

Automation

# Run prompts on a schedule

Copy pageCopy page

Use /loop and the cron scheduling tools to run prompts repeatedly, poll for status, or set one-time reminders within a Claude Code session.

Copy pageCopy page

Session-scoped scheduled tasks let Claude re-run a prompt automatically on an interval within a Claude Code session. Use them to poll a deployment, babysit a PR, check back on a long-running build, or remind yourself to do something later in the session.

These cases are covered on other pages:

- **Reacting to events as they happen instead of polling**: see [Channels](channels.md). Your CI can push the failure into the session directly.
- **Keeping the session working turn after turn toward a condition rather than on an interval**: see [`/goal`](goal.md).

Tasks are session-scoped. When you resume with `--resume` or `--continue`, Claude Code restores tasks that haven’t [expired](#seven-day-expiry), except those listed under [Limitations](#limitations). For scheduling that survives independently of any session, create a [cloud scheduled task](web-scheduled-tasks.md), set up a [Desktop scheduled task](../16-Mobile-Desktop/desktop-scheduled-tasks.md), or use [GitHub Actions](github-actions.md).


[​](#compare-scheduling-options)

Compare scheduling options

Claude Code offers three ways to schedule recurring or one-off work:

|                            | [Cloud](web-scheduled-tasks.md)                                                | [Desktop](../16-Mobile-Desktop/desktop-scheduled-tasks.md)                                                            | [`/loop`](scheduled-tasks.md)                                             |
|:---------------------------|:--------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------|
| Runs on                    | Cloud, Anthropic-managed by default                                       | Your machine                                                                                           | Your machine                                                                    |
| Requires machine on        | No                                                                        | Yes                                                                                                    | Yes                                                                             |
| Requires open session      | No                                                                        | No                                                                                                     | Yes                                                                             |
| Persistent across restarts | Yes                                                                       | Yes                                                                                                    | Restored on `--resume`, with [exceptions](scheduled-tasks.md#limitations) |
| Access to local files      | No (fresh clone)                                                          | Yes                                                                                                    | Yes                                                                             |
| MCP servers                | Connectors configured per task                                            | [Config files](../06-MCP-Tools/General/mcp.md) and connectors                                                            | Inherits from session                                                           |
| Permission prompts         | [Auto mode](web-scheduled-tasks.md#permission-prompts-during-a-run) by default | Configurable per task                                                                                  | Inherits from session                                                           |
| Customizable schedule      | Yes                                                                       | Yes                                                                                                    | Yes                                                                             |
| Minimum interval           | 1 hour                                                                    | 1 minute when Claude sets it, [1 hour in the forms](../16-Mobile-Desktop/desktop-scheduled-tasks.md#schedule-options) | 1 minute                                                                        |

Use **cloud tasks** for work that should run reliably without your machine. Use **Desktop tasks** when you need access to local files and tools. Use **`/loop`** for quick polling during a session.


[​](#run-a-prompt-repeatedly-with-/loop)

Run a prompt repeatedly with /loop

The `/loop` [bundled skill](commands.md) is the quickest way to run a prompt on repeat while the session stays open. Both the interval and the prompt are optional, and what you provide determines how the loop behaves.

| What you provide          | Example                     | What happens                                                                                                  |
|:--------------------------|:----------------------------|:--------------------------------------------------------------------------------------------------------------|
| Interval and prompt       | `/loop 5m check the deploy` | Your prompt runs on a [fixed schedule](#run-on-a-fixed-interval)                                              |
| Prompt only               | `/loop check the deploy`    | Your prompt runs at an [interval Claude chooses](#let-claude-choose-the-interval) each iteration              |
| Interval only, or nothing | `/loop`                     | The [built-in maintenance prompt](#run-the-built-in-maintenance-prompt) runs, or your `loop.md` if one exists |

You can also pass a skill as the prompt, for example `/loop 20m /review-pr 1234`, to re-run that skill each iteration. A scheduled fire only runs skills that Claude is [allowed to invoke on its own](../08-Plugins-Skills/skills.md#control-who-invokes-a-skill). The following reach Claude as plain text instead of executing:

- Built-in commands such as `/permissions`, `/model`, or `/clear`
- Skills marked [`disable-model-invocation: true`](../08-Plugins-Skills/skills.md#frontmatter-reference), including the bundled `/verify` skill
- Skills withheld from Claude by a [`skillOverrides`](../08-Plugins-Skills/skills.md#override-skill-visibility-from-settings) setting or a `Skill` [deny rule](../08-Plugins-Skills/skills.md#restrict-claude%E2%80%99s-skill-access)
- [MCP prompts](../06-MCP-Tools/General/mcp.md#use-mcp-prompts-as-commands) such as `/mcp__github__list_prs`


[​](#run-on-a-fixed-interval)

Run on a fixed interval

When you supply an interval, Claude converts it to a cron expression, schedules the job, and confirms the cadence and job ID.

```python
/loop 5m check if the deployment finished and tell me what happened
```

The interval can lead the prompt as a bare token like `30m`, or trail it as a clause like `every 2 hours`. Supported units are `s` for seconds, `m` for minutes, `h` for hours, and `d` for days. Seconds are rounded up to the nearest minute since cron has one-minute granularity. Intervals that don’t map to a clean cron step, such as `7m` or `90m`, are rounded to the nearest interval that does and Claude tells you what it picked.


[​](#let-claude-choose-the-interval)

Let Claude choose the interval

When you omit the interval, Claude chooses one dynamically instead of running on a fixed cron schedule. After each iteration it picks a delay between one minute and one hour based on what it observed: short waits while a build is finishing or a PR is active, longer waits when nothing is pending. The chosen delay and the reason for it are printed at the end of each iteration. The example below checks CI and review comments, with Claude waiting longer between iterations once the PR goes quiet:

```python
/loop check whether CI passed and address any review comments
```

In a session where the [Monitor tool is available](tools-reference.md#monitor-tool), Claude may use it directly when you ask for a dynamic `/loop` schedule. Monitor runs a background script and streams each output line back, which avoids polling altogether and is often more token-efficient and responsive than re-running a prompt on an interval. A dynamically scheduled loop appears in your [scheduled task list](#manage-scheduled-tasks) like any other task, so you can list or cancel it the same way. The list shows its pending wakeup as a one-shot task, so a wakeup scheduled for `:00` or `:30` can [run a little early](#when-a-one-shot-task-runs-early). The [seven-day expiry](#seven-day-expiry) applies to the loop too.

Dynamically chosen intervals and the [built-in maintenance prompt](#run-the-built-in-maintenance-prompt) work on every provider, and with [feature-flag fetching](env-vars.md#features-that-need-feature-flag-fetching) turned off. On Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, and Microsoft Foundry, or with fetching turned off, both require Claude Code v2.1.248 or later.


[​](#run-the-built-in-maintenance-prompt)

Run the built-in maintenance prompt

When you omit the prompt, Claude uses a built-in maintenance prompt instead of one you supply. On each iteration it works through the following, in order:

- continue any unfinished work from the conversation
- tend to the current branch’s pull request: review comments, failed CI runs, merge conflicts
- run cleanup passes such as bug hunts or simplification when nothing else is pending

Claude does not start new initiatives outside that scope, and irreversible actions such as pushing or deleting only proceed when they continue something the transcript already authorized.

```python
/loop
```

A bare `/loop` runs this prompt at a [dynamically chosen interval](#let-claude-choose-the-interval). Add an interval, for example `/loop 15m`, to run it on a fixed schedule instead. To replace the built-in prompt with your own default, see [Customize the default prompt with loop.md](#customize-the-default-prompt-with-loop-md).


[​](#customize-the-default-prompt-with-loop-md)

Customize the default prompt with loop.md

Create a `loop.md` file to replace the [built-in maintenance prompt](#run-the-built-in-maintenance-prompt) with your own instructions. It defines a single default prompt for bare `/loop`, not a list of separate scheduled tasks, and Claude Code ignores it whenever you supply a prompt on the command line. To schedule additional prompts alongside it, use `/loop <prompt>` or [ask Claude directly](#manage-scheduled-tasks). Claude looks for the file in two locations and uses the first one it finds.

| Path                | Scope                                                            |
|:--------------------|:-----------------------------------------------------------------|
| `.claude/loop.md`   | Project-level. Takes precedence when both files exist.           |
| `~/.claude/loop.md` | User-level. Applies in any project that does not define its own. |

The file is plain Markdown with no required structure. Write it as if you were typing the `/loop` prompt directly. The following example keeps a release branch healthy:

.claude/loop.md

```python
Check the `release/next` PR. If CI is red, pull the failing job log,
diagnose, and push a minimal fix. If new review comments have arrived,
address each one and resolve the thread. If everything is green and
quiet, say so in one line.
```

Edits to `loop.md` take effect on the next iteration, so you can refine the instructions while a loop is running. When no `loop.md` exists in either location, the loop falls back to the built-in maintenance prompt. Keep the file concise: content beyond 25,000 bytes is truncated.


[​](#stop-a-loop)

Stop a loop

- **[Self-paced loop](#let-claude-choose-the-interval)**: while the loop is waiting for its next iteration, press `Esc` to stop it. You can also stop it with `Ctrl+C` while Claude is idle, except in a [background session you’ve attached to](#detach-without-stopping-a-loop). A `Pending wakeup cancelled` notice confirms that the loop won’t fire again.
- **[Fixed-interval loop](#run-on-a-fixed-interval)**: to stop a loop such as `/loop 5m`, ask Claude to cancel it, for example `cancel the deploy check loop`. `Esc` and `Ctrl+C` don’t stop it, or any task you [scheduled by asking Claude directly](#manage-scheduled-tasks). A loop you don’t cancel ends when [seven days elapse](#seven-day-expiry).

In [self-paced mode](#let-claude-choose-the-interval), Claude can also end the loop on its own once the task is complete. Claude calls the [`ScheduleWakeup` tool](tools-reference.md) with `stop: true`, which cancels the pending wakeup immediately. If an iteration ends without either rescheduling or stopping, Claude Code schedules one fallback wakeup about 20 minutes later and ends the loop when that iteration doesn’t reschedule either.


[​](#detach-without-stopping-a-loop)

Detach without stopping a loop

When you’re [attached to a background session](../09-Agents-Patterns/agent-view.md#attach-to-a-session) and Claude is idle, press `Ctrl+C` twice on an empty prompt to detach. A self-paced loop waiting there for its next iteration keeps running, and that iteration starts on schedule. To stop the loop instead, press `Esc` before you detach. Detaching with `Ctrl+C` without stopping the loop requires Claude Code v2.1.295 or later.


[​](#set-a-one-time-reminder)

Set a one-time reminder

For one-shot reminders, describe what you want in natural language instead of using `/loop`. Claude schedules a single-fire task that deletes itself after running.

```python
remind me at 3pm to push the release branch
```

```python
in 45 minutes, check whether the integration tests passed
```

Claude pins the fire time to a specific minute and hour using a cron expression and confirms when it will fire.


[​](#manage-session-scoped-scheduled-tasks)

Manage session-scoped scheduled tasks

Ask Claude in natural language to list or cancel tasks, or reference the underlying tools directly.

```python
what scheduled tasks do I have?
```

```python
cancel the deploy check job
```

These are the underlying tools Claude uses:

| Tool         | Purpose                                                                                                         |
|:-------------|:----------------------------------------------------------------------------------------------------------------|
| `CronCreate` | Schedule a new task. Accepts a 5-field cron expression, the prompt to run, and whether it recurs or fires once. |
| `CronList`   | List scheduled tasks with their IDs, schedules, [next run times](#jitter), and prompts.                         |
| `CronDelete` | Cancel a task by ID.                                                                                            |

Each scheduled task has an 8-character ID you can pass to `CronDelete`. A session can hold up to 50 scheduled tasks at once.


[​](#how-session-scoped-scheduled-tasks-run)

How session-scoped scheduled tasks run

The scheduler checks every second for due tasks and enqueues them at low priority. A scheduled prompt fires between your turns, not while Claude is mid-response. If Claude is busy when a task comes due, the prompt waits until the current turn ends. All times are interpreted in your local timezone. A cron expression like `0 9 * * *` means 9am wherever you’re running Claude Code, not UTC.


[​](#jitter)

Jitter

A scheduled task can run at a different time than its schedule says. If every session’s tasks ran exactly on schedule, many of them would call the API at the same moment, so Claude Code shifts each task’s run time. Recurring tasks run late, except a task that runs every five minutes, written `*/5 * * * *`. One-shot tasks scheduled on the hour or half hour run a little early. To see when a task is next due, read the row under Claude’s `CronCreate` call in your terminal. The row shows that time after the schedule, for example `next run 10:21 AM`. To check again later, [ask Claude to list your tasks](#manage-scheduled-tasks) and look for `next run` in the rows under the `CronList` call. Next run times in these rows require Claude Code v2.1.299 or later.


[​](#how-late-a-recurring-task-runs)

How late a recurring task runs

Unless it runs every five minutes, a recurring task starts each run late by up to half the gap to the next run, and by at most 30 minutes. Your task is one of these three cases:

- **Evenly spaced runs**: a task with equal gaps, such as hourly, daily, or every 10 minutes, runs the same number of minutes late every time, including when the session is idle.
- **Unevenly spaced runs**: a task with uneven gaps, such as one scheduled for `:00` and `:15` each hour, can run a different number of minutes late at each.
- **Every five minutes**: a task written `*/5 * * * *` isn’t delayed. A run exactly five minutes after the last one would start after a five-minute [prompt cache](prompt-caching.md#which-ttl-each-request-gets) had expired, so each run starts 15 seconds sooner.

Find your schedule in the first column of this table to see when each of its runs starts.

| Schedule                                                                 | When each run starts                        |
|:-------------------------------------------------------------------------|:--------------------------------------------|
| Every 5 minutes, written `*/5 * * * *`, which is what `/loop 5m` creates | 4 minutes 45 seconds after the previous run |
| Every 10 minutes                                                         | 0 to 5 minutes late                         |
| Every 30 minutes                                                         | 0 to 15 minutes late                        |
| Every hour, or less often such as daily                                  | 0 to 30 minutes late                        |

For example, `7,37 * * * *` schedules a task for `:07` and `:37`, which are 30 minutes apart, so its delay is somewhere between 0 and 15 minutes. If this task’s delay is 14 minutes, it runs at `:21` and `:51` every hour. Changing the schedule to a different minute moves the run time, and a delay is still added on top.


[​](#when-a-one-shot-task-runs-early)

When a one-shot task runs early

A one-shot task scheduled for `:00` or `:30` runs up to 90 seconds early. Claude Code doesn’t shift a one-shot task scheduled for any other minute, so when the timing matters, schedule it off the hour and half hour: `3 9 * * *` instead of `0 9 * * *`.


[​](#seven-day-expiry)

Seven-day expiry

Recurring tasks automatically expire 7 days after creation. The task fires one final time, then deletes itself. This bounds how long a forgotten loop can run. If you need a recurring task to last longer, cancel and recreate it before it expires, or use [cloud scheduled tasks](web-scheduled-tasks.md) or [Desktop scheduled tasks](../16-Mobile-Desktop/desktop-scheduled-tasks.md) for durable scheduling.


[​](#cron-expression-reference)

Cron expression reference

`CronCreate` accepts standard 5-field cron expressions: `minute hour day-of-month month day-of-week`. All fields support wildcards (`*`), single values (`5`), steps (`*/15`), ranges (`1-5`), and comma-separated lists (`1,15,30`).

| Example        | Meaning                      |
|:---------------|:-----------------------------|
| `*/5 * * * *`  | Every 5 minutes              |
| `0 * * * *`    | Every hour on the hour       |
| `7 * * * *`    | Every hour at 7 minutes past |
| `0 9 * * *`    | Every day at 9am local       |
| `0 9 * * 1-5`  | Weekdays at 9am local        |
| `30 14 15 3 *` | March 15 at 2:30pm local     |

Day-of-week uses `0` or `7` for Sunday through `6` for Saturday. Extended syntax like `L`, `W`, `?`, and name aliases such as `MON` or `JAN` is not supported. When both day-of-month and day-of-week are constrained, a date matches if either field matches. This follows standard vixie-cron semantics.


[​](#disable-session-scoped-scheduled-tasks)

Disable session-scoped scheduled tasks

Set `CLAUDE_CODE_DISABLE_CRON=1` in your environment to disable the scheduler entirely. The cron tools and `/loop` become unavailable, and any already-scheduled tasks stop firing. See [Environment variables](env-vars.md) for the full list of disable flags.


[​](#limitations)

Limitations

Session-scoped scheduling has inherent constraints:

- Tasks only fire while Claude Code is running and idle. Closing the terminal or letting the session exit stops them firing. [Backgrounding the session](../09-Agents-Patterns/agent-view.md#from-inside-a-session) carries `/loop` tasks over to a background session, which keeps running without a terminal.
- No catch-up for missed fires. If a task’s scheduled time passes while Claude is busy on a long-running request, it fires once when Claude becomes idle, not once per missed interval.
- In a [background session](../09-Agents-Patterns/agent-view.md#from-inside-a-session), a [self-paced loop](#let-claude-choose-the-interval) stops if its next wakeup comes due while the session’s process isn’t running, such as after a crash. When the process starts again, the transcript shows a [notice that the wakeup won’t fire](errors.md#restarted-after-its-next-loop-wakeup-was-due). To continue the loop, [reply to the session](../09-Agents-Patterns/agent-view.md#peek-and-reply) and ask Claude to keep it running.
- When you resume a session with `claude --resume` or `claude --continue`, Claude Code restores the tasks scheduled with `CronCreate`, except recurring tasks that have [expired](#seven-day-expiry) and one-shot tasks whose scheduled time has passed. A [self-paced `/loop`](#let-claude-choose-the-interval) isn’t restored, so run `/loop` again to restart it.
- A restored recurring task doesn’t fire for the runs it missed while the session wasn’t running. Its next run is the first one due after you resume, and [jitter](#jitter) applies to that run.
- When you resume with `claude --resume` or `claude --continue`, Claude Code doesn’t restart the background Bash commands and monitors that were running when the session ended. If you still need one, ask Claude to start it again.
- With [feature-flag fetching off](env-vars.md#features-that-need-feature-flag-fetching), Claude Code stores a task you asked to keep across sessions in the project’s `.claude/scheduled_tasks.json` file. When the `.claude` directory or that file is a symlink, Claude Code returns an error instead of scheduling the task. A saved task runs only in the project folder where you created it. If you copy the file into another folder, such as a new worktree, sessions there list the copied tasks but don’t run them, so create the task again in that folder.

For cron-driven automation that needs to run unattended:

- [Cloud scheduled tasks](web-scheduled-tasks.md): run in the cloud on a schedule, via API call, or on GitHub events
- [GitHub Actions](github-actions.md): use a `schedule` trigger in CI
- [Desktop scheduled tasks](../16-Mobile-Desktop/desktop-scheduled-tasks.md): run locally on your machine

---

## Catch security issues as Claude writes code - Claude Code Docs

Source: https://code.claude.com/docs/en/security-guidance
Path: 02-Claude-Code-CLI/security-guidance.md

## On this page

- [Prerequisites](#prerequisites)
- [Install the plugin](#install-the-plugin)
  - [Enable for your team in local sessions](#enable-for-your-team-in-local-sessions)
- [What the plugin checks](#what-the-plugin-checks)
  - [Checks on each file edit](#checks-on-each-file-edit)
  - [Checks at the end of each turn](#checks-at-the-end-of-each-turn)
  - [Checks on each commit or push Claude makes](#checks-on-each-commit-or-push-claude-makes)
  - [Review independence and limits](#review-independence-and-limits)
- [Add your own rules](#add-your-own-rules)
  - [Add guidance for the model-backed reviews](#add-guidance-for-the-model-backed-reviews)
  - [Add custom per-edit patterns](#add-custom-per-edit-patterns)
  - [Rule file lookup locations](#rule-file-lookup-locations)
- [Usage cost](#usage-cost)
- [Disable or uninstall](#disable-or-uninstall)
- [How the plugin integrates with Claude Code](#how-the-plugin-integrates-with-claude-code)
- [How this fits with other security tools](#how-this-fits-with-other-security-tools)
- [Troubleshooting](#troubleshooting)
- [Related resources](#related-resources)

Security scans

# Catch security issues as Claude writes code

Copy pageCopy page

Install the security-guidance plugin to have Claude review its own code changes for vulnerabilities and fix them in the same session.

Copy pageCopy page

The security guidance plugin makes Claude review its own code changes for common vulnerabilities while it works and fix what it finds in the same session. The plugin catches issues such as injection, unsafe deserialization, and unsafe DOM APIs before the code reaches a pull request, reducing how much security review falls to human reviewers downstream. Once installed, the plugin runs automatically. There is nothing to invoke and no separate command to remember. The plugin is the in-session companion to [Code Review](code-review.md), which runs on pull requests. This plugin reduces what reaches the PR. Code Review catches what does. For how the plugin layers with on-demand review and CI scanning, or to scan code you already have rather than changes Claude is writing, see [How this fits with other security tools](#how-this-fits-with-other-security-tools).


[​](#prerequisites)

Prerequisites

- Python 3.7 or later on your `PATH`. The agentic commit review needs Python 3.10 or later, as do all model-backed reviews when Claude Code uses a third-party provider such as Amazon Bedrock or Google Cloud’s Agent Platform. The plugin prefers the versioned interpreters `python3.13` through `python3.10`, then falls back to `python3`, `python`, and `py -3`
- A git repository for the directory you work in. The end-of-turn and commit reviews diff against git state and skip silently outside a repository. The per-edit pattern check works anywhere

On first run the plugin creates a virtual environment under `~/.claude/security/` and installs the Claude Agent SDK into it, which requires `pip` and network access. If that install fails, or the available Python is older than 3.10, the commit review on first-party authentication falls back to a single-shot review instead of the agentic one; on a third-party provider such as Amazon Bedrock or Google Cloud’s Agent Platform the model-backed reviews need the SDK themselves, so they skip. The plugin shows a one-time notice when an older Python is the cause.


[​](#install-the-plugin)

Install the plugin

In a terminal Claude Code session, install from the [official Anthropic marketplace](../08-Plugins-Skills/plugins-anthropic-marketplaces.md):

```python
/plugin install security-guidance@claude-plugins-official
```

`/plugin` opens an interactive panel in the terminal CLI. If Claude replies that `/plugin` isn’t available in this environment, install another way:

- **Claude desktop app, local or SSH session**: use the **Desktop app** tab under [Install a plugin](../08-Plugins-Skills/discover-plugins.md#install-a-plugin)
- **VS Code extension**: install from the [**Manage plugins** dialog](../03-IDE-Integrations/vs-code.md#manage-plugins)
- **Cloud sessions**: a cloud session doesn’t load plugins from your user settings or from the repository’s `.claude/settings.json`, as [What carries over from your setup](cloud-environments.md#what-carries-over-from-your-setup) explains. For plugins your organization distributes through managed settings, see [Manage plugins for your organization](../08-Plugins-Skills/plugins-org.md)

The terminal install prompts for a scope. Choose user scope to write the plugin to your user settings, so it loads in every new local session you start on this machine. If the install fails, match the message Claude Code reports:

- `Marketplace "claude-plugins-official" not found`: add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`, then retry the install.
- `Plugin "<name>" not found in marketplace "claude-plugins-official"`: your local copy of the marketplace catalog may be out of date. Refresh it with `/plugin marketplace update claude-plugins-official`, then retry the install. If the retry prints the same message, see [Plugin not found in marketplace](../08-Plugins-Skills/plugins-troubleshooting.md#plugin-not-found-in-marketplace).

Check the install summary. If it reports `Run /reload-plugins to apply.`, see [Apply plugin changes without restarting](../08-Plugins-Skills/plugins-cli-reference.md#reload-plugins) to activate the plugin in your current session.


[​](#enable-for-your-team-in-local-sessions)

Enable for your team in local sessions

To turn the plugin on in the local sessions your teammates start in the repository, declare it in the project’s checked-in settings:

.claude/settings.json

```python
{
  "enabledPlugins": {
    "security-guidance@claude-plugins-official": true
  }
}
```

Administrators can enable the plugin organization-wide by setting [`enabledPlugins`](settings-reference.md#enabledplugins) in [managed settings](../13-Enterprise-Admin/admin-setup.md).


[​](#what-the-plugin-checks)

What the plugin checks

The plugin reviews Claude’s work at three points, each at a different depth:

- [On each file edit](#on-each-file-edit): a fast pattern match for risky calls, with no model call
- [At the end of each turn](#at-the-end-of-each-turn): a background model review of everything that turn changed
- [On each commit or push Claude makes](#on-each-commit-or-push-claude-makes): a deeper agentic review that reads surrounding code

You can extend each layer by [adding your own rules](#add-your-own-rules). Built-in checks cannot be removed individually, but you can [disable each layer](#disable-or-uninstall) independently.


[​](#checks-on-each-file-edit)

Checks on each file edit

When Claude writes to a file, the plugin scans the new content for known risky patterns. This is a pattern match with no model call, so it adds no usage cost. Example pattern categories:

- Dynamic code execution: `eval(`, `new Function`, `os.system`, `child_process.exec`
- Unsafe deserialization: `pickle`
- DOM injection: `dangerouslySetInnerHTML`, `.innerHTML =`, `document.write`
- Workflow files: edits under `.github/workflows/`, which can grant repository-level permissions

The check runs after the edit lands and appends the warning to Claude’s context for the next step. Each warning fires once per pattern per file per session, so repeat matches in the same file do not flood the conversation. You can [add your own patterns](#add-custom-per-edit-patterns) to this layer with a `security-patterns.yaml` file.


[​](#checks-at-the-end-of-each-turn)

Checks at the end of each turn

A turn is one round of Claude responding: you send a message, Claude works and replies, and the turn ends. After each turn, the plugin computes a git diff of everything that changed in the working tree during the turn, including changes from Claude’s edit tools, Bash commands, and subagents, and sends it to a separate Claude review focused on security. The review runs in the background, so Claude’s reply is not delayed. If the review finds issues, Claude is re-prompted with the findings and addresses them as a follow-up. This catches issues a string match cannot, such as:

- Authorization bypass
- Insecure direct object references
- Injection
- Server-side request forgery
- Weak cryptography

You see both the finding and Claude’s resolution directly in your session. The review covers up to 30 changed files per turn and fires at most three times in a row before yielding back to you.


[​](#checks-on-each-commit-or-push-claude-makes)

Checks on each commit or push Claude makes

When Claude runs `git commit` or `git push` through its Bash tool, the plugin runs a deeper agentic review of the change in the background. This review reads surrounding code, including callers, sanitizers, and related files, to decide whether a finding is real before reporting it. The extra context keeps false positives low on patterns that look dangerous in isolation but are safe in your codebase. This layer fires only on commits and pushes Claude makes through its Bash tool. Commits you run from your own shell, including the `!` shell escape inside a session, are not reviewed. Commit and push reviews are capped at 20 per rolling hour. If the commit review’s findings duplicate what the end-of-turn review already reported, Claude is not re-prompted, so a clean commit produces no visible output from this layer.


[​](#review-independence-and-limits)

Review independence and limits

The plugin does not ask the same Claude instance that wrote the code to grade itself. The per-edit check is a deterministic string match with no model involved. The end-of-turn and commit reviews run as a separate Claude call with a fresh context and a security-focused prompt: the reviewer starts from the diff, has no investment in the original approach, and is instructed only to find problems. None of the layers block writes or commits. Findings reach the writing Claude as instructions, Claude addresses them in the conversation, and the review model can miss issues. Treat the plugin as one layer of defense in depth, not a complete security solution. See [How this fits with other security tools](#how-this-fits-with-other-security-tools).


[​](#add-your-own-rules)

Add your own rules

The plugin has two extension points: a Markdown guidance file for the model-backed reviews, and a YAML or JSON patterns file for the per-edit string match. Both are additive. You can add checks but cannot disable built-in ones from these files.


[​](#add-guidance-for-the-model-backed-reviews)

Add guidance for the model-backed reviews

Create `.claude/claude-security-guidance.md` in your project and describe your threat model and review checklist in plain language. The model-backed reviews load it as additional context alongside the built-in vulnerability checklist. The following example is for a web service with role-gated admin routes and a customer-data logging policy:

.claude/claude-security-guidance.md

```python
# Security guidance for this repo

- Do not log `customer_id` or `account_number` at INFO level or above.
- All routes under `/admin` must call `require_role("admin")` before any database read.
- Use `crypto.timingSafeEqual` for token comparison instead of `===`.
```

These rules are guidance for the reviewer, not deterministic guardrails. The plugin surfaces violations as findings for Claude to fix, but it does not block writes or guarantee every violation is caught. The guidance is additive only: a rule that says to ignore a vulnerability class does not suppress those findings. For hard enforcement, pair the plugin with a [hook that blocks the edit](../07-Hooks/hooks-guide.md#block-edits-to-protected-files) or a CI check.


[​](#add-custom-per-edit-patterns)

Add custom per-edit patterns

Create `.claude/security-patterns.yaml` to add regex or substring rules to the [per-edit pattern check](#on-each-file-edit). These run as deterministic string matches alongside the built-in patterns:

.claude/security-patterns.yaml

```python
patterns:
  - rule_name: internal_api_key
    substrings: ["sk_live_", "AKIA"]
    reminder: "Hardcoded API key prefix. Load credentials from the secret manager."
  - rule_name: tenant_unfiltered_query
    regex: "\\.objects\\.all\\(\\)"
    paths: ["**/src/tenants/**"]
    reminder: "Multi-tenant code must filter by org_id."
```

| Field           | Type   | Description                                                                                                                                             |
|:----------------|:-------|:--------------------------------------------------------------------------------------------------------------------------------------------------------|
| `rule_name`     | string | Identifier shown in the warning                                                                                                                         |
| `reminder`      | string | Warning text appended to Claude’s context, capped at 1 KB                                                                                               |
| `regex`         | string | Python regex matched against the edited content                                                                                                         |
| `substrings`    | list   | Literal substrings; provide this or `regex`                                                                                                             |
| `paths`         | list   | Optional glob patterns; the rule applies only to matching files. Globs match against the full file path, so prefix project-relative patterns with `**/` |
| `exclude_paths` | list   | Optional glob patterns to skip; same matching as `paths`                                                                                                |

The plugin also reads `.claude/security-patterns.yml` and `.claude/security-patterns.json` with the same schema. JSON works on any Python install. The YAML forms require PyYAML to be importable, which the plugin does not install for you. The plugin loads up to 50 custom rules and skips regexes that look prone to catastrophic backtracking.


[​](#rule-file-lookup-locations)

Rule file lookup locations

The plugin looks for `claude-security-guidance.md` and `security-patterns.yaml` in the same locations, independently of how the plugin was enabled:

| Scope         | Path                                        | Notes                                               |
|:--------------|:--------------------------------------------|:----------------------------------------------------|
| User          | `~/.claude/claude-security-guidance.md`     | Applies to every project on your machine            |
| Project       | `.claude/claude-security-guidance.md`       | Checked in with the repository                      |
| Project local | `.claude/claude-security-guidance.local.md` | For personal overrides; add it to your `.gitignore` |

The plugin loads all locations that exist and concatenates them, with a combined cap of 8 KB for the guidance file. Administrators can distribute organization-wide rules by pushing the user-scope file to `~/.claude/` through device management. The same paths apply to `security-patterns.yaml`.


[​](#usage-cost)

Usage cost

The [per-edit pattern check](#on-each-file-edit) makes no model call and adds no cost. The [end-of-turn](#at-the-end-of-each-turn) and [commit](#on-each-commit-or-push-claude-makes) reviews each spend additional model usage that counts toward your [usage](../17-Billing-Plans/costs.md) like any other Claude request. The commit review is agentic and may take several model turns per commit. Expect roughly one review call per turn that changes files and one deeper review per commit, both subject to the caps above. Both model-backed reviews use Claude Opus 4.7 by default. Set `SECURITY_REVIEW_MODEL` to choose a different model for the end-of-turn review and `SG_AGENTIC_MODEL` for the commit review. The plugin is available on all plans.


[​](#disable-or-uninstall)

Disable or uninstall

To turn off individual layers while keeping the rest, set the matching environment variable:

| Variable                        | Effect                                                                     |
|:--------------------------------|:---------------------------------------------------------------------------|
| `ENABLE_PATTERN_RULES=0`        | Disable the [per-edit pattern check](#on-each-file-edit)                   |
| `ENABLE_STOP_REVIEW=0`          | Disable the [end-of-turn diff review](#at-the-end-of-each-turn)            |
| `ENABLE_COMMIT_REVIEW=0`        | Disable the [commit and push review](#on-each-commit-or-push-claude-makes) |
| `ENABLE_CODE_SECURITY_REVIEW=0` | Disable all model-backed reviews at once                                   |
| `SECURITY_GUIDANCE_DISABLE=1`   | Disable the plugin entirely without uninstalling                           |

To pause the plugin in your user scope:

```python
/plugin disable security-guidance@claude-plugins-official
```

To remove it from your user scope:

```python
/plugin uninstall security-guidance@claude-plugins-official
```

If the plugin was enabled through a project’s `.claude/settings.json`, uninstalling it from `/plugin` writes an override to your `.claude/settings.local.json` rather than editing the checked-in file, so the plugin stays off for you while teammates are unaffected. The same dialog also offers to uninstall the plugin for everyone by removing it from the shared `.claude/settings.json`. If it was enabled through [managed settings](../13-Enterprise-Admin/admin-setup.md), only an administrator can disable it.


[​](#how-the-plugin-integrates-with-claude-code)

How the plugin integrates with Claude Code

The plugin is built entirely on [hooks](../07-Hooks/hooks.md), the mechanism for running your own code at specific points in Claude’s loop. It registers:

| Hook event                                                       | Purpose                                                                     |
|:-----------------------------------------------------------------|:----------------------------------------------------------------------------|
| `SessionStart`                                                   | Bootstrap the plugin’s Python environment                                   |
| `UserPromptSubmit`                                               | Capture the working-tree baseline that the end-of-turn review diffs against |
| `PostToolUse` on `Edit`, `Write`, and `NotebookEdit`             | Per-edit pattern match                                                      |
| `Stop`                                                           | End-of-turn diff review, run in the background                              |
| `PostToolUse` on `Bash`, filtered to `git commit` and `git push` | Commit and push review, run in the background                               |

If you build your own hooks, the [plugin’s source](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/security-guidance) is a working example of running a separate model call from a hook and feeding the result back to the session.


[​](#how-this-fits-with-other-security-tools)

How this fits with other security tools

The plugin is one layer in a defense-in-depth approach. It catches issues earliest, while code is still in the editor, but it is not a guarantee and does not replace later checks. A typical stack:

| Stage                  | Tool                                                           | What it covers                                                                                           |
|:-----------------------|:---------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------|
| In session             | Security guidance plugin                                       | Common vulnerabilities in code Claude writes, fixed in the same session                                  |
| On demand, single pass | [`/security-review`](commands.md#all-commands)           | One-time security pass on the current branch, run when you ask                                           |
| On demand, deep scan   | [Claude Security plugin](claude-security.md)             | Multi-agent vulnerability scan of a repository or diff, with independently reviewed findings and patches |
| On pull request        | [Code Review](code-review.md), Team and Enterprise plans | Multi-agent correctness and security review with full codebase context                                   |
| In CI                  | Your existing static analysis and dependency scanners          | Language-specific rules, supply-chain checks, and policy enforcement the plugin does not attempt         |

To find security issues in code you already have, rather than in changes Claude is writing, ask Claude in a session to review a specific file or directory for vulnerabilities, or use the [Claude Security plugin](claude-security.md) for a deeper multi-agent scan of the whole repository; [`/security-review`](commands.md#all-commands) covers only the changes on your current branch. Either way, the review reads the source code in your checkout, not a running site or deployed service.


[​](#troubleshooting)

Troubleshooting

The plugin writes runtime diagnostics to `~/.claude/security/log.txt`. Check there first if reviews are not appearing. Common reasons a review layer skips without a message in the conversation:

- The directory is not a git repository: the end-of-turn and commit reviews require git state and skip outside a repository
- The session has no Anthropic authentication and no third-party provider configured: the model-backed reviews skip and only the per-edit pattern check runs
- A `security-patterns.yaml` file is present but PyYAML is not importable: the file is ignored. Use `security-patterns.json` instead


[​](#related-resources)

Related resources

To go deeper on the pieces this page touches:

- [Code Review](code-review.md): set up the PR-time multi-agent review
- [Automate actions with hooks](../07-Hooks/hooks-guide.md): build your own checks at the same lifecycle points
- [Find plugins in the official marketplace](../08-Plugins-Skills/plugins-anthropic-marketplaces.md#find-plugins-in-the-official-marketplace): where to browse the other official plugins

---

## Manage sessions - Claude Code Docs

Source: https://code.claude.com/docs/en/sessions
Path: 02-Claude-Code-CLI/sessions.md

## On this page

- [Resume a session](#resume-a-session)
  - [Resume a running background session](#resume-a-running-background-session)
  - [What a resumed session restores](#what-a-resumed-session-restores)
  - [Permission mode on resume](#permission-mode-on-resume)
  - [The “Resume this conversation?” dialog](#resume-usage-limit-dialog)
  - [Where the session picker looks](#where-the-session-picker-looks)
  - [/loop, -p, Agent SDK, and background sessions](#%2Floop-p-agent-sdk-and-background-sessions)
  - [Sessions in other worktrees and projects](#sessions-in-other-worktrees-and-projects)
  - [Resume by session ID or name](#resume-by-session-id-or-name)
- [Name your sessions](#name-your-sessions)
- [Use the session picker](#use-the-session-picker)
- [Branch a session](#branch-a-session)
- [Manage context within a session](#manage-context-within-a-session)
- [Export and locate session data](#export-and-locate-session-data)
  - [Access conversations from scripts](#access-conversations-from-scripts)
  - [Where transcripts are stored](#where-transcripts-are-stored)
  - [Delete session data](#delete-session-data)
  - [Name the project directory yourself](#name-the-project-directory-yourself)
- [See also](#see-also)

Use Claude Code

# Manage sessions

Copy pageCopy page

Name, resume, branch, and switch between Claude Code conversations. Covers `--continue`, `--resume`, `--from-pr`, the `/resume` picker, session naming, exporting transcripts, and where transcripts are stored.

Copy pageCopy page

A [session](glossary.md#session) is a saved conversation tied to a project directory. Claude Code stores it locally as you work, so you can resume where you left off, branch to try a different approach, or switch between tasks. The [desktop app](../16-Mobile-Desktop/desktop.md#work-in-parallel-with-sessions), [claude.ai/code](claude-code-on-the-web.md), and the [VS Code extension](../03-IDE-Integrations/vs-code.md#resume-past-conversations) each keep their own session list, and the desktop app can also [resume a CLI session](../16-Mobile-Desktop/desktop.md#coming-from-the-cli). This page covers the CLI.


[​](#resume-a-session)

Resume a session

Sessions are saved continuously to [local transcript files](#export-and-locate-session-data) as you work, so you can return to one after exiting or running `/clear`. Use these entry points:

| Command                             | What it does                                                                                                      |
|:------------------------------------|:------------------------------------------------------------------------------------------------------------------|
| `claude --continue`                 | Reopens the most recent session in the current directory                                                          |
| `claude --resume`                   | Opens the [session picker](#use-the-session-picker)                                                               |
| `claude --resume <name>`            | Resumes the named session directly                                                                                |
| `claude --resume <transcript-path>` | Resumes the session stored in the `.jsonl` [transcript file](#where-transcripts-are-stored) at that absolute path |
| `claude --from-pr <number>`         | Opens the session picker filtered to sessions linked to that pull request                                         |
| `/resume`                           | Switches to a different session from inside an active session                                                     |


[​](#resume-a-running-background-session)

Resume a running background session

When the conversation you resume with `claude --resume` or `/resume` belongs to a [background session](../09-Agents-Patterns/agent-view.md) that is still running, Claude Code opens the running session itself. With `--bg` on the command line, the resume is a [background dispatch](../09-Agents-Patterns/agent-view.md#from-your-shell) instead. Before v2.1.285, Claude Code refused and told you to open the session with `claude attach <id>`, or to stop it with `claude stop <id>` first.

- **From your shell**: `claude --resume <session>` runs [`claude attach`](../09-Agents-Patterns/agent-view.md#attach-to-a-session) on that session in the same terminal instead of loading the transcript itself. A prompt you pass on the command line, as in `claude --resume <session> "check the tests too"`, goes to the session as its next turn first, and Claude Code prints `Sent your prompt to the background session (<id>); opening it…` before attaching. `claude -p --resume <session> "prompt"` typed at a terminal does the same, so `-p` doesn’t keep that run non-interactive. Claude Code doesn’t open the session when the command line has any of these:
  - Piped or redirected input or output
  - Flags that configure the session, such as `--permission-mode`, `--model`, or `--settings`
  - Flags that read the output, such as `--output-format json` or `--json-schema`
  - Flags that limit or rewind the run, such as `--max-turns` or `--max-budget-usd`

  With any of these, or when [agent view is turned off](../09-Agents-Patterns/agent-view.md#turn-off-agent-view), Claude Code sends nothing and exits with status 1, printing that the session is running in the background along with the `claude attach <id>` command that opens it, or telling you to find it in `claude agents` when it can’t determine the ID. Add `--fork-session` to resume a copy of the conversation instead. To continue the conversation itself in a session of your own, with your flags applied, run `claude stop <id>` and then repeat the command. A prompt that starts with `/` or `!` isn’t sent, and neither is any prompt while the session waits on your answer to a question. In both cases Claude Code doesn’t open the session, and the message includes `Your prompt was not sent to it` with the reason.
- **From inside a session**: `/resume` moves your current conversation to the background and attaches this terminal to the running session, printing `Opening "<title>", running in the background (<id>)`. Press `←` on an empty prompt to return to agent view, which also lists the conversation you left. When the current conversation can’t move to the background, for example because you’re already attached to a background session or session persistence is off, `/resume` prints the `claude attach` command to run instead.


[​](#what-a-resumed-session-restores)

What a resumed session restores

When Claude Code loads a conversation from its transcript, the resumed session restores the conversation along with the state saved in it:

- Conversation history: the messages, tool calls, and results. If the session was [compacted](context-window.md#what-survives-compaction), the conversation opens at a `Conversation compacted` row. Claude continues with the last compaction’s summary, the messages that compaction left unsummarized, and every message since. The messages that the last compaction summarized aren’t loaded again.
- Interrupted tool calls: a tool that was still running when the previous process ended, for example in a crash, doesn’t finish or get rerun when you resume. Claude sees the call marked as cut off before its result was recorded and is told to check whether it took effect before running it again, unless [`CLAUDE_CODE_RESUME_INTERRUPTED_TURN`](env-vars.md#variables) is set.
- Model: the session continues on the model it was using, except in the cases in [Setting your model](model-config.md#setting-your-model).
- Agent: a session started with [`--agent`](../09-Agents-Patterns/sub-agents.md#invoke-subagents-explicitly) or the `agent` setting continues as that agent, keeping its tool restrictions and model. Pass `--agent` when resuming to pick a different one; for the system prompt in either case, see [System prompt flags in resumed conversations](cli-reference.md#system-prompt-flags-in-resumed-conversations). Claude Code looks for the agent in two places: the session’s original directory, provided you have [trusted that workspace](permissions.md#project-allow-rules-and-workspace-trust), and then the directory you resume from, so a project-scoped agent still loads when you resume from another directory. If Claude Code doesn’t find the agent in either place, the session resumes with the default tools and shows a [warning naming the agent](errors.md#session-agent-no-longer-available).
- Permission mode: if you resume from a terminal with `claude --continue`, `claude --resume <session-id>`, or `claude --resume <name>` when the name matches one session, without `-p`, Claude Code restores the permission mode the session was in, except in the cases in [permission mode on resume](#permission-mode-on-resume), which also covers the session picker, `/resume`, and resuming with `claude -p`. Pass `--permission-mode` or `--dangerously-skip-permissions` to override the restored mode.
- Active goal: a [goal](goal.md#resume-with-an-active-goal) that was still active when the session ended carries over; its turn count, timer, and token-spend baseline reset.
- Session-scoped scheduled tasks: [tasks that haven’t expired](scheduled-tasks.md#limitations) are restored. Background Bash and monitor tasks aren’t.
- Background work: a [background subagent](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background), background Bash command, or [workflow](workflows.md) that ended with the previous process shows up in the resumed transcript as a note that it didn’t finish. Claude Code doesn’t start a turn from those notes; Claude reads them with your next prompt.

Not every configuration flag from the original launch is restored. If the session depended on `--mcp-config`, `--settings`, `--plugin-dir`, `--fallback-model`, or directories added with `--add-dir`, pass them again when you resume; directories added mid-session with `/add-dir` aren’t restored either, though the session picker still uses them to locate the session. The standard settings files, such as `settings.json` and `settings.local.json`, are re-read at launch, so configuration that lives in them doesn’t need to be passed again. For `--system-prompt` and `--append-system-prompt`, see [System prompt flags in resumed conversations](cli-reference.md#system-prompt-flags-in-resumed-conversations).


[​](#permission-mode-on-resume)

Permission mode on resume

Which permission mode Claude Code starts a resumed session in depends on how you resume. The cases below apply when Claude Code loads the conversation from its transcript; when you [open a background session that is still running](#resume-a-running-background-session) instead, that session keeps the permission mode it is in.

- Terminal: `claude --continue`, `claude --resume <session-id>`, or `claude --resume <name>` when the name matches one session, without `-p`. Claude Code restores the permission mode the session was in, except in the cases in the table. Pass `--permission-mode` or `--dangerously-skip-permissions` to override the restored mode.
- Non-interactive: `claude -p --resume` or `claude -p --continue`. Claude Code starts the run in the permission mode a new `claude -p` run would start in, except that a session that ended in plan mode resumes in plan mode under the [conditions below](#resume-in-plan-mode-with-p).
- VS Code: the extension’s conversation panel. The table covers only a conversation that ended in plan mode; for the rest, see [resume past conversations](../03-IDE-Integrations/vs-code.md#resume-past-conversations).
- Session picker at launch: a session you select from the [session picker](#use-the-session-picker), whether you opened it with `claude --resume` alone, `claude --from-pr`, or a name that matches more than one session. Claude Code starts the session in the permission mode it would start a new session in from the same command line, except that a session that ended in plan mode resumes in plan mode. If you pass `--permission-mode`, `--dangerously-skip-permissions`, or `--fork-session`, Claude Code doesn’t restore plan mode. No other stored permission mode is restored.
- `/resume` inside a session, with or without an argument: the conversation you switch to continues in the permission mode your current session is in, except that a conversation that ended in plan mode resumes in plan mode, even if you launched Claude Code with `--permission-mode` or `--dangerously-skip-permissions`. If that conversation was already open earlier in this run of Claude Code, such as the conversation you started in or one you left with `/clear` or `/resume`, it continues in your current permission mode instead.

If a [deny rule](permissions.md#manage-permissions) removes the [`ExitPlanMode`](tools-reference.md) tool, Claude can’t present a plan for approval, so Claude Code doesn’t restore plan mode. The session starts in the permission mode a new session would start in from the same command line. With `/resume`, the conversation continues in your current permission mode. Restoring plan mode on the non-interactive and VS Code paths requires Claude Code v2.1.246 or later. Each row names the permission mode the session ended in, which of the terminal, non-interactive, and VS Code paths you resume it by, and the permission mode Claude Code starts the resumed session in.

| Session ended in    | How you resume                                                             | Permission mode after you resume                                                                                                                                                                                                                                                                                                                             |
|:--------------------|:---------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `bypassPermissions` | Terminal                                                                   | The permission mode a new session would start in. To [bypass permissions](permission-modes.md#skip-all-checks-with-bypasspermissions-mode) again, enable it at launch with one of its launch flags or `permissions.defaultMode: "bypassPermissions"` in [user, `--settings`, or managed settings](settings-reference.md#permissions-defaultmode) |
| `plan`              | Terminal                                                                   | Plan mode. With `--fork-session`, the permission mode a new session would start in                                                                                                                                                                                                                                                                           |
| `plan`              | Terminal, when a deny rule removes `ExitPlanMode`                          | The permission mode a new session would start in                                                                                                                                                                                                                                                                                                             |
| `auto`              | Terminal                                                                   | `auto`, only when your account still meets the [auto mode requirements](permission-modes.md#eliminate-prompts-with-auto-mode)                                                                                                                                                                                                                          |
| Manual              | Terminal                                                                   | Manual when a new session would start in auto mode from the [built-in default](permission-modes.md#which-mode-a-session-starts-in). When a `defaultMode` from a settings file [takes effect](permission-modes.md#which-mode-a-session-starts-in), Claude Code starts the resumed session in that mode instead                                    |
| `plan`              | Non-interactive, under the [conditions below](#resume-in-plan-mode-with-p) | Plan mode                                                                                                                                                                                                                                                                                                                                                    |
| Any mode            | Non-interactive, in any other case                                         | The permission mode a new `claude -p` run would start in                                                                                                                                                                                                                                                                                                     |
| `plan`              | VS Code                                                                    | Plan mode, with [the exceptions on the VS Code page](../03-IDE-Integrations/vs-code.md#resume-past-conversations)                                                                                                                                                                                                                                                             |

##### Resume in plan mode with `-p`

A `claude -p --resume` or `claude -p --continue` run resumes in plan mode only when all of these conditions hold:

- You pass [`--permission-prompt-tool`](cli-reference.md#cli-flags) and don’t pass [`--permission-prompts none`](headless.md#turn-off-permission-prompts-in-unattended-runs), so that Claude Code can present the plan for approval
- You don’t pass `--permission-mode` or `--dangerously-skip-permissions`
- You don’t pass `--fork-session`
- The run isn’t started through [channels](channels.md)
- No [deny rule](permissions.md#manage-permissions) removes the `ExitPlanMode` tool


[​](#resume-usage-limit-dialog)

The “Resume this conversation?” dialog

If you see the “Resume this conversation?” dialog when resuming a session, its estimate is the share of your 5-hour usage limit that the saved conversation alone would use. The estimate doesn’t count what you’ve already used. On Pro and Max plans, the dialog can appear when you resume a long conversation [after a long break](prompt-caching.md#resuming-a-session) or on a different model. The estimated use comes when you send your first message after **Resume**, not when you select it. Choose by whether your next task still needs the saved conversation:

- **Resume**: keep working in the saved conversation.
- **Start a new conversation**: switch to work that doesn’t need the saved conversation. To reopen it later, run [`/resume`](#use-the-session-picker) at the prompt. The estimate doesn’t apply to your first message in the new conversation. If the option says that Claude can look up this conversation, you can still refer to earlier work in the new conversation.


[​](#where-the-session-picker-looks)

Where the session picker looks

Claude Code stores sessions per project directory. By default the session picker shows:

- Sessions from the current worktree, including [background sessions](../09-Agents-Patterns/agent-view.md), which are marked `bg` in the list
- Sessions started elsewhere that added the current directory with `/add-dir`

Use `Ctrl+W` to widen to all worktrees of the repository or `Ctrl+A` to widen to every project on this machine.


[​](#/loop-p-agent-sdk-and-background-sessions)

`/loop`, `-p`, Agent SDK, and background sessions

Sessions whose first prompt was a [`/loop`](scheduled-tasks.md#run-a-prompt-repeatedly-with-%2Floop) command don’t appear in the picker, and `claude --continue` skips them too. Running `/loop` later in a conversation doesn’t hide the session. Claude Code leaves sessions created with [`claude -p`](headless.md) or the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) out of the session picker and out of `claude --continue`. You can still resume one by passing its session ID to `claude --resume <session-id>`. When you run [`claude -p --continue`](headless.md#continue-conversations), Claude Code includes `-p`, SDK, and `/loop` sessions. `claude --continue` opens a [background session](../09-Agents-Patterns/agent-view.md) that has finished, but not one that is still running; opening finished background sessions requires Claude Code v2.1.257 or later. If your most recent conversation is one you [moved to the background](../09-Agents-Patterns/agent-view.md#send-the-session-to-the-background) and it is still running there, Claude Code exits with `Your most recent conversation is running in the background` and that session’s ID. Attach to the session from [`claude agents`](../09-Agents-Patterns/agent-view.md#attach-to-a-session), or run `claude --resume` to pick another one.


[​](#sessions-in-other-worktrees-and-projects)

Sessions in other worktrees and projects

When you select a session from another worktree of the same repository, Claude Code resumes it in place; when the session’s own worktree no longer exists, Claude Code [resumes it in your current directory](worktrees.md#resume-a-worktree-session). When you select a session from an unrelated project, Claude Code copies a `cd` and resume command to your clipboard instead. If that project’s directory no longer exists, Claude Code resumes the session in your current directory rather than copying a `cd` command that would fail. Moving a session with [`/cd`](commands.md) relocates it to the new directory’s project storage, so it appears in that directory’s picker afterward.


[​](#resume-by-session-id-or-name)

Resume by session ID or name

You can run `claude --resume <session-id>` from any directory, so you can resume a session that started elsewhere or moved with [`/cd`](commands.md). Claude Code looks for the ID in this order:

1.  The current project directory and its git worktrees
2.  Every other project on this machine

The cross-project search resolves the ID only when exactly one other project holds a transcript with messages for it, so a hand-copied duplicate makes Claude Code report not-found rather than resume an arbitrary copy. If no stored session matches the ID, Claude Code reports `No conversation found with session ID: <session-id>`. Resuming by name resolves across the current repository and its worktrees. Both forms look for an exact match and resume it directly even if it lives in a different worktree:

| Command                  | Exact match      | Ambiguous name                                                              |
|:-------------------------|:-----------------|:----------------------------------------------------------------------------|
| `claude --resume <name>` | Resumes directly | Opens the session picker with the name pre-filled as a search term          |
| `/resume <name>`         | Resumes directly | Reports an error; run `/resume` with no argument to open the session picker |


[​](#name-your-sessions)

Name your sessions

Give sessions descriptive names so they’re findable in the session picker and resumable by name. This matters most when you’re working on several tasks in parallel.

| When                             | How to set the name                                                                                                                                                                    |
|:---------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| At startup                       | `claude -n auth-refactor`                                                                                                                                                              |
| During a session                 | `/rename auth-refactor`. The name also appears on the prompt bar                                                                                                                       |
| From the session picker          | Highlight a session and press `Ctrl+R`                                                                                                                                                 |
| On plan accept                   | Accepting a plan in [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode) gives the session a generated title based on the plan unless you’ve already named it |
| From claude.ai or the Claude app | Rename a [Remote Control session](remote-control.md#connect-from-another-device); Claude Code applies the same name in the CLI. Requires Claude Code v2.1.221 or later           |
| From the desktop app             | Rename a session in the [desktop app](../16-Mobile-Desktop/desktop.md#organize-and-find-sessions)                                                                                                     |

Once you name a session through a CLI route or from claude.ai, return to it with `claude --resume <name>` or `/resume <name>`; a desktop-app session resumes in the [desktop app](../16-Mobile-Desktop/desktop.md#work-in-parallel-with-sessions). See [Resume a session](#resume-a-session) for how name resolution behaves across worktrees. Sessions you don’t name still get two labels that Claude Code assigns. Only the generated title works as a resume handle:

- Default display name: interactive sessions you never name still get a default display name when they start. The default combines the working directory’s name with a two-character suffix, for example `my-app-3f`, and identifies the session in listings of running sessions, such as [agent view](../09-Agents-Patterns/agent-view.md) and `claude agents --json` output. The default isn’t a resume handle. If you pass it to `claude --resume` or `/resume`, Claude Code doesn’t find the session.
- Generated title: if you don’t name a session, Claude Code generates a session title for it. The title is a short summary of your first prompt, written by a background request to the small/fast model, normally a Haiku-class model. A `claude -p` run you start directly from a shell or script doesn’t get one. Accepting a plan replaces the generated title with a title based on the plan. You can pass either title to `claude --resume` or `/resume`, and Claude Code resolves it the same way as a name you set.


[​](#use-the-session-picker)

Use the session picker

Run `/resume` inside a session, or `claude --resume` with no arguments, to open the interactive session picker. Use these keyboard shortcuts to navigate, search, and widen the list:

| Shortcut                                                                | Action                                                                                                                                                       |
|:------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `↑` / `↓` or `k` / `j`                                                  | Navigate between sessions                                                                                                                                    |
| `→` / `←`                                                               | Expand or collapse grouped sessions                                                                                                                          |
| `Enter`                                                                 | Resume the highlighted session                                                                                                                               |
| `1` to `9`                                                              | Resume the session at that position in the list                                                                                                              |
| `Space`                                                                 | Preview the session content. `Ctrl+V` also works on terminals that don’t capture it as paste                                                                 |
| `Ctrl+R`                                                                | Rename the highlighted session                                                                                                                               |
| `/` or any printable character other than `Space`, `j`, `k`, or a digit | Enter search mode and filter sessions. Paste a GitHub, GitHub Enterprise, GitLab, or Bitbucket pull or merge request URL to find the session that created it |
| `Ctrl+A`                                                                | Show sessions from all projects on this machine. Press again to return to the current repository                                                             |
| `Ctrl+W`                                                                | Show sessions from all worktrees of the current repository. Press again to return to the current worktree. Only shown in multi-worktree repositories         |
| `Ctrl+B`                                                                | Filter to sessions from the current git branch. Press again to show all branches                                                                             |
| `Esc`                                                                   | Exit the session picker or search mode                                                                                                                       |

Each row shows the session name if you set one, otherwise the AI-generated session title, conversation summary, or first prompt, along with time since last activity, git branch, and file size. Sessions created with `/branch` or `--fork-session` get their own session IDs and appear as separate rows. When the picker finds more than one entry for the same session, it groups them under a single row. Press `→` to expand a group. If Claude Code can’t load the session you select from the `claude --resume` picker, it prints [`Failed to resume the conversation`](errors.md#failed-to-resume-the-conversation) with a command to retry, then exits with code 1. From the `/resume` picker inside a session, Claude Code reports the failure and your current conversation keeps running.


[​](#branch-a-session)

Branch a session

Branching creates a copy of the conversation so far and switches you into it, leaving the original intact. Use it to try a different approach without losing the path you were on. From inside a session, run `/branch` with an optional name:

```python
/branch try-streaming-approach
```

If you omit the name, Claude Code names the new branch after the first prompt in the conversation. From the command line, combine `--continue` or `--resume` with `--fork-session`:

```python
claude --continue --fork-session
```

The `/branch` confirmation prints two session IDs: the new branch you are now in and the original. The original is unchanged on disk and remains in the session picker; return to it with `/resume <original-name>` or by passing its ID to `/resume`. `/branch` copies the transcript and switches the running Claude Code process to write to it. That distinction determines what the branch inherits:

| State                                                                                                                                                                              | After `/branch`                                                                                                                                                                                                 |
|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Conversation history                                                                                                                                                               | Copied into the branch up to the point you ran `/branch`                                                                                                                                                        |
| ”Allow for this session” permission grants                                                                                                                                         | Carried over; the branch runs in the same process, so your existing grants still apply. If you fork into a separate process with `--fork-session`, the new process starts without them and you re-approve there |
| In-flight [background subagents](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) and [background Bash commands](interactive-mode.md#background-bash-commands) | Keep running. Their output appears in the new branch you switched into, not in the original session                                                                                                             |
| [Remote Control](remote-control.md) connection                                                                                                                               | Stays connected. A phone or browser connected to the session follows you into the branch and keeps receiving new messages there                                                                                 |

If you resume the same session in two terminals without forking, messages from both interleave into one transcript. For checkpoint-based rewind within a single session, see [Checkpointing](checkpointing.md).


[​](#manage-context-within-a-session)

Manage context within a session

These commands control what’s in the context window without leaving the session:

- **`/clear`**: start fresh with an empty context. Claude Code saves the previous session; resume it with `/resume`, or, in the same Claude Code process, from [the rewind menu’s previous-session entry](checkpointing.md#rewind-past-a-cleared-conversation). With no argument, the new session keeps a name you set with `--name` or `/rename`, but not an AI-generated session title. To name the session you’re leaving instead, pass the name, as in `/clear release-prep`; the new session then starts unnamed
- **`/compact [instructions]`**: replace history with a summary, optionally focused on what you specify
- **`/context`**: show what is currently consuming context

For how compaction interacts with CLAUDE.md, skills, and rules, see the [context window guide](context-window.md). For strategies on when to clear versus compact, see [Best practices](best-practices.md#manage-your-session).


[​](#export-and-locate-session-data)

Export and locate session data

Run `/export` to open a menu that lets you copy the current conversation to your clipboard or save it as a plain-text file, with messages and tool outputs rendered as readable text. Pass a filename to skip the menu and write directly to that file.


[​](#access-conversations-from-scripts)

Access conversations from scripts

`/export` produces a rendered transcript for a person to read. The interfaces below produce structured data for a script to parse: a JSON result from a run, the path to a session’s transcript file, or a live stream of events. Pick by what triggers the script:

- **Run Claude once and capture the result**: invoke `claude -p` with [`--output-format json` or `stream-json`](headless.md#get-structured-output) to capture the result, session ID, usage, and cost of a non-interactive run as structured JSON.
- **Ask an existing session a question**: pass a session ID to [`claude -p --resume`](headless.md#continue-conversations) to send a follow-up prompt, such as a summary request, and capture the structured response.
- **React to session events**: read the `transcript_path` field that [hooks](../07-Hooks/hooks.md#common-input-fields) and [status line commands](statusline.md#available-data) receive as input. A `SessionEnd` hook can archive the transcript when a session ends.
- **Embed Claude in a TypeScript or Python app**: use the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) to receive each message programmatically.

The example below uses the second interface. It sends a follow-up prompt to an existing session and reads the answer with `jq`:

```python
claude -p --resume <session-id> --output-format json "summarize what we changed" | jq -r '.result'
```


[​](#where-transcripts-are-stored)

Where transcripts are stored

By default, Claude Code stores transcripts as JSONL at `~/.claude/projects/<project>/<session-id>.jsonl`, where `<project>` is your working directory path with non-alphanumeric characters replaced by `-`. For a working directory whose converted name exceeds 200 characters, Claude Code truncates the name to 200 characters and appends a hash of the full path, so the directory name stays within filesystem limits. Each line is a JSON object for a message, tool use, or metadata entry. The entry format is internal to Claude Code and changes between versions, so scripts that parse these files directly can break on any release. To build on session data, use `/export` or the [script interfaces](#access-conversations-from-scripts) instead. The location, retention, and write behavior are configurable:

| To                                                                                                               | Set                                                                                              | Where                                            |
|------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|--------------------------------------------------|
| Move storage off `~/.claude`                                                                                     | [`CLAUDE_CONFIG_DIR`](env-vars.md)                                                         | Environment variable                             |
| [Name the `<project>` directory yourself](#name-the-project-directory-yourself)                                  | [`CLAUDE_CODE_PROJECT_DIR_NAME`](env-vars.md)                                              | Environment variable                             |
| Change the 30-day retention                                                                                      | [`cleanupPeriodDays`](settings-reference.md#cleanupperioddays)                             | `settings.json`                                  |
| Set an age limit for [Claude Desktop and Cowork transcripts](claude-directory.md#cleaned-up-automatically) | [`desktopSessionCleanupPeriodDays`](settings-reference.md#desktopsessioncleanupperioddays) | User settings, managed settings, or `--settings` |
| Limit how large a `-p` or Agent SDK session’s transcript file grows                                              | [`CLAUDE_CODE_TRANSCRIPT_LOCAL_GC`](env-vars.md)                                           | Environment variable                             |
| Suppress transcript writes in all modes                                                                          | [`CLAUDE_CODE_SKIP_PROMPT_HISTORY`](env-vars.md)                                           | Environment variable                             |
| Suppress writes for one non-interactive run                                                                      | [`--no-session-persistence`](cli-reference.md)                                             | CLI flag with `claude -p`                        |


[​](#delete-session-data)

Delete session data

Transcripts age out under the [retention sweep rules](claude-directory.md#cleaned-up-automatically). To delete a project’s transcripts and related state sooner, run [`claude purge`](claude-directory.md#clear-local-data). If you delete a [background session](../09-Agents-Patterns/agent-view.md) with [`claude rm <id>`](../09-Agents-Patterns/agent-view.md#what-deleting-a-session-removes), its transcript stays on disk and remains available through `claude --resume`.


[​](#name-the-project-directory-yourself)

Name the project directory yourself

By default, Claude Code derives the `<project>` name from the whole working directory path. To choose the name yourself, set `CLAUDE_CODE_PROJECT_DIR_NAME` alongside `CLAUDE_CONFIG_DIR`. Claude Code then stores that session’s transcripts and [auto memory](memory.md#auto-memory) under your name. This suits a host that embeds Claude Code and gives each session its own config directory. Requires Claude Code v2.1.234 or later. For example, this launch keeps tenant A’s data under `/srv/tenant-a` and names its project directory `work`:

```python
CLAUDE_CONFIG_DIR=/srv/tenant-a CLAUDE_CODE_PROJECT_DIR_NAME=work claude
```

Claude Code writes the session’s transcripts to `/srv/tenant-a/projects/work/` and its auto memory to `/srv/tenant-a/projects/work/memory/`, whatever the working directory is. Three rules apply when you set it:

- **Set `CLAUDE_CONFIG_DIR` too**: the name doesn’t vary with the working directory, so under the default `~/.claude` it would merge every project’s transcripts and auto memory into one directory. Claude Code ignores `CLAUDE_CODE_PROJECT_DIR_NAME` when `CLAUDE_CONFIG_DIR` is unset.
- **Use 1-64 letters, digits, hyphens, or underscores**: don’t use a Windows device name such as `con`. Claude Code ignores any other value and uses the derived name.
- **Set it in the shell environment that starts `claude`**: Claude Code reads it once at startup from that environment, so an `env` block in a settings file can’t set it.

Once you’ve named a config directory’s project directory, keep launching with that name. If you start Claude Code with the same `CLAUDE_CONFIG_DIR` but without `CLAUDE_CODE_PROJECT_DIR_NAME`, it reads and writes the derived directory again. The sessions stored under your name stay on disk: press `Ctrl+A` in the [session picker](#use-the-session-picker) to list sessions from every project directory under that config directory, the pinned one included, and whichever way you launch, [`claude --resume <session-id>`](#resume-a-session) finds a session stored under either name.


[​](#see-also)

See also

These pages cover related session and parallelism mechanics:

- [Worktrees](worktrees.md): run isolated parallel sessions on separate branches
- [Checkpointing](checkpointing.md): rewind code and conversation to an earlier point
- [Context window](context-window.md): what fills context and what survives compaction
- [Non-interactive mode](headless.md): session behavior under `claude -p`

---

## Set up Code Review for Claude Code | Claude Help Center

Source: https://support.claude.com/en/articles/14233555-set-up-code-review-for-claude-code
Path: 02-Claude-Code-CLI/set-up-code-review-for-claude-code.md

# Set up Code Review for Claude Code


Code Review analyzes your GitHub pull requests and posts findings as inline comments on the lines of code where it found issues. A fleet of specialized agents examine the code changes in the context of your full codebase, looking for logic errors, security vulnerabilities, broken edge cases, and regressions.

This article covers how to enable Code Review, configure review triggers, customize what gets flagged, and troubleshoot common setup issues.

**Note:** Code Review is available on Team and Enterprise plans. It isn’t available for organizations with zero data retention enabled. Code Review usage is billed separately through usage credits and doesn’t count against your plan’s included usage.

------------------------------------------------------------------------

## How Code Review works

Once an organization enables Code Review, it can trigger automatically when a pull request opens, on every push, or only when someone manually requests a review. When a review runs, multiple agents analyze the diff and surrounding code in parallel. Each agent looks for a different class of issue, then a verification step checks results against actual code behavior to filter out false positives.

Findings are deduplicated, ranked by severity, and posted as inline comments on the specific lines where issues were found. If no issues are found, Claude posts a short confirmation comment on the PR. Reviews don’t approve or block your PR, so existing review workflows stay intact.

Reviews scale in cost with PR size and complexity, completing in 20 minutes on average.

### Severity levels

Each finding is tagged with a severity level:

[TABLE]

Findings include a collapsible extended reasoning section you can expand to see why Claude flagged the issue and how it verified the problem.

### What Code Review checks

By default, Code Review focuses on correctness: bugs that would break production, not formatting preferences or missing test coverage. You can expand what it checks by adding guidance files to your repository.

------------------------------------------------------------------------

## Set up Code Review

The steps below cover setup for repositories on github.com. If your repositories are on a self-hosted GitHub Enterprise Server (GHES) instance, see **[Claude Code with GitHub Enterprise Server](github-enterprise-server.md)** for the full setup guide.

Owners and Primary Owners of Team and Enterprise plans can enable Code Review once for the organization and select which repositories to include. In addition to an owner role within your Claude organization, you’ll need permission to install GitHub Apps in your GitHub organization.

1.  Go to **[Organization settings \> Claude Code](https://claude.ai/admin-settings/claude-code)** and find the **Code Review** section.

2.  Click “Configure” to begin the GitHub App installation flow.

3.  Follow the prompts to install the Claude GitHub App to your GitHub organization. The app requests read and write permissions for contents, issues, and pull requests.

4.  Choose which repositories to enable for Code Review. If you don’t see a repository, confirm you gave the Claude GitHub App access to it during installation.

5.  Set a review trigger for each repository using the **Review Behavior** dropdown (see the next section for details on each option).

To verify setup, open a test PR. If you chose an automatic trigger, a check run named **Claude Code Review** should appear within a few minutes. If you chose Manual, comment “@claude review” on the PR to start the first review.

------------------------------------------------------------------------

## Choose a review trigger

After setup, the **Code Review** section shows your repositories in a table. For each repository, choose when reviews run:

- **Once after PR creation:** The review runs once when a PR is opened or marked ready for review.

- **After every push:** The review runs on every push to the PR branch, catching new issues as the PR evolves. Claude auto-resolves threads when you fix previously flagged issues. This runs the most reviews and costs the most.

- **Manual:** Reviews start only when someone comments “@claude review” on a PR. Useful for high-traffic repos where you want to select which PRs get reviewed.

The repositories table also shows the average cost per review for each repo based on recent activity.

------------------------------------------------------------------------

## Manually trigger reviews

Comment “@claude review” on a pull request to start a review and opt that PR into push-triggered reviews going forward. This works regardless of the repository’s configured trigger.

For the comment to trigger a review:

- Post it as a top-level PR comment, not an inline comment on a diff line.

- Put “@claude review” at the start of the comment.

- You must have owner, member, or collaborator access to the repository.

- The PR must be open and not a draft.

If a review is already running, the request is queued until the in-progress review completes.

------------------------------------------------------------------------

## Customize reviews

Code Review reads two files from your repository to guide what it flags. Both are additive on top of the default correctness checks.

### CLAUDE.md

Code Review reads your repository’s CLAUDE.md files and treats newly introduced violations as nit-level findings. If your PR changes code in a way that makes a CLAUDE.md statement outdated, Claude flags that the docs need updating too.

Claude reads CLAUDE.md files at every level of your directory hierarchy, so rules in a subdirectory’s CLAUDE.md apply only to files under that path.

### REVIEW.md

Add a REVIEW.md file to your repository root for review-specific rules. Use it to encode:

- Company or team style guidelines

- Language- or framework-specific conventions not covered by linters

- Things Claude should always flag (for example, “any new API route must have an integration test”)

- Things Claude should skip (for example, “don’t comment on generated code”)

Claude auto-discovers REVIEW.md at the repository root. No configuration is needed.

------------------------------------------------------------------------

## Pricing and usage

Code Review is billed based on token usage. Each review averages \$15–25 in cost, scaling with PR size, codebase complexity, and how many issues require verification.

Code Review usage is billed separately through usage credits and doesn’t count against your plan’s included usage. The review trigger you choose affects total cost:

- **Once after PR creation** runs once per PR.

- **After every push** runs on each push, multiplying cost by the number of pushes.

- **Manual** incurs no cost until someone comments “@claude review.” After that comment, additional pushes to the PR trigger reviews automatically.

Costs appear on your Anthropic bill regardless of whether your organization uses AWS Bedrock or Google Vertex AI for other Claude Code features.

To set a monthly spend cap, go to **[Organization settings \> Usage](https://claude.ai/admin-settings/usage)** and configure the limit for the Claude Code Review service.

Monitor spend via the weekly cost chart in the analytics dashboard or the per-repo average cost column in admin settings.

### View usage

Go to the **[Code Review analytics dashboard](https://claude.ai/analytics/code-review)** to see activity across your organization. The dashboard shows:

- **PRs reviewed:** Daily count of pull requests reviewed over the selected time range.

- **Cost weekly:** Weekly spend on Code Review.

- **Feedback:** Count of review comments that were auto-resolved because someone addressed the issue.

- **Repository breakdown:** Per-repo counts of PRs reviewed and comments resolved.

------------------------------------------------------------------------

## Troubleshooting

### Repositories don’t appear after installing the GitHub App

If you’ve installed the Claude GitHub App but your repositories don’t appear in the admin panel:

1.  Confirm the Claude GitHub App has access to the repositories you expect. Go to your GitHub organization’s settings, find the Claude GitHub App under **Installed GitHub Apps**, and check whether it has access to all repositories or only selected ones.

2.  If your organization uses GitHub Enterprise Cloud with Enterprise Managed Users (EMU), authorize Claude while you're signed in with your managed account and have an active SSO session. There's no separate enterprise-level approval step.

3.  Try disconnecting and reconnecting your GitHub account in Claude. Go to **[Customize \> Connectors](https://claude.ai/customize/connectors)**, disconnect GitHub, and connect it again. Which repositories the App can access is managed on GitHub's side, covered in step 1.

4.  If the issue persists, **[contact our Support team](../15-Claude-AI-Features/how-to-get-support.md)** with your organization name and GitHub organization name so we can investigate.

### Code Review doesn’t start on a new PR

If no check run appears after opening a PR:

- Confirm the repository is listed and enabled in your admin settings.

- Check the review trigger setting. If it’s set to Manual, you’ll need to comment “@claude review” on the PR to start a review.

- Make sure the PR isn’t a draft. Code Review doesn’t run on draft PRs.

- Verify the Claude GitHub App still has access to the repository in your GitHub organization’s settings.

### GitHub Enterprise Cloud with IP restrictions

If your GitHub Enterprise Cloud organization restricts access by IP address, the Claude GitHub App may be unable to access your repositories. To fix this, **[enable IP allow list inheritance for installed GitHub Apps](https://docs.github.com/en/enterprise-cloud@latest/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/managing-allowed-ip-addresses-for-your-organization#allowing-access-by-github-apps)** in your GitHub enterprise settings. The Claude GitHub App registers its IP ranges, so enabling this setting allows access without manual configuration. To **[add the ranges to your allow list manually](https://docs.github.com/en/enterprise-cloud@latest/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/managing-allowed-ip-addresses-for-your-organization#adding-an-allowed-ip-address)** instead, or to configure other firewalls, see the **[Anthropic API IP addresses](../04-API-Reference/Endpoints/ip-addresses.md)**.

### GitHub Enterprise Server (self-hosted)

Self-hosted GitHub Enterprise Server (GHES) is supported through a separate setup flow. See **[Claude Code with GitHub Enterprise Server](github-enterprise-server.md)** for full instructions.

Common GHES setup issues:

- **"Public cannot be private" error during setup:** Your GHES hostname must resolve to a publicly routable IP address. Code Review reaches your server over the internet, so internal or private network addresses won't work. Update DNS or your network configuration so the hostname resolves to a public IP, then retry.

- **GitHub Enterprise Cloud with Data Residency is a different product.** GitHub Enterprise Cloud with data residency (.ghe.com) is also supported. An Owner follows the GitHub Enterprise Server admin setup and enters the `ghe.com` hostname.

------------------------------------------------------------------------

## Frequently asked questions

### Is Code Review available as a capability when creating a custom role?

No, Code Review is not available to add to a **[custom role](../17-Billing-Plans/manage-custom-roles-on-enterprise-plans.md)** at this time.

------------------------------------------------------------------------

## Related resources

- **[Plugins](../08-Plugins-Skills/discover-plugins.md)** — Browse the plugin marketplace, including a code-review plugin for running on-demand reviews locally before pushing.

- **[GitHub Actions](github-actions.md)** — Run Claude in your own GitHub Actions workflows for custom automation beyond Code Review.

- **[GitLab CI/CD](gitlab-ci-cd.md)** — Self-hosted Claude integration for GitLab pipelines.

---

## Example settings files - Claude Code Docs

Source: https://code.claude.com/docs/en/settings-example
Path: 02-Claude-Code-CLI/settings-example.md

## On this page

- [Your own settings](#your-own-settings)
- [A team’s shared settings](#a-teams-shared-settings)
- [An organization’s managed settings](#an-organizations-managed-settings)

Settings

# Example settings files

Copy pageCopy page

Realistic settings.json files for a developer, a team, and an organization: copy one, keep the keys you want, and change the values.

Copy pageCopy page

This page holds three example `settings.json` files, one for each place you save a setting:

- A developer’s `~/.claude/settings.json`
- A team’s `.claude/settings.json`, committed to the repository
- An organization’s `managed-settings.json`

Each one is a plausible file for that reader, so you can see the shape and copy the parts you want. None of them is a recommended baseline. Every value comes from the key’s entry on the [settings reference](settings-reference.md), which has its type, default, and where it can be set. Each example has two tabs. **Copyable settings file** is the file as you’d save it. **What each key does** is the same file with a comment above each key; Claude Code doesn’t accept comments in a settings file, so copy from the first tab.


[​](#your-own-settings)

Your own settings

One developer’s personal settings. It picks a model and effort, adjusts the terminal, and pre-approves a read-only command and one file read. Everything not listed keeps its default. A file like this goes in `~/.claude/settings.json`, where it applies to every project you open.

- Copyable settings file

- What each key does

Save this as `~/.claude/settings.json`. It’s valid JSON with no comments, so you can paste it as is and delete the keys you don’t want.

~/.claude/settings.json

```python
{
  "model": "claude-sonnet-5",
  "modelSettings": {
    "claude-sonnet-5": { "effortLevel": "xhigh" }
  },
  "editorMode": "vim",
  "theme": "light-daltonized",
  "statusLine": {
    "type": "command",
    "command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'",
    "padding": 2
  },
  "spinnerTipsEnabled": false,
  "preferredNotifChannel": "terminal_bell",
  "permissions": {
    "allow": [
      "Bash(git diff *)",
      "Read(~/.zshrc)"
    ]
  },
  "autoUpdatesChannel": "stable",
  "cleanupPeriodDays": 20
}
```

The same file with a comment above each key. Read it here; copy from the other tab, because Claude Code doesn’t accept comments in a settings file.

~/.claude/settings.json

```python
{
  // Start every session on Sonnet 5
  "model": "claude-sonnet-5",
  // Run Sonnet 5 above its default high level; /effort saves a level per model, and --effort sets one for a single session
  "modelSettings": {
    "claude-sonnet-5": { "effortLevel": "xhigh" }
  },
  // Vim keybindings in the prompt
  "editorMode": "vim",
  // The colorblind-friendly light theme
  "theme": "light-daltonized",
  // A status line below the prompt: model name and context used
  "statusLine": {
    "type": "command",
    "command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'",
    "padding": 2
  },
  // Hide the tips that rotate under the spinner
  "spinnerTipsEnabled": false,
  // Ring the terminal bell for notifications, such as a finished task or a waiting permission prompt
  "preferredNotifChannel": "terminal_bell",
  // Let Claude Code run git diff and read your .zshrc without asking
  "permissions": {
    "allow": [
      "Bash(git diff *)",
      "Read(~/.zshrc)"
    ]
  },
  // Take updates from the stable channel
  "autoUpdatesChannel": "stable",
  // Delete session transcripts and other local session data older than 20 days
  "cleanupPeriodDays": 20
}
```


[​](#a-teams-shared-settings)

A team’s shared settings

One team’s shared settings, committed to the repository so everyone who clones it gets the same permissions, hooks, and plugin marketplace. Save a file like this at `.claude/settings.json` at the top of the repository. What to know before you commit one:

- **Cloud sessions outside a [project](claude-projects.md#what-threads-pick-up-from-your-repositories)’s threads read it too.** A [cloud session](settings.md#settings-in-cloud-sessions) with one repository starts inside the clone, so the committed file applies there as well.
- **Telemetry goes in managed or personal settings.** Claude Code ignores the [OpenTelemetry exporter variables](settings-reference.md#variables-claude-code-ignores-in-env) in a repository’s settings files, apart from some values that turn telemetry off. Set them in [managed settings](../13-Enterprise-Admin/monitoring-usage.md#administrator-configuration) for your organization, or in each person’s `~/.claude/settings.json`.
- **Allow rules wait for trust.** Allow rules and `extraKnownMarketplaces` entries take effect after each person [trusts this folder itself](permissions.md#project-allow-rules-and-workspace-trust), not only a parent folder; deny and ask rules apply in every session, trusted or not.
- **The hook is a script in the repo.** This file’s hook runs `.claude/hooks/block-rm.sh`; [How a hook resolves](../07-Hooks/hooks.md#how-a-hook-resolves) walks through writing it.
- **Rules match the command and path as written.** `Bash(git push *)` doesn’t match [`git -C . push`](permissions.md#bash-rule-limits). `Read(./.env)` on its own stops the file tools and commands that name the file, such as `cat .env`, but not [`grep -r` run over the directory](permissions.md#read-and-edit); the `sandbox` block in this file closes that gap, because the sandbox [adds your `Read` deny paths](settings-reference.md#sandbox-filesystem-denyread) to what every sandboxed command can’t read.

- Copyable settings file

- What each key does

Save this as `.claude/settings.json` at the top of the repository and commit it. It’s valid JSON with no comments, so you can paste it as is and delete the keys you don’t want.

.claude/settings.json

```python
{
  "permissions": {
    "allow": [
      "Bash(npm run *)"
    ],
    "ask": [
      "Bash(git push *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.sh"
          }
        ]
      }
    ]
  },
  "extraKnownMarketplaces": {
    "acme-tools": {
      "source": {
        "source": "github",
        "repo": "acme-corp/claude-plugins"
      }
    }
  },
  "enabledPlugins": {
    "code-formatter@acme-tools": true
  },
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "allowWrite": [
        "/tmp/build"
      ]
    },
    "network": {
      "allowedDomains": [
        "registry.npmjs.org",
        "*.example.com"
      ]
    }
  },
  "plansDirectory": "./plans"
}
```

The same file with a comment above each key. Read it here; copy from the other tab, because Claude Code doesn’t accept comments in a settings file.

.claude/settings.json

```python
{
  "permissions": {
    // Run npm scripts without asking
    "allow": [
      "Bash(npm run *)"
    ],
    // Confirm before git push commands
    "ask": [
      "Bash(git push *)"
    ],
    // Deny reads of env files and the secrets folder by the file tools and file-reading commands
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  },
  // Before every Bash command, run a script in the repo that can block it
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.sh"
          }
        ]
      }
    ]
  },
  // Register the team's plugin marketplace on every clone
  "extraKnownMarketplaces": {
    "acme-tools": {
      "source": {
        "source": "github",
        "repo": "acme-corp/claude-plugins"
      }
    }
  },
  // Enable one plugin from that marketplace; a plugin from an external source such as a GitHub repository still needs each person to install it once
  "enabledPlugins": {
    "code-formatter@acme-tools": true
  },
  // Sandbox commands: writable build dir; npm and example.com pre-allowed
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "allowWrite": [
        "/tmp/build"
      ]
    },
    "network": {
      "allowedDomains": [
        "registry.npmjs.org",
        "*.example.com"
      ]
    }
  },
  // Keep plan files inside the repo
  "plansDirectory": "./plans"
}
```


[​](#an-organizations-managed-settings)

An organization’s managed settings

A `managed-settings.json` file that shows the shape of the managed keys, with one plausible value for each. It isn’t a recommended policy: pick the keys that match your own requirements and set your own values. The example sets these keys:

- `forceLoginMethod` and `forceLoginOrgUUID` pin the login method and organization
- `availableModels` and `enforceAvailableModels` restrict which models sessions can use
- `permissions.deny` denies two file reads and `curl` commands [as Claude writes them](permissions.md#bash-rule-limits), and `disableBypassPermissionsMode` removes the bypass permission mode
- [`allowManagedPermissionRulesOnly`](settings-reference.md#allowmanagedpermissionrulesonly) and [`allowManagedMcpServersOnly`](settings-reference.md#allowmanagedmcpserversonly) make the managed permission and MCP allowlists the only ones that apply
- `allowedMcpServers` pins the MCP server by URL
- `strictKnownMarketplaces` allows one plugin marketplace
- `sandbox` sandboxes commands with a fixed network allowlist and no unsandboxed retry. Its `failIfUnavailable` key [stops Claude Code from starting where the sandbox can’t run](sandboxing.md#enforce-sandboxing-with-managed-settings)
- `requiredMinimumVersion` sets a minimum Claude Code version
- `cleanupPeriodDays` shortens retention of session transcripts and other local data to seven days
- `companyAnnouncements` shows a message at startup

Administrators deploy a file like this as `managed-settings.json`, or the same JSON through MDM or [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md). One deployed file applies to every machine or account it reaches. To give a group different values, deploy a different file or profile to that group, since [server-managed settings don’t support per-group policy yet](../13-Enterprise-Admin/server-managed-settings.md#current-limitations).

- Copyable settings file

- What each key does

Deploy this as `managed-settings.json`, or the same JSON through MDM or the claude.ai console. It’s valid JSON with no comments; replace the example organization UUID, server URL, and marketplace with your own and delete the keys you don’t want.

managed-settings.json

```python
{
  "forceLoginMethod": "claudeai",
  "forceLoginOrgUUID": [
    "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  ],
  "availableModels": [
    "opus",
    "sonnet"
  ],
  "enforceAvailableModels": true,
  "permissions": {
    "deny": [
      "Bash(curl *)",
      "Read(./.env)",
      "Read(./secrets/**)"
    ],
    "disableBypassPermissionsMode": "disable"
  },
  "allowManagedPermissionRulesOnly": true,
  "allowedMcpServers": [
    {
      "serverUrl": "https://api.githubcopilot.com/*"
    }
  ],
  "allowManagedMcpServersOnly": true,
  "strictKnownMarketplaces": [
    {
      "source": "github",
      "repo": "acme-corp/approved-plugins"
    }
  ],
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true,
    "allowUnsandboxedCommands": false,
    "network": {
      "allowedDomains": [
        "registry.npmjs.org",
        "github.com"
      ],
      "allowManagedDomainsOnly": true
    }
  },
  "requiredMinimumVersion": "2.1.150",
  "cleanupPeriodDays": 7,
  "companyAnnouncements": [
    "Welcome to Acme Corp! Review our code guidelines at docs.example.com"
  ]
}
```

The same file with a comment above each key. Read it here; copy from the other tab, because Claude Code doesn’t accept comments in a settings file.

managed-settings.json

```python
{
  // Only claude.ai logins, and only in this organization
  "forceLoginMethod": "claudeai",
  "forceLoginOrgUUID": [
    "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  ],
  // Only Opus and Sonnet models; with enforceAvailableModels, the Default option obeys the list too
  "availableModels": [
    "opus",
    "sonnet"
  ],
  "enforceAvailableModels": true,
  "permissions": {
    // Deny curl commands and reads of the project's .env file and secrets folder on every machine
    "deny": [
      "Bash(curl *)",
      "Read(./.env)",
      "Read(./secrets/**)"
    ],
    // Remove the bypass-permissions mode from every session
    "disableBypassPermissionsMode": "disable"
  },
  // Ignore permission rules from user, project, and local settings
  "allowManagedPermissionRulesOnly": true,
  // Only the GitHub MCP server, matched by URL rather than by name, since a user can
  // name any server "github". User-added servers that don't match don't load, including
  // every stdio server when the list has only URL entries. The allowManagedMcpServersOnly
  // key below makes this managed list the only allowlist that applies
  "allowedMcpServers": [
    {
      "serverUrl": "https://api.githubcopilot.com/*"
    }
  ],
  "allowManagedMcpServersOnly": true,
  // Plugins can come only from this marketplace
  "strictKnownMarketplaces": [
    {
      "source": "github",
      "repo": "acme-corp/approved-plugins"
    }
  ],
  // Sandbox every command Claude runs, refuse to start if the sandbox can't be
  // set up, and never let a blocked command retry outside the sandbox; network
  // limited to npm and GitHub, and users can't add domains
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true,
    "allowUnsandboxedCommands": false,
    "network": {
      "allowedDomains": [
        "registry.npmjs.org",
        "github.com"
      ],
      "allowManagedDomainsOnly": true
    }
  },
  // Refuse to start on versions older than 2.1.150
  "requiredMinimumVersion": "2.1.150",
  // Delete session transcripts and other local session data after 7 days
  "cleanupPeriodDays": 7,
  // A message every user sees at startup
  "companyAnnouncements": [
    "Welcome to Acme Corp! Review our code guidelines at docs.example.com"
  ]
}
```

---

## All settings - Claude Code Docs

Source: https://code.claude.com/docs/en/settings-reference
Path: 02-Claude-Code-CLI/settings-reference.md

# All settings

Copy pageCopy page

Complete reference for every Claude Code settings.json key: where each one goes, its type and default, and a paste-ready example, with an index of every key.

Copy pageCopy page

This reference page lists each key Claude Code reads from a settings file, plus the [short group of keys](#global-config-settings) it keeps in `~/.claude.json` instead. To pick a file, or check precedence, start with [Settings files and precedence](settings.md).


[​](#settings-index)

Settings index

Every key below links to its entry. Scope lists the [files](settings.md#settings-files-and-who-they-affect) it can go in: `User` is `~/.claude/settings.json`, `Project` is `.claude/settings.json`, `Local` is `.claude/settings.local.json`, and `Managed` is [what your organization deploys](../13-Enterprise-Admin/managed-settings.md). `Any file` means all four, and `Global config` means [`~/.claude.json`](#global-config-settings).

| Key                                                                                                   | Description                                                                                                                                                                                                                           | Topic                              | Scope                   |
|:------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------|:------------------------|
| [`advisorModel`](#advisormodel)                                                                       | Pick which model answers when Claude asks the [advisor tool](advisor.md)                                                                                                                                                        | Model and responses                | Any file                |
| [`agent`](#agent)                                                                                     | Start every session as a named [subagent](../09-Agents-Patterns/sub-agents.md) with its prompt, tools, and model                                                                                                                                      | Agents, sessions, and worktrees    | Any file                |
| [`agentPushNotifEnabled`](#agentpushnotifenabled)                                                     | Let Claude send a [push notification to your phone](remote-control.md#mobile-push-notifications) when it decides to                                                                                                             | Remote, desktop, and notifications | Any file                |
| [`allowAllClaudeAiMcps`](#allowallclaudeaimcps)                                                       | Load the [claude.ai connectors](../06-MCP-Tools/General/mcp.md) Claude Code fetches itself alongside a deployed [`managed-mcp.json`](../06-MCP-Tools/General/managed-mcp.md#exclusive-control-with-managed-mcp-json)                                                      | MCP                                | Managed                 |
| [`allowClaudeInChromeWithManagedMcp`](#allowclaudeinchromewithmanagedmcp)                             | Let the built-in [Claude in Chrome](../03-IDE-Integrations/chrome.md) server run alongside a deployed [`managed-mcp.json`](../06-MCP-Tools/General/managed-mcp.md#exclusive-control-with-managed-mcp-json)                                                               | MCP                                | Managed                 |
| [`allowedChannelPlugins`](#allowedchannelplugins)                                                     | Replace the default allowlist of [channel plugins](channels.md#restrict-which-channel-plugins-can-run) that can push messages                                                                                                   | Plugins and skills                 | Managed                 |
| [`allowedHttpHookUrls`](#allowedhttphookurls)                                                         | Limit which URLs [HTTP hooks](../07-Hooks/hooks.md) can target                                                                                                                                                                              | Hooks and automation               | Any file                |
| [`allowedMcpServers`](#allowedmcpservers)                                                             | Allowlist which [MCP servers](../06-MCP-Tools/General/mcp.md) users can add                                                                                                                                                                             | MCP                                | Any file                |
| [`allowedProviders`](#allowedproviders)                                                               | Limit which [API providers](third-party-integrations.md) a machine may use                                                                                                                                                      | Authentication and providers       | Managed                 |
| [`allowManagedHooksOnly`](#allowmanagedhooksonly)                                                     | Run only the [hooks](../07-Hooks/hooks.md) your organization deploys                                                                                                                                                                        | Hooks and automation               | Managed                 |
| [`allowManagedMcpServersOnly`](#allowmanagedmcpserversonly)                                           | Make the managed [MCP](../06-MCP-Tools/General/mcp.md) allowlist the only one that applies                                                                                                                                                              | MCP                                | Managed                 |
| [`allowManagedPermissionRulesOnly`](#allowmanagedpermissionrulesonly)                                 | Make [managed settings](../13-Enterprise-Admin/managed-settings.md) the only settings source of [permission rules](permissions.md#managed-settings)                                                                                              | Permission settings                | Managed                 |
| [`alwaysThinkingEnabled`](#alwaysthinkingenabled)                                                     | Turn [extended thinking](model-config.md#extended-thinking) off for every session                                                                                                                                               | Model and responses                | Any file                |
| [`apiKeyHelper`](#apikeyhelper)                                                                       | Generate the [API credential](authentication.md#credential-management) with your own command                                                                                                                                    | Authentication and providers       | Any file                |
| [`askUserQuestionTimeout`](#askuserquestiontimeout)                                                   | Let an unanswered question [auto-continue](tools-reference.md#question-auto-continue-timeout) after idle time                                                                                                                   | Interface and terminal             | User or managed         |
| [`appendPlugins`](#appendplugins)                                                                     | Run your organization’s [mods](../08-Plugins-Skills/plugins-mods-admin.md) after every mod a user installs                                                                                                                                           | Plugins and skills                 | User or managed         |
| [`attribution`](#attribution)                                                                         | Customize the attribution Claude Code adds to commits and pull requests                                                                                                                                                               | Git and attribution                | Any file                |
| [`attribution.commit`](#attribution-commit)                                                           | Change or hide the trailer Claude Code adds to commits                                                                                                                                                                                | Git and attribution                | Any file                |
| [`attribution.pr`](#attribution-pr)                                                                   | Change or hide the attribution line in pull request descriptions                                                                                                                                                                      | Git and attribution                | Any file                |
| [`attribution.sessionUrl`](#attribution-sessionurl)                                                   | Omit the claude.ai session link from [cloud](claude-code-on-the-web.md) and [Remote Control](remote-control.md) commits                                                                                                   | Git and attribution                | Any file                |
| [`autoCompactEnabled`](#autocompactenabled)                                                           | Turn [automatic compaction](context-window.md) off or on                                                                                                                                                                        | Memory and context                 | Any file                |
| [`autoCompactWindow`](#autocompactwindow)                                                             | Set how full the context gets before Claude Code [compacts](context-window.md)                                                                                                                                                  | Memory and context                 | Any file                |
| [`autoConnectIde`](#autoconnectide)                                                                   | Connect to a running [VS Code](../03-IDE-Integrations/vs-code.md) or [JetBrains](../03-IDE-Integrations/jetbrains.md#from-external-terminals) IDE automatically from an external terminal                                                                               | Global config settings             | Global config           |
| [`autoContinueAtUsageLimit`](#autocontinueatusagelimit)                                               | Wait in the open session and [continue the task automatically](interactive-mode.md#wait-for-a-usage-limit-to-reset) after a claude.ai usage limit resets                                                                        | Interface and terminal             | User or managed         |
| [`autoInstallIdeExtension`](#autoinstallideextension)                                                 | Turn off automatic install of the [IDE extension](../03-IDE-Integrations/vs-code.md#install-the-extension) from a VS Code terminal                                                                                                                     | Global config settings             | Global config           |
| [`autoMemoryDirectory`](#automemorydirectory)                                                         | Store [auto memory](memory.md#auto-memory) in a directory you choose                                                                                                                                                            | Memory and context                 | Any file                |
| [`autoMemoryEnabled`](#automemoryenabled)                                                             | Turn [auto memory](memory.md#auto-memory) off or on                                                                                                                                                                             | Memory and context                 | Any file                |
| [`autoMode`](#automode)                                                                               | Add your own allow and deny rules to the [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) classifier                                                                                                           | Permission settings                | User or managed         |
| [`autoMode.classifyAllShell`](#automode-classifyallshell)                                             | Send every shell command through the [auto mode classifier](permission-modes.md#what-the-classifier-blocks-by-default), even ones a narrow allow rule matches                                                                   | Permission settings                | User or managed         |
| [`autoScrollEnabled`](#autoscrollenabled)                                                             | [Follow new output](fullscreen.md#auto-follow) to the bottom in fullscreen rendering                                                                                                                                            | Interface and terminal             | Any file                |
| [`autoUpdatesChannel`](#autoupdateschannel)                                                           | Follow the stable [release channel](../01-Getting-Started/setup.md#configure-release-channel) instead of latest                                                                                                                                       | Updates and versioning             | Any file                |
| [`availableModels`](#availablemodels)                                                                 | [Restrict which models](model-config.md#restrict-model-selection) people can pick                                                                                                                                               | Model and responses                | Any file                |
| [`availableModelsMatch`](#availablemodelsmatch)                                                       | Make each `availableModels` model ID entry [permit only the version it names](model-config.md#block-specific-models-or-versions)                                                                                                | Model and responses                | Managed                 |
| [`awaySummaryEnabled`](#awaysummaryenabled)                                                           | Turn off the [session recap](interactive-mode.md#session-recap) shown when you come back to the terminal                                                                                                                        | Remote, desktop, and notifications | Any file                |
| [`awsAuthRefresh`](#awsauthrefresh)                                                                   | Refresh expired [Bedrock credentials](amazon-bedrock.md#advanced-credential-configuration) in `.aws` with your own command                                                                                                      | Authentication and providers       | Any file                |
| [`awsCredentialExport`](#awscredentialexport)                                                         | Supply [Bedrock credentials](amazon-bedrock.md#advanced-credential-configuration) as JSON from your own command                                                                                                                 | Authentication and providers       | Any file                |
| [`axScreenReader`](#axscreenreader)                                                                   | Render [screen-reader friendly output](accessibility.md)                                                                                                                                                                        | Interface and terminal             | User or managed         |
| [`bashEditDiffEnabled`](#basheditdiffenabled)                                                         | Record the [files that changed while a Bash command ran](../07-Hooks/hooks.md#bash) in every permission mode                                                                                                                                | Interface and terminal             | User or managed         |
| [`bashOutputMaxChars`](#bashoutputmaxchars)                                                           | Set how much of a successful command’s [output](tools-reference.md#output-limits) Claude receives inline                                                                                                                        | Memory and context                 | Any file                |
| [`blockedMarketplaces`](#blockedmarketplaces)                                                         | Block [plugin marketplace](../08-Plugins-Skills/plugins.md) sources for your organization                                                                                                                                                   | Plugins and skills                 | Managed                 |
| [`browserExternalPageTools`](#browserexternalpagetools)                                               | Keep Claude’s tools off external pages in the [desktop](../16-Mobile-Desktop/desktop.md) Browser pane                                                                                                                                                | Tools                              | Managed                 |
| [`channelsEnabled`](#channelsenabled)                                                                 | Allow [channels](channels.md#enable-channels-for-your-organization) for your organization                                                                                                                                       | Plugins and skills                 | Managed                 |
| [`claudeInChromeDefaultEnabled`](#claudeinchromedefaultenabled)                                       | Turn on [Chrome integration](../03-IDE-Integrations/chrome.md) when a session starts, in the interactive CLI and the VS Code extension                                                                                                                 | Global config settings             | Global config           |
| [`claudeMd`](#claudemd)                                                                               | Inject organization-wide [CLAUDE.md](memory.md#deploy-organization-wide-claude-md) instructions from managed settings                                                                                                           | Memory and context                 | Managed                 |
| [`claudeMdExcludes`](#claudemdexcludes)                                                               | Skip specific [CLAUDE.md](memory.md#exclude-specific-claude-md-files) files when memory loads                                                                                                                                   | Memory and context                 | Any file                |
| [`cleanupPeriodDays`](#cleanupperioddays)                                                             | Choose how many days Claude Code keeps [transcripts](../13-Enterprise-Admin/data-usage.md#data-retention) before deleting them                                                                                                                         | Privacy and telemetry              | Any file                |
| [`companyAnnouncements`](#companyannouncements)                                                       | Show your organization’s announcements at startup                                                                                                                                                                                     | Interface and terminal             | Any file                |
| [`copyFullResponse`](#copyfullresponse)                                                               | Make [`/copy`](commands.md) copy the full response without showing the picker                                                                                                                                                   | Global config settings             | Global config           |
| [`copyOnSelect`](#copyonselect)                                                                       | Turn off automatic copying of text you select with the mouse in [fullscreen rendering](fullscreen.md#use-the-mouse) and agent view                                                                                              | Global config settings             | Global config           |
| [`crossSessionInbound`](#crosssessioninbound)                                                         | Choose whether Claude Code delivers [messages from your other sessions](cross-session-messaging.md#control-inbound-messages), shows a notice without delivering them, or refuses them                                           | Agents, sessions, and worktrees    | Any file                |
| [`defaultShell`](#defaultshell)                                                                       | Choose whether Bash or PowerShell runs the shell commands you type with the [`!` prefix](interactive-mode.md#shell-mode-with-prefix)                                                                                            | Interface and terminal             | Any file                |
| [`defaultToAgentsView`](#defaulttoagentsview)                                                         | Open [agent view](../09-Agents-Patterns/agent-view.md) instead of a new conversation when you run `claude` with no arguments                                                                                                                          | Global config settings             | Global config           |
| [`deniedMcpServers`](#deniedmcpservers)                                                               | Block specific [MCP servers](../06-MCP-Tools/General/mcp.md) by URL, command, or name                                                                                                                                                                   | MCP                                | Any file                |
| [`deniedModels`](#deniedmodels)                                                                       | [Block specific models](model-config.md#block-specific-models-or-versions), even ones `availableModels` permits                                                                                                                 | Model and responses                | Managed                 |
| [`desktopSessionCleanupPeriodDays`](#desktopsessioncleanupperioddays)                                 | Set an age limit in days for [Claude Desktop and Cowork transcripts](claude-directory.md#cleaned-up-automatically)                                                                                                              | Privacy and telemetry              | User or managed         |
| [`dialogExpiry`](#dialogexpiry)                                                                       | Set how long Claude Code waits for [Remote Control](remote-control.md) or an SDK host to answer a forwarded dialog before it cancels the dialog                                                                                 | Interface and terminal             | User or managed         |
| [`diffTool`](#difftool)                                                                               | Choose whether Claude’s proposed file changes open in the [VS Code](../03-IDE-Integrations/vs-code.md) or [JetBrains](../03-IDE-Integrations/jetbrains.md#features) diff viewer or stay in the terminal                                                                 | Global config settings             | Global config           |
| [`disableAgentView`](#disableagentview)                                                               | Turn off background agents and [agent view](../09-Agents-Patterns/agent-view.md)                                                                                                                                                                      | Agents, sessions, and worktrees    | Any file                |
| [`disableAllHooks`](#disableallhooks)                                                                 | Turn off [hooks](../07-Hooks/hooks.md), a custom [status line](statusline.md), and a custom [`@` file suggestion](interactive-mode.md#quick-commands) command at once                                                           | Hooks and automation               | Any file                |
| [`disableArtifact`](#disableartifact)                                                                 | Deprecated; use `enableArtifact` to turn the [Artifact tool](artifacts.md) off                                                                                                                                                  | Remote, desktop, and notifications | Any file                |
| [`disableAutoMode`](#disableautomode)                                                                 | Remove [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) from the permission mode cycle                                                                                                                         | Permission settings                | Any file                |
| [`disableBrowserExternalNavigation`](#disablebrowserexternalnavigation)                               | Limit the [desktop](../16-Mobile-Desktop/desktop.md) Browser pane to localhost for people and Claude                                                                                                                                                 | Tools                              | Managed                 |
| [`disableBundledSkills`](#disablebundledskills)                                                       | Turn off the [skills](../08-Plugins-Skills/skills.md#bundled-skills) and [workflows](workflows.md) included with Claude Code                                                                                                                   | Plugins and skills                 | Any file                |
| [`disableClaudeAiConnectors`](#disableclaudeaiconnectors)                                             | Turn off [claude.ai connectors](../06-MCP-Tools/General/mcp.md#disable-claude-ai-connectors) so Claude Code doesn’t fetch them                                                                                                                          | MCP                                | Any file                |
| [`disableCommandPluginSources`](#disablecommandpluginsources)                                         | Block [plugins](../08-Plugins-Skills/plugins.md) that install by running a marketplace-declared command                                                                                                                                     | Plugins and skills                 | Managed                 |
| [`disableDeepLinkRegistration`](#disabledeeplinkregistration)                                         | Stop Claude Code from registering the [`claude-cli://` handler](deep-links.md)                                                                                                                                                  | Remote, desktop, and notifications | Any file                |
| [`disableDesktopLocalSessions`](#disabledesktoplocalsessions)                                         | Turn off [Desktop Code sessions](../16-Mobile-Desktop/desktop.md#local-sessions-on-managed-devices) that run on the device, leaving SSH to other hosts and cloud                                                                                     | Remote, desktop, and notifications | Managed                 |
| [`disabledMcpjsonServers`](#disabledmcpjsonservers)                                                   | Reject specific servers from a project’s [`.mcp.json`](../06-MCP-Tools/General/mcp.md#project-scope)                                                                                                                                                    | MCP                                | Any file                |
| [`disableMobileSimulatorTools`](#disablemobilesimulatortools)                                         | Block Claude’s tools in the [desktop](../16-Mobile-Desktop/desktop.md) iOS Simulator pane                                                                                                                                                            | Tools                              | Managed                 |
| [`disableRemoteControl`](#disableremotecontrol)                                                       | Turn off [Remote Control](remote-control.md) everywhere it can start                                                                                                                                                            | Remote, desktop, and notifications | Any file                |
| [`disableSideloadFlags`](#disablesideloadflags)                                                       | Reject the CLI flags that sideload [plugins](../08-Plugins-Skills/plugins.md), [subagents](../09-Agents-Patterns/sub-agents.md), and [MCP servers](../06-MCP-Tools/General/mcp.md)                                                                                            | Enterprise and managed settings    | Managed                 |
| [`disableSkillShellExecution`](#disableskillshellexecution)                                           | Stop [skills](../08-Plugins-Skills/skills.md) and custom commands from running inline shell                                                                                                                                                          | Plugins and skills                 | Any file                |
| [`disableWorkflows`](#disableworkflows)                                                               | Turn [dynamic workflows](workflows.md) off for everyone; use `enableWorkflows` for yourself                                                                                                                                     | Hooks and automation               | Any file                |
| [`editorMode`](#editormode)                                                                           | Use [vim key bindings](interactive-mode.md#vim-editor-mode) in the input prompt                                                                                                                                                 | Interface and terminal             | Any file                |
| [`effortLevel`](#effortlevel)                                                                         | Set a default [effort level](model-config.md#adjust-effort-level) for models without a saved level of their own                                                                                                                 | Model and responses                | Any file                |
| [`emojiCompletionEnabled`](#emojicompletionenabled)                                                   | Turn off [`:shortcode:` emoji suggestions and replacement](interactive-mode.md#emoji-shortcodes) in the prompt input                                                                                                            | Interface and terminal             | Any file                |
| [`enableAllProjectMcpServers`](#enableallprojectmcpservers)                                           | Approve every server in project [`.mcp.json`](../06-MCP-Tools/General/mcp.md#project-server-approvals-and-workspace-trust) files without a prompt                                                                                                       | MCP                                | Any file                |
| [`enableArtifact`](#enableartifact)                                                                   | Turn the [Artifact tool](artifacts.md) off with a `false` in any file; no file can turn it back on                                                                                                                              | Remote, desktop, and notifications | Any file                |
| [`enabledMcpjsonServers`](#enabledmcpjsonservers)                                                     | Approve specific servers from a project’s [`.mcp.json`](../06-MCP-Tools/General/mcp.md#project-server-approvals-and-workspace-trust)                                                                                                                    | MCP                                | Any file                |
| [`enabledPlugins`](#enabledplugins)                                                                   | Turn individual [plugins](../08-Plugins-Skills/plugins.md) on or off per scope                                                                                                                                                              | Plugins and skills                 | Any file                |
| [`enableWorkflows`](#enableworkflows)                                                                 | Turn [dynamic workflows](workflows.md) on or off against your plan’s default                                                                                                                                                    | Hooks and automation               | Any file                |
| [`enforceAvailableModels`](#enforceavailablemodels)                                                   | Keep the [`/model` Default choice](model-config.md#enforce-the-allowlist-for-the-default-model) inside your `availableModels` allowlist                                                                                         | Model and responses                | Any file                |
| [`env`](#env)                                                                                         | Set [environment variables](env-vars.md#in-settings-files) for every session and its subprocesses                                                                                                                               | Memory and context                 | Any file                |
| [`externalEditorContext`](#externaleditorcontext)                                                     | Show Claude’s last response as comments when you press [Ctrl+G](interactive-mode.md#general-controls) to edit                                                                                                                   | Global config settings             | Global config           |
| [`extraKnownMarketplaces`](#extraknownmarketplaces)                                                   | Register [marketplaces](../08-Plugins-Skills/plugins.md) for a repository or an organization                                                                                                                                                | Plugins and skills                 | Any file                |
| [`fallbackModel`](#fallbackmodel)                                                                     | Name [backup models](model-config.md#fallback-model-chains) for when the primary is overloaded                                                                                                                                  | Model and responses                | Any file                |
| [`fastMode`](#fastmode)                                                                               | Turn [fast mode](fast-mode.md) on for sessions where it’s available                                                                                                                                                             | Model and responses                | Any file                |
| [`fastModePerSessionOptIn`](#fastmodepersessionoptin)                                                 | Require people to turn [fast mode](fast-mode.md) on each session                                                                                                                                                                | Model and responses                | Any file                |
| [`feedbackDrafts`](#feedbackdrafts)                                                                   | Control whether Claude queues [feedback drafts](tools-reference.md#sendfeedback-tool-behavior) for you to review                                                                                                                | Privacy and telemetry              | User or managed         |
| [`feedbackSurveyRate`](#feedbacksurveyrate)                                                           | Change how often the [session quality survey](../13-Enterprise-Admin/data-usage.md#session-quality-surveys) appears                                                                                                                                    | Privacy and telemetry              | Any file                |
| [`fileCheckpointingEnabled`](#filecheckpointingenabled)                                               | Turn off or on the file snapshots that [`/rewind`](checkpointing.md) restores                                                                                                                                                   | Memory and context                 | Any file                |
| [`fileSuggestion`](#filesuggestion)                                                                   | Supply [`@` file autocomplete](interactive-mode.md#quick-commands) from your own command                                                                                                                                        | Interface and terminal             | Any file                |
| [`footerLinksRegexes`](#footerlinksregexes)                                                           | Make issue or review IDs in output into [clickable links](statusline.md#clickable-links) below the input box                                                                                                                    | Interface and terminal             | User or managed         |
| [`forceLoginGatewayUrl`](#forcelogingatewayurl)                                                       | Set the [gateway URL](../13-Enterprise-Admin/claude-apps-gateway.md#set-the-gateway-url) the login screen connects to                                                                                                                                  | Authentication and providers       | User or managed         |
| [`forceLoginMethod`](#forceloginmethod)                                                               | [Restrict login](authentication.md#restrict-login-to-your-organization) to claude.ai, Claude Console, or a [cloud gateway](../13-Enterprise-Admin/claude-apps-gateway.md)                                                                        | Authentication and providers       | Any file                |
| [`forceLoginOrgUUID`](#forceloginorguuid)                                                             | [Pin claude.ai logins to your organization](authentication.md#restrict-login-to-your-organization); only a managed source enforces it                                                                                           | Authentication and providers       | Any file                |
| [`forceRemoteSettingsRefresh`](#forceremotesettingsrefresh)                                           | Block startup until [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) are freshly fetched                                                                                                                                   | Enterprise and managed settings    | Managed                 |
| [`gatewayInternalNetworks`](#gatewayinternalnetworks)                                                 | Let `/login` reach a [cloud gateway](../13-Enterprise-Admin/claude-apps-gateway.md#allow-a-gateway-on-public-address-space-you-own) on public IPv4 space your organization uses internally                                                             | Authentication and providers       | Managed                 |
| [`gcpAuthRefresh`](#gcpauthrefresh)                                                                   | Refresh [Google Cloud credentials](google-vertex-ai.md#advanced-credential-configuration) with your own command                                                                                                                 | Authentication and providers       | Any file                |
| [`hooks`](#hooks)                                                                                     | Run your own commands as [hooks](../07-Hooks/hooks.md) at points in Claude Code’s lifecycle                                                                                                                                                 | Hooks and automation               | Any file                |
| [`httpHookAllowedEnvVars`](#httphookallowedenvvars)                                                   | Limit which env vars [HTTP hooks](../07-Hooks/hooks.md) can put in headers                                                                                                                                                                  | Hooks and automation               | Any file                |
| [`idleCompaction`](#idlecompaction)                                                                   | Stop Claude Code from compacting a long conversation while your terminal session is idle                                                                                                                                              | Memory and context                 | Any file                |
| [`includeCoAuthoredBy`](#includecoauthoredby)                                                         | Deprecated; use `attribution` to hide or change commit and PR attribution                                                                                                                                                             | Git and attribution                | Any file                |
| [`includeGitInstructions`](#includegitinstructions)                                                   | Remove the built-in commit and PR instructions from Claude’s context                                                                                                                                                                  | Git and attribution                | Any file                |
| [`inputNeededNotifEnabled`](#inputneedednotifenabled)                                                 | Get a [push notification](remote-control.md#mobile-push-notifications) when Claude is waiting on you                                                                                                                            | Remote, desktop, and notifications | Any file                |
| [`isolatePeerMachines`](#isolatepeermachines)                                                         | Ask you before Claude [messages one of your sessions on another machine](cross-session-messaging.md#require-approval-for-cross-machine-messages)                                                                                | Agents, sessions, and worktrees    | Any file                |
| [`keybindingFlavor`](#keybindingflavor)                                                               | Deprecated and has no effect; the word-editing shortcuts always [follow readline conventions](interactive-mode.md#make-ctrl-w-delete-back-to-whitespace)                                                                        | Interface and terminal             | Any file                |
| [`language`](#language)                                                                               | Have Claude respond in a language other than English                                                                                                                                                                                  | Model and responses                | Any file                |
| [`leftArrowOpensAgents`](#leftarrowopensagents)                                                       | Turn off the `←` shortcut that [backgrounds the session and opens agent view](../09-Agents-Patterns/agent-view.md#switch-sessions-without-leaving-the-terminal)                                                                                       | Global config settings             | Global config           |
| [`managedMcpServers`](#managedmcpservers)                                                             | Provide remote [MCP servers](../06-MCP-Tools/General/managed-mcp.md#provide-servers-through-managed-settings) to every user alongside the ones they add                                                                                                 | MCP                                | Managed                 |
| [`managedSourcesBehavior`](#managedsourcesbehavior)                                                   | Compose every [managed source](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) you deploy instead of using the highest-priority one alone                                                                         | Enterprise and managed settings    | Managed                 |
| [`maxEffortLevel`](#maxeffortlevel)                                                                   | Cap the [effort level](model-config.md#adjust-effort-level) for every model or per model, on every provider                                                                                                                     | Model and responses                | Any file                |
| [`maxProseWidth`](#maxprosewidth)                                                                     | Cap how wide the prose in Claude’s responses runs in a wide terminal                                                                                                                                                                  | Interface and terminal             | Any file                |
| [`minimumVersion`](#minimumversion)                                                                   | Keep [auto-updates](../01-Getting-Started/setup.md#pin-a-minimum-version) from installing anything below a version                                                                                                                                    | Updates and versioning             | Any file                |
| [`model`](#model)                                                                                     | Change the [model](model-config.md#set-a-default-model-for-new-sessions) Claude Code starts with                                                                                                                                | Model and responses                | Any file                |
| [`modelOverrides`](#modeloverrides)                                                                   | [Map model IDs](model-config.md#override-model-ids-per-version) to your provider’s IDs, such as Bedrock ARNs                                                                                                                    | Model and responses                | Any file                |
| [`modelPicker`](#modelpicker)                                                                         | Choose which models the [`/model` picker](model-config.md#available-models) lists, in your own order and with your own labels                                                                                                   | Model and responses                | User or managed         |
| [`modelPricing`](#modelpricing)                                                                       | Report spend at your organization’s contracted rates instead of list price                                                                                                                                                            | Model and responses                | Managed                 |
| [`modelSettings`](#modelsettings)                                                                     | Keep a saved [effort level](model-config.md#adjust-effort-level) or [auto-compact window](model-config.md#set-the-auto-compact-window) per model, or cap one model’s effort                                               | Model and responses                | Any file                |
| [`otelHeadersHelper`](#otelheadershelper)                                                             | Generate rotating [OpenTelemetry](../13-Enterprise-Admin/monitoring-usage.md#dynamic-headers) headers with your own command                                                                                                                            | Authentication and providers       | Any file                |
| [`outputStyle`](#outputstyle)                                                                         | Change Claude’s role, tone, and output format with an [output style](output-styles.md)                                                                                                                                          | Model and responses                | Any file                |
| [`parentSettingsBehavior`](#parentsettingsbehavior)                                                   | Apply or drop restrictions an [SDK or IDE host](../13-Enterprise-Admin/managed-settings.md#let-an-embedding-host-add-policy) passes when you deploy [managed settings](../13-Enterprise-Admin/managed-settings.md)                                                      | Enterprise and managed settings    | Managed                 |
| [`permissionExplainerEnabled`](#permissionexplainerenabled)                                           | Removed in v2.1.257, together with the `Ctrl+E` command explanation on shell permission prompts                                                                                                                                       | Global config settings             | Global config           |
| [`permissions`](#permissions)                                                                         | Set allow, ask, and deny rules and the starting [permission mode](permission-modes.md)                                                                                                                                          | Permission settings                | Any file                |
| [`permissions.additionalDirectories`](#permissions-additionaldirectories)                             | Give Claude file access to [directories outside the current one](permissions.md#working-directories)                                                                                                                            | Permission settings                | Any file                |
| [`permissions.allow`](#permissions-allow)                                                             | Approve listed [tool uses](permissions.md#permission-rule-syntax) without a prompt                                                                                                                                              | Permission settings                | Any file                |
| [`permissions.ask`](#permissions-ask)                                                                 | Always prompt before listed [tool uses](permissions.md#permission-rule-syntax)                                                                                                                                                  | Permission settings                | Any file                |
| [`permissions.blockReadsOutsideWorkingDirectories`](#permissions-blockreadsoutsideworkingdirectories) | Make the file tools refuse reads outside the [working directories](permissions.md#working-directories) in every permission mode                                                                                                 | Permission settings                | Any file                |
| [`permissions.defaultMode`](#permissions-defaultmode)                                                 | Set the [permission mode](permission-modes.md#which-mode-a-session-starts-in) new sessions start in                                                                                                                             | Permission settings                | Any file                |
| [`permissions.deny`](#permissions-deny)                                                               | Block listed [tool uses](permissions.md#permission-rule-syntax), including reads of files that hold secrets                                                                                                                     | Permission settings                | Any file                |
| [`permissions.disableBypassPermissionsMode`](#permissions-disablebypasspermissionsmode)               | Prevent anyone from entering [bypassPermissions mode](permission-modes.md#skip-all-checks-with-bypasspermissions-mode)                                                                                                          | Permission settings                | Any file                |
| [`plansDirectory`](#plansdirectory)                                                                   | Choose where [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode) writes plan files                                                                                                                          | Memory and context                 | Any file                |
| [`pluginConfigs`](#pluginconfigs)                                                                     | Store the answers you gave a [plugin](../08-Plugins-Skills/plugins.md)’s configuration dialog                                                                                                                                               | Plugins and skills                 | User or managed         |
| [`pluginSuggestionMarketplaces`](#pluginsuggestionmarketplaces)                                       | Choose which [marketplaces](../08-Plugins-Skills/plugins-org.md#restrict-what-users-can-install) can surface plugin install suggestions in `/plugin`                                                                                                 | Plugins and skills                 | Managed                 |
| [`pluginTrustMessage`](#plugintrustmessage)                                                           | Add your own text to the [plugin](../08-Plugins-Skills/plugins.md) trust warning                                                                                                                                                            | Plugins and skills                 | Managed                 |
| [`policyHelper`](#policyhelper)                                                                       | Run an executable that computes [managed settings](../13-Enterprise-Admin/managed-settings.md#compute-the-policy-with-a-helper-program) at startup                                                                                                     | Enterprise and managed settings    | Managed                 |
| [`policyHelper.path`](#policyhelper-path)                                                             | Name the [helper executable](../13-Enterprise-Admin/managed-settings.md#compute-the-policy-with-a-helper-program) Claude Code runs                                                                                                                     | Enterprise and managed settings    | Managed                 |
| [`policyHelper.refreshIntervalMs`](#policyhelper-refreshintervalms)                                   | Re-run the [helper](../13-Enterprise-Admin/managed-settings.md#compute-the-policy-with-a-helper-program) in the background on an interval                                                                                                              | Enterprise and managed settings    | Managed                 |
| [`policyHelper.timeoutMs`](#policyhelper-timeoutms)                                                   | Set how long Claude Code waits for the [helper](../13-Enterprise-Admin/managed-settings.md#compute-the-policy-with-a-helper-program)                                                                                                                   | Enterprise and managed settings    | Managed                 |
| [`preferredNotifChannel`](#preferrednotifchannel)                                                     | Choose a [terminal bell or desktop notification](terminal-config.md#get-a-terminal-bell-or-notification) for task completion                                                                                                    | Remote, desktop, and notifications | Any file                |
| [`prefersReducedMotion`](#prefersreducedmotion)                                                       | [Reduce or turn off](accessibility.md#accessibility-settings) spinner, shimmer, and flash animations                                                                                                                            | Interface and terminal             | Any file                |
| [`prependPlugins`](#prependplugins)                                                                   | Run your organization’s [mods](../08-Plugins-Skills/plugins-mods-admin.md) before every mod a user installs                                                                                                                                          | Plugins and skills                 | User or managed         |
| [`processWrapper`](#processwrapper)                                                                   | Run Claude Code’s background processes through a [corporate launcher](../13-Enterprise-Admin/corporate-launcher.md) on macOS and Linux                                                                                                                 | Agents, sessions, and worktrees    | User or managed         |
| [`promptCacheTtl`](#promptcachettl)                                                                   | Choose the [prompt cache lifetime](prompt-caching.md#cache-lifetime) for the main conversation                                                                                                                                  | Model and responses                | Any file                |
| [`promptSuggestionEnabled`](#promptsuggestionenabled)                                                 | Hide the grayed-out [prompt suggestions](interactive-mode.md#prompt-suggestions) in the input box                                                                                                                               | Interface and terminal             | Any file                |
| [`prStatusFooterEnabled`](#prstatusfooterenabled)                                                     | Turn off the prompt footer’s [PR review status](interactive-mode.md#pr-review-status) badge and the pull request check behind it                                                                                                | Global config settings             | Global config           |
| [`prUrlTemplate`](#prurltemplate)                                                                     | Point PR links at an internal code-review tool instead of github.com                                                                                                                                                                  | Git and attribution                | Any file                |
| [`remote.defaultEnvironmentId`](#remote-defaultenvironmentid)                                         | Pick the default [cloud environment](cloud-environments.md) for `claude --cloud`; a self-hosted `ccpool_` ID is read only from user and managed settings and `--settings`                                                       | Remote, desktop, and notifications | Any file                |
| [`remoteControlAtStartup`](#remotecontrolatstartup)                                                   | Connect [Remote Control](remote-control.md#enable-remote-control-for-all-sessions) automatically when a session starts                                                                                                          | Remote, desktop, and notifications | Any file                |
| [`requiredMaximumVersion`](#requiredmaximumversion)                                                   | [Refuse to start](../01-Getting-Started/setup.md#pin-a-minimum-version) on a version newer than your organization allows                                                                                                                              | Updates and versioning             | Managed                 |
| [`requiredMinimumVersion`](#requiredminimumversion)                                                   | [Refuse to start](../01-Getting-Started/setup.md#pin-a-minimum-version) on a version older than your organization requires                                                                                                                            | Updates and versioning             | Managed                 |
| [`respectGitignore`](#respectgitignore)                                                               | Keep gitignored files out of the [`@` file picker](interactive-mode.md#quick-commands)                                                                                                                                          | Interface and terminal             | Any file                |
| [`respondToBashCommands`](#respondtobashcommands)                                                     | Stop Claude from responding after a [`!` shell command](interactive-mode.md#shell-mode-with-prefix) runs                                                                                                                        | Interface and terminal             | Any file                |
| [`sandbox`](#sandbox)                                                                                 | [Isolate Bash commands](sandboxing.md) from your filesystem and network on macOS, Linux, and WSL2                                                                                                                               | Sandbox settings                   | Any file                |
| [`sandbox.allowAppleEvents`](#sandbox-allowappleevents)                                               | Let [sandboxed](sandboxing.md) commands send Apple Events on macOS                                                                                                                                                              | Sandbox settings                   | User or managed         |
| [`sandbox.allowNestedUserNamespaces`](#sandbox-allownestedusernamespaces)                             | Let [sandboxed](sandboxing.md#chromium-or-rootless-podman-fails-inside-the-sandbox-on-linux) commands create user namespaces on Linux and WSL2                                                                                  | Sandbox settings                   | User or managed         |
| [`sandbox.allowUnsandboxedCommands`](#sandbox-allowunsandboxedcommands)                               | Let Claude retry a blocked command outside the [sandbox](sandboxing.md#the-unsandboxed-retry-escape-hatch), or forbid it                                                                                                        | Sandbox settings                   | Any file                |
| [`sandbox.autoAllowBashIfSandboxed`](#sandbox-autoallowbashifsandboxed)                               | Run [sandboxed](sandboxing.md#auto-allow-mode) commands without a permission prompt                                                                                                                                             | Sandbox settings                   | Any file                |
| [`sandbox.bwrapPath`](#sandbox-bwrappath)                                                             | Point the [sandbox](sandboxing.md) at a bubblewrap binary outside `PATH`                                                                                                                                                        | Sandbox settings                   | Managed                 |
| [`sandbox.credentials`](#sandbox-credentials)                                                         | Hide or mask credential files and variables inside the [sandbox](sandboxing.md#protect-credentials)                                                                                                                             | Sandbox settings                   | Any file                |
| [`sandbox.credentials.allowPlaintextInject`](#sandbox-credentials-allowplaintextinject)               | Let [masked credentials](sandboxing.md#mask-credentials) reach plain HTTP services on trusted test networks                                                                                                                     | Sandbox settings                   | User or managed         |
| [`sandbox.credentials.awsPairs`](#sandbox-credentials-awspairs)                                       | Link custom-named AWS key variables into one credential for [re-signing](sandboxing.md#re-sign-aws-requests)                                                                                                                    | Sandbox settings                   | User or managed         |
| [`sandbox.credentials.envVars`](#sandbox-credentials-envvars)                                         | Unset or mask an environment variable inside the [sandbox](sandboxing.md#mask-environment-variables)                                                                                                                            | Sandbox settings                   | Any file                |
| [`sandbox.credentials.files`](#sandbox-credentials-files)                                             | Block or mask reads of a credential file inside the [sandbox](sandboxing.md#mask-credential-files)                                                                                                                              | Sandbox settings                   | Any file                |
| [`sandbox.credentials.sigv4`](#sandbox-credentials-sigv4)                                             | Choose whether streaming, presigned, or [SigV4A AWS requests](sandboxing.md#re-sign-aws-requests) fail or pass through                                                                                                          | Sandbox settings                   | User or managed         |
| [`sandbox.enabled`](#sandbox-enabled)                                                                 | Turn on [Bash sandboxing](sandboxing.md#get-started) on macOS, Linux, and WSL2                                                                                                                                                  | Sandbox settings                   | Any file                |
| [`sandbox.enableWeakerNestedSandbox`](#sandbox-enableweakernestedsandbox)                             | Run the Linux [sandbox](sandboxing.md) inside an unprivileged container                                                                                                                                                         | Sandbox settings                   | Any file                |
| [`sandbox.enableWeakerNetworkIsolation`](#sandbox-enableweakernetworkisolation)                       | Let `gh`, `gcloud`, and `terraform` verify TLS behind a MITM proxy inside the [sandbox](sandboxing.md#go-based-clis-fail-tls-verification-on-macos) on macOS                                                                    | Sandbox settings                   | Any file                |
| [`sandbox.excludedCommands`](#sandbox-excludedcommands)                                               | Name commands Claude Code can run outside the [sandbox](sandboxing.md)                                                                                                                                                          | Sandbox settings                   | Any file                |
| [`sandbox.failIfUnavailable`](#sandbox-failifunavailable)                                             | Refuse to start when the [sandbox](sandboxing.md) can’t, instead of running unsandboxed                                                                                                                                         | Sandbox settings                   | Any file                |
| [`sandbox.filesystem`](#sandbox-filesystem)                                                           | Control which paths [sandboxed](sandboxing.md#filesystem-isolation) commands can read and write                                                                                                                                 | Sandbox settings                   | Any file                |
| [`sandbox.filesystem.allowManagedReadPathsOnly`](#sandbox-filesystem-allowmanagedreadpathsonly)       | Stop developers from re-opening [read paths your organization blocked](sandboxing.md#keep-developers-from-widening-the-policy)                                                                                                  | Sandbox settings                   | Managed                 |
| [`sandbox.filesystem.allowRead`](#sandbox-filesystem-allowread)                                       | Re-open reading inside a region [`denyRead`](#sandbox-filesystem-denyread) blocks                                                                                                                                                     | Sandbox settings                   | Any file                |
| [`sandbox.filesystem.allowWrite`](#sandbox-filesystem-allowwrite)                                     | Add paths [sandboxed](sandboxing.md) commands can write to                                                                                                                                                                      | Sandbox settings                   | Any file                |
| [`sandbox.filesystem.denyRead`](#sandbox-filesystem-denyread)                                         | Block [sandboxed](sandboxing.md) commands from reading specific paths                                                                                                                                                           | Sandbox settings                   | Any file                |
| [`sandbox.filesystem.denyWrite`](#sandbox-filesystem-denywrite)                                       | Block [sandboxed](sandboxing.md) commands from writing to specific paths                                                                                                                                                        | Sandbox settings                   | Any file                |
| [`sandbox.filesystem.disabled`](#sandbox-filesystem-disabled)                                         | [Turn off filesystem isolation](sandboxing.md#disable-filesystem-isolation) while keeping network isolation                                                                                                                     | Sandbox settings                   | User or managed         |
| [`sandbox.ignoreViolations`](#sandbox-ignoreviolations)                                               | Silence violation reports for paths a command is expected to probe                                                                                                                                                                    | Sandbox settings                   | Any file                |
| [`sandbox.network`](#sandbox-network)                                                                 | Control which hosts, ports, and sockets [sandboxed](sandboxing.md#network-isolation) commands reach                                                                                                                             | Sandbox settings                   | Any file                |
| [`sandbox.network.allowAllUnixSockets`](#sandbox-network-allowallunixsockets)                         | Let [sandboxed](sandboxing.md) commands connect to every Unix socket                                                                                                                                                            | Sandbox settings                   | Any file                |
| [`sandbox.network.allowedDomains`](#sandbox-network-alloweddomains)                                   | Pre-allow domains so [sandboxed](sandboxing.md) commands don’t prompt for them                                                                                                                                                  | Sandbox settings                   | Any file                |
| [`sandbox.network.allowLocalBinding`](#sandbox-network-allowlocalbinding)                             | Let [sandboxed](sandboxing.md) commands listen on network ports and connect to localhost on macOS                                                                                                                               | Sandbox settings                   | Any file                |
| [`sandbox.network.allowMachLookup`](#sandbox-network-allowmachlookup)                                 | Let macOS [sandboxed](sandboxing.md) tools like the iOS Simulator or Playwright reach their XPC services                                                                                                                        | Sandbox settings                   | Any file                |
| [`sandbox.network.allowManagedDomainsOnly`](#sandbox-network-allowmanageddomainsonly)                 | Lock the network allowlist to [managed settings](sandboxing.md#keep-developers-from-widening-the-policy)                                                                                                                        | Sandbox settings                   | Managed                 |
| [`sandbox.network.allowUnixSockets`](#sandbox-network-allowunixsockets)                               | List Unix socket paths [sandboxed](sandboxing.md) commands can use on macOS                                                                                                                                                     | Sandbox settings                   | Any file                |
| [`sandbox.network.deniedDomains`](#sandbox-network-denieddomains)                                     | Block domains for [sandboxed](sandboxing.md) commands, even inside an allowed wildcard                                                                                                                                          | Sandbox settings                   | Any file                |
| [`sandbox.network.httpProxyPort`](#sandbox-network-httpproxyport)                                     | Route [sandbox](sandboxing.md#custom-proxy-configuration) HTTP traffic through your own proxy                                                                                                                                   | Sandbox settings                   | Any file                |
| [`sandbox.network.socksProxyPort`](#sandbox-network-socksproxyport)                                   | Route [sandbox](sandboxing.md#custom-proxy-configuration) SOCKS traffic through your own proxy                                                                                                                                  | Sandbox settings                   | Any file                |
| [`sandbox.network.strictAllowlist`](#sandbox-network-strictallowlist)                                 | Deny hosts outside the [allowlist](sandboxing.md#network-isolation) instead of prompting                                                                                                                                        | Sandbox settings                   | User or managed         |
| [`sandbox.network.tlsTerminate`](#sandbox-network-tlsterminate)                                       | Have the [sandbox](sandboxing.md#network-isolation) proxy terminate TLS so it can read HTTPS requests                                                                                                                           | Sandbox settings                   | User or managed         |
| [`sandbox.ripgrep`](#sandbox-ripgrep)                                                                 | Use your own ripgrep binary inside the [sandbox](sandboxing.md)                                                                                                                                                                 | Sandbox settings                   | User or managed         |
| [`sandbox.socatPath`](#sandbox-socatpath)                                                             | Point the [sandbox](sandboxing.md) proxy at a `socat` binary outside `PATH`                                                                                                                                                     | Sandbox settings                   | Managed                 |
| [`showClearContextOnPlanAccept`](#showclearcontextonplanaccept)                                       | Show a “clear context” option on the [plan accept screen](permission-modes.md#review-and-approve-a-plan)                                                                                                                        | Interface and terminal             | Any file                |
| [`showThinkingSummaries`](#showthinkingsummaries)                                                     | See summaries of Claude’s [thinking](model-config.md#extended-thinking) instead of a collapsed stub                                                                                                                             | Model and responses                | Any file                |
| [`showTurnDuration`](#showturnduration)                                                               | Hide the “Cooked for” duration after each response                                                                                                                                                                                    | Interface and terminal             | Any file                |
| [`skillListingBudgetFraction`](#skilllistingbudgetfraction)                                           | Reserve more or less context for the [skill listing](../08-Plugins-Skills/skills.md#skill-descriptions-are-cut-short)                                                                                                                                | Memory and context                 | Any file                |
| [`skillListingMaxDescChars`](#skilllistingmaxdescchars)                                               | Cap each skill’s description length in the [skill listing](../08-Plugins-Skills/skills.md#skill-descriptions-are-cut-short)                                                                                                                          | Memory and context                 | Any file                |
| [`skillOverrides`](#skilloverrides)                                                                   | [Hide or collapse a skill](../08-Plugins-Skills/skills.md#override-skill-visibility-from-settings) without editing its SKILL.md                                                                                                                      | Plugins and skills                 | Any file                |
| [`skipAutoPermissionPrompt`](#skipautopermissionprompt)                                               | Skip the one-time notice Claude Code shows when you first enter [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) yourself rather than through the built-in default                                             | Permission settings                | User or managed         |
| [`skipDangerousModePermissionPrompt`](#skipdangerousmodepermissionprompt)                             | Skip the confirmation dialog before [bypassPermissions mode](permission-modes.md#skip-all-checks-with-bypasspermissions-mode)                                                                                                   | Permission settings                | User, local, or managed |
| [`skipWebFetchPreflight`](#skipwebfetchpreflight)                                                     | Skip the [WebFetch hostname check](tools-reference.md#webfetch-tool-behavior) when Anthropic is unreachable                                                                                                                     | Privacy and telemetry              | Any file                |
| [`spellcheck`](#spellcheck)                                                                           | Underline misspelled words in the prompt input with a [spell checker](interactive-mode.md#check-spelling-as-you-type) you install                                                                                               | Interface and terminal             | User or managed         |
| [`spinnerTipsEnabled`](#spinnertipsenabled)                                                           | Hide tips in the spinner while Claude works                                                                                                                                                                                           | Interface and terminal             | Any file                |
| [`spinnerTipsOverride`](#spinnertipsoverride)                                                         | Add your own tips to the spinner rotation, or replace the built-in tips                                                                                                                                                               | Interface and terminal             | Any file                |
| [`spinnerVerbs`](#spinnerverbs)                                                                       | Add or replace the verbs shown while a turn runs                                                                                                                                                                                      | Interface and terminal             | Any file                |
| [`sshConfigs`](#sshconfigs)                                                                           | Add [SSH connections](../16-Mobile-Desktop/desktop.md#pre-configure-ssh-connections-for-your-team) to the Desktop environment selector                                                                                                               | Remote, desktop, and notifications | User or managed         |
| [`sshHostAllowlist`](#sshhostallowlist)                                                               | Limit which hosts [Desktop SSH sessions](../16-Mobile-Desktop/desktop.md#restrict-which-ssh-hosts-users-can-connect-to) can reach                                                                                                                    | Remote, desktop, and notifications | Managed                 |
| [`statusLine`](#statusline)                                                                           | Run your own command to render a [status line](statusline.md) below the prompt                                                                                                                                                  | Interface and terminal             | Any file                |
| [`strictKnownMarketplaces`](#strictknownmarketplaces)                                                 | Allowlist the [marketplace](../08-Plugins-Skills/plugins.md) sources users can add and install from                                                                                                                                         | Plugins and skills                 | Managed                 |
| [`strictPluginOnlyCustomization`](#strictpluginonlycustomization)                                     | Block [skills](../08-Plugins-Skills/skills.md), [agents](../09-Agents-Patterns/sub-agents.md), [hooks](../07-Hooks/hooks.md), and [MCP servers](../06-MCP-Tools/General/mcp.md) from user and project sources                                                                                | Plugins and skills                 | Managed                 |
| [`strictPluginOnlyCustomization.agents`](#strictpluginonlycustomization-agents)                       | Lock [agents](../09-Agents-Patterns/sub-agents.md) to plugin and managed sources                                                                                                                                                                      | Plugins and skills                 | Managed                 |
| [`strictPluginOnlyCustomization.hooks`](#strictpluginonlycustomization-hooks)                         | Lock [hooks](../07-Hooks/hooks.md) to plugin and managed sources                                                                                                                                                                            | Plugins and skills                 | Managed                 |
| [`strictPluginOnlyCustomization.mcp`](#strictpluginonlycustomization-mcp)                             | Lock [MCP servers](../06-MCP-Tools/General/mcp.md) to plugin and managed sources                                                                                                                                                                        | Plugins and skills                 | Managed                 |
| [`strictPluginOnlyCustomization.skills`](#strictpluginonlycustomization-skills)                       | Lock [skills](../08-Plugins-Skills/skills.md) to plugin and managed sources                                                                                                                                                                          | Plugins and skills                 | Managed                 |
| [`subagentPromptCacheTtl`](#subagentpromptcachettl)                                                   | Choose the [prompt cache lifetime](prompt-caching.md#cache-lifetime) for subagents and other requests outside the main conversation                                                                                             | Model and responses                | Any file                |
| [`subagentStatusLine`](#subagentstatusline)                                                           | Rewrite rows in the [subagent](../09-Agents-Patterns/sub-agents.md) task display with your own command                                                                                                                                                | Interface and terminal             | Any file                |
| [`switchModelsOnFlag`](#switchmodelsonflag)                                                           | Switch models automatically or pause when a [safety classifier](model-config.md#ask-before-switching) flags a request                                                                                                           | Model and responses                | Any file                |
| [`syncClaudeAiPlugins`](#syncclaudeaiplugins)                                                         | Stop loading the [plugins enabled on your claude.ai account](../08-Plugins-Skills/plugins-loading.md#synced-plugins) and stop downloading new ones                                                                                                   | Plugins and skills                 | User, local, or managed |
| [`syncClaudeAiSkills`](#syncclaudeaiskills)                                                           | Stop loading the [skills enabled on your claude.ai account](../08-Plugins-Skills/skills.md#how-synced-skills-behave) and stop downloading new ones                                                                                                   | Plugins and skills                 | User, local, or managed |
| [`syntaxHighlightingDisabled`](#syntaxhighlightingdisabled)                                           | Turn off syntax highlighting in diffs and code blocks                                                                                                                                                                                 | Interface and terminal             | Any file                |
| [`taskOutputMaxChars`](#taskoutputmaxchars)                                                           | Removed in v2.1.277, together with the `TaskOutput` tool it sized                                                                                                                                                                     | Memory and context                 | Any file                |
| [`teammateDefaultModel`](#teammatedefaultmodel)                                                       | Removed in v2.1.234; see [Specify teammates and models](../09-Agents-Patterns/agent-teams.md#specify-teammates-and-models) for how Claude Code picks a teammate’s model                                                                               | Global config settings             | Global config           |
| [`teammateMode`](#teammatemode)                                                                       | Choose how [agent team teammates display](../09-Agents-Patterns/agent-teams.md#choose-a-display-mode)                                                                                                                                                 | Agents, sessions, and worktrees    | Any file                |
| [`terminalProgressBarEnabled`](#terminalprogressbarenabled)                                           | Hide the terminal progress bar in terminals that support it                                                                                                                                                                           | Interface and terminal             | Any file                |
| [`terminalTitleFromRename`](#terminaltitlefromrename)                                                 | Stop [`/rename`](sessions.md#name-your-sessions) and `--name` from changing the terminal tab title                                                                                                                              | Interface and terminal             | Any file                |
| [`theme`](#theme)                                                                                     | Pick the interface [color theme](terminal-config.md#match-the-color-theme), built-in or custom                                                                                                                                  | Interface and terminal             | Any file                |
| [`timeFormat`](#timeformat)                                                                           | Show the times in the interface on a 12-hour or 24-hour clock, in UTC, or with a strftime pattern                                                                                                                                     | Interface and terminal             | Any file                |
| [`timeZone`](#timezone)                                                                               | Show the times in the interface in a time zone other than your system’s                                                                                                                                                               | Interface and terminal             | Any file                |
| [`tui`](#tui)                                                                                         | Choose the [fullscreen](fullscreen.md) or classic terminal renderer                                                                                                                                                             | Interface and terminal             | Any file                |
| [`ultracode`](#ultracode)                                                                             | Have Claude plan a [workflow](workflows.md#let-claude-decide-with-ultracode) for each substantive task without being asked                                                                                                      | Model and responses                | Any file                |
| [`useAutoModeDuringPlan`](#useautomodeduringplan)                                                     | Let the [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) classifier review shell commands in [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode); set `false` to get prompts instead | Permission settings                | User, local, or managed |
| [`verbose`](#verbose)                                                                                 | Show [full tool output](cli-reference.md#cli-flags) instead of truncated summaries; `viewMode` takes precedence when both are set                                                                                               | Interface and terminal             | Any file                |
| [`viewMode`](#viewmode)                                                                               | Start every session in [default, verbose, or focus view](cli-reference.md#cli-flags)                                                                                                                                            | Interface and terminal             | Any file                |
| [`vimInsertModeRemaps`](#viminsertmoderemaps)                                                         | Map a two-key [INSERT-mode sequence](interactive-mode.md#remap-insert-mode-key-sequences) such as `jj` to Escape                                                                                                                | Interface and terminal             | User or managed         |
| [`voice`](#voice)                                                                                     | Turn on [voice dictation](voice-dictation.md) and pick hold or tap mode                                                                                                                                                         | Interface and terminal             | Any file                |
| [`voiceEnabled`](#voiceenabled)                                                                       | Turn on [voice dictation](voice-dictation.md) with the older single-key form                                                                                                                                                    | Interface and terminal             | Any file                |
| [`wheelScrollAccelerationEnabled`](#wheelscrollaccelerationenabled)                                   | Turn off [mouse-wheel acceleration](fullscreen.md#mouse-wheel-scrolling) in fullscreen rendering                                                                                                                                | Interface and terminal             | Any file                |
| [`workflowKeywordTriggerEnabled`](#workflowkeywordtriggerenabled)                                     | Let the word `ultracode` in a prompt start a [workflow](workflows.md); set `false` to type it without starting one                                                                                                              | Hooks and automation               | Any file                |
| [`workflowSizeGuideline`](#workflowsizeguideline)                                                     | Set the agent count Claude aims for in [dynamic workflows](workflows.md)                                                                                                                                                        | Hooks and automation               | Any file                |
| [`worktree`](#worktree)                                                                               | Configure how Claude Code creates git [worktrees](worktrees.md)                                                                                                                                                                 | Agents, sessions, and worktrees    | Any file                |
| [`worktree.baseRef`](#worktree-baseref)                                                               | Branch new [worktrees](worktrees.md) from the remote default branch or your local HEAD                                                                                                                                          | Agents, sessions, and worktrees    | Any file                |
| [`worktree.bgIsolation`](#worktree-bgisolation)                                                       | Let background sessions edit the working copy without a [worktree](worktrees.md)                                                                                                                                                | Agents, sessions, and worktrees    | Any file                |
| [`worktree.location`](#worktree-location)                                                             | Choose where [Desktop SSH sessions](../16-Mobile-Desktop/desktop.md#ssh-sessions) create their worktrees on a remote machine                                                                                                                         | Agents, sessions, and worktrees    | User                    |
| [`worktree.sparsePaths`](#worktree-sparsepaths)                                                       | Check out only the directories you need in each [worktree](worktrees.md)                                                                                                                                                        | Agents, sessions, and worktrees    | Any file                |
| [`worktree.symlinkDirectories`](#worktree-symlinkdirectories)                                         | Symlink large directories into each [worktree](worktrees.md) instead of duplicating them                                                                                                                                        | Agents, sessions, and worktrees    | Any file                |
| [`wslInheritsWindowsSettings`](#wslinheritswindowssettings)                                           | Have WSL read [managed settings](../13-Enterprise-Admin/managed-settings.md) from the Windows policy chain                                                                                                                                             | Enterprise and managed settings    | Managed                 |


[​](#model-and-responses)

Model and responses

Choose which models Claude Code uses and how it responds. For how these settings interact with the `/model` command and environment variables, see [Model configuration](model-config.md).


[​](#advisormodel)

`advisorModel`

Pick which model answers when Claude calls the server-side [advisor tool](advisor.md). Unset it to turn the advisor off. The advisor must be at least as capable as your main model. See [Choose an advisor model](advisor.md#choose-an-advisor-model) for the accepted pairings and what happens when you pick one that isn’t accepted. You don’t usually edit this key by hand. Run `/advisor` to open a picker that shows the current choice, the models that can advise, and **No advisor**. Claude Code saves your pick to this key in `~/.claude/settings.json`. If you pick from a [Remote Control](remote-control.md) client or in a session attached to a remote worker, the pick applies to that session only and doesn’t change this key. If your account requires the [usage-credits consent](advisor.md#fable-advisor-and-usage-credits), accept it first by running `/model fable`. Until you do, picking Fable in `/advisor` saves nothing and Claude Code tells you to run `/model fable` first.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, one of the aliases `"fable"`, `"opus"`, or `"sonnet"`, which resolve to Claude Code’s current default version of that model family, or a full model ID such as `"claude-opus-5-5"`
- **Default**: unset, so the advisor is off
- **Per-session overrides**: `--advisor` takes precedence over this key for one session. [`CLAUDE_CODE_DISABLE_ADVISOR_TOOL`](env-vars.md) turns the advisor off, and this key can’t turn it back on

settings.json

```python
{
  "advisorModel": "opus"
}
```

The key has no effect on providers where the advisor [isn’t available](advisor.md#requirements), such as Amazon Bedrock and Claude Platform on AWS. `"fable"` requires [Fable access](advisor.md#choose-an-advisor-model).


[​](#alwaysthinkingenabled)

`alwaysThinkingEnabled`

Turn [extended thinking](model-config.md#extended-thinking) off for every session by setting this to `false`. Thinking is on by default, so `true` changes nothing. Most people set this through `/config` rather than by editing the file. On models that always think, such as Opus 5.5, Sonnet 5.5, Haiku 5.5, and the Fable models, `false` has no effect. On [third-party providers](third-party-integrations.md) Claude Code omits the `thinking` parameter instead of turning thinking off, so adaptive-reasoning models may still think. With thinking turned off on the Anthropic API, Claude Code sends effort `high` instead of a higher level to models it knows [don’t accept that combination](errors.md#effort-isnt-available-with-thinking-turned-off), such as Opus 5.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: no effect; thinking is already on
  - `false`: Claude Code turns extended thinking off for every session
- **Default**: unset, so thinking is on for models that support it
- **Per-session overrides**: [`MAX_THINKING_TOKENS`](env-vars.md) takes precedence over this key for one session: `0` turns thinking off, under the same model and provider limits as `false`, and a positive value turns thinking on even when this key is `false`. On adaptive-reasoning models the number itself is ignored

settings.json

```python
{
  "alwaysThinkingEnabled": false
}
```


[​](#availablemodels)

`availableModels`

Restrict which models people can select for the main session, [subagents](../09-Agents-Patterns/sub-agents.md), [skills](../08-Plugins-Skills/skills.md), and the [advisor](advisor.md). A managed list constrains `/model`, `--model`, and the `model` key in a developer’s own files; a model outside it can’t be selected. With the default prefix matching, this doesn’t touch the Default option on its own; pair it with [`enforceAvailableModels`](#enforceavailablemodels) for that.

- **Scope**: [`Any file`](#scopes). Deploy it in managed settings to enforce it for an organization.
- **Type**: array of model aliases or IDs
- **Default**: unset, so every model is available

This example lets people select only Sonnet and Haiku models:

settings.json

```python
{
  "availableModels": ["sonnet", "haiku"]
}
```

A model ID entry such as `"claude-opus-5"` also permits later versions that extend it, such as Opus 5.5. To block one of those versions, use [`deniedModels`](#deniedmodels). To make each model ID entry permit only the version it names, use [`availableModelsMatch`](#availablemodelsmatch). See [Restrict model selection](model-config.md#restrict-model-selection).


[​](#availablemodelsmatch)

`availableModelsMatch`

Choose how [`availableModels`](#availablemodels) entries match model IDs. By default a model ID entry also permits later versions that extend it, so `"claude-opus-5"` permits Opus 5.5. With `"exact"`, each model ID entry permits only the version it names, so a newer version of that model stays blocked until you list it. Requires Claude Code v2.1.283 or later.

- **Scope**: [`Managed`](#scopes). Claude Code ignores the key in user, project, and local settings and in `--settings`, with a warning
- **Type**: string, one of:
  - `"prefix"`: a model ID entry permits its version and any model ID that extends it with another segment
  - `"exact"`: a model ID entry permits only the version it names, including that version’s dated IDs, so `"claude-opus-5"` permits Opus 5 but not `claude-opus-5-5`. A family alias such as `"opus"` still permits the whole family, and `best`, `opusplan`, and `default` entries are ignored
- **Default**: `"prefix"`

This example permits Opus 5 and Sonnet 5 and no later release of either:

managed-settings.json

```python
{
  "availableModels": ["claude-opus-5", "claude-sonnet-5"],
  "availableModelsMatch": "exact"
}
```

With `"exact"`, the Default option is also limited to the listed models whenever the list names at least one model or family. See [Block specific models or versions](model-config.md#block-specific-models-or-versions).


[​](#deniedmodels)

`deniedModels`

Block specific models, with or without an [`availableModels`](#availablemodels) allowlist and even when that list permits them. Claude Code hides a blocked model from the `/model` picker, and the model can’t be selected anywhere `availableModels` is enforced. A session on the Default option doesn’t run a blocked model either, as [Block specific models or versions](model-config.md#block-specific-models-or-versions) describes. Requires Claude Code v2.1.283 or later.

- **Scope**: [`Managed`](#scopes). Claude Code ignores the key in user, project, and local settings and in `--settings`, with a warning
- **Type**: array of model aliases or IDs
  - A family alias such as `"opus"` blocks every model in that family
  - A model ID such as `"claude-opus-5-5"` blocks that version in every spelling, including dated and provider-specific IDs
  - A model ID with no minor version, such as `"claude-opus-5"`, also blocks later minor versions such as Opus 5.5. Write `"claude-opus-5-0"` to block Opus 5 alone
  - `best`, `opusplan`, and `default` entries are ignored
- **Default**: unset, so no model is blocked

This example permits Opus and Sonnet models and blocks Opus 5.5:

managed-settings.json

```python
{
  "availableModels": ["opus", "sonnet"],
  "deniedModels": ["claude-opus-5-5"]
}
```

See [Block specific models or versions](model-config.md#block-specific-models-or-versions).


[​](#effortlevel)

`effortLevel`

Set a default [effort level](model-config.md#adjust-effort-level) for models you haven’t saved a level for. Lower levels are faster and cheaper on straightforward tasks, and higher levels reason more deeply on complex problems. When you run `/effort low`, `medium`, `high`, or `xhigh` in an interactive session on your machine, Claude Code saves the level for the active model under [`modelSettings`](#modelsettings) rather than writing this key. Before v2.1.251, `/effort` wrote this key. Within the same settings file, Claude Code uses a model’s saved level rather than this key. [`modelSettings`](#modelsettings) states the cross-file precedence. In a session attached to a remote worker, in a `-p` run, and in the Agent SDK, `/effort` applies to that session only. [Adjust effort level](model-config.md#adjust-effort-level) lists the interactive picks that also apply to that session only. The message that `/effort` prints says which happened.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, one of:
  - `"low"`: the least reasoning, for short, scoped, latency-sensitive tasks that aren’t intelligence-sensitive
  - `"medium"`: reduces token usage for cost-sensitive work that can trade off some intelligence
  - `"high"`: balances token usage and intelligence
  - `"xhigh"`: deeper reasoning at higher token spend
- **Default**: unset
- **Per-session overrides**: `--effort` takes precedence over this key for one session, and [`CLAUDE_CODE_EFFORT_LEVEL`](env-vars.md) takes precedence over both

settings.json

```python
{
  "effortLevel": "xhigh"
}
```

In your user settings file, `~/.claude/settings.json`, this key is the older form `/effort` wrote before it saved levels per model, and it keeps applying where it applied before, on Opus 5, Fable 5.1, and earlier models. Opus 5.5 and models released after it ignore it and start at their own default until you save a level for them, which `/effort` writes under [`modelSettings`](#modelsettings). In project, local, and managed settings, and with `--settings`, this key applies to every model.


[​](#enforceavailablemodels)

`enforceAvailableModels`

The `/model` picker has a **Default** option, and [`default` model setting](model-config.md#default-model-setting) describes the model it resolves to. An [`availableModels`](#availablemodels) allowlist limits the models you can name, but with the default [prefix matching](#availablemodelsmatch) it doesn’t remap your account type’s default, so **Default** can still resolve to a model outside the list. This key closes that gap. Requires Claude Code v2.1.175 or later. When your organization deploys any managed settings, Claude Code reads this key from the managed source alone and ignores it in your other files. For how this key applies to the startup model checks, see [Amazon Bedrock](amazon-bedrock.md#when-your-organization-enforces-a-model-allowlist) and [Google Cloud’s Agent Platform](google-vertex-ai.md#when-your-organization-enforces-a-model-allowlist).

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: when **Default** would resolve to a model outside `availableModels`, Claude Code resolves it to the first available model in the list
  - `false`: this key doesn’t change how **Default** resolves
- **Default**: `false`

This example restricts named selections to Sonnet and Haiku models and makes **Default** resolve to the first of them that is available:

settings.json

```python
{
  "availableModels": ["sonnet", "haiku"],
  "enforceAvailableModels": true
}
```

This key has no effect when `availableModels` is unset or empty. See [Enforce the allowlist for the Default model](model-config.md#enforce-the-allowlist-for-the-default-model). Requires Claude Code v2.1.175 or later.


[​](#fallbackmodel)

`fallbackModel`

Name backup models for Claude Code to try, in order, when your primary model is overloaded or unavailable. Claude Code switches to the next available model in the chain for the rest of the turn and shows a notice. Without a chain, Claude Code retries the same model and then surfaces the server’s error, and you retry or switch models yourself. A switch means one turn with a cold [prompt cache](prompt-caching.md#switching-models) on the fallback model; your next message tries the primary model first again.

- **Scope**: [`Any file`](#scopes)
- **Type**: array of model aliases or IDs; `"default"` expands to the default model
- **Default**: unset, so a failed request isn’t retried on another model
- **Per-session overrides**: `--fallback-model` takes precedence over this key for one session

This example tries Sonnet 5 first, then Haiku 4.5, when your primary model fails:

settings.json

```python
{
  "fallbackModel": ["claude-sonnet-5", "claude-haiku-4-5"]
}
```

Unlike most array settings, this key doesn’t merge across settings files: the highest-precedence file that defines it supplies the whole chain. If your project file sets `["claude-sonnet-5"]` and your user file sets `["claude-haiku-4-5"]`, the chain is `["claude-sonnet-5"]` only. Claude Code keeps at most three distinct allowed models from the list and ignores the rest. See [Fallback model chains](model-config.md#fallback-model-chains).


[​](#fastmode)

`fastMode`

Turn [fast mode](fast-mode.md) on for sessions where it’s available, for interactive work like rapid iteration or live debugging where you want speed at a higher cost per token. You don’t usually edit this key by hand: running `/fast` writes `fastMode: true` to `~/.claude/settings.json`, and running it again to turn fast mode off removes the key. Fast mode runs only on Opus 5.5, Opus 5, and Opus 4.8: turning it on from another model switches you to Opus, and switching to an unsupported model turns it off. See [Switch models while fast mode is on](fast-mode.md#switch-models-while-fast-mode-is-on).

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code turns fast mode on for sessions where it’s available
  - `false`: fast mode stays off
- **Default**: unset, so fast mode is off
- **Per-session overrides**: [`CLAUDE_CODE_DISABLE_FAST_MODE`](env-vars.md) turns fast mode off for one session, and this key can’t turn it back on

settings.json

```python
{
  "fastMode": true
}
```


[​](#fastmodepersessionoptin)

`fastModePerSessionOptIn`

Normally, running `/fast` saves [`fastMode`](#fastmode) to a person’s user settings, so fast mode is on at the start of every later session. Set this key to `true` to stop that: a saved `fastMode: true` no longer turns fast mode on at session start, and each person has to run `/fast` in each session they want it. Claude Code leaves the `fastMode` key in their file, so turning this key off restores the old behavior. Owners on Team or Enterprise plans can deploy it organization-wide through [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md). When managed settings set the key, `/fast on` is refused outside interactive terminal sessions and reports that your organization has disabled fast mode. That covers [non-interactive mode](headless.md), the [VS Code extension](../03-IDE-Integrations/vs-code.md), and [cloud sessions](claude-code-on-the-web.md).

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: a saved `fastMode: true` no longer turns fast mode on at session start, so each person runs `/fast` in each session they want it; a `fastMode: true` passed with `--settings` still counts for that session unless managed settings set this key
  - `false`: a saved `fastMode: true` turns fast mode on at the start of every later session
- **Default**: `false`

settings.json

```python
{
  "fastModePerSessionOptIn": true
}
```

See [Require per-session opt-in](fast-mode.md#require-per-session-opt-in).


[​](#language)

`language`

Have Claude respond in a language other than English by default. There is no fixed list for responses: Claude Code passes the value verbatim to Claude as an instruction to always respond in that language, so any language name Claude can read works. Claude Code doesn’t check the value, so a misspelled name reaches Claude as written rather than producing an error. The same value sets the language for [voice dictation](voice-dictation.md#change-the-dictation-language), which does have a fixed list of [supported dictation languages](voice-dictation.md#change-the-dictation-language), and for auto-generated session titles.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, any language name, such as `"japanese"`, `"spanish"`, or `"french"`; Claude Code doesn’t validate it
- **Default**: unset; session titles then match the language of your conversation

settings.json

```python
{
  "language": "japanese"
}
```


[​](#maxeffortlevel)

`maxEffortLevel`

Cap the [effort level](model-config.md#adjust-effort-level) a session can use, leaving lower levels available. Any higher level runs at the cap instead, including one from `/effort`, the `/model` picker, `--effort`, [`CLAUDE_CODE_EFFORT_LEVEL`](env-vars.md), a skill’s or subagent’s `effort` frontmatter, or the model’s own default. Claude Code applies the cap itself before each request, so it holds on every provider, including Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry. Requires Claude Code v2.1.267 or later.

- **Scope**: [`Any file`](#scopes). Deploy it in managed settings to enforce it for an organization. When several scopes set a cap, the lowest applies, so a cap set in one scope can’t be raised from another
- **Type**: string, one of `"low"`, `"medium"`, `"high"`, `"xhigh"`, or `"max"`. A `"max"` value sets no cap
- **Default**: unset, so no cap applies
- **Per-model caps**: add `maxEffortLevel` to a model’s [`modelSettings`](#modelsettings) entry. That entry replaces this key for the model only within the settings source that sets both, such as your user settings or one [managed source](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources). Set `"max"` there to exempt the model from that source’s cap; Claude Code still applies caps from other sources

This example caps every model at `medium` and exempts Sonnet 4.6:

settings.json

```python
{
  "maxEffortLevel": "medium",
  "modelSettings": {
    "claude-sonnet-4-6": {
      "maxEffortLevel": "max"
    }
  }
}
```

When your organization also sets an [effort limit](model-config.md#organization-effort-limits) for a model, the lower of the two caps applies.


[​](#model)

`model`

Set the model every new session uses, so you don’t have to pick one with `/model` each time. Setting it here doesn’t stop you from switching mid-session. If your admin set an [organization default model](model-config.md#organization-default-model) to override user selection, you get that model even when you set this key in user, project, or local settings.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, a model alias or full model ID
- **Default**: unset, so Claude Code uses your account’s default model
- **Per-session overrides**: `--model` takes precedence over [`ANTHROPIC_MODEL`](env-vars.md), and both take precedence over this key for one session, including over a managed `model`; an [`availableModels`](#availablemodels) list still applies to the pick

settings.json

```python
{
  "model": "claude-sonnet-5"
}
```

A value here outranks [`ANTHROPIC_DEFAULT_MODEL`](model-config.md#set-a-default-model-for-new-sessions), which Claude Code uses only when nothing else selects a model.


[​](#modeloverrides)

`modelOverrides`

Map Anthropic model IDs to provider-specific model IDs, such as Amazon Bedrock inference profile ARNs. Each model picker entry then uses its mapped value when calling the provider API. Administrators use this on [Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry](model-config.md#override-model-ids-per-version) to route each model version to a specific inference profile, version name, or deployment for governance, cost allocation, or regional routing.

- **Scope**: [`Any file`](#scopes)
- **Type**: object mapping model ID to provider model ID
- **Default**: unset

This example routes every call for Opus 4.6 to the named Bedrock inference profile:

settings.json

```python
{
  "modelOverrides": {
    "claude-opus-4-6": "arn:aws:bedrock:us-east-1:123456789012:inference-profile/example"
  }
}
```

See [Override model IDs per version](model-config.md#override-model-ids-per-version).


[​](#modelpicker)

`modelPicker`

List the models the `/model` picker offers, in the order you write them and under labels you choose, so the picker lists the models your organization runs, after the built-in lineup or instead of it. Each row’s `model` is taken verbatim, so it accepts anything `--model` accepts: an alias such as `opus`, an Anthropic model ID, or a provider-format ID for Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, or an LLM gateway. Requires Claude Code v2.1.242 or later.

- **Scope**: [`User or managed`](#scopes). Claude Code reads the key from managed settings, `--settings`, and user settings, and ignores it in project and local settings so a repository you clone can’t relabel the picker. The highest of those three that sets the key supplies the whole lineup, and Claude Code never combines lineups from two sources.
- **Type**: object with an `options` array of rows and an optional `replaceBuiltInOptions` Boolean
- **Default**: unset, so the picker shows the built-in lineup

This example adds two Bedrock deployments after the built-in lineup, under names your team recognizes:

managed-settings.json

```python
{
  "modelPicker": {
    "options": [
      { "model": "us.anthropic.claude-opus-4-8", "label": "Opus (production)" },
      {
        "model": "us.anthropic.claude-sonnet-4-6",
        "label": "Sonnet (production)",
        "description": "Day-to-day work"
      }
    ]
  }
}
```


[​](#fields-for-modelpicker)

Fields for `modelPicker`

The key takes two fields, one for the rows themselves and one for whether they replace the built-in lineup or add to it.

| Field                   | Type                                                                                             | What it does                                                                                                                                                                                                                                                                  |
|:------------------------|:-------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `options`               | array of rows, each with a required `model` and optional `label`, `description`, and `behavesAs` | The rows the picker shows, in this order, except that a grayed-out row moves to the bottom. Without a `label`, Claude Code titles the row with the built-in name for a model it knows, or the model ID otherwise, and without a `description` it writes a generic second line |
| `replaceBuiltInOptions` | Boolean, default `false`                                                                         | Set it to `true` to show only these rows, **Default**, and a row for the model the session is already using. Leave it unset to add these rows after the built-in lineup                                                                                                       |

An entry in `options` can also carry an optional `behavesAs` string beside its `model`, which requires v2.1.257 or later. Set it to the ID of a model your Claude Code version already knows, such as `claude-opus-4-8`, on an entry whose `model` is newer than your version. Claude Code then applies that known model’s capabilities and effort defaults to the entry instead of treating its model as unknown. The entry’s label and the model ID Claude Code sends in requests don’t change. With `replaceBuiltInOptions` on, Claude Code hides every other row: the built-in lineup, the rows it adds for [`availableModels`](#availablemodels) entries, the models [gateway discovery](../13-Enterprise-Admin/llm-gateway-protocol.md#model-discovery) found, and [`ANTHROPIC_CUSTOM_MODEL_OPTION`](model-config.md#add-a-custom-model-option). With it off, Claude Code skips a listed model that the built-in lineup already covers. A label changes what the picker shows, not which model Claude Code runs. An [`availableModels`](#availablemodels) allowlist still applies to these rows. Before you add a listed model to the allowlist, read [Merge behavior](model-config.md#merge-behavior): a specific model ID narrows its family’s wildcard entry. Claude Code also checks each row against the session before it shows the picker:

- **Dropped**: a row Claude Code can’t serve, such as a retired model or a model your organization has no access to
- **Grayed out**: a row you can’t select yet, shown with the reason
- **No row survives**: Claude Code keeps the built-in lineup, filtered by the allowlist as usual

Claude Code drops a row it can’t parse and keeps the rest. See [Fix a broken settings file](settings.md#fix-a-broken-settings-file).


[​](#modelpricing)

`modelPricing`

Report spend at the rates your organization pays instead of list price. Set it when your organization has contracted rates, so the dollar figures developers see match your bill. Claude Code applies the rates in `/usage`, the [status line](statusline.md), the Agent SDK’s `total_cost_usd`, the [`--max-budget-usd`](cli-reference.md) limit, and the [OpenTelemetry](../13-Enterprise-Admin/monitoring-usage.md) cost metric and events. You supply the rates: Claude Code doesn’t read them from your contract or the Claude Console. Requires Claude Code v2.1.242 or later.

- **Scope**: [`Managed`](#scopes). Deploy the key through server-managed settings, an MDM policy, a `managed-settings.json` file, or a [policy helper](../13-Enterprise-Admin/managed-settings.md#compute-the-policy-with-a-helper-program). Claude Code ignores it in user, project, and local settings, in `--settings`, and on Windows in the user-writable [HKCU registry](../13-Enterprise-Admin/managed-settings.md#where-each-mechanism-stores-the-policy). With server-managed settings, each session reports costs at list price until that session’s [settings fetch](../13-Enterprise-Admin/server-managed-settings.md#fetch-and-caching-behavior) has confirmed the setting. A host application that embeds Claude Code and sets [`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`](env-vars.md) can supply a table of its own through the SDK [`managedSettings`](../05-Agent-SDK/agent-sdk-typescript.md#options) option, which Claude Code uses only when no managed source sets the key and only in Claude Code v2.1.246 or later.
- **Type**: object with an optional `multiplier` and an optional `overrides` map
- **Default**: unset, so Claude Code reports list price unless a host application supplies a table

Set `multiplier` alone for a flat discount or markup, `overrides` alone for per-model rates, or both. This example sets contracted rates for Sonnet 4.6 and then reduces every figure, the Sonnet row included, by 15%:

managed-settings.json

```python
{
  "modelPricing": {
    "multiplier": 0.85,
    "overrides": {
      "claude-sonnet-4-6": {
        "input": 2.4,
        "output": 12,
        "cacheRead": 0.24,
        "cacheWrite": 3
      }
    }
  }
}
```

Set `multiplier` above 1, up to 10, to mark every figure up. A markup requires Claude Code v2.1.271 or later. Earlier versions ignore a `multiplier` above 1 with a warning and keep the rest of the setting. For the steps, including how to confirm the rates are in effect, see [Report spend at your contracted rates](../17-Billing-Plans/costs.md#report-spend-at-your-contracted-rates).


[​](#fields-for-modelpricing)

Fields for `modelPricing`

| Field        | Type                                                                                                    | What it does                                                                                                                                                                                                        |
|:-------------|:--------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `multiplier` | number greater than 0 and at most 10                                                                    | Scales every cost Claude Code computes, whether or not an `overrides` row covers it. Below 1 is a discount, above 1 a markup                                                                                        |
| `overrides`  | map of model ID to a rate object with `input`, `output`, `cacheRead`, and `cacheWrite`, each 0 to 10000 | The USD-per-million-token rates for that model, all four required. `cacheWrite` covers both five-minute and one-hour cache writes. See [Which models a row applies to](#which-models-a-modelpricing-row-applies-to) |

Claude Code uses a row’s rates exactly as you wrote them, without adding the fast-mode surcharge or the [US-only-inference rate](../17-Billing-Plans/about-claude-pricing.md). If you also set `multiplier`, Claude Code applies it on top of the row’s rates. Claude Code drops a row with a rate it can’t parse, or a `multiplier` it can’t parse, and keeps the rest; see [Fix a broken settings file](settings.md#fix-a-broken-settings-file).


[​](#which-models-a-modelpricing-row-applies-to)

Which models a `modelPricing` row applies to

Claude Code decides which models a row applies to from the row’s key:

- **A built-in model’s ID**: a key Claude Code itself uses for a built-in model, whether that key is the model’s own ID, such as `claude-sonnet-4-6`, or its Bedrock, Agent Platform, or Foundry ID. Claude Code applies the row to every dated snapshot ID and provider-specific ID of that model.
- **Any other key**: a key that isn’t a built-in model’s ID, such as a gateway model alias. Claude Code applies the row to that one ID only. When a model ID matches one of your keys exactly and also falls under a row keyed by a built-in model’s ID, Claude Code uses the exact match.
- **A Bedrock application inference profile**: once Claude Code has resolved the profile to the model it routes to, through your [`modelOverrides`](#modeloverrides) map or the [`bedrock:GetInferenceProfile` lookup](amazon-bedrock.md#iam-configuration), Claude Code applies that model’s row to the profile.


[​](#modelsettings)

`modelSettings`

Save an [effort level](model-config.md#adjust-effort-level) for each model you use. Requires Claude Code v2.1.251 or later. In an interactive session on your machine, when you save `low`, `medium`, `high`, or `xhigh` as your default with `/effort` or the `/model` picker’s effort slider, Claude Code writes that level here under the model you’re using, so you rarely edit this key yourself. When you pick one of those levels in the [VS Code extension’s model picker](../03-IDE-Integrations/vs-code.md#use-the-prompt-box), Claude Code saves it here the same way. The [`effortLevel`](#effortlevel) entry lists the sessions where `/effort` applies to that session only. Edit the key by hand to change or remove a level you saved. A model’s `effortLevel` here takes precedence over the top-level [`effortLevel`](#effortlevel) in the same settings file. Across files, Claude Code resolves each model separately: the highest-precedence [settings file](settings.md#settings-precedence) that sets either an `effortLevel` for that model or a top-level `effortLevel` that [applies to that model](#effortlevel) decides, so an `effortLevel` in managed settings outranks a level you saved in user settings. [Adjust effort level](model-config.md#adjust-effort-level) lists what else can override a saved level, such as `--effort` at launch. To cap one model’s effort rather than set its level, add a [`maxEffortLevel`](#maxeffortlevel) field to that model’s entry. The field requires Claude Code v2.1.267 or later.

- **Scope**: [`Any file`](#scopes)
- **Type**: object mapping a model name to an object with any of these fields:
  - `effortLevel`: one of `"low"`, `"medium"`, `"high"`, or `"xhigh"`
  - [`maxEffortLevel`](#maxeffortlevel): the highest effort level the model may run at
  - `autoCompactWindow`: a number of tokens from `100000` to `1000000`, or `"auto"` for the window tuned for the model. [`/autocompact`](model-config.md#set-the-auto-compact-window) saves here. For that model, the value takes precedence over a top-level [`autoCompactWindow`](#autocompactwindow) in the same settings file. Requires Claude Code v2.1.288 or later
- **Default**: unset

Claude Code writes each entry under the model’s canonical name, such as `claude-opus-5-5`, and matches that model’s alias, date-suffixed, `[1m]`, and recognized provider-specific IDs to the same entry. This example keeps Opus 5.5 at `high` while other models use their own saved or default levels:

settings.json

```python
{
  "modelSettings": {
    "claude-opus-5-5": {
      "effortLevel": "high"
    }
  }
}
```

Run `/effort auto` to clear your saved level for the model you’re using. Claude Code leaves the other entries and any top-level `effortLevel` in place.


[​](#outputstyle)

`outputStyle`

Select an [output style](output-styles.md) by name. An output style is a saved set of instructions that changes Claude’s role, tone, and output format, such as the built-in Explanatory and Learning styles or one you wrote yourself. If you change this key during a session, Claude uses the new style starting with your next message. For what that message costs in prompt caching, see [Changing output style](prompt-caching.md#changing-output-style). Before v2.1.251, the edit applied only after you ran `/clear` or started a new session.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, the name of a [built-in](output-styles.md#built-in-output-styles) or [custom](output-styles.md#create-a-custom-output-style) output style
- **Default**: unset, so Claude Code uses the default style

This example selects the built-in Explanatory style, which adds educational insights between tasks:

settings.json

```python
{
  "outputStyle": "Explanatory"
}
```


[​](#promptcachettl)

`promptCacheTtl`

Choose how long the [prompt cache](prompt-caching.md) holds the main conversation. This key applies to your interactive, `-p`, and Agent SDK turns, together with the helpers Claude Code runs inline with them. The one-hour lifetime keeps the cache warm across longer breaks, and the API [bills each cache write at a higher rate](../04-API-Reference/Guides/build-with-claude-prompt-caching.md#pricing) than at the five-minute lifetime. Requires Claude Code v2.1.242 or later.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, one of:
  - `"5m"`: the cache holds for five minutes
  - `"1h"`: the cache holds for an hour
- **Default**: unset, so each main-conversation request gets [its default lifetime](prompt-caching.md#which-ttl-each-request-gets)
- **Per-session overrides**: [`FORCE_PROMPT_CACHING_5M`](env-vars.md) takes precedence over everything else, then [`CLAUDE_CODE_PROMPT_CACHE_TTL`](env-vars.md), then this key, and last [`ENABLE_PROMPT_CACHING_1H`](env-vars.md)

This example keeps the main conversation on the one-hour lifetime and leaves subagents on five minutes:

settings.json

```python
{
  "promptCacheTtl": "1h",
  "subagentPromptCacheTtl": "5m"
}
```

For what each lifetime costs, see [Cache lifetime](prompt-caching.md#cache-lifetime).


[​](#showthinkingsummaries)

`showThinkingSummaries`

See summaries of Claude’s [extended thinking](model-config.md#extended-thinking) in interactive sessions. Set it if you want the full summaries when you expand thinking with `Ctrl+O`. When unset or `false`, the Anthropic API redacts thinking blocks and Claude Code shows a collapsed stub.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: you see full thinking summaries when you expand thinking with `Ctrl+O`
  - `false`: the Anthropic API redacts thinking blocks and Claude Code shows a collapsed stub
- **Default**: `false`

settings.json

```python
{
  "showThinkingSummaries": true
}
```

Redaction changes only what you see, not what the model generates. To reduce thinking spend, [lower the budget or disable thinking](model-config.md#extended-thinking) instead.


[​](#subagentpromptcachettl)

`subagentPromptCacheTtl`

Choose how long the [prompt cache](prompt-caching.md) holds the requests Claude Code makes outside the main conversation. This key applies to [subagents](../09-Agents-Patterns/sub-agents.md), [workflows](workflows.md), and Claude Code’s own background and helper requests, such as compaction and session titles. The one-hour lifetime keeps the cache warm across longer breaks, and the API [bills each cache write at a higher rate](../04-API-Reference/Guides/build-with-claude-prompt-caching.md#pricing) than at the five-minute lifetime. Requires Claude Code v2.1.242 or later.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, one of:
  - `"5m"`: the cache holds for five minutes
  - `"1h"`: the cache holds for an hour
- **Default**: unset, so each of these requests gets [its default lifetime](prompt-caching.md#which-ttl-each-request-gets)
- **Per-session overrides**: [`FORCE_PROMPT_CACHING_5M`](env-vars.md) takes precedence over everything else, then [`CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL`](env-vars.md), then this key, then [`ENABLE_PROMPT_CACHING_1H`](env-vars.md), which asks for the one-hour lifetime on every request. For where a subagent’s own frontmatter value ranks, see [Choose the TTL yourself](prompt-caching.md#choose-the-ttl-yourself)

This example gives subagents and the other requests outside the main conversation the one-hour lifetime:

settings.json

```python
{
  "subagentPromptCacheTtl": "1h"
}
```

This key covers the requests [`promptCacheTtl`](#promptcachettl) doesn’t, so set both to choose a lifetime for every request Claude Code makes. For how a subagent’s cache differs from the main conversation’s, see [Subagents and the cache](prompt-caching.md#subagents-and-the-cache).


[​](#switchmodelsonflag)

`switchModelsOnFlag`

Choose what happens when a [safety classifier flags a request](model-config.md#automatic-model-fallback): switch to the fallback model and continue, or pause so you can choose between switching and editing the prompt.

- **Scope**: [`Any file`](#scopes). Appears in `/config` as **Switch models when a message is flagged**, with the options **Switch automatically** and **Ask each time**.
- **Type**: Boolean
  - `true`: Claude Code switches to the fallback model and continues
  - `false`: in an interactive session Claude Code pauses so you can choose between switching and editing the prompt; where no dialog can show, such as a `-p` run, the flagged request ends as an error
- **Default**: unset. Claude Code switches automatically, though it may [ask first](model-config.md#ask-before-switching) in an interactive session

settings.json

```python
{
  "switchModelsOnFlag": false
}
```

See [Ask before switching](model-config.md#ask-before-switching).


[​](#ultracode)

`ultracode`

Start sessions with [ultracode](workflows.md#let-claude-decide-with-ultracode) on. With it on, Claude plans a workflow for each substantive task instead of waiting for you to ask. Claude plans workflows only when [dynamic workflows](workflows.md) are enabled for you and your model supports `xhigh` effort. The key doesn’t change the session’s effort level: ultracode runs at whichever level the session uses. Claude Code reads this key but never writes it: `/effort ultracode` turns ultracode on for the current session only.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: sessions start with ultracode on when dynamic workflows are enabled for you and your model supports `xhigh`
  - `false`: sessions start with ultracode off
- **Default**: unset, so ultracode is off
- **Per-session overrides**: `/effort ultracode` turns ultracode on for one session without this key, and `/effort ultracode off` turns it off for one session when this key is `true`. The `--effort ultracode` flag also turns it on for one session, at `xhigh` effort

settings.json

```python
{
  "ultracode": true
}
```

The session’s effort level comes from [`effortLevel`](#effortlevel), [`modelSettings`](#modelsettings), and the other [effort sources](model-config.md#adjust-effort-level), and an [effort cap](model-config.md#organization-effort-limits) such as [`maxEffortLevel`](#maxeffortlevel) lowers that level without turning ultracode off. This and the `/effort ultracode off` form require Claude Code v2.1.284 or later. Before v2.1.284, `ultracode: true` ran the session at `xhigh` effort, and an effort cap below `xhigh` kept ultracode off. An Agent SDK `apply_flag_settings` control request also accepts the key.


[​](#permission-settings)

Permission settings

Decide what Claude can do without asking, which permission mode a session starts in, and what auto mode’s classifier allows. For rule syntax and the permission model, see [Configure permissions](permissions.md).


[​](#allowmanagedpermissionrulesonly)

`allowManagedPermissionRulesOnly`

Make managed settings the only settings source of permission rules. Claude Code then ignores `allow`, `ask`, and `deny` rules in user, project, local, and `--settings` files, ignores `--allowedTools`, hides the always-allow choices in permission prompts, and stops saving new rules. When [parent settings from an embedding host](../13-Enterprise-Admin/managed-settings.md#let-an-embedding-host-add-policy) apply, Claude Code treats them as part of the managed tier. It drops their `allow` rules and `additionalDirectories`, and keeps their `deny` and `ask` rules except `Read` and `Edit` rules whose pattern starts with `!`. A host can’t carve paths out of the managed rules with a `!` rule, whether or not you set this key. `--disallowedTools` rules and the current session’s `deny` and `ask` rules still apply, including after Claude Code reloads settings mid-session. They only restrict, so they can’t widen what the managed rules grant. Before v2.1.257, Claude Code dropped those command-line and session rules at the first settings reload. For what a `!` pattern in a `--disallowedTools` or session rule can carve out, see [Read and Edit rules](permissions.md#read-and-edit). When you set this key, Claude Code v2.1.282 or later also ignores the [`allowed-tools`](../08-Plugins-Skills/skills.md#pre-approve-tools-for-a-skill) frontmatter in skills and `.claude/commands/` files from these sources:

- A repository’s `.claude/` directory
- Your `~/.claude/skills/` and `~/.claude/commands/` directories, including [skills synced from claude.ai](../08-Plugins-Skills/skills.md#where-synced-skills-load)
- An `--add-dir` directory
- [Plugins declared with a `.claude-plugin` manifest](../08-Plugins-Skills/plugins-loading.md#plugins-shared-through-a-repository) inside `~/.claude/skills/` or the project’s `.claude/skills/`
- Plugins loaded for one session only, whose ids end in [`@inline`](../08-Plugins-Skills/plugins-loading.md#find-where-a-plugin-came-from), when all of these hold:
  - The session is a [Code session](../16-Mobile-Desktop/desktop.md#environment-configuration) or [Cowork session](../13-Enterprise-Admin/managed-settings.md#where-and-when-a-policy-applies), other than a cloud session, for which the Claude Desktop app itself starts Claude Code
  - Your managed settings set the key, not only an embedding host’s [parent settings](../13-Enterprise-Admin/managed-settings.md#let-an-embedding-host-add-policy)
  - The session runs Claude Code v2.1.305 or later

Skills from managed settings and bundled skills keep their `allowed-tools`. `@inline` plugins outside those Desktop sessions keep theirs too, except one named [`anthropic-skills`](../08-Plugins-Skills/skills.md#names-reserved-for-synced-skills). A skill’s `disallowed-tools` still applies. For what a developer sees when Claude Code ignores the field, see [When only managed permission rules apply](../08-Plugins-Skills/skills.md#when-only-managed-permission-rules-apply).

- **Scope**: [`Managed`](#scopes)
- **Type**: Boolean
  - `true`: managed settings become the only settings source of permission rules
  - `false`: Claude Code applies permission rules from user, project, local, and `--settings` files in addition to the managed ones
- **Default**: unset, so Claude Code applies permission rules from user, project, and local settings and from `--settings`, in addition to the managed ones

managed-settings.json

```python
{
  "allowManagedPermissionRulesOnly": true
}
```

This key doesn’t lock down the MCP server allowlist; for that, set [`allowManagedMcpServersOnly`](#allowmanagedmcpserversonly). See [Managed-only settings](../13-Enterprise-Admin/managed-settings.md#managed-only-settings).


[​](#automode)

`autoMode`

Add your own rules to what the [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) classifier blocks and allows. Use it to tell the classifier which repos, buckets, and domains your organization trusts, so it stops blocking routine internal operations. The classifier ships with [built-in allow and deny rules](auto-mode-config.md#inspect-the-defaults-and-your-effective-config). Include the literal string `"$defaults"` in an array to keep those built-in rules at that position and add yours around them; leave it out to replace them with yours.

- **Scope**: [`User or managed`](#scopes)
- **Type**: object with `environment`, `allow`, `soft_deny`, and `hard_deny` arrays of prose rules, plus the [`classifyAllShell`](#automode-classifyallshell) Boolean
- **Default**: unset, so the classifier uses only its [built-in rules](auto-mode-config.md#inspect-the-defaults-and-your-effective-config)

This example keeps the built-in `soft_deny` rules, through `"$defaults"`, and adds one more that blocks `terraform apply`:

settings.json

```python
{
  "autoMode": {
    "soft_deny": ["$defaults", "Never run terraform apply"]
  }
}
```

When more than one of those files sets the same array, Claude Code concatenates the entries. For the rule format and how each array is applied, see [Configure auto mode](auto-mode-config.md).


[​](#automode-classifyallshell)

`autoMode.classifyAllShell`

Send every Bash and PowerShell command through the auto mode classifier while auto mode is active. By default, auto mode suspends only allow rules that could run arbitrary code: tool-wide and wildcard rules such as `Bash(*)`, and interpreter or shell-wrapper prefixes such as `Bash(python *)`. A command that any other allow rule matches, such as `Bash(npm test)`, skips the classifier unless it carries [per-command allowed domains](sandboxing.md#per-command-allowed-domains-in-auto-mode). When it skips, a destructive argument the rule’s prefix didn’t anticipate can get through unseen. Setting this key suspends every shell allow rule for the session so the classifier sees every command. Requires Claude Code v2.1.193 or later.

- **Scope**: [`User or managed`](#scopes). Read wherever [`autoMode`](#automode) is read.
- **Type**: Boolean
  - `true`: while auto mode is active, Claude Code sends every Bash and PowerShell command through the classifier and suspends your shell allow rules; outside auto mode the rules still apply
  - `false`: auto mode suspends only allow rules that could run arbitrary code, such as `Bash(*)` and `Bash(python *)`; a command that any other allow rule matches skips the classifier unless it carries [per-command allowed domains](sandboxing.md#per-command-allowed-domains-in-auto-mode), and every other shell command goes through it
- **Default**: `false`

settings.json

```python
{
  "autoMode": {
    "classifyAllShell": true
  }
}
```

See [Route all shell commands through the classifier](auto-mode-config.md#route-all-shell-commands-through-the-classifier).


[​](#disableautomode)

`disableAutoMode`

Remove [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) from the `Shift+Tab` cycle. Any session that would otherwise [start in auto mode](permission-modes.md#which-mode-a-session-starts-in), whether from `--permission-mode auto`, a settings file, or the built-in default, starts in `default` instead. Administrators set it in managed settings to prevent developers in their organization from using auto mode.

- **Scope**: [`Any file`](#scopes). Most useful in [managed settings](../13-Enterprise-Admin/managed-settings.md), where users can’t override it. Also accepted under `permissions` as `permissions.disableAutoMode`.
- **Type**: the string `"disable"`
- **Default**: unset

settings.json

```python
{
  "disableAutoMode": "disable"
}
```


[​](#permissions)

`permissions`

Control which tools Claude can use without asking, which ones always prompt, and which ones are blocked, and set the [permission mode](permission-modes.md) a session starts in. Every `permissions.*` key below nests under this object.

- **Scope**: [`Any file`](#scopes)
- **Type**: object with `allow`, `ask`, `deny`, `additionalDirectories`, `blockReadsOutsideWorkingDirectories`, `defaultMode`, `disableBypassPermissionsMode`, and `disableAutoMode`
- **Default**: unset

This example approves `npm run` commands without asking, prompts before `git push`, blocks reads of `.env`, and starts sessions in `acceptEdits`:

settings.json

```python
{
  "permissions": {
    "allow": ["Bash(npm run *)"],
    "ask": ["Bash(git push *)"],
    "deny": ["Read(./.env)"],
    "defaultMode": "acceptEdits"
  }
}
```

The three rule arrays share one syntax; see [Permission rule syntax](#permission-rule-syntax) under `permissions.allow`. For how permission rules from different files combine, see [how permission rules merge across scopes](permissions.md#settings-precedence); for how settings keys in general combine, see [Settings precedence](settings.md#settings-precedence) on the settings guide.


[​](#useautomodeduringplan)

`useAutoModeDuringPlan`

Choose whether Claude Code uses the auto mode classifier to review shell commands in plan mode. With the default `true`, the classifier reviews each command during planning when auto mode is available and you see no prompt, except for [critical-path removals](permission-modes.md#critical-paths). Set `false` to get a permission prompt for every command outside the built-in read-only set. Appears in `/config` as **Use auto mode during plan**.

- **Scope**: [`User, local, or managed`](#scopes). A repository can’t turn it off for you.
- **Type**: Boolean
  - `true`: the same as unset; when auto mode is available, the classifier reviews each shell command during planning instead of prompting you for it, except [critical-path removals](permission-modes.md#critical-paths). A `false` in any of these files still turns it off
  - `false`: you get a permission prompt for every command outside the built-in read-only set
- **Default**: `true`

settings.json

```python
{
  "useAutoModeDuringPlan": false
}
```


[​](#permissions-allow)

`permissions.allow`

List the tool uses Claude Code approves without asking you. In an MCP rule, `*` can appear only in the tool name after the `mcp__<server>__` prefix, such as `mcp__github__get_*`; it can’t appear in the server name.

- **Scope**: [`Any file`](#scopes)
- **Type**: array of permission rule strings
- **Default**: unset
- **Per-session overrides**: `--allowedTools` adds allow rules for one session, and a deny rule from any settings file still blocks a tool it names

This example approves `git diff` and lets Claude Code read your `.zshrc` without asking:

settings.json

```python
{
  "permissions": {
    "allow": ["Bash(git diff *)", "Read(~/.zshrc)"]
  }
}
```

Claude Code applies `allow` rules from a project’s `.claude/settings.json` only after you accept the [workspace trust dialog](permissions.md#project-allow-rules-and-workspace-trust) for that folder.


[​](#permission-rule-syntax)

Permission rule syntax

Permission rules follow the format `Tool` or `Tool(specifier)`. Claude Code evaluates `deny` rules first, then `ask`, then `allow`, and the first match decides regardless of how specific each rule is; see the [permission rule evaluation order](permissions.md#manage-permissions). Each row shows one rule shape and what it matches.

| Rule                           | What it matches                  |
|:-------------------------------|:---------------------------------|
| `Bash`                         | Every Bash command               |
| `Bash(npm run *)`              | Commands starting with `npm run` |
| `Read(./.env)`                 | Reads of the `.env` file         |
| `WebFetch(domain:example.com)` | Fetch requests to example.com    |

For the complete rule syntax, including wildcard behavior, tool-specific patterns for Read, Edit, WebFetch, MCP, and Agent rules, and the security limitations of Bash patterns, see [Permission rule syntax](permissions.md#permission-rule-syntax).


[​](#permissions-ask)

`permissions.ask`

List the tool uses that prompt you for confirmation even in a permission mode that would otherwise approve them, such as `acceptEdits` or `bypassPermissions`. In `dontAsk` mode Claude Code denies a matching tool use instead of prompting.

- **Scope**: [`Any file`](#scopes)
- **Type**: array of permission rule strings
- **Default**: unset

settings.json

```python
{
  "permissions": {
    "ask": ["Bash(git push *)"]
  }
}
```


[​](#permissions-deny)

`permissions.deny`

List the tool uses Claude Code blocks. Use it for files that hold API keys, secrets, or environment values: Claude Code excludes matching files from file discovery and search results, denies reads of them, and blocks the [Edit and Write tools](permissions.md#read-and-edit) on the matching paths. Read and Edit deny rules apply to Claude’s built-in file tools, to file commands Claude Code recognizes in Bash, such as `cat`, `head`, `tail`, `sed`, and `tee`, and to the targets of Bash [redirections](permissions.md#redirections) such as `> file` and `< file`; they don’t apply to a command that reads files without naming them, such as `grep -r pattern .`, or to arbitrary subprocesses, so for OS-level enforcement [enable the sandbox](sandboxing.md).

- **Scope**: [`Any file`](#scopes)
- **Type**: array of permission rule strings
- **Default**: unset
- **Per-session overrides**: `--disallowedTools` adds deny rules for one session alongside this key

This example denies reads of `.env` files, the `secrets` directory, and a credentials file, and blocks `curl` commands:

settings.json

```python
{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Read(./config/credentials.json)",
      "Bash(curl *)"
    ]
  }
}
```

Tool names accept glob patterns, so `"*"` denies every tool and `"mcp__*"` denies every MCP tool. Claude Code ignores a deny rule for the [`EndConversation`](tools-reference.md#endconversation-tool-behavior) tool as long as any other tool is still available to Claude. A `Bash` deny rule matches the command as Claude writes it, so `Bash(curl *)` doesn’t stop `/usr/bin/curl` or `sh -c 'curl …'`; see [what a Bash rule doesn’t match](permissions.md#bash-rule-limits). This key replaces the deprecated `ignorePatterns` configuration.


[​](#permissions-additionaldirectories)

`permissions.additionalDirectories`

Give Claude file access to directories outside the one you started in, as additional [working directories](permissions.md#working-directories). Most `.claude/` configuration is [not discovered](permissions.md#additional-directories-grant-file-access-not-configuration) from these directories.

- **Scope**: [`Any file`](#scopes), with [limits on the sandbox write access](sandboxing.md#repository-settings-under-an-admin-required-sandbox) that project and local entries give
- **Type**: array of directory paths
- **Default**: unset
- **Per-session overrides**: `--add-dir` and `/add-dir` add directories for one session alongside this key

settings.json

```python
{
  "permissions": {
    "additionalDirectories": ["../docs/"]
  }
}
```

Like `allow` rules, entries in a project’s `.claude/settings.json` take effect only after you accept the [workspace trust dialog](permissions.md#project-allow-rules-and-workspace-trust) for that folder.


[​](#permissions-blockreadsoutsideworkingdirectories)

`permissions.blockReadsOutsideWorkingDirectories`

Make Claude’s file tools refuse reads outside your [working directories](permissions.md#working-directories) in every permission mode, including `bypassPermissions`. Claude Code denies `Read`, `Grep`, `Glob`, and `LSP` calls on those paths and tells Claude to ask you to add the directory with `/add-dir`. Files Claude Code itself needs stay readable, such as your skills, plugins, rules, agents, commands, and the `CLAUDE.md` memory file under `~/.claude/`. Requires Claude Code v2.1.257 or later. Claude Code doesn’t refuse shell commands the same way:

- [Actions no mode auto-approves](permission-modes.md#actions-no-mode-auto-approves) covers when a shell command that reads such a path prompts you
- [Sandboxed commands under the block](#sandboxed-commands-under-the-block) covers what a sandboxed command can read

A Bash command the shell parser can’t trace, such as one that changes directory more than once or runs a subshell, prompts you even in auto mode and `bypassPermissions` mode. The prompt appears even when the command names no path outside the working directories. This prompt doesn’t apply when the command runs in the [sandbox](sandboxing.md) and the sandbox enforces the block. Claude Code also writes `true` here when you choose to block such reads on [auto mode’s prompt before the first read outside the working directories](permission-modes.md#first-read-outside-the-working-directories).

- **Scope**: [`Any file`](#scopes). A `true` in any file applies, so a repository can turn the block on for itself but can’t lift yours.
- **Type**: Boolean
  - `true`: Claude’s file tools refuse reads outside the working directories
  - `false`: the same as unset; the block still applies if another file sets `true`
- **Default**: unset, so reads outside the working directories follow your [permission mode](permission-modes.md)

settings.json

```python
{
  "permissions": {
    "blockReadsOutsideWorkingDirectories": true
  }
}
```

Directories you add with `--add-dir`, `/add-dir`, or `additionalDirectories` in your user or managed settings count as working directories for the block. Directories added only in repository settings don’t count: those in `.claude/settings.json`, and those in `.claude/settings.local.json` unless git reports that file as untracked. In a directory that isn’t a git repository, or when git tracks the file, Claude Code treats `.claude/settings.local.json` as repository settings, so put directories you want to keep readable in your user settings instead. When [`autoMemoryDirectory`](#automemorydirectory) comes from the project’s `.claude/settings.json`, or from a `.claude/settings.local.json` [treated as repository-supplied](permissions.md#when-your-local-settings-file-needs-trust), Claude Code loads no [auto memory](memory.md#storage-location) from that directory and saves none to it. To lift the block, remove the key from every settings file that sets it, then start a new session.


[​](#sandboxed-commands-under-the-block)

Sandboxed commands under the block

When [sandboxing](sandboxing.md) is on, the block also covers sandboxed commands. Claude Code denies them read access to your home directory and to the other roots that hold user files: `/Users`, `/home`, `/root`, `/Volumes`, `/mnt`, `/media`, `/run/media`, and `/srv`. It then re-opens the working directories, [worktrees](worktrees.md) Claude Code creates in the session, the session temp directory, and the parts of `~/.claude` that commands need, such as skills and plugins. While the block is in force, `allowRead` and `allowWrite` entries from repository settings don’t count. When the session’s working directory is a linked [git worktree](worktrees.md), including one Claude Code entered mid-session, the repository’s common `.git` directory stays readable and writable to sandboxed commands, so git keeps working there. In these cases the block doesn’t reach sandboxed commands, while Claude’s file tools keep enforcing it:

- Filesystem isolation is off through [`sandbox.filesystem.disabled`](#sandbox-filesystem-disabled)
- [`allowManagedReadPathsOnly`](#sandbox-filesystem-allowmanagedreadpathsonly) is set
- The path of the directory you started Claude Code in contains a glob character such as `*`, `?`, or `[`

Under the block, Claude Code re-opens your global git configuration files to sandboxed commands so `git` keeps your identity and settings:

- `~/.gitconfig`
- The `config`, `ignore`, and `attributes` files under `$XDG_CONFIG_HOME/git`, which defaults to `~/.config/git`
- Files your global git configuration names through `[include]`, `[includeIf]`, `core.excludesFile`, or `core.attributesFile`

Claude Code judges each file separately. When a file lies where a sandboxed command can write, directly or through a symlink, Claude Code doesn’t re-open the files it names. On Linux and WSL2, a configuration file that is a symlink can stay unreadable at its own path, and `git` then runs without it. `~/.git-credentials` and `$XDG_CONFIG_HOME/git/credentials` stay blocked. If a re-opened file holds a secret, such as an `http.extraHeader` token, add its path to [`sandbox.filesystem.denyRead`](#sandbox-filesystem-denyread). A `denyRead` entry that covers a file always takes precedence over this re-open.


[​](#permissions-defaultmode)

`permissions.defaultMode`

Set the [permission mode](permission-modes.md) new sessions start in. When you leave it unset, sessions start in the [built-in default](permission-modes.md#which-mode-a-session-starts-in) for your surface.

- **Scope**: [`Any file`](#scopes). `auto` and `bypassPermissions` don’t take effect from project or local settings, so set them in `~/.claude/settings.json` instead. Before v2.1.257, `bypassPermissions` took effect from any file. For conversations the VS Code extension starts, Claude Code reads only user, managed, and `--settings` values.
- **Type**: string, one of:
  - `"default"`: Claude Code runs only reads without asking
  - `"acceptEdits"`: Claude Code also runs file edits and common filesystem commands such as `mkdir` and `mv` without asking
  - `"plan"`: Claude Code reads and plans but blocks edits until you approve a plan
  - `"auto"`: Claude Code runs without routine prompts; before actions such as shell commands and network requests run, a background classifier checks that they align with your request
  - `"dontAsk"`: Claude Code auto-denies every call that would otherwise prompt, though a [mod](../08-Plugins-Skills/plugins-mods-overview.md) you installed can still approve [some of those calls](permissions.md#precedence-among-rules-hooks-and-mods). File reads inside your working directories, other actions that need no approval, and pre-approved tools still run, apart from reads from [network paths](permissions.md#network-paths)
  - `"bypassPermissions"`: Claude Code runs everything without asking
  - `"manual"`: an alias for `"default"`
- **Default**: unset
- **Per-session overrides**: `--permission-mode`, and its equivalent `--dangerously-skip-permissions` for `bypassPermissions`, take precedence over this key for one session

settings.json

```python
{
  "permissions": {
    "defaultMode": "acceptEdits"
  }
}
```

Permission rules layer on top of every mode: `deny` rules block in every mode, including `bypassPermissions`. See [Permission modes](permission-modes.md). In cloud sessions, Claude Code honors only `acceptEdits`, `plan`, `default`, and `auto` from this key. For conversations the VS Code extension starts, see [which setting the extension reads for the starting permission mode](permission-modes.md#switch-permission-modes).


[​](#permissions-disablebypasspermissionsmode)

`permissions.disableBypassPermissionsMode`

Prevent anyone from entering `bypassPermissions` mode. Claude Code then rejects the `--dangerously-skip-permissions` flag, and ignores an [agent definition’s](../09-Agents-Patterns/sub-agents.md#permission-modes) `permissionMode: bypassPermissions`, so the subagent runs with the parent session’s permission mode.

- **Scope**: [`Any file`](#scopes). Typically set in [managed settings](../13-Enterprise-Admin/managed-settings.md) to enforce organizational policy.
- **Type**: the string `"disable"`
- **Default**: unset
- **Per-session overrides**: this key takes precedence over `--dangerously-skip-permissions`, which Claude Code rejects while the key is set

settings.json

```python
{
  "permissions": {
    "disableBypassPermissionsMode": "disable"
  }
}
```

Before v2.1.223, Claude Code applied the frontmatter permission mode even with bypass disabled.


[​](#skipautopermissionprompt)

`skipAutoPermissionPrompt`

Skip the one-time notice describing [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) that Claude Code shows when you first enter auto mode yourself, for example through your own settings or the mode selector, rather than when the built-in default starts a session in it. Claude Code shows that notice once and then records that it was shown, so this key only matters where the notice hasn’t appeared yet.

- **Scope**: [`User or managed`](#scopes). A repository can’t set it for you.
- **Type**: Boolean
  - `true`: Claude Code skips the notice
  - `false`: the same as unset; the notice appears once unless another of these files sets `true`
- **Default**: unset, so the notice appears once

settings.json

```python
{
  "skipAutoPermissionPrompt": true
}
```


[​](#skipdangerousmodepermissionprompt)

`skipDangerousModePermissionPrompt`

Skip the confirmation dialog Claude Code shows before a session enters `bypassPermissions` mode, whether from `--dangerously-skip-permissions` or from `defaultMode: "bypassPermissions"`. Claude Code writes `true` here in your user settings when you accept that dialog once.

- **Scope**: [`User, local, or managed`](#scopes). An untrusted repository can’t skip the dialog for you.
- **Type**: Boolean
  - `true`: Claude Code skips the confirmation dialog before a session enters `bypassPermissions` mode
  - `false`: the same as unset; the dialog appears unless another of these files sets `true`
- **Default**: unset, so the dialog appears

settings.json

```python
{
  "skipDangerousModePermissionPrompt": true
}
```


[​](#sandbox-settings)

Sandbox settings

Isolate the commands Claude runs from your filesystem, your network, and your credentials. For how sandboxing works and platform requirements, see [Sandboxing](sandboxing.md).


[​](#sandbox)

`sandbox`

Isolate the Bash commands Claude runs from your filesystem and network with [sandboxing](sandboxing.md). Turn the sandbox on with `enabled`, then narrow or widen what sandboxed commands can touch with the `filesystem`, `network`, and `credentials` sub-objects. The sandbox runs on macOS, Linux, and WSL2.

- **Scope**: [`Any file`](#scopes)
- **Type**: object with `enabled`, `failIfUnavailable`, `autoAllowBashIfSandboxed`, `excludedCommands`, `allowUnsandboxedCommands`, `enableWeakerNestedSandbox`, `enableWeakerNetworkIsolation`, `allowAppleEvents`, `allowNestedUserNamespaces`, `bwrapPath`, `socatPath`, `ignoreViolations`, and `ripgrep`, plus the `filesystem`, `network`, and `credentials` objects
- **Default**: unset, so Claude Code runs commands without a sandbox

This turns the sandbox on, skips permission prompts for sandboxed commands, runs `docker` outside the sandbox, opens two extra write paths, hides your AWS credentials file, and pre-allows GitHub and npm:

settings.json

```python
{
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": true,
    "excludedCommands": ["docker *"],
    "filesystem": {
      "allowWrite": ["/tmp/build", "~/.kube"],
      "denyRead": ["~/.aws/credentials"]
    },
    "network": {
      "allowedDomains": ["github.com", "*.npmjs.org"]
    }
  }
}
```

When managed settings set a Boolean key such as `enabled` or `failIfUnavailable`, that value overrides anything a developer sets. Claude Code merges array keys across the settings scopes the session loads, so a developer can append entries; see [Keep developers from widening the policy](sandboxing.md#keep-developers-from-widening-the-policy) for the managed-only locks. To require the sandbox for an organization, see [Enforce sandboxing with managed settings](sandboxing.md#enforce-sandboxing-with-managed-settings).


[​](#sandbox-enabled)

`sandbox.enabled`

Turn on [sandboxing](sandboxing.md) for Bash commands. When you pick a mode in the `/sandbox` panel, Claude Code writes this key to `.claude/settings.local.json` for the current project; set it in `~/.claude/settings.json` to sandbox every project.

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox)
- **Type**: Boolean
  - `true`: Claude Code sandboxes Bash commands
  - `false`: Bash commands run unsandboxed
- **Default**: `false`

settings.json

```python
{
  "sandbox": {
    "enabled": true
  }
}
```

On Linux and WSL2 the sandbox needs `bubblewrap` and `socat`; see [Set up Linux and WSL2](sandboxing.md#set-up-linux-and-wsl2). When the sandbox can’t start, Claude Code runs commands unsandboxed unless you also set [`failIfUnavailable`](#sandbox-failifunavailable).


[​](#sandbox-failifunavailable)

`sandbox.failIfUnavailable`

Make Claude Code exit with an error at startup when `sandbox.enabled` is `true` but the sandbox can’t start, because a dependency is missing or the platform is unsupported. Without this key, Claude Code runs commands unsandboxed. Managed deployments that require sandboxing as a security gate can use this setting. On a platform the sandbox doesn’t support, Claude Code doesn’t start with this key on. See [Enforce sandboxing with managed settings](sandboxing.md#enforce-sandboxing-with-managed-settings).

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox)
- **Type**: Boolean
  - `true`: Claude Code exits with an error at startup when `sandbox.enabled` is `true` but the sandbox can’t start
  - `false`: Claude Code runs commands unsandboxed when the sandbox can’t start
- **Default**: `false`

This makes every managed machine sandbox commands or refuse to start:

managed-settings.json

```python
{
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true
  }
}
```

See [Enforce sandboxing with managed settings](sandboxing.md#enforce-sandboxing-with-managed-settings).


[​](#sandbox-autoallowbashifsandboxed)

`sandbox.autoAllowBashIfSandboxed`

Let Claude Code run sandboxed Bash commands without a permission prompt. Commands that can’t run in the sandbox still go through the regular permission flow, and `deny` rules and content-scoped `ask` rules such as `Bash(git push *)` still apply; a bare `Bash` ask rule is skipped for sandboxed commands. Set it to `false` to send sandboxed commands through the regular permission flow too, which the `/sandbox` **Mode** tab calls regular permissions mode.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code runs sandboxed Bash commands without a permission prompt, except in the cases that [Auto-allow mode](sandboxing.md#auto-allow-mode) describes; `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` turns auto-allow off
  - `false`: sandboxed commands go through the regular permission flow, so your allow rules and permission mode decide. The `/sandbox` **Mode** tab calls this regular permissions mode
- **Default**: `true`

This keeps the sandbox on and sends sandboxed commands through the regular permission flow:

settings.json

```python
{
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": false
  }
}
```

See [Auto-allow mode](sandboxing.md#auto-allow-mode) for what auto-allow mode still prompts on and how it behaves in plan mode.


[​](#sandbox-excludedcommands)

`sandbox.excludedCommands`

Name commands that Claude Code runs outside the sandbox, such as tools that don’t work under it. Each entry uses the same syntax as the content of a `Bash(...)` [permission rule](permissions.md#permission-rule-syntax): an exact command, a prefix such as `docker *`, or a wildcard pattern. A pattern with no wildcard is an exact match, so `docker` matches only `docker` with no arguments. Your entries take a Bash call out of the sandbox only when they cover every command in it, and some call shapes stay sandboxed even then. A `docker *` entry alone doesn’t take `npm ci && docker build .` out of the sandbox.

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox)
- **Type**: array of command patterns
- **Default**: unset, so no command is excluded

settings.json

```python
{
  "sandbox": {
    "excludedCommands": ["docker *"]
  }
}
```

Claude Code keeps a Bash call sandboxed when it has one of these shapes, among others:

- A command starting with `sudo`, `eval`, or `xargs`
- A `cd`, `pushd`, or `popd`, wherever it appears in the call
- A command substitution, a subshell, or a control-flow block such as `if` or `for`
- A redirection, such as `docker build . > build.log`, other than one that only duplicates a file descriptor, as `2>&1` does
- A command name that comes from a variable
- A `git clone`, `git init`, `git worktree add`, `git worktree move`, or `git bundle create` with a path argument that is absolute, starts with `~`, or contains a `..` segment

For example, `cd build && docker compose up` stays sandboxed under a `docker *` entry, and adding a `cd` entry doesn’t change that. Under a `git *` entry, `git clone <url> vendor/lib` runs outside the sandbox, but `git clone <url> ~/tools` stays sandboxed. A clone writes a whole tree of files, possibly executable ones, wherever its destination path points. Excluded commands still go through the regular permission flow. Exclusion is a convenience, not a security boundary: when a tool only needs to write somewhere specific, [`filesystem.allowWrite`](#sandbox-filesystem-allowwrite) keeps it sandboxed. Entries from the settings scopes the session loads combine into one list unless the sandbox is [admin-required](sandboxing.md#repository-settings-under-an-admin-required-sandbox). While it is, Claude Code ignores entries in `.claude/settings.json` and `.claude/settings.local.json`, so a cloned repository can’t take commands out of the sandbox. Entries in managed settings, `--settings`, and your `~/.claude/settings.json` still apply, and no managed-only lock covers this list.


[​](#sandbox-allowunsandboxedcommands)

`sandbox.allowUnsandboxedCommands`

Let Claude retry a command outside the sandbox with the `dangerouslyDisableSandbox` parameter after the sandbox blocks it. When it’s `false`, Claude Code ignores that parameter. While the sandbox is running, commands Claude runs are then sandboxed unless they match an [`excludedCommands`](#sandbox-excludedcommands) entry. The `/sandbox` **Overrides** tab shows that state as **Strict sandbox mode**. A `false` in managed settings turns on strict sandbox mode for the developers it covers.

- **Scope**: [`Any file`](#scopes), with [a limit on project and local settings](sandboxing.md#turn-off-the-retry-with-strict-sandbox-mode)
- **Type**: Boolean
  - `true`: Claude can retry a command outside the sandbox with the `dangerouslyDisableSandbox` parameter after the sandbox blocks it
  - `false`: Claude Code ignores that parameter, so while the sandbox is running, commands Claude runs are sandboxed unless they match an `excludedCommands` entry
- **Default**: `true`

This enforces strict sandbox mode for everyone the managed settings cover:

managed-settings.json

```python
{
  "sandbox": {
    "enabled": true,
    "allowUnsandboxedCommands": false
  }
}
```

A `false` from managed settings or `--settings` also makes the sandbox [admin-required](sandboxing.md#repository-settings-under-an-admin-required-sandbox). A `false` in your user settings holds against a project’s `true` but doesn’t make the sandbox admin-required. Holding against a project’s value requires Claude Code v2.1.285 or later. Who approves an unsandboxed retry depends on your permission mode and allow rules. See [The unsandboxed retry escape hatch](sandboxing.md#the-unsandboxed-retry-escape-hatch). To see when commands you type yourself at the [`!` shell-mode prompt](interactive-mode.md#shell-mode-with-prefix) run sandboxed, see [strict sandbox mode](sandboxing.md#turn-off-the-retry-with-strict-sandbox-mode).


[​](#sandbox-filesystem)

`sandbox.filesystem`

Control which paths sandboxed commands can read and write. By default they can write to the working directory, the per-user temp directory, and directories you add with `--add-dir`, `/add-dir`, or `permissions.additionalDirectories`, and can read the rest of the filesystem, including credential files. Widen or narrow that with the four path lists, or switch the filesystem layer off with `disabled`. See [Filesystem isolation](sandboxing.md#filesystem-isolation) for the default boundaries.

- **Scope**: [`Any file`](#scopes)
- **Type**: object with `allowWrite`, `denyWrite`, `denyRead`, and `allowRead` arrays, plus the `allowManagedReadPathsOnly` and `disabled` Booleans
- **Default**: unset, so the default read and write boundaries apply

This lets sandboxed commands write to a build directory and your kubeconfig, and hides your AWS credentials file:

settings.json

```python
{
  "sandbox": {
    "filesystem": {
      "allowWrite": ["/tmp/build", "~/.kube"],
      "denyRead": ["~/.aws/credentials"]
    }
  }
}
```

Claude Code enforces these lists at the OS sandbox boundary, so they apply to every subprocess a sandboxed command starts, such as `kubectl`, `terraform`, or `npm`. Claude Code adds your [permission rules](sandboxing.md#permission-rules) to the same lists: `Edit` allow and deny rules to `allowWrite` and `denyWrite`, `Read` deny rules to `denyRead`, and `WebFetch(domain:...)` allow and deny rules to the [`network`](#sandbox-network) domain lists. Unless a lock applies, Claude Code merges these lists across the settings files the session loads. [`allowManagedReadPathsOnly`](#sandbox-filesystem-allowmanagedreadpathsonly) limits `allowRead` to entries from managed settings, and [`allowManagedDomainsOnly`](#sandbox-network-allowmanageddomainsonly) does the same for allowed domains. [Repository locks](sandboxing.md#repository-settings-under-an-admin-required-sandbox) leave out entries from a repository’s settings files. [Configure sandboxing](sandboxing.md#configure-sandboxing) covers sources you exclude with `--setting-sources`. When you edit a list during a session, Claude Code [applies the change to the running session](settings.md#when-edits-take-effect).


[​](#sandbox-path-prefixes)

Sandbox path prefixes

Paths in `allowWrite`, `denyWrite`, `denyRead`, `allowRead`, and [`credentials.files`](#sandbox-credentials-files) resolve by their prefix:

| Prefix            | Meaning                                                                                | Example                                                                   |
|:------------------|:---------------------------------------------------------------------------------------|:--------------------------------------------------------------------------|
| `/`               | Absolute path from filesystem root                                                     | `/tmp/build` stays `/tmp/build`                                           |
| `~/`              | Relative to home directory                                                             | `~/.kube` becomes `$HOME/.kube`                                           |
| `./` or no prefix | Relative to the project root for project settings, or to `~/.claude` for user settings | `./output` in `.claude/settings.json` resolves to `<project-root>/output` |

The `//path` prefix for absolute paths also works. If you use single-slash `/path` expecting project-relative resolution, switch to `./path`. This syntax differs from [Read and Edit permission rules](permissions.md#read-and-edit), which use `//path` for absolute and `/path` for project-relative: sandbox filesystem paths use standard conventions, so `/tmp/build` is an absolute path. Claude Code strips a trailing slash from a directory path, so `~/.aws` and `~/.aws/` match the same directory. Before v2.1.224, Claude Code passed the trailing slash through to the sandbox, and Claude could still read or write paths under a `denyRead` or `denyWrite` entry written with one. Claude Code also removes a trailing `/**`, so `~/build/**` and `~/build` cover the same directory. Whether a wildcard such as `*` works depends on which list the entry is in and on the platform:

- **`allowWrite` and `denyWrite`**: on macOS, wildcards work. On Linux and WSL2, the sandbox mounts concrete paths, so Claude Code skips an entry that contains `*`, `?`, or `[` once the trailing `/**` is removed, and that entry has no effect. Claude Code adds the paths from your `Edit` permission rules to these lists, so the same limit applies to them, and the **Config** tab of `/sandbox` warns about `Edit` and `Read` permission rules that contain wildcards.
- **`denyRead` and `allowRead`**: wildcards work on every platform. On Linux and WSL2, Claude Code expands a read entry to the concrete paths it matches, which it doesn’t do for the write lists.

Braces match as ordinary characters in a name, so `~/data/{keys,tokens}` covers a directory literally named `{keys,tokens}`, not two alternatives. To cover `~/data/keys` and `~/data/tokens`, add each as its own entry.


[​](#sandbox-filesystem-allowwrite)

`sandbox.filesystem.allowWrite`

Add paths where sandboxed commands can write, beyond the working directory, the per-user temp directory, and the directories you’ve added with `--add-dir`, `/add-dir`, or `permissions.additionalDirectories`. Use it when a subprocess such as `kubectl` or a build tool needs to write outside the project.

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox)
- **Type**: array of path strings, using the [sandbox path prefixes](#sandbox-path-prefixes)
- **Default**: unset, so sandboxed commands can write to the working directory, the per-user temp directory, directories you’ve added with `--add-dir` or `/add-dir`, and directories in [`permissions.additionalDirectories`](#permissions-additionaldirectories)

This lets a build write under `/tmp/build` and lets `kubectl` update your kubeconfig:

settings.json

```python
{
  "sandbox": {
    "filesystem": {
      "allowWrite": ["/tmp/build", "~/.kube"]
    }
  }
}
```

Claude 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](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](sandboxing.md#protected-paths).


[​](#sandbox-filesystem-denywrite)

`sandbox.filesystem.denyWrite`

Block sandboxed commands from writing to specific paths, including paths inside a directory that is otherwise writable.

- **Scope**: [`Any file`](#scopes)
- **Type**: array of path strings, using the [sandbox path prefixes](#sandbox-path-prefixes)
- **Default**: unset

This keeps sandboxed commands from changing system configuration or installing binaries:

settings.json

```python
{
  "sandbox": {
    "filesystem": {
      "denyWrite": ["/etc", "/usr/local/bin"]
    }
  }
}
```

Claude Code merges entries across every settings scope the session loads, and adds the paths from your `Edit(...)` deny permission rules.


[​](#sandbox-filesystem-denyread)

`sandbox.filesystem.denyRead`

Block sandboxed commands from reading specific paths, such as credential files that the default read policy would otherwise expose. To protect a credential file and keep it usable through the sandbox proxy, see [`sandbox.credentials`](#sandbox-credentials) instead.

- **Scope**: [`Any file`](#scopes)
- **Type**: array of path strings, using the [sandbox path prefixes](#sandbox-path-prefixes)
- **Default**: unset, so sandboxed commands keep the [default read access](sandboxing.md#filesystem-isolation), which includes credential files such as `~/.aws/credentials`

settings.json

```python
{
  "sandbox": {
    "filesystem": {
      "denyRead": ["~/.aws/credentials"]
    }
  }
}
```

Claude Code merges entries across every settings scope the session loads, and adds the paths from your `Read(...)` deny permission rules. When [`filesystem.disabled`](#sandbox-filesystem-disabled) is `true`, Claude Code doesn’t enforce these entries.


[​](#sandbox-filesystem-allowread)

`sandbox.filesystem.allowRead`

Re-open reading for specific paths inside a region that [`denyRead`](#sandbox-filesystem-denyread) blocks, to build workspace-only read access. An exact or wildcard `denyRead` entry stays blocked inside a broader `allowRead`, as the [overlap table](sandboxing.md#configure-sandboxing) shows. When a wildcard `denyRead` entry such as `~/**/.env` matches a directory, Claude Code blocks reads of its contents as well. Before v2.1.236 on macOS, Claude Code re-opened the paths a wildcard `denyRead` entry matched wherever a broader `allowRead` entry covered them, and left a matched directory’s contents readable.

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox)
- **Type**: array of path strings, using the [sandbox path prefixes](#sandbox-path-prefixes)
- **Default**: unset

This blocks reads of your home directory except the project itself:

settings.json

```python
{
  "sandbox": {
    "filesystem": {
      "denyRead": ["~/"],
      "allowRead": ["."]
    }
  }
}
```

Claude Code resolves a `.` entry to the project root in project settings and to `~/.claude` in user settings. Claude Code merges entries across the settings files the session loads unless [`allowManagedReadPathsOnly`](#sandbox-filesystem-allowmanagedreadpathsonly) is set, and leaves out entries from repository settings while [`permissions.blockReadsOutsideWorkingDirectories`](#sandboxed-commands-under-the-block) is on. [Repository locks](sandboxing.md#repository-settings-under-an-admin-required-sandbox) can leave out a repository’s entries too.


[​](#sandbox-filesystem-allowmanagedreadpathsonly)

`sandbox.filesystem.allowManagedReadPathsOnly`

Honor only the [`allowRead`](#sandbox-filesystem-allowread) entries that come from managed settings, so developers can’t re-open read access to paths your organization blocked. Claude Code still merges `denyRead` entries from every settings scope the session loads.

- **Scope**: [`Managed`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code honors only the `allowRead` entries from managed settings
  - `false`: `allowRead` entries from other settings files can merge in
- **Default**: `false`

This blocks reads of the home directory, re-opens `~/work`, and stops developers from re-opening anything else:

managed-settings.json

```python
{
  "sandbox": {
    "filesystem": {
      "denyRead": ["~/"],
      "allowRead": ["~/work"],
      "allowManagedReadPathsOnly": true
    }
  }
}
```

See [Keep developers from widening the policy](sandboxing.md#keep-developers-from-widening-the-policy).


[​](#sandbox-filesystem-disabled)

`sandbox.filesystem.disabled`

Skip filesystem isolation while keeping network isolation. Sandboxed commands get unrestricted read and write access to the host filesystem, and their network egress stays confined to [`network.allowedDomains`](#sandbox-network-alloweddomains). Use it when you sandbox to control where commands connect rather than what they write. Requires Claude Code v2.1.216 or later.

- **Scope**: [`User or managed`](#scopes). When managed settings configure `sandbox.filesystem` at all, or list a `sandbox.credentials.files` entry with `"mode": "deny"`, only managed settings can set it.
- **Type**: Boolean
  - `true`: Claude Code skips filesystem isolation and keeps network isolation
  - `false`: filesystem isolation stays on
- **Default**: `false`, so filesystem isolation stays on

This leaves the filesystem open and confines network egress to GitHub and npm:

settings.json

```python
{
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "disabled": true
    },
    "network": {
      "allowedDomains": ["github.com", "*.npmjs.org"]
    }
  }
}
```

With the layer off, Claude Code doesn’t enforce `denyRead` or `credentials.files` `deny` entries, while `credentials.envVars` entries and applied `mask` entries keep working. [`autoAllowBashIfSandboxed`](#sandbox-autoallowbashifsandboxed) still defaults to `true`, so set it to `false` to keep prompting. See [Disable filesystem isolation](sandboxing.md#disable-filesystem-isolation) for the full list of sources that can set it and what changes when isolation is off. Requires Claude Code v2.1.216 or later.


[​](#sandbox-ignoreviolations)

`sandbox.ignoreViolations`

Silence sandbox violation reports for paths you expect a command to probe and be refused, such as a tool that checks `/etc/hosts` on startup, so those denials don’t show up as violations or in what Claude sees. The sandbox still blocks the access; only the report is suppressed. Keys are substrings to match against the command, with `*` matching every command, and values are substrings of the violation to ignore for that command, such as a filesystem path.

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox)
- **Type**: object mapping a command substring to an array of violation substrings, usually paths
- **Default**: unset, so every violation is reported

settings.json

```python
{
  "sandbox": {
    "ignoreViolations": {
      "*": ["/etc/hosts"]
    }
  }
}
```


[​](#sandbox-enableweakernestedsandbox)

`sandbox.enableWeakerNestedSandbox`

Run the Linux sandbox inside an unprivileged Docker container, where bubblewrap can’t mount a fresh `/proc`. Instead the inner sandbox bind-mounts the container’s existing `/proc`, which exposes process information that a fresh mount would hide. This reduces security; use it only when the outer container already provides the isolation you need.

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox)
- **Type**: Boolean
  - `true`: the inner sandbox bind-mounts the container’s existing `/proc` instead of mounting a fresh one
  - `false`: the sandbox mounts a fresh `/proc`, which doesn’t work in an unprivileged Docker container
- **Default**: `false`

settings.json

```python
{
  "sandbox": {
    "enabled": true,
    "enableWeakerNestedSandbox": true
  }
}
```

Linux and WSL2 only. See [Bubblewrap fails to start inside a container](sandboxing.md#bubblewrap-fails-to-start-inside-a-container).


[​](#sandbox-enableweakernetworkisolation)

`sandbox.enableWeakerNetworkIsolation`

Let sandboxed commands on macOS reach the system TLS trust service, `com.apple.trustd.agent`. Go-based tools such as `gh`, `gcloud`, and `terraform` need it to verify TLS certificates when you use [`network.httpProxyPort`](#sandbox-network-httpproxyport) with a MITM proxy and a custom CA. This reduces security by opening a potential data exfiltration path through the trust service.

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox)
- **Type**: Boolean
  - `true`: sandboxed commands on macOS can reach `com.apple.trustd.agent`
  - `false`: sandboxed commands on macOS can’t reach the system TLS trust service
- **Default**: `false`

settings.json

```python
{
  "sandbox": {
    "enabled": true,
    "enableWeakerNetworkIsolation": true
  }
}
```

If you don’t use a MITM proxy, list the failing tools in [`excludedCommands`](#sandbox-excludedcommands) instead; see [Go-based CLIs fail TLS verification on macOS](sandboxing.md#go-based-clis-fail-tls-verification-on-macos).


[​](#sandbox-allowappleevents)

`sandbox.allowAppleEvents`

Let sandboxed commands on macOS send Apple Events, which `open`, `osascript`, and tools that open URLs in a browser need; without it they fail with error `-600`. This removes code-execution isolation: sandboxed commands can launch other applications unsandboxed with no user prompt, and can send AppleScript commands to running applications such as Terminal, subject to the per-app macOS automation-consent prompt (TCC).

- **Scope**: [`User or managed`](#scopes)
- **Type**: Boolean
  - `true`: sandboxed commands on macOS can send Apple Events
  - `false`: sandboxed commands on macOS can’t send Apple Events, so `open` and `osascript` fail with error `-600`
- **Default**: `false`

settings.json

```python
{
  "sandbox": {
    "enabled": true,
    "allowAppleEvents": true
  }
}
```

To keep isolation and still run one such tool, add it to [`excludedCommands`](#sandbox-excludedcommands) instead. See [Apple Events on macOS](sandboxing.md#security-limitations).


[​](#sandbox-allownestedusernamespaces)

`sandbox.allowNestedUserNamespaces`

Let sandboxed commands on Linux and WSL2 create user namespaces, which Chromium’s and Electron’s own sandbox, a nested bubblewrap, and `unshare` need. If you set this key to `true`, you turn off a security boundary: code from a sandboxed command can end up running outside the sandbox. For rootless Podman or Buildah, use [`excludedCommands`](#sandbox-excludedcommands) instead, because the sandbox stops them in other ways too. Requires Claude Code v2.1.305 or later.

- **Scope**: [`User or managed`](#scopes). A `true` counts from `~/.claude/settings.json`, JSON passed with `--settings`, or [managed settings](../13-Enterprise-Admin/managed-settings.md). Claude Code ignores a `true` in a project’s `.claude/settings.json` or `.claude/settings.local.json`. In a session with [`CLAUDE_CODE_SUBPROCESS_ENV_SCRUB`](env-vars.md#variables) set to `1`, Claude Code ignores a `true` from every source. A `false` counts from any file, by [settings precedence](settings.md#settings-precedence).
- **Type**: Boolean
  - `true`: sandboxed commands can create user namespaces
  - `false`: this key allows nothing extra, and the sandbox’s default applies
- **Default**: `false`

settings.json

```python
{
  "sandbox": {
    "enabled": true,
    "allowNestedUserNamespaces": true
  }
}
```

With this key on, don’t rely on any of the sandbox’s restrictions, including [protected paths](sandboxing.md#protected-paths) and [`credentials.files`](#sandbox-credentials-files) entries, to stop a malicious command. In [auto-allow mode](sandboxing.md#auto-allow-mode), that command can run without a permission prompt. If your organization has a security team, check with them before you turn the key on. To find the fix for your tool, see [Chromium or rootless Podman fails inside the sandbox on Linux](sandboxing.md#chromium-or-rootless-podman-fails-inside-the-sandbox-on-linux).


[​](#sandbox-ripgrep)

`sandbox.ripgrep`

Point the sandbox at a ripgrep binary of your own instead of the one Claude Code uses, for example when your platform needs a differently built `rg`.

- **Scope**: [`User or managed`](#scopes)
- **Type**: object with `command`, the path to the ripgrep binary, and optional `args`, an array of arguments to prepend
- **Default**: unset, so the sandbox uses the same ripgrep binary as Claude Code. That is the bundled binary unless you set [`USE_BUILTIN_RIPGREP`](env-vars.md) to `0`

settings.json

```python
{
  "sandbox": {
    "ripgrep": {
      "command": "/usr/local/bin/rg"
    }
  }
}
```


[​](#sandbox-bwrappath)

`sandbox.bwrapPath`

Point the sandbox at a bubblewrap binary installed outside `PATH`, such as a vendored copy on an air-gapped host. Claude Code uses the path both for the startup dependency check and when it wraps each sandboxed command.

- **Scope**: [`Managed`](#scopes). Claude Code reads it only from managed settings so that a user, project, or local file can’t point the sandbox at a different binary.
- **Type**: string, an absolute path; Claude Code drops a relative path and falls back to `PATH` lookup
- **Default**: unset, so Claude Code finds `bwrap` on `PATH`

managed-settings.json

```python
{
  "sandbox": {
    "enabled": true,
    "bwrapPath": "/opt/admin/bwrap"
  }
}
```

Linux and WSL2 only.


[​](#sandbox-socatpath)

`sandbox.socatPath`

Point the sandbox network proxy at a `socat` binary installed outside `PATH`.

- **Scope**: [`Managed`](#scopes)
- **Type**: string, an absolute path; Claude Code drops a relative path and falls back to `PATH` lookup
- **Default**: unset, so Claude Code finds `socat` on `PATH`

managed-settings.json

```python
{
  "sandbox": {
    "enabled": true,
    "socatPath": "/opt/admin/socat"
  }
}
```

Linux and WSL2 only.


[​](#sandbox-credentials)

`sandbox.credentials`

Declare the credential files and environment variables to [protect from sandboxed commands](sandboxing.md#protect-credentials). Each entry names a file `path` or a variable `name` and a `mode`: `deny` hides the credential inside the sandbox, and `mask` shows sandboxed commands a placeholder while the [sandbox proxy](sandboxing.md#mask-credentials) substitutes the real value on outbound requests. Claude Code protects only the entries you list; there is no built-in credential deny list.

- **Scope**: [`Any file`](#scopes). Claude Code honors `mask` entries, `allowPlaintextInject`, `awsPairs`, and `sigv4` only from user settings, managed settings, and the `--settings` flag.
- **Type**: object with `files`, `envVars`, `allowPlaintextInject`, `awsPairs`, and `sigv4`
- **Default**: unset, so no credentials are protected

This hides your AWS credentials file and removes `GITHUB_TOKEN` from sandboxed commands:

settings.json

```python
{
  "sandbox": {
    "credentials": {
      "files": [{ "path": "~/.aws/credentials", "mode": "deny" }],
      "envVars": [{ "name": "GITHUB_TOKEN", "mode": "deny" }]
    }
  }
}
```

The `deny` file protection is part of the filesystem layer, so it doesn’t apply when you [disable filesystem isolation](sandboxing.md#disable-filesystem-isolation); the environment variable protection still does.


[​](#invalid-credential-entries-in-managed-settings)

Invalid credential entries in managed settings

When a managed `sandbox.credentials` entry fails validation, Claude Code keeps protecting the credential where it can:

- An entry in `files` or `envVars` that still has a valid `path` or `name` and a `mode` of `mask` or `deny`, such as one whose `extract` pattern has no capturing group, is degraded to `mode: "deny"` with a warning, so the credential stays blocked, not masked, until you fix the entry. A degraded `files` entry pins [`filesystem.disabled`](sandboxing.md#disable-filesystem-isolation) like an explicit `deny` entry, and the warning notes that its read block isn’t enforced if managed settings turn filesystem isolation off.
- An entry with an unknown `mode` or an invalid `path` or `name` is stripped.
- Each case warns; whether an entry is degraded or stripped, the remaining valid entries are still enforced.

Applies in v2.1.191 and later; before v2.1.221, every invalid entry was stripped. For the other managed keys with per-field handling, see [Invalid entries in managed settings](../13-Enterprise-Admin/managed-settings.md#invalid-entries-in-managed-settings).


[​](#sandbox-credentials-files)

`sandbox.credentials.files`

Protect credential files or directories from sandboxed commands. With `"mode": "deny"`, Claude Code blocks reads of the path inside the sandbox, the same read block as [`sandbox.filesystem.denyRead`](#sandbox-filesystem-denyread). With `"mode": "mask"`, sandboxed commands on Linux and WSL2 read a sentinel copy of the file, and the sandbox proxy substitutes the real value on outbound requests to that entry’s `injectHosts`; on macOS the file is unreadable inside the sandbox instead. `"mode": "mask"` requires Claude Code v2.1.221 or later.

- **Scope**: [`Any file`](#scopes). Claude Code drops `mask` entries from project `.claude/settings.json` and local `.claude/settings.local.json`.
- **Type**: array of objects, each with `path` and a `mode` of `"deny"` or `"mask"`, plus the optional [mask fields for files](#mask-fields-for-files)
- **Default**: unset, so no credential files are protected

This hides your AWS credentials file and masks the `gh` hosts file, substituting the real value only on requests to `api.github.com`:

settings.json

```python
{
  "sandbox": {
    "credentials": {
      "files": [
        { "path": "~/.aws/credentials", "mode": "deny" },
        { "path": "~/.config/gh/hosts.yml", "mode": "mask", "injectHosts": ["api.github.com"] }
      ]
    }
  }
}
```

Paths use the same [prefixes](#sandbox-path-prefixes) as the `sandbox.filesystem.*` settings, and Claude Code merges the arrays from every settings scope the session loads. [Protect credentials](sandboxing.md#protect-credentials) covers what still applies from sources you exclude with `--setting-sources`. `mask` entries require Claude Code v2.1.221 or later. `mask` substitution runs only through the sandbox proxy, so set [`sandbox.network.tlsTerminate`](#sandbox-network-tlsterminate), or [`allowPlaintextInject`](#sandbox-credentials-allowplaintextinject) for plain-HTTP test networks. `mask` applies to a single file, so list each credential file individually. Claude Code accepts but ignores the `mask` fields on a `deny` entry. [Mask credentials](sandboxing.md#mask-credentials) covers which settings sources are honored, and [Mask credential files](sandboxing.md#mask-credential-files) covers when an entry falls back to `deny`.


[​](#mask-fields-for-files)

Mask fields for files

A `mask` entry accepts these optional fields. Without `extract` or `decode`, Claude Code replaces the entire file content with one sentinel. On macOS with filesystem isolation on, Claude Code applies a `mask` entry as `deny` before `extract` or `decode` runs; see [Mask credential files](sandboxing.md#mask-credential-files).

| Field              | Type                                                                                                               | What it does                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
|:-------------------|:-------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `extract`          | string, a regular expression with at least one capturing group                                                     | Mask only the text captured by group 1 of each match, so the rest of the file stays parseable. With `decode` also set, Claude Code checks each capture as a possible JWT instead of replacing it outright. Requires v2.1.221 or later                                                                                                                                                                                                                                                                                                                                    |
| `onExtractNoMatch` | `"warn"`, `"deny"`, or `"error"`; default `"warn"`                                                                 | What happens when `extract` or `decode` finds nothing to mask. `warn` leaves the file readable as-is inside the sandbox, `deny` makes it unreadable, and `error` stops sandbox setup until you fix the configuration. Claude Code treats `deny` as `error` when the read block wouldn’t be enforced, because you [disable filesystem isolation](sandboxing.md#disable-filesystem-isolation) or a [`sandbox.filesystem.allowRead`](#sandbox-filesystem-allowread) entry re-opens the path. Requires v2.1.221 or later; the `decode` case requires v2.1.224 or later |
| `decode`           | the string `"jwt"`                                                                                                 | Find JSON Web Tokens (JWTs) in the file, with a built-in pattern or with `extract` when set, verify each candidate, and replace it with a structurally valid fake token, so code inside the sandbox that decodes the token keeps working. When no candidate verifies, `onExtractNoMatch` governs the outcome. Requires v2.1.224 or later                                                                                                                                                                                                                                 |
| `maskClaims`       | array of strings, at least one claim name; requires `decode`                                                       | Mask only the named top-level payload claims inside each verified JWT and rebuild the token around the modified payload, so the other claims stay readable. When no named claim matches, `onExtractNoMatch` governs the outcome. Requires v2.1.224 or later                                                                                                                                                                                                                                                                                                              |
| `maskDuplicates`   | Boolean, default `false`                                                                                           | Also replace verbatim copies of each masked value elsewhere in the file, such as a secret pasted into a comment. Claude Code matches raw substrings, so reserve it for long, high-entropy secrets. Consulted only when `extract` or `decode` is set. Requires v2.1.221 or later                                                                                                                                                                                                                                                                                          |
| `injectHosts`      | array of strings, each a host that [`sandbox.network.allowedDomains`](#sandbox-network-alloweddomains) also admits | Narrow the hosts where the sandbox proxy substitutes the real value. When unset, the proxy substitutes it on requests to every host in `sandbox.network.allowedDomains`. Requires v2.1.221 or later                                                                                                                                                                                                                                                                                                                                                                      |

This masks only the `oauth_token` value in the `gh` hosts file, replaces every other copy of it in the file, makes the file unreadable if the pattern matches nothing, and substitutes the real token only on requests to `api.github.com`:

settings.json

```python
{
  "sandbox": {
    "credentials": {
      "files": [
        {
          "path": "~/.config/gh/hosts.yml",
          "mode": "mask",
          "extract": "oauth_token:\\s*(\\S+)",
          "maskDuplicates": true,
          "onExtractNoMatch": "deny",
          "injectHosts": ["api.github.com"]
        }
      ]
    }
  }
}
```


[​](#sandbox-credentials-envvars)

`sandbox.credentials.envVars`

Protect environment variables from sandboxed commands. With `"mode": "deny"`, Claude Code removes the variable from the environment of sandboxed commands. With `"mode": "mask"`, sandboxed commands see a per-session sentinel value, and the sandbox proxy substitutes the real value on outbound requests to that entry’s `injectHosts`, so tools such as `gh` and `npm` keep authenticating without ever holding the real credential.

- **Scope**: [`Any file`](#scopes). Claude Code drops `mask` entries from project `.claude/settings.json` and local `.claude/settings.local.json`.
- **Type**: array of objects, each with `name` and a `mode` of `"deny"` or `"mask"`, plus the optional [mask fields for environment variables](#mask-fields-for-environment-variables)
- **Default**: unset, so no environment variables are protected

This removes `NPM_TOKEN` from sandboxed commands and masks `GITHUB_TOKEN`, substituting the real value only on requests to `api.github.com`:

settings.json

```python
{
  "sandbox": {
    "credentials": {
      "envVars": [
        { "name": "NPM_TOKEN", "mode": "deny" },
        { "name": "GITHUB_TOKEN", "mode": "mask", "injectHosts": ["api.github.com"] }
      ]
    }
  }
}
```

The `name` must start with a letter or underscore and contain only letters, digits, and underscores. Claude Code merges the arrays from every settings scope the session loads, and applies `deny` when the same variable appears with both modes. [Protect credentials](sandboxing.md#protect-credentials) covers what still applies from sources you exclude with `--setting-sources`. `mask` substitution runs only through the sandbox proxy, so set [`sandbox.network.tlsTerminate`](#sandbox-network-tlsterminate), or [`allowPlaintextInject`](#sandbox-credentials-allowplaintextinject) for plain-HTTP test networks; see [Mask credentials](sandboxing.md#mask-credentials). Claude Code accepts but ignores the `mask` fields on a `deny` entry.


[​](#mask-fields-for-environment-variables)

Mask fields for environment variables

A `mask` entry accepts these optional fields. Without `extract` or `decode`, Claude Code replaces the entire value with one sentinel. `extract` and `decode` can’t be combined on the same entry.

| Field              | Type                                                                                                               | What it does                                                                                                                                                                                                                                                                                                                                                               |
|:-------------------|:-------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `extract`          | string, a regular expression with at least one capturing group                                                     | Mask only the text captured by group 1 of each match, such as the password inside a `DATABASE_URL` connection string, so the rest of the value stays parseable. Requires v2.1.224 or later                                                                                                                                                                                 |
| `onExtractNoMatch` | `"warn"`, `"deny"`, or `"error"`; default `"warn"`. On an entry with `decode`, only `"warn"` is accepted           | What happens when `extract` matches nothing. `warn` passes the variable through unmasked, `deny` unsets it inside the sandbox, and `error` stops sandbox setup until you fix the configuration. Requires v2.1.224 or later                                                                                                                                                 |
| `decode`           | the string `"jwt"`                                                                                                 | Verify the whole value is a JWT and replace it with a structurally valid fake token, so code inside the sandbox that decodes the token keeps working; the proxy substitutes the whole real token on egress. A value that doesn’t verify passes through unmasked with a warning. Requires v2.1.224 or later                                                                 |
| `maskClaims`       | array of strings, at least one claim name; requires `decode`                                                       | Mask only the named top-level payload claims inside the decoded JWT and rebuild the token around the modified payload, so the other claims stay readable. When no named claim matches, the variable passes through unmasked with a warning. Requires v2.1.224 or later                                                                                                     |
| `injectHosts`      | array of strings, each a host that [`sandbox.network.allowedDomains`](#sandbox-network-alloweddomains) also admits | Narrow the hosts where the sandbox proxy substitutes the real value. When unset, the proxy substitutes it on requests to every host in `sandbox.network.allowedDomains`. Write an IPv6 destination as the bare compressed address, such as `"::1"`, not the bracketed form; see [IPv6 destinations in `injectHosts`](sandboxing.md#ipv6-destinations-in-injecthosts) |

This masks only the password inside `DATABASE_URL`, unsets the variable if the pattern matches nothing, and masks a JWT in `SERVICE_JWT` while leaving every claim except `api_key` readable:

settings.json

```python
{
  "sandbox": {
    "credentials": {
      "envVars": [
        {
          "name": "DATABASE_URL",
          "mode": "mask",
          "extract": "://[^:]+:([^@]+)@",
          "onExtractNoMatch": "deny"
        },
        {
          "name": "SERVICE_JWT",
          "mode": "mask",
          "decode": "jwt",
          "maskClaims": ["api_key"]
        }
      ]
    }
  }
}
```


[​](#sandbox-credentials-allowplaintextinject)

`sandbox.credentials.allowPlaintextInject`

Allow `mask` substitution on plain HTTP requests as well as TLS-terminated HTTPS. On plain HTTP the upstream identity is unverified and the credential travels in cleartext, so leave this off outside trusted test networks.

- **Scope**: [`User or managed`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code allows `mask` substitution on plain HTTP requests as well as TLS-terminated HTTPS
  - `false`: Claude Code allows `mask` substitution only on TLS-terminated HTTPS
- **Default**: `false`

settings.json

```python
{
  "sandbox": {
    "credentials": {
      "allowPlaintextInject": true
    }
  }
}
```


[​](#sandbox-credentials-awspairs)

`sandbox.credentials.awsPairs`

Group masked environment variables that form one AWS credential for [SigV4 re-signing](sandboxing.md#re-sign-aws-requests) when your credential lives in variables with non-standard names. Claude Code links the conventional `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN` trio automatically when you mask their whole values, so you need this key only for other names. Requires Claude Code v2.1.224 or later.

- **Scope**: [`User or managed`](#scopes)
- **Type**: array of objects, each with `accessKeyIdVar`, `secretAccessKeyVar`, and optionally `sessionTokenVar`, naming `sandbox.credentials.envVars` entries
- **Default**: unset, so only the conventional trio is paired

This links three custom-named variables into one AWS credential for re-signing:

settings.json

```python
{
  "sandbox": {
    "credentials": {
      "awsPairs": [
        {
          "accessKeyIdVar": "MY_KEY_ID",
          "secretAccessKeyVar": "MY_SECRET_KEY",
          "sessionTokenVar": "MY_SESSION_TOKEN"
        }
      ]
    }
  }
}
```

Each named variable must be a whole-value `mask` entry in [`sandbox.credentials.envVars`](#sandbox-credentials-envvars), without `extract` or `decode`, and can fill only one slot across all pairs. These rules also apply:

- The proxy re-signs requests on the hosts listed in the access key ID entry’s `injectHosts`
- When `sessionTokenVar` is set, the proxy sends the real token as `x-amz-security-token` on re-signed requests
- Naming any of the conventional variables in a pair replaces the automatic pairing


[​](#sandbox-credentials-sigv4)

`sandbox.credentials.sigv4`

Choose what the sandbox proxy does with AWS request forms it [can’t re-sign](sandboxing.md#re-sign-aws-requests): `streaming` for aws-chunked streaming uploads, `presigned` for presigned URLs, and `sigv4a` for SigV4A asymmetric signatures. This applies only to requests signed with a masked pair’s placeholder access key ID. Requires Claude Code v2.1.224 or later.

- **Scope**: [`User or managed`](#scopes)
- **Type**: object with `streaming`, `presigned`, and `sigv4a`, each one of:
  - `"deny"`: the proxy fails the request
  - `"passthrough"`: the proxy forwards the request signed with the masked placeholder, so the tool receives AWS’s own rejection
- **Default**: unset, so every form is `"deny"`

This forwards streaming uploads instead of failing them at the proxy:

settings.json

```python
{
  "sandbox": {
    "credentials": {
      "sigv4": {
        "streaming": "passthrough"
      }
    }
  }
}
```

With `deny`, the proxy fails the request. With `passthrough`, the proxy forwards the request with its signature computed from the masked placeholder, so AWS rejects it and the calling tool receives AWS’s own response instead of a proxy error.


[​](#sandbox-network)

`sandbox.network`

Control which hosts, ports, and sockets sandboxed commands can reach. The sandbox routes outbound traffic through a proxy that enforces these lists; see [Network isolation](sandboxing.md#network-isolation) for how the proxy decides and when it prompts.

- **Scope**: [`Any file`](#scopes). `strictAllowlist`, `allowManagedDomainsOnly`, and `tlsTerminate` are read from fewer sources, as their entries say.
- **Type**: object with the sub-keys below
- **Default**: unset, so no domains are pre-allowed and your permission mode decides [what happens to each new host](sandboxing.md#hosts-outside-your-allowed-domains)

This pre-allows GitHub and npm, blocks `uploads.github.com`, and lets commands bind to localhost:

settings.json

```python
{
  "sandbox": {
    "network": {
      "allowedDomains": ["github.com", "*.npmjs.org"],
      "deniedDomains": ["uploads.github.com"],
      "allowLocalBinding": true
    }
  }
}
```

Claude Code merges the array sub-keys across settings scopes, so a project can add domains to your user list unless a [repository lock](sandboxing.md#repository-settings-under-an-admin-required-sandbox) applies. `WebFetch(domain:...)` allow and deny [permission rules](sandboxing.md#permission-rules) feed the same allow and deny lists.


[​](#sandbox-network-allowunixsockets)

`sandbox.network.allowUnixSockets`

List the Unix socket paths sandboxed commands can connect to on macOS. Claude Code ignores this list on Linux and WSL2, where the seccomp filter can’t inspect socket paths; use [`allowAllUnixSockets`](#sandbox-network-allowallunixsockets) there instead.

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox)
- **Type**: array of strings, each a socket path
- **Default**: unset, so the macOS sandbox blocks every Unix socket

settings.json

```python
{
  "sandbox": {
    "network": {
      "allowUnixSockets": ["~/.ssh/agent-socket"]
    }
  }
}
```

A socket path can grant broad access: allowing `/var/run/docker.sock`, for example, lets a sandboxed command control the Docker daemon. See [Security limitations](sandboxing.md#security-limitations).


[​](#sandbox-network-allowallunixsockets)

`sandbox.network.allowAllUnixSockets`

Let sandboxed commands connect to every Unix socket. On Linux and WSL2, the sandbox’s [seccomp filter](sandboxing.md#set-up-linux-and-wsl2) blocks `socket(AF_UNIX, ...)` calls, so this is the only way to permit Unix sockets there. When the filter is missing, which `/sandbox` reports on its Dependencies tab, the sandbox doesn’t block Unix-socket calls. See [Set up Linux and WSL2](sandboxing.md#set-up-linux-and-wsl2) for where the filter comes from.

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox)
- **Type**: Boolean
  - `true`: sandboxed commands can connect to every Unix socket. On Linux and WSL2 they can also connect to VM sockets, the `AF_VSOCK` address family
  - `false`: the sandbox blocks Unix-socket connections: on macOS except the paths in `allowUnixSockets`, and on Linux and WSL2 through the seccomp filter when it’s present
- **Default**: `false`

settings.json

```python
{
  "sandbox": {
    "network": {
      "allowAllUnixSockets": true
    }
  }
}
```

On WSL2, `true` also reopens the interop socket that launches Windows binaries such as `cmd.exe` and `powershell.exe`.


[​](#sandbox-network-allowlocalbinding)

`sandbox.network.allowLocalBinding`

Let sandboxed commands on macOS listen on network ports, for example to start a dev server, and connect to any port on localhost. A command that listens on a non-loopback address accepts connections from other machines. The key has no effect on Linux and WSL2, where each sandboxed command has its own loopback interface. To reach a server on the host from Linux or WSL2, see [A command fails to reach a server on localhost](sandboxing.md#a-command-fails-to-reach-a-server-on-localhost).

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox)
- **Type**: Boolean
  - `true`: sandboxed commands on macOS can listen on any local address and connect to any port on localhost
  - `false`: sandboxed commands on macOS can’t listen on a port or connect directly to servers on localhost
- **Default**: `false`

settings.json

```python
{
  "sandbox": {
    "network": {
      "allowLocalBinding": true
    }
  }
}
```


[​](#sandbox-network-allowmachlookup)

`sandbox.network.allowMachLookup`

List additional XPC and Mach service names the macOS sandbox may look up. Tools that communicate over XPC, such as the iOS Simulator or Playwright, need their services listed here.

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox)
- **Type**: array of strings, each a service name; a single trailing `*` matches a prefix, and `"*"` alone matches every service
- **Default**: unset

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

settings.json

```python
{
  "sandbox": {
    "network": {
      "allowMachLookup": ["com.apple.coresimulator.*"]
    }
  }
}
```


[​](#sandbox-network-alloweddomains)

`sandbox.network.allowedDomains`

Pre-allow domains for outbound traffic from sandboxed commands, so the sandbox doesn’t prompt for them. Wildcards such as `*.example.com` match subdomains, and an optional `:port` suffix limits an entry to one port; an entry without a port matches every port.

- **Scope**: [`Any file`](#scopes), with [limits on project and local settings](sandboxing.md#repository-settings-under-an-admin-required-sandbox). Only managed settings when [`allowManagedDomainsOnly`](#sandbox-network-allowmanageddomainsonly) is set.
- **Type**: array of strings, each a domain, wildcard pattern, or IP literal, with an optional `:port` suffix
- **Default**: unset, so your permission mode decides [what happens to each new host](sandboxing.md#hosts-outside-your-allowed-domains)

This pre-allows GitHub on every port, every npm subdomain, and one API host on port 443 only:

settings.json

```python
{
  "sandbox": {
    "network": {
      "allowedDomains": ["github.com", "*.npmjs.org", "api.example.com:443"]
    }
  }
}
```

Write IPv6 literals bracketed, with an optional port: `"[::1]"` allows every port and `"[::1]:443"` one port. The bracketed form requires Claude Code v2.1.229 or later. See [IPv6 addresses in domain lists](sandboxing.md#ipv6-addresses-in-domain-lists).


[​](#sandbox-network-denieddomains)

`sandbox.network.deniedDomains`

Block domains for outbound traffic from sandboxed commands, using the same wildcard, port, and IPv6 syntax as [`allowedDomains`](#sandbox-network-alloweddomains). A denied domain stays blocked even when an `allowedDomains` entry matches it too.

- **Scope**: [`Any file`](#scopes)
- **Type**: array of strings, each a domain, wildcard pattern, or IP literal, with an optional `:port` suffix
- **Default**: unset

settings.json

```python
{
  "sandbox": {
    "network": {
      "deniedDomains": ["sensitive.cloud.example.com"]
    }
  }
}
```

Claude Code merges this list from every settings source the session loads even when `allowManagedDomainsOnly` is set, so a developer can always tighten the deny list. For IPv6 literals, see [IPv6 addresses in domain lists](sandboxing.md#ipv6-addresses-in-domain-lists). An entry written with the trailing dot that marks a fully qualified domain name, such as `example.com.`, blocks the same connections as `example.com`.


[​](#sandbox-network-strictallowlist)

`sandbox.network.strictAllowlist`

Deny sandboxed commands access to hosts outside the allowlist instead of prompting for approval. The allowlist is [`allowedDomains`](#sandbox-network-alloweddomains) plus domains from `WebFetch(domain:...)` allow rules, or only the managed settings entries when [`allowManagedDomainsOnly`](#sandbox-network-allowmanageddomainsonly) is set. [Locks that apply without an admin-required sandbox](sandboxing.md#locks-that-apply-without-an-admin-required-sandbox) covers a repository’s entries. Requires Claude Code v2.1.219 or later.

- **Scope**: [`User or managed`](#scopes). A repository can’t turn it on or off.
- **Type**: Boolean
  - `true`: Claude Code denies sandboxed commands access to hosts outside the allowlist
  - `false`: unless another trusted settings file sets `true`, Claude Code decides a host outside the allowlist by permission mode instead of denying it outright: in auto mode it checks the host against the command’s [per-command allowed domains](sandboxing.md#per-command-allowed-domains-in-auto-mode), in `dontAsk` mode it denies, in `bypassPermissions` mode and in interactive terminal plan-mode sessions where bypass is available it allows, and otherwise it asks you
- **Default**: `false`

settings.json

```python
{
  "sandbox": {
    "network": {
      "strictAllowlist": true
    }
  }
}
```

Claude Code enforces this for sandboxed commands only; in-process tools such as `WebFetch` still follow their [permission rules](sandboxing.md#permission-rules). When any of the honored sources sets it to `true`, it stays on. See [Network isolation](sandboxing.md#network-isolation). Requires Claude Code v2.1.219 or later.


[​](#sandbox-network-allowmanageddomainsonly)

`sandbox.network.allowManagedDomainsOnly`

Lock the network allowlist to what managed settings define. Claude Code then honors only `allowedDomains` and `WebFetch(domain:...)` allow rules from managed settings, ignores domains from user, project, local, and `--settings` settings, and blocks a non-allowed domain automatically instead of prompting.

- **Scope**: [`Managed`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code honors only `allowedDomains` and `WebFetch(domain:...)` allow rules from managed settings and blocks a non-allowed domain instead of prompting
  - `false`: domains from other settings files can merge into the allowlist
- **Default**: `false`

This locks the allowlist to GitHub and npm and ignores any domains developers add:

managed-settings.json

```python
{
  "sandbox": {
    "network": {
      "allowManagedDomainsOnly": true,
      "allowedDomains": ["github.com", "*.npmjs.org"]
    }
  }
}
```

While the key is `true`, the sandbox is [admin-required](sandboxing.md#repository-settings-under-an-admin-required-sandbox), and only managed settings can set a [proxy port](#sandbox-network-httpproxyport). Denied domains still merge from every source the session loads. See [Keep developers from widening the policy](sandboxing.md#keep-developers-from-widening-the-policy).


[​](#sandbox-network-httpproxyport)

`sandbox.network.httpProxyPort`

Point the sandbox at your own HTTP proxy instead of the one Claude Code runs. Organizations do this to inspect HTTPS traffic, apply their own filtering rules, or log requests. Your proxy takes over filtering, and Claude Code stops applying its domain lists and network prompts to traffic sent there. When unset, Claude Code starts its own proxy for HTTP traffic.

- **Scope**: [`Any file`](#scopes), unless [other sandbox settings limit which files can set a port](sandboxing.md#custom-proxy-configuration)
- **Type**: number, a local TCP port
- **Default**: unset, so Claude Code runs its own proxy

settings.json

```python
{
  "sandbox": {
    "network": {
      "httpProxyPort": 8080
    }
  }
}
```

Set [`socksProxyPort`](#sandbox-network-socksproxyport) too if your proxy should carry SOCKS traffic as well; with only one of the two set, Claude Code still runs its own proxy for the other protocol. See [Custom proxy configuration](sandboxing.md#custom-proxy-configuration).


[​](#sandbox-network-socksproxyport)

`sandbox.network.socksProxyPort`

Point the sandbox at your own SOCKS5 proxy instead of the one Claude Code runs. Your proxy takes over filtering, and Claude Code stops applying its domain lists and network prompts to traffic sent there. When unset, Claude Code starts its own proxy for SOCKS traffic.

- **Scope**: [`Any file`](#scopes), unless [other sandbox settings limit which files can set a port](sandboxing.md#custom-proxy-configuration)
- **Type**: number, a local TCP port
- **Default**: unset, so Claude Code runs its own proxy

settings.json

```python
{
  "sandbox": {
    "network": {
      "socksProxyPort": 8081
    }
  }
}
```

See [Custom proxy configuration](sandboxing.md#custom-proxy-configuration).


[​](#sandbox-network-tlsterminate)

`sandbox.network.tlsTerminate`

Make the sandbox proxy terminate TLS so it can read the contents of HTTPS requests. This is experimental, and `mask` [credential substitution](sandboxing.md#mask-credentials) requires it. Set `{}` to generate an ephemeral certificate authority for the session, or set `caCertPath` and `caKeyPath` to use your own.

- **Scope**: [`User or managed`](#scopes). A repository can’t switch it on or supply a certificate authority.
- **Type**: object with optional `caCertPath` and `caKeyPath` strings, each a file path
- **Default**: unset, so the proxy doesn’t terminate or inspect TLS

settings.json

```python
{
  "sandbox": {
    "network": {
      "tlsTerminate": {}
    }
  }
}
```

When more than one honored source sets it, Claude Code uses the value from the highest-precedence source: managed settings, then the `--settings` flag, then user settings.


[​](#memory-and-context)

Memory and context

Control what Claude Code loads into context, how it compacts, and where it keeps memory and plans. See [Manage context](context-window.md) and [Memory](memory.md).


[​](#autocompactenabled)

`autoCompactEnabled`

Have Claude Code [compact the conversation automatically](context-window.md#when-your-context-fills-up) when context approaches the limit. Appears in `/config` as **Auto-compact**, and toggling it there writes this key to your user settings.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code compacts the conversation automatically when context approaches the limit
  - `false`: Claude Code doesn’t compact automatically
- **Default**: `true`
- **Per-session overrides**: [`DISABLE_AUTO_COMPACT`](env-vars.md) turns auto-compact off for one session; whichever of the two turns it off, the other can’t turn it back on

settings.json

```python
{
  "autoCompactEnabled": false
}
```

The manual `/compact` command keeps working while auto-compact is off. If you turn auto-compact off, [idle compaction](#idlecompaction) turns off too.


[​](#autocompactwindow)

`autoCompactWindow`

Set how full the context window gets before Claude Code [compacts automatically](context-window.md#when-your-context-fills-up).

- **Scope**: [`Any file`](#scopes)
- **Type**: number of tokens, from `100000` to `1000000`. Claude Code caps the value at your model’s context window; the [models overview](../20-Models/about-claude-models-overview.md) lists each model’s window
- **Default**: unset, so Claude Code picks a window tuned for your model
- **Per-session overrides**: [`--autocompact`](cli-reference.md#cli-flags) takes precedence over this key for one session, and [`CLAUDE_CODE_AUTO_COMPACT_WINDOW`](env-vars.md) takes precedence over both unless Claude Code [ignores the variable’s value](model-config.md#claude_code_auto_compact_window-values)

settings.json

```python
{
  "autoCompactWindow": 500000
}
```

The [`/autocompact`](commands.md#all-commands) command saves a window for the current model under [`modelSettings`](#modelsettings), which takes precedence over this key in the same file for that model. [Set the auto-compact window](model-config.md#set-the-auto-compact-window) covers how the command, flag, variable, and setting interact.


[​](#automemorydirectory)

`autoMemoryDirectory`

Store [auto memory](memory.md#storage-location) in a directory of your choice instead of the per-project default.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, an absolute or `~/`-prefixed directory path
- **Default**: unset, so Claude Code uses `~/.claude/projects/<project>/memory/`

settings.json

```python
{
  "autoMemoryDirectory": "~/my-memory-dir"
}
```

From project or local settings, Claude Code honors this key under the same [workspace trust rule as hooks](permissions.md#what-runs-before-you-trust-a-folder), since a cloned repository can supply those files.


[​](#automemoryenabled)

`autoMemoryEnabled`

Turn [auto memory](memory.md#enable-or-disable-auto-memory) on or off. When `false`, Claude doesn’t read from or write to the auto memory directory. You can also toggle it with `/memory` during a session, which writes this key to your user settings.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: the same as unset; auto memory stays on unless something that outranks this key turns it off for the session, such as `--bare`, safe mode, or `CLAUDE_CODE_DISABLE_AUTO_MEMORY`
  - `false`: Claude doesn’t read from or write to the auto memory directory
- **Default**: `true`
- **Per-session overrides**: [`CLAUDE_CODE_DISABLE_AUTO_MEMORY`](env-vars.md) takes precedence over this key for one session, in either direction

settings.json

```python
{
  "autoMemoryEnabled": false
}
```


[​](#bashoutputmaxchars)

`bashOutputMaxChars`

Set how many characters of a successful Bash or PowerShell command’s [output Claude receives inline](tools-reference.md#output-limits). When output passes the limit, Claude Code saves it to a file and Claude receives a short preview plus the file’s path. Raise the limit when command output, such as a verbose build or a full test-suite log, routinely overflows the default and you want Claude to read it without opening the file. Requires Claude Code v2.1.261 or later.

- **Scope**: [`Any file`](#scopes)
- **Type**: number of characters, a positive integer. Claude Code clamps the value into the range `4000` to `128000`
- **Default**: unset, so Claude receives up to 30,000 characters inline

settings.json

```python
{
  "bashOutputMaxChars": 100000
}
```

When you set this key, Claude Code ignores the [`BASH_MAX_OUTPUT_LENGTH`](env-vars.md) environment variable.


[​](#claudemd)

`claudeMd`

Inject CLAUDE.md-style instructions as organization-managed memory without deploying a separate file. Claude Code loads the text as a managed memory entry ahead of user and project CLAUDE.md files.

- **Scope**: [`Managed`](#scopes)
- **Type**: string, the text of a CLAUDE.md file; write it as you would the file, Markdown included, with line breaks as `\n`
- **Default**: unset

This example deploys two rules as a short Markdown list:

managed-settings.json

```python
{
  "claudeMd": "# Engineering rules\n\n- Always run make lint before committing.\n- Never push directly to main."
}
```

See [Deploy organization-wide CLAUDE.md](memory.md#deploy-organization-wide-claude-md).


[​](#claudemdexcludes)

`claudeMdExcludes`

Skip specific `CLAUDE.md` files when Claude Code loads [memory](memory.md#exclude-specific-claude-md-files). In a large monorepo, use it to skip CLAUDE.md files from other teams that aren’t relevant to your work; [Exclude irrelevant CLAUDE.md files](large-codebases.md#exclude-irrelevant-claude-md-files) in the large-codebases guide walks through that case. Patterns match against absolute file paths.

- **Scope**: [`Any file`](#scopes)
- **Type**: array of strings, each a glob pattern or absolute path
- **Default**: unset, so Claude Code loads every CLAUDE.md it finds

settings.json

```python
{
  "claudeMdExcludes": ["**/vendor/**/CLAUDE.md"]
}
```

Exclusions apply only to user, project, and local memory files; managed policy CLAUDE.md files can’t be excluded.


[​](#env)

`env`

Set environment variables for every session and for the subprocesses Claude Code starts from it. Most variables in the [environment variables reference](env-vars.md) can go here, which is how you apply one to every session or roll it out to your team. Project and local settings can’t set [some of them](#variables-claude-code-ignores-in-env).

- **Scope**: [`Any file`](#scopes)
- **Type**: object mapping variable names to string values
- **Default**: unset

This example turns off automatic compaction and routes API requests through a proxy:

settings.json

```python
{
  "env": {
    "DISABLE_AUTO_COMPACT": "1",
    "ANTHROPIC_BASE_URL": "https://proxy.example.com"
  }
}
```


[​](#how-env-values-interact-with-your-shell)

How `env` values interact with your shell

- A value here overwrites the same variable exported in your shell, and when more than one settings file sets a variable, the [highest-precedence](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.
- When the Claude Desktop app or a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) 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](debug-your-config.md) names each ignored variable.
- 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.
- `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`.
- Values here are plain text in the settings file and reach every subprocess Claude Code starts. For an OTLP bearer token that rotates, use [`otelHeadersHelper`](#otelheadershelper); for API credentials, use [`apiKeyHelper`](#apikeyhelper).


[​](#when-claude-code-applies-env-values)

When Claude Code applies `env` values

- From user settings, `--settings`, and managed settings: at startup, and again in the running session when a saved change alters the merged `env`.
- From project and local settings: after you trust the workspace, or at startup in `-p` mode, which never shows the trust dialog, and again when a saved change alters the merged `env`.
- Variables Claude Code classifies as safe, such as model selection, timeouts and limits, and feature toggles: at startup from every settings file, apart from the [variables project and local settings can’t set](#variables-claude-code-ignores-in-env).
- After you [move the session with `/cd`](permissions.md#move-the-session-to-another-directory) on v2.1.246 or later: the new directory’s project and local `env` values, on top of the previous directory’s.


[​](#variables-claude-code-ignores-in-env)

Variables Claude Code ignores in `env`

- Project and local settings can’t set variables that a checked-out repository shouldn’t control; set those in your shell, user settings, or managed settings instead. Claude Code drops each one, apart from a few values that turn telemetry off, and logs a warning you can see with `claude --debug`. They include:
  - Variables that choose where Claude Code stores or writes its own files: `CLAUDE_CONFIG_DIR`, `CLAUDE_CODE_TMPDIR`, and the operating-system directory variables such as `HOME`, `TMPDIR`, `TMP`, `TEMP`, and the `XDG_*` family.
  - Windows variables that pick the programs and machine-wide configuration for the processes Claude Code starts, such as `SystemRoot`, `ComSpec`, `ProgramData`, `LOCALAPPDATA`, `PATHEXT`, `PSModulePath`, and the `ProgramFiles` family.
  - Variables that export session content: [`OTEL_LOG_RAW_API_BODIES`](env-vars.md#variables) and the detailed beta tracing pair `ENABLE_BETA_TRACING_DETAILED` and `BETA_TRACING_ENDPOINT`.
  - The [OpenTelemetry exporter](../13-Enterprise-Admin/monitoring-usage.md) variables that turn telemetry on, choose where it goes, or choose what content it captures:
    - `CLAUDE_CODE_ENABLE_TELEMETRY`, plus the enhanced telemetry beta pair `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA` and `ENABLE_ENHANCED_TELEMETRY_BETA`
    - The exporter selectors `OTEL_LOGS_EXPORTER`, `OTEL_METRICS_EXPORTER`, and `OTEL_TRACES_EXPORTER`
    - The content variables `OTEL_LOG_USER_PROMPTS`, `OTEL_LOG_ASSISTANT_RESPONSES`, `OTEL_LOG_TOOL_CONTENT`, and `OTEL_LOG_TOOL_DETAILS`
    - `OTEL_EXPORTER_OTLP_*` variables whose names end in `_ENDPOINT`, `_HEADERS`, `_PROTOCOL`, `_CERTIFICATE`, `_CLIENT_KEY`, or `_INSECURE`, in the generic and per-signal forms, such as `OTEL_EXPORTER_OTLP_ENDPOINT` and `OTEL_EXPORTER_OTLP_METRICS_HEADERS`
    - `OTEL_EXPORTER_PROMETHEUS_HOST` and `OTEL_EXPORTER_PROMETHEUS_PORT`

    Only these values still apply from project and local settings, because they turn something off: `none` for the three exporter selectors, and an off value such as `0` for `OTEL_LOG_USER_PROMPTS`, `OTEL_LOG_TOOL_CONTENT`, and `OTEL_LOG_TOOL_DETAILS`. Such a value overrides the same variable in your user settings, but not one that the environment you start Claude Code from, a `--settings` file, or managed settings sets. When a project or local settings file sets a variable in this group, a local interactive session shows a notice at startup. Run `/status` or `claude doctor` to see which ones Claude Code ignored and which turned telemetry off; both list names, never values. A non-interactive run with `-p` or an Agent SDK session shows no notice, so check that your collector still receives data after you upgrade. If it doesn’t, set the variables in your user settings, managed settings, the job’s environment, or a file you pass with `--settings`. Ignoring this group in project and local settings requires Claude Code v2.1.282 or later.
  - Variables that change how Claude Code starts or syncs, such as `CLAUDE_CODE_PROCESS_WRAPPER`, `CLAUDE_CODE_SYNC_SKILLS`, `CLAUDE_CODE_SYNC_PLUGINS`, `CLAUDE_CODE_PLUGIN_CACHE_DIR`, and `CLAUDE_CODE_PLUGIN_SEED_DIR`.
  - The [screen reader mode](accessibility.md) variable `CLAUDE_AX_SCREEN_READER` and the other variables whose names start with `CLAUDE_AX_`, such as [`CLAUDE_AX_STARTUP_QUIET_MS`](env-vars.md#variables).
  - [`CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS`](env-vars.md#variables), which sets the timer on an unanswered dialog.
  - [`CLAUDE_CODE_DISABLE_ATTACHMENTS`](env-vars.md#variables), which turns off attachment processing.
  - [`CLAUDE_CODE_DISABLE_FILE_MENTIONS`](env-vars.md#variables), which stops Claude Code from expanding `@` mentions of files and directories.

  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`.
- Identity variables that Claude Code’s hosting environments own, such as `CLAUDE_CODE_REMOTE` and `CLAUDE_CODE_ACCOUNT_UUID`, are ignored from every file.
- [`CLAUDE_CODE_MESSAGING_SOCKET` and `CLAUDE_CODE_MESSAGING_TOKEN`](env-vars.md#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.
- [`CLAUDE_CODE_PROJECT_DIR_NAME`](sessions.md#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.
- [`CLAUDE_CODE_RESTRICTED`](env-vars.md#variables), which Claude Code reads from the launch environment only, is ignored from every file.
- [`CLAUDE_CODE_DISABLE_POWERSHELL_CMD_RM_DENY`](env-vars.md#variables), which Claude Code reads from the launch environment only, is ignored from every file. The variable requires Claude Code v2.1.283 or later.
- [`CLAUDE_CODE_DISABLE_DANGEROUS_RM_TIMEOUT`, `CLAUDE_CODE_DISABLE_SUBSTITUTION_RM_PROMPT`, `CLAUDE_CODE_DISABLE_INLINE_SHELL_RM_PROMPT`, and `CLAUDE_CODE_DISABLE_MOUNTED_DRIVE_RM_PROMPT`](env-vars.md#variables), which Claude Code reads from the launch environment only, are ignored from every file.
- [`CLAUDE_CODE_WARN_DISK_FREE_GIB` and `CLAUDE_CODE_WARN_MEMORY_FREE_GIB`](env-vars.md#variables), which Claude Code reads from the launch environment only, are ignored from every file. The variables require Claude Code v2.1.304 or later.


[​](#filecheckpointingenabled)

`fileCheckpointingEnabled`

Have Claude Code snapshot files before each edit so [`/rewind`](checkpointing.md) can restore them. Appears in `/config` as **Rewind code (checkpoints)**, and toggling it there writes this key to your user settings.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code snapshots files before each edit so `/rewind` can restore them
  - `false`: Claude Code doesn’t snapshot files, so `/rewind` can’t restore them
- **Default**: `true`
- **Per-session overrides**: [`CLAUDE_CODE_DISABLE_FILE_CHECKPOINTING`](env-vars.md) turns checkpointing off for one session; whichever of the two turns it off, the other can’t turn it back on

settings.json

```python
{
  "fileCheckpointingEnabled": false
}
```

In a `-p` run or an Agent SDK session, Claude Code ignores this key. The SDK turns checkpointing on with its `enableFileCheckpointing` option, and a bare `-p` run needs `CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING=true`. See [File checkpointing in the Agent SDK](../05-Agent-SDK/agent-sdk-file-checkpointing.md).


[​](#idlecompaction)

`idleCompaction`

Idle compaction [compacts](context-window.md#what-survives-compaction) a long conversation that you’ve stepped away from, shortly before its prompt cache expires. Your next message then sends a summary instead of the whole conversation. When you come back, the conversation shows a line that starts with `Compacted while idle, before the prompt cache expired`. Idle compaction is on by default for conversations that meet all of these conditions:

- **Session**: you’re in an interactive terminal session
- **Auto-compaction**: [`autoCompactEnabled`](#autocompactenabled) is on
- **Prompt cache**: the conversation is on the [one-hour prompt cache TTL](prompt-caching.md#which-ttl-each-request-gets)
- **Feature flags**: Claude Code can [fetch feature flags from Anthropic](env-vars.md#features-that-need-feature-flag-fetching)
- **Size**: the conversation’s context has reached the token threshold, which you can [change](#change-the-idle-compaction-threshold) from its default of 200,000
- **Idle time**: about 54 minutes have passed since the last request, and your computer is awake at that point

To turn idle compaction off, set this key to `false`.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code compacts idle conversations that meet the conditions
  - `false`: Claude Code doesn’t compact while your session is idle
- **Default**: `true`
- **Per-session overrides**: [`DISABLE_AUTO_COMPACT`](env-vars.md) turns idle compaction off along with auto-compaction

settings.json

```python
{
  "idleCompaction": false
}
```

To turn idle compaction off or on from inside a session, run `/config` and change the **Idle compaction** row. Your choice is saved to your user settings and applies right away. The row requires Claude Code v2.1.302 or later. If you run one of those versions and `/config` doesn’t show the row, check for these causes:

- **Another settings source sets the key**: a value in managed settings, the `--settings` flag, or a project or local settings file overrides your user settings. Change the key in that source instead
- **Feature flags are unavailable**: where Claude Code can’t [fetch feature flags from Anthropic](env-vars.md#features-that-need-feature-flag-fetching), idle compaction doesn’t run, so there is nothing to turn off

The key requires Claude Code v2.1.290 or later. On an earlier version, which ignores this key, turn off [`autoCompactEnabled`](#autocompactenabled) to stop idle compaction.


[​](#change-the-idle-compaction-threshold)

Change the idle compaction threshold

Set [`CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS`](env-vars.md) to the number of tokens a conversation’s context must reach before idle compaction applies to it. Use a positive whole number. Values below `100000` are raised to `100000`, the lowest threshold. At the default, a conversation on a 200K context window auto-compacts before it reaches 200,000 tokens. This example lowers the threshold to 150,000 so that those conversations qualify:

settings.json

```python
{
  "env": {
    "CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS": "150000"
  }
}
```


[​](#plansdirectory)

`plansDirectory`

Choose where Claude Code stores the plan files it writes in [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode). Claude Code resolves the path relative to the project root.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, a path relative to the project root
- **Default**: unset, so Claude Code uses `~/.claude/plans`

settings.json

```python
{
  "plansDirectory": "./plans"
}
```

Claude Code stores plans in `~/.claude/plans` instead of the directory you set in cases such as these:

- **Outside the project root**: the path resolves outside the project root, as `"../plans"` does.
- **Backslash on macOS, Linux, and WSL**: the resolved path contains a backslash, as the Windows-style `"docs\\plans"` does. Write `"docs/plans"`, which works on Windows too.


[​](#skilllistingbudgetfraction)

`skillListingBudgetFraction`

Each turn, Claude sees a [listing of your skills](../08-Plugins-Skills/skills.md#skill-descriptions-are-cut-short) with their descriptions, and Claude Code caps that listing at a share of the context window. When the listing is over the cap, Claude Code keeps every skill’s name but drops the descriptions of the least-used skills, so Claude can still invoke those skills but is less likely to choose one on its own. Raise this key to keep more descriptions visible at the cost of more context per turn.

- **Scope**: [`Any file`](#scopes)
- **Type**: number, a fraction greater than `0` and at most `1`
- **Default**: `0.01`, which reserves 1% of the context window

settings.json

```python
{
  "skillListingBudgetFraction": 0.02
}
```

To see how much context the listing uses and which skills contribute most, run `/doctor`.


[​](#skilllistingmaxdescchars)

`skillListingMaxDescChars`

Each turn, Claude sees a [listing of your skills](../08-Plugins-Skills/skills.md#skill-descriptions-are-cut-short) that shows each skill’s `description` and `when_to_use` text. This key caps how many characters of that text Claude Code shows per skill; longer text is cut at the cap.

- **Scope**: [`Any file`](#scopes)
- **Type**: number of characters, a positive integer
- **Default**: `1536`

settings.json

```python
{
  "skillListingMaxDescChars": 2048
}
```

Raise it to keep long descriptions intact at the cost of more context per turn; lower it to fit more skills under [`skillListingBudgetFraction`](#skilllistingbudgetfraction).


[​](#taskoutputmaxchars)

`taskOutputMaxChars`

Removed in v2.1.277, together with the `TaskOutput` tool it sized. Setting it has no effect on current versions. Claude reads a background task’s [output file](tools-reference.md#background-commands) with `Read` instead.

Through v2.1.276, you set this key to the number of characters of a [background task’s](tools-reference.md#background-commands) output that Claude received inline when it read the task with the `TaskOutput` tool.


[​](#interface-and-terminal)

Interface and terminal

Change how Claude Code looks and behaves in your terminal: theme, editor mode, status line, spinner, notifications inside the session, and accessibility. See [Terminal configuration](terminal-config.md).


[​](#askuserquestiontimeout)

`askUserQuestionTimeout`

Let an unanswered [`AskUserQuestion`](tools-reference.md) dialog auto-continue after a period of idle time, submitting whatever options you had already selected. Set it when you step away and want Claude to continue without you. With the default, questions wait until you answer them. For when the timer pauses or never starts, see [Question auto-continue timeout](tools-reference.md#question-auto-continue-timeout).

- **Scope**: [`User or managed`](#scopes)
- **Type**: string, one of `"60s"`, `"5m"`, `"10m"`, or `"never"`
- **Default**: `"never"`

settings.json

```python
{
  "askUserQuestionTimeout": "5m"
}
```

Appears in `/config` as **Question auto-continue timeout**, which writes this key to user settings; Claude Code hides the row while managed settings or the `--settings` flag set the key.


[​](#autocontinueatusagelimit)

`autoContinueAtUsageLimit`

After a claude.ai usage limit stops your session, wait in the open session and continue the task automatically after the reset. See [Turn automatic continue off](interactive-mode.md#turn-automatic-continue-off). Requires Claude Code v2.1.234 or later.

- **Scope**: [`User or managed`](#scopes). Read from user settings, `--settings`, and managed settings only. When none of those sets the key, a project or local settings file that sets it turns the feature off rather than being ignored.
- **Type**: Boolean
  - `true`: after a claude.ai usage limit stops your session, Claude Code waits in the open session and continues the task automatically after the reset
  - `false`: Claude Code doesn’t start the wait on its own. You can still [start a wait yourself](interactive-mode.md#start-a-wait-yourself) from the usage-limit options menu
- **Default**: `true`

settings.json

```python
{
  "autoContinueAtUsageLimit": false
}
```

Appears in `/config` as **Continue automatically at usage limit**, which writes this key to user settings; Claude Code hides the row while managed settings or the `--settings` flag set the key.


[​](#autoscrollenabled)

`autoScrollEnabled`

Follow new output to the bottom of the conversation in [fullscreen rendering](fullscreen.md). Turn it off to stay where you scrolled while Claude keeps working; permission prompts still scroll into view.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: the conversation follows new output to the bottom
  - `false`: you stay where you scrolled while Claude keeps working; permission prompts still appear below the transcript
- **Default**: `true`

settings.json

```python
{
  "autoScrollEnabled": false
}
```

Appears in `/config` as **Auto-scroll** when fullscreen rendering is on, which writes this key to user settings.


[​](#axscreenreader)

`axScreenReader`

Render screen-reader friendly output: flat text without decorative borders or animations. Screen-reader mode uses the classic renderer, so the `tui` setting has no effect while it is active; attached [background sessions](../09-Agents-Patterns/agent-view.md) still render fullscreen.

- **Scope**: [`User or managed`](#scopes). You can also set the key in a file you pass with `--settings`. Claude Code ignores the key in project and local settings, so neither a repository nor your own `.claude/settings.local.json` can turn screen-reader mode on or off.
- **Type**: Boolean
  - `true`: Claude Code renders flat text without decorative borders or animations, using the classic renderer
  - `false`: Claude Code renders normally
- **Default**: unset, so screen-reader mode is off
- **Per-session overrides**: [`--ax-screen-reader`](cli-reference.md#cli-flags) takes precedence over [`CLAUDE_AX_SCREEN_READER`](env-vars.md), and both take precedence over this key for one session

settings.json

```python
{
  "axScreenReader": true
}
```


[​](#basheditdiffenabled)

`bashEditDiffEnabled`

Choose whether Claude Code records which files changed in a Git repository while a Bash command runs. When it records them, you see their diff in the terminal after the command, and your [PostToolUse Bash hooks](../07-Hooks/hooks.md#bash) receive the changed-file list. A listed file isn’t always one the command changed. A change that another program or another Bash call made while the command ran can appear there too. Set the key to `true` to record them in every permission mode. Requires Claude Code v2.1.269 or later.

- **Scope**: [`User or managed`](#scopes). A `true` counts only from your user settings, JSON passed with `--settings`, or [managed settings](../13-Enterprise-Admin/managed-settings.md), so a `true` in a repository’s `.claude/settings.json` or `.claude/settings.local.json` can’t turn the recording on. A `false` in either repository file still turns it off unless a [higher-precedence](settings.md#settings-precedence) file sets `true`.
- **Type**: Boolean
- **Default**: unset, so Claude Code records changes in auto mode and `bypassPermissions` mode when it directs Claude to edit files through Bash
- **Per-session overrides**: [`CLAUDE_CODE_BASH_EDIT_DIFF`](env-vars.md) takes precedence over this key for one session

settings.json

```python
{
  "bashEditDiffEnabled": true
}
```


[​](#companyannouncements)

`companyAnnouncements`

Show your organization’s announcements to users at startup. When you list more than one, Claude Code picks one at random for each session; on a person’s very first launch it shows the first entry.

- **Scope**: [`Any file`](#scopes)
- **Type**: array of strings
- **Default**: unset, so no announcement shows

settings.json

```python
{
  "companyAnnouncements": [
    "Welcome to Acme Corp! Review our code guidelines at docs.example.com"
  ]
}
```


[​](#defaultshell)

`defaultShell`

Choose whether Bash or PowerShell runs the shell commands you type with the [`!` prefix](interactive-mode.md#shell-mode-with-prefix) in the input box, the ones Claude Code runs directly and adds to the session. `"powershell"` works only while the [PowerShell tool](tools-reference.md#powershell-tool) is on. The tool is on by default on Windows without Git Bash, and on Windows with Git Bash for claude.ai and Console accounts. In Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry sessions, and on macOS, Linux, and WSL, set `CLAUDE_CODE_USE_POWERSHELL_TOOL=1` to turn the tool on. Set that variable to `0` to turn the tool off.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, one of:
  - `"bash"`: Claude Code runs your `!` commands in Bash
  - `"powershell"`: Claude Code runs your `!` commands in PowerShell
- **Default**: `"bash"`, or `"powershell"` on Windows when Bash isn’t available

settings.json

```python
{
  "defaultShell": "powershell"
}
```

If the shell you name isn’t available, Claude Code uses the other one: `"powershell"` falls back to Bash when the PowerShell tool is off, and `"bash"` falls back to PowerShell when Bash isn’t installed.


[​](#dialogexpiry)

`dialogExpiry`

Set the deadline for dialogs Claude Code [forwards to a remote client](remote-control.md#limitations), such as a Remote Control or SDK host, and for the approval dialog for a [held cross-session message](cross-session-messaging.md#control-inbound-messages). On Claude Code v2.1.236 or later, the same deadline bounds the mid-session [Fable usage-credits consent prompt](model-config.md#fable-and-usage-credits) in a session that may have nobody at the terminal. When no answer arrives before the deadline, Claude Code cancels the dialog and continues with its no-action default. Requires Claude Code v2.1.224 or later.

- **Scope**: [`User or managed`](#scopes)
- **Type**: string, one of `"60s"`, `"5m"`, `"10m"`, or `"never"`, which disables the deadline
- **Default**: `"5m"`
- **Per-session overrides**: [`CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS`](env-vars.md) takes precedence over this key for one session

settings.json

```python
{
  "dialogExpiry": "10m"
}
```

Permission prompts and [`AskUserQuestion`](tools-reference.md#askuserquestion-tool-behavior) questions use their own flows and aren’t governed by this deadline. Appears in `/config` as **Dialog expiry**, which writes this key to user settings; the row requires Claude Code v2.1.232 or later, and Claude Code hides it while managed settings or the `--settings` flag set the key.


[​](#editormode)

`editorMode`

Choose the key binding mode for the input prompt.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, one of:
  - `"normal"`: standard key bindings in the prompt input
  - `"vim"`: vim-style editing with NORMAL, INSERT, and VISUAL modes
- **Default**: `"normal"`

settings.json

```python
{
  "editorMode": "vim"
}
```

Appears in `/config` as **Editor mode**, which writes this key to user settings.


[​](#emojicompletionenabled)

`emojiCompletionEnabled`

Show emoji suggestions when you type `:` plus a shortcode in the prompt input, and replace a completed shortcode such as `:heart:` with its emoji. Set it to `false` to turn off both.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code shows emoji suggestions after `:` and replaces a completed shortcode with its emoji
  - `false`: Claude Code neither suggests emoji nor replaces shortcodes
- **Default**: `true`

settings.json

```python
{
  "emojiCompletionEnabled": false
}
```

See [Emoji shortcodes](interactive-mode.md#emoji-shortcodes). Requires Claude Code v2.1.217 or later.


[​](#filesuggestion)

`fileSuggestion`

Run your own command to supply `@` file path autocomplete instead of the built-in file suggestion. The built-in suggestion uses fast filesystem traversal; a large monorepo may do better with project-specific indexing such as a pre-built file index.

- **Scope**: [`Any file`](#scopes). Under the [status line and file suggestion gates](#status-line-and-file-suggestion-gates), Claude Code turns the command off or runs only a managed value, and skips yours without warning.
- **Type**: object with `type`, always `"command"`, and `command`, the shell command to run
- **Default**: unset, so Claude Code uses the built-in file suggestion

settings.json

```python
{
  "fileSuggestion": {
    "type": "command",
    "command": "~/.claude/file-suggestion.sh"
  }
}
```

After you save this, type `@` followed by part of a path in the prompt: the suggestions come from your command’s output.


[​](#command-input-and-output)

Command input and output

Claude Code runs the command with the same environment variables as [hooks](../07-Hooks/hooks.md), including `CLAUDE_PROJECT_DIR`, and stops waiting after five seconds. The command receives JSON on stdin with a `query` field holding what you’ve typed so far:

```python
{"query": "src/comp"}
```

Print newline-separated file paths to stdout. Claude Code shows at most 15:

```python
src/components/Button.tsx
src/components/Modal.tsx
src/components/Form.tsx
```

The following script reads the query and hands it to a repository file index:

```python
#!/bin/bash
query=$(cat | jq -r '.query')
# Replace your-repo-file-index with your own file search command
your-repo-file-index --query "$query" | head -20
```


[​](#footerlinksregexes)

`footerLinksRegexes`

Render extra clickable badges in the footer below the input box when a regex matches turn output: tool results, including file contents and fetched pages, and Claude’s own responses. Use it to turn IDs printed by project CLIs, such as review tools and issue trackers, into session links.

- **Scope**: [`User or managed`](#scopes)
- **Type**: array of objects, each with `type` set to `"regex"`, a `pattern` regex, a `url` template, and an optional `label`; `{name}` placeholders in `url` and `label` are filled from named capture groups in `pattern`
- **Default**: unset, so no badges render

This example matches issue keys such as `PROJ-1234` and builds each link from the captured key:

settings.json

```python
{
  "footerLinksRegexes": [
    {
      "type": "regex",
      "pattern": "\\b(?<key>PROJ-\\d+)\\b",
      "url": "https://issues.example.com/browse/{key}",
      "label": "{key}"
    }
  ]
}
```

With this configured, when `PROJ-1234` appears in a tool result or in Claude’s reply, a `PROJ-1234` badge appears in the footer linking to `https://issues.example.com/browse/PROJ-1234`.


[​](#badge-constraints)

Badge constraints

Each entry’s URL, label, and badge count are bounded as follows:

| Constraint  | Behavior                                                                                                                                                                                           |
|:------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| URL origin  | Captured values are URL-encoded and the constructed URL must share the template’s literal origin. A capture can fill a path segment or query value but can’t change where the link points          |
| URL length  | Constructed URLs longer than 2048 characters are dropped                                                                                                                                           |
| URL scheme  | Must be `https`, `http`, or a recognized editor or workspace deep-link scheme: `vscode`, `vscode-insiders`, `cursor`, `windsurf`, `zed`, `jetbrains`, `idea`, `slack`, `linear`, `notion`, `figma` |
| Label       | Defaults to the matched text and is truncated to 28 display columns                                                                                                                                |
| Badge count | At most 5 badges render. The oldest is displaced by newer matches and `/clear` removes them                                                                                                        |

When a turn completes, Claude Code matches each entry’s `pattern` regex against the turn output on the main thread, so a slow regex blocks the UI until it finishes. Nested quantifiers such as `(a+)+$` can take exponentially long against certain inputs and freeze the session, so keep each `pattern` linear and avoid nesting `+` or `*`. Footer badges render alongside a [custom status line](statusline.md) when one is configured; neither replaces the other. Use a status line for a script-driven row that computes its own content from session data, and footer badges to turn IDs from the conversation into links without a script.


[​](#keybindingflavor)

`keybindingFlavor`

Deprecated since v2.1.261 and has no effect. The prompt’s word-editing keys always [follow readline conventions](interactive-mode.md#make-ctrl-w-delete-back-to-whitespace), as in Bash. Claude Code still accepts `keybindingFlavor`, so a settings file that sets it stays valid.

In v2.1.238 through v2.1.260, setting it to `"readline"` made `Ctrl+W` delete back to the previous whitespace instead of only the previous word.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, `"classic"` or `"readline"`
- **Default**: unset


[​](#maxprosewidth)

`maxProseWidth`

Cap the width of the prose in Claude’s responses so lines stay readable in a wide terminal. Paragraphs, headings, lists, and blockquotes wrap within this many columns, while tables and code blocks keep the full terminal width. Requires Claude Code v2.1.282 or later.

- **Scope**: [`Any file`](#scopes)
- **Type**: number of terminal columns, a whole number, minimum `40`. Claude Code ignores any other value
- **Default**: unset, so prose wraps at the terminal edge

settings.json

```python
{
  "maxProseWidth": 80
}
```


[​](#prefersreducedmotion)

`prefersReducedMotion`

Reduce or turn off interface animations such as the spinner, shimmer, and flash effects. Appears in `/config` as **Reduce motion**.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code reduces or turns off interface animations such as the spinner, shimmer, and flash effects
  - `false`: the same as unset; Claude Code shows its animations
- **Default**: `false`

settings.json

```python
{
  "prefersReducedMotion": true
}
```


[​](#promptsuggestionenabled)

`promptSuggestionEnabled`

Show or hide [prompt suggestions](interactive-mode.md#prompt-suggestions), the grayed-out predictions that appear in your prompt input. Set it to `false`, or turn off **Prompt suggestions** in `/config`, to hide them.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: you see prompt suggestions in your prompt input
  - `false`: Claude Code hides prompt suggestions
- **Default**: `true`
- **Per-session overrides**: [`CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION`](env-vars.md) takes precedence over this key for one session

settings.json

```python
{
  "promptSuggestionEnabled": false
}
```

Prompt suggestions need a claude.ai or Console account with telemetry on. On Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry, or with telemetry turned off, such as by [`DISABLE_TELEMETRY`](env-vars.md), this key has no effect and only `CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=1` turns them on.


[​](#respectgitignore)

`respectGitignore`

Control whether the `@` file picker leaves out files that match `.gitignore` patterns. Appears in `/config` as **Respect .gitignore in file picker**.

- **Scope**: [`Any file`](#scopes). When no settings file sets it, Claude Code falls back to `respectGitignore` in `~/.claude.json`, which the `/config` toggle writes.
- **Type**: Boolean
  - `true`: the `@` file picker leaves out files that match `.gitignore` patterns
  - `false`: the `@` file picker includes files that match `.gitignore` patterns
- **Default**: `true`

settings.json

```python
{
  "respectGitignore": false
}
```


[​](#respondtobashcommands)

`respondToBashCommands`

Choose whether Claude responds after you run a shell command with the [`!` prefix](interactive-mode.md#shell-mode-with-prefix) in the input box. By default, Claude Code adds the command’s output to the conversation and Claude replies to it. Set this key to `false` to add the output to context without a reply, so you can run several commands and ask about them together.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code adds the command’s output to the conversation and Claude replies to it
  - `false`: Claude Code adds the output to context without a reply
- **Default**: `true`

settings.json

```python
{
  "respondToBashCommands": false
}
```

See [Shell mode with `!` prefix](interactive-mode.md#shell-mode-with-prefix).


[​](#showclearcontextonplanaccept)

`showClearContextOnPlanAccept`

When Claude finishes a plan in [plan mode](permission-modes.md#review-and-approve-a-plan), it shows an approval menu. Planning can use a lot of context, so this key adds a first option to that menu, **Yes, clear context and …**, that approves the plan, clears the conversation context, and starts implementing from the plan alone. The rest of the label names the permission mode the session continues in, and shows how much of your context the planning used.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: the plan approval menu gets a first option, **Yes, clear context and …**, that approves the plan and clears the conversation context
  - `false`: the plan approval menu shows no clear-context option
- **Default**: `false`

settings.json

```python
{
  "showClearContextOnPlanAccept": true
}
```


[​](#showturnduration)

`showTurnDuration`

Show or hide the turn duration message after each response, such as “Cooked for 1m 6s · done 6:05 PM”. The clock after “done” shows when the turn finished; [`timeFormat`](#timeformat) and [`timeZone`](#timezone) control its format and zone. Appears in `/config` as **Show turn duration**.

- **Scope**: [`Any file`](#scopes). A value in `~/.claude.json` from an older version applies when no settings file sets it.
- **Type**: Boolean
  - `true`: you see the turn duration message after each response
  - `false`: Claude Code hides the turn duration message
- **Default**: `true`

settings.json

```python
{
  "showTurnDuration": false
}
```


[​](#spellcheck)

`spellcheck`

Underline misspelled words in the prompt input as you type, using a spell checker you install. Claude Code checks only the text in the input box. [Check spelling as you type](interactive-mode.md#check-spelling-as-you-type) covers installing aspell, hunspell, or ispell and what the checker covers. Requires Claude Code v2.1.235 or later.

- **Scope**: [`User or managed`](#scopes). The block from the highest tier that sets it applies as a whole.
- **Type**: object with `enabled` (Boolean), `checker` (`"aspell"`, `"hunspell"`, `"ispell"`, or `"auto"`), `language` (string, passed to the checker as its dictionary name), and `color` (string, a terminal color name, `#rrggbb`, `rgb(r,g,b)`, `ansi256(n)`, or `ansi:<name>`)
- **Default**: unset, so spell checking is off; `checker` defaults to `"auto"`, the first of the three found on `PATH`; `language` defaults to the checker’s own dictionary; `color` defaults to the theme’s error color

settings.json

```python
{
  "spellcheck": { "enabled": true, "language": "en_GB" }
}
```


[​](#spinnertipsenabled)

`spinnerTipsEnabled`

While Claude works, the spinner line rotates through short tips about Claude Code features, such as “Use Plan Mode to prepare for a complex request before making changes. Press Shift+Tab twice to enable.” Set this key to `false` to hide them. Appears in `/config` as **Show tips**.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: you see tips in the spinner while Claude is working
  - `false`: Claude Code hides spinner tips
- **Default**: `true`

settings.json

```python
{
  "spinnerTipsEnabled": false
}
```


[​](#spinnertipsoverride)

`spinnerTipsOverride`

Add your own tips to the [spinner tips](#spinnertipsenabled) that Claude Code shows while Claude works, or replace the built-in tips with yours. Claude Code puts your tips in the same rotation as the built-in ones. If you set [`spinnerTipsEnabled`](#spinnertipsenabled) to `false`, Claude Code hides all tips, yours included.

- **Scope**: [`Any file`](#scopes). Claude Code honors tip objects, `tipsFile`, `label`, and `excludeDefault` from user settings, the `--settings` flag, and managed settings; from project and local settings it reads plain string tips only.
- **Type**: object with `tips`, `tipsFile`, `label`, and `excludeDefault` fields, each optional
- **Default**: unset, so Claude Code shows only the built-in tips

Tip objects, `tipsFile`, `label`, and the Scope line’s rule that project and local settings contribute plain strings only require Claude Code v2.1.247 or later. Each `tips` entry is a plain string or an object with these fields:

| Field              | Required | Description                                                                                                                                                                                                |
|:-------------------|:---------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id`               | Yes      | Up to 64 letters, digits, `.`, `_`, or `-`. Claude Code keys the tip’s show history on it, so the tip’s cooldown survives reordering the list. Of two entries with the same id, Claude Code uses the first |
| `text`             | Yes      | The tip, one line of up to 500 characters. Claude Code strips ANSI escapes and control characters and collapses whitespace                                                                                 |
| `cooldownSessions` | No       | Sessions Claude Code waits before showing the tip again, `0` to `1000`, default `0`                                                                                                                        |
| `priority`         | No       | Order among tips that have gone unshown equally long, higher first, `-10` to `10`, default `0`                                                                                                             |

Claude Code reads a plain string as a tip with those defaults and a position-based id, so its show history resets when you reorder the list. Give a tip an `id` to keep its history across edits. Claude Code reads at most 200 tips across `tips` and `tipsFile`, and drops an invalid entry with a debug warning instead of rejecting the settings file. Use the remaining fields to name a tips file, set the prefix, and hide the built-in tips:

- `tipsFile`: an absolute or `~/` path to a local JSON file holding an array of the same entries, or an object with a `tips` array, up to 256 KB. Claude Code reads the file once per process, so it loads your edits at the next start. You can’t set it through [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md); deploy inline `tips` there, or deploy the path in an on-disk `managed-settings.json`.
- `label`: the prefix Claude Code shows before tips from user, `--settings`, and managed settings, up to 40 characters. The default is `Tip`, the same prefix as the built-in tips, and tips from project and local settings always use it.
- `excludeDefault`: set it to `true` to hide the built-in tips and show only yours. When Claude Code can’t load any of your tips, for example because `tipsFile` doesn’t exist or every entry is invalid, it keeps the built-in rotation instead of an empty spinner.

When more than one settings file sets the key, Claude Code shows tips from all of them and takes `tipsFile`, `label`, and `excludeDefault` from whichever of managed settings, the `--settings` flag, and user settings is the highest-precedence one that sets each. This example, in your user settings, adds a plain string tip and an object tip to the rotation under the `Acme tip` prefix:

settings.json

```python
{
  "spinnerTipsOverride": {
    "label": "Acme tip",
    "tips": [
      "Run /review before opening a PR",
      {
        "id": "gateway-errors",
        "text": "Seeing 5xx errors? Check the gateway status page first",
        "cooldownSessions": 5,
        "priority": 2
      }
    ]
  }
}
```

Each field in the example changes one thing about how Claude Code shows the tips:

- `label`: Claude Code shows both tips as `Acme tip: ...` instead of `Tip: ...`.
- The plain string: Claude Code gives it the defaults, so it can come up again in the very next session.
- `id`: Claude Code keys the second tip’s show history on `gateway-errors`, so its cooldown still applies after you add or reorder tips.
- `cooldownSessions`: after Claude Code shows the `gateway-errors` tip, it doesn’t show that tip again until five sessions later.
- `priority`: when the `gateway-errors` tip and another tip have gone unshown for the same number of sessions, for example when neither has been shown yet, Claude Code shows `gateway-errors` first. The plain string has the default priority, `0`.

While Claude works, Claude Code shows your tips in the spinner with your prefix, such as `Acme tip: Run /review before opening a PR`.


[​](#spinnerverbs)

`spinnerVerbs`

While a turn is in progress, the spinner shows a rotating verb such as “Accomplishing”, “Architecting”, or “Baking”. Use this key to add your own verbs to that rotation or replace the built-in list with yours.

- **Scope**: [`Any file`](#scopes)
- **Type**: object with a `verbs` array of strings and `mode`, one of:
  - `"append"`: Claude Code adds your verbs to the built-in set
  - `"replace"`: Claude Code shows only your verbs
- **Default**: unset, so Claude Code uses the built-in verbs

This example adds two verbs to the built-in set:

settings.json

```python
{
  "spinnerVerbs": {
    "mode": "append",
    "verbs": ["Pondering", "Crafting"]
  }
}
```

In `"replace"` mode with an empty `verbs` array, Claude Code keeps the built-in verbs.


[​](#statusline)

`statusLine`

Run your own command to render a [status line](statusline.md) below the prompt with context such as the model, cost, or git branch. Optional fields adjust spacing, add periodic re-runs, and hide the built-in vim mode indicator when your script renders `vim.mode` itself.

- **Scope**: [`Any file`](#scopes). When [`allowManagedHooksOnly`](#allowmanagedhooksonly) is on, or [`disableAllHooks`](#disableallhooks) is set outside managed settings, only the managed settings value runs.
- **Type**: object with `type` set to `"command"` and a `command` string, plus optional `padding` as a number of characters, `refreshInterval` as a number of seconds, minimum `1`, and `hideVimModeIndicator` as a Boolean
- **Default**: unset, so no status line

This example prints the model name and context usage, and adds two characters of horizontal spacing:

settings.json

```python
{
  "statusLine": {
    "type": "command",
    "command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'",
    "padding": 2
  }
}
```

The example needs [`jq`](https://jqlang.org/) installed and runs in a shell. For PowerShell and Git Bash equivalents, see [Windows configuration](statusline.md#windows-configuration); for the full setup, see [Manually configure a status line](statusline.md#manually-configure-a-status-line).


[​](#subagentstatusline)

`subagentStatusLine`

When Claude runs [subagents](../09-Agents-Patterns/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.

- **Scope**: [`Any file`](#scopes). When [`allowManagedHooksOnly`](#allowmanagedhooksonly) is on, or [`disableAllHooks`](#disableallhooks) is set outside managed settings, only the managed settings value runs.
- **Type**: object with `type` set to `"command"` and a `command` string
- **Default**: unset, so Claude Code renders the default rows

settings.json

```python
{
  "subagentStatusLine": {
    "type": "command",
    "command": "jq -c '.tasks[] | {id, content: \"\\(.name): \\(.tokenCount) tokens\"}'"
  }
}
```

See [Subagent status lines](statusline.md#subagent-status-lines).


[​](#syntaxhighlightingdisabled)

`syntaxHighlightingDisabled`

Claude Code colors code by language in the diffs, code blocks, and file previews it shows in the terminal, with its built-in highlighter; no plugin or language server is involved. 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.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code turns off syntax highlighting in diffs, code blocks, and file previews
  - `false`: Claude Code highlights syntax
- **Default**: `false`

settings.json

```python
{
  "syntaxHighlightingDisabled": true
}
```


[​](#terminalprogressbarenabled)

`terminalProgressBarEnabled`

Some terminals can show a progress indicator on the tab or in the taskbar for the program running in them. While Claude is working, Claude Code reports an in-progress state to the terminal, so you can see from another tab or window whether the session is still busy. The indicator stays visible after the turn ends while [background subagents](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) or [dynamic workflows](workflows.md) are still running, and clears once the session is idle. Claude Code reports it only in terminals that support the indicator: ConEmu, Ghostty 1.2.0 or later, and iTerm2 3.6.6 or later. Set this key to `false` to stop Claude Code from reporting it. Appears in `/config` as **Terminal progress bar**.

- **Scope**: [`Any file`](#scopes). A value in `~/.claude.json` from an older version applies when no settings file sets it.
- **Type**: Boolean
  - `true`: you see the terminal progress bar in terminals that support it
  - `false`: Claude Code hides the terminal progress bar
- **Default**: `true`

settings.json

```python
{
  "terminalProgressBarEnabled": false
}
```


[​](#terminaltitlefromrename)

`terminalTitleFromRename`

Claude Code sets your terminal tab’s title. By default it uses a title it generates from the conversation, and once you give the session a [name](sessions.md#name-your-sessions) with `/rename` or `--name`, the tab shows that name instead. Set this key to `false` to keep the generated title on the tab even after you name the session. The name itself still applies, so `/resume <name>` and the session picker find it.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: the terminal tab title shows the session name you set
  - `false`: the tab keeps the title Claude Code generates from your conversation
- **Default**: `true`

settings.json

```python
{
  "terminalTitleFromRename": false
}
```

To stop Claude Code from updating the terminal title at all, set [`CLAUDE_CODE_DISABLE_TERMINAL_TITLE`](env-vars.md) to `1` instead.


[​](#theme)

`theme`

Pick the color theme for the interface. Appears in `/config` as **Theme**.

- **Scope**: [`Any file`](#scopes). A value in `~/.claude.json` from an older version applies when no settings file sets it.
- **Type**: string, one of:
  - `"auto"`: matches your terminal’s light or dark background
  - `"dark"`: the dark theme
  - `"light"`: the light theme
  - `"dark-daltonized"`: the dark theme with colorblind-friendly colors
  - `"light-daltonized"`: the light theme with colorblind-friendly colors
  - `"dark-ansi"`: the dark theme using only your terminal’s ANSI color palette
  - `"light-ansi"`: the light theme using only your terminal’s ANSI color palette
  - `"custom:<slug>"` or `"custom:<plugin-name>:<slug>"`: a custom theme from `~/.claude/themes/` or a plugin
- **Default**: `"dark"`

settings.json

```python
{
  "theme": "light-daltonized"
}
```

See [Create a custom theme](terminal-config.md#create-a-custom-theme).


[​](#timeformat)

`timeFormat`

Choose how Claude Code writes the times it shows in the interface, such as the `done 6:05 PM` at the end of each turn duration message and the timestamps in the [transcript viewer](interactive-mode.md#transcript-viewer). To pick a preset, run `/config` and set **Time format**. Requires Claude Code v2.1.257 or later.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, one of:
  - `"auto"`: the same as unset; each time keeps its built-in format, which follows your locale on the turn duration message
  - `"12-hour"`: a 12-hour clock
  - `"24-hour"`: a 24-hour clock
  - `"24-hour-utc"`: a 24-hour clock in UTC with `Z` after the minutes, such as `18:05Z`; Claude Code ignores [`timeZone`](#timezone) for this preset
  - A strftime pattern such as `"%H:%M"`: Claude Code writes each time with the pattern. Any value that contains a `%` is a pattern, and any other value outside the presets counts as `"auto"`
- **Default**: `"auto"`

settings.json

```python
{
  "timeFormat": "24-hour"
}
```

`/config` offers only the presets, so to use a strftime pattern, add the key to a settings file. This example shows each time as a two-digit 24-hour clock:

settings.json

```python
{
  "timeFormat": "%H:%M"
}
```

The turn duration message and the transcript viewer then show times such as `18:05`. In the transcript viewer, the pattern is the whole timestamp, so add date directives when you want the date there. This example puts the date in front of the clock:

settings.json

```python
{
  "timeFormat": "%Y-%m-%d %H:%M"
}
```

The same surfaces then show times such as `2026-09-01 18:05`.


[​](#timezone)

`timeZone`

Show the times in the interface in a time zone other than your system’s. Set it to an [IANA time zone name](https://www.iana.org/time-zones), such as `"UTC"` or `"Europe/Dublin"`. The times that [`timeFormat`](#timeformat) controls then show in this zone. If `timeFormat` is `"24-hour-utc"`, times stay in UTC and Claude Code ignores this key. `/config` has no row for this key, so set it in a settings file. Requires Claude Code v2.1.257 or later.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, an IANA time zone name. When Claude Code doesn’t recognize the name, it uses your system time zone
- **Default**: unset, so times show in your system time zone

settings.json

```python
{
  "timeZone": "Europe/Dublin"
}
```


[​](#tui)

`tui`

Choose the terminal UI renderer. Use `"fullscreen"` for the flicker-free [alt-screen renderer](fullscreen.md) with virtualized scrollback, or `"default"` for the classic main-screen renderer. Running `/tui fullscreen` or `/tui default` writes this key for you.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, one of:
  - `"default"`: the classic main-screen renderer
  - `"fullscreen"`: the flicker-free alt-screen renderer with virtualized scrollback
- **Default**: unset, so Claude Code [picks the renderer for you](fullscreen.md#fullscreen-by-default)
- **Per-session overrides**: [`CLAUDE_CODE_NO_FLICKER`](env-vars.md) and [`CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN`](env-vars.md) take precedence over this key for one session: `CLAUDE_CODE_NO_FLICKER=1` turns fullscreen on, and `CLAUDE_CODE_NO_FLICKER=0` or `CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1` turns it off; when both are set, Claude Code turns it off

settings.json

```python
{
  "tui": "fullscreen"
}
```

Under tmux `-CC` or over SSH to Windows, Claude Code keeps the classic renderer unless you set `CLAUDE_CODE_NO_FLICKER=1`. Background sessions opened from [agent view](../09-Agents-Patterns/agent-view.md) always use the fullscreen renderer regardless of this setting.


[​](#verbose)

`verbose`

By default, the transcript collapses each tool call to a short summary, such as the command Claude ran and a line count of its output, and you press `Ctrl+O` to switch the whole transcript to the expanded view when you want the details. Set this key to `true` to show every tool call’s full input and output inline as it happens, which is useful when you’re debugging a hook, an MCP server, or a long shell command. Appears in `/config` as **Verbose output**.

- **Scope**: [`Any file`](#scopes). A value in `~/.claude.json` from an older version applies when no settings file sets it.
- **Type**: Boolean
  - `true`: you see full tool output
  - `false`: you see truncated summaries of tool output
- **Default**: `false`
- **Per-session overrides**: [`--verbose`](cli-reference.md#cli-flags) takes precedence over this key for one session

settings.json

```python
{
  "verbose": true
}
```

A [`viewMode`](#viewmode) value or a sticky `/focus` selection overrides this key every session.


[​](#viewmode)

`viewMode`

Set the transcript view Claude Code starts in: `"default"`, `"verbose"`, or `"focus"`. When set, it overrides both the sticky `/focus` selection and the [`verbose`](#verbose) setting.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, one of:
  - `"default"`: the normal transcript with truncated tool output
  - `"verbose"`: the transcript with full tool output
  - `"focus"`: only your last prompt, a one-line summary of tool calls with edit diffstats, and the final response. Focus view needs the [fullscreen renderer](#tui)
- **Default**: unset, so the `verbose` setting and your last `/focus` choice apply
- **Per-session overrides**: [`--verbose`](cli-reference.md#cli-flags) takes precedence over this key for one session

settings.json

```python
{
  "viewMode": "focus"
}
```


[​](#viminsertmoderemaps)

`vimInsertModeRemaps`

Map two-key INSERT-mode sequences to Escape in [vim editor mode](interactive-mode.md#vim-editor-mode). Each key is exactly two printable characters typed in sequence, and `"<Esc>"` is the only supported target; Claude Code ignores other entries.

- **Scope**: [`User or managed`](#scopes). A repository can’t remap your keystrokes.
- **Type**: object mapping a two-character sequence to `"<Esc>"`
- **Default**: unset

settings.json

```python
{
  "vimInsertModeRemaps": {
    "jj": "<Esc>"
  }
}
```

Has no effect unless `editorMode` is `"vim"`. See [Remap INSERT-mode key sequences](interactive-mode.md#remap-insert-mode-key-sequences).


[​](#voice)

`voice`

Turn on [voice dictation](voice-dictation.md) and choose how the dictation key behaves. Claude Code writes this object for you when you run `/voice`.

- **Scope**: [`Any file`](#scopes)
- **Type**: object with `enabled` as a Boolean, `autoSubmit` as a Boolean that applies in hold mode only, and `mode`, one of:
  - `"hold"`: you hold the dictation key while speaking and release it to stop
  - `"tap"`: you tap the key once to start recording and again to send
- **Default**: unset, so dictation is off; when `enabled` is `true` and `mode` is unset, Claude Code uses `"hold"`

This example turns dictation on and makes the key tap once to start recording and again to send:

settings.json

```python
{
  "voice": {
    "enabled": true,
    "mode": "tap"
  }
}
```

`autoSubmit` sends the prompt when you release the key in hold mode. Voice dictation requires a claude.ai account.


[​](#voiceenabled)

`voiceEnabled`

Deprecated since v2.1.92, when the [`voice`](#voice) object replaced it. Claude Code still reads it so older settings files keep working, but new configurations should set `voice.enabled`.

Turn voice dictation on with the single Boolean form that predates the `voice` object. When both are set, `voice.enabled` applies.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: voice dictation is on when you’re logged in with a claude.ai account and your organization’s policy allows voice, unless `voice.enabled` is set
  - `false`: voice dictation is off, unless `voice.enabled` is set
- **Default**: unset

settings.json

```python
{
  "voiceEnabled": true
}
```


[​](#wheelscrollaccelerationenabled)

`wheelScrollAccelerationEnabled`

Accelerate mouse-wheel scroll speed during fast scrolls in [fullscreen rendering](fullscreen.md#mouse-wheel-scrolling). Set it to `false` for a constant scroll rate per wheel notch.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code accelerates mouse-wheel scroll speed during fast scrolls
  - `false`: Claude Code scrolls at a constant rate per wheel notch
- **Default**: `true`

settings.json

```python
{
  "wheelScrollAccelerationEnabled": false
}
```


[​](#git-and-attribution)

Git and attribution

Control the attribution Claude Code adds to commits and pull requests and how it works with git.


[​](#attribution)

`attribution`

Customize the attribution Claude Code adds to git commits and pull requests. Commits get a [git trailer](https://git-scm.com/docs/git-interpret-trailers) such as `Co-Authored-By` by default; pull request descriptions get plain text. Set each part separately with the sub-keys below.

- **Scope**: [`Any file`](#scopes)
- **Type**: object with `commit` and `pr` strings and a `sessionUrl` Boolean, or `false` to hide all attribution. The `false` value requires Claude Code v2.1.281 or later; earlier versions reject it and [skip the whole user, project, or local settings file](settings.md#fix-a-broken-settings-file) that holds it
- **Default**: unset, so Claude Code uses the standard attribution shown under each sub-key

To hide all attribution, set `attribution` to `false`. In a settings file that earlier versions also read, set [`commit`](#attribution-commit) and [`pr`](#attribution-pr) to empty strings and [`sessionUrl`](#attribution-sessionurl) to `false` instead. This example replaces the commit attribution, removes pull request attribution, and drops the session link:

settings.json

```python
{
  "attribution": {
    "commit": "Generated with AI\n\nCo-Authored-By: AI <ai@example.com>",
    "pr": "",
    "sessionUrl": false
  }
}
```

Once you set `commit` or `pr`, Claude Code ignores the deprecated `includeCoAuthoredBy` setting and uses its default text for whichever of the two you left unset. Claude Code tells Claude that your own instructions about attribution, such as a CLAUDE.md or [memory](memory.md) rule, take precedence over these commit and PR lines, unless the line is set in [managed settings](../13-Enterprise-Admin/managed-settings.md).


[​](#includecoauthoredby)

`includeCoAuthoredBy`

Deprecated since v2.0.62, when [`attribution`](#attribution) replaced it. Claude Code still reads it, but new configurations should set `attribution`.

Use [`attribution`](#attribution) instead, which replaces this key and lets you change or hide the commit trailer, the pull request text, and the session link separately. Claude Code still honors `includeCoAuthoredBy: false` from settings files that predate `attribution`, but ignores it once you set `attribution.commit` or `attribution.pr`.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: the same as unset; Claude Code adds the commit trailer and the pull request attribution text
  - `false`: Claude Code omits both the commit trailer and the pull request attribution text, unless `attribution` sets `commit` or `pr`, in which case the [`attribution`](#attribution) rules apply
- **Default**: `true`

settings.json

```python
{
  "includeCoAuthoredBy": false
}
```

To hide all attribution, see [`attribution`](#attribution).


[​](#includegitinstructions)

`includeGitInstructions`

Claude Code gives Claude two git-related pieces of context: its built-in instructions for how to write commits and pull requests, in the Bash tool’s description, and a git status snapshot of your repository. The snapshot holds the current branch, the main branch, `git status` output, and recent commits. Claude Code reads it when a conversation starts. Set this key to `false` to leave both out, for example when you use your own git workflow skills.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code includes its built-in commit and pull request workflow instructions and the git status snapshot. Cloud sessions never include the snapshot
  - `false`: Claude Code leaves both out
- **Default**: `true`
- **Per-session overrides**: [`CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS`](env-vars.md) takes precedence over this key for one session

settings.json

```python
{
  "includeGitInstructions": false
}
```

If you replace the system prompt in [non-interactive mode](headless.md) or the Agent SDK, the session starts without the snapshot even when this key is `true`:

- **`-p` runs**: you replace the prompt when you pass [`--system-prompt`](cli-reference.md#system-prompt-flags) or `--system-prompt-file`. You also replace it when you run a custom agent with its own prompt, selected with [`--agent`](../09-Agents-Patterns/sub-agents.md#invoke-subagents-explicitly) or the [`agent`](#agent) setting. Outside [bare mode](headless.md#start-faster-with-bare-mode), to keep the snapshot, run without a custom agent and add your instructions with [`--append-system-prompt`](cli-reference.md#system-prompt-flags) instead of replacing the prompt.
- **[Agent SDK](../05-Agent-SDK/agent-sdk-modifying-system-prompts.md)**: you replace the prompt with a custom system prompt or a custom main-thread agent. If you set no system prompt, the SDK uses its minimal default and the session starts without the snapshot too. Outside [bare mode](headless.md#start-faster-with-bare-mode), to keep the snapshot, use the `claude_code` preset without a custom `agent`.


[​](#prurltemplate)

`prUrlTemplate`

Point the PR links Claude Code renders, in the footer badge and in tool-result summaries, at an internal code-review tool instead of `github.com`. Claude Code substitutes `{host}`, `{owner}`, `{repo}`, `{number}`, and `{url}` from the PR URL. [GitLab merge request](interactive-mode.md#gitlab-merge-requests) links on both surfaces keep their GitLab URL.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, a URL template using any of the five placeholders
- **Default**: unset

settings.json

```python
{
  "prUrlTemplate": "https://reviews.example.com/{owner}/{repo}/pull/{number}"
}
```

Claude Code applies the template only to the links it renders itself; a PR number Claude writes in a message, such as `#123`, stays as Claude wrote it. A URL that doesn’t have the `/pull/<number>` shape is left unchanged.


[​](#attribution-commit)

`attribution.commit`

Set the attribution text Claude Code adds to git commits, including any trailers. Set it to an empty string to hide commit attribution.

- **Scope**: [`Any file`](#scopes)
- **Type**: string
- **Default**: unset, so Claude Code adds `Co-Authored-By: <name> <noreply@anthropic.com>`. The name is the model in use when the commit is made, such as `Claude Sonnet 5`. When a [subagent](../09-Agents-Patterns/sub-agents.md) makes the commit, the trailer names the subagent’s model.
  - When Claude Code recognizes the model as a Claude model but can’t confirm its exact version, it writes `Claude` alone.
  - When it can’t match the model ID to any Claude model, such as a third-party model served through a custom [`ANTHROPIC_BASE_URL`](env-vars.md), it writes `Claude Code`.

This example replaces the default trailer with a custom line and a custom `Co-Authored-By` trailer:

settings.json

```python
{
  "attribution": {
    "commit": "Generated with AI\n\nCo-Authored-By: AI <ai@example.com>"
  }
}
```


[​](#attribution-pr)

`attribution.pr`

Set the attribution text Claude Code adds to pull request descriptions. Set it to an empty string to hide pull request attribution.

- **Scope**: [`Any file`](#scopes)
- **Type**: string
- **Default**: unset, so Claude Code adds `🤖 Generated with [Claude Code](https://claude.com/claude-code)`

settings.json

```python
{
  "attribution": {
    "pr": ""
  }
}
```


[​](#attribution-sessionurl)

`attribution.sessionUrl`

Choose whether Claude Code appends the claude.ai session link when it commits or opens a pull request from a [cloud](claude-code-on-the-web.md) or [Remote Control](remote-control.md) session. Claude Code adds the link as a `Claude-Session` trailer on commits and as a link in pull request descriptions. Set it to `false` to omit the link.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code appends the claude.ai session link when it commits or opens a pull request from a cloud or Remote Control session
  - `false`: Claude Code omits the link
- **Default**: `true`

settings.json

```python
{
  "attribution": {
    "sessionUrl": false
  }
}
```


[​](#hooks-and-automation)

Hooks and automation

Register hooks, restrict which hooks run, and control workflows. For hook events and payloads, see the [hooks reference](../07-Hooks/hooks.md).


[​](#allowedhttphookurls)

`allowedHttpHookUrls`

Limit which URLs [HTTP hooks](../07-Hooks/hooks.md#http-hook-fields) can target. When you define this key, Claude Code runs an HTTP hook only if its URL matches one of the patterns and blocks the rest without running them; an empty array blocks every HTTP hook.

- **Scope**: [`Any file`](#scopes). Arrays merge across settings files.
- **Type**: array of URL patterns, with `*` as a wildcard
- **Default**: unset, so any URL is allowed

This example allows any URL under `https://hooks.example.com/` and any `http://localhost` URL:

settings.json

```python
{
  "allowedHttpHookUrls": ["https://hooks.example.com/*", "http://localhost:*"]
}
```

Hostname matching is case-insensitive and treats `hooks.example.com.`, with the trailing dot that marks a fully qualified domain name, the same as `hooks.example.com`, which is how DNS treats them. The allowlist applies to hooks from every source, including managed settings. In the Agent SDK’s `managedSettings` option, Claude Code ignores this key when its list has entries, so pass the list in the SDK’s `settings` option instead. See [what each value does in parent settings](../13-Enterprise-Admin/claude-apps-gateway.md#how-hook-and-skill-keys-in-parent-settings-take-effect).


[​](#allowmanagedhooksonly)

`allowManagedHooksOnly`

Restrict hook execution to hooks your organization deploys.

- **Scope**: [`Managed`](#scopes)
- **Type**: Boolean
  - `true`: only managed hooks run, plus Agent SDK hooks and hooks from plugins your managed settings force-enable. See [What runs under `allowManagedHooksOnly`](#what-runs-under-allowmanagedhooksonly)
  - `false`: hooks from every settings scope and plugin run
- **Default**: unset, so hooks from every settings scope and plugin run

managed-settings.json

```python
{
  "allowManagedHooksOnly": true
}
```


[​](#what-runs-under-allowmanagedhooksonly)

What runs under `allowManagedHooksOnly`

When you set it to `true`, Claude Code changes which hooks and hook-like commands load:

- **Managed and SDK hooks run**: hooks from managed settings and hooks the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) registers in process
- **Force-enabled plugin hooks run**: hooks from plugins your managed settings force-enable through [`enabledPlugins`](#enabledplugins). Claude Code matches on the full `plugin@marketplace` ID, so a plugin with the same name from a different marketplace stays blocked. This lets you distribute vetted hooks through an organization marketplace while blocking everything else. A [mod](../08-Plugins-Skills/plugins-mods-overview.md) in such a plugin loads only when it [counts as your organization’s](../08-Plugins-Skills/plugins-mods-admin.md#install-your-organizations-mods)
- **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](../08-Plugins-Skills/plugins-mods-overview.md#mods-built-into-claude-code) keep running. To block only users’ mods, set [`allowManagedModsOnly`](../08-Plugins-Skills/plugins-mods-admin.md#set-options-on-the-built-in-guard) instead.
- **Command-sourced plugins are disabled**: Claude Code also disables plugins with a [`command` source](../08-Plugins-Skills/plugins-marketplace-reference.md#command-plugin-source), including plugins force-enabled in managed `enabledPlugins`, unless you set [`disableCommandPluginSources`](#disablecommandpluginsources) to `false` explicitly
- **Marketplace `headersHelper` commands are blocked**: Claude Code also blocks marketplace [`headersHelper` commands](../08-Plugins-Skills/plugins-host-marketplace.md#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
- **Status line and file suggestion narrow to managed settings**: Claude Code reads [`statusLine`](statusline.md), [`fileSuggestion`](#filesuggestion), and [`subagentStatusLine`](statusline.md#subagent-status-lines) from managed settings only, following the [status line and file suggestion gates](#status-line-and-file-suggestion-gates)

The [`/goal`](goal.md) command can’t run while this key is set, because it depends on hooks.


[​](#disableallhooks)

`disableAllHooks`

Turn off [hooks](../07-Hooks/hooks.md#disable-or-remove-hooks), any custom [status line](statusline.md), and any custom [file suggestion](#filesuggestion) command. Use it to turn all of these off temporarily without deleting them from your settings.

- **Scope**: [`Any file`](#scopes). Only managed settings can disable managed hooks.
- **Type**: Boolean
  - `true`: Claude Code turns off hooks, any custom status line, and any custom file suggestion command
  - `false`: hooks, the status line, and the file suggestion command run
- **Default**: unset, so hooks run

settings.json

```python
{
  "disableAllHooks": true
}
```

The reach depends on which file carries the key:

- **In managed settings**: Claude Code disables every configured hook, including managed ones, and keeps running the hooks the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) registers in process
- **In the Agent SDK’s `managedSettings` option**: Claude Code treats the key as `allowManagedHooksOnly: true`, so see [what runs under `allowManagedHooksOnly`](#what-runs-under-allowmanagedhooksonly) for which hooks stop. On a machine where an administrator deploys managed settings, Claude Code ignores this key unless the administrator [lets an embedding host add policy](../13-Enterprise-Admin/managed-settings.md#let-an-embedding-host-add-policy). Requires Claude Code v2.1.309 or later.
- **In any other settings file**: Claude Code disables user, project, local, and plugin hooks; managed hooks, Agent SDK hooks, and hooks from plugins force-enabled in managed [`enabledPlugins`](#enabledplugins) keep running

The key also stops [mods](../08-Plugins-Skills/plugins-mods-overview.md), which are plugins whose code registers hooks:

- **In managed settings**: the mods in every installed plugin stop, your organization’s included
- **In any other settings file**: the mods you installed stop, and [your organization’s mods](../08-Plugins-Skills/plugins-mods-admin.md#install-your-organizations-mods) keep running

Mods built into Claude Code keep running in both cases. Each has [its own switch](../08-Plugins-Skills/plugins-mods-overview.md#mods-built-into-claude-code). Keeping Agent SDK hooks running when managed settings set this key requires Claude Code v2.1.242 or later. The [`/goal`](goal.md) command can’t run while hooks are disabled, and the `/hooks` menu shows a notice instead of your hooks.


[​](#status-line-and-file-suggestion-gates)

Status line and file suggestion gates

Claude Code makes two decisions for `statusLine`, `fileSuggestion`, and `subagentStatusLine`, in this order:

- **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](permissions.md#what-runs-before-you-trust-a-folder)
- **Narrowed to managed settings**: when [`allowManagedHooksOnly`](#allowmanagedhooksonly) is set, when `disableAllHooks` is `true` outside managed settings after [settings precedence](../07-Hooks/hooks.md#disable-or-remove-hooks) applies, or when you start Claude Code with `--safe-mode`

Under narrowing, Claude Code runs a managed value if one is deployed. Otherwise it skips your value without warning: the status line is disabled, and `@` autocomplete falls back to the built-in file suggestion.


[​](#disableworkflows)

`disableWorkflows`

Turn off [dynamic workflows](workflows.md#turn-workflows-off) and the bundled workflow commands for everyone your settings reach, such as an organization through managed settings. To turn workflows on or off just for yourself, use [`enableWorkflows`](#enableworkflows) instead, which the **Dynamic workflows** toggle in `/config` writes to your user settings.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code turns off dynamic workflows and the bundled workflow commands for everyone your settings reach
  - `false`: the same as unset; whether workflows are on then follows [`enableWorkflows`](#enableworkflows) and your plan’s default
- **Default**: `false`
- **Per-session overrides**: [`CLAUDE_CODE_DISABLE_WORKFLOWS`](env-vars.md) turns workflows off for one session; whichever of the two turns them off, the other can’t turn them back on

settings.json

```python
{
  "disableWorkflows": true
}
```


[​](#enableworkflows)

`enableWorkflows`

Turn [dynamic workflows](workflows.md) on or off for yourself when your plan’s default isn’t what you want. Appears in `/config` as **Dynamic workflows**, which writes this key to your user settings and removes it again when you toggle back to your plan’s default. To turn workflows off for everyone from managed settings, use [`disableWorkflows`](#disableworkflows) instead.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code turns dynamic workflows on for you
  - `false`: Claude Code turns dynamic workflows off for you
- **Default**: unset, so workflows are on unless you’re on the Pro plan, where they’re off
- **Per-session overrides**: [`CLAUDE_CODE_DISABLE_WORKFLOWS`](env-vars.md) turns workflows off for one session, and `true` here can’t turn them back on while it’s set

settings.json

```python
{
  "enableWorkflows": true
}
```

[`disableWorkflows`](#disableworkflows) and your organization’s workflows policy also take precedence: `enableWorkflows: true` can’t turn workflows back on while any source turns workflows off. Claude Code hides the `/config` row while a source other than your user settings sets `enableWorkflows`, or sets `disableWorkflows` to `true`.


[​](#hooks)

`hooks`

Run your own commands, prompts, agents, HTTP requests, or MCP tools as [hooks](../07-Hooks/hooks.md) at points in Claude Code’s lifecycle, such as before a tool call or when a session starts; the [hooks reference](../07-Hooks/hooks.md#hook-events) lists every event, its payload, and its exit codes. Each event maps to a list of matcher groups, and each group lists the handlers to run when the matcher applies.

- **Scope**: [`Any file`](#scopes). Hooks merge across files rather than replacing each other, and hooks from managed settings can’t be removed from other files.
- **Type**: object keyed by [hook event](../07-Hooks/hooks.md#hook-events); each value is an array of `{ "matcher", "hooks" }` groups whose `hooks` entries have a `type` of `"command"`, `"prompt"`, `"agent"`, `"http"`, or `"mcp_tool"`
- **Default**: unset, so no hooks run

This example runs a script before every Bash tool call:

settings.json

```python
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command", "command": "~/.claude/hooks/check-bash.sh" }
        ]
      }
    ]
  }
}
```

For every event, matcher pattern, and handler field, see the [hooks reference](../07-Hooks/hooks.md#configuration). To turn hooks off, see [`disableAllHooks`](#disableallhooks); to limit hooks to the ones your organization deploys, see [`allowManagedHooksOnly`](#allowmanagedhooksonly).


[​](#httphookallowedenvvars)

`httpHookAllowedEnvVars`

An [HTTP hook](../07-Hooks/hooks.md#http-hook-fields) can put the value of an environment variable into a request header, for example an `Authorization: Bearer $HOOK_TOKEN` header, but only for variables the hook lists in its own `allowedEnvVars`. This key sets an outer limit on that list for every HTTP hook: a hook can use a variable only if both its own `allowedEnvVars` and this key name it. Use it to stop a hook from reading a secret it shouldn’t, even when the hook’s definition asks for it.

- **Scope**: [`Any file`](#scopes). Arrays merge across settings files.
- **Type**: array of environment variable names
- **Default**: unset, so each hook’s own `allowedEnvVars` list applies

This example limits header interpolation to `MY_TOKEN` and `HOOK_SECRET`:

settings.json

```python
{
  "httpHookAllowedEnvVars": ["MY_TOKEN", "HOOK_SECRET"]
}
```

The allowlist applies to hooks from every source, including managed settings. In the Agent SDK’s `managedSettings` option, Claude Code ignores this key when its list has entries, so pass the list in the SDK’s `settings` option instead. See [what each value does in parent settings](../13-Enterprise-Admin/claude-apps-gateway.md#how-hook-and-skill-keys-in-parent-settings-take-effect).


[​](#workflowkeywordtriggerenabled)

`workflowKeywordTriggerEnabled`

Choose whether typing the keyword `ultracode` in a prompt triggers a [dynamic workflow](workflows.md#ask-for-a-workflow-in-your-prompt). Set it to `false` to type the word without triggering one.

- **Scope**: [`Any file`](#scopes). Appears in `/config` as **Ultracode keyword trigger**.
- **Type**: Boolean
  - `true`: typing `ultracode` in a prompt triggers a dynamic workflow
  - `false`: you can type the word without triggering one
- **Default**: `true`

settings.json

```python
{
  "workflowKeywordTriggerEnabled": false
}
```

The `ultracode` effort setting, `/workflows`, and saved workflow commands are unaffected.


[​](#workflowsizeguideline)

`workflowSizeGuideline`

Set the [agent count Claude aims for](workflows.md#set-a-size-guideline) in the dynamic workflows it writes. Claude Code sends the value to Claude as advice, not an enforced cap: `"small"` asks for fewer than 5 agents, `"medium"` fewer than 10, and `"large"` fewer than 50. Choose `"small"` when you want to bound what a workflow spends. Requires Claude Code v2.1.219 or later.

- **Scope**: [`Any file`](#scopes). A value there takes precedence over the **Dynamic workflow size** choice in `/config`, which Claude Code stores in `~/.claude.json`, and Claude Code hides that row while a settings file sets the key.
- **Type**: string, one of:
  - `"unrestricted"`: no guideline, so Claude sizes the workflow to the task
  - `"small"`: Claude aims for fewer than 5 agents
  - `"medium"`: Claude aims for fewer than 10 agents
  - `"large"`: Claude aims for fewer than 50 agents
- **Default**: `"medium"`, or `"small"` when you’re signed in on a Pro plan with Claude Code v2.1.271 or later

settings.json

```python
{
  "workflowSizeGuideline": "small"
}
```

Requires Claude Code v2.1.219 or later; on v2.1.202 through v2.1.218, set the guideline in `/config` instead.


[​](#plugins-and-skills)

Plugins and skills

Enable plugins, register marketplaces, restrict which plugin sources an organization allows, and control which skills load. For installing and building plugins, see [Plugins](../08-Plugins-Skills/plugins.md).


[​](#disablebundledskills)

`disableBundledSkills`

Turn off the [skills](../08-Plugins-Skills/skills.md) and workflows included with Claude Code. Claude Code removes bundled skills and workflows entirely, while built-in commands such as `/init` stay typable but are hidden from the model.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code removes bundled skills and workflows and hides built-in commands such as `/init` from the model
  - `false`: bundled skills load
- **Default**: unset, so bundled skills load
- **Per-session overrides**: [`CLAUDE_CODE_DISABLE_BUNDLED_SKILLS`](env-vars.md) set to `1` turns bundled skills off for one session; whichever of the two turns them off, the other can’t turn them back on

settings.json

```python
{
  "disableBundledSkills": true
}
```

Skills from plugins, `.claude/skills/`, and `.claude/commands/` are unaffected. `/doctor` stays typable like the built-in commands; to hide it, set [`DISABLE_DOCTOR_COMMAND`](env-vars.md) instead.


[​](#disableskillshellexecution)

`disableSkillShellExecution`

Turn off inline shell execution for `` !`...` `` and ```` ```! ```` blocks in [skills](../08-Plugins-Skills/skills.md) and custom commands from user, project, plugin, or additional-directory sources. Claude Code replaces each command with `[shell command execution disabled by policy]` instead of running it.

- **Scope**: [`Any file`](#scopes). A `true` in managed settings can’t be overridden by `false` elsewhere.
- **Type**: Boolean
  - `true`: Claude Code replaces each inline shell command with `[shell command execution disabled by policy]` instead of running it
  - `false`: inline shell runs
- **Default**: unset, so inline shell runs

settings.json

```python
{
  "disableSkillShellExecution": true
}
```

Bundled skills and skills deployed through managed settings are unaffected.


[​](#skilloverrides)

`skillOverrides`

Hide or collapse a [skill](../08-Plugins-Skills/skills.md#override-skill-visibility-from-settings) without editing its `SKILL.md`. Claude Code applies the value under each skill’s name to the skill list Claude sees and to your `/` autocomplete.

- **Scope**: [`Any file`](#scopes). The `/skills` menu writes to `.claude/settings.local.json`.
- **Type**: object mapping skill name to one of:
  - `"on"`: Claude sees the skill and you can type `/name`
  - `"name-only"`: Claude sees the skill by name without its description
  - `"user-invocable-only"`: Claude doesn’t see the skill, but you can still type `/name`
  - `"off"`: Claude doesn’t see the skill and `/name` is hidden from autocomplete
- **Default**: unset, so every skill is `"on"`

This example lists `legacy-context` to Claude by name only and hides `deploy` from Claude and from `/` autocomplete:

settings.json

```python
{
  "skillOverrides": {
    "legacy-context": "name-only",
    "deploy": "off"
  }
}
```

Overrides don’t apply to plugin skills, which you manage through `/plugin`. In managed settings and files passed with `--settings`, a key on a bundled skill’s alias, such as `checkup` for `/doctor`, also applies to the skill; see [how alias keys combine with keys on the skill’s own name](../08-Plugins-Skills/skills.md#override-skill-visibility-from-settings).


[​](#syncclaudeaiskills)

`syncClaudeAiSkills`

Turn off the download of the [skills enabled for your claude.ai account](../08-Plugins-Skills/skills.md#how-synced-skills-behave). Claude Code downloads them into `~/.claude/skills/synced/` in [terminal sessions where you sign in with your claude.ai account](../08-Plugins-Skills/skills.md#where-synced-skills-load), interactive or non-interactive, and in Cowork and cloud sessions. Set `false` to stop that download and stop loading the skills it already synced. Claude Code honors only `false`: `true` is the same as unset and doesn’t turn syncing on where it’s otherwise off.

- **Scope**: [`User, local, or managed`](#scopes), and files passed with `--settings`. A repository can’t turn it off for you.
- **Type**: Boolean
  - `false`: Claude Code stops downloading synced skills and stops loading the ones already in `~/.claude/skills/synced/`. In user or managed settings, it also moves them to `~/.claude/skills/.trash/`
  - `true`: the same as unset
- **Default**: unset, so sessions signed in with your claude.ai account sync your skills

This example keeps a machine from downloading the account’s skills in any session:

settings.json

```python
{
  "syncClaudeAiSkills": false
}
```


[​](#syncclaudeaiplugins)

`syncClaudeAiPlugins`

Turn off the download of the [plugins enabled for your claude.ai account](../08-Plugins-Skills/plugins-loading.md#synced-plugins). Claude Code downloads them into `~/.claude/plugins/synced/` at the start of terminal sessions where you sign in with your claude.ai account and in Cowork sessions, and loads each one as `<name>@synced`. Set `false` to stop that download and stop loading the plugins it already synced. Claude Code honors only `false`: `true` is the same as unset and doesn’t turn syncing on where it’s otherwise off. Requires Claude Code v2.1.273 or later.

- **Scope**: [`User, local, or managed`](#scopes), and files passed with `--settings`. A repository can’t turn it off for you.
- **Type**: Boolean
  - `false`: Claude Code stops downloading synced plugins and stops loading the ones already in `~/.claude/plugins/synced/`. In user or managed settings, it also moves them to `~/.claude/plugins/.trash/`
  - `true`: the same as unset
- **Default**: unset, so sessions signed in with your claude.ai account sync your plugins

To turn off one synced plugin rather than all of them, set `"<name>@synced": false` in [`enabledPlugins`](#enabledplugins). This example keeps a machine from downloading the account’s plugins in any session:

settings.json

```python
{
  "syncClaudeAiPlugins": false
}
```


[​](#allowedchannelplugins)

`allowedChannelPlugins`

Choose which [channel](channels.md) plugins can push messages into sessions in your organization. When you set it, Claude Code uses your list in place of the default Anthropic allowlist; each entry names a plugin and the marketplace it comes from.

- **Scope**: [`Managed`](#scopes)
- **Type**: array of objects, each with `marketplace` and `plugin` strings. An entry can instead be a `"plugin@marketplace"` string such as `"telegram@claude-plugins-official"`, which Claude Code treats as the equivalent object. The string form requires Claude Code v2.1.267 or later; earlier versions reject the whole `allowedChannelPlugins` value when it contains one
- **Default**: unset, so Claude Code uses the default Anthropic allowlist

This example turns channels on and allows only the Telegram plugin from the official Anthropic marketplace:

managed-settings.json

```python
{
  "channelsEnabled": true,
  "allowedChannelPlugins": [
    { "marketplace": "claude-plugins-official", "plugin": "telegram" }
  ]
}
```

An empty array blocks every channel plugin. This key takes effect once channels pass the [`channelsEnabled`](#channelsenabled) gate for the account: on Team and Enterprise plans, and on Console accounts with managed settings, that means `channelsEnabled: true`. See [Restrict which channel plugins can run](channels.md#restrict-which-channel-plugins-can-run).


[​](#blockedmarketplaces)

`blockedMarketplaces`

Block plugin marketplace sources for your organization. Claude Code checks the blocklist on marketplace add and on plugin install, update, refresh, and auto-update, so a marketplace someone added before you set the policy can’t be used to fetch plugins either. Blocked sources are checked before download, so they never touch the filesystem. If you set this key in the [claude.ai admin console](../13-Enterprise-Admin/server-managed-settings.md), claude.ai also applies it when anyone in your organization adds a marketplace from a git repository on claude.ai, as [How restrictions work](../08-Plugins-Skills/plugins-org.md#restrict-what-users-can-install) describes.

- **Scope**: [`Managed`](#scopes)
- **Type**: array of marketplace source objects, in the same forms as [`strictKnownMarketplaces`](#allowed-source-types)
- **Default**: unset, so no marketplace is blocked

This example blocks one GitHub repository as a marketplace source:

managed-settings.json

```python
{
  "blockedMarketplaces": [
    { "source": "github", "repo": "untrusted/plugins" }
  ]
}
```

A `github` entry may use the [owner-wildcard form](#owner-wildcards) `"owner/*"` to block every repository under that GitHub owner, which requires Claude Code v2.1.223 or later. Add `{ "source": "skills-dir" }` to stop Claude Code loading [`@skills-dir` plugins](../08-Plugins-Skills/plugins-loading.md#plugins-shared-through-a-repository) from both `~/.claude/skills/` and a project’s `.claude/skills/`, without restricting any marketplace. See [Managed marketplace restrictions](../08-Plugins-Skills/plugins-org.md#restrict-what-users-can-install).


[​](#channelsenabled)

`channelsEnabled`

Allow [channels](channels.md) for your organization. On claude.ai Team and Enterprise plans, Claude Code blocks channels until you set this to `true`. For [Anthropic Console](authentication.md#claude-console-authentication) accounts that authenticate with an API key, channels are allowed by default. If your organization deploys managed settings, Claude Code blocks channels on those accounts too until you set this key to `true`.

- **Scope**: [`Managed`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code allows channels for your organization
  - `false`: the same as unset; whether channels are blocked depends on your plan, as the Default says
- **Default**: unset; channels are blocked on Team and Enterprise plans and on Console accounts with managed settings, and allowed on Pro and Max plans and on Console accounts without managed settings

managed-settings.json

```python
{
  "channelsEnabled": true
}
```

To restrict which plugins can register as channels once they’re enabled, set [`allowedChannelPlugins`](#allowedchannelplugins). See [Enterprise controls](channels.md#enterprise-controls).


[​](#disablecommandpluginsources)

`disableCommandPluginSources`

Block the [`command` plugin source](../08-Plugins-Skills/plugins-marketplace-reference.md#command-plugin-source), which installs a plugin by running a marketplace-declared command on the user’s machine. When you set it to `true`, Claude Code never runs the command, doesn’t install or update command-sourced plugins, and stops loading the ones already installed. Set it to `false` to allow them explicitly. Whenever it blocks command sources, whether you set it to `true` or leave it unset under [`allowManagedHooksOnly`](#allowmanagedhooksonly), it also blocks marketplace [`headersHelper` commands](../08-Plugins-Skills/plugins-host-marketplace.md#authenticate-archive-downloads), except for a marketplace that managed settings themselves declare. Requires Claude Code v2.1.229 or later, and the `headersHelper` block requires v2.1.238 or later.

- **Scope**: [`Managed`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code never runs the marketplace-declared command, doesn’t install or update command-sourced plugins, and stops loading the ones already installed
  - `false`: Claude Code allows command-sourced plugins explicitly
- **Default**: unset, so Claude Code follows [`allowManagedHooksOnly`](#allowmanagedhooksonly): an organization that restricts hook execution to managed settings gets command sources disabled too

managed-settings.json

```python
{
  "disableCommandPluginSources": true
}
```

Requires Claude Code v2.1.229 or later.


[​](#pluginsuggestionmarketplaces)

`pluginSuggestionMarketplaces`

Name the marketplaces whose plugins can appear as contextual install suggestions, in spinner tips and pinned at the top of the `/plugin` **Discover** tab. The built-in first-party frontend-design tip is unaffected. Suggestions come from each plugin’s `relevance` declaration in its marketplace entry.

- **Scope**: [`Managed`](#scopes)
- **Type**: array of marketplace names
- **Default**: unset, so no marketplace-declared suggestions surface

managed-settings.json

```python
{
  "pluginSuggestionMarketplaces": ["acme-corp-plugins"]
}
```

A name takes effect only when the marketplace is registered on the machine and its registered source is also declared in the same managed settings, either as the [`extraKnownMarketplaces`](#extraknownmarketplaces) entry for that name or as an entry of [`strictKnownMarketplaces`](#strictknownmarketplaces). Claude Code ignores a marketplace registered from a different source under an allowlisted name. The official marketplace is exempt from the source requirement: allowlisting its name alone suffices, since that name can only register from the official Anthropic source. See [Suggest plugins by context](../08-Plugins-Skills/plugins-relevance.md).


[​](#plugintrustmessage)

`pluginTrustMessage`

Add your organization’s own text to the plugin trust warning Claude Code shows before installation, for example to confirm that plugins from your internal marketplace are vetted.

- **Scope**: [`Managed`](#scopes)
- **Type**: string
- **Default**: unset, so Claude Code shows the standard warning alone

managed-settings.json

```python
{
  "pluginTrustMessage": "All plugins from our marketplace are approved by IT"
}
```


[​](#strictknownmarketplaces)

`strictKnownMarketplaces`

Restrict which plugin marketplace sources people in your organization can add and install plugins from. Claude Code enforces the allowlist on marketplace add and on plugin install, update, refresh, and auto-update, before any network or filesystem operation, so a marketplace someone added before you set the policy can’t be used to fetch plugins once its source no longer matches. Blocked users see an error naming the managed policy. If you set this key in the [claude.ai admin console](../13-Enterprise-Admin/server-managed-settings.md), claude.ai also applies it when anyone in your organization adds a marketplace from a git repository on claude.ai, as [How restrictions work](../08-Plugins-Skills/plugins-org.md#restrict-what-users-can-install) describes.

- **Scope**: [`Managed`](#scopes)
- **Type**: array of marketplace source objects; see [Allowed source types](#allowed-source-types)
- **Default**: unset, so users can add any marketplace. An empty array is a complete lockdown that blocks every marketplace source, including the official Anthropic marketplace

This example allows two GitHub repositories, one pinned to the `v2.0` ref, and one hosted `marketplace.json` URL:

managed-settings.json

```python
{
  "strictKnownMarketplaces": [
    { "source": "github", "repo": "acme-corp/approved-plugins" },
    { "source": "github", "repo": "acme-corp/security-tools", "ref": "v2.0" },
    { "source": "url", "url": "https://plugins.example.com/marketplace.json" }
  ]
}
```

You can also write this key as `allowedMarketplaces`; [Marketplace key aliases](#marketplace-key-aliases) describes how Claude Code treats the alias and which version accepts it. This key is a policy gate: it controls what users may add but registers nothing. To restrict and pre-register in one file, see [Combine with `extraKnownMarketplaces`](#combine-with-extraknownmarketplaces). For the user-facing view, see [Managed marketplace restrictions](../08-Plugins-Skills/plugins-org.md#restrict-what-users-can-install).


[​](#allowed-source-types)

Allowed source types

Each entry below shows one allowlist entry per source type and the fields it accepts. Most types match exactly; `hostPattern` and `pathPattern` match by regex, and `github` entries can use an [owner wildcard](#owner-wildcards).

| Source        | Example entry                                                                                                                   | Fields                                                                                                                              |
|:--------------|:--------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------|
| `github`      | `{ "source": "github", "repo": "acme-corp/plugins", "ref": "main", "path": "marketplace" }`                                     | `repo` required; `ref` is a branch or tag; `path` is a subdirectory                                                                 |
| `git`         | `{ "source": "git", "url": "https://gitlab.example.com/tools/plugins.git", "ref": "production" }`                               | `url` required; `ref` and `path` as for `github`                                                                                    |
| `url`         | `{ "source": "url", "url": "https://plugins.example.com/marketplace.json", "headers": { "Authorization": "Bearer ${TOKEN}" } }` | `url` required; `headers` adds HTTP headers for authenticated access                                                                |
| `file`        | `{ "source": "file", "path": "/opt/acme-corp/plugins/marketplace.json" }`                                                       | `path` required, the absolute path to a `marketplace.json` file                                                                     |
| `directory`   | `{ "source": "directory", "path": "/opt/acme-corp/approved-marketplaces" }`                                                     | `path` required, the absolute path to a directory containing `.claude-plugin/marketplace.json`                                      |
| `hostPattern` | `{ "source": "hostPattern", "hostPattern": "^github\\.example\\.com$" }`                                                        | `hostPattern` required, a regex matched anywhere in the marketplace host; anchor it with `^` and `$` to match the whole host        |
| `pathPattern` | `{ "source": "pathPattern", "pathPattern": "^/opt/approved/" }`                                                                 | `pathPattern` required, a regex matched anywhere in the `path` of `file` and `directory` sources; start it with `^` to pin a prefix |
| `skills-dir`  | `{ "source": "skills-dir" }`                                                                                                    | No fields                                                                                                                           |

Some source types carry rules beyond the table:

- **`url`**: a URL marketplace downloads only the `marketplace.json` file, and Claude Code doesn’t fetch plugin files by relative path from that server, so its plugins must use a [plugin source](../08-Plugins-Skills/plugins-marketplace-reference.md#plugin-sources) other than a relative path, such as an archive URL, which can be on the same host. For plugins with relative paths, use a Git-based marketplace instead. See [Plugins with relative paths fail in URL-based marketplaces](../08-Plugins-Skills/plugins-troubleshooting.md#plugins-with-relative-paths-fail-in-url-based-marketplaces).
- **`hostPattern`**: use it to allow every marketplace on an internal GitHub Enterprise or GitLab server without listing each repository. Claude Code matches `github` sources against `github.com`, takes the hostname from `url` sources, and takes it from `git` sources depending on the [git URL](https://git-scm.com/docs/git-clone#_git_urls)’s form:
  - A URL with a scheme, such as `https://` or `ssh://`: the hostname in the URL.
  - An SSH address without a scheme, in git’s `user@host:path` form, such as `git@git.example.com:tools/plugins.git`: the host between `@` and `:`, which is the host git connects to.
  - Any other form without a scheme: no host, so no `strictKnownMarketplaces` `hostPattern` entry matches it. For a `blockedMarketplaces` `hostPattern`, Claude Code takes a host from a wider set of forms, so a blocklist entry can still match such a form. Before v2.1.234, a `strictKnownMarketplaces` `hostPattern` also matched some forms that git doesn’t treat as SSH addresses.

  `file` and `directory` sources have no host and never match a `hostPattern` entry.
- **`pathPattern`**: use it to allow filesystem marketplaces alongside `hostPattern` entries for network sources. `".*"` allows every local path; a narrower pattern such as `"^/opt/approved/"` restricts to a directory.
- **`skills-dir`**: any allowlist, even an empty one, stops Claude Code loading [`@skills-dir` plugins](../08-Plugins-Skills/plugins-loading.md#plugins-shared-through-a-repository) from both `~/.claude/skills/` and a project’s `.claude/skills/`. To keep loading them, add the `{ "source": "skills-dir" }` entry and leave [`strictPluginOnlyCustomization`](#strictpluginonlycustomization) unset. The entry has no meaning outside this key and `blockedMarketplaces`.


[​](#owner-wildcards)

Owner wildcards

A `github` entry whose `repo` value is `"<owner>/*"` matches every repository under that GitHub owner. Owner wildcards require Claude Code v2.1.223 or later and work only in `strictKnownMarketplaces` and `blockedMarketplaces`. Everywhere else a `github` source appears, such as `extraKnownMarketplaces` or `/plugin marketplace add`, the `repo` value must name a single repository. Before v2.1.223, Claude Code compared the entry literally, so an allowlist entry matched no repository and a blocklist entry blocked nothing; single-repository entries are enforced on every version. This entry allows any marketplace repository in the `acme-corp` organization:

managed-settings.json

```python
{
  "strictKnownMarketplaces": [
    { "source": "github", "repo": "acme-corp/*" }
  ]
}
```

Only the whole repository-name position can be a wildcard. Claude Code ignores entries such as `*`, `*/plugins`, or `acme-corp/tools-*` as invalid, so they match no repository. The matching rules differ between the two settings:

| Rule                      | `strictKnownMarketplaces`                                                                                                                                             | `blockedMarketplaces`                                                           |
|---------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------|
| Matching source spellings | `owner/repo` form only. A git URL that clones the same repository doesn’t match                                                                                       | Any spelling, including git URLs that resolve to the same github.com repository |
| Owner case                | Case-sensitive                                                                                                                                                        | Case-insensitive                                                                |
| `ref`                     | Follows the exact-entry rules: an entry with a `ref` matches only sources with that exact ref, and an entry without one matches only sources that don’t specify a ref | An entry without a `ref` blocks all refs of the repositories it matches         |
| `path`                    | Looser than the exact-entry rules: an entry with a `path` requires that exact value, while an entry without one matches any path inside the repository                | An entry without a `path` blocks all paths of the repositories it matches       |


[​](#exact-matching)

Exact matching

For every source type except owner-wildcard `github` entries and the regex-matched `hostPattern` and `pathPattern` entries, Claude Code allows a user’s addition only when the marketplace source matches an entry exactly. For the git-based sources `github` and `git`, exact matching includes the optional fields:

- The `repo` or `url` must match exactly
- The `ref` field must match exactly, or both must be undefined
- The `path` field must match exactly, or both must be undefined

For example, Claude Code treats each pair below as two different sources:

- `{ "source": "github", "repo": "acme-corp/plugins" }` and `{ "source": "github", "repo": "acme-corp/plugins", "ref": "main" }`
- `{ "source": "github", "repo": "acme-corp/plugins", "path": "marketplace" }` and `{ "source": "github", "repo": "acme-corp/plugins" }`


[​](#allow-only-the-official-marketplace)

Allow only the official marketplace

To allow the official Anthropic marketplace and nothing else, list its repository:

managed-settings.json

```python
{
  "strictKnownMarketplaces": [
    { "source": "github", "repo": "anthropics/claude-plugins-official" }
  ]
}
```

With this entry, Claude Code keeps an already-registered official marketplace available and, on a fresh machine, registers the marketplace automatically the first time you start an interactive terminal session. Automatic registration most commonly misses:

- Non-interactive environments that run before the machine’s first interactive terminal session.
- Machines where Claude Code has only run through the VS Code extension.
- Machines where Claude Code already ran an interactive terminal session under a policy that blocked the marketplace, such as the empty-array lockdown. Claude Code records the blocked attempt and doesn’t retry after the policy changes.

On these machines, add the marketplace to [`extraKnownMarketplaces`](#extraknownmarketplaces) in the same `managed-settings.json` so Claude Code registers it automatically, or run `claude plugin marketplace add anthropics/claude-plugins-official`.


[​](#combine-with-extraknownmarketplaces)

Combine with `extraKnownMarketplaces`

The two keys do different jobs. This table compares them:

| Aspect            | `strictKnownMarketplaces`                | `extraKnownMarketplaces`                                                                             |
|-------------------|------------------------------------------|------------------------------------------------------------------------------------------------------|
| Purpose           | Organizational policy enforcement        | Team convenience                                                                                     |
| Settings file     | Managed settings only                    | Any settings file                                                                                    |
| Behavior          | Blocks non-allowlisted additions         | Registers missing marketplaces                                                                       |
| When enforced     | Before network and filesystem operations | Immediately from user or managed settings; after the workspace trust dialog for a repository’s files |
| Can be overridden | No, highest precedence                   | Yes, by higher-precedence settings                                                                   |
| Source format     | Direct source object                     | Named marketplace with a nested `source` object                                                      |

To both restrict and pre-register a marketplace for all users, set both in `managed-settings.json`:

managed-settings.json

```python
{
  "strictKnownMarketplaces": [
    { "source": "github", "repo": "acme-corp/plugins" }
  ],
  "extraKnownMarketplaces": {
    "acme-tools": {
      "source": { "source": "github", "repo": "acme-corp/plugins" }
    }
  }
}
```

With only `strictKnownMarketplaces` set, users can still add an allowed marketplace themselves with `/plugin marketplace add`. The official Anthropic marketplace is the only one Claude Code registers automatically, and only when the allowlist allows it. [Allow only the official marketplace](#allow-only-the-official-marketplace) lists the machines it misses.


[​](#strictpluginonlycustomization)

`strictPluginOnlyCustomization`

Block skills, agents, hooks, and MCP servers from user and project sources, so they can come only from plugins or managed settings. Combine it with [`strictKnownMarketplaces`](#strictknownmarketplaces) to control the full customization supply chain: the marketplace allowlist controls which plugins users can install.

- **Scope**: [`Managed`](#scopes)
- **Type**: `true` to lock all four kinds of customization, or an array naming the kinds to lock, from `"skills"`, `"agents"`, `"hooks"`, and `"mcp"`
- **Default**: unset, so nothing is locked

This example locks skills and hooks and leaves agents and MCP servers unlocked:

managed-settings.json

```python
{
  "strictPluginOnlyCustomization": ["skills", "hooks"]
}
```

If you lock any surface, Claude Code also stops loading [skills-directory plugins](../08-Plugins-Skills/plugins-loading.md#skills-directory-plugins-blocked-by-managed-settings), the plugin folders that users keep under `~/.claude/skills/` or `.claude/skills/`. Users place those folders themselves rather than installing them from a marketplace, so Claude Code treats them as user customization under this setting. The four sub-key entries below list what else each surface blocks and what still loads. Claude Code ignores surface names it doesn’t recognize rather than failing the settings file, so you can add new surface names before every client has updated.


[​](#strictpluginonlycustomization-skills)

`strictPluginOnlyCustomization.skills`

Lock the `skills` surface. Claude Code stops loading skills from `~/.claude/skills/` and `.claude/skills/`, custom commands from `~/.claude/commands/` and `.claude/commands/`, skills and commands under `--add-dir` directories, and skills synced from your claude.ai account. It keeps loading bundled skills, skills in the managed policy directory, and skills from plugins other than [skills-directory plugins](../08-Plugins-Skills/plugins-loading.md#skills-directory-plugins-blocked-by-managed-settings).

- **Scope**: [`Managed`](#scopes)
- **Type**: the string `"skills"` in the [`strictPluginOnlyCustomization`](#strictpluginonlycustomization) array
- **Default**: not locked

managed-settings.json

```python
{
  "strictPluginOnlyCustomization": ["skills"]
}
```


[​](#strictpluginonlycustomization-agents)

`strictPluginOnlyCustomization.agents`

Lock the `agents` surface. Claude Code stops loading agents from `~/.claude/agents/`, `.claude/agents/`, and `--add-dir` directories. It keeps loading built-in agents, agents in the managed policy directory, and agents from plugins other than [skills-directory plugins](../08-Plugins-Skills/plugins-loading.md#skills-directory-plugins-blocked-by-managed-settings).

- **Scope**: [`Managed`](#scopes)
- **Type**: the string `"agents"` in the [`strictPluginOnlyCustomization`](#strictpluginonlycustomization) array
- **Default**: not locked

managed-settings.json

```python
{
  "strictPluginOnlyCustomization": ["agents"]
}
```


[​](#strictpluginonlycustomization-hooks)

`strictPluginOnlyCustomization.hooks`

Lock the `hooks` surface:

- **Stops running**:
  - Hooks from user, project, and local `settings.json`
  - Frontmatter hooks in skills, custom commands, and agents, from the sources that a [`skills`](#strictpluginonlycustomization-skills) or [`agents`](#strictpluginonlycustomization-agents) lock would block
- **Keeps running**: hooks in managed settings, and hooks from plugins other than [skills-directory plugins](../08-Plugins-Skills/plugins-loading.md#skills-directory-plugins-blocked-by-managed-settings)

Skills, custom commands, and agents whose frontmatter hooks stop running still load while their own surface isn’t locked. A personal or project [skill](../08-Plugins-Skills/skills.md#where-skills-live) that declares `hooks` in its frontmatter also loses its [`allowed-tools`](../08-Plugins-Skills/skills.md#pre-approve-tools-for-a-skill) pre-approval, so your users get permission prompts for the tools that field lists. When such a skill runs in a subagent through [`context: fork`](../08-Plugins-Skills/skills.md#run-skills-in-a-subagent), it keeps the pre-approval. A skill that declares no `hooks` keeps its pre-approval too.

- **Scope**: [`Managed`](#scopes)
- **Type**: the string `"hooks"` in the [`strictPluginOnlyCustomization`](#strictpluginonlycustomization) array
- **Default**: not locked

managed-settings.json

```python
{
  "strictPluginOnlyCustomization": ["hooks"]
}
```


[​](#strictpluginonlycustomization-mcp)

`strictPluginOnlyCustomization.mcp`

Lock the `mcp` surface. Claude Code stops loading MCP servers from `~/.claude.json` and `.mcp.json`. It keeps loading [`managed-mcp.json`](../06-MCP-Tools/General/managed-mcp.md) servers, servers from [`managedMcpServers`](#managedmcpservers), and MCP servers from plugins other than [skills-directory plugins](../08-Plugins-Skills/plugins-loading.md#skills-directory-plugins-blocked-by-managed-settings).

- **Scope**: [`Managed`](#scopes)
- **Type**: the string `"mcp"` in the [`strictPluginOnlyCustomization`](#strictpluginonlycustomization) array
- **Default**: not locked

managed-settings.json

```python
{
  "strictPluginOnlyCustomization": ["mcp"]
}
```


[​](#enabledplugins)

`enabledPlugins`

Turn individual [plugins](../08-Plugins-Skills/plugins.md) on or off, keyed by `plugin-name@marketplace-name`. A plugin with no entry at any scope falls back to its [`defaultEnabled`](../08-Plugins-Skills/plugins-reference.md#fields) value. When you enable or disable a plugin with `/plugin` or `claude plugin enable`, Claude Code writes this key for you.

- **Scope**: [`Any file`](#scopes)
- **Type**: object mapping `plugin-name@marketplace-name` to a Boolean
- **Default**: unset, so each plugin follows its `defaultEnabled` value

This example enables two plugins from the `team-tools` marketplace and disables one from `personal`:

settings.json

```python
{
  "enabledPlugins": {
    "code-formatter@team-tools": true,
    "deployment-tools@team-tools": true,
    "experimental-features@personal": false
  }
}
```

Each scope serves a different purpose:

- **User settings**: your personal plugin preferences
- **Project settings**: plugins shared with everyone in the repository
- **Local settings**: per-machine overrides, gitignored when Claude Code saves a setting there
- **Managed settings**: organization-wide policy. A plugin set to `false` here is blocked from installation at every scope and hidden from the marketplace

Project settings take precedence over user settings, so setting a plugin to `false` in `~/.claude/settings.json` doesn’t disable a plugin that the project’s `.claude/settings.json` enables. To opt out of a project-enabled plugin on your machine, set it to `false` in `.claude/settings.local.json` instead. Plugins force-enabled by managed settings can’t be disabled this way, since managed settings override local settings. Enabling a plugin from an external source such as a GitHub repository or npm package in a project’s `.claude/settings.json` doesn’t install it for other people. On every path that loads plugins, Claude Code reports the plugin as not installed until each user [installs it themselves](../08-Plugins-Skills/plugins-org.md#require-plugins-per-repository).


[​](#extraknownmarketplaces)

`extraKnownMarketplaces`

Register additional plugin marketplaces by name, so that people who open the repository, or everyone your managed settings reach, get the marketplace without adding it themselves. Claude Code registers each marketplace it doesn’t already know. Whether a plugin that [`enabledPlugins`](#enabledplugins) names from it installs depends on the plugin’s source and which file enables it; that entry has the rules.

- **Scope**: [`Any file`](#scopes). Claude Code honors entries in a repository’s `.claude/settings.json` or `.claude/settings.local.json` only after you accept the workspace trust dialog for that folder; in a folder you haven’t trusted, including a `-p` run there, it ignores them without a message.
- **Type**: object mapping a marketplace name to an object with a `source` object and an optional `autoUpdate` Boolean
- **Default**: unset

This example registers a GitHub marketplace and a marketplace from a self-hosted git URL:

settings.json

```python
{
  "extraKnownMarketplaces": {
    "acme-tools": {
      "source": {
        "source": "github",
        "repo": "acme-corp/claude-plugins"
      }
    },
    "security-plugins": {
      "source": {
        "source": "git",
        "url": "https://git.example.com/security/plugins.git"
      }
    }
  }
}
```

[What runs before you trust a folder](permissions.md#what-runs-before-you-trust-a-folder) compares the trust gate with the other content a repository can supply. You can also write this key as `additionalMarketplaces`; see [Marketplace key aliases](#marketplace-key-aliases). Set `"autoUpdate": true` alongside `source` to make Claude Code refresh that marketplace and update its installed plugins in the background after startup. When omitted, `claude-plugins-official` and most other official Anthropic marketplaces default to `true`, and third-party marketplaces default to `false`. See [Configure auto-updates](../08-Plugins-Skills/discover-plugins.md#keep-plugins-updated). When more than one settings file defines a marketplace entry under the same name, Claude Code uses the entry from the [highest-precedence file](settings.md#settings-precedence) whole. That entry replaces the lower-precedence entry and inherits none of its fields, so a redefinition can’t combine one file’s `source.headers` credential with a URL another file controls. Before v2.1.228, Claude Code merged same-name entries field by field, so an entry in a higher-precedence file could inherit fields it didn’t set, including another file’s `headers`.


[​](#marketplace-source-types)

Marketplace source types

The `source` object takes one of these forms:

- **`github`**: a GitHub repository, with `repo`
- **`git`**: any git URL, with `url`
- **`url`**: a direct URL to a `marketplace.json` file, with `url` and optional `headers` and `headersHelper` for authenticated access. `headersHelper` names a command that prints headers whose values are too short-lived to list in `headers`, and requires Claude Code v2.1.238 or later
- **`file`**: a local path to a `marketplace.json` file, with `path`
- **`directory`**: a local filesystem path, with `path`. Use it for development, or for a marketplace your organization [deploys to each machine](../08-Plugins-Skills/plugins-mods-admin.md#install-your-organizations-mods).
- **`settings`**: an inline marketplace declared directly in the settings file without a hosted repository, with `name` and `plugins`

The `git` source type works with any git hosting service, including self-hosted GitLab and Bitbucket. Claude Code clones the repository with the same authentication that `git clone` would use on that machine: configured credential helpers or SSH keys. A provider token such as `GITHUB_TOKEN` takes effect through a credential helper that reads it. See [Private repositories](../08-Plugins-Skills/plugins-host-marketplace.md#grant-access-to-a-private-marketplace) for setup details. For `github` and `git` sources, Claude Code never downloads [Git LFS](https://git-lfs.com) content when it clones the marketplace repository to add or update it. LFS-tracked files are checked out as pointer files, and the add or update output reports how many. The `skipLfs` field inside the `source` object is accepted and has no effect. Before v2.1.274, Claude Code downloaded LFS content unless you set `"skipLfs": true`. For a `url` source, set `headersHelper` inside the `source` object when the credential in `headers` expires and a command has to produce a fresh one. Requires Claude Code v2.1.238 or later. For what the command must print and where Claude Code runs it, see [Write the headersHelper command](../08-Plugins-Skills/plugins-host-marketplace.md#write-the-headershelper-command), and for the cases where Claude Code doesn’t run it, see [When Claude Code skips a headersHelper command](../08-Plugins-Skills/plugins-host-marketplace.md#when-claude-code-skips-a-headershelper-command-or-drops-its-output). Once you set `headersHelper` on an `https://` marketplace URL, Claude Code runs the command at two points, reusing one run’s output for up to 60 seconds:

- Before each fetch of that marketplace’s `marketplace.json`, including a later refresh. Claude Code sends the printed headers with that fetch.
- Before each plugin archive download on the marketplace URL’s origin, meaning the same scheme, host, and port. Claude Code sends the output with that download, and no other download gets the headers.

Claude Code ignores any `headersHelper` set in the `.claude/settings.json` or `.claude/settings.local.json` of a directory you add with [`--add-dir`](permissions.md#what-runs-before-you-trust-a-folder), on a `url` source and on an inline plugin entry alike, and sends only the fixed `headers` set in that file. [How users accept a headersHelper command](../08-Plugins-Skills/plugins-host-marketplace.md#how-users-accept-a-headershelper-command) covers the other settings files. Plugins listed in a `settings` source must reference external sources such as GitHub or npm, and the `name` must match the marketplace key. You still enable each plugin separately in `enabledPlugins`. This example declares one plugin inline:

settings.json

```python
{
  "extraKnownMarketplaces": {
    "team-tools": {
      "source": {
        "source": "settings",
        "name": "team-tools",
        "plugins": [
          {
            "name": "code-formatter",
            "source": {
              "source": "github",
              "repo": "acme-corp/code-formatter"
            }
          }
        ]
      }
    }
  }
}
```

A plugin entry under `source: 'settings'` whose own `source` is an [`archive`](../08-Plugins-Skills/plugins-marketplace-reference.md#archive-plugin-source) can set `headers` for the archive download. If the value you would put in `headers` is short-lived, such as a token your registry mints on request, set a `headersHelper` command instead. An entry may set both. Both fields require Claude Code v2.1.238 or later. Claude Code sends the entry’s `headers`, and whatever the command prints, with that plugin’s archive download and with no other download. Claude Code runs the command only when a user [installs or updates that one plugin by itself](../08-Plugins-Skills/plugins-host-marketplace.md#how-users-accept-a-headershelper-command). Three further rules depend on which file holds the entry:

- **`strict`**: unlike an entry in a marketplace’s `marketplace.json`, an entry in settings doesn’t need `"strict": false`, because a settings file carries no manifest fields to inline. See [Strict mode](../08-Plugins-Skills/plugins-marketplace-reference.md#strict-mode).
- **Folder trust**: for an entry in a project’s `.claude/settings.json` or `.claude/settings.local.json`, Claude Code runs the command only after the user has also [trusted that folder](permissions.md#what-runs-before-you-trust-a-folder).
- **Header filter**: Claude Code drops [request-routing and client-identity header names](../08-Plugins-Skills/plugins-host-marketplace.md#when-claude-code-skips-a-headershelper-command-or-drops-its-output) from an entry in a project’s `.claude/settings.json` or `.claude/settings.local.json`, because a repository can supply those files. Claude Code applies the same filter to a catalog entry and to an entry in an `--add-dir` directory’s settings, and no filter to an entry in your user settings, a `--settings` file, or managed settings.


[​](#marketplace-key-aliases)

Marketplace key aliases

On Claude Code v2.1.232 or later, you can write `extraKnownMarketplaces` as `additionalMarketplaces` and `strictKnownMarketplaces` as `allowedMarketplaces`. Claude Code treats each alias as follows:

- Earlier versions ignore the alias, so keep the canonical spelling in a file that older versions also read, such as a managed settings file for a fleet with mixed Claude Code versions.
- In any settings file that accepts the canonical key, Claude Code reads the alias exactly as it reads the canonical key.
- Claude Code may rewrite `additionalMarketplaces` to `extraKnownMarketplaces` when it updates the file.
- If you set both spellings in one file, Claude Code uses the canonical value and ignores the alias.


[​](#pluginconfigs)

`pluginConfigs`

Store the non-sensitive answers you give a plugin’s [`userConfig`](../08-Plugins-Skills/plugins-reference.md#user-configuration) configuration dialog, keyed by plugin ID. Claude Code writes this key to your user settings when you fill in the dialog, so you don’t need to edit it by hand. Claude Code stores sensitive options in the macOS Keychain instead, falling back to `~/.claude/.credentials.json` when the Keychain rejects the write; on platforms without a supported keychain, it stores them in `~/.claude/.credentials.json`.

- **Scope**: [`User or managed`](#scopes)
- **Type**: object mapping a plugin ID to an object with an `options` field, mapping each option name to a string, number, Boolean, or array of strings, and an optional `mcpServers` field holding per-server user configuration values in the same shape
- **Default**: unset

This example stores the `api_endpoint` option for the `deployer` plugin from `acme-tools`:

settings.json

```python
{
  "pluginConfigs": {
    "deployer@acme-tools": {
      "options": {
        "api_endpoint": "https://api.example.com"
      }
    }
  }
}
```

Built-in plugins store their options under the same key with an `@builtin` suffix. For example, the [**Project instructions**](memory.md#choose-which-instruction-files-load) setting that controls whether Claude Code reads `AGENTS.md` files is `pluginConfigs["cc-plugin-agents-md@builtin"].options.instructionFiles`. Before v2.1.285, the plugin’s ID was `agents-md@builtin`. Later versions read an entry under either ID. Claude Code ignores project and local entries because it substitutes these values into plugin hook, MCP, and LSP configurations, and a cloned repository must not be able to supply them.


[​](#prependplugins)

`prependPlugins`

List the managed plugins whose [mods](../08-Plugins-Skills/plugins-mods-overview.md) run before every mod a user installs, in the listed order. When you set this key in managed settings, name `sec-default@builtin` in the list to keep the built-in guard. In managed settings, Claude Code skips an id whose plugin doesn’t count as your organization’s. See [Install your organization’s mods and set the order](../08-Plugins-Skills/plugins-mods-admin.md#install-your-organizations-mods) for those conditions and for how the two ordering keys work together.

- **Scope**: [`User or managed`](#scopes). Claude Code reads the key from managed settings. It reads the key from user settings only on a machine with no managed settings, in a session whose credential isn’t a Team or Enterprise `/login`. It ignores the key in project and local settings and in a `--settings` file.
- **Type**: array of `plugin-name@marketplace-name` strings
- **Default**: unset

managed-settings.json

```python
{
  "extraKnownMarketplaces": {
    "acme-tools": {
      "source": { "source": "directory", "path": "/opt/acme/claude-plugins" }
    }
  },
  "enabledPlugins": { "acme-guard@acme-tools": true },
  "prependPlugins": ["acme-guard@acme-tools", "sec-default@builtin"]
}
```


[​](#appendplugins)

`appendPlugins`

List the managed plugins whose [mods](../08-Plugins-Skills/plugins-mods-overview.md) run after every mod a user installs, in the listed order. An id listed in both `prependPlugins` and `appendPlugins` is prepended. In managed settings, Claude Code skips an id whose plugin doesn’t [count as your organization’s](../08-Plugins-Skills/plugins-mods-admin.md#install-your-organizations-mods).

- **Scope**: [`User or managed`](#scopes). Claude Code reads the key from managed settings. It reads the key from user settings only on a machine with no managed settings, in a session whose credential isn’t a Team or Enterprise `/login`. It ignores the key in project and local settings and in a `--settings` file.
- **Type**: array of `plugin-name@marketplace-name` strings
- **Default**: unset

managed-settings.json

```python
{
  "extraKnownMarketplaces": {
    "acme-tools": {
      "source": { "source": "directory", "path": "/opt/acme/claude-plugins" }
    }
  },
  "enabledPlugins": { "acme-audit@acme-tools": true },
  "appendPlugins": ["acme-audit@acme-tools"]
}
```


[​](#mcp)

MCP

Control which MCP servers Claude Code connects to and which an organization allows. See [Connect to external tools with MCP](../06-MCP-Tools/General/mcp.md) and [Managed MCP configuration](../06-MCP-Tools/General/managed-mcp.md).


[​](#allowallclaudeaimcps)

`allowAllClaudeAiMcps`

Load the [claude.ai connectors](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) Claude Code fetches itself alongside a deployed `managed-mcp.json`. Without this key, `managed-mcp.json` takes exclusive control of MCP servers and suppresses those connectors.

- **Scope**: [`Managed`](#scopes). Users can’t re-enable connectors that exclusive control suppressed.
- **Type**: Boolean
  - `true`: Claude Code loads the claude.ai connectors alongside a deployed `managed-mcp.json`
  - `false`: a deployed `managed-mcp.json` takes exclusive control of MCP servers and suppresses the claude.ai connectors [Claude Code fetches itself](../06-MCP-Tools/General/mcp.md#how-connectors-reach-claude-code)
- **Default**: `false`, so a deployed `managed-mcp.json` suppresses the claude.ai connectors Claude Code fetches itself

managed-settings.json

```python
{
  "allowAllClaudeAiMcps": true
}
```

[`allowedMcpServers`](#allowedmcpservers) and [`deniedMcpServers`](#deniedmcpservers) still apply to the connectors this key loads. Connectors delivered to a [cloud session](claude-code-on-the-web.md) whose host carries a `managed-mcp.json`, such as a self-hosted runner, stay suppressed. See [Allow claude.ai connectors alongside the managed set](../06-MCP-Tools/General/managed-mcp.md#allow-claude-ai-connectors-alongside-the-managed-set).


[​](#allowclaudeinchromewithmanagedmcp)

`allowClaudeInChromeWithManagedMcp`

Let the built-in [Claude in Chrome](../03-IDE-Integrations/chrome.md) server run alongside a deployed `managed-mcp.json`. Without this key, a deployed `managed-mcp.json` blocks Claude in Chrome in terminal sessions. Requires Claude Code v2.1.282 or later.

- **Scope**: [`Managed`](#scopes), from the device’s own managed settings only: an MDM-deployed plist or HKLM registry key, or a system `managed-settings.json` file. Claude Code ignores it in server-managed settings, in the user-writable HKCU registry, and in user or project settings.
- **Type**: Boolean
  - `true`: the built-in Claude in Chrome server can run alongside a deployed `managed-mcp.json`
  - `false`: a deployed `managed-mcp.json` blocks Claude in Chrome in terminal sessions
- **Default**: `false`, so a deployed `managed-mcp.json` blocks Claude in Chrome in terminal sessions

managed-settings.json

```python
{
  "allowClaudeInChromeWithManagedMcp": true
}
```

A [`deniedMcpServers`](#deniedmcpservers) entry for `claude-in-chrome` still blocks the server with this key on. See [Allow Claude in Chrome alongside the managed set](../06-MCP-Tools/General/managed-mcp.md#allow-claude-in-chrome-alongside-the-managed-set).


[​](#allowedmcpservers)

`allowedMcpServers`

Allowlist the MCP servers people can add. Claude Code blocks any server that doesn’t match an entry wherever it’s defined, including plugin servers, servers a user passes with `--mcp-config`, and servers from claude.ai. Built-in servers such as Claude in Chrome, the `ide` server Claude Code connects to in a running [VS Code](../03-IDE-Integrations/vs-code.md#the-built-in-ide-mcp-server) or [JetBrains](../03-IDE-Integrations/jetbrains.md#the-built-in-ide-mcp-server) IDE, and servers the CLI itself configures are exempt from the allowlist, and the denylist still applies to them. On Claude Code v2.1.268 or later, a [Claude Tag](claude-tag.md) session’s Slack tools are also exempt from the allowlist, and the denylist still applies to them. In-process `type: "sdk"` servers are exempt from both lists; the [app that started the session](../06-MCP-Tools/General/mcp.md#how-connectors-reach-claude-code) registers them. Servers your organization delivers are also exempt from the allowlist, and the denylist still applies to them. The exemption covers every [`managedMcpServers`](#managedmcpservers) entry, and any [`managed-mcp.json`](../06-MCP-Tools/General/managed-mcp.md#exclusive-control-with-managed-mcp-json) entry whose values use [no `${VAR}` expansion outside `env`](../06-MCP-Tools/General/managed-mcp.md#how-allowlists-and-denylists-apply-to-the-managed-set). See [How a server is evaluated](../06-MCP-Tools/General/managed-mcp.md#how-a-server-is-evaluated) for the full check order. Before v2.1.259, servers from `managed-mcp.json` had to match too.

- **Scope**: [`Any file`](#scopes). Entries from every file merge into one allowlist unless [`allowManagedMcpServersOnly`](#allowmanagedmcpserversonly) is set. Deploy it in managed settings to enforce it.
- **Type**: array of objects, each with exactly one key. Use `serverName`, a string limited to letters, numbers, hyphens, and underscores; `serverCommand`, an array of the command and its arguments matched exactly; or `serverUrl`, a URL pattern with `*` wildcards
- **Default**: unset, so every server is allowed; an empty array blocks every server users add

This example allows only the stdio server that the listed `npx` command starts:

settings.json

```python
{
  "allowedMcpServers": [
    { "serverCommand": ["npx", "-y", "@modelcontextprotocol/server-filesystem"] }
  ]
}
```

A [`deniedMcpServers`](#deniedmcpservers) entry takes precedence, so a server on both lists is blocked. Once the list contains any `serverCommand` entry, a stdio server must match a `serverCommand` entry, and once it contains any `serverUrl` entry, a remote server must match a `serverUrl` entry: a `serverName` match no longer admits that kind of server. See [Policy-based control with allowlists and denylists](../06-MCP-Tools/General/managed-mcp.md#policy-based-control-with-allowlists-and-denylists).


[​](#allowmanagedmcpserversonly)

`allowManagedMcpServersOnly`

Make the managed allowlist the only one that applies. Claude Code then reads [`allowedMcpServers`](#allowedmcpservers) from managed settings alone and ignores allowlists in user, project, and local settings; [`deniedMcpServers`](#deniedmcpservers) still merges from every settings scope, so users can still block servers for themselves. Administrators set it so a user’s own settings can’t broaden what the managed allowlist permits.

- **Scope**: [`Managed`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code reads `allowedMcpServers` from managed settings alone and ignores allowlists in user, project, and local settings
  - `false`: allowlists from every settings scope merge
- **Default**: `false`, so allowlists from every settings scope merge

This example locks the allowlist to managed settings and allows only the server named `github`:

managed-settings.json

```python
{
  "allowManagedMcpServersOnly": true,
  "allowedMcpServers": [
    { "serverName": "github" }
  ]
}
```

Users can still add MCP servers of their own; only servers that match the managed allowlist load. See [Restrict the allowlist to managed settings only](../06-MCP-Tools/General/managed-mcp.md#restrict-the-allowlist-to-managed-settings-only).


[​](#deniedmcpservers)

`deniedMcpServers`

Block specific MCP servers. Claude Code refuses to load a matching server wherever it’s defined, including plugin servers, servers passed with `--mcp-config`, servers from `managed-mcp.json`, servers from [`managedMcpServers`](#managedmcpservers), and the claude.ai connectors [it fetches itself](../06-MCP-Tools/General/mcp.md#how-connectors-reach-claude-code). In-process `type: "sdk"` servers are exempt; the app that started the session registers them.

- **Scope**: [`Any file`](#scopes). Entries from every file merge into one denylist, and [`allowManagedMcpServersOnly`](#allowmanagedmcpserversonly) doesn’t change that. Deploy it in managed settings to enforce it.
- **Type**: array of objects, each with exactly one key: `serverName`, a string, so a claude.ai connector’s display name such as `"claude.ai Slack"` works; `serverCommand`, an array of the command and its arguments matched exactly; or `serverUrl`, a URL pattern with `*` wildcards
- **Default**: unset, so no server is blocked; an empty array also blocks nothing

settings.json

```python
{
  "deniedMcpServers": [
    { "serverName": "filesystem" }
  ]
}
```

The denylist takes precedence over [`allowedMcpServers`](#allowedmcpservers), so a server on both lists is blocked. See [Policy-based control with allowlists and denylists](../06-MCP-Tools/General/managed-mcp.md#policy-based-control-with-allowlists-and-denylists).


[​](#disableclaudeaiconnectors)

`disableClaudeAiConnectors`

Turn off the [claude.ai MCP connectors](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) [Claude Code fetches itself](../06-MCP-Tools/General/mcp.md#how-connectors-reach-claude-code), so it neither fetches nor connects them. A `true` in any settings file applies: a checked-in project `.claude/settings.json` can opt a repository out of those connectors, but a project-level `false` can’t override a user- or managed-level `true`.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code neither fetches nor connects those connectors
  - `false`: the same as unset; Claude Code fetches your connectors unless another settings file or `ENABLE_CLAUDEAI_MCP_SERVERS` turns them off
- **Default**: `false`, so Claude Code fetches your connectors
- **Per-session overrides**: [`ENABLE_CLAUDEAI_MCP_SERVERS`](env-vars.md) set to `false` turns connectors off for one session; whichever of the two turns them off, the other can’t turn them back on

settings.json

```python
{
  "disableClaudeAiConnectors": true
}
```

Servers you pass explicitly with `--mcp-config` are unaffected. To block individual connectors instead of all of them, use [`deniedMcpServers`](#deniedmcpservers). See [Disable claude.ai connectors](../06-MCP-Tools/General/mcp.md#disable-claude-ai-connectors).


[​](#disabledmcpjsonservers)

`disabledMcpjsonServers`

Reject specific servers defined in a project’s `.mcp.json` file so Claude Code never connects them or asks you to approve them. A rejection in any settings file applies, including a project `.claude/settings.json` checked into the repository.

- **Scope**: [`Any file`](#scopes)
- **Type**: array of strings, the server names as they appear in `.mcp.json`
- **Default**: unset

settings.json

```python
{
  "disabledMcpjsonServers": ["filesystem"]
}
```

Claude Code writes this key to `.claude/settings.local.json` when you reject a server in the approval dialog. `claude mcp get <name>` shows a rejected server as `✘ Rejected (see disabledMcpjsonServers in settings)`. Rejection takes precedence over [`enabledMcpjsonServers`](#enabledmcpjsonservers) and [`enableAllProjectMcpServers`](#enableallprojectmcpservers).


[​](#enableallprojectmcpservers)

`enableAllProjectMcpServers`

Approve every MCP server defined in project `.mcp.json` files without a prompt. Claude Code writes this key to `.claude/settings.local.json` when you choose to approve all servers in the approval dialog.

- **Scope**: [`Any file`](#scopes). In a folder whose trust dialog you haven’t accepted, Claude Code honors it from user settings, managed settings, and `--settings` and ignores it in the shared project file, both in the session and for `claude mcp list` and `claude mcp get`; [Project server approvals and workspace trust](../06-MCP-Tools/General/mcp.md#project-server-approvals-and-workspace-trust) says when an untracked `.claude/settings.local.json` counts too.
- **Type**: Boolean
  - `true`: Claude Code approves every MCP server defined in project `.mcp.json` files without a prompt
  - `false`: Claude Code asks you to approve each server. In a trusted folder, a `false` in a higher-precedence file overrides a `true` in a lower one; in a folder you haven’t trusted, a `true` in any honored file is enough
- **Default**: unset, so Claude Code asks you to approve each server

settings.json

```python
{
  "enableAllProjectMcpServers": true
}
```

A [`disabledMcpjsonServers`](#disabledmcpjsonservers) entry still rejects a server.


[​](#enabledmcpjsonservers)

`enabledMcpjsonServers`

Approve specific servers defined in project `.mcp.json` files so Claude Code connects them without asking. Claude Code writes this key to `.claude/settings.local.json` when you approve a server in the approval dialog.

- **Scope**: [`Any file`](#scopes). In a folder whose trust dialog you haven’t accepted, Claude Code honors it from user settings, managed settings, and `--settings` and ignores it in the shared project file, both in the session and for `claude mcp list` and `claude mcp get`; [Project server approvals and workspace trust](../06-MCP-Tools/General/mcp.md#project-server-approvals-and-workspace-trust) says when an untracked `.claude/settings.local.json` counts too.
- **Type**: array of strings, the server names as they appear in `.mcp.json`
- **Default**: unset

This example approves the `memory` and `github` servers from the project’s `.mcp.json`:

settings.json

```python
{
  "enabledMcpjsonServers": ["memory", "github"]
}
```

A [`disabledMcpjsonServers`](#disabledmcpjsonservers) entry still rejects a server.


[​](#managedmcpservers)

`managedMcpServers`

Provide remote MCP servers to every user from managed settings. Users keep the servers they add themselves and can’t edit or remove the ones you provide. Requires Claude Code v2.1.259 or later.

- **Scope**: [`Managed`](#scopes). Claude Code drops the key with a warning in user, project, and local settings, and doesn’t read it in the Claude Desktop app’s Code tab on a third-party deployment or in the app’s Cowork sessions, where Claude Desktop supplies and locks those sessions’ MCP servers itself.
- **Type**: object keyed by server name. Each entry has the `.mcp.json` shape for an `http` or `sse` server: a required `https://` `url`, and optionally `headers`, `oauth`, and the other HTTP and SSE options. Claude Code drops entries that fail validation, and [What an entry can contain](../06-MCP-Tools/General/managed-mcp.md#what-an-entry-can-contain) lists the conditions
- **Default**: unset, so managed settings provide no servers

This example provides one HTTP server named `search`:

managed-settings.json

```python
{
  "managedMcpServers": {
    "search": {
      "type": "http",
      "url": "https://search.example.com/mcp"
    }
  }
}
```

For precedence, how provided servers combine with `managed-mcp.json` and the allow and deny lists, and what users see, see [Provide servers through managed settings](../06-MCP-Tools/General/managed-mcp.md#provide-servers-through-managed-settings).


[​](#agents-sessions-and-worktrees)

Agents, sessions, and worktrees

Set the default agent, control teammates and cross-session messaging, and configure worktrees. See [Subagents](../09-Agents-Patterns/sub-agents.md) and [Worktrees](worktrees.md).


[​](#agent)

`agent`

Run the main thread as a named [subagent](../09-Agents-Patterns/sub-agents.md#invoke-subagents-explicitly), so Claude Code applies that subagent’s system prompt, tool restrictions, and model to your session. The same key sets the default agent for sessions you dispatch from `claude agents`.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, the name of a built-in or custom agent
- **Default**: unset, so the main thread runs as Claude Code’s default agent
- **Per-session overrides**: `--agent` takes precedence over this key for one session

settings.json

```python
{
  "agent": "code-reviewer"
}
```

A plugin’s own `settings.json` can also supply this key; see [Ship default settings with your plugin](../08-Plugins-Skills/plugins-components.md#default-settings).


[​](#crosssessioninbound)

`crossSessionInbound`

Choose what this session does with [messages arriving from your other Claude Code sessions](cross-session-messaging.md#control-inbound-messages). When no value applies, Claude Code decides per message from the two sessions’ permission-mode classes. Requires Claude Code v2.1.224 or later.

- **Scope**: [`Any file`](#scopes). A project or local value applies only when it’s stricter than the value managed settings, the `--settings` flag, or user settings give.
- **Type**: string, one of:
  - `"accept"`: Claude Code delivers the message to Claude
  - `"hold"`: Claude Code shows a notice for the message without delivering it
  - `"refuse"`: Claude Code drops the message
- **Default**: unset, so Claude Code decides per message

settings.json

```python
{
  "crossSessionInbound": "hold"
}
```

Claude Code reads managed settings first, then the `--settings` flag, then user settings, and applies the first value found. `refuse` is stricter than `hold`, and `hold` is stricter than `accept`. When none of the trusted sources sets a value, a project or local `hold` or `refuse` still applies, replacing the per-message default. In sessions with cross-session messaging, this key appears in `/config` as **Messages from your other sessions**, which writes it to user settings; the row requires Claude Code v2.1.232 or later, and Claude Code hides it while the `--settings` flag or managed settings set the key. Claude Code [warns](errors.md#crosssessioninbound-must-be-one-of-accept-hold-refuse) when you set a value it doesn’t recognize. While that value is present in a user, project, local, or `--settings` file, Claude Code holds inbound messages, even when a source that takes precedence sets `accept`. A `refuse` that another source sets still applies. Fix or remove the value to clear the hold. When the unrecognized value is in [managed settings](../13-Enterprise-Admin/managed-settings.md), Claude Code instead treats it as `refuse` until an administrator fixes it. Before v2.1.248, Claude Code ignored an unrecognized value without warning.


[​](#disableagentview)

`disableAgentView`

Turn off [background agents and agent view](../09-Agents-Patterns/agent-view.md): `claude agents`, `--bg`, `/background`, and the on-demand supervisor. Set it in [managed settings](../13-Enterprise-Admin/managed-settings.md) to enforce it for an organization.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code turns off `claude agents`, `--bg`, `/background`, and the on-demand supervisor
  - `false`: agent view is available
- **Default**: unset, so agent view is available
- **Per-session overrides**: [`CLAUDE_CODE_DISABLE_AGENT_VIEW`](env-vars.md) turns agent view off for one session; whichever of the two turns it off, the other can’t turn it back on

settings.json

```python
{
  "disableAgentView": true
}
```


[​](#isolatepeermachines)

`isolatePeerMachines`

Require your explicit approval before Claude’s `SendMessage` reaches one of your sessions beyond this machine; see [Require approval for cross-machine messages](cross-session-messaging.md#require-approval-for-cross-machine-messages). The approval prompt appears even in [`bypassPermissions` mode](permission-modes.md#skip-all-checks-with-bypasspermissions-mode).

- **Scope**: [`Any file`](#scopes). A `true` from any scope applies, so a checked-in project file can turn the requirement on but not off.
- **Type**: Boolean
  - `true`: Claude Code asks for your approval before Claude’s `SendMessage` reaches one of your sessions beyond this machine
  - `false`: cross-machine messages don’t prompt
- **Default**: unset, so cross-machine messages don’t prompt

settings.json

```python
{
  "isolatePeerMachines": true
}
```

The cross-machine `SendMessage` approval requires Claude Code v2.1.224 or later.


[​](#processwrapper)

`processWrapper`

On macOS and Linux, place a corporate launcher command in front of the [background processes Claude Code starts](../13-Enterprise-Admin/corporate-launcher.md#what-the-launcher-covers). Claude Code runs the launcher with its own command line appended, so the launcher must exec into Claude Code; see [Run Claude Code behind a corporate launcher](../13-Enterprise-Admin/corporate-launcher.md) for the launcher contract. Requires Claude Code v2.1.210 or later.

- **Scope**: [`User or managed`](#scopes)
- **Type**: string, the launcher command as an argv prefix, such as an absolute path with optional arguments
- **Default**: unset, so background processes start unwrapped
- **Per-session overrides**: [`CLAUDE_CODE_PROCESS_WRAPPER`](env-vars.md) takes precedence over this key for one session

settings.json

```python
{
  "processWrapper": "/opt/corp/launcher --profile claude"
}
```

Claude Code ignores the launcher on Windows and starts every process unwrapped. Requires Claude Code v2.1.210 or later.


[​](#teammatemode)

`teammateMode`

Choose where Claude Code shows [agent team](../09-Agents-Patterns/agent-teams.md) teammates: inside your main terminal pane, or in split panes when your terminal supports them. See [Choose a display mode](../09-Agents-Patterns/agent-teams.md#choose-a-display-mode).

- **Scope**: [`Any file`](#scopes). Claude Code also reads a value left in `~/.claude.json` by older versions.
- **Type**: string, one of:
  - `"in-process"`: teammates run inside your main terminal pane
  - `"auto"`: split panes when you’re running inside tmux, or inside iTerm2 with `it2` on your `PATH` or tmux installed; in-process otherwise
  - `"tmux"`: split panes using tmux or iTerm2, detected from your terminal
  - `"iterm2"`: iTerm2 native split panes through the `it2` CLI
- **Default**: `"in-process"`
- **Per-session overrides**: `--teammate-mode` takes precedence over this key for one session

settings.json

```python
{
  "teammateMode": "auto"
}
```


[​](#worktree)

`worktree`

Configure how Claude Code creates and manages [git worktrees](worktrees.md) for `--worktree`, the `EnterWorktree` tool, and isolated subagents and background sessions.

- **Scope**: [`Any file`](#scopes)
- **Type**: object with `baseRef`, `symlinkDirectories`, `sparsePaths`, and `bgIsolation`
- **Default**: unset

This example branches new worktrees from your current `HEAD` and symlinks `node_modules` into each one:

settings.json

```python
{
  "worktree": {
    "baseRef": "head",
    "symlinkDirectories": ["node_modules"]
  }
}
```

To copy gitignored files like `.env` into new worktrees, add a [`.worktreeinclude` file](worktrees.md#copy-gitignored-files-into-worktrees) to your project root instead of a setting.


[​](#worktree-baseref)

`worktree.baseRef`

Choose which ref new worktrees branch from. `"fresh"` branches from `origin/<default-branch>` for a clean tree matching the remote; `"head"` branches from your current local `HEAD`, so unpushed commits and feature-branch state are present in the worktree.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, one of:
  - `"fresh"`: new worktrees branch from `origin/<default-branch>`
  - `"head"`: new worktrees branch from your current local `HEAD`, including unpushed commits
- **Default**: `"fresh"`

settings.json

```python
{
  "worktree": {
    "baseRef": "head"
  }
}
```

Inside a linked worktree, `"head"` resolves to that worktree’s `HEAD`, not the main checkout’s.


[​](#worktree-symlinkdirectories)

`worktree.symlinkDirectories`

Symlink directories from the main repository into each worktree so you don’t duplicate large directories on disk.

- **Scope**: [`Any file`](#scopes)
- **Type**: array of strings, directory paths relative to the repository root
- **Default**: unset, so Claude Code symlinks no directories

This example symlinks `node_modules` and `.cache` from the main repository into every new worktree:

settings.json

```python
{
  "worktree": {
    "symlinkDirectories": ["node_modules", ".cache"]
  }
}
```


[​](#worktree-sparsepaths)

`worktree.sparsePaths`

Check out only the listed directories in each worktree through git sparse-checkout. Claude Code writes only those directories plus root-level files to disk, which is faster in large monorepos; see [Check out only the directories you need](large-codebases.md#check-out-only-the-directories-you-need).

- **Scope**: [`Any file`](#scopes)
- **Type**: array of strings, directory paths relative to the repository root
- **Default**: unset, so each worktree checks out the whole tree

This example checks out only `packages/my-app` and `shared/utils`, plus root-level files, in each worktree:

settings.json

```python
{
  "worktree": {
    "sparsePaths": ["packages/my-app", "shared/utils"]
  }
}
```

While a sparse worktree exists, git enables `extensions.worktreeConfig` in the repository’s shared `.git/config`.


[​](#worktree-bgisolation)

`worktree.bgIsolation`

Choose how [background sessions](../09-Agents-Patterns/agent-view.md#how-file-edits-are-isolated) isolate their file edits. If you moved a session to the background with `←` or `/background`, that session edits files in place whatever this key says. With `"worktree"`, Claude Code blocks `Edit` and `Write` in the main checkout until the session calls `EnterWorktree`; with `"none"`, background jobs edit the working copy directly. Set `"none"` for a repository where git worktrees are impractical.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, one of:
  - `"worktree"`: Claude Code blocks `Edit` and `Write` in the main checkout until the session calls `EnterWorktree`
  - `"none"`: background jobs edit the working copy directly
- **Default**: `"worktree"`

settings.json

```python
{
  "worktree": {
    "bgIsolation": "none"
  }
}
```

Outside a git repository, a [`WorktreeCreate` hook](worktrees.md#non-git-version-control) that fails releases the block so the session can edit the working directory in place.


[​](#worktree-location)

`worktree.location`

Choose the folder on a remote machine where [Desktop SSH sessions](../16-Mobile-Desktop/desktop.md#choose-where-ssh-session-worktrees-go) create their worktrees, instead of `<project-root>/.claude/worktrees/`. Only the desktop app reads this key: `--worktree`, the `EnterWorktree` tool, isolated subagents, and background sessions ignore it. Requires Claude Desktop v1.44121.0 or later.

- **Scope**: [`User`](#scopes), in `~/.claude/settings.json` on the remote machine
- **Type**: string, an absolute path or one that starts with `~/`
- **Default**: unset, so worktrees go inside the project

This example sets the folder to `~/worktrees`:

settings.json

```python
{
  "worktree": {
    "location": "~/worktrees"
  }
}
```

A **Worktree folder** set on the SSH connection in Desktop takes precedence. If your organization restricts which folders sessions may use, Desktop keeps worktrees inside the project.


[​](#remote-desktop-and-notifications)

Remote, desktop, and notifications

Configure Remote Control, cloud environments, the desktop app, and the notifications Claude Code sends when it needs you. See [Remote Control](remote-control.md).


[​](#agentpushnotifenabled)

`agentPushNotifEnabled`

Allow Claude to send a push notification to your phone when it decides one is worth sending, for example when a long task finishes. Claude can send one while [Remote Control](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.

- **Scope**: [`Any file`](#scopes). Claude Code also reads a value left in `~/.claude.json` by older versions.
- **Type**: Boolean
  - `true`: Claude can send a push notification to your phone when it decides one is worth sending
  - `false`: Claude doesn’t send those notifications
- **Default**: `false`

settings.json

```python
{
  "agentPushNotifEnabled": true
}
```

If you run sessions under a [`claude remote-control`](remote-control.md#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. See [Mobile push notifications](remote-control.md#mobile-push-notifications).


[​](#awaysummaryenabled)

`awaySummaryEnabled`

Show a one-line session recap when you return to the terminal after a few minutes away. Set it to `false`, or turn off **Session recap** in `/config`, to stop the recap.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: you see a one-line session recap when you return after a few minutes away
  - `false`: Claude Code shows no recap
- **Default**: unset, so the recap is on
- **Per-session overrides**: [`CLAUDE_CODE_ENABLE_AWAY_SUMMARY`](env-vars.md) takes precedence over this key for one session, in either direction

settings.json

```python
{
  "awaySummaryEnabled": false
}
```

Claude Code never shows the recap in non-interactive mode.


[​](#disableartifact)

`disableArtifact`

Deprecated, and replaced by [`enableArtifact`](#enableartifact). Claude Code still honors `disableArtifact: true` as equivalent to `enableArtifact: false`, and ignores `disableArtifact: false`.

Use [`enableArtifact`](#enableartifact) instead to turn off the [Artifact](artifacts.md) tool, which publishes session output as a private web page on claude.ai. When you turn the **Artifacts** row off in `/config`, Claude Code writes `enableArtifact` to your user settings and clears this key.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code turns the Artifact tool off for every session the file applies to, and no other file turns it back on
  - `false`: ignored; to leave the tool on, remove the key
- **Default**: unset, so the tool follows your account’s [availability](artifacts.md#availability)
- **Per-session overrides**: [`CLAUDE_CODE_DISABLE_ARTIFACT`](env-vars.md) set to `1` turns the tool off for one session

settings.json

```python
{
  "disableArtifact": true
}
```

[Disable artifacts](artifacts.md#disable-artifacts) lists every way to turn the tool off.


[​](#disabledeeplinkregistration)

`disableDeepLinkRegistration`

Stop Claude Code from registering the `claude-cli://` protocol handler with the operating system, which it otherwise does after you send the first prompt of an interactive session. [Deep links](deep-links.md) let external tools open a Claude Code session with a pre-filled prompt. Set this in environments where protocol handler registration is restricted or managed separately.

- **Scope**: [`Any file`](#scopes)
- **Type**: the string `"disable"`
- **Default**: unset, so Claude Code registers the handler

settings.json

```python
{
  "disableDeepLinkRegistration": "disable"
}
```


[​](#disabledesktoplocalsessions)

`disableDesktopLocalSessions`

Turn off Code sessions that run on the device in the [desktop app](../16-Mobile-Desktop/desktop.md#local-sessions-on-managed-devices), for deployments where developers should work on remote machines over SSH. With the key set to `true`, users see this in the Code tab:

- **Environment selector**: the entry for the user’s computer is grayed out and unselectable, with the tooltip **Disabled by your organization**. On Windows the WSL entry is grayed out the same way, though whether WSL sessions run on a managed device at all is [governed separately](../13-Enterprise-Admin/admin-setup.md#wsl-sessions-in-claude-code-desktop).
- **New sessions**: default to the first [SSH connection](../16-Mobile-Desktop/desktop.md#ssh-sessions) if one is configured
- **Sessions on the device**: the app refuses to start or resume a session on the device, including an SSH connection back to the same machine
- **SSH sessions to other hosts and cloud sessions**: unaffected

The desktop app reads this key; the terminal CLI ignores it. Requires Claude Desktop v1.37937.0 or later.

- **Scope**: [`Managed`](#scopes). By default, the desktop app reads the key from [one managed source](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources).
- **Type**: Boolean; only the JSON Boolean `true` takes effect
  - `true`: the desktop app offers no on-device Code sessions; existing local sessions stay listed but can’t continue
  - `false`: local sessions stay available
- **Default**: unset, so local sessions are available

managed-settings.json

```python
{
  "disableDesktopLocalSessions": true
}
```

The desktop app ignores any other value, and a value that isn’t a Boolean, such as the string `"true"` or `1`, also logs a warning. Pair it with [`sshConfigs`](#sshconfigs) so users land on a working connection, and with [`sshHostAllowlist`](#sshhostallowlist) to limit which hosts they can reach. See [Local sessions on managed devices](../16-Mobile-Desktop/desktop.md#local-sessions-on-managed-devices). Claude Desktop supplies Code sessions with policy derived from your desktop configuration, for example the egress allowlist, filesystem sandbox, and MCP restrictions in third-party deployments. Claude Code ignores those parent settings whenever an [admin source](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) is present: server-managed settings, an MDM or OS-level policy, or a managed settings file. Deploying this key through one of those on a device that had none before, as in third-party deployments, therefore stops the desktop-derived policies from applying. [Let an embedding host add policy](../13-Enterprise-Admin/managed-settings.md#let-an-embedding-host-add-policy) covers when parent settings can still merge; this holds for any key you deploy that way, not only this one.


[​](#disableremotecontrol)

`disableRemoteControl`

Turn off [Remote Control](remote-control.md): Claude Code then refuses `claude remote-control`, the `--remote-control` flag, auto-start, and the in-session toggle, and reports that your organization’s policy disabled it. Place it in [managed settings](../13-Enterprise-Admin/managed-settings.md) for per-device MDM enforcement.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code refuses `claude remote-control`, the `--remote-control` flag, auto-start, and the in-session toggle
  - `false`: Remote Control stays available
- **Default**: `false`

settings.json

```python
{
  "disableRemoteControl": true
}
```


[​](#enableartifact)

`enableArtifact`

Turn off the [Artifact](artifacts.md) tool, which publishes session output as a private web page on claude.ai. When you turn the **Artifacts** row off in `/config`, Claude Code writes this key to your user settings, so you don’t usually edit it by hand.

- **Scope**: [`Any file`](#scopes). Every file can turn the tool off, and none can turn it back on.
- **Type**: Boolean
  - `false`: Claude Code turns the Artifact tool off for every session the file applies to
  - `true`: the same as leaving the key unset, because it never overrides a `false` from another file, from [`CLAUDE_CODE_DISABLE_ARTIFACT`](env-vars.md), or from your organization’s [admin setting](artifacts.md#manage-artifacts-for-your-organization)
- **Default**: unset, so the tool follows your account’s [availability](artifacts.md#availability)

settings.json

```python
{
  "enableArtifact": false
}
```

While a source other than your own user settings keeps the tool turned off, Claude Code hides the **Artifacts** row in `/config`, because turning it on there wouldn’t change anything. [Disable artifacts](artifacts.md#disable-artifacts) lists every way to turn the tool off.


[​](#inputneedednotifenabled)

`inputNeededNotifEnabled`

Get a push notification on your phone when a permission prompt or question is waiting for your input. Claude Code sends these only while [Remote Control](remote-control.md) is connected. Appears in `/config` as **Push when actions required**.

- **Scope**: [`Any file`](#scopes). Claude Code also reads a value left in `~/.claude.json` by older versions.
- **Type**: Boolean
  - `true`: you get a push notification on your phone when a permission prompt or question is waiting, while Remote Control is connected
  - `false`: Claude Code sends no such notifications
- **Default**: `false`

settings.json

```python
{
  "inputNeededNotifEnabled": true
}
```

See [Mobile push notifications](remote-control.md#mobile-push-notifications).


[​](#preferrednotifchannel)

`preferredNotifChannel`

Choose how Claude Code notifies you when a task completes or a permission prompt is waiting. A [mod’s notifications](../08-Plugins-Skills/plugins-mods-api.md#show-something-without-starting-a-turn) use the same setting. Appears in `/config` as **Local notifications**.

- **Scope**: [`Any file`](#scopes). Claude Code also reads a value left in `~/.claude.json` by older versions.
- **Type**: string, one of:
  - `"auto"`: Claude Code sends a desktop notification in iTerm2, Ghostty, and Kitty, rings the bell in Terminal.app only when its audible bell is off, and does nothing elsewhere
  - `"terminal_bell"`: Claude Code rings the bell character in any terminal
  - `"iterm2"`: Claude Code sends an iTerm2 desktop notification
  - `"iterm2_with_bell"`: Claude Code sends an iTerm2 desktop notification and rings the bell
  - `"kitty"`: Claude Code sends a Kitty desktop notification
  - `"ghostty"`: Claude Code sends a Ghostty desktop notification
  - `"notifications_disabled"`: Claude Code sends no notification
- **Default**: `"auto"`

settings.json

```python
{
  "preferredNotifChannel": "terminal_bell"
}
```

With `"auto"`, Claude Code sends a desktop notification in iTerm2, Ghostty, and Kitty. In Terminal.app it rings the bell character only when you have turned Terminal’s audible bell off, and in other terminals it does nothing. Set `"terminal_bell"` to ring the bell character in any terminal. See [Get a terminal bell or notification](terminal-config.md#get-a-terminal-bell-or-notification).


[​](#remote-defaultenvironmentid)

`remote.defaultEnvironmentId`

Pick the default [cloud environment](cloud-environments.md) for cloud sessions you create from the CLI, such as with `claude --cloud`. Claude Code writes this key to your user settings when you pick an environment with [`/remote-env`](cloud-environments.md#select-an-environment-from-the-cli).

- **Scope**: [`Any file`](#scopes). For a self-hosted environment ID, user or managed settings, or the `--settings` flag only.
- **Type**: string, an environment ID such as `env_...` or `ccpool_...`
- **Default**: unset, so Claude Code uses the Anthropic-hosted environment when your list has one, and otherwise the first environment in your list that isn’t a [Remote Control bridge environment](cloud-environments.md#the-default-environment), or the first environment when every one is a bridge environment
- **Per-session overrides**: `--environment` takes precedence over this key for the one cloud session it creates

settings.json

```python
{
  "remote": {
    "defaultEnvironmentId": "env_0123abcd"
  }
}
```

An Anthropic-hosted environment ID, which starts with `env_`, follows the standard settings precedence, so a value in a repository’s project settings overrides your user-level pick. A [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) ID, which starts with `ccpool_`, is honored only from user settings, managed settings, and the `--settings` flag; Claude Code ignores one in a repository’s project or local settings, and `/remote-env` shows which value it ignored, so a checked-in file can’t steer sessions onto a self-hosted environment you didn’t choose.


[​](#remotecontrolatstartup)

`remoteControlAtStartup`

Connect [Remote Control](remote-control.md) automatically when each interactive session starts, instead of waiting for `/remote-control`. Set it to `true` to turn auto-connect on, `false` to turn it off. Appears in `/config` as **Enable Remote Control for all sessions**.

- **Scope**: [`Any file`](#scopes). Claude Code also reads a value left in `~/.claude.json` by older versions.
- **Type**: Boolean
  - `true`: Claude Code connects Remote Control automatically when each interactive session starts
  - `false`: Claude Code waits for `/remote-control`
- **Default**: unset, so the [auto-connect default](remote-control.md#enable-remote-control-for-all-sessions) applies
- **Per-session overrides**: `--remote-control` turns Remote Control on for one session even when this key is `false`, and no flag turns it off for one session

settings.json

```python
{
  "remoteControlAtStartup": true
}
```

Claude Code ignores a `true` from project or local settings, so a repository can turn auto-connect off for its checkout but can’t turn it on. For the full per-scope behavior, see [Enable Remote Control for all sessions](remote-control.md#enable-remote-control-for-all-sessions) and the [security keys where the stricter value applies](settings.md#security-keys-where-the-stricter-value-applies).


[​](#sshconfigs)

`sshConfigs`

Add SSH connections to the [Desktop](../16-Mobile-Desktop/desktop.md#pre-configure-ssh-connections-for-your-team) environment selector. Administrators use `sshConfigs` to distribute shared connections to a team. Users can select a managed connection and [set their own **Worktree folder**](../16-Mobile-Desktop/desktop.md#set-the-worktree-folder-on-an-existing-connection) for it. They can’t edit its other fields or delete it in the app.

- **Scope**: [`User or managed`](#scopes). The desktop app reads this key. By default, it reads managed connections from [one managed source](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources).
- **Type**: array of objects, each with required `id`, `name`, and `sshHost` and optional `sshPort` and `sshIdentityFile`
- **Default**: unset

This example adds one connection named `Dev VM` that connects to `user@dev.example.com`:

settings.json

```python
{
  "sshConfigs": [
    {
      "id": "dev-vm",
      "name": "Dev VM",
      "sshHost": "user@dev.example.com"
    }
  ]
}
```


[​](#sshhostallowlist)

`sshHostAllowlist`

Limit the hosts a [Desktop SSH session](../16-Mobile-Desktop/desktop.md#restrict-which-ssh-hosts-users-can-connect-to) can connect to. Only the Desktop app reads this key; the CLI doesn’t. Patterns are case-insensitive: `*` matches any host, `*.example.com` matches `example.com` and every subdomain, and anything else is an exact match against the hostname after `~/.ssh/config` resolution. An empty array turns SSH sessions off. With Claude Desktop v3.1623.0 or later, a session’s [jump hosts](../16-Mobile-Desktop/desktop.md#allow-jump-hosts) have to match a pattern too.

- **Scope**: [`Managed`](#scopes). By default, Desktop reads the key from [one managed source](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources).
- **Type**: array of hostname patterns
- **Default**: unset, so any host is allowed

This example allows `devboxes.example.com` and its subdomains, plus the exact host `bastion.example.com`:

managed-settings.json

```python
{
  "sshHostAllowlist": ["*.devboxes.example.com", "bastion.example.com"]
}
```

A value that Desktop can’t read as a list of hosts, such as `true` or an object, counts as an empty array until you correct it, except `null`, which counts as unset. Requires Claude Desktop v2.26454.0 or later. If you set [`managedSourcesBehavior`](#managedsourcesbehavior) to `"merge"` in your highest-ranked source, Desktop combines the lists from every [admin source](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) and allows a host that matches any of them. If you set an empty array in one source, SSH sessions stay on for the hosts another source lists.


[​](#authentication-and-providers)

Authentication and providers

Supply credentials through helper scripts and, for organizations, force a login method or organization. See [Authentication](authentication.md).


[​](#allowedproviders)

`allowedProviders`

List the services a machine may reach Claude through, such as the Anthropic API, Amazon Bedrock, or an LLM gateway. A session on a provider that isn’t listed is refused at startup, at login, and when it next contacts the API, so switching to an unlisted provider mid-session is refused too. The [refusal message](errors.md#managed-settings-dont-allow-this-api-provider) names what selected the provider and the steps to continue. Requires Claude Code v2.1.285 or later.

- **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](../13-Enterprise-Admin/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](../13-Enterprise-Admin/server-managed-settings.md#platform-availability).
- **Type**: array of strings, each one of:
  - `"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
  - `"bedrock"`: [Amazon Bedrock](amazon-bedrock.md)
  - `"vertex"`: [Google Cloud’s Agent Platform](google-vertex-ai.md), formerly Vertex AI
  - `"foundry"`: [Microsoft Foundry](microsoft-foundry.md)
  - `"anthropicAws"`: [Claude Platform on AWS](claude-platform-on-aws.md)
  - `"mantle"`: the Amazon Bedrock [Mantle endpoint](amazon-bedrock.md#use-the-mantle-endpoint). A session that [runs Mantle alongside the Invoke API](amazon-bedrock.md#run-mantle-alongside-the-invoke-api) uses both providers, so list `"bedrock"` and `"mantle"` together for it
  - `"customEndpoint"`: the Anthropic API or a cloud provider’s API sent to another host, such as an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md) named by `ANTHROPIC_BASE_URL` or by a provider’s endpoint variable such as `ANTHROPIC_BEDROCK_BASE_URL`. Claude Code admits it only for the exact value a managed [`env`](#env) block pins
  - `"gateway"`: a [Cloud gateway](../13-Enterprise-Admin/claude-apps-gateway.md) sign-in
- **Default**: unset, so any provider can be used

managed-settings.json

```python
{
  "allowedProviders": ["anthropic", "bedrock"]
}
```

Each cloud provider’s entry means that provider’s own service, including its regional, FIPS, and private endpoints. An entry Claude Code doesn’t recognize as a provider name is dropped and reported, and the rest of the list stays enforced. With an empty list, or one whose every entry is unrecognized, Claude Code refuses every provider and doesn’t start on the machine.


[​](#endpoints-that-need-a-pin-in-managed-env)

Endpoints that need a pin in managed `env`

A pin is an endpoint variable’s value set in a managed [`env`](#env) block. When a session sends a provider’s traffic somewhere other than that provider’s own service, Claude Code admits it only if the session’s value is the same as the pin. These endpoints need one:

- **`"customEndpoint"` sessions**: the variable that names the host, such as `ANTHROPIC_BASE_URL`
- **Amazon Bedrock**: the AWS SDK’s `AWS_ENDPOINT_URL`, `AWS_ENDPOINT_URL_BEDROCK`, and `AWS_ENDPOINT_URL_BEDROCK_RUNTIME` variables when they point outside Bedrock’s own service. The session stays under `"bedrock"` rather than `"customEndpoint"`
- **A gateway sign-in’s URL**: the session stays under `"gateway"`, and [`forceLoginGatewayUrl`](#forcelogingatewayurl) also counts as the pin

Which `env` blocks count as pins depends on where the list is set:

- **An administrator source on the machine sets a list**: only the `env` blocks of the machine’s own administrator sources count
- **Only server-managed settings set a list**: an `env` value in those server-managed settings counts too

The list doesn’t judge a cloud provider’s credential and tenancy variables or the network path, such as `HTTPS_PROXY` and certificate settings. Set those for the fleet in the managed `env` block.


[​](#apikeyhelper)

`apiKeyHelper`

Run your own command to produce the credential Claude Code sends with model requests. Claude Code runs the command through the system shell, `/bin/sh` on macOS and Linux and `cmd` on Windows, and sends its output as both the `X-Api-Key` and `Authorization: Bearer` headers. Use it for dynamic or rotating credentials, such as short-lived tokens fetched from a vault.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, a shell command line
- **Default**: unset, so Claude Code doesn’t run a helper

settings.json

```python
{
  "apiKeyHelper": "/bin/generate_temp_api_key.sh"
}
```

Claude Code caches the value and reruns the command in these cases:

- After the cache lifetime, five minutes by default or the interval you set with [`CLAUDE_CODE_API_KEY_HELPER_TTL_MS`](env-vars.md).
- When a request to the Anthropic API, directly or through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md), fails with `401` or `403`.
- Before sending a request to the Anthropic API, directly or through an LLM gateway, when the cached output is a JWT that expired after the helper produced it. Requires Claude Code v2.1.246 or later.

The last two cases apply only when the helper’s output is the credential Claude Code sends and `ANTHROPIC_AUTH_TOKEN` isn’t set. In interactive sessions, when the command comes from project or local settings, Claude Code doesn’t run it until you accept the workspace trust prompt. See [Credential management](authentication.md#credential-management).


[​](#awsauthrefresh)

`awsAuthRefresh`

Run your own command, such as `aws sso login`, to refresh the credentials in your `.aws` directory when the ones Claude Code has for [Amazon Bedrock](amazon-bedrock.md) stop working. Claude Code checks the current credentials against STS first and runs the command only when that check fails, then reads the refreshed `.aws` directory. When the check fails at the same time in several Claude Code processes that use the same command and credentials, such as separate terminals or IDE windows, one process runs the command and the rest wait for that run instead of starting their own. A process that has waited 60 seconds with a request pending runs the command itself. To turn this off, set [`CLAUDE_CODE_DISABLE_AUTH_REFRESH_LOCK`](env-vars.md) to `1`.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, a shell command line
- **Default**: unset, so Claude Code doesn’t refresh AWS credentials for you

settings.json

```python
{
  "awsAuthRefresh": "aws sso login --profile myprofile"
}
```

Use this key when your refresh flow writes to `.aws`; use [`awsCredentialExport`](#awscredentialexport) when it prints credentials instead. See [advanced credential configuration](amazon-bedrock.md#advanced-credential-configuration).


[​](#awscredentialexport)

`awsCredentialExport`

Run your own command that prints AWS credentials as JSON, so Claude Code can call [Amazon Bedrock](amazon-bedrock.md) with credentials that don’t live in your `.aws` directory. Claude Code accepts the `aws sts` output shape and the flat `aws configure export-credentials` shape, and scopes the credentials to its own Bedrock client, so the shell commands Claude runs still see your ambient credentials.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, a shell command line
- **Default**: unset, so Claude Code uses the ambient AWS credential chain

settings.json

```python
{
  "awsCredentialExport": "/bin/generate_aws_grant.sh"
}
```

Unlike [`awsAuthRefresh`](#awsauthrefresh), Claude Code always runs this command when it’s set, without checking the ambient credentials first. See [advanced credential configuration](amazon-bedrock.md#advanced-credential-configuration).


[​](#forceloginmethod)

`forceLoginMethod`

Restrict which kind of account people can log in with. Set `"claudeai"` to allow only claude.ai accounts, `"console"` to allow only Claude Console accounts, or `"gateway"` to send people to a [cloud gateway](../13-Enterprise-Admin/claude-apps-gateway.md) instead of a first-party login. Administrators set it in managed settings and pair it with [`forceLoginOrgUUID`](#forceloginorguuid) to keep developers’ claude.ai logins inside one organization. If you set it to `"claudeai"` or `"console"` in any settings file, Claude Code also stops offering the [keyless Console sign-in](authentication.md#sign-in-without-an-api-key) in the sessions that file applies to.

- **Scope**: [`Any file`](#scopes). Claude Code honors `"gateway"` from the same sources as [`forceLoginGatewayUrl`](#forcelogingatewayurl) and treats it as unset everywhere else.
- **Type**: string, one of:
  - `"claudeai"`: only claude.ai accounts can log in
  - `"console"`: only Claude Console accounts can log in
  - `"gateway"`: Claude Code sends people to a cloud gateway instead of a first-party login
- **Default**: unset, so people pick a login method

settings.json

```python
{
  "forceLoginMethod": "claudeai"
}
```

Every first-party login path applies the restriction, including the [VS Code extension](../03-IDE-Integrations/vs-code.md), the Agent SDK, `claude setup-token`, and `/install-github-app`, except the terminal’s interactive login screen, reached by `/login` or first-run onboarding, which pre-selects the method without enforcing it. Before v2.1.212, only terminal logins applied it. See [Restrict login to your organization](authentication.md#restrict-login-to-your-organization) for how each login path, environment credentials, and third-party providers are handled. When a managed source on the machine sets `"gateway"`, Claude Code doesn’t use a leftover login, API key, or `apiKeyHelper` credential. See [Administrator policy requires a Cloud gateway sign-in](errors.md#administrator-policy-requires-a-cloud-gateway-sign-in) for the message each one produces. If you select a cloud provider through `CLAUDE_CODE_USE_BEDROCK` or a similar environment variable, the session doesn’t need the gateway sign-in. Before v2.1.261, Claude Code used a leftover login on these machines.


[​](#forcelogingatewayurl)

`forceLoginGatewayUrl`

Set the gateway URL the `/login` Cloud gateway screen connects to, so people reach your [cloud gateway](../13-Enterprise-Admin/claude-apps-gateway.md) without typing its address. The screen has no URL field: with this key set, it shows your gateway URL and connects when the person presses Enter; without it, it tells them to contact their IT administrator. In managed settings, either this key or `forceLoginMethod: "gateway"` makes the machine gateway-only, except for sessions that select a cloud provider with `CLAUDE_CODE_USE_*`. `/login` then opens on the Cloud gateway screen with no login-method picker. See [Administrator policy requires a Cloud gateway sign-in](errors.md#administrator-policy-requires-a-cloud-gateway-sign-in) for what happens to a leftover first-party login or API key. Set both keys so the screen connects instead of showing an error.

- **Scope**: [`User or managed`](#scopes). Read from a managed source on the machine: `managed-settings.json`, the macOS plist or Windows HKLM registry, or a policy helper. On a machine with none of those, Claude Code v2.1.295 or later also reads it from [user settings](../13-Enterprise-Admin/claude-apps-gateway.md#set-the-gateway-url-in-user-settings). Claude Code ignores it in HKCU and server-managed settings.
- **Type**: string, a full URL including the scheme
- **Default**: unset, so the Cloud gateway screen shows an error telling people to contact their IT administrator

managed-settings.json

```python
{
  "forceLoginGatewayUrl": "https://claude-gateway.example.com"
}
```

If the value isn’t a valid URL, the sign-in screen reports it, and the rest of the managed settings file still applies. See [Set the gateway URL](../13-Enterprise-Admin/claude-apps-gateway.md#set-the-gateway-url).


[​](#forceloginorguuid)

`forceLoginOrgUUID`

From a managed source, require claude.ai account logins to belong to one Anthropic organization, given as a single UUID, or to any of several organizations, given as an array. From any settings file, Claude Code also uses a single UUID to pre-select that organization during a claude.ai or Claude Console login, and pre-selects nothing for an array. If you set the key in any settings file, Claude Code also stops offering the [keyless Console sign-in](authentication.md#sign-in-without-an-api-key) in the sessions that file applies to and creates an API key instead.

- **Scope**: [`Any file`](#scopes). Only a managed source enforces the restriction; a single UUID in any other settings file pre-selects the organization during login without restricting it.
- **Type**: string, one UUID, or array of strings, several UUIDs
- **Default**: unset, so any organization can log in

This example accepts logins from either of two organizations without pre-selecting one:

managed-settings.json

```python
{
  "forceLoginOrgUUID": ["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"]
}
```

If a managed source sets an empty array, or a value that isn’t a string or an array of strings, users who sign in with an Anthropic account can’t start Claude Code or complete a login. They see a message that names `forceLoginOrgUUID` and tells them to contact their administrator. A [`policyHelper`](#policyhelper) that emits a value of the wrong type [fails its run](#helper-failures) instead. See [Restrict login to your organization](authentication.md#restrict-login-to-your-organization) for how Claude Code treats Claude Console logins, the other login paths, and environment credentials.


[​](#gatewayinternalnetworks)

`gatewayInternalNetworks`

Declare the public IPv4 blocks that your organization numbers its internal network from, so `/login` accepts a [cloud gateway](../13-Enterprise-Admin/claude-apps-gateway.md) there. Requires Claude Code v2.1.268 or later. Without this key, `/login` connects to any gateway on a private address and nothing else. With it, `/login` also accepts a gateway inside a listed block, over a direct connection only. The machine’s own address on that connection must also be inside the same block.

- **Scope**: [`Managed`](#scopes). Read only from a source on the machine: `managed-settings.json`, the macOS plist or Windows HKLM registry, or a policy helper. Claude Code ignores it in HKCU and server-managed settings.
- **Type**: array of strings, at most four IPv4 CIDR blocks, each `/8` to `/32`, not overlapping one another, and none overlapping private space.
- **Default**: unset, so `/login` accepts only gateways on private addresses

managed-settings.json

```python
{
  "gatewayInternalNetworks": ["203.0.113.0/24"]
}
```

Replace the documentation range in the example with your own block. Claude Code refuses the documentation ranges, the ranges that VPN and NAT64 clients use locally, and reserved space that no network is numbered from, such as multicast. If an entry is invalid, or the value isn’t a list of strings, `/login` names the problem and refuses every new gateway sign-in on the machine until you fix the value. Existing sign-ins keep working. See [Allow a gateway on public address space you own](../13-Enterprise-Admin/claude-apps-gateway.md#allow-a-gateway-on-public-address-space-you-own) for the full rules and what developers see.


[​](#gcpauthrefresh)

`gcpAuthRefresh`

Run your own command to refresh Google Cloud Application Default Credentials when Claude Code finds they’ve expired or can’t be loaded, so [Google Cloud’s Agent Platform](google-vertex-ai.md) requests keep working without you re-authenticating by hand. When several Claude Code processes that use the same command and credentials, such as separate terminals or IDE windows, find them expired at the same time, one process runs the command and the rest wait for that run instead of starting their own. A process that has waited 60 seconds with a request pending runs the command itself. To turn this off, set [`CLAUDE_CODE_DISABLE_AUTH_REFRESH_LOCK`](env-vars.md) to `1`.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, a shell command line
- **Default**: unset, so Claude Code’s credential error tells you to run `gcloud auth application-default login` yourself

settings.json

```python
{
  "gcpAuthRefresh": "gcloud auth application-default login"
}
```

See [advanced credential configuration](google-vertex-ai.md#advanced-credential-configuration).


[​](#otelheadershelper)

`otelHeadersHelper`

Run your own command to generate the headers Claude Code sends with OpenTelemetry exports, for backends whose tokens rotate. Claude Code runs it at startup and periodically after that, and expects a JSON object of string header values on stdout.

- **Scope**: [`Any file`](#scopes)
- **Type**: string, an executable path or a shell command line
- **Default**: unset, so Claude Code adds no helper-generated headers

settings.json

```python
{
  "otelHeadersHelper": "/bin/generate_otel_headers.sh"
}
```

Set the refresh interval with [`CLAUDE_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS`](env-vars.md). See [Dynamic headers](../13-Enterprise-Admin/monitoring-usage.md#dynamic-headers) for the script requirements and what happens when the helper fails.


[​](#updates-and-versioning)

Updates and versioning

Choose an update channel and, for organizations, pin the versions people can run. See [Update Claude Code](../01-Getting-Started/setup.md#update-claude-code).


[​](#autoupdateschannel)

`autoUpdatesChannel`

Choose which [release channel](../01-Getting-Started/setup.md#configure-release-channel) background auto-updates and `claude update` follow. Set `"stable"` for a version that is typically about one week old and skips releases with major regressions, or `"latest"` for the most recent release.

- **Scope**: [`Any file`](#scopes). Set it in managed settings to enforce one channel across your organization.
- **Type**: string, one of:
  - `"latest"`: updates follow the most recent release
  - `"stable"`: updates follow a version that is typically about one week old and skips releases with major regressions
- **Default**: unset, so Claude Code follows `"latest"`

settings.json

```python
{
  "autoUpdatesChannel": "stable"
}
```

Claude Code writes `"stable"` to your user settings when you pick it under **Auto-update channel** in `/config`, and removes the key when you switch back to latest there. `claude install stable` and `claude install latest` also save the channel you name. Switching from `"latest"` to `"stable"` in `/config` asks whether to allow a downgrade or stay on your current version; staying sets [`minimumVersion`](#minimumversion). Homebrew installs ignore this key: the `claude-code` cask tracks stable and `claude-code@latest` tracks latest, and `claude update` defers to `brew upgrade`. To turn auto-updates off entirely, set [`DISABLE_AUTOUPDATER`](../01-Getting-Started/setup.md#disable-auto-updates) in `env`.


[​](#minimumversion)

`minimumVersion`

Keep background auto-updates and `claude update` from installing any version below this one, so moving to the `"stable"` channel doesn’t downgrade you from a newer `"latest"` build. Claude Code writes this key for you when you choose to stay on your current version while switching channels in `/config`, and clears it when you switch back to `"latest"`.

- **Scope**: [`Any file`](#scopes). Set it in managed settings to pin an organization-wide minimum that user and project settings can’t lower.
- **Type**: string, a version number such as `"2.1.100"`; a value that isn’t a valid version is ignored
- **Default**: unset, so updates can install any version the channel offers

This example follows the stable channel and refuses to install any version below 2.1.100:

settings.json

```python
{
  "autoUpdatesChannel": "stable",
  "minimumVersion": "2.1.100"
}
```

This key only constrains updates. To make Claude Code refuse to start below a version, use [`requiredMinimumVersion`](#requiredminimumversion) instead. See [Pin a minimum version](../01-Getting-Started/setup.md#pin-a-minimum-version).


[​](#requiredmaximumversion)

`requiredMaximumVersion`

Set the newest Claude Code version your organization allows to start. When the running version is newer, Claude Code exits at startup and tells the user to install an approved version through your organization’s approved method; `claude install <version>` may also work. Requires Claude Code v2.1.163 or later.

- **Scope**: [`Managed`](#scopes). Claude Code gives no warning when it ignores the key elsewhere.
- **Type**: string, a version number such as `"2.1.150"`; a value that isn’t a valid version is ignored
- **Default**: unset, so no ceiling applies

managed-settings.json

```python
{
  "requiredMaximumVersion": "2.1.150"
}
```

Background auto-updates and `claude update` skip versions above the ceiling, so an installation inside the range stays inside it. `claude update`, `claude install`, and `claude doctor` keep working above the ceiling so users can recover. Pair it with [`requiredMinimumVersion`](#requiredminimumversion) to enforce a range.


[​](#requiredminimumversion)

`requiredMinimumVersion`

Set the oldest Claude Code version your organization allows to start. When the running version is older, Claude Code exits at startup and tells the user to update through your organization’s approved method. The check runs at startup only, so a session that’s already running continues. Requires Claude Code v2.1.163 or later.

- **Scope**: [`Managed`](#scopes). Claude Code gives no warning when it ignores the key elsewhere.
- **Type**: string, a version number such as `"2.1.150"`; a value that isn’t a valid version is ignored
- **Default**: unset, so no floor applies

managed-settings.json

```python
{
  "requiredMinimumVersion": "2.1.150"
}
```

`claude update`, `claude install`, and `claude doctor` keep working below the floor so users can recover. Unlike [`minimumVersion`](#minimumversion), which only prevents downgrades, this key blocks startup. Pair it with [`requiredMaximumVersion`](#requiredmaximumversion) to enforce a range.


[​](#tools)

Tools

Turn off specific tools in the [Claude Code desktop app](../16-Mobile-Desktop/desktop.md). The terminal CLI ignores these keys. For the tools themselves, see [Tools available to Claude](tools-reference.md).


[​](#browserexternalpagetools)

`browserExternalPageTools`

Stop Claude from using its tools to read or act on external pages in the desktop app’s [Browser pane](../16-Mobile-Desktop/desktop.md#browse-external-sites). People in your organization can still open external sites themselves, and local dev server previews keep working with Claude’s tools. The desktop app reads this key; the terminal CLI ignores it.

- **Scope**: [`Managed`](#scopes)
- **Type**: string, `"disabled"`; the desktop app also accepts `"disable"`, in either case
- **Default**: unset, so Claude’s tools work on external pages

managed-settings.json

```python
{
  "browserExternalPageTools": "disabled"
}
```

Any other value leaves Claude’s tools on, and a non-empty string that isn’t one of the two accepted values logs a warning. To block external sites for people and Claude alike, set [`disableBrowserExternalNavigation`](#disablebrowserexternalnavigation) instead. See [Restrict external browsing for your organization](../16-Mobile-Desktop/desktop.md#restrict-external-browsing-for-your-organization).


[​](#disablebrowserexternalnavigation)

`disableBrowserExternalNavigation`

Turn off external browsing in the desktop app’s [Browser pane](../16-Mobile-Desktop/desktop.md#browse-external-sites) for people and Claude alike. Localhost dev server previews keep working. The desktop app reads this key; the terminal CLI ignores it.

- **Scope**: [`Managed`](#scopes)
- **Type**: Boolean; only the JSON Boolean `true` takes effect
  - `true`: the desktop app turns off external browsing in the Browser pane for people and Claude alike; localhost previews keep working
  - `false`: external browsing stays on
- **Default**: unset, so external browsing is on

managed-settings.json

```python
{
  "disableBrowserExternalNavigation": true
}
```

The desktop app ignores any other value, and a value that isn’t a Boolean, such as the string `"true"` or `1`, also logs a warning. To leave external browsing on but keep Claude’s tools off external pages, set [`browserExternalPageTools`](#browserexternalpagetools) instead. See [Restrict external browsing for your organization](../16-Mobile-Desktop/desktop.md#restrict-external-browsing-for-your-organization).


[​](#disablemobilesimulatortools)

`disableMobileSimulatorTools`

Block Claude’s tools for the desktop app’s [iOS Simulator pane](../16-Mobile-Desktop/desktop-ios-simulator.md#turn-off-simulator-access). People keep manual use of the pane; only Claude’s access is removed, and nobody can turn it back on from inside the app. The desktop app reads this key; the terminal CLI ignores it.

- **Scope**: [`Managed`](#scopes)
- **Type**: Boolean; only the JSON Boolean `true` takes effect
  - `true`: the desktop app blocks Claude’s tools for the iOS Simulator pane
  - `false`: Claude’s simulator tools follow each person’s settings toggle in the desktop app
- **Default**: unset, so Claude’s simulator tools follow each person’s settings toggle in the desktop app

managed-settings.json

```python
{
  "disableMobileSimulatorTools": true
}
```

The desktop app ignores any other value, and a value that isn’t a Boolean, such as the string `"true"` or `1`, also logs a warning.


[​](#privacy-and-telemetry)

Privacy and telemetry

Control how long Claude Code keeps session data and what it sends. The switches that turn off usage metrics and error reports are environment variables, not settings keys: set `DISABLE_TELEMETRY`, `DISABLE_ERROR_REPORTING`, or `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` in the [`env`](#env) key or in the shell. [Telemetry services](../13-Enterprise-Admin/data-usage.md#telemetry-services) says what each one stops. Two exceptions turn off from a settings file: [`feedbackDrafts`](#feedbackdrafts) below for Claude-drafted feedback, and [`feedbackSurveyRate`](#feedbacksurveyrate) below for the session survey.


[​](#cleanupperioddays)

`cleanupPeriodDays`

Set how many days Claude Code keeps [session transcripts and other application data](claude-directory.md#cleaned-up-automatically) before deleting them. Claude Code runs the deletion as a background sweep after a session starts, as long as it can safely determine the retention period. The sweep deletes transcripts without showing a message, so a session you haven’t used for longer than the retention period no longer appears in the [`/resume`](sessions.md#resume-a-session) picker.

- **Scope**: [`Any file`](#scopes)
- **Type**: number of days, a whole number, minimum `1`
- **Default**: `30`

settings.json

```python
{
  "cleanupPeriodDays": 20
}
```

Setting `0` fails validation, so pick a large value such as `3650` for long retention. To stop Claude Code from writing transcripts at all, see [Plaintext storage](claude-directory.md#plaintext-storage).


[​](#desktopsessioncleanupperioddays)

`desktopSessionCleanupPeriodDays`

Set an age limit in days for the transcripts of sessions you started or most recently continued in Claude Desktop or Cowork. Without this key, Claude Code [keeps those transcripts at any age](claude-directory.md#cleaned-up-automatically). Claude Code deletes each one once it’s older than both this limit and [`cleanupPeriodDays`](#cleanupperioddays), so with `cleanupPeriodDays` at its default of 30, a value of `7` still keeps them 30 days. [Cleaned up automatically](claude-directory.md#cleaned-up-automatically) lists the cases where `cleanupPeriodDays` applies instead and Claude Code ignores this key. Requires Claude Code v2.1.248 or later.

- **Scope**: [`User or managed`](#scopes). Claude Code also reads the key from a file you pass with `--settings`, and ignores it in project and local settings.
- **Type**: number of days, a whole number, minimum `0`
- **Default**: `0`, which sets no age limit

settings.json

```python
{
  "desktopSessionCleanupPeriodDays": 90
}
```


[​](#feedbackdrafts)

`feedbackDrafts`

Control [Claude-drafted feedback](tools-reference.md#sendfeedback-tool-behavior): whether Claude can queue feedback drafts for you to review, and whether Claude Code shows a card when Claude queues one.

- **Scope**: [`User or managed`](#scopes)
- **Type**: string, one of `"notify"`, `"quiet"`, or `"off"`
  - `"notify"`: Claude Code shows a card above the prompt when Claude queues a draft, up to [three cards in a session](tools-reference.md#what-you-see-when-claude-drafts) by default
  - `"quiet"`: Claude drafts without a card. You see the count of queued drafts in the prompt footer and review them in `/feedback`
  - `"off"`: Claude Code removes the SendFeedback tool, so Claude can’t queue drafts
- **Default**: `"notify"`
- **Per-session overrides**: [`CLAUDE_CODE_SEND_FEEDBACK`](env-vars.md) set to `0` turns the feature off for one session

settings.json

```python
{
  "feedbackDrafts": "quiet"
}
```

Appears in `/config` as **Claude-drafted feedback**, which writes this key to your user settings. You see the `/config` row only in sessions [where Claude can draft feedback](tools-reference.md#sessions-without-claude-drafted-feedback); setting `"off"` doesn’t hide it, so you can turn the feature back on from the same row. A value in managed settings takes precedence over your user setting, so when an administrator sets this key, the row shows the managed value and changing it has no effect. Claude Code ignores this key in project and local settings.


[​](#feedbacksurveyrate)

`feedbackSurveyRate`

Set the probability that the [session quality survey](../13-Enterprise-Admin/data-usage.md#session-quality-surveys) appears when a session is eligible for it. Set `0` to keep the survey from appearing.

- **Scope**: [`Any file`](#scopes)
- **Type**: number between `0` and `1`
- **Default**: unset, so Claude Code uses the rate Anthropic sets remotely, or its built-in rate of `0.005` on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry, which don’t receive remote configuration
- **Per-session overrides**: [`CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY`](env-vars.md) set to `1` turns the survey off for one session whatever rate this key sets

settings.json

```python
{
  "feedbackSurveyRate": 0.05
}
```

The same rate applies to the survey in the VS Code extension.


[​](#skipwebfetchpreflight)

`skipWebFetchPreflight`

Skip the [WebFetch domain safety check](../13-Enterprise-Admin/data-usage.md#webfetch-domain-safety-check), which sends each requested hostname to `api.anthropic.com` before fetching. Set `true` in environments that block traffic to Anthropic, such as Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry deployments with restrictive egress.

- **Scope**: [`Any file`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code skips the WebFetch domain safety check
  - `false`: the check runs before the first fetch to each hostname in a session, and again for a hostname whose earlier check was blocked or failed
- **Default**: unset, so the check runs before the first fetch to each hostname in a session

settings.json

```python
{
  "skipWebFetchPreflight": true
}
```

With the check skipped, WebFetch attempts any URL without consulting the blocklist, so pair it with [`WebFetch` permission rules](permissions.md#webfetch) if you need to restrict which domains Claude can reach.


[​](#enterprise-and-managed-settings)

Enterprise and managed settings

Keys an organization uses to compute, refresh, and combine managed settings. See [Set up managed settings](../13-Enterprise-Admin/admin-setup.md).


[​](#disablesideloadflags)

`disableSideloadFlags`

Reject the `--plugin-dir`, `--plugin-url`, `--agents`, and `--mcp-config` CLI flags at startup, which users could otherwise pass to bypass [`strictKnownMarketplaces`](#strictknownmarketplaces) for a single run. Claude Code exits with an error naming the rejected flags. In [cloud sessions](claude-code-on-the-web.md), Claude Code instead starts the session and drops every server-delivered `--mcp-config` entry except in-process `type: "sdk"` entries and a [Claude Tag](claude-tag.md) session’s Slack tools. Requires Claude Code v2.1.193 or later.

- **Scope**: [`Managed`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code rejects `--plugin-dir`, `--plugin-url`, `--agents`, and `--mcp-config` at startup and exits with an error naming them. In cloud sessions, it instead starts the session and drops every server-delivered `--mcp-config` entry except in-process `type: "sdk"` entries and a Claude Tag session’s Slack tools
  - `false`: Claude Code accepts those flags
- **Default**: `false`

managed-settings.json

```python
{
  "disableSideloadFlags": true
}
```

Claude Code still accepts a `--mcp-config` whose servers are all in-process `type: "sdk"` entries, so the Agent SDK and VS Code extension keep working. Users can still add servers with `claude mcp add` or a `.mcp.json` file; for per-server control, set [`allowedMcpServers`](../06-MCP-Tools/General/managed-mcp.md) as well. Requires Claude Code v2.1.193 or later. The same check covers plugin folders named in the [`CLAUDE_CODE_PLUGIN_DIRS`](env-vars.md#variables) environment variable, which requires Claude Code v2.1.280 or later. When the variable names a folder, Claude Code exits with the same error, and the error says to unset the variable. In cloud sessions, Claude Code also ignores server-delivered mid-session MCP updates, the path behind cloud session configuration and SDK `setMcpServers()` calls that reach those sessions. In-process `type: "sdk"` entries and a Claude Tag session’s Slack tools stay exempt there too. Before v2.1.268, both this drop and the startup drop also removed a Claude Tag session’s Slack tools. Before v2.1.239, a server-delivered `--mcp-config` blocked a cloud session from starting. The desktop app manages some plugins itself, including plugins synced from claude.ai and plugins your organization deploys through the app. If you deploy this key to a device through MDM, OS-level policy, or a managed settings file, the desktop app doesn’t pass those plugins to the following sessions on that device:

- **[Code sessions on the user’s machine](../16-Mobile-Desktop/desktop.md#environment-configuration)**: they also start without the skills enabled for the user’s claude.ai account. Plugins that Claude Code installs from marketplaces in your managed settings still load. In [Claude Desktop on 3P](https://claude.com/docs/third-party/claude-desktop/overview), MCP servers from plugins you deploy to the device’s `org-plugins` directory stay available too, because the desktop app connects to them itself. Before Claude Desktop v1.37937.0, these sessions failed at startup instead.
- **[Cowork sessions on the user’s machine](../13-Enterprise-Admin/managed-settings.md#where-and-when-a-policy-applies)**: the skills inside those plugins and the skills enabled for the user’s claude.ai account stay available. In [Claude Desktop on 3P](https://claude.com/docs/third-party/claude-desktop/overview), MCP servers from plugins you deploy to the device’s `org-plugins` directory stay available too, because the desktop app connects to them itself. Before Claude Desktop v1.44121.0, these sessions failed at startup instead.


[​](#forceremotesettingsrefresh)

`forceRemoteSettingsRefresh`

Block CLI startup until Claude Code has freshly fetched [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md). If the fetch fails, Claude Code exits instead of continuing with cached or no settings. Set it when your environment can’t accept even a brief window in which a session runs without its managed policy. When the key is unset, Claude Code doesn’t block startup on the fetch, though when the developer signs in at startup it waits up to five seconds for the fetch. A Cloud gateway session always waits, and exits if the gateway can’t be reached.

- **Scope**: [`Managed`](#scopes). Claude Code honors a `true` from any admin-controlled managed source, even one that isn’t the highest-priority source.
- **Type**: Boolean
  - `true`: Claude Code blocks startup until it has freshly fetched server-managed settings, and exits if the fetch fails
  - `false`: Claude Code doesn’t block startup on the fetch, though at a sign-in startup it waits up to five seconds for the fetch
- **Default**: `false`

managed-settings.json

```python
{
  "forceRemoteSettingsRefresh": true
}
```

Set it in an MDM profile or the managed settings file to enforce fail-closed startup before the first server payload arrives. Claude Code applies the check only in sessions that fetch server-managed settings, so a session that [doesn’t fetch them](../13-Enterprise-Admin/server-managed-settings.md#platform-availability) starts without waiting. The `claude auth` subcommands are exempt, so users can re-authenticate when expired credentials are why the fetch fails. See [Enforce fail-closed startup](../13-Enterprise-Admin/server-managed-settings.md#enforce-fail-closed-startup).


[​](#managedsourcesbehavior)

`managedSourcesBehavior`

Choose whether Claude Code applies only the highest-priority [managed source](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) your organization delivers, or combines every admin source it delivers. By default Claude Code takes the highest-priority source that carries a [policy key](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) and ignores the rest. A policy key is any settings key other than this one and `wslInheritsWindowsSettings`. Under that default, once server-managed settings or an MDM policy deliver a policy key, a `managed-settings.json` file contributes only the [keys Claude Code reads from every admin source](../13-Enterprise-Admin/managed-settings.md#keys-read-from-every-admin-source). With `"merge"`, every admin source you deliver contributes its keys to one combined policy. Requires Claude Code v2.1.242 or later. Set `"merge"` only where every source [ranked](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) below your highest one is under an administrator’s control, because Claude Code then adds entries from a lower source, such as `permissions.allow` rules, to the policy.

- **Scope**: [`Managed`](#scopes). Claude Code reads this key from the highest-priority source that carries either this key or a policy key, and ignores this key in every source ranked lower, so a lower source can’t opt itself into combining with the source above it. Neither the Windows HKCU registry nor [parent settings from an embedding host](../13-Enterprise-Admin/managed-settings.md#let-an-embedding-host-add-policy) take part in the merge.
- **Type**: string, one of:
  - `"first-wins"`: the highest-priority source that carries a policy key supplies the policy, and lower sources contribute only the [keys Claude Code reads from every admin source](../13-Enterprise-Admin/managed-settings.md#keys-read-from-every-admin-source)
  - `"merge"`: every admin source you deliver contributes its keys, combined by the rules below
- **Default**: `"first-wins"`

Deliver the key in the highest-priority source you deploy. A machine that never receives server-managed settings needs the key in its MDM profile too, because Claude Code reads the key from the highest-priority source that carries it or a policy key. A `managed-settings.json` file is the lowest-ranked admin source, so `"merge"` set there has no source below it to combine with. In server-managed settings, the key looks like this:

```python
{
  "managedSourcesBehavior": "merge"
}
```

Under `"merge"`, Claude Code combines each key by its kind. This table gives the rule for each kind. The restriction allowlist, values-taken-whole, and highest-source-only rows name every key they cover, and the other rows give examples:

| Kind of key                                | How Claude Code combines it                                                                                                                                                                          | Keys                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
|:-------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Lists                                      | Combines entries from every source                                                                                                                                                                   | [`permissions.allow`](#permissions-allow), [`sandbox.network.allowedDomains`](#sandbox-network-alloweddomains), and other list keys                                                                                                                                                                                                                                                                                                                                                                                               |
| Locks                                      | Applies the strictest value any source sets. When no source sets a strict value, applies a looser value only from the highest source                                                                 | [`allowManagedPermissionRulesOnly`](#allowmanagedpermissionrulesonly), [`permissions.disableBypassPermissionsMode`](#permissions-disablebypasspermissionsmode), and other boolean or enum locks                                                                                                                                                                                                                                                                                                                                   |
| Restriction allowlists                     | Takes the list whole from the highest source that sets it, without adding entries from lower sources. When the highest source doesn’t set one, takes it whole from the next source down              | [`availableModels`](#availablemodels), [`allowedMcpServers`](#allowedmcpservers), [`allowedProviders`](#allowedproviders), [`strictKnownMarketplaces`](#strictknownmarketplaces), [`allowedChannelPlugins`](#allowedchannelplugins), and the [`fallbackModel`](#fallbackmodel) chain                                                                                                                                                                                                                                              |
| Values taken whole                         | Takes the value whole from the highest source that sets it, without combining entries or fields from lower sources. When the highest source doesn’t set it, takes it whole from the next source down | [`sandbox.credentials.awsPairs`](#sandbox-credentials-awspairs), [`sandbox.ripgrep`](#sandbox-ripgrep)                                                                                                                                                                                                                                                                                                                                                                                                                            |
| Provided MCP servers                       | Combines the server names from every source. When two sources set the same name, applies the higher source’s whole entry                                                                             | [`managedMcpServers`](#managedmcpservers)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Read from the highest-priority source only | Reads the key only from the highest-priority source that carries a policy key, so a lower source’s value is ignored even when the highest source sets none                                           | [`apiKeyHelper`](#apikeyhelper), [`awsAuthRefresh`](#awsauthrefresh), [`awsCredentialExport`](#awscredentialexport), [`gcpAuthRefresh`](#gcpauthrefresh), [`otelHeadersHelper`](#otelheadershelper), `proxyAuthHelper`, [`forceLoginOrgUUID`](#forceloginorguuid), the `"claudeai"` and `"console"` values of [`forceLoginMethod`](#forceloginmethod), [`parentSettingsBehavior`](#parentsettingsbehavior), [`modelPicker`](#modelpicker), [`policyHelper`](#policyhelper), [`permissions.defaultMode`](#permissions-defaultmode) |
| `env`                                      | [Merges per variable across admin sources](../13-Enterprise-Admin/managed-settings.md#keys-read-from-every-admin-source), under both `"first-wins"` and `"merge"`                                                     | [`env`](#env)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Every other key                            | Takes the value from the highest source that sets it                                                                                                                                                 | [`cleanupPeriodDays`](#cleanupperioddays), [`model`](#model)                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |

Taking `sandbox.credentials.awsPairs` and `sandbox.ripgrep` whole requires Claude Code v2.1.257 or later. A few keys add a condition that the table doesn’t show:

- **[`policyHelper`](#policyhelper)**: Claude Code honors it only when the highest source that carries a policy key is an MDM policy or a managed settings file, so under server-managed settings it doesn’t apply.
- **[`modelOverrides`](#modeloverrides)**: pairs with `availableModels`. Claude Code takes `modelOverrides` from the highest source that sets it, unless a higher source sets `availableModels` without `modelOverrides`. In that case it ignores `modelOverrides` from every source.
- **[`forceLoginGatewayUrl`](#forcelogingatewayurl), [`gatewayInternalNetworks`](#gatewayinternalnetworks), and the `"gateway"` value of [`forceLoginMethod`](#forceloginmethod)**: Claude Code never reads any of them from server-managed settings, so a value there neither applies nor hides one set in an MDM policy or managed settings file. Among the admin sources on the machine, only the highest-ranked one that carries a policy key supplies them, whether or not server-managed settings are also present.
- **[`allowedProviders`](#allowedproviders)**: after the table’s rule, the machine’s own list still limits the result, as its entry’s Scope note states.

To confirm which sources combined on a machine, run `/status` and [read the `Setting sources` line](../13-Enterprise-Admin/managed-settings.md#read-the-source-in-/status).


[​](#parentsettingsbehavior)

`parentSettingsBehavior`

Choose whether Claude Code applies managed settings supplied by an embedding host process, such as the Agent SDK or an IDE extension, when an admin-deployed managed tier is also present. With `"first-wins"`, Claude Code drops the host-supplied settings; with `"merge"`, it applies them under the admin tier through a restrictive-only filter. Set `"merge"` when a host needs to pass its own restrictions to the sessions it launches, for example Claude Desktop delivering a gateway’s egress allowlist.

- **Scope**: [`Managed`](#scopes). Claude Code reads it from the highest-priority admin-controlled managed source.
- **Type**: string, one of:
  - `"first-wins"`: Claude Code drops the host-supplied settings when an admin-deployed managed tier is present
  - `"merge"`: Claude Code applies the host-supplied settings under the admin tier through a restrictive-only filter
- **Default**: `"first-wins"`

managed-settings.json

```python
{
  "parentSettingsBehavior": "merge"
}
```

This key has no effect when no admin-deployed managed tier exists: the host’s settings then apply as the only managed tier, still filtered to restrictive values. For the filter’s limits and how the managed sources interact, see [Parent settings from embedding hosts](../13-Enterprise-Admin/managed-settings.md#parent-settings-from-embedding-hosts) and [Restrict parent settings](../13-Enterprise-Admin/claude-apps-gateway.md#restrict-parent-settings).


[​](#policyhelper)

`policyHelper`

Run an executable you deploy that computes managed settings at startup, so you can derive policy from device posture, identity, or a remote service instead of a static file. Claude Code runs the helper before it accepts the first prompt and treats the settings it emits as the managed settings for the session.

- **Scope**: [`Managed`](#scopes). Read from the macOS plist, the Windows HKLM registry, or the managed settings file. Claude Code reads the key from the highest-priority managed source that carries a [policy key](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) and runs the helper only when that source is one of those three; it ignores the key in server-managed settings, the HKCU registry, and host-supplied parent settings.
- **Type**: object with `path`, `timeoutMs`, and `refreshIntervalMs`
- **Default**: unset, so no helper runs

When server-managed settings deliver the policy at launch, they take precedence over the helper’s source and the helper doesn’t run. If a later settings fetch reports the server-managed settings removed, Claude Code runs the helper at that point rather than waiting for the next launch. Its output governs the rest of the session, and a run that fails ends the session with the same message as a [failed startup run](#helper-failures). This example runs the helper with a 5-second timeout and re-runs it every five minutes:

managed-settings.json

```python
{
  "policyHelper": {
    "path": "/usr/local/bin/claude-policy",
    "timeoutMs": 5000,
    "refreshIntervalMs": 300000
  }
}
```


[​](#write-the-helper-output)

Write the helper output

Claude Code runs the helper with no arguments, sets `CLAUDE_CODE_VERSION` in its environment, and reads a JSON envelope from stdout, capped at 1 MiB. Put the settings under a `managedSettings` key. A bare settings object with no `managedSettings` key parses with `managedSettings` undefined and applies nothing, and Claude Code reports no error:

```python
{
  "managedSettings": {
    "permissions": { "deny": ["Read(//etc/secrets/**)"] }
  }
}
```

When the helper emits `managedSettings`, that object becomes the only managed settings source for the run: Claude Code ignores the MDM, file, and HKCU sources, reads the [cross-source keys](../13-Enterprise-Admin/managed-settings.md#keys-read-from-every-admin-source) from the helper’s output alone, and never merges [parent settings](../13-Enterprise-Admin/managed-settings.md#parent-settings-from-embedding-hosts). The startup `forceRemoteSettingsRefresh` check runs before the helper and reads any admin source. A helper that exits `0` with an envelope that omits `managedSettings` contributes no managed settings, and the other sources apply as usual.


[​](#helper-failures)

Helper failures

A helper run fails when:

- `path` breaks the rules in [`policyHelper.path`](#policyhelper-path).
- No regular file is at `path`. Claude Code checks for the file before starting the helper, within the same `timeoutMs` budget, so an unresponsive network mount can cause the run to fail.
- The helper exits non-zero, is still running when `timeoutMs` elapses, or doesn’t start at all, for example because it isn’t executable.
- The helper writes more than 1 MiB to stdout or to stderr.
- stdout isn’t a single JSON object, or its `managedSettings` has a [schema violation Claude Code can’t repair](../13-Enterprise-Admin/managed-settings.md#find-entries-claude-code-dropped).

When the startup run fails, Claude Code prints the reason and refuses to start. After a non-zero exit, the reason includes the helper’s stderr, or its stdout when stderr is empty. After a timeout, the reason names the `timeoutMs` limit and includes none of the helper’s output. The refusal covers interactive sessions, `claude -p`, Agent SDK sessions, [background sessions](../09-Agents-Patterns/agent-view.md), and most subcommands. The refusal is deliberate, so a helper that needs outage resilience should serve from its own cache and exit `0`. When a background refresh fails, Claude Code keeps the last successful policy in effect, and `/status` shows the failing refresh with its reason until a refresh succeeds. Each refresh runs under the same `timeoutMs` and failure rules as the startup run. With `--debug`, Claude Code writes the helper’s stderr from every run to the [debug log](debug-your-config.md). Claude Code reports an invalid `policyHelper` value as a [dropped entry](../13-Enterprise-Admin/managed-settings.md#find-entries-claude-code-dropped) and starts the session on the remaining managed settings without running a helper. Invalid values include a bare path string and a `timeoutMs` below [its minimum](#policyhelper-timeoutms). To turn a helper off, remove the key from the source that sets it.


[​](#policyhelper-path)

`policyHelper.path`

Name the helper executable Claude Code runs. For what happens when the path breaks the rules below, see [Helper failures](#helper-failures).

- **Scope**: [`Managed`](#scopes). Read from the macOS plist, the Windows HKLM registry, or the managed settings file, wherever [`policyHelper`](#policyhelper) is read.
- **Type**: string, an absolute path in normalized form, without `.` or `..` segments; on Windows, a drive-letter or UNC path that ends in `.exe`
- **Default**: none; required when `policyHelper` is set

managed-settings.json

```python
{
  "policyHelper": {
    "path": "/usr/local/bin/claude-policy"
  }
}
```


[​](#policyhelper-timeoutms)

`policyHelper.timeoutMs`

Set how long Claude Code waits for the helper before treating the run as failed. A timed-out run fails the same way as a non-zero exit, so at startup Claude Code refuses to start.

- **Scope**: [`Managed`](#scopes). Read from the macOS plist, the Windows HKLM registry, or the managed settings file, wherever [`policyHelper`](#policyhelper) is read.
- **Type**: integer, milliseconds, minimum `1000`
- **Default**: `10000`

managed-settings.json

```python
{
  "policyHelper": {
    "path": "/usr/local/bin/claude-policy",
    "timeoutMs": 5000
  }
}
```


[​](#policyhelper-refreshintervalms)

`policyHelper.refreshIntervalMs`

Have Claude Code re-run the helper in the background on an interval so policy changes reach a running session. When a refresh succeeds, its output replaces the previous managed settings without a restart; when a refresh fails, Claude Code keeps the policy it already has.

- **Scope**: [`Managed`](#scopes). Read from the macOS plist, the Windows HKLM registry, or the managed settings file, wherever [`policyHelper`](#policyhelper) is read.
- **Type**: integer, milliseconds: `0` to disable refresh, otherwise at least `60000`
- **Default**: unset, so Claude Code runs the helper once at startup

This example re-runs the helper every five minutes:

managed-settings.json

```python
{
  "policyHelper": {
    "path": "/usr/local/bin/claude-policy",
    "refreshIntervalMs": 300000
  }
}
```


[​](#wslinheritswindowssettings)

`wslInheritsWindowsSettings`

Have Claude Code on WSL read managed settings from the Windows policy chain, with HKLM and the Windows managed settings file taking priority over `/etc/claude-code` and HKCU below it. While the chain is on, Claude Code reads `/etc/claude-code` only when [no Windows admin document is present](../13-Enterprise-Admin/managed-settings.md#present-admin-documents) in the HKLM registry value or the `C:\Program Files\ClaudeCode\` folder. Set it to extend the policy you already deploy on Windows to WSL sessions on the same machine, so they follow the same rules as host sessions. Claude Code honors it only when set in the HKLM registry key or in a managed settings file or drop-in under `C:\Program Files\ClaudeCode\`, both of which require Windows admin to write.

- **Scope**: [`Managed`](#scopes). In an admin-controlled Windows source.
- **Type**: Boolean
  - `true`: Claude Code on WSL reads managed settings from the Windows policy chain, and reads `/etc/claude-code` only when no Windows admin document is present
  - `false`: WSL reads only `/etc/claude-code`
- **Default**: `false`, so WSL reads only `/etc/claude-code`

managed-settings.json

```python
{
  "wslInheritsWindowsSettings": true
}
```

Once an admin source turns the chain on, HKCU policy joins it on WSL only when HKCU also sets the key to `true`. That copy doesn’t turn the chain on by itself. A Windows source that contains only this key, set to `true` or `false`, doesn’t count as a policy source, so a lower-priority source still supplies the policy. This key has no effect on native Windows. Claude Code reads `true` and `false` with or without quotes and reads `null` as removing the key. An admin-controlled Windows source that holds any other value counts as a [present admin document](../13-Enterprise-Admin/managed-settings.md#present-admin-documents) with the chain turned on: neither `/etc/claude-code` nor HKCU applies, and a startup warning names the key. An HKLM value or Windows-folder file that exists but can’t be read also keeps `/etc/claude-code` from applying whether or not the chain is on. Requires Claude Code v2.1.282 or later.


[​](#global-config-settings)

Global config settings

Save these keys in `~/.claude.json`, not in a settings file. Claude Code ignores them anywhere else. Claude Code and `/config` write most of them for you, and you can also edit them by hand.


[​](#autoconnectide)

`autoConnectIde`

Connect to a running IDE automatically when you start Claude Code from an external terminal. Appears in `/config` as **Auto-connect to IDE (external terminal)** when you run Claude Code outside a VS Code or JetBrains terminal.

- **Scope**: [`Global config`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code connects to a running IDE automatically when you start it from an external terminal
  - `false`: Claude Code doesn’t connect automatically from an external terminal; inside a VS Code or JetBrains terminal, or with `--ide`, it still connects
- **Default**: `false`
- **Per-session overrides**: [`CLAUDE_CODE_AUTO_CONNECT_IDE`](env-vars.md) takes precedence over this key for one session, in either direction

~/.claude.json

```python
{
  "autoConnectIde": true
}
```

Claude Code ignores this key in `settings.json`.


[​](#autoinstallideextension)

`autoInstallIdeExtension`

Install the Claude Code IDE extension automatically when you run Claude Code from a VS Code terminal. Appears in `/config` as **Auto-install IDE extension** when you run Claude Code inside a VS Code or JetBrains terminal.

- **Scope**: [`Global config`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code installs the IDE extension automatically when you run it from a VS Code terminal
  - `false`: Claude Code doesn’t install the extension automatically
- **Default**: `true`
- **Per-session overrides**: [`CLAUDE_CODE_IDE_SKIP_AUTO_INSTALL`](env-vars.md) set to `1` skips the install for one session even when this key is `true`

~/.claude.json

```python
{
  "autoInstallIdeExtension": false
}
```

Claude Code ignores this key in `settings.json`.


[​](#claudeinchromedefaultenabled)

`claudeInChromeDefaultEnabled`

Start every interactive CLI session with [Chrome integration](../03-IDE-Integrations/chrome.md) on, without passing `--chrome` each time. If you run [`claude remote-control`](remote-control.md), a session it starts for one of your [project](claude-projects.md) threads follows this key too, except in `bypassPermissions` mode. With Claude Code v2.1.287 or later, this key also applies to sessions in the [VS Code extension](../03-IDE-Integrations/vs-code.md#automate-browser-tasks-with-chrome): see [Enable Chrome by default](../03-IDE-Integrations/chrome.md#enable-chrome-by-default). Running `/chrome` and selecting **Enabled by default** sets this key for you. Appears in `/config` as **Claude in Chrome enabled by default**.

- **Scope**: [`Global config`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code turns on Chrome integration when an interactive CLI session starts, as it does when you pass `--chrome`. In the VS Code extension, sessions connect to the browser as they start
  - `false`: interactive CLI sessions start with Chrome integration off, and Claude Code stops [offering to set it up](../03-IDE-Integrations/chrome.md#install-the-extension-when-claude-asks). Pass `--chrome` to turn it on for one interactive session. In the VS Code extension, a session connects when you type `@browser`, as when the key is unset
- **Default**: unset, so Chrome integration is off and Claude Code can still offer to set it up
- **Per-session overrides**: `--chrome` and [`--no-chrome`](cli-reference.md) take precedence over this key for one interactive session

~/.claude.json

```python
{
  "claudeInChromeDefaultEnabled": true
}
```

Claude Code ignores this key in `settings.json`.


[​](#copyfullresponse)

`copyFullResponse`

Make [`/copy`](commands.md) copy the full response every time, without showing the picker. Selecting **Always copy full response** in that picker sets this key to `true`. Appears in `/config` as **Skip the /copy picker**.

- **Scope**: [`Global config`](#scopes)
- **Type**: Boolean
  - `true`: `/copy` copies the full response without showing the picker
  - `false`: when the response contains code blocks or blockquotes, `/copy` shows a picker where you choose one block or the full response
- **Default**: `false`

~/.claude.json

```python
{
  "copyFullResponse": true
}
```

Claude Code ignores this key in `settings.json`.


[​](#copyonselect)

`copyOnSelect`

Copy text to your clipboard automatically when you finish selecting it with the mouse in [fullscreen rendering](fullscreen.md#use-the-mouse) or [agent view](../09-Agents-Patterns/agent-view.md). Appears in `/config` as **Copy on select** while fullscreen rendering is on.

- **Scope**: [`Global config`](#scopes)
- **Type**: Boolean
  - `true`: Claude Code copies text to your clipboard when you finish selecting it
  - `false`: selecting text leaves your clipboard unchanged, and you [copy the selection with a keyboard shortcut](fullscreen.md#use-the-mouse) instead
- **Default**: `true`

~/.claude.json

```python
{
  "copyOnSelect": false
}
```

Claude Code ignores this key in `settings.json`.


[​](#defaulttoagentsview)

`defaultToAgentsView`

Open [agent view](../09-Agents-Patterns/agent-view.md) instead of a new conversation when you run `claude` with no arguments. Appears in `/config` as **Open agents view by default** unless agent view is [turned off](#disableagentview).

- **Scope**: [`Global config`](#scopes)
- **Type**: Boolean
  - `true`: `claude` with no arguments opens agent view, unless agent view is [turned off](#disableagentview)
  - `false`: `claude` with no arguments starts a new conversation
- **Default**: `false`

~/.claude.json

```python
{
  "defaultToAgentsView": true
}
```

Claude Code ignores this key in `settings.json`.


[​](#difftool)

`diffTool`

Choose where Claude Code shows the diff of an `Edit` or `Write` change it proposes when a [VS Code](../03-IDE-Integrations/vs-code.md) or [JetBrains](../03-IDE-Integrations/jetbrains.md#features) IDE is connected: `"auto"` opens it in the IDE’s diff viewer, `"terminal"` keeps it in the terminal. Appears in `/config` as **Diff tool** only while Claude Code is connected to a VS Code or JetBrains IDE.

- **Scope**: [`Global config`](#scopes)
- **Type**: string, one of:
  - `"auto"`: Claude Code opens the diff in the IDE’s diff viewer when a VS Code or JetBrains IDE is connected
  - `"terminal"`: Claude Code keeps the diff in the terminal
- **Default**: `"auto"`

~/.claude.json

```python
{
  "diffTool": "terminal"
}
```

Claude Code ignores this key in `settings.json`.


[​](#externaleditorcontext)

`externalEditorContext`

When you press `Ctrl+G`, Claude Code opens the prompt you’re typing in your [external editor](interactive-mode.md#general-controls). With this key on, the editor buffer starts with Claude’s previous response as `#` comment lines, so you can read it while you write, and Claude Code strips those lines when you save. Appears in `/config` as **Show last response in external editor**.

- **Scope**: [`Global config`](#scopes)
- **Type**: Boolean
  - `true`: the editor buffer starts with Claude’s previous response as `#` comment lines, which Claude Code strips when you save
  - `false`: the editor buffer opens with only your prompt
- **Default**: `false`

~/.claude.json

```python
{
  "externalEditorContext": true
}
```

With it on, the buffer Claude Code opens looks like this, and only the text below the marker line is sent as your prompt:

```python
# ─── Claude's last response (for reference; removed on save) ───
# I added the retry loop to fetchUser in src/api.ts and a test
# for the timeout case. Want me to wire the same retry into
# fetchOrders?
# ─── Write your reply below this line ──────────────────────────

Yes, and cap it at three attempts.
```

Claude Code keeps the last 50 lines of the response and marks the cut with `# … (earlier output truncated)`. Claude Code ignores this key in `settings.json`.


[​](#leftarrowopensagents)

`leftArrowOpensAgents`

Press `←` on an empty prompt to [background the session and open agent view](../09-Agents-Patterns/agent-view.md#switch-sessions-without-leaving-the-terminal). Set this key to `false` to turn the shortcut off. Appears in `/config` as **← opens agents** when agent view is available.

- **Scope**: [`Global config`](#scopes)
- **Type**: Boolean
  - `true`: pressing `←` on an empty prompt in a session you started in the terminal backgrounds it and opens agent view
  - `false`: Claude Code turns the shortcut off; in a session you [attached to from agent view](../09-Agents-Patterns/agent-view.md#attach-to-a-session), `←` on an empty prompt still detaches
- **Default**: `true`

~/.claude.json

```python
{
  "leftArrowOpensAgents": false
}
```

Claude Code ignores this key in `settings.json`.


[​](#permissionexplainerenabled)

`permissionExplainerEnabled`

Removed in v2.1.257, together with the `Ctrl+E` command explanation on Bash and PowerShell permission prompts. Setting it has no effect on current versions.

Through v2.1.256, you could press `Ctrl+E` on a Bash or PowerShell permission prompt to see a model-generated explanation of the command, and set this key to `false` to turn that shortcut off.

- **Scope**: [`Global config`](#scopes). On v2.1.256 and earlier.
- **Type**: Boolean
- **Default**: `true`


[​](#prstatusfooterenabled)

`prStatusFooterEnabled`

Show a badge in the prompt footer for the current branch’s open pull request or merge request, with a colored underline that shows its [status](interactive-mode.md#pr-review-status). Appears in `/config` as **Show PR status footer**.

- **Scope**: [`Global config`](#scopes)
- **Type**: Boolean
  - `true`: the footer shows the badge under the conditions in [PR review status](interactive-mode.md#pr-review-status)
  - `false`: Claude Code skips the footer’s pull request and merge request check and doesn’t show that badge. A session you [attached to from agent view](../09-Agents-Patterns/agent-view.md#attach-to-a-session) can still show a plain link to a pull request [linked to it](../09-Agents-Patterns/agent-view.md#pull-request-status)
- **Default**: `true`

~/.claude.json

```python
{
  "prStatusFooterEnabled": false
}
```

Claude Code ignores this key in `settings.json`.


[​](#teammatedefaultmodel)

`teammateDefaultModel`

Removed in v2.1.234, together with its `/config` row **Default teammate model**. Setting it has no effect on current versions.

Through v2.1.233, you set this key to the model for [agent team](../09-Agents-Patterns/agent-teams.md#specify-teammates-and-models) teammates your prompt didn’t name a model for: an alias such as `"sonnet"`, or `null` to follow the lead’s model. For the model Claude Code picks for such teammates now, see [specify teammates and models](../09-Agents-Patterns/agent-teams.md#specify-teammates-and-models).

- **Scope**: [`Global config`](#scopes). On v2.1.233 and earlier.
- **Type**: string, a model alias or full model ID, or `null`
- **Default**: unset


[​](#see-also)

See also

- [Configure permissions](permissions.md): rule syntax, permission modes, and workspace trust
- [Environment variables](env-vars.md): every `CLAUDE_*`, `ANTHROPIC_*`, and provider variable Claude Code reads
- [Tools available to Claude](tools-reference.md): the built-in tools and which need approval
- [Example settings files](settings-example.md): a personal file, a team file, and an organization’s managed file
- [Set up managed settings](../13-Enterprise-Admin/admin-setup.md): how organizations decide what to enforce
- [Deploy managed settings](../13-Enterprise-Admin/managed-settings.md): delivery mechanisms, precedence within the managed tier, and invalid entries in managed settings
- [Debug your configuration](debug-your-config.md): `claude doctor` and the Settings Error dialog

---

## Settings files and precedence - Claude Code Docs

Source: https://code.claude.com/docs/en/settings
Path: 02-Claude-Code-CLI/settings.md

## On this page

- [Settings files and who they affect](#settings-files-and-who-they-affect)
  - [Compare the scope of each settings file](#compare-the-scope-of-each-settings-file)
  - [Find or create your settings files](#find-or-create-your-settings-files)
  - [Share settings with your team](#share-settings-with-your-team)
  - [Keep personal settings out of a repository](#keep-personal-settings-out-of-a-repository)
  - [Where Claude Code keeps the local file in a git repository](#where-claude-code-keeps-the-local-file-in-a-git-repository)
  - [Check what your organization enforces](#check-what-your-organization-enforces)
- [Change a setting](#change-a-setting)
  - [Use the /config menu](#use-the-%2Fconfig-menu)
  - [Edit a settings file](#edit-a-settings-file)
  - [Change a setting for one session](#change-a-setting-for-one-session)
  - [When edits take effect](#when-edits-take-effect)
  - [Confirm what loaded](#confirm-what-loaded)
  - [Fix a broken settings file](#fix-a-broken-settings-file)
- [Settings precedence](#settings-precedence)
  - [Lists merge instead of overriding](#lists-merge-instead-of-overriding)
  - [Precedence examples](#precedence-examples)
  - [Team settings override personal settings](#team-settings-override-personal-settings)
  - [Organization settings override everything](#organization-settings-override-everything)
  - [The command line overrides your files for one session](#the-command-line-overrides-your-files-for-one-session)
  - [A flag or environment variable sets the same thing](#a-flag-or-environment-variable-sets-the-same-thing)
  - [Troubleshoot a setting that doesn’t apply](#troubleshoot-a-setting-that-doesn%E2%80%99t-apply)
  - [A value you set is ignored](#a-value-you-set-is-ignored)
  - [A change you made in Claude Code is lost in new sessions](#a-change-you-made-in-claude-code-is-lost-in-new-sessions)
  - [A managed change hasn’t reached you](#a-managed-change-hasn%E2%80%99t-reached-you)
  - [A committed key doesn’t reach teammates](#a-committed-key-doesn%E2%80%99t-reach-teammates)
  - [Permission rules combine differently than you expected](#permission-rules-combine-differently-than-you-expected)
  - [Exceptions to managed settings precedence](#exceptions-to-managed-settings-precedence)
- [Settings in cloud sessions](#settings-in-cloud-sessions)
- [What’s next](#what%E2%80%99s-next)

Settings

# Settings files and precedence

Copy pageCopy page

Change Claude Code settings, pick the scope a key belongs in, verify the change, and learn which value Claude Code uses when a key is set in several places.

Copy pageCopy page

Settings are the JSON keys that change how Claude Code behaves: which model it starts with, what it can run without asking, which files it can’t read, how it looks in your terminal, and what your organization enforces.

To look up a specific key, go to [All settings](settings-reference.md), which lists every key with the file you set it in, its default, and an example.

Claude Code reads settings from JSON settings files such as `~/.claude/settings.json`. It looks for them in a few locations, and [the file it reads a setting from decides who the setting applies to](#settings-files-and-who-they-affect). This page covers those files: which one to put a setting in, how to change a setting and confirm it applied, and which value Claude Code uses when the same key is set in more than one file. [Configure permissions](permissions.md) covers what Claude Code can run without asking and how to write `allow`, `ask`, and `deny` rules.

This page covers Claude Code running on your machine: the terminal, the [VS Code](../03-IDE-Integrations/vs-code.md) and [JetBrains](../03-IDE-Integrations/jetbrains.md) extensions, and the [desktop app](../16-Mobile-Desktop/desktop.md), which all read the same settings files. A [cloud session](claude-code-on-the-web.md) runs on a different machine and reads only some of them; see [Settings in cloud sessions](#settings-in-cloud-sessions).


[​](#settings-files-and-who-they-affect)

Settings files and who they affect

Claude Code reads settings from four files, and an organization can also deliver managed settings from the claude.ai console. Each source has a scope: the set of people and projects a setting saved in it applies to, whether that’s only you, everyone in a project, or everyone in your organization.

| Scope          | File                                                                                               | Who it affects                                                                                                                                     | Use it for                                                                         |
|:---------------|:---------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------|
| User           | `~/.claude/settings.json`                                                                          | You, in every project on this machine                                                                                                              | Personal preferences: theme, editor mode, default model, your own permission rules |
| Shared project | `.claude/settings.json`                                                                            | Everyone working in the folder that contains it. In a git repository, commit it so teammates get it                                                | Team permissions, hooks, plugins, and the environment variables the project needs  |
| Project local  | `.claude/settings.local.json`                                                                      | You, in this one project only. Claude Code keeps it out of git when it creates the file; if you create it by hand, add it to `.gitignore` yourself | Personal overrides for one project, and testing before you share                   |
| Managed        | `managed-settings.json` and other [managed sources](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms) | Everyone your organization deploys it to; [Settings precedence](#settings-precedence) says what can override it                                    | Security policy and compliance requirements                                        |

In the File column, `~/.claude` is the `.claude` folder in your home directory, and a bare `.claude` is the `.claude` folder inside your project.


[​](#compare-the-scope-of-each-settings-file)

Compare the scope of each settings file

Suppose you have three projects on your machine, `website/`, `api/`, and `acme-app/`, a teammate has their own clone of `acme-app/`, and you start a [cloud session](#settings-in-cloud-sessions) on `acme-app/`. The graphic below shows which of those folders a setting applies in when you start Claude Code from them. Click a settings file to see the folders it reaches.

- **`~/.claude/settings.json`**: every project on your machine, and nothing on your teammate’s or in the cloud session
- **`acme-app/.claude/settings.json`**: your `acme-app/`. It reaches your teammate’s clone and the cloud session only if you commit the file to version control; until you do, it’s a file on your disk like any other and nobody else has it
- **`acme-app/.claude/settings.local.json`**: your `acme-app/` only. Claude Code adds it to your global git excludes the first time it writes the file, so it stays out of your commits; if you create the file by hand, [add it to `.gitignore` yourself](#keep-personal-settings-out-of-a-repository)
- **Managed settings**, whether a `managed-settings.json` file, an MDM policy, or [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) from the claude.ai console: every project on every machine your organization deploys it to, or that you sign in to with your organization account. Only server-managed settings reach the cloud session


[​](#find-or-create-your-settings-files)

Find or create your settings files

Installing Claude Code doesn’t create any settings file. If your machine or project already has one, it came from one of these sources:

- **Managed**: your organization deploys it. You don’t create or edit it.
- **Shared project**: a project that already uses Claude Code may have one committed. If not, create it at `.claude/settings.json` in the project folder.
- **User** and **Project local**: create them yourself, or let Claude Code create them. It writes `~/.claude/settings.json` the first time you change an option in the `/config` menu that it stores in user settings, such as the theme, and `.claude/settings.local.json` the first time you give a standing approval on a permission prompt, such as “Yes, and don’t ask again” for a Bash command. A few `/config` options, including **Show tips**, save to `.claude/settings.local.json` instead of the user file.

On Windows, `~/.claude` means `%USERPROFILE%\.claude`. To keep the home-directory files somewhere else, set [`CLAUDE_CONFIG_DIR`](env-vars.md); Claude Code then stores your settings, session history, and plugins there instead.

Claude Code also keeps a fifth file, [`~/.claude.json`](claude-directory.md#ce-claude-json), that it writes for itself; you don’t need to edit it. It holds your account details, [MCP server](../06-MCP-Tools/General/mcp.md) configurations, per-project state such as trust decisions, and the [global config keys](settings-reference.md#global-config-settings) that `/config` writes for you.


[​](#share-settings-with-your-team)

Share settings with your team

Commit `.claude/settings.json` so everyone who clones the repository gets the same permissions, hooks, and plugins. Each teammate can still override it for themselves in their own `.claude/settings.local.json`, so personal exceptions don’t need a commit. For a complete team file, see [a team’s shared settings](settings-example.md#a-teams-shared-settings). Some of what you commit waits until each teammate [trusts the folder](permissions.md#project-allow-rules-and-workspace-trust), and a few keys never take effect from a repository file; [Troubleshoot a setting that doesn’t apply](#common-cases) covers both.


[​](#keep-personal-settings-out-of-a-repository)

Keep personal settings out of a repository

To change a setting for yourself in one project without changing it for your teammates, save it in `.claude/settings.local.json` inside the project. Claude Code applies that file over the committed `.claude/settings.json`, so if your team’s file sets `"model": "claude-sonnet-5"` and you want Opus, put `"model": "claude-opus-5-5"` in your local file and only your sessions change. Claude Code also writes to this file, keeps it out of your commits, and applies its allow rules without the trust step:

- **Claude Code writes it too.** When Claude asks permission to run a Bash command and you choose “Yes, and don’t ask again”, Claude Code saves that [permission approval](permissions.md#permission-system) here as an `allow` rule.
- **You don’t need to gitignore it yourself, unless you created it by hand.** The first time Claude Code writes the file in a git repository that doesn’t already ignore it, it adds `**/.claude/settings.local.json` to your global git excludes file, so the file stays out of your commits in every repository. That file is `core.excludesFile` when your global git config sets it to an absolute or `~`-prefixed path; otherwise it’s `$XDG_CONFIG_HOME/git/ignore`, or `~/.config/git/ignore` when `XDG_CONFIG_HOME` is unset. If you created the file by hand and Claude Code hasn’t written to it yet, add it to `.gitignore` yourself.
- **Its allow rules don’t wait for trust while the file stays untracked.** Because the file is yours and not the repository’s, Claude Code applies its `allow` rules without the [workspace trust](permissions.md#project-allow-rules-and-workspace-trust) step it requires for the committed file. If the file is tracked by git, the trust step applies to it too; see [When your local settings file needs trust](permissions.md#when-your-local-settings-file-needs-trust).


[​](#where-claude-code-keeps-the-local-file-in-a-git-repository)

Where Claude Code keeps the local file in a git repository

When Claude asks permission to run a Bash command and you choose “Yes, and don’t ask again”, Claude Code saves that approval as an `allow` rule in `.claude/settings.local.json`. If you start Claude Code in a subdirectory of a git repository, it reads and writes that file at the repository root and applies the approval across the whole repository. In a [worktree](worktrees.md), it uses the file at the main checkout’s root. Two rules qualify the root location:

- **When the file stays with `.claude/settings.json` instead**: outside a git repository, when the repository root is your home directory, on Windows, or when the repository root or its `.git` or `.claude` entry isn’t owned by your user.
- **Paths in the file don’t anchor at the repository root**: a permission rule that starts with `/` or a relative sandbox path [anchors at the session’s primary working directory](permissions.md#read-and-edit) instead.

Before v2.1.211, Claude Code kept the file in the starting directory. It still reads a file an earlier version left there alongside the root file; where both set the same key, the root’s value applies, and permission rules from both files apply. The Agent SDK’s [`resolveSettings()`](../05-Agent-SDK/agent-sdk-typescript.md#resolvesettings) helper always reads the file from the starting directory. Claude Code reads the shared `.claude/settings.json` from the session’s [primary working directory](permissions.md#working-directories), so to use a file committed at the repository root, start Claude Code there. After you [move the session with `/cd`](permissions.md#move-the-session-to-another-directory), Claude Code reads both project files from the new directory instead, placing the local file by the same rules. Reading them from the directory you moved to requires Claude Code v2.1.246 or later. For a worktree session that you start from the desktop app, see [What worktrees share with the main checkout](worktrees.md#what-worktrees-share-with-the-main-checkout).


[​](#check-what-your-organization-enforces)

Check what your organization enforces

If your organization manages Claude Code, some settings are decided for you and nothing you put in your own files changes them. To see which, run `/status`: the `Setting sources` line names the managed source that applies to you. Managed settings apply wherever Claude Code runs on this machine; [What a developer can change](../13-Enterprise-Admin/managed-settings.md#what-a-developer-can-change) covers local admin rights and tools other than Claude Code. Managed settings reach you through the [delivery mechanisms](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms) on the managed settings page, most commonly:

- [Server-managed settings](../13-Enterprise-Admin/server-managed-settings.md), which Claude Code fetches from the claude.ai admin console or a self-hosted [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md)
- MDM or OS-level policies, and `managed-settings.json` files in a system directory
- An embedding host such as Claude Desktop, through the SDK `managedSettings` option; see [Control policy from an embedding host](../13-Enterprise-Admin/managed-settings.md#parent-settings-from-embedding-hosts)

In a [Cowork](https://claude.com/docs/cowork/overview) session that runs on your machine in the Claude Desktop app, Claude Code doesn’t fetch server-managed settings from the claude.ai admin console, and it reads policy deployed to your device unless your organization’s Claude Desktop configuration sets `requireCoworkFullVmSandbox`. [Where and when a policy applies](../13-Enterprise-Admin/managed-settings.md#where-and-when-a-policy-applies) covers Cowork and cloud sessions. If you’re the administrator, [Set up Claude Code for your organization](../13-Enterprise-Admin/admin-setup.md) walks through choosing what to enforce, and [Deploy managed settings](../13-Enterprise-Admin/managed-settings.md) covers delivery and how to confirm a policy is in force. For the warning the managed settings editor in the claude.ai admin console can show, see [Configure server-managed settings](../13-Enterprise-Admin/server-managed-settings.md#configure-server-managed-settings).


[​](#change-a-setting)

Change a setting

You can change a setting from the `/config` menu, by editing a settings file, or for one session from the command line. Claude Code’s system prompt isn’t published. To give Claude standing instructions, use [`CLAUDE.md` files](memory.md) or the `--append-system-prompt` flag.


[​](#use-the-/config-menu)

Use the /config menu

Run `/config` inside Claude Code and open the **Config** tab. It lists a short set of personal options such as theme, editor mode, and verbose output, not every settings key. Select an option to change it; Claude Code saves it for you:

- **Most options**: `~/.claude/settings.json`
- **A few options, such as Show tips**: `.claude/settings.local.json`
- **The [global config options](settings-reference.md#global-config-settings)**: `~/.claude.json`

To set one option without the menu, pass `key=value`, such as `/config verbose=true`.

`/config` is part of the terminal interface. The [VS Code](../03-IDE-Integrations/vs-code.md) chat panel and the [desktop app](../16-Mobile-Desktop/desktop.md) don’t open it; change settings there by editing a settings file or through those apps’ own settings.


[​](#edit-a-settings-file)

Edit a settings file

Open the settings file for the scope you want in your editor and add or change a key. Settings files are strict JSON: a `//` comment or a trailing comma is a syntax error, and Claude Code reports the file as a [Settings Error](#fix-a-broken-settings-file) at the next start. For example, to let Claude Code run your lint and test commands without asking and stop it reading `.env` files, add this to `~/.claude/settings.json`:

~/.claude/settings.json

```python
{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)"
    ]
  }
}
```

Each entry under `permissions` is a rule that names a tool and what it may do; [Configure permissions](permissions.md) explains the syntax. The `$schema` line points to the [published JSON schema](https://json.schemastore.org/claude-code-settings.json) for Claude Code settings, which gives you autocomplete and inline validation in VS Code, Cursor, and any other editor that supports JSON schema. The schema can lag behind the newest CLI releases, so a validation warning on a recently documented key doesn’t mean your configuration is invalid. After you save, run `/status` inside Claude Code to confirm the file loaded; [Confirm what loaded](#check-what-loaded) says what the `Setting sources` line shows and how a broken file is reported. For a complete personal file, team file, and organization file, each shown with a comment on every key it sets, see the [example settings files](settings-example.md).


[​](#change-a-setting-for-one-session)

Change a setting for one session

To try a value without saving it, set it when you start Claude Code. The value applies to that session and your settings files stay as they were. You have three ways to do it:

- **`--settings`**: pass a key as JSON, inline or as a path to a file. Claude Code applies it above your user, project, and local files and below managed settings. It can set any key your user settings file can set; it can’t set `Managed` or `Global config` keys.
- **A flag for that key**: some keys have their own flag, such as `--model` for `model` and `--effort` for `effortLevel` and `modelSettings`.
- **An environment variable**: export the key’s paired variable before you run `claude`, such as `ANTHROPIC_MODEL` for `model`.

Each key’s entry on the [settings reference](settings-reference.md) lists its per-session overrides and which one takes precedence, so check the entry for the key you want to change. Commands you run inside a session mostly save your choice: when you change a setting in `/config`, Claude Code writes it to your settings files, and `/model` saves the value as your default for new sessions. If you press `s` in the `/model` picker, Claude Code switches the model without saving it as your user default. [Adjust effort level](model-config.md#adjust-effort-level) says which `/effort` picks Claude Code saves as your default for the model you’re using and which apply to the current session only. For example, to start one session on Opus without changing your default:

```python
claude --settings '{"model": "claude-opus-5-5"}'
```


[​](#when-edits-take-effect)

When edits take effect

Claude 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. The reload covers user, project, local, and managed settings, and Claude Code runs the [`ConfigChange` hook](../07-Hooks/hooks.md#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](../13-Enterprise-Admin/managed-settings.md#choose-a-delivery-mechanism) gives it per source. Claude 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](../13-Enterprise-Admin/managed-settings.md#where-and-when-a-policy-applies). The ones you’re most likely to edit mid-session:

- [`model`](settings-reference.md#model): use [`/model`](model-config.md#setting-your-model) to switch mid-session. Each model has its own prompt cache, so the first request after a switch re-reads the whole conversation uncached; see [Switching models](prompt-caching.md#switching-models)
- [`effortLevel`](settings-reference.md#effortlevel) and [`modelSettings`](settings-reference.md#modelsettings): use [`/effort`](model-config.md#adjust-effort-level) to change effort mid-session


[​](#confirm-what-loaded)

Confirm what loaded

Run `/status` inside Claude Code to see which settings sources are active. The **Status** tab includes a `Setting sources` line that lists each settings file Claude Code loaded for the current session, such as `User settings` or `Project local settings`. When [managed settings](../13-Enterprise-Admin/admin-setup.md#decide-how-settings-reach-devices) are in effect, the managed settings entry shows in parentheses how they reached your machine. The line confirms which files Claude Code read; it doesn’t show which file supplied each key. To list entries Claude Code rejected, run [`claude doctor`](debug-your-config.md); for a model that project or managed settings set, the startup header names the file that set it. `/status` and `/config` open the same dialog on different tabs, and the **Config** tab isn’t a view of your `settings.json` contents.


[​](#fix-a-broken-settings-file)

Fix a broken settings file

If you mistype JSON or set a key to a value Claude Code doesn’t accept, Claude Code tells you at the start of an interactive session. What it shows depends on how much of the file is affected:

- **Settings Error**: a user, project, or local file has invalid JSON or a value the schema rejects. At the start of an interactive session Claude Code shows a dialog that lets you fix the file with Claude’s help, exit, or continue without the broken settings.
- **Settings Warning**: only individual entries fail, such as a malformed permission rule or an unknown hook event name. Claude Code skips those values and keeps the rest of the file in effect.
- **Managed settings**: Claude Code keeps enforcing the rest of the file. [Invalid entries in managed settings](../13-Enterprise-Admin/managed-settings.md#invalid-entries-in-managed-settings) says what it drops and which keys fall back to a stricter value until you fix them. For a managed settings document that isn’t valid JSON, see [Managed settings document could not be parsed](errors.md#managed-settings-document-could-not-be-parsed).
- **Configuration error**: `~/.claude.json` can’t be parsed. Claude Code copies the broken file to `~/.claude/backups/.claude.json.corrupted.<timestamp>` and asks whether to exit and fix it by hand or reset to the default configuration; a `-p` run prints the error and exits. To recover your previous state, copy back one of the five most recent `.claude.json.backup.<timestamp>` files in `~/.claude/backups/`, which Claude Code saves before it writes the file.

After you continue, run `/status` to see the affected files and `claude doctor` for the details of each error. A `-p` run shows no dialog. Unless [a managed settings document can’t be parsed](errors.md#managed-settings-document-could-not-be-parsed), Claude Code skips the broken file or values and continues with the rest, so after a `-p` run that ignores a setting, run `claude doctor` to see what it dropped.


[​](#settings-precedence)

Settings precedence

When the same key appears in more than one place, Claude Code uses the value from the highest level that sets it. The stack below shows the levels, highest on top; a key at a higher level overrides the same key anywhere below it. In order, highest precedence first:

1.  **Managed settings**: settings your organization deploys, by a `managed-settings.json` file, an MDM policy, or [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) from the claude.ai console. Nothing in your own settings files or `--settings` overrides a managed key, and a flag such as `--model` picks only from the models your organization allows. A managed [`model`](settings-reference.md#model) is a starting default, not a lock; the locks are [`availableModels`](settings-reference.md#availablemodels) and [`deniedModels`](settings-reference.md#deniedmodels). When your organization delivers more than one managed source, the rules for [precedence within the managed tier](../13-Enterprise-Admin/managed-settings.md#precedence-within-the-managed-tier) say what Claude Code reads from each.
2.  **Command line**: JSON you pass with `--settings <file-or-json>` when you start `claude`, for that session only; see [Change a setting for one session](#change-a-setting-for-one-session). A key you set there overrides the same key in your project and user settings files, and a key you leave out keeps its value from those files. Other flags, such as `--model`, set one thing for the session and aren’t part of this stack; a key’s entry on the [settings reference](settings-reference.md) says which flags override it.
3.  **Project local settings** (`.claude/settings.local.json`): your personal settings for this project.
4.  **Shared project settings** (`.claude/settings.json`): settings your team checks into source control.
5.  **User settings** (`~/.claude/settings.json`): your personal settings for every project.

Environment variables aren’t a level in this stack. When a behavior has both a shell variable and a settings key, which one applies is decided per pair, not by level: `ANTHROPIC_MODEL` exported in your shell applies over the `model` key from any file, while `ANTHROPIC_DEFAULT_MODEL` applies only when no file sets `model`. The [environment variables reference](env-vars.md#precedence) says which keys have a pair and which one Claude Code reads first. An `env` block inside a settings file is an ordinary key and follows the levels above. For a few security-sensitive keys, Claude Code honors a stricter value from a lower level over a managed value; [Exceptions to managed settings precedence](#exceptions-to-managed-settings-precedence) lists them.


[​](#lists-merge-instead-of-overriding)

Lists merge instead of overriding

When you set the same list key, such as `permissions.allow`, in more than one file, Claude Code combines the lists instead of picking one, so each file can add entries without removing another file’s. Four keys that hold model lists or per-model entries follow their own rules:

- [`fallbackModel`](settings-reference.md#fallbackmodel) is an ordered chain where position carries meaning, so Claude Code takes the whole value from the highest-precedence file that defines it.
- [`modelPicker`](settings-reference.md#modelpicker) holds one ordered list of rows plus a replace flag, so Claude Code never merges rows from two sources. It takes the whole value from the highest of managed settings, `--settings`, and user settings that defines it, and ignores the key in project and local settings. Requires Claude Code v2.1.242 or later.
- [`availableModels`](settings-reference.md#availablemodels): when the managed settings Claude Code applies define it, Claude Code applies that list as-is and ignores entries you add in user, project, or local settings, unless an app that embeds Claude Code supplies its own model list; see [Exceptions to managed settings precedence](#exceptions-to-managed-settings-precedence). Across managed sources the list never merges either; [how Claude Code combines managed sources](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) says which source’s list applies. Across non-managed scopes Claude Code merges the arrays as usual.
- [`modelSettings`](settings-reference.md#modelsettings): Claude Code resolves it one model at a time, together with [`effortLevel`](settings-reference.md#effortlevel). The `modelSettings` entry states which file’s value applies to a model.


[​](#precedence-examples)

Precedence examples

While Claude works, Claude Code shows a one-line tip under the spinner, such as “Use /config to change your default permission mode (including Plan Mode)”. Suppose you want those tips off, so you set [`spinnerTipsEnabled`](settings-reference.md#spinnertipsenabled) to `false` in `~/.claude/settings.json`. Each scenario below is something that can turn them back on, and what you can do about it.


[​](#team-settings-override-personal-settings)

Team settings override personal settings

Your team’s `.claude/settings.json` sets it to `true`. Claude Code uses the project value because shared project sits above user, so you see tips in that project and nowhere else. You can get your value back: add `"spinnerTipsEnabled": false` to `.claude/settings.local.json` in that project. Project local sits above shared project, so your sessions there stop showing tips and your teammates’ sessions don’t change.


[​](#organization-settings-override-everything)

Organization settings override everything

Your organization’s managed settings set it to `true`. Nothing you put in user, project, or local settings turns tips off, and neither does `--settings`. Managed is the top level. You can’t get your value back. Run `/status` to see which managed source applies, and ask your administrator if the policy should change.


[​](#the-command-line-overrides-your-files-for-one-session)

The command line overrides your files for one session

You started the session with `claude --settings '{"spinnerTipsEnabled": true}'`. Command line sits above every file except managed, so that session shows tips even though your files say `false`. You get your value back on the next session; `--settings` lasts one session and doesn’t write to any file.


[​](#a-flag-or-environment-variable-sets-the-same-thing)

A flag or environment variable sets the same thing

Some keys have a command line flag or an environment variable that overrides the settings value regardless of which file set it: `ANTHROPIC_MODEL` overrides the [`model`](settings-reference.md#model) setting, and `--model` overrides both for a session. Whether you can get your value back depends on the key: unset the variable or drop the flag, and check the key’s entry on the [settings reference](settings-reference.md) and the variable’s row on the [environment variables reference](env-vars.md) for which one Claude Code uses.


[​](#troubleshoot-a-setting-that-doesn’t-apply)

Troubleshoot a setting that doesn’t apply

When you set a key and Claude Code doesn’t behave as if you had, start with `/status` to see which files it loaded, then find your symptom below. [Debug your configuration](debug-your-config.md) covers the wider checks, including a clean-configuration test.


[​](#a-value-you-set-is-ignored)

A value you set is ignored

Something else is setting the same key, the file can’t set that value, or the file didn’t load:

- **A higher level sets it.** Another settings file, a `--settings` flag, or a managed source sets the key above yours; the [stack](#settings-precedence) says which. A flag or environment variable can also override the key on its own, decided key by key; the key’s entry on the [settings reference](settings-reference.md) says which one Claude Code uses, and the [`env` entry](settings-reference.md#env) covers a managed `env` value versus a shell export.
- **A security key keeps its strict value.** For a few keys Claude Code honors the restrictive value from any file, so a project `true` for [`disableClaudeAiConnectors`](settings-reference.md#disableclaudeaiconnectors) stays on; see [Exceptions to managed settings precedence](#exceptions-to-managed-settings-precedence).
- **The file can’t set that value.** [`permissions.defaultMode`](settings-reference.md#permissions-defaultmode) values `auto` and `bypassPermissions` don’t take effect from project or local settings; set them in user or managed settings instead, or pass `--permission-mode` for one session. Before v2.1.257, `bypassPermissions` took effect from any file. A telemetry export variable in an [`env`](settings-reference.md#env) block doesn’t take effect from project or local settings either, apart from a few off values. [Variables Claude Code ignores in `env`](settings-reference.md#variables-claude-code-ignores-in-env) lists the variables and those values.
- **The file is broken.** Invalid JSON or a rejected value makes Claude Code skip the file or the entry; see [Fix a broken settings file](#fix-a-broken-settings-file).


[​](#a-change-you-made-in-claude-code-is-lost-in-new-sessions)

A change you made in Claude Code is lost in new sessions

When you save a choice for new sessions from inside Claude Code, such as a default model with `/model`, Claude Code writes it to your user settings file, `~/.claude/settings.json`. If you can’t write to that file, for example because another tool generates it or links it to a read-only copy, the change applies to the current session and is gone in the next one. Set the key in the tool that generates the file, or replace the file with one you can write to. If you can write to the file and the change still doesn’t last, check whether the change was [for one session only](#change-a-setting-for-one-session) or [a higher level sets the same key](#a-value-you-set-is-ignored). For the `model` key, [A new session starts on a different model than you picked](model-config.md#a-new-session-starts-on-a-different-model-than-you-picked) lists more causes.


[​](#a-managed-change-hasn’t-reached-you)

A managed change hasn’t reached you

Managed sources reach a running session on the schedule in the [delivery table](../13-Enterprise-Admin/managed-settings.md#choose-a-delivery-mechanism), so restart the session first. If `/status` then names a different source than the one your administrator changed, a higher-priority source applies; [How Claude Code combines managed sources](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) gives the order.


[​](#a-committed-key-doesn’t-reach-teammates)

A committed key doesn’t reach teammates

Two things keep a key in `.claude/settings.json` from applying for everyone who clones it:

- **Claude Code ignores the key in a repository file.** Look for `User, local, or managed`, `User or managed`, `User`, `Managed`, or `Global config` in the Scope column of the [settings index](settings-reference.md#settings-index). Those keys never apply from the shared file, apart from a few that a repository file can still switch off. Each of those entries says so on its Scope line. `Global config` keys apply only from `~/.claude.json`. Inside the `env` key, the telemetry export variables never apply from the shared file either, apart from a few off values; see [Variables Claude Code ignores in `env`](settings-reference.md#variables-claude-code-ignores-in-env).
- **The key waits for trust.** `permissions.allow` rules, `permissions.additionalDirectories`, `extraKnownMarketplaces`, and most [`env`](settings-reference.md#env) values apply only after each teammate [trusts the folder](permissions.md#project-allow-rules-and-workspace-trust). Until then they still see prompts and don’t get plugins from a marketplace the file declares. `deny` and `ask` rules apply right away.


[​](#permission-rules-combine-differently-than-you-expected)

Permission rules combine differently than you expected

- **You chose “Yes, and don’t ask again” on a permission prompt but still get prompted for the same tool.** That choice saved an `allow` rule to your local file, and an `allow` rule there doesn’t outrank an `ask` rule from a project or managed file; [how permission rules combine](permissions.md#settings-precedence) explains the order. In the VS Code extension the approval card lets you pick the destination file, including the project’s shared file, which changes the rule for everyone; in the CLI, Claude Code writes only to your local file.
- **Your organization’s allow rules still apply alongside yours.** That’s expected: Claude Code merges [`permissions.allow`](settings-reference.md#permissions-allow) across scopes, unless your organization sets [`allowManagedPermissionRulesOnly`](settings-reference.md#allowmanagedpermissionrulesonly).


[​](#exceptions-to-managed-settings-precedence)

Exceptions to managed settings precedence

For a few keys whose values restrict a session, Claude Code honors a restrictive value from a scope that otherwise couldn’t override managed settings. Find the key in this table to see which value it honors and from where.

| Key                                                                                                                              | Value Claude Code honors                                                                                                     | Notes                                                                                                                                                                   |
|:---------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`disableClaudeAiConnectors`](settings-reference.md#disableclaudeaiconnectors)                                             | `true` from any scope                                                                                                        | Honored even when a managed source sets `false`                                                                                                                         |
| [`enableArtifact`](settings-reference.md#enableartifact)                                                                   | `false` from any scope, and `disableArtifact: true` from any scope                                                           | Honored even when a managed source sets `true`; nothing turns the [Artifact tool](artifacts.md#disable-artifacts) back on. Requires Claude Code v2.1.242 or later |
| [`isolatePeerMachines`](settings-reference.md#isolatepeermachines)                                                         | `true` from any scope                                                                                                        | Honored even when a managed source sets `false`                                                                                                                         |
| [`permissions.blockReadsOutsideWorkingDirectories`](settings-reference.md#permissions-blockreadsoutsideworkingdirectories) | `true` from any scope                                                                                                        | Honored even when a managed source sets `false`. Requires Claude Code v2.1.257 or later                                                                                 |
| [`autoMode.classifyAllShell`](settings-reference.md#automode-classifyallshell)                                             | `true` from `~/.claude/settings.json` or `--settings`                                                                        | Honored even when a managed source sets `false`                                                                                                                         |
| [`remoteControlAtStartup`](settings-reference.md#remotecontrolatstartup)                                                   | `false` from `.claude/settings.json` or `.claude/settings.local.json`                                                        | Honored even when a managed source sets `true`; a project or local `true` is ignored                                                                                    |
| [`crossSessionInbound`](settings-reference.md#crosssessioninbound)                                                         | A stricter value from `.claude/settings.json` or `.claude/settings.local.json`, on the `accept` \< `hold` \< `refuse` ladder | Honored over managed, `--settings`, and user values; a project or local value that isn’t stricter is ignored                                                            |
| [`useAutoModeDuringPlan`](settings-reference.md#useautomodeduringplan)                                                     | `false` from any managed source, `--settings`, `~/.claude/settings.json`, or `.claude/settings.local.json`                   | Honored even when the winning managed source sets `true`; a `false` in `.claude/settings.json` is ignored                                                               |
| [`syncClaudeAiSkills`](settings-reference.md#syncclaudeaiskills)                                                           | `false` from any managed source, `--settings`, `~/.claude/settings.json`, or `.claude/settings.local.json`                   | Honored even when the winning managed source sets `true`; a `false` in `.claude/settings.json` is ignored                                                               |
| [`syncClaudeAiPlugins`](settings-reference.md#syncclaudeaiplugins)                                                         | `false` from any managed source, `--settings`, `~/.claude/settings.json`, or `.claude/settings.local.json`                   | Honored even when the winning managed source sets `true`; a `false` in `.claude/settings.json` is ignored                                                               |
| [`maxEffortLevel`](settings-reference.md#maxeffortlevel)                                                                   | A lower cap from any scope, including `--settings`                                                                           | Honored even when the managed settings Claude Code applies set a higher cap; the lowest cap applies. Requires Claude Code v2.1.267 or later                             |

An app that runs Claude Code inside itself and sets [`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`](env-vars.md) is also an exception. Claude Code takes that app’s model configuration over the `model`, `fallbackModel`, `modelPicker`, and `modelOverrides` keys from every managed source, and over the model-selection variables in a managed `env` block, such as `ANTHROPIC_MODEL` and the `ANTHROPIC_DEFAULT_*_MODEL` family. Claude Code keeps a managed [`availableModels`](settings-reference.md#availablemodels) allowlist in force unless the app supplies its own.


[​](#settings-in-cloud-sessions)

Settings in cloud sessions

A [cloud session](claude-code-on-the-web.md) runs in a [cloud environment](cloud-environments.md) on a fresh clone of your repository, not on your machine. That changes which settings reach it:

- **Cloud threads in a project**: in a cloud thread in a [project](claude-projects.md#what-threads-pick-up-from-your-repositories), none of a repository’s `.claude/settings.json` permission rules, hooks, or `env` apply, however many repositories the project has. [What threads pick up from your repositories](claude-projects.md#what-threads-pick-up-from-your-repositories) lists what to use instead.
- **Shared project settings** (`.claude/settings.json`): read in a session with one repository outside a project’s threads, because the file is part of the clone and the session starts inside it. Commit a setting there to apply it in those sessions.
- **Shared project settings with several repositories**: in an Anthropic-hosted environment, a session with several repositories starts above the clones and reads only the `enabledPlugins` and `extraKnownMarketplaces` keys from each repository’s `.claude/settings.json`, not permission rules, hooks, `env`, or other keys. The marketplaces and plugins those two keys declare still [don’t load in a cloud session](cloud-environments.md#what-carries-over-from-your-setup). For a self-hosted environment, see [which repository’s settings apply](../13-Enterprise-Admin/self-hosted-environments-configuration.md#repository-settings-in-sessions-with-several-repositories).
- **User and project local settings** (`~/.claude/settings.json` and `.claude/settings.local.json`): not read. Both stay on your machine, and the local file isn’t in the clone.
- **Managed settings**: a `managed-settings.json` file or MDM profile on your device doesn’t reach a cloud session. Your organization’s [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) do; [surface coverage](model-config.md#surface-coverage) lists which cloud sessions receive them. A [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) also reads the managed settings file in its runner image. [How Claude Code combines managed sources](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) says when that file applies.
- **`/config`**: in your browser at claude.ai/code, opens the Claude Code section of your claude.ai settings instead of changing a value. To change a setting for a cloud session, set an [environment variable](cloud-environments.md#set-environment-variables) on the environment. In a session with one repository outside a project’s threads, you can instead commit the key to that repository’s `.claude/settings.json`.

[What carries over from your setup](cloud-environments.md#what-carries-over-from-your-setup) lists the rest: `CLAUDE.md`, skills, MCP servers, plugins, and credentials.


[​](#what’s-next)

What’s next

- [All settings](settings-reference.md): every key, with where you set it and an example
- [Example settings files](settings-example.md): a personal file, a team file, and an organization’s managed file
- [Configure permissions](permissions.md): allow, ask, and deny rules, and what Claude Code runs without asking
- [Environment variables](env-vars.md): the variables Claude Code reads and the `env` block
- [Debug your configuration](debug-your-config.md): when a setting doesn’t apply
- [Claude directory reference](claude-directory.md): every file Claude Code reads, including subagents, MCP servers, plugins, and `CLAUDE.md`

---

## Customize your status line - Claude Code Docs

Source: https://code.claude.com/docs/en/statusline
Path: 02-Claude-Code-CLI/statusline.md

## On this page

- [Set up a status line](#set-up-a-status-line)
  - [Use the /statusline command](#use-the-%2Fstatusline-command)
  - [Manually configure a status line](#manually-configure-a-status-line)
  - [Disable the status line](#disable-the-status-line)
- [Build a status line step by step](#build-a-status-line-step-by-step)
- [How status lines work](#how-status-lines-work)
  - [When the status line updates](#when-the-status-line-updates)
  - [What your script can output](#what-your-script-can-output)
  - [Size output to the terminal](#size-output-to-the-terminal)
- [Available data](#available-data)
  - [Context window fields](#context-window-fields)
  - [Spend limit fields](#spend-limit-fields)
  - [Prompt cache fields](#prompt-cache-fields)
  - [Last miss cause](#last-miss-cause)
- [Examples](#examples)
  - [Context window usage](#context-window-usage)
  - [Git status with colors](#git-status-with-colors)
  - [Cost and duration tracking](#cost-and-duration-tracking)
  - [Display multiple lines](#display-multiple-lines)
  - [Clickable links](#clickable-links)
  - [Rate limit usage](#rate-limit-usage)
  - [Cache expensive operations](#cache-expensive-operations)
  - [Windows configuration](#windows-configuration)
- [Subagent status lines](#subagent-status-lines)
  - [Task fields](#task-fields)
- [Tips](#tips)
- [Troubleshooting](#troubleshooting)
  - [Status line not appearing](#status-line-not-appearing)
  - [Status line shows -- or empty values](#status-line-shows-or-empty-values)
  - [Context percentage shows unexpected values](#context-percentage-shows-unexpected-values)
  - [OSC 8 links not clickable](#osc-8-links-not-clickable)
  - [Display glitches with escape sequences](#display-glitches-with-escape-sequences)
  - [Workspace trust required](#workspace-trust-required)
  - [Script errors or hangs](#script-errors-or-hangs)
  - [Notifications share the status line row](#notifications-share-the-status-line-row)

Interface

# Customize your status line

Copy pageCopy page

Configure a custom status bar to monitor context window usage, costs, and git status in Claude Code

Copy pageCopy page

The status line is a customizable bar at the bottom of Claude Code that runs any shell script you configure. It receives JSON session data on stdin and displays whatever your script prints, giving you a persistent, at-a-glance view of context usage, costs, git status, or anything else you want to track. Status lines are useful when you:

- Want to monitor context window usage as you work
- Need to track session costs
- Work across multiple sessions and need to distinguish them
- Want git branch and status always visible

The status line renders in its own row above the built-in footer badges and does not replace them. With a custom status line configured, Claude Code stops showing most of the footer’s keyboard hints, including `esc to interrupt`, the `? for shortcuts` fallback, and the `hold space to speak` [voice dictation](voice-dictation.md) hint. To add clickable link badges to the footer when an ID appears in the conversation, without writing a script, configure [`footerLinksRegexes`](settings-reference.md#footerlinksregexes) instead. Here’s an example of a [multi-line status line](#display-multiple-lines) that displays git info on the first line and a color-coded context bar on the second.

This page walks through [setting up a basic status line](#set-up-a-status-line), explains [how the data flows](#how-status-lines-work) from Claude Code to your script, lists [all the fields you can display](#available-data), and provides [ready-to-use examples](#examples) for common patterns like git status, cost tracking, and progress bars.


[​](#set-up-a-status-line)

Set up a status line

Use the [`/statusline` command](#use-the-%2Fstatusline-command) to have Claude Code generate a script for you, or [manually create a script](#manually-configure-a-status-line) and add it to your settings.


[​](#use-the-/statusline-command)

Use the /statusline command

The `/statusline` command accepts natural language instructions describing what you want displayed. Claude Code generates a script file in `~/.claude/` and updates your settings automatically:

```python
/statusline show model name and context percentage with a progress bar
```

Approve the file edit prompts if Claude Code asks for permission during setup.


[​](#manually-configure-a-status-line)

Manually configure a status line

Add a `statusLine` field to your user settings (`~/.claude/settings.json`, where `~` is your home directory) or [project settings](settings.md#where-settings-live). Set `type` to `"command"` and point `command` to a script path or an inline shell command. For a full walkthrough of creating a script, see [Build a status line step by step](#build-a-status-line-step-by-step).

```python
{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh",
    "padding": 2
  }
}
```

The `command` field runs in a shell, so you can also use inline commands instead of a script file. This example uses `jq` to parse the JSON input and display the model name and context percentage:

```python
{
  "statusLine": {
    "type": "command",
    "command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'"
  }
}
```

The optional `padding` field adds extra horizontal spacing (in characters) to the status line content. Defaults to `0`. This padding is in addition to the interface’s built-in spacing, so it controls relative indentation rather than absolute distance from the terminal edge. The optional `refreshInterval` field re-runs your command every N seconds in addition to the [event-driven updates](#how-status-lines-work). The minimum is `1`. Set this when your status line shows time-based data such as a clock, or when background subagents change git state while the main session is idle. Leave it unset to run only on events. The optional `hideVimModeIndicator` field suppresses the built-in `-- INSERT --` text below the prompt. Set this to `true` when your script renders [`vim.mode`](#available-data) itself, so the mode is not shown twice.


[​](#disable-the-status-line)

Disable the status line

Run `/statusline` and ask it to remove or clear your status line (for example, `/statusline delete`, `/statusline clear`, `/statusline remove it`). You can also manually delete the `statusLine` field from your settings.json.


[​](#build-a-status-line-step-by-step)

Build a status line step by step

This walkthrough shows what `/statusline` sets up for you by manually creating a status line that displays the current model, working directory, and context window usage percentage.

Running [`/statusline`](#use-the-%2Fstatusline-command) with a description of what you want configures all of this for you automatically.

These examples use Bash scripts, which work on macOS and Linux. On Windows, see [Windows configuration](#windows-configuration) for PowerShell and Git Bash examples.

1

Create a script that reads JSON and prints output

Claude Code sends JSON data to your script via stdin. This script uses [`jq`](https://jqlang.org/), a command-line JSON parser you may need to install, to extract the model name, directory, and context percentage, then prints a formatted line.Save this to `~/.claude/statusline.sh` (where `~` is your home directory, such as `/Users/username` on macOS or `/home/username` on Linux):

```python
#!/bin/bash
# Read JSON data that Claude Code sends to stdin
input=$(cat)

# Extract fields using jq
MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
# The "// 0" provides a fallback if the field is null
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)

# Output the status line - ${DIR##*/} extracts just the folder name
echo "[$MODEL] 📁 ${DIR##*/} | ${PCT}% context"
```

2

Make it executable

Mark the script as executable so your shell can run it:

```python
chmod +x ~/.claude/statusline.sh
```

3

Add to settings

Tell Claude Code to run your script as the status line. Add this configuration to `~/.claude/settings.json`, which sets `type` to `"command"` (meaning “run this shell command”) and points `command` to your script:

```python
{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh"
  }
}
```

Your status line appears at the bottom of the interface. Claude Code reloads settings automatically and runs your script as soon as you save the file.


[​](#how-status-lines-work)

How status lines work

Claude Code runs your script with [JSON session data](#available-data) on stdin and displays whatever the script prints to stdout.

The status line runs locally and does not consume API tokens. It temporarily hides during certain UI interactions, including the help menu and permission prompts.


[​](#when-the-status-line-updates)

When the status line updates

Your script runs once when a session starts, including when you resume one. After that, it runs again when:

- A new assistant message arrives
- `/compact` finishes
- The permission mode changes
- Vim mode toggles
- You change the `command` in your `statusLine` settings
- A [`refreshInterval`](#manually-configure-a-status-line) timer elapses, if you set one
- A [rate-limit window](#rate-limit-usage) in the data your script last received reaches its `resets_at` time
- A warm [prompt cache](#prompt-cache-fields) in the data your script last received reaches its `expires_at` time

Claude Code debounces updates at 300ms, so rapid changes batch together and your script runs once after the changes stop. A change to the `command` itself skips the debounce: Claude Code runs the new command right away. If a new update triggers while your script is still running, Claude Code cancels the in-flight script. If you edit your script, the changes appear the next time an update trigger re-runs it. The event-driven triggers can go quiet when the main session is idle, for example while a coordinator waits on background subagents. To keep time-based or externally-sourced segments current during idle periods, set [`refreshInterval`](#manually-configure-a-status-line) to also re-run the command on a fixed timer.


[​](#what-your-script-can-output)

What your script can output

Your script can print more than a single line of plain text:

- **Multiple lines**: each `echo` or `print` statement displays as a separate row. See the [multi-line example](#display-multiple-lines).
- **Colors**: use [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) like `\033[32m` for green (terminal must support them). See the [git status example](#git-status-with-colors).
- **Links**: use [OSC 8 escape sequences](https://en.wikipedia.org/wiki/ANSI_escape_code#OSC) to make text clickable (Cmd+click on macOS, Ctrl+click on Windows/Linux). Requires a terminal that supports hyperlinks like iTerm2, Kitty, or WezTerm. See the [clickable links example](#clickable-links).


[​](#size-output-to-the-terminal)

Size output to the terminal

Claude Code captures your script’s output instead of connecting it directly to the terminal, so `tput cols` and language-level width detection cannot read the terminal size from inside the script. Read the `COLUMNS` and `LINES` environment variables instead. Claude Code sets these to the current terminal dimensions before running your script.


[​](#available-data)

Available data

Claude Code sends the following JSON fields to your script via stdin:

| Field                                                                                                     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
|-----------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `model.id`, `model.display_name`                                                                          | Current model identifier and display name                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `cwd`, `workspace.current_dir`                                                                            | Current working directory. Both fields contain the same value; `workspace.current_dir` is preferred for consistency with `workspace.project_dir`.                                                                                                                                                                                                                                                                                                                           |
| `workspace.project_dir`                                                                                   | Directory where Claude Code was launched, which may differ from `cwd` if the working directory changes during a session                                                                                                                                                                                                                                                                                                                                                     |
| `workspace.added_dirs`                                                                                    | Additional directories added via `/add-dir` or `--add-dir`. Empty array if none have been added                                                                                                                                                                                                                                                                                                                                                                             |
| `workspace.git_worktree`                                                                                  | Git worktree name when the current directory is inside a linked worktree created with `git worktree add`. Absent in the main working tree. Populated for any git worktree, unlike `worktree.*`, which is present only while the session is in a [worktree session](worktrees.md)                                                                                                                                                                                      |
| `workspace.repo.host`, `workspace.repo.owner`, `workspace.repo.name`                                      | Repository identity parsed from the `origin` remote, for example, `"github.com"`, `"anthropics"`, `"claude-code"`. Absent outside a git repository or when no `origin` remote is configured. For a gitlab.com project nested in subgroups, `owner` is the full namespace path with slashes, such as `"group/subgroup"`. Before v2.1.260, `workspace.repo` was absent for these projects                                                                                     |
| `cost.total_cost_usd`                                                                                     | Estimated session cost in USD, computed client-side at list price unless a [`modelPricing`](settings-reference.md#modelpricing) table is in effect. May differ from your actual bill. Resets to \$0 when `/clear` starts a new session                                                                                                                                                                                                                                |
| `cost.total_duration_ms`                                                                                  | Total wall-clock time the session has been running, in milliseconds. Accumulates across resumes and doesn’t include time while the session isn’t running                                                                                                                                                                                                                                                                                                                    |
| `cost.total_api_duration_ms`                                                                              | Total time spent waiting for API responses in milliseconds                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `cost.total_lines_added`, `cost.total_lines_removed`                                                      | Lines of code changed                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `context_window.total_input_tokens`, `context_window.total_output_tokens`                                 | Token counts currently in the context window, from the most recent API response. Input includes cache reads and writes                                                                                                                                                                                                                                                                                                                                                      |
| `context_window.context_window_size`                                                                      | Maximum context window size in tokens. 200000 by default, or 1000000 for models with extended context.                                                                                                                                                                                                                                                                                                                                                                      |
| `context_window.used_percentage`                                                                          | Pre-calculated percentage of context window used                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `context_window.remaining_percentage`                                                                     | Pre-calculated percentage of context window remaining                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `context_window.current_usage`                                                                            | Token counts from the last API call, described in [context window fields](#context-window-fields)                                                                                                                                                                                                                                                                                                                                                                           |
| `exceeds_200k_tokens`                                                                                     | Whether the total token count (input, cache, and output tokens combined) from the most recent API response exceeds 200k. This is a fixed threshold regardless of actual context window size.                                                                                                                                                                                                                                                                                |
| `fast_mode`                                                                                               | Whether [fast mode](fast-mode.md) is enabled for the session                                                                                                                                                                                                                                                                                                                                                                                                          |
| `effort.level`                                                                                            | Current reasoning effort (`low`, `medium`, `high`, `xhigh`, or `max`). Reflects the live session value, including mid-session `/effort` changes. Absent when the current model does not support the effort parameter                                                                                                                                                                                                                                                        |
| `thinking.enabled`                                                                                        | Whether extended thinking is enabled for the session                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `rate_limits.five_hour.used_percentage`, `rate_limits.seven_day.used_percentage`                          | Percentage of the 5-hour or 7-day rate limit consumed, from 0 to 100                                                                                                                                                                                                                                                                                                                                                                                                        |
| `rate_limits.five_hour.resets_at`, `rate_limits.seven_day.resets_at`                                      | Unix epoch seconds when the 5-hour or 7-day rate limit window resets                                                                                                                                                                                                                                                                                                                                                                                                        |
| `rate_limits.spend_limit.used_percentage`, `rate_limits.spend_limit.resets_at`                            | Behind a Claude apps gateway, how much of your spend limit you have used and when its period resets. See [spend limit fields](#spend-limit-fields). Requires Claude Code v2.1.251 or later                                                                                                                                                                                                                                                                                  |
| `rate_limits.spend_limit.used_usd`, `rate_limits.spend_limit.limit_usd`, `rate_limits.spend_limit.period` | Your estimated spend and your limit in US dollars, and the limit’s period. These fields can be absent. See [spend limit fields](#spend-limit-fields). Requires v2.1.284 or later on both Claude Code and the gateway                                                                                                                                                                                                                                                        |
| `prompt_cache`                                                                                            | The session’s [prompt cache](prompt-caching.md) statistics for the main conversation: hit ratio, misses, and whether the cache is warm. See [prompt cache fields](#prompt-cache-fields) for every field. Absent until the main conversation’s first API response. Requires Claude Code v2.1.251 or later                                                                                                                                                              |
| `session_id`                                                                                              | Unique session identifier                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `session_name`                                                                                            | Session name. Uses the custom name set with the `--name` flag or `/rename` when one exists, otherwise the AI-generated session title. The [default display name](sessions.md#name-your-sessions), such as `my-app-3f`, doesn’t populate this field. Absent when the session has neither a custom name nor an AI-generated title                                                                                                                                       |
| `prompt_id`                                                                                               | UUID identifying the user prompt currently being processed. Matches the [`prompt.id` attribute on OpenTelemetry events](../13-Enterprise-Admin/monitoring-usage.md#event-correlation-attributes). Absent until the first user input                                                                                                                                                                                                                                                          |
| `transcript_path`                                                                                         | Path to conversation transcript file                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `version`                                                                                                 | Claude Code version                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `output_style.name`                                                                                       | Name of the current output style                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `vim.mode`                                                                                                | Current vim mode (`NORMAL`, `INSERT`, `VISUAL`, or `VISUAL LINE`) when [vim mode](interactive-mode.md#vim-editor-mode) is enabled                                                                                                                                                                                                                                                                                                                                     |
| `agent.name`                                                                                              | Agent name when running with the `--agent` flag or agent settings configured                                                                                                                                                                                                                                                                                                                                                                                                |
| `pr.number`, `pr.url`                                                                                     | Open pull request for the current branch. Mirrors the PR badge in the footer. In a repository with a GitLab remote, Claude Code fills these fields from the branch’s open [merge request](interactive-mode.md#gitlab-merge-requests) instead, so `pr.number` is the merge request number. Merge request data requires Claude Code v2.1.234 or later. Absent when not in a git repository, until a pull request or merge request is found, or once it merges or closes |
| `pr.review_state`                                                                                         | Review status of the open PR: `approved`, `pending`, `changes_requested`, or `draft`. May be independently absent even when `pr` is present                                                                                                                                                                                                                                                                                                                                 |
| `pr.kind`                                                                                                 | `mr` when `pr` describes a [GitLab merge request](interactive-mode.md#gitlab-merge-requests). Absent for GitHub pull requests, so scripts written before this field keep working. For a merge request, Claude Code sets `review_state` to `approved` when GitLab reports it mergeable, `pending` for any other open state, and `draft` for a draft. Requires Claude Code v2.1.234 or later                                                                            |
| `worktree.name`                                                                                           | Name of the active worktree. Present only while the session is in a [worktree session](worktrees.md)                                                                                                                                                                                                                                                                                                                                                                  |
| `worktree.path`                                                                                           | Absolute path to the worktree directory                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `worktree.branch`                                                                                         | Git branch name for the worktree (for example, `"worktree-my-feature"`). Absent for hook-based worktrees                                                                                                                                                                                                                                                                                                                                                                    |
| `worktree.original_cwd`                                                                                   | The directory Claude was in before entering the worktree                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `worktree.original_branch`                                                                                | Git branch checked out before entering the worktree. Absent for hook-based worktrees                                                                                                                                                                                                                                                                                                                                                                                        |

Full JSON schema

Your status line command receives this JSON structure via stdin:

```python
{
  "cwd": "/current/working/directory",
  "session_id": "abc123...",
  "session_name": "my-session",
  "prompt_id": "550e8400-e29b-41d4-a716-446655440000",
  "transcript_path": "/path/to/transcript.jsonl",
  "model": {
    "id": "claude-opus-5-5",
    "display_name": "Opus"
  },
  "workspace": {
    "current_dir": "/current/working/directory",
    "project_dir": "/original/project/directory",
    "added_dirs": [],
    "git_worktree": "feature-xyz",
    "repo": {
      "host": "github.com",
      "owner": "anthropics",
      "name": "claude-code"
    }
  },
  "version": "2.1.90",
  "output_style": {
    "name": "default"
  },
  "cost": {
    "total_cost_usd": 0.01234,
    "total_duration_ms": 45000,
    "total_api_duration_ms": 2300,
    "total_lines_added": 156,
    "total_lines_removed": 23
  },
  "context_window": {
    "total_input_tokens": 15500,
    "total_output_tokens": 1200,
    "context_window_size": 200000,
    "used_percentage": 8,
    "remaining_percentage": 92,
    "current_usage": {
      "input_tokens": 8500,
      "output_tokens": 1200,
      "cache_creation_input_tokens": 5000,
      "cache_read_input_tokens": 2000
    }
  },
  "exceeds_200k_tokens": false,
  "prompt_cache": {
    "warm": true,
    "caching_observed": true,
    "ttl": "1h",
    "expires_at": 1738429200,
    "requests": 14,
    "misses": 2,
    "expected_rebuilds": 1,
    "hit_ratio": 0.91,
    "cache_write_tokens": 352000,
    "miss_recache_tokens": 310200,
    "last_miss_at": 1738425230,
    "last_miss_cause": {
      "causes": ["tools_changed"],
      "tools_added": 2,
      "tools_removed": 0
    },
    "miss_causes": {
      "tools_changed": 2
    },
    "recache_tokens_if_cold": 45000
  },
  "fast_mode": false,
  "effort": {
    "level": "high"
  },
  "thinking": {
    "enabled": true
  },
  "rate_limits": {
    "five_hour": {
      "used_percentage": 23.5,
      "resets_at": 1738425600
    },
    "seven_day": {
      "used_percentage": 41.2,
      "resets_at": 1738857600
    },
    "spend_limit": {
      "used_percentage": 62.8,
      "resets_at": 1740787200,
      "used_usd": 314.12,
      "limit_usd": 500,
      "period": "monthly"
    }
  },
  "vim": {
    "mode": "NORMAL"
  },
  "agent": {
    "name": "security-reviewer"
  },
  "pr": {
    "number": 1234,
    "url": "https://github.com/anthropics/claude-code/pull/1234",
    "review_state": "pending"
  },
  "worktree": {
    "name": "my-feature",
    "path": "/path/to/.claude/worktrees/my-feature",
    "branch": "worktree-my-feature",
    "original_cwd": "/path/to/project",
    "original_branch": "main"
  }
}
```

**Fields that may be absent** (not present in JSON):

- `session_name`: appears when a custom name has been set with `--name` or `/rename`, or once an AI-generated session title exists. The default display name, such as `my-app-3f`, doesn’t populate it
- `prompt_id`: appears only after the first user input
- `workspace.git_worktree`: appears only when the current directory is inside a linked git worktree
- `workspace.repo`: appears only inside a git repository with an `origin` remote configured
- `effort`: appears only when the current model supports the reasoning effort parameter
- `vim`: appears only when vim mode is enabled
- `agent`: appears only when running with the `--agent` flag or agent settings configured
- `pr`: appears only while an open PR or GitLab merge request is found for the current branch, and is removed once it merges or closes. `pr.review_state` and `pr.kind` may be independently absent
- `worktree`: appears only while the session is in a [worktree session](worktrees.md). When present, `branch` and `original_branch` may also be absent for hook-based worktrees
- `rate_limits`: appears only for claude.ai Pro and Max subscribers, or behind a Claude apps gateway that sets a spend limit for you, and only after the first API response in the session. Each window (`five_hour`, `seven_day`, `spend_limit`) may be independently absent, and Claude Code drops a window once its `resets_at` time passes. Use `jq -r '.rate_limits.five_hour.used_percentage // empty'` to handle absence gracefully.
- `prompt_cache`: appears after the main conversation’s first API response. See [prompt cache fields](#prompt-cache-fields)

**Fields that may be `null`**:

- `context_window.current_usage`: `null` before the first API call in a session, and again after `/compact` until the next API call repopulates it
- `context_window.used_percentage`, `context_window.remaining_percentage`: may be `null` early in the session

Handle missing fields with conditional access and null values with fallback defaults in your scripts.


[​](#context-window-fields)

Context window fields

The `context_window` object describes the live context window from the most recent API response.

- **Combined totals** (`total_input_tokens`, `total_output_tokens`): tokens currently in the context window. `total_input_tokens` is the sum of `input_tokens`, `cache_creation_input_tokens`, and `cache_read_input_tokens`; `total_output_tokens` is the output tokens from the most recent response. Both are `0` before the first API response.
- **Per-component usage** (`current_usage`): the same token counts broken out by category. Use this when you need cache hits separate from fresh input.

The `current_usage` object contains:

- `input_tokens`: input tokens in current context
- `output_tokens`: output tokens generated
- `cache_creation_input_tokens`: tokens written to cache
- `cache_read_input_tokens`: tokens read from cache

For what the cache fields mean and how they’re billed, see [check cache performance](prompt-caching.md#check-cache-performance). The `used_percentage` field is calculated from input tokens only: `input_tokens + cache_creation_input_tokens + cache_read_input_tokens`. It does not include `output_tokens`. If you calculate context percentage manually from `current_usage`, use the same input-only formula to match `used_percentage`. The `current_usage` object is `null` before the first API call in a session, and again immediately after `/compact` until the next API call repopulates it.


[​](#spend-limit-fields)

Spend limit fields

Behind a [Claude apps gateway with spend limits](../13-Enterprise-Admin/claude-apps-gateway-spend-limits.md#usage-warnings-in-claude-code), the `rate_limits.spend_limit` object describes the spend limit that applies to you. It appears after the session’s first API response and requires Claude Code v2.1.251 or later. Your script receives its fields on separate schedules:

- `used_percentage` and `resets_at`: come with every response, so they are present whenever `spend_limit` is. `used_percentage` runs from 0 to 100, or above 100 once you exceed the limit, and `resets_at` is the Unix epoch seconds when the limit’s period resets.
- `used_usd`, `limit_usd`, and `period`: your estimated spend so far and your limit in US dollars, and the period the limit covers, one of `daily`, `weekly`, or `monthly`. The gateway [computes `used_usd` from token counts](../13-Enterprise-Admin/claude-apps-gateway-spend-limits.md#how-requests-are-priced), so it’s an estimate and not a billed amount. Claude Code reads them from the gateway in a separate request, about every five minutes while you send requests. The dollar amounts can be about five minutes older than `used_percentage`, so the two may briefly disagree. Requires v2.1.284 or later on both Claude Code and the gateway.

Treat `used_usd`, `limit_usd`, and `period` as optional even when `spend_limit` is present. Your script receives the percentage before them, and they stay absent if you set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`, which turns that request off. Read each with a fallback in your script, such as `jq -r '.rate_limits.spend_limit.used_usd // empty'`.


[​](#prompt-cache-fields)

Prompt cache fields

The `prompt_cache` object summarizes how the session’s main conversation is using the [prompt cache](prompt-caching.md). Claude Code computes it from the cache token counts in the API’s responses, so it works on every provider. The object appears after the main conversation’s first API response. Claude Code doesn’t count subagent requests in these statistics. Requires Claude Code v2.1.251 or later. The table lists each field with its meaning. Timestamps are Unix epoch seconds, the same unit as `rate_limits.*.resets_at`. A short status line usually shows one or two of these; `warm` and `hit_ratio` summarize the cache state most directly.

| Field                    | Description                                                                                                                                                                                                                          |
|--------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `warm`                   | Whether the cached prefix is still within its TTL. `false` when the last response reported no cache tokens, even while `caching_observed` is `true`                                                                                  |
| `caching_observed`       | Whether any response this session reported cache tokens. `false` means prompt caching is off, or your provider or gateway doesn’t report it                                                                                          |
| `ttl`                    | [Cache lifetime](prompt-caching.md#cache-lifetime) of the current cached prefix: `"5m"` or `"1h"`                                                                                                                              |
| `expires_at`             | When the cached prefix leaves its TTL and goes cold, in epoch seconds. `null` when the last response reported no cache tokens                                                                                                        |
| `requests`               | API requests recorded for the main conversation this session                                                                                                                                                                         |
| `misses`                 | Requests that re-processed content the cache already held: more than 5% and at least 2,000 tokens of what the request could have read from cache, with no compaction or tool-result clearing to explain the shortfall in cache reads |
| `expected_rebuilds`      | Cache rebuilds that followed a compaction or a clearing of old tool results                                                                                                                                                          |
| `hit_ratio`              | Cache read tokens as a fraction of all input tokens this session, from 0 to 1. The denominator counts cache reads, cache writes, and uncached input. `null` while those counts are all zero                                          |
| `cache_write_tokens`     | All tokens written to the cache this session, the first request’s initial write included                                                                                                                                             |
| `miss_recache_tokens`    | Tokens written to the cache by the requests counted as misses                                                                                                                                                                        |
| `last_miss_at`           | When the last miss happened, in epoch seconds. `null` while the session has no misses                                                                                                                                                |
| `last_miss_cause`        | What Claude Code identified as the likely cause of the last miss, described under [Last miss cause](#last-miss-cause). Requires Claude Code v2.1.260 or later                                                                        |
| `miss_causes`            | How many of this session’s diagnosed misses had each cause, keyed by the same cause names as `last_miss_cause`. Requires Claude Code v2.1.260 or later                                                                               |
| `recache_tokens_if_cold` | Tokens the next request re-caches if the cache has gone cold by then. `null` right after a compaction or a clearing of old tool results, until the next request records the rewritten conversation’s size                            |

Claude Code shows the same statistics in the terminal, on the [`/usage` command’s `Prompt cache (main)` line](../17-Billing-Plans/costs.md#prompt-cache-statistics).


[​](#last-miss-cause)

Last miss cause

The `last_miss_cause` object reports what Claude Code identified as the likely cause of the most recent miss. Its `causes` array holds one or more cause names, such as `tools_changed`, `system_prompt_changed`, `ttl_expired_5m`, or `likely_server_side`. The object is `null` until the session’s first miss, and again whenever Claude Code couldn’t identify a cause for the most recent miss. Requires Claude Code v2.1.260 or later. Two causes add counts to the object:

- `tools_added` and `tools_removed`: with `tools_changed`, how many tools were added to or removed from the request
- `system_char_delta`: with `system_prompt_changed`, the change in the system prompt’s length, in characters


[​](#examples)

Examples

These examples show common status line patterns. To use any example:

1.  Save the script to a file like `~/.claude/statusline.sh` (or `.py`/`.js`)
2.  Make it executable: `chmod +x ~/.claude/statusline.sh`
3.  Add the path to your [settings](#manually-configure-a-status-line)

The Bash examples use [`jq`](https://jqlang.org/) to parse JSON. Python and Node.js have built-in JSON parsing.


[​](#context-window-usage)

Context window usage

Display the current model and context window usage with a visual progress bar. Each script reads JSON from stdin, extracts the `used_percentage` field, and builds a 10-character bar where filled blocks (▓) represent usage:

Bash

Python

Node.js

```python
#!/bin/bash
# Read all of stdin into a variable
input=$(cat)

# Extract fields with jq, "// 0" provides fallback for null
MODEL=$(echo "$input" | jq -r '.model.display_name')
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)

# Build progress bar: printf -v creates a run of spaces, then
# ${var// /▓} replaces each space with a block character
BAR_WIDTH=10
FILLED=$((PCT * BAR_WIDTH / 100))
EMPTY=$((BAR_WIDTH - FILLED))
BAR=""
[ "$FILLED" -gt 0 ] && printf -v FILL "%${FILLED}s" && BAR="${FILL// /▓}"
[ "$EMPTY" -gt 0 ] && printf -v PAD "%${EMPTY}s" && BAR="${BAR}${PAD// /░}"

echo "[$MODEL] $BAR $PCT%"
```

```python
#!/usr/bin/env python3
import json, sys

# json.load reads and parses stdin in one step
data = json.load(sys.stdin)
model = data['model']['display_name']
# "or 0" handles null values
pct = int(data.get('context_window', {}).get('used_percentage', 0) or 0)

# String multiplication builds the bar
filled = pct * 10 // 100
bar = '▓' * filled + '░' * (10 - filled)

print(f"[{model}] {bar} {pct}%")
```

```python
#!/usr/bin/env node
// Node.js reads stdin asynchronously with events
let input = '';
process.stdin.on('data', chunk => input += chunk);
process.stdin.on('end', () => {
    const data = JSON.parse(input);
    const model = data.model.display_name;
    // Optional chaining (?.) safely handles null fields
    const pct = Math.floor(data.context_window?.used_percentage || 0);

    // String.repeat() builds the bar
    const filled = Math.floor(pct * 10 / 100);
    const bar = '▓'.repeat(filled) + '░'.repeat(10 - filled);

    console.log(`[${model}] ${bar} ${pct}%`);
});
```


[​](#git-status-with-colors)

Git status with colors

Show git branch with color-coded indicators for staged and modified files. This script uses [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) for terminal colors: `\033[32m` is green, `\033[33m` is yellow, and `\033[0m` resets to default.

Each script checks if the current directory is a git repository, counts staged and modified files, and displays color-coded indicators:

Bash

Python

Node.js

```python
#!/bin/bash
input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')

GREEN='\033[32m'
YELLOW='\033[33m'
RESET='\033[0m'

if git rev-parse --git-dir > /dev/null 2>&1; then
    BRANCH=$(git branch --show-current 2>/dev/null)
    STAGED=$(git diff --cached --numstat 2>/dev/null | wc -l | tr -d ' ')
    MODIFIED=$(git diff --numstat 2>/dev/null | wc -l | tr -d ' ')

    GIT_STATUS=""
    [ "$STAGED" -gt 0 ] && GIT_STATUS="${GREEN}+${STAGED}${RESET}"
    [ "$MODIFIED" -gt 0 ] && GIT_STATUS="${GIT_STATUS}${YELLOW}~${MODIFIED}${RESET}"

    echo -e "[$MODEL] 📁 ${DIR##*/} | 🌿 $BRANCH $GIT_STATUS"
else
    echo "[$MODEL] 📁 ${DIR##*/}"
fi
```

```python
#!/usr/bin/env python3
import json, sys, subprocess, os

data = json.load(sys.stdin)
model = data['model']['display_name']
directory = os.path.basename(data['workspace']['current_dir'])

GREEN, YELLOW, RESET = '\033[32m', '\033[33m', '\033[0m'

try:
    subprocess.check_output(['git', 'rev-parse', '--git-dir'], stderr=subprocess.DEVNULL)
    branch = subprocess.check_output(['git', 'branch', '--show-current'], text=True).strip()
    staged_output = subprocess.check_output(['git', 'diff', '--cached', '--numstat'], text=True).strip()
    modified_output = subprocess.check_output(['git', 'diff', '--numstat'], text=True).strip()
    staged = len(staged_output.split('\n')) if staged_output else 0
    modified = len(modified_output.split('\n')) if modified_output else 0

    git_status = f"{GREEN}+{staged}{RESET}" if staged else ""
    git_status += f"{YELLOW}~{modified}{RESET}" if modified else ""

    print(f"[{model}] 📁 {directory} | 🌿 {branch} {git_status}")
except:
    print(f"[{model}] 📁 {directory}")
```

```python
#!/usr/bin/env node
const { execSync } = require('child_process');
const path = require('path');

let input = '';
process.stdin.on('data', chunk => input += chunk);
process.stdin.on('end', () => {
    const data = JSON.parse(input);
    const model = data.model.display_name;
    const dir = path.basename(data.workspace.current_dir);

    const GREEN = '\x1b[32m', YELLOW = '\x1b[33m', RESET = '\x1b[0m';

    try {
        execSync('git rev-parse --git-dir', { stdio: 'ignore' });
        const branch = execSync('git branch --show-current', { encoding: 'utf8' }).trim();
        const staged = execSync('git diff --cached --numstat', { encoding: 'utf8' }).trim().split('\n').filter(Boolean).length;
        const modified = execSync('git diff --numstat', { encoding: 'utf8' }).trim().split('\n').filter(Boolean).length;

        let gitStatus = staged ? `${GREEN}+${staged}${RESET}` : '';
        gitStatus += modified ? `${YELLOW}~${modified}${RESET}` : '';

        console.log(`[${model}] 📁 ${dir} | 🌿 ${branch} ${gitStatus}`);
    } catch {
        console.log(`[${model}] 📁 ${dir}`);
    }
});
```


[​](#cost-and-duration-tracking)

Cost and duration tracking

Track your session’s API costs and elapsed time. The `cost.total_cost_usd` field accumulates the estimated cost of all API calls in the current session. The `cost.total_duration_ms` field measures the total time the session has been running, while `cost.total_api_duration_ms` tracks only the time spent waiting for API responses. Each script formats cost as currency and converts milliseconds to minutes and seconds:

Bash

Python

Node.js

```python
#!/bin/bash
input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name')
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
DURATION_MS=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')

COST_FMT=$(printf '$%.2f' "$COST")
DURATION_SEC=$((DURATION_MS / 1000))
MINS=$((DURATION_SEC / 60))
SECS=$((DURATION_SEC % 60))

echo "[$MODEL] 💰 $COST_FMT | ⏱️ ${MINS}m ${SECS}s"
```

```python
#!/usr/bin/env python3
import json, sys

data = json.load(sys.stdin)
model = data['model']['display_name']
cost = data.get('cost', {}).get('total_cost_usd', 0) or 0
duration_ms = data.get('cost', {}).get('total_duration_ms', 0) or 0

duration_sec = duration_ms // 1000
mins, secs = duration_sec // 60, duration_sec % 60

print(f"[{model}] 💰 ${cost:.2f} | ⏱️ {mins}m {secs}s")
```

```python
#!/usr/bin/env node
let input = '';
process.stdin.on('data', chunk => input += chunk);
process.stdin.on('end', () => {
    const data = JSON.parse(input);
    const model = data.model.display_name;
    const cost = data.cost?.total_cost_usd || 0;
    const durationMs = data.cost?.total_duration_ms || 0;

    const durationSec = Math.floor(durationMs / 1000);
    const mins = Math.floor(durationSec / 60);
    const secs = durationSec % 60;

    console.log(`[${model}] 💰 $${cost.toFixed(2)} | ⏱️ ${mins}m ${secs}s`);
});
```


[​](#display-multiple-lines)

Display multiple lines

Your script can output multiple lines to create a richer display.

This example combines several techniques: threshold-based colors (green under 70%, yellow 70-89%, red 90%+), a progress bar, and git branch info. Each `print` or `echo` statement creates a separate row:

Bash

Python

Node.js

```python
#!/bin/bash
input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
DURATION_MS=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')

CYAN='\033[36m'; GREEN='\033[32m'; YELLOW='\033[33m'; RED='\033[31m'; RESET='\033[0m'

# Pick bar color based on context usage
if [ "$PCT" -ge 90 ]; then BAR_COLOR="$RED"
elif [ "$PCT" -ge 70 ]; then BAR_COLOR="$YELLOW"
else BAR_COLOR="$GREEN"; fi

FILLED=$((PCT / 10)); EMPTY=$((10 - FILLED))
printf -v FILL "%${FILLED}s"; printf -v PAD "%${EMPTY}s"
BAR="${FILL// /█}${PAD// /░}"

MINS=$((DURATION_MS / 60000)); SECS=$(((DURATION_MS % 60000) / 1000))

BRANCH=""
git rev-parse --git-dir > /dev/null 2>&1 && BRANCH=" | 🌿 $(git branch --show-current 2>/dev/null)"

echo -e "${CYAN}[$MODEL]${RESET} 📁 ${DIR##*/}$BRANCH"
COST_FMT=$(printf '$%.2f' "$COST")
echo -e "${BAR_COLOR}${BAR}${RESET} ${PCT}% | ${YELLOW}${COST_FMT}${RESET} | ⏱️ ${MINS}m ${SECS}s"
```

```python
#!/usr/bin/env python3
import json, sys, subprocess, os

data = json.load(sys.stdin)
model = data['model']['display_name']
directory = os.path.basename(data['workspace']['current_dir'])
cost = data.get('cost', {}).get('total_cost_usd', 0) or 0
pct = int(data.get('context_window', {}).get('used_percentage', 0) or 0)
duration_ms = data.get('cost', {}).get('total_duration_ms', 0) or 0

CYAN, GREEN, YELLOW, RED, RESET = '\033[36m', '\033[32m', '\033[33m', '\033[31m', '\033[0m'

bar_color = RED if pct >= 90 else YELLOW if pct >= 70 else GREEN
filled = pct // 10
bar = '█' * filled + '░' * (10 - filled)

mins, secs = duration_ms // 60000, (duration_ms % 60000) // 1000

try:
    branch = subprocess.check_output(['git', 'branch', '--show-current'], text=True, stderr=subprocess.DEVNULL).strip()
    branch = f" | 🌿 {branch}" if branch else ""
except:
    branch = ""

print(f"{CYAN}[{model}]{RESET} 📁 {directory}{branch}")
print(f"{bar_color}{bar}{RESET} {pct}% | {YELLOW}${cost:.2f}{RESET} | ⏱️ {mins}m {secs}s")
```

```python
#!/usr/bin/env node
const { execSync } = require('child_process');
const path = require('path');

let input = '';
process.stdin.on('data', chunk => input += chunk);
process.stdin.on('end', () => {
    const data = JSON.parse(input);
    const model = data.model.display_name;
    const dir = path.basename(data.workspace.current_dir);
    const cost = data.cost?.total_cost_usd || 0;
    const pct = Math.floor(data.context_window?.used_percentage || 0);
    const durationMs = data.cost?.total_duration_ms || 0;

    const CYAN = '\x1b[36m', GREEN = '\x1b[32m', YELLOW = '\x1b[33m', RED = '\x1b[31m', RESET = '\x1b[0m';

    const barColor = pct >= 90 ? RED : pct >= 70 ? YELLOW : GREEN;
    const filled = Math.floor(pct / 10);
    const bar = '█'.repeat(filled) + '░'.repeat(10 - filled);

    const mins = Math.floor(durationMs / 60000);
    const secs = Math.floor((durationMs % 60000) / 1000);

    let branch = '';
    try {
        branch = execSync('git branch --show-current', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
        branch = branch ? ` | 🌿 ${branch}` : '';
    } catch {}

    console.log(`${CYAN}[${model}]${RESET} 📁 ${dir}${branch}`);
    console.log(`${barColor}${bar}${RESET} ${pct}% | ${YELLOW}$${cost.toFixed(2)}${RESET} | ⏱️ ${mins}m ${secs}s`);
});
```


[​](#clickable-links)

Clickable links

This example creates a clickable link to your GitHub repository. Hold Cmd (macOS) or Ctrl (Windows/Linux) and click to open the link in your browser.

Each script gets the git remote URL, converts SSH format to HTTPS, and wraps the repo name in OSC 8 escape codes. The Bash version uses `printf '%b'` which interprets backslash escapes more reliably than `echo -e` across different shells:

Bash

Python

Node.js

```python
#!/bin/bash
input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name')

# Convert git SSH URL to HTTPS
REMOTE=$(git remote get-url origin 2>/dev/null | sed 's/git@github.com:/https:\/\/github.com\//' | sed 's/\.git$//')

if [ -n "$REMOTE" ]; then
    REPO_NAME=$(basename "$REMOTE")
    # OSC 8 format: \e]8;;URL\a then TEXT then \e]8;;\a
    # printf %b interprets escape sequences reliably across shells
    printf '%b' "[$MODEL] 🔗 \e]8;;${REMOTE}\a${REPO_NAME}\e]8;;\a\n"
else
    echo "[$MODEL]"
fi
```

```python
#!/usr/bin/env python3
import json, sys, subprocess, re, os

data = json.load(sys.stdin)
model = data['model']['display_name']

# Get git remote URL
try:
    remote = subprocess.check_output(
        ['git', 'remote', 'get-url', 'origin'],
        stderr=subprocess.DEVNULL, text=True
    ).strip()
    # Convert SSH to HTTPS format
    remote = re.sub(r'^git@github\.com:', 'https://github.com/', remote)
    remote = re.sub(r'\.git$', '', remote)
    repo_name = os.path.basename(remote)
    # OSC 8 escape sequences
    link = f"\033]8;;{remote}\a{repo_name}\033]8;;\a"
    print(f"[{model}] 🔗 {link}")
except:
    print(f"[{model}]")
```

```python
#!/usr/bin/env node
const { execSync } = require('child_process');
const path = require('path');

let input = '';
process.stdin.on('data', chunk => input += chunk);
process.stdin.on('end', () => {
    const data = JSON.parse(input);
    const model = data.model.display_name;

    try {
        let remote = execSync('git remote get-url origin', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
        // Convert SSH to HTTPS format
        remote = remote.replace(/^git@github\.com:/, 'https://github.com/').replace(/\.git$/, '');
        const repoName = path.basename(remote);
        // OSC 8 escape sequences
        const link = `\x1b]8;;${remote}\x07${repoName}\x1b]8;;\x07`;
        console.log(`[${model}] 🔗 ${link}`);
    } catch {
        console.log(`[${model}]`);
    }
});
```


[​](#rate-limit-usage)

Rate limit usage

Display claude.ai subscription rate limit usage, or your spend against a Claude apps gateway spend limit, in the status line. For subscribers, the `rate_limits` object contains a rolling `five_hour` window and a weekly `seven_day` window. Each window provides `used_percentage`, from 0 to 100, and `resets_at`, the Unix epoch seconds when the window resets. Behind a gateway, read the `spend_limit` object, described under [spend limit fields](#spend-limit-fields). The `rate_limits` object is only present for claude.ai Pro and Max subscribers, or behind a Claude apps gateway with spend limits, and only after the first API response. Each script handles the absent fields gracefully, and behind a gateway prints `spend: $314.12 / $500`, or `spend: 63%` while the dollar fields are absent:

Bash

Python

Node.js

```python
#!/bin/bash
input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name')
# "// empty" produces no output when rate_limits is absent
FIVE_H=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
WEEK=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')

LIMITS=""
[ -n "$FIVE_H" ] && LIMITS="5h: $(printf '%.0f' "$FIVE_H")%"
[ -n "$WEEK" ] && LIMITS="${LIMITS:+$LIMITS }7d: $(printf '%.0f' "$WEEK")%"

# Behind a Claude apps gateway: dollars when the gateway reports them, else the percentage
SPEND_PCT=$(echo "$input" | jq -r '.rate_limits.spend_limit.used_percentage // empty')
SPEND_USD=$(echo "$input" | jq -r '.rate_limits.spend_limit | select(.used_usd != null) | "$\(.used_usd) / $\(.limit_usd)"')
[ -n "$SPEND_PCT" ] && LIMITS="${LIMITS:+$LIMITS }spend: ${SPEND_USD:-$(printf '%.0f' "$SPEND_PCT")%}"

[ -n "$LIMITS" ] && echo "[$MODEL] | $LIMITS" || echo "[$MODEL]"
```

```python
#!/usr/bin/env python3
import json, sys

data = json.load(sys.stdin)
model = data['model']['display_name']

parts = []
rate = data.get('rate_limits', {})
five_h = rate.get('five_hour', {}).get('used_percentage')
week = rate.get('seven_day', {}).get('used_percentage')

if five_h is not None:
    parts.append(f"5h: {five_h:.0f}%")
if week is not None:
    parts.append(f"7d: {week:.0f}%")

# Behind a Claude apps gateway: dollars when the gateway reports them, else the percentage
spend = rate.get('spend_limit', {})
if spend.get('used_percentage') is not None:
    if spend.get('used_usd') is not None:
        parts.append(f"spend: ${spend['used_usd']} / ${spend['limit_usd']}")
    else:
        parts.append(f"spend: {spend['used_percentage']:.0f}%")

if parts:
    print(f"[{model}] | {' '.join(parts)}")
else:
    print(f"[{model}]")
```

```python
#!/usr/bin/env node
let input = '';
process.stdin.on('data', chunk => input += chunk);
process.stdin.on('end', () => {
    const data = JSON.parse(input);
    const model = data.model.display_name;

    const parts = [];
    const fiveH = data.rate_limits?.five_hour?.used_percentage;
    const week = data.rate_limits?.seven_day?.used_percentage;

    if (fiveH != null) parts.push(`5h: ${Math.round(fiveH)}%`);
    if (week != null) parts.push(`7d: ${Math.round(week)}%`);

    // Behind a Claude apps gateway: dollars when the gateway reports them, else the percentage
    const spend = data.rate_limits?.spend_limit;
    if (spend?.used_percentage != null) {
        parts.push(spend.used_usd != null
            ? `spend: $${spend.used_usd} / $${spend.limit_usd}`
            : `spend: ${Math.round(spend.used_percentage)}%`);
    }

    console.log(parts.length ? `[${model}] | ${parts.join(' ')}` : `[${model}]`);
});
```


[​](#cache-expensive-operations)

Cache expensive operations

Your status line script runs frequently during active sessions. Commands like `git status` or `git diff` can be slow, especially in large repositories. This example caches git information to a temp file and only refreshes it every 5 seconds. The cache filename needs to be stable across status line invocations within a session, but unique across sessions so concurrent sessions in different repositories don’t read each other’s cached git state. Process-based identifiers like `$$`, `os.getpid()`, or `process.pid` change on every invocation and defeat the cache. Use the `session_id` from the JSON input instead: it’s stable for the lifetime of a session and unique per session. Each script checks if the cache file is missing or older than 5 seconds before running git commands:

Bash

Python

Node.js

```python
#!/bin/bash
input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
SESSION_ID=$(echo "$input" | jq -r '.session_id')

CACHE_FILE="/tmp/statusline-git-cache-$SESSION_ID"
CACHE_MAX_AGE=5  # seconds

cache_is_stale() {
    [ ! -f "$CACHE_FILE" ] || \
    # stat -c %Y (Linux) or stat -f %m (macOS) prints the file's last-modified
    # time. The Linux form must run first: on Linux, the macOS form prints a
    # filesystem report to stdout before failing, and that output would be
    # captured by the command substitution and break the arithmetic.
    [ $(($(date +%s) - $(stat -c %Y "$CACHE_FILE" 2>/dev/null || stat -f %m "$CACHE_FILE" 2>/dev/null || echo 0))) -gt $CACHE_MAX_AGE ]
}

if cache_is_stale; then
    if git rev-parse --git-dir > /dev/null 2>&1; then
        BRANCH=$(git branch --show-current 2>/dev/null)
        STAGED=$(git diff --cached --numstat 2>/dev/null | wc -l | tr -d ' ')
        MODIFIED=$(git diff --numstat 2>/dev/null | wc -l | tr -d ' ')
        echo "$BRANCH|$STAGED|$MODIFIED" > "$CACHE_FILE"
    else
        echo "||" > "$CACHE_FILE"
    fi
fi

IFS='|' read -r BRANCH STAGED MODIFIED < "$CACHE_FILE"

if [ -n "$BRANCH" ]; then
    echo "[$MODEL] 📁 ${DIR##*/} | 🌿 $BRANCH +$STAGED ~$MODIFIED"
else
    echo "[$MODEL] 📁 ${DIR##*/}"
fi
```

```python
#!/usr/bin/env python3
import json, sys, subprocess, os, time

data = json.load(sys.stdin)
model = data['model']['display_name']
directory = os.path.basename(data['workspace']['current_dir'])
session_id = data['session_id']

CACHE_FILE = f"/tmp/statusline-git-cache-{session_id}"
CACHE_MAX_AGE = 5  # seconds

def cache_is_stale():
    if not os.path.exists(CACHE_FILE):
        return True
    return time.time() - os.path.getmtime(CACHE_FILE) > CACHE_MAX_AGE

if cache_is_stale():
    try:
        subprocess.check_output(['git', 'rev-parse', '--git-dir'], stderr=subprocess.DEVNULL)
        branch = subprocess.check_output(['git', 'branch', '--show-current'], text=True).strip()
        staged = subprocess.check_output(['git', 'diff', '--cached', '--numstat'], text=True).strip()
        modified = subprocess.check_output(['git', 'diff', '--numstat'], text=True).strip()
        staged_count = len(staged.split('\n')) if staged else 0
        modified_count = len(modified.split('\n')) if modified else 0
        with open(CACHE_FILE, 'w') as f:
            f.write(f"{branch}|{staged_count}|{modified_count}")
    except:
        with open(CACHE_FILE, 'w') as f:
            f.write("||")

with open(CACHE_FILE) as f:
    branch, staged, modified = f.read().strip().split('|')

if branch:
    print(f"[{model}] 📁 {directory} | 🌿 {branch} +{staged} ~{modified}")
else:
    print(f"[{model}] 📁 {directory}")
```

```python
#!/usr/bin/env node
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');

let input = '';
process.stdin.on('data', chunk => input += chunk);
process.stdin.on('end', () => {
    const data = JSON.parse(input);
    const model = data.model.display_name;
    const dir = path.basename(data.workspace.current_dir);
    const sessionId = data.session_id;

    const CACHE_FILE = `/tmp/statusline-git-cache-${sessionId}`;
    const CACHE_MAX_AGE = 5; // seconds

    const cacheIsStale = () => {
        if (!fs.existsSync(CACHE_FILE)) return true;
        return (Date.now() / 1000) - fs.statSync(CACHE_FILE).mtimeMs / 1000 > CACHE_MAX_AGE;
    };

    if (cacheIsStale()) {
        try {
            execSync('git rev-parse --git-dir', { stdio: 'ignore' });
            const branch = execSync('git branch --show-current', { encoding: 'utf8' }).trim();
            const staged = execSync('git diff --cached --numstat', { encoding: 'utf8' }).trim().split('\n').filter(Boolean).length;
            const modified = execSync('git diff --numstat', { encoding: 'utf8' }).trim().split('\n').filter(Boolean).length;
            fs.writeFileSync(CACHE_FILE, `${branch}|${staged}|${modified}`);
        } catch {
            fs.writeFileSync(CACHE_FILE, '||');
        }
    }

    const [branch, staged, modified] = fs.readFileSync(CACHE_FILE, 'utf8').trim().split('|');

    if (branch) {
        console.log(`[${model}] 📁 ${dir} | 🌿 ${branch} +${staged} ~${modified}`);
    } else {
        console.log(`[${model}] 📁 ${dir}`);
    }
});
```


[​](#windows-configuration)

Windows configuration

On Windows, Claude Code runs status line commands through Git Bash when Git Bash is installed, or through PowerShell when Git Bash is absent. Git Bash treats unquoted backslashes as escape characters, so a Windows-style path such as `C:\Users\username\script.mjs` reaches the script runner with its separators removed and the command fails without a visible error. Write file paths in the `command` string with forward slashes, as shown in the examples below. The `~` shorthand also works and expands to your Windows home directory. To run a PowerShell script as your status line, invoke it via `powershell`. This works whether Claude Code routes the command through Git Bash or PowerShell:

settings.json

statusline.ps1

```python
{
  "statusLine": {
    "type": "command",
    "command": "powershell -NoProfile -File C:/Users/username/.claude/statusline.ps1"
  }
}
```

```python
$input_json = $input | Out-String | ConvertFrom-Json
$cwd = $input_json.cwd
$model = $input_json.model.display_name
$used = $input_json.context_window.used_percentage
$dirname = Split-Path $cwd -Leaf

if ($used) {
    Write-Host "$dirname [$model] ctx: $used%"
} else {
    Write-Host "$dirname [$model]"
}
```

Or, when Git Bash is installed, run a Bash script directly:

settings.json

statusline.sh

```python
{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh"
  }
}
```

```python
#!/usr/bin/env bash
input=$(cat)
cwd=$(echo "$input" | grep -o '"cwd":"[^"]*"' | cut -d'"' -f4)
model=$(echo "$input" | grep -o '"display_name":"[^"]*"' | cut -d'"' -f4)
dirname="${cwd##*[/\\]}"
echo "$dirname [$model]"
```


[​](#subagent-status-lines)

Subagent status lines

The `subagentStatusLine` setting renders a custom row body for each [subagent](../09-Agents-Patterns/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.

```python
{
  "subagentStatusLine": {
    "type": "command",
    "command": "~/.claude/subagent-statusline.sh"
  }
}
```

The 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](../07-Hooks/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). Write 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. The same trust, `disableAllHooks`, and [`allowManagedHooksOnly`](settings-reference.md#allowmanagedhooksonly) gates that apply to `statusLine` apply here. Plugins can ship a default `subagentStatusLine` in their [`settings.json`](../08-Plugins-Skills/plugins-reference.md#standard-layout), but unlike hooks, plugin values don’t run under `allowManagedHooksOnly` even when the plugin is force-enabled in managed settings `enabledPlugins`.


[​](#task-fields)

Task fields

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

| Field               | Type                       | Description                                                                                                                                                                                                                                                                                                                                                                       |
|:--------------------|:---------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id`                | string                     | Identifier of the task. Echo it as `id` in the line you write back for this row                                                                                                                                                                                                                                                                                                   |
| `name`              | string, optional           | Name the subagent is [addressed by](../09-Agents-Patterns/sub-agents.md#subagent-names), when it has one                                                                                                                                                                                                                                                                                          |
| `type`              | string                     | Kind of task: `local_agent`                                                                                                                                                                                                                                                                                                                                                       |
| `agentType`         | string                     | Subagent type the task runs as, such as the built-in [`Explore`](../09-Agents-Patterns/sub-agents.md#built-in-subagents) or a custom `code-reviewer`. Holds the same value that hooks receive as [`agent_type`](../07-Hooks/hooks.md#subagentstart). Requires Claude Code v2.1.293 or later                                                                                                             |
| `status`            | string                     | State of the task, such as `running`, `completed`, `failed`, or `killed`                                                                                                                                                                                                                                                                                                          |
| `description`       | string                     | Short description of the task, such as the one Claude gave when it spawned the subagent                                                                                                                                                                                                                                                                                           |
| `label`             | string                     | Short progress summary of the task when Claude Code has one, otherwise the same text as `description`                                                                                                                                                                                                                                                                             |
| `startTime`         | number                     | When the task started, in milliseconds since the Unix epoch                                                                                                                                                                                                                                                                                                                       |
| `model`             | string, optional           | ID of the resolved model the task runs on. Omitted until the model is resolved                                                                                                                                                                                                                                                                                                    |
| `effort`            | string or number, optional | Reasoning effort set for the subagent in its [definition frontmatter](../09-Agents-Patterns/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 |
| `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                                                                                                                                            |
| `tokenCount`        | number                     | Running token count of the subagent, the figure the default row shows                                                                                                                                                                                                                                                                                                             |
| `tokenSamples`      | array of numbers           | Up to the last 16 `tokenCount` readings, one per refresh tick, oldest first and ending with the current one                                                                                                                                                                                                                                                                       |
| `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                                                                                                                                                                                                                                 |


[​](#tips)

Tips

- **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`
- **Keep output short**: the status bar has limited width, so long output may get truncated or wrap awkwardly
- **Cache slow operations**: your script runs frequently during active sessions, so commands like `git status` can cause lag. See the [caching example](#cache-expensive-operations) for how to handle this.

Community projects like [ccstatusline](https://github.com/sirmalloc/ccstatusline) and [starship-claude](https://github.com/martinemde/starship-claude) provide pre-built configurations with themes and additional features.


[​](#troubleshooting)

Troubleshooting

If the status line is blank, start with [Status line not appearing](#status-line-not-appearing). A folder you haven’t trusted and a script that fails also leave it blank, as [Workspace trust required](#workspace-trust-required) and [Script errors or hangs](#script-errors-or-hangs) describe.


[​](#status-line-not-appearing)

Status line not appearing

If you configured a status line and nothing shows at the bottom of the interface, work through these checks:

- Verify your script is executable: `chmod +x ~/.claude/statusline.sh`
- Check that your script outputs to stdout, not stderr
- Run your script manually to verify it produces output
- On Windows with Git Bash installed, backslashes in the `command` path are likely being consumed as escape characters before the script runs. Use forward slashes in the path. See [Windows configuration](#windows-configuration).
- If `disableAllHooks` is `true` outside managed settings after [settings precedence](../07-Hooks/hooks.md#disable-or-remove-hooks) applies, Claude Code runs only a `statusLine` from managed settings, and with no managed `statusLine` the status line is disabled. Remove the setting, or set it to `false` in the file that sets it, to re-enable. See [`disableAllHooks`](settings-reference.md#disableallhooks).
- If your organization sets `allowManagedHooksOnly` in managed settings, your custom status line disappears without warning: you can only get a status line from a `statusLine` value in those managed settings. See [what runs under `allowManagedHooksOnly`](settings-reference.md#what-runs-under-allowmanagedhooksonly) for the full behavior, and ask your administrator whether this setting applies to you.
- Run `claude --debug` to log your script’s stderr on every status line invocation, and its exit code on the first invocation in a session
- Ask Claude to read your settings file and execute the `statusLine` command directly to surface errors


[​](#status-line-shows-or-empty-values)

Status line shows `--` or empty values

Fields may be `null` before the first API response completes, so handle null values in your script with fallbacks such as `// 0` in jq. Restart Claude Code if values remain empty after multiple messages.


[​](#context-percentage-shows-unexpected-values)

Context percentage shows unexpected values

The status line reports the counts from the last API response, while `/context` adds an estimate for messages added since that response, so `/context` can read higher until the next response. Use `used_percentage` for the simplest accurate context state. For the formula behind `used_percentage`, see [Context window fields](#context-window-fields).


[​](#osc-8-links-not-clickable)

OSC 8 links not clickable

Whether a link is clickable depends on your terminal, on whether Claude Code detects hyperlink support in it, on whether SSH or tmux strips the escape sequence, and on how your script prints it:

- Verify your terminal supports OSC 8 hyperlinks (iTerm2, Kitty, WezTerm)
- Terminal.app does not support clickable links
- If link text appears but isn’t clickable, Claude Code may not have detected hyperlink support in your terminal. Set the `FORCE_HYPERLINK` environment variable to override detection before launching Claude Code:

  ``` shiki
  FORCE_HYPERLINK=1 claude
  ```

  In PowerShell, set the variable in the current session first:

  ``` shiki
  $env:FORCE_HYPERLINK = "1"; claude
  ```
- SSH and tmux sessions may strip OSC sequences depending on configuration
- If escape sequences appear as literal text like `\e]8;;`, use `printf '%b'` instead of `echo -e` for more reliable escape handling


[​](#display-glitches-with-escape-sequences)

Display glitches with escape sequences

Complex escape sequences (ANSI colors, OSC 8 links) can occasionally cause garbled output if they overlap with other UI updates. Multi-line status lines with escape codes are more prone to rendering issues than single-line plain text. If you see corrupted text, try simplifying your script to plain text output.


[​](#workspace-trust-required)

Workspace trust required

Until you accept the workspace trust dialog, the status line stays blank. Because `statusLine` executes a shell command, Claude Code runs it under the same [workspace trust rule as hooks in settings files](permissions.md#what-runs-before-you-trust-a-folder). Accepting the dialog for the folder, or for a parent directory whose trust extends to it, is enough. Until then, `claude --debug` logs `Status line command skipped: workspace trust not accepted`. Restart Claude Code and accept the trust dialog to enable it.


[​](#script-errors-or-hangs)

Script errors or hangs

Claude Code displays your script’s output only after the script exits with code 0:

- Scripts that exit with non-zero codes or produce no output cause the status line to go blank
- Slow scripts block the status line from updating until they complete. Keep scripts fast to avoid stale output.
- If a new update triggers while a slow script is running, the in-flight script is cancelled
- Test your script independently with mock input before configuring it


[​](#notifications-share-the-status-line-row)

Notifications share the status line row

Outside [fullscreen rendering](fullscreen.md), Claude Code shows notifications on the same row as your status line. In fullscreen rendering, Claude Code gives notifications a row of their own.

- System notifications like MCP server errors and auto-updates display on the right side of the row. Transient notifications such as the context-low warning also cycle through this area.
- Enabling verbose mode adds a token counter to this area, showing the size of your context as the last API response reported it, not the [per-turn count beside the spinner](../17-Billing-Plans/costs.md#read-the-token-count-beside-the-spinner)
- On narrow terminals, these notifications may truncate your status line output

---

## Configure your terminal for Claude Code - Claude Code Docs

Source: https://code.claude.com/docs/en/terminal-config
Path: 02-Claude-Code-CLI/terminal-config.md

## On this page

- [Enter multiline prompts](#enter-multiline-prompts)
- [Enable Option key shortcuts on macOS](#enable-option-key-shortcuts-on-macos)
- [Get a terminal bell or notification](#get-a-terminal-bell-or-notification)
  - [Play a sound with a Notification hook](#play-a-sound-with-a-notification-hook)
- [See session status in your terminal](#see-session-status-in-your-terminal)
- [Configure tmux](#configure-tmux)
- [Fix Backspace deleting a whole word on Windows](#fix-backspace-deleting-a-whole-word-on-windows)
- [Match the color theme](#match-the-color-theme)
  - [Create a custom theme](#create-a-custom-theme)
- [Switch to fullscreen rendering](#switch-to-fullscreen-rendering)
- [Cap response width in wide terminals](#cap-response-width-in-wide-terminals)
- [Paste large content](#paste-large-content)
  - [How Claude treats pasted text](#how-claude-treats-pasted-text)
  - [Delete and restore a collapsed paste](#delete-and-restore-a-collapsed-paste)
  - [Recall a prompt that had pasted text](#recall-a-prompt-that-had-pasted-text)
- [Edit prompts with Vim keybindings](#edit-prompts-with-vim-keybindings)
- [Related resources](#related-resources)

Interface

# Configure your terminal for Claude Code

Copy pageCopy page

Fix Shift+Enter for newlines, get a terminal bell when Claude finishes, configure tmux, match the color theme, and enable Vim mode in the Claude Code CLI.

Copy pageCopy page

Claude Code works in any terminal without configuration. This page is for when something specific is not behaving the way you expect. Find your symptom below. If everything already feels right, you do not need this page.

- [Shift+Enter submits instead of inserting a newline](#enter-multiline-prompts)
- [Option-key shortcuts do nothing on macOS](#enable-option-key-shortcuts-on-macos)
- [No sound or alert when Claude finishes](#get-a-terminal-bell-or-notification)
- [You run Claude Code inside tmux](#configure-tmux)
- [Backspace deletes a whole word on Windows](#fix-backspace-deleting-a-whole-word-on-windows)
- [Display flickers or scrollback jumps](#switch-to-fullscreen-rendering)
- [You want Vim keys in the prompt](#edit-prompts-with-vim-keybindings)

This page is about getting your terminal to send the right signals to Claude Code. To change which keys Claude Code itself responds to, see [keybindings](keybindings.md) instead.


[​](#enter-multiline-prompts)

Enter multiline prompts

Pressing Enter submits your message. To add a line break without submitting, press Ctrl+J, or type `\` and then press Enter. Both work in every terminal with no setup. In most terminals you can also press Shift+Enter, but support varies by terminal emulator:

| Terminal                                                                                           | Shift+Enter for newline                                     |
|:---------------------------------------------------------------------------------------------------|:------------------------------------------------------------|
| Ghostty, Kitty, iTerm2, WezTerm, Warp, Apple Terminal, Windows Terminal                            | Works without setup                                         |
| 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 |
| VS Code, Cursor, Devin Desktop, Alacritty before 0.16, Zed                                         | Run `/terminal-setup` once                                  |
| gnome-terminal, JetBrains IDEs such as PyCharm and Android Studio                                  | Not available; use Ctrl+J or `\` then Enter                 |

For VS Code, Cursor, Devin Desktop, Alacritty before 0.16, and Zed, `/terminal-setup` writes a Shift+Enter keybinding into the terminal’s configuration file. On the first run you see a confirmation such as `Installed VSCode terminal Shift+Enter key binding`. Existing bindings are left in place; if you see a message such as `VSCode terminal Shift+Enter key binding already configured`, no change was made. Run `/terminal-setup` directly in the host terminal rather than inside tmux or screen, since it needs to write to the host terminal’s configuration. In VS Code, Cursor, and Devin Desktop, `/terminal-setup` also updates two editor settings: it sets `terminal.integrated.gpuAcceleration` to `"off"` to prevent garbled text in the integrated terminal, and it sets `terminal.integrated.mouseWheelScrollSensitivity` for smoother scrolling in [fullscreen mode](fullscreen.md). To undo the GPU acceleration change, set it back to `"auto"` and reload the editor window. In Zed, `/terminal-setup` updates your `keymap.json` in place:

- If the keymap already has bindings and none of them is a Terminal `shift-enter`, Claude Code first backs it up to a copy in the same directory, such as `keymap.json.1a2b3c4d.bak`, then merges the Shift+Enter binding into your keymap, keeping your other keybindings and comments
- If Claude Code can’t read or parse the keymap, can’t back it up, or can’t verify the merged result, it [leaves the file unchanged and prints the keybinding block to add yourself](errors.md#terminal-setup-left-your-zed-keymap-unchanged)

If you are running inside tmux, Shift+Enter also requires the [tmux configuration below](#configure-tmux) even when the outer terminal supports it. To bind newline to a different key, or to swap behavior so Enter inserts a newline and Shift+Enter submits, map the `chat:newline` and `chat:submit` actions in your [keybindings file](keybindings.md).


[​](#enable-option-key-shortcuts-on-macos)

Enable Option key shortcuts on macOS

Some Claude Code shortcuts use the Option key, such as Option+Enter for a newline or Option+P to switch models. On macOS, most terminals do not send Option as a modifier by default, so these shortcuts do nothing until you enable it. The terminal setting for this is usually labeled “Use Option as Meta Key”; Meta is the historical Unix name for the key now labeled Option or Alt.

- Apple Terminal

- iTerm2

- VS Code

Open Settings → Profiles → Keyboard and check “Use Option as Meta Key”.If you accepted Claude Code’s first-run terminal setup prompt, this is already done. That prompt runs `/terminal-setup` for you, which enables Option as Meta and turns off the audible bell in your Apple Terminal profile.In [screen reader mode](accessibility.md), `/terminal-setup` leaves the bell setting unchanged so the terminal bell stays audible. If an earlier run turned the bell off, turn it back on under Settings → Profiles → Advanced → “Audible bell”.

Open Settings → Profiles → Keys → General and set Left Option key and Right Option key to “Esc+”.Running `/terminal-setup` in iTerm2 enables “Applications in terminal may access clipboard” under Settings → General → Selection so the `/copy` command can write to your system clipboard. The command detects iTerm2 even when run from inside tmux. Restart iTerm2 for the change to take effect.

Add `"terminal.integrated.macOptionIsMeta": true` to your VS Code settings.

For Ghostty, Kitty, and other terminals, look for an Option-as-Alt or Option-as-Meta setting in the terminal’s configuration file.


[​](#get-a-terminal-bell-or-notification)

Get a terminal bell or notification

When Claude finishes a task or pauses for a permission prompt, and you appear to be away from the terminal, it fires a notification event. See [when each notification type fires](../07-Hooks/hooks.md#notification) for the exact timing. Surfacing this as a terminal bell or desktop notification lets you switch to other work while a long task runs. By default Claude Code sends a desktop notification only in Ghostty, Kitty, and iTerm2. In other terminals, set [`preferredNotifChannel`](settings-reference.md#preferrednotifchannel) to `"terminal_bell"` to ring the terminal bell instead, or configure a [Notification hook](#play-a-sound-with-a-notification-hook) for a custom sound or command. The following settings entry turns on the terminal bell:

~/.claude/settings.json

```python
{
  "preferredNotifChannel": "terminal_bell"
}
```

The desktop notification reaches your local machine over SSH, so a remote session can still alert you. Ghostty and Kitty forward it to your OS notification center without further setup. iTerm2 requires you to enable forwarding:

1

Open iTerm2 notification settings

Go to Settings → Profiles → Terminal.

2

Enable alerts

Check “Notification Center Alerts”, then click “Filter Alerts” and enable “Send escape sequence-generated alerts”.

If notifications still do not appear, confirm that your terminal application has notification permission in your OS settings, and if you are running inside tmux, [enable passthrough](#configure-tmux).


[​](#play-a-sound-with-a-notification-hook)

Play a sound with a Notification hook

In any terminal you can configure a [Notification hook](../07-Hooks/hooks-guide.md#get-notified-when-claude-needs-input) to play a sound or run a custom command when Claude needs your attention. Hooks run alongside the built-in notification rather than replacing it, so terminals that do not receive a desktop notification, such as Warp or the VS Code integrated terminal, can use a hook or set `preferredNotifChannel` to `"terminal_bell"` instead. The example below plays a system sound on macOS. The linked guide has desktop notification commands for macOS, Linux, and Windows.

~/.claude/settings.json

```python
{
  "hooks": {
    "Notification": [
      {
        "hooks": [{ "type": "command", "command": "afplay /System/Library/Sounds/Glass.aiff" }]
      }
    ]
  }
}
```


[​](#see-session-status-in-your-terminal)

See session status in your terminal

If your terminal implements the OSC 7501 Program Status Protocol, it can show whether each interactive Claude Code session is working, waiting on you, or done, which helps when you run long tasks or several sessions at once. There is nothing to turn on in Claude Code. To find out whether your terminal implements the protocol and where it shows the status, check its documentation. If it does and you see no status for a session, check for each of these causes:

- **Claude Code version**: status reporting requires Claude Code v2.1.295 or later. Run `claude --version` in your shell to check.
- **tmux**: inside tmux, Claude Code checks tmux for support instead of your terminal, and [`allow-passthrough`](#configure-tmux) has no effect on that. Start the session outside tmux.
- **Background session**: a [background session](../09-Agents-Patterns/agent-view.md) doesn’t report its status to your terminal, even while you’re attached to it. Agent view shows its status instead.
- **[`CLAUDE_CODE_DISABLE_TERMINAL_TITLE`](env-vars.md#variables)**: if you set this variable to `1`, Claude Code doesn’t check for support or report status. Unset it.


[​](#configure-tmux)

Configure tmux

When Claude Code runs inside tmux, by default Shift+Enter submits instead of inserting a newline, and desktop notifications and the [progress bar](settings-reference.md#terminalprogressbarenabled) never reach the outer terminal. Add these lines to `~/.tmux.conf`, then run `tmux source-file ~/.tmux.conf` to apply them to the running server:

~/.tmux.conf

```python
set -g allow-passthrough on
set -s extended-keys on
set -as terminal-features 'xterm*:extkeys'
```

The `allow-passthrough` line lets notifications and progress updates reach the outer terminal instead of being swallowed by tmux. The `extended-keys` lines let tmux distinguish Shift+Enter from plain Enter so the newline shortcut works.


[​](#fix-backspace-deleting-a-whole-word-on-windows)

Fix Backspace deleting a whole word on Windows

On Windows, Claude Code reads a Backspace that arrives as `^H` as Ctrl+Backspace, which [deletes the previous word](interactive-mode.md#text-editing), except when `TERM_PROGRAM` is `mintty` or `TERM` is `cygwin`. On macOS and Linux, Claude Code reads it as plain Backspace. If each press of Backspace deletes a whole word, your terminal sends `^H` for plain Backspace. Set [`CLAUDE_CODE_BS_AS_CTRL_BACKSPACE=0`](env-vars.md). Backspace and Ctrl+H then erase one character each. If Ctrl+Backspace erases only one character on macOS or Linux because your terminal sends `^H` for it, set the variable to `1` instead.


[​](#match-the-color-theme)

Match the color theme

Use the `/theme` command, or the theme picker in `/config`, to choose a Claude Code theme that matches your terminal. Selecting the auto option detects your terminal’s light or dark background, so the theme follows OS appearance changes whenever your terminal does. Claude Code does not control the terminal’s own color scheme, which is set by the terminal application. To customize what appears at the bottom of the interface, configure a [custom status line](statusline.md) that shows the current model, working directory, git branch, or other context.


[​](#create-a-custom-theme)

Create a custom theme

In addition to the built-in presets, `/theme` lists any custom themes you have defined and any themes contributed by installed [plugins](../08-Plugins-Skills/plugins-components.md#themes-and-output-styles). Select **New custom theme…** at the end of the list to create one interactively: you name the theme, then pick individual color tokens to override. Press `Ctrl+E` while a custom theme is highlighted to edit it. Each custom theme is a JSON file in `~/.claude/themes/`. The filename without the `.json` extension is the theme’s slug, and selecting the theme stores `custom:<slug>` as your theme preference. The file has three optional fields:

| Field       | Type   | Description                                                                                                                                     |
|:------------|:-------|:------------------------------------------------------------------------------------------------------------------------------------------------|
| `name`      | string | Display label shown in `/theme`. Defaults to the filename slug                                                                                  |
| `base`      | string | Built-in preset the theme starts from: `dark`, `light`, `dark-daltonized`, `light-daltonized`, `dark-ansi`, or `light-ansi`. Defaults to `dark` |
| `overrides` | object | Map of color token names to color values. Tokens not listed here fall through to the base preset                                                |

Color values accept `#rrggbb`, `#rgb`, `rgb(r,g,b)`, `ansi256(n)`, or `ansi:<name>` where `<name>` is one of the 16 standard ANSI color names such as `red` or `cyanBright`. Unknown tokens and invalid color values are ignored, so a typo cannot break rendering. The following example defines a theme that keeps the dark preset but recolors the prompt accent, error text, and success text:

~/.claude/themes/dracula.json

```python
{
  "name": "Dracula",
  "base": "dark",
  "overrides": {
    "claude": "#bd93f9",
    "error": "#ff5555",
    "success": "#50fa7b"
  }
}
```

Claude Code watches `~/.claude/themes/` and reloads when a file is added or changed, so edits made in your editor apply to a running session without a restart. If the `~/.claude/themes/` folder itself didn’t exist when Claude Code started, restart once after creating your first theme file. After that, changes apply without a restart. The reference below covers the tokens you can set in `overrides`. The interactive editor in `/theme` shows the same tokens with a live preview, plus a few single-purpose accents such as onboarding screen colors that are omitted here.

Color token reference

The following example combines tokens from several of the groups below: the brand accent, the plan mode border, the diff backgrounds, and the message background.

~/.claude/themes/midnight.json

```python
{
  "name": "Midnight",
  "base": "dark",
  "overrides": {
    "claude": "#a78bfa",
    "planMode": "#38bdf8",
    "diffAdded": "#14532d",
    "diffRemoved": "#7f1d1d",
    "userMessageBackground": "#1e1b4b"
  }
}
```


[​](#text-and-accent-colors)

Text and accent colors

Control the primary brand accent and the foreground text shades used throughout the interface.

| Token         | Controls                                                         |
|:--------------|:-----------------------------------------------------------------|
| `claude`      | Primary brand accent, used for the spinner and assistant label   |
| `text`        | Default foreground text                                          |
| `inverseText` | Text drawn on top of a colored background, such as status badges |
| `inactive`    | Secondary text such as hints, timestamps, and disabled items     |
| `subtle`      | Faint borders and de-emphasized secondary text                   |
| `suggestion`  | Autocomplete suggestions and selection highlight in pickers      |
| `permission`  | Dialog borders, including permission prompts and pickers         |
| `remember`    | Memory and `CLAUDE.md` indicators                                |


[​](#status-colors)

Status colors

Signal success, failure, and warning states across messages and indicators.

| Token     | Controls                                                |
|:----------|:--------------------------------------------------------|
| `success` | Success messages and passing checks                     |
| `error`   | Error messages and failures                             |
| `warning` | Warnings, caution messages, and the auto mode indicator |
| `merged`  | Merged pull request status                              |


[​](#input-box-and-mode-indicators)

Input box and mode indicators

Set the input box border color and the accent shown while a permission mode or indicator is active.

| Token          | Controls                                                                                                                                                                                  |
|:---------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `promptBorder` | Input box border                                                                                                                                                                          |
| `planMode`     | Plan mode accent, plan messages, and plan-mode dialogs                                                                                                                                    |
| `autoAccept`   | Accept-edits mode accent                                                                                                                                                                  |
| `bashBorder`   | Input box border when entering a `!` shell command                                                                                                                                        |
| `ide`          | IDE connection indicator                                                                                                                                                                  |
| `fastMode`     | Fast mode indicator                                                                                                                                                                       |
| `effortUltra`  | The `ultracode` tag on the input box border while [ultracode](model-config.md#adjust-effort-level) is on. Your override of this color takes effect on Claude Code v2.1.239 or later |


[​](#diff-rendering)

Diff rendering

Color added and removed code in file edits and reviews.

| Token               | Controls                                                                      |
|:--------------------|:------------------------------------------------------------------------------|
| `diffAdded`         | Background of added lines                                                     |
| `diffRemoved`       | Background of removed lines                                                   |
| `diffAddedDimmed`   | Background of added lines in the dimmed diff shown after you reject an edit   |
| `diffRemovedDimmed` | Background of removed lines in the dimmed diff shown after you reject an edit |
| `diffAddedWord`     | Word-level highlight within an added line                                     |
| `diffRemovedWord`   | Word-level highlight within a removed line                                    |


[​](#fullscreen-mode)

Fullscreen mode

Claude Code uses `userMessageBackgroundHover`, `selectionBg`, and `composerSidebarBackground` only in [fullscreen rendering mode](fullscreen.md). It paints `userMessageBackground`, `bashMessageBackgroundColor`, and `memoryBackgroundColor` in both the default and fullscreen renderers.

| Token                        | Controls                                                                                                                                                                               |
|:-----------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `userMessageBackground`      | Background behind your messages in the transcript                                                                                                                                      |
| `userMessageBackgroundHover` | Background behind a message while hovered or expanded                                                                                                                                  |
| `bashMessageBackgroundColor` | Background behind `!` shell command entries in the transcript                                                                                                                          |
| `memoryBackgroundColor`      | Background behind `#` memory entries in the transcript                                                                                                                                 |
| `selectionBg`                | Background of text selected with the mouse                                                                                                                                             |
| `composerSidebarBackground`  | Background of the panel beside the conversation, such as the [diff panel](fullscreen.md#watch-your-changes-in-the-diff-panel) or a [mod’s pane](../08-Plugins-Skills/plugins-mods-interface.md) |


[​](#usage-meter-and-speaker-labels)

Usage meter and speaker labels

Adjust the bar shown in the `/usage` view and the labels that distinguish your messages from Claude’s.

| Token              | Controls                                          |
|:-------------------|:--------------------------------------------------|
| `rate_limit_fill`  | Filled portion of the usage meter                 |
| `rate_limit_empty` | Unfilled portion of the usage meter               |
| `briefLabelYou`    | Color of the `You` label on your messages         |
| `briefLabelClaude` | Color of the `Claude` label on assistant messages |


[​](#shimmer-variants-and-subagent-colors)

Shimmer variants and subagent colors

Several tokens have a paired shimmer variant that supplies the lighter color used in the spinner’s animated gradient. Override the shimmer alongside its base token if the animation looks mismatched.

- `claude` and `claudeShimmer`
- `warning` and `warningShimmer`
- `permission` and `permissionShimmer`
- `promptBorder` and `promptBorderShimmer`
- `inactive` and `inactiveShimmer`
- `fastMode` and `fastModeShimmer`

Each [subagent](../09-Agents-Patterns/sub-agents.md) and parallel task is shown in one of eight named colors so you can tell them apart in the transcript. The token names follow the pattern `<color>_FOR_SUBAGENTS_ONLY`, where `<color>` is `red`, `blue`, `green`, `yellow`, `purple`, `orange`, `pink`, or `cyan`. Override these to change what each named color looks like. For example, a subagent with `color: blue` in its definition is drawn using the `blue_FOR_SUBAGENTS_ONLY` value.Claude Code renders the [`ultrathink`](model-config.md#use-ultrathink-for-one-off-deep-reasoning) keyword in the prompt input with a seven-color rainbow gradient. The token names follow the pattern `rainbow_<color>` and `rainbow_<color>_shimmer`, where `<color>` is `red`, `orange`, `yellow`, `green`, `blue`, `indigo`, or `violet`.


[​](#switch-to-fullscreen-rendering)

Switch to fullscreen rendering

In [screen reader mode](accessibility.md), this section doesn’t apply. Claude Code always renders as plain scrolling text except in attached [background sessions](../09-Agents-Patterns/agent-view.md), and if you run `/tui fullscreen` in any other session, Claude Code prints an explanation instead of switching. If the display flickers or the scroll position jumps while Claude is working, switch to [fullscreen rendering mode](fullscreen.md). In this mode you scroll with the mouse or PageUp inside Claude Code rather than with your terminal’s native scrollback; see the [fullscreen page](fullscreen.md#search-and-review-the-conversation) for how to search and copy. If flicker is the only problem and your terminal supports synchronized output but isn’t auto-detected, such as Emacs `eat`, set [`CLAUDE_CODE_FORCE_SYNC_OUTPUT=1`](env-vars.md) to stop the flicker without changing renderers. Run `/tui fullscreen` to switch and save the preference. Your conversation relaunches intact and future sessions start in fullscreen unless a [fullscreen start fails](fullscreen.md#fullscreen-renderer-didnt-finish-starting). You can also set the `CLAUDE_CODE_NO_FLICKER` environment variable before starting Claude Code:

Bash and Zsh

PowerShell

~/.claude/settings.json

```python
CLAUDE_CODE_NO_FLICKER=1 claude
```

```python
$env:CLAUDE_CODE_NO_FLICKER = "1"; claude
```

```python
{
  "env": {
    "CLAUDE_CODE_NO_FLICKER": "1"
  }
}
```


[​](#cap-response-width-in-wide-terminals)

Cap response width in wide terminals

In a wide terminal, each line of prose in Claude’s responses runs the full width of the window. To wrap the prose at a set number of columns instead, set [`maxProseWidth`](settings-reference.md#maxprosewidth) in your settings.


[​](#paste-large-content)

Paste large content

When you paste more than 800 characters or more than three lines into the prompt, Claude Code collapses the input to a placeholder such as `[Pasted text #1 +120 lines]` so the input box stays usable, and still sends the full content when you submit. For very large inputs such as entire files or long logs, write the content to a file and ask Claude to read it instead of pasting. The conversation transcript stays readable and Claude can refer to the file by path in later turns. The VS Code integrated terminal can also drop characters from very large pastes before they reach Claude Code, so use a file there. If the paste carries [invisible Unicode characters](interactive-mode.md#invisible-characters-in-prompts), Claude Code removes them when you press Enter and puts the cleaned prompt back in the input box for you to send with another Enter.


[​](#how-claude-treats-pasted-text)

How Claude treats pasted text

When you submit, Claude sees the content behind each `[Pasted text #N]` placeholder marked as text you pasted from somewhere else rather than typed. Claude is told that a paste can contain instructions you didn’t write, and to follow instructions inside it only where the message you typed asks it to. In sessions that don’t [fetch feature flags](env-vars.md#features-that-need-feature-flag-fetching), pastes aren’t marked.


[​](#delete-and-restore-a-collapsed-paste)

Delete and restore a collapsed paste

When you delete with a word or line shortcut such as `Ctrl+W` or `Ctrl+K`, or with a vim delete through an `f`/`t` motion such as `df]`, and the deleted range reaches inside a `[Pasted text #N]` placeholder, Claude Code removes the placeholder whole. To restore it, paste the deletion back with [`Ctrl+Y`](interactive-mode.md#text-editing) after a word or line shortcut, or with [`p` in NORMAL mode](interactive-mode.md#editing-normal-mode) after a vim delete.


[​](#recall-a-prompt-that-had-pasted-text)

Recall a prompt that had pasted text

Claude Code keeps the content behind each `[Pasted text #N]` placeholder under `~/.claude/paste-cache/`, so when you recall a prompt from [command history](interactive-mode.md#command-history) and resubmit it, the full pasted content is sent again, including in a later session. Cache files older than [`cleanupPeriodDays`](settings-reference.md#cleanupperioddays) are deleted under the [retention sweep rules](claude-directory.md#cleaned-up-automatically), so a recalled prompt can reference pasted text that no longer exists. When you submit such a prompt, Claude Code never sends the literal `[Pasted text #N]` string, and shows a notification naming the missing paste:

- In a plain prompt with text remaining, Claude Code removes the placeholder and sends the remaining text.
- In a [shell mode](interactive-mode.md#shell-mode-with-prefix) command or a `/` command, where the removal would change what runs, and in any prompt the removal leaves empty, Claude Code cancels the submission and keeps the original text in the input, with the placeholder still in it. Delete the placeholder or edit the command, then resubmit.


[​](#edit-prompts-with-vim-keybindings)

Edit prompts with Vim keybindings

Claude Code includes a Vim-style editing mode for the prompt input. Enable it through `/config` → Editor mode, or by setting [`editorMode`](settings-reference.md#editormode) to `"vim"` in `~/.claude/settings.json`. Set Editor mode back to `normal` to turn it off. Vim mode supports a subset of NORMAL- and VISUAL-mode motions and operators, such as `hjkl` navigation, `v`/`V` selection, and `d`/`c`/`y` with text objects. See the [Vim editor mode reference](interactive-mode.md#vim-editor-mode) for the full key table. Vim motions aren’t remappable through the keybindings file. To map a two-key INSERT-mode sequence such as `jj` to Escape, set [`vimInsertModeRemaps`](interactive-mode.md#remap-insert-mode-key-sequences) in your user settings. Pressing Enter still submits your prompt in INSERT mode, unlike standard Vim. Use `o` or `O` in NORMAL mode, or Ctrl+J, to insert a newline instead.


[​](#related-resources)

Related resources

- [Interactive mode](interactive-mode.md): full keyboard shortcut reference and the Vim key table
- [Keybindings](keybindings.md): remap any Claude Code shortcut, including Enter and Shift+Enter
- [Fullscreen rendering](fullscreen.md): details on scrolling, search, and copy in fullscreen mode
- [Hooks guide](../07-Hooks/hooks-guide.md): more Notification hook examples for Linux and Windows
- [Troubleshooting](troubleshooting.md): fixes for issues outside terminal configuration

---

## Terminal guide for new users - Claude Code Docs

Source: https://code.claude.com/docs/en/terminal-guide
Path: 02-Claude-Code-CLI/terminal-guide.md

## On this page

- [Install Claude Code on macOS or Linux](#install-claude-code-on-macos-or-linux)
- [Install Claude Code on Windows](#install-claude-code-on-windows)
- [What’s next?](#what%E2%80%99s-next)
  - [Build something](#build-something)
  - [Work with files on your computer](#work-with-files-on-your-computer)
  - [Ask questions](#ask-questions)
  - [Other ways to use Claude Code](#other-ways-to-use-claude-code)
  - [Learn more](#learn-more)
- [Troubleshooting](#troubleshooting)
  - [macOS and Linux troubleshooting](#macos-and-linux-troubleshooting)
  - [Windows troubleshooting](#windows-troubleshooting)

# Terminal guide for new users

Copy pageCopy page

A step-by-step guide to installing Claude Code for first-time terminal users on macOS, Linux, and Windows.

Copy pageCopy page

You can use Claude Code even if you’ve never used a terminal before. This guide walks you through opening a terminal, installing Claude Code, and your first interactions.

- [macOS and Linux](#macos-and-linux)
- [Windows](#windows)

Don’t want to use the terminal? The Claude Code desktop app lets you skip the terminal entirely. Download it for [macOS](https://claude.ai/api/desktop/darwin/universal/dmg/latest/redirect?utm_source=claude_code&utm_medium=docs) or [Windows](https://claude.com/download?utm_source=claude_code&utm_medium=docs), then see the [Desktop quickstart](../16-Mobile-Desktop/desktop-quickstart.md) to get started. On Linux, install the app with apt by following the [Linux install instructions](../16-Mobile-Desktop/desktop-linux.md).


[​](#install-claude-code-on-macos-or-linux)

Install Claude Code on macOS or Linux

Follow these steps to install and start Claude Code from a macOS or Linux terminal. Claude Code requires macOS 13.0 or later. See the [system requirements](../01-Getting-Started/setup.md#system-requirements) for supported Linux distributions.

1

Open a terminal

**macOS**: Press `Cmd + Space` to open Spotlight Search, type `Terminal`, and press `Enter`.**Linux**: Open your terminal app. On most distributions, press `Ctrl + Alt + T` or search for “Terminal” in your application menu.A window will appear with a blinking cursor. This is your terminal, where you type commands.

2

Install Claude Code

Copy this line, paste it into your terminal (`Cmd + V` on macOS, `Ctrl + Shift + V` on Linux), and press `Enter`:

```python
curl -fsSL https://claude.ai/install.sh | bash
```

This downloads and runs the Claude Code installer from claude.ai. The command shows no progress while Claude Code downloads, so leave the window open and wait. When the installer finishes, you’ll see “Claude Code successfully installed!” If you see an error instead, check the [troubleshooting section](#macos-and-linux-troubleshooting) below.

3

Start Claude Code

Type `claude` and press `Enter`:

```python
claude
```

If you see `command not found: claude`, the install directory isn’t on your PATH yet. Follow the [‘command not found: claude’](#macos-and-linux-troubleshooting) fix below, then open a new terminal window and try again.You’ll be prompted to [log in](authentication.md) with your Claude account. Follow the on-screen instructions. A browser window will open for you to sign in.

4

Start using Claude Code

Once logged in, you can start asking Claude questions about your code or anything else. Claude Code runs entirely in text. You type messages and press `Enter` to send them. A few things to know:

- You can’t click on things in the terminal. Use the arrow keys to move around.
- Press `Esc` to interrupt Claude if it’s running.
- Type `exit` or press `Ctrl + D` twice on an empty prompt to leave Claude Code.
- Type `/help` to see available commands.

------------------------------------------------------------------------


[​](#install-claude-code-on-windows)

Install Claude Code on Windows

Follow these steps to optionally install Git for Windows, set up PowerShell, and start Claude Code on Windows. Claude Code requires Windows 10 version 1809 or later. See the [system requirements](../01-Getting-Started/setup.md#system-requirements) for full details.

1

Install Git for Windows (optional)

Git for Windows provides Git Bash, which enables the Bash tool. Without it, Claude Code uses PowerShell instead. You won’t need to learn Git yourself.If you don’t already have it:

1.  Go to [git-scm.com/downloads/win](https://git-scm.com/downloads/win) and download the installer
2.  Run the installer. Click Next on each screen to accept the defaults. The installer has many screens, but you don’t need to change anything.
3.  If it asks you to choose an editor, keep the default and click Next.
4.  When you see “Adjusting your PATH environment,” keep the recommended option selected.

Already have Git? You can skip this step. If you’re not sure, install it anyway. Reinstalling won’t cause problems.

2

Open PowerShell

PowerShell is Windows’ built-in terminal for typing commands. It comes pre-installed on every Windows computer.Press `Win + X` and select **Windows PowerShell** (or **Terminal**) from the menu. A window with a blinking cursor will appear. This is where you’ll type commands.

Windows has two command-line programs: PowerShell and CMD. They look similar but use different commands. Make sure you’re in PowerShell for the next step.How to tell which one you’re in:

- **PowerShell**: shows `PS C:\Users\YourName>` at the start of each line
- **CMD**: shows `C:\Users\YourName>` without the `PS`

3

Install Claude Code

Copy this line, paste it into PowerShell with `Ctrl + V` or right-click, and press `Enter`:

```python
irm https://claude.ai/install.ps1 | iex
```

This downloads and runs the Claude Code installer. `irm` fetches the file and `iex` runs it. The command shows no progress while Claude Code downloads, so leave the window open and wait. When the installer finishes, you’ll see “Claude Code successfully installed!” If you see an error instead, check the [troubleshooting section](#windows-troubleshooting) below.

If you’re in CMD instead of PowerShell, use this command:

```python
curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd
```

4

Start Claude Code

Run `claude`. If PowerShell says `'claude' is not recognized`, the install directory isn’t on your PATH yet. Follow the [‘claude is not recognized’](#windows-troubleshooting) fix below, then open a new PowerShell window and try again.

```python
claude
```

You’ll be prompted to [log in](authentication.md) with your Claude account. Follow the on-screen instructions. A browser window will open for you to sign in.

5

Start using Claude Code

Once logged in, you can start asking Claude questions about your code or anything else. Claude Code runs entirely in text. You type messages and press `Enter` to send them. A few things to know:

- You can’t click on things in the terminal. Use the arrow keys to move around.
- Press `Esc` to interrupt Claude if it’s running.
- Type `exit` or press `Ctrl + D` twice on an empty prompt to leave Claude Code.
- Type `/help` to see available commands.

------------------------------------------------------------------------


[​](#what’s-next)

What’s next?

Once you see the Claude Code welcome screen, you’re ready to go. You don’t need to know how to code. Describe what you want in plain English, and Claude writes the code for you.


[​](#build-something)

Build something

Claude can create projects from a description:

```python
make me a simple webpage that says hello world
```

If Claude asks for your permission before creating or changing files, press `Enter` to choose **Yes** and approve. Once Claude creates the files, double-click the HTML file to open it in your browser.


[​](#work-with-files-on-your-computer)

Work with files on your computer

Claude can read and organize files you already have:

```python
look at the screenshots on my Desktop and rename them based on what's in each image
```


[​](#ask-questions)

Ask questions

Claude can explain things, help you learn, or plan out a project:

```python
I want to build a personal budget tracker. What would I need?
```

If you don’t have a project yet, that’s fine. Claude can help you start a new one.


[​](#other-ways-to-use-claude-code)

Other ways to use Claude Code

You don’t have to use the terminal. Claude Code is also available in:

- [VS Code](../03-IDE-Integrations/vs-code.md) and [JetBrains IDEs](../03-IDE-Integrations/jetbrains.md) as editor extensions
- The [desktop app](../16-Mobile-Desktop/desktop-quickstart.md), with no terminal required
- The [web](claude-code-on-the-web.md) at claude.ai/code for cloud sessions
- [GitHub Actions](github-actions.md) and [GitLab CI/CD](gitlab-ci-cd.md) for automation


[​](#learn-more)

Learn more

- [Quickstart](../01-Getting-Started/quickstart.md): a guided walkthrough of your first project with Claude Code
- [How Claude Code works](how-claude-code-works.md): understand how Claude reads your files, runs commands, and makes edits
- [Best practices](best-practices.md): get better results with effective prompting and project setup
- [Common workflows](common-workflows.md): step-by-step guides for debugging, testing, refactoring, and more
- [Terminal configuration](terminal-config.md): customize your terminal for the best Claude Code experience

------------------------------------------------------------------------


[​](#troubleshooting)

Troubleshooting


[​](#macos-and-linux-troubleshooting)

macOS and Linux troubleshooting

If you run into problems installing on macOS or Linux, check these common issues:

'command not found: claude'

If you see `command not found: claude` after installing, the folder where the installer put `claude` isn’t in your PATH. The installer prints the exact fix under `Setup notes` at the end of the install, so run that command, or use the one for your shell below.For Zsh, the macOS default shell:

```python
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
```

For Bash on Linux:

```python
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
```

For Bash on macOS, follow the macOS Bash step in [fix your PATH](troubleshoot-install.md#verify-your-path) instead.Then open a new terminal and try `claude` again. If it still isn’t found, check that the file `~/.local/bin/claude` exists. If it doesn’t, the install didn’t finish. For more details, see [fix your PATH](troubleshoot-install.md#verify-your-path).

Error with HTML code or 'syntax error near unexpected token'

If you see `bash: line 1: syntax error near unexpected token '<'` or HTML code like `<!DOCTYPE html>` in your terminal, the install URL returned a web page instead of the installer script.If the page says “App unavailable in region,” Claude Code is not available in your country. See [supported countries](https://www.anthropic.com/supported-countries).Otherwise, try running the command again. If it keeps happening, install with [Homebrew](https://brew.sh) instead:

```python
brew install --cask claude-code
```

When it finishes, open a new terminal window, type `claude --version`, and press Enter: the command prints a version number such as `2.1.211 (Claude Code)` when the install worked.

'dyld' error or 'built for Mac OS X 13.0'

If you see `dyld: cannot load`, `dyld: Symbol not found`, or `built for Mac OS X 13.0`, your macOS version is likely older than Claude Code supports.Open the Apple menu and select About This Mac to check your version. If it’s older than 13.0, update macOS through Software Update. See the [macOS troubleshooting guide](troubleshoot-install.md#dyld-cannot-load-on-macos) for more details.

For other errors, see the full [installation troubleshooting guide](troubleshoot-install.md).


[​](#windows-troubleshooting)

Windows troubleshooting

If you run into problems installing on Windows, check these common issues:

'irm is not recognized'

You’re in CMD, not PowerShell. Close this window and open PowerShell instead (`Win + X` then select Windows PowerShell).Alternatively, use the CMD install command:

```python
curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd
```

SSL/TLS error or 'Could not create SSL/TLS secure channel'

This usually happens on older Windows 10 systems. Run this line first, then retry the install:

```python
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
irm https://claude.ai/install.ps1 | iex
```

'Claude Code on Windows requires either Git for Windows (for bash) or PowerShell'

Neither PowerShell nor Git Bash was found. Claude Code needs at least one shell.

1.  Ensure `powershell.exe` is on your `PATH`. Its default location is `C:\Windows\System32\WindowsPowerShell\v1.0\`. Alternatively, install [PowerShell 7](https://aka.ms/powershell), which provides `pwsh`.
2.  If you’d rather use Git Bash, install [Git for Windows](https://git-scm.com/downloads/win) per the [first step in the Windows section](#windows).
3.  If Git is installed but Claude Code can’t find it, tell it where to look:

    ``` shiki
    $env:CLAUDE_CODE_GIT_BASH_PATH="C:\Program Files\Git\bin\bash.exe"
    ```

    Then run `claude` again. If your Git is installed somewhere else, find the path by running:

    ``` shiki
    Get-Command git | Select-Object Source
    ```

    Look for the `Git\bin` folder in that path and use it instead.

To make this permanent so you don’t have to set it every time, see [configure Git Bash path](troubleshoot-install.md#claude-code-on-windows-requires-either-git-for-windows-for-bash-or-powershell).

'claude is not recognized'

If the error started right after Claude Code updated, see [restore `claude.exe` from its backup](troubleshoot-install.md#claude-exe-missing-after-an-update-on-windows) first.If the install directory isn’t in your PATH, add it by running these commands in PowerShell:

```python
$currentPath = [Environment]::GetEnvironmentVariable('PATH', 'User')
[Environment]::SetEnvironmentVariable('PATH', "$currentPath;$env:USERPROFILE\.local\bin", 'User')
```

Close PowerShell, open a new window, and try `claude` again. You should see the Claude Code welcome screen. See [verify your PATH](troubleshoot-install.md#verify-your-path) for more details.

'Claude Code does not support 32-bit Windows'

On a 64-bit machine, this error means you opened `Windows PowerShell (x86)` instead of `Windows PowerShell`. The x86 entry runs as a 32-bit process. Close it, open the Start menu entry without `(x86)` in its name, and run the install command again. If you’re not sure your machine is 64-bit, or the error persists, see [the full explanation](troubleshoot-install.md#claude-code-does-not-support-32-bit-windows).

For other errors, see the full [installation troubleshooting guide](troubleshoot-install.md).

---

## Enterprise deployment overview - Claude Code Docs

Source: https://code.claude.com/docs/en/third-party-integrations
Path: 02-Claude-Code-CLI/third-party-integrations.md

## On this page

- [Compare deployment options](#compare-deployment-options)
- [Configure proxies and gateways](#configure-proxies-and-gateways)
- [Best practices for organizations](#best-practices-for-organizations)
  - [Invest in documentation and memory](#invest-in-documentation-and-memory)
  - [Simplify deployment](#simplify-deployment)
  - [Start with guided usage](#start-with-guided-usage)
  - [Pin model versions for cloud providers](#pin-model-versions-for-cloud-providers)
  - [Configure security policies](#configure-security-policies)
  - [Use MCP for integrations](#leverage-mcp-for-integrations)
- [Next steps](#next-steps)

Deployment

# Enterprise deployment overview

Copy pageCopy page

Learn how Claude Code can integrate with various third-party services and infrastructure to meet enterprise deployment requirements.

Copy pageCopy page

Organizations can deploy Claude Code through Anthropic directly or through a cloud provider. This page helps you choose the right configuration.


[​](#compare-deployment-options)

Compare deployment options

For most organizations, Claude for Teams or Claude for Enterprise provides the best experience. Team members get access to both Claude Code and Claude on the web with a single subscription, centralized billing, and no infrastructure setup required. **Claude for Teams** is self-service and includes collaboration features, admin tools, SSO, billing management, and [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) for organization-wide Claude Code configuration. Best for smaller teams that need to get started quickly. **Claude for Enterprise** adds domain capture, role-based permissions, and compliance API access. Best for larger organizations with security and compliance requirements. Learn more about [Team plans](../17-Billing-Plans/what-is-the-team-plan.md) and [Enterprise plans](../17-Billing-Plans/what-is-the-enterprise-plan.md). The deployment options compared below cover where model inference runs. To run Claude Code [cloud sessions](claude-code-on-the-web.md) on compute your organization operates, see [self-hosted environments](../13-Enterprise-Admin/self-hosted-environments.md). If your organization has specific infrastructure requirements, compare the options below:

[TABLE]

For a feature-by-feature breakdown of what’s available on each option, see [Feature availability](feature-availability.md). Select a deployment option to view setup instructions:

- [Claude for Teams or Enterprise](authentication.md#claude-for-teams-or-enterprise)
- [Anthropic Console](authentication.md#claude-console-authentication)
- [Claude apps gateway](../13-Enterprise-Admin/claude-apps-gateway.md), a self-hosted gateway that adds IdP sign-in in front of Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, Microsoft Foundry, or the Anthropic API
- [Amazon Bedrock](amazon-bedrock.md)
- [Claude Platform on AWS](claude-platform-on-aws.md)
- [Google Cloud’s Agent Platform](google-vertex-ai.md)
- [Microsoft Foundry](microsoft-foundry.md)

For Amazon Bedrock and Google Vertex AI, you can also run `claude` and select **3rd-party platform** at the login prompt to launch an interactive setup wizard.


[​](#configure-proxies-and-gateways)

Configure proxies and gateways

Most organizations can use a cloud provider directly without additional configuration. However, you may need to configure a corporate proxy or LLM gateway if your organization has specific network or management requirements. These are different configurations that can be used together:

- **Corporate proxy**: Routes traffic through an HTTP/HTTPS proxy. Use this if your organization requires all outbound traffic to pass through a proxy server for security monitoring, compliance, or network policy enforcement. Configure with the `HTTPS_PROXY` or `HTTP_PROXY` environment variables. Learn more in [Enterprise network configuration](../13-Enterprise-Admin/network-config.md).
- **LLM Gateway**: A service that sits between Claude Code and the cloud provider to handle authentication and routing. Use this if you need centralized usage tracking across teams, custom rate limiting or budgets, or centralized authentication management. Configure with the `ANTHROPIC_BASE_URL`, `ANTHROPIC_BEDROCK_BASE_URL`, `ANTHROPIC_AWS_BASE_URL`, `ANTHROPIC_VERTEX_BASE_URL`, or `ANTHROPIC_FOUNDRY_BASE_URL` environment variables. Learn more in [LLM gateways](../13-Enterprise-Admin/llm-gateway.md).

For the per-provider environment variables that route Amazon Bedrock, Microsoft Foundry, or Google Cloud’s Agent Platform through an LLM gateway, see [route to a cloud provider through a gateway](../13-Enterprise-Admin/llm-gateway-connect.md#route-to-a-cloud-provider-through-a-gateway). Run `/status` in Claude Code to verify which provider, base URL, and proxy a session is using. If your organization uses [customer-managed encryption keys](../04-API-Reference/Other/manage-claude-cmek.md) (CMEK) and routes Claude Code through an LLM gateway or a custom `ANTHROPIC_BASE_URL`, CMEK doesn’t apply to Claude Code’s operational telemetry on those sessions. To turn telemetry off for every developer, deliver `DISABLE_TELEMETRY` through managed settings as shown in [Turn telemetry off for your organization](../13-Enterprise-Admin/managed-settings.md#turn-telemetry-off-for-your-organization).


[​](#best-practices-for-organizations)

Best practices for organizations


[​](#invest-in-documentation-and-memory)

Invest in documentation and memory

Invest in documentation so that Claude Code understands your codebase. Organizations can deploy CLAUDE.md files at multiple levels. See [where CLAUDE.md files can live](memory.md#choose-where-to-put-claude-md-files) and [how to deploy an organization-wide CLAUDE.md](memory.md#deploy-organization-wide-claude-md).


[​](#simplify-deployment)

Simplify deployment

If you have a custom development environment, creating a “one click” way to install Claude Code is key to growing adoption across an organization.


[​](#start-with-guided-usage)

Start with guided usage

Encourage new users to try Claude Code for codebase Q&A, or on smaller bug fixes or feature requests. Ask Claude Code to make a plan. Check Claude’s suggestions and give feedback if it’s off-track. Over time, as users understand this new paradigm better, then they’ll be more effective at letting Claude Code run more agentically.


[​](#pin-model-versions-for-cloud-providers)

Pin model versions for cloud providers

If you deploy through [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), [Microsoft Foundry](microsoft-foundry.md), or [Claude Platform on AWS](claude-platform-on-aws.md), pin specific model versions using `ANTHROPIC_DEFAULT_FABLE_MODEL`, `ANTHROPIC_DEFAULT_OPUS_MODEL`, `ANTHROPIC_DEFAULT_SONNET_MODEL`, and `ANTHROPIC_DEFAULT_HAIKU_MODEL`. Without pinning, model aliases resolve to Claude Code’s built-in default for that provider, which can lag the newest release and may not yet be enabled in your account. Pinning lets you control when your users move to a new model. See [Model configuration](model-config.md#pin-models-for-third-party-deployments) for what each provider does when the default is unavailable.


[​](#configure-security-policies)

Configure security policies

Security teams can configure managed permissions for what Claude Code is and is not allowed to do, which cannot be overwritten by local configuration. [Learn more](../13-Enterprise-Admin/security.md). To limit which of these deployment options a managed machine may use, set [`allowedProviders`](settings-reference.md#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.


[​](#leverage-mcp-for-integrations)

Use MCP for integrations

MCP 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](../06-MCP-Tools/General/mcp.md).


[​](#next-steps)

Next steps

Once you’ve chosen a deployment option and configured access for your team:

1.  **Roll out to your team**: Share installation instructions and have team members [install Claude Code](../01-Getting-Started/setup.md) and authenticate with their credentials.
2.  **Set up shared configuration**: Create a [CLAUDE.md file](memory.md) in your repositories to help Claude Code understand your codebase and coding standards.
3.  **Configure permissions**: Review [security settings](../13-Enterprise-Admin/security.md) to define what Claude Code can and cannot do in your environment.

---

## Tools reference - Claude Code Docs

Source: https://code.claude.com/docs/en/tools-reference
Path: 02-Claude-Code-CLI/tools-reference.md

## On this page

- [Configure tools with permission rules and hooks](#configure-tools-with-permission-rules-and-hooks)
- [Agent tool behavior](#agent-tool-behavior)
- [AskUserQuestion tool behavior](#askuserquestion-tool-behavior)
  - [Question auto-continue timeout](#question-auto-continue-timeout)
- [Bash tool behavior](#bash-tool-behavior)
  - [What persists between commands](#what-persists-between-commands)
  - [Timeout and output limits](#timeout-and-output-limits)
  - [Output limits](#output-limits)
  - [Background commands](#background-commands)
  - [When a background command stops](#when-a-background-command-stops)
  - [Time limit for background commands](#time-limit-for-background-commands)
  - [Raise the time limit for background commands](#raise-the-time-limit-for-background-commands)
  - [Foreground commands that move to the background](#foreground-commands-that-move-to-the-background)
  - [Memory limit on Linux and WSL](#memory-limit-on-linux-and-wsl)
- [Edit tool behavior](#edit-tool-behavior)
  - [Non-UTF-8 files](#non-utf-8-files)
- [EndConversation tool behavior](#endconversation-tool-behavior)
- [Glob tool behavior](#glob-tool-behavior)
- [Grep tool behavior](#grep-tool-behavior)
- [LSP tool behavior](#lsp-tool-behavior)
- [Monitor tool](#monitor-tool)
  - [WebSocket source](#websocket-source)
- [NotebookEdit tool behavior](#notebookedit-tool-behavior)
- [PowerShell tool](#powershell-tool)
  - [Enable the PowerShell tool](#enable-the-powershell-tool)
  - [Bash deny rules also turn off the PowerShell tool](#bash-deny-rules-also-turn-off-the-powershell-tool)
  - [Shell selection in settings, hooks, and skills](#shell-selection-in-settings-hooks-and-skills)
  - [Exit code 1 from searches and git diff in PowerShell](#exit-code-1-from-searches-and-git-diff-in-powershell)
  - [Windows encoding and exit codes](#windows-encoding-and-exit-codes)
  - [Preview limitations](#preview-limitations)
- [Read tool behavior](#read-tool-behavior)
  - [Large files](#large-files)
- [SendFeedback tool behavior](#sendfeedback-tool-behavior)
  - [What you see when Claude drafts](#what-you-see-when-claude-drafts)
  - [Review and edit a draft](#review-and-edit-a-draft)
  - [Send a draft](#send-a-draft)
  - [Discard or keep a draft](#discard-or-keep-a-draft)
  - [Turn Claude-drafted feedback off](#turn-claude-drafted-feedback-off)
  - [Sessions without Claude-drafted feedback](#sessions-without-claude-drafted-feedback)
- [Task tool availability](#task-tool-availability)
  - [Task-tracking tools in subagents and agent teams](#task-tracking-tools-in-subagents-and-agent-teams)
- [WebFetch tool behavior](#webfetch-tool-behavior)
  - [WebFetch availability](#webfetch-availability)
- [WebSearch tool behavior](#websearch-tool-behavior)
  - [Session search limit](#session-search-limit)
- [Write tool behavior](#write-tool-behavior)
- [Check which tools are available](#check-which-tools-are-available)
- [See also](#see-also)

Reference

# Tools reference

Copy pageCopy page

Complete reference for the tools Claude Code can use, including permission requirements and per-tool behavior.

Copy pageCopy page

Claude Code has access to a set of built-in tools that help it understand and modify your codebase. The tool names are the exact strings you use in [permission rules](permissions.md#tool-specific-permission-rules), [subagent tool lists](../09-Agents-Patterns/sub-agents.md), and [hook matchers](../07-Hooks/hooks.md). To control which tools Claude can use and when it asks first, configure [permission rules](permissions.md#tool-specific-permission-rules) in your settings, [hooks](../07-Hooks/hooks.md), or a [subagent’s tool list](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields). See [Configure tools with permission rules and hooks](#configure-tools-with-permission-rules-and-hooks) for each place that accepts a tool name. To add custom tools, connect an [MCP server](../06-MCP-Tools/General/mcp.md). To extend Claude with reusable prompt-based workflows, write a [skill](../08-Plugins-Skills/skills.md), which runs through the existing `Skill` tool rather than adding a new tool entry.

In [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode), a classifier decides most permission prompts instead of you. The `Permission required` column shows whether the tool prompts in [Manual mode](permission-modes.md) for paths inside the working directory. File-access tools marked No, including `Read`, `Grep`, and `Glob`, still prompt for paths outside the [working directory and additional directories](permissions.md#working-directories). `Bash` is marked Yes but runs a built-in set of [read-only commands](permissions.md#read-only-commands) without prompting.

| Tool                   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Permission required |
|:-----------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------|
| `Agent`                | Spawns a [subagent](../09-Agents-Patterns/sub-agents.md) with its own context window to handle a task. With [agent teams](../09-Agents-Patterns/agent-teams.md) enabled, a call that carries a `name` can launch a [teammate](../09-Agents-Patterns/agent-teams.md#how-claude-starts-agent-teams) instead. See [Agent tool behavior](#agent-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | No                  |
| `Artifact`             | Publishes an HTML or Markdown file as an [artifact](artifacts.md): a private, interactive page on claude.ai. You can share it with a public link, or inside your organization on Team and Enterprise plans, where public sharing requires an Owner to [enable it](artifacts.md#control-public-sharing). Requires a Pro, Max, Team, or Enterprise plan and `/login` authentication; see [Availability](artifacts.md#availability)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Yes                 |
| `AskUserQuestion`      | Asks multiple-choice questions to gather requirements or clarify ambiguity. Questions stay open until you answer them by default. See [AskUserQuestion tool behavior](#askuserquestion-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | No                  |
| `Bash`                 | Executes shell commands in your environment. See [Bash tool behavior](#bash-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | Yes                 |
| `CronCreate`           | Schedules a recurring or one-shot prompt within the current session. Tasks are session-scoped and restored on `--resume` or `--continue` if unexpired. See [session-scoped scheduled tasks](scheduled-tasks.md)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | No                  |
| `CronDelete`           | Cancels a session-scoped scheduled task by ID                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | No                  |
| `CronList`             | Lists all session-scoped scheduled tasks                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | No                  |
| `Edit`                 | Makes targeted edits to specific files. See [Edit tool behavior](#edit-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | Yes                 |
| `EndConversation`      | Ends the session, in rare cases of sustained abusive input or when you ask Claude to demonstrate the tool. See [EndConversation tool behavior](#endconversation-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | No                  |
| `EnterPlanMode`        | Switches to plan mode to design an approach before coding                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | No                  |
| `EnterWorktree`        | Creates an isolated [git worktree](worktrees.md) and switches into it. Pass a `path` to switch into an existing worktree instead of creating a new one. On first entry the target may be a worktree of the current repository or, in a multi-repo workspace, of a repository nested inside it. Before v2.1.203, a nested repository’s worktree was rejected. A `path` outside `.claude/worktrees/` prompts for your approval before entering, since it moves the session’s working directory and write access to that location. New-worktree creation and paths under `.claude/worktrees/` don’t prompt. Before v2.1.206, Claude entered paths outside `.claude/worktrees/` without a prompt. From within a worktree session, or from a subagent with a pinned working directory such as [`isolation: worktree`](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields), only the `path` form is available and the target must be under `.claude/worktrees/` of the session’s repository                                             | Yes                 |
| `ExitPlanMode`         | Presents a plan for approval and exits plan mode                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Yes                 |
| `ExitWorktree`         | Exits a worktree session and returns to the original directory. Not available to subagents that already run in their own working directory, such as with [`isolation: worktree`](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | No                  |
| `Glob`                 | Finds files based on pattern matching. Absent by default on macOS, Linux, and WSL. See [Glob tool behavior](#glob-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | No                  |
| `Grep`                 | Searches for patterns in file contents. Absent by default on macOS, Linux, and WSL. See [Grep tool behavior](#grep-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | No                  |
| `ListAgents`           | Lists the agents Claude can message with `SendMessage`: subagents in the session, [agent team](../09-Agents-Patterns/agent-teams.md) teammates, your other local Claude Code sessions, and, while this session is connected to [Remote Control](remote-control.md), your [cloud sessions](claude-code-on-the-web.md) and your Remote Control sessions on other machines. Backs the `/list-agents` command. See [cross-session messaging](cross-session-messaging.md). Requires Claude Code v2.1.224 or later, and appears only in sessions where [cross-session messaging is enabled](cross-session-messaging.md#availability). Teammate rows and the first line showing this session’s own name require v2.1.239 or later                                                                                                                                                                                                                                                                                                    | No                  |
| `ListMcpResourcesTool` | Lists resources exposed by connected [MCP servers](../06-MCP-Tools/General/mcp.md), leaving out [MCP Apps UI resources](../06-MCP-Tools/General/mcp.md#reference-mcp-resources), which are pages for a host application to render                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | No                  |
| `LSP`                  | Code intelligence via language servers: jump to definitions, find references, report type errors and warnings. See [LSP tool behavior](#lsp-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | No                  |
| `Monitor`              | Runs a command in the background and feeds each output line back to Claude, so it can react to log entries, file changes, or polled status mid-conversation. Can also open a WebSocket and treat each incoming message as an event. See [Monitor tool](#monitor-tool)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | Yes                 |
| `NotebookEdit`         | Modifies Jupyter notebook cells. See [NotebookEdit tool behavior](#notebookedit-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Yes                 |
| `PowerShell`           | Executes PowerShell commands natively. See [PowerShell tool](#powershell-tool) for availability                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Yes                 |
| `PushNotification`     | Sends a desktop notification, and a phone push when [Remote Control](remote-control.md) is connected, so a long-running task or [session-scoped scheduled task](scheduled-tasks.md) can reach you when you step away. Push delivery runs through Anthropic-hosted infrastructure, which is not accessible from Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, or Microsoft Foundry                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | No                  |
| `Read`                 | Reads the contents of files. See [Read tool behavior](#read-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | No                  |
| `ReadMcpResourceTool`  | Reads a specific MCP resource by URI                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | No                  |
| `RemoteTrigger`        | Creates, updates, runs, and lists [cloud scheduled tasks](web-scheduled-tasks.md), formerly routines, on claude.ai. Backs the `/schedule` command. The [`RemoteTrigger` input reference](../05-Agent-SDK/agent-sdk-typescript.md#remotetrigger) documents every action and the organization policies that remove the tool. Cloud scheduled tasks live on claude.ai and require a Pro, Max, Team, or Enterprise plan. This tool is therefore not accessible from Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, or Microsoft Foundry                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | No                  |
| `ReportFindings`       | Reports code-review findings as a structured list, with a file, summary, and failure scenario per finding, so Claude Code can render them instead of printing them as text. Claude calls it when active code-review instructions tell it to. A finding can also carry an optional `category` slug, such as `correctness` or `test-coverage`, shown next to the file location in the rendered list                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | No                  |
| `ScheduleWakeup`       | Reschedules the next iteration of a [self-paced `/loop`](scheduled-tasks.md#let-claude-choose-the-interval). Claude calls this at the end of each iteration to pick when the next one runs, between one minute and one hour out; you don’t call it directly. To end the loop instead, Claude calls it with `stop: true`, which cancels the pending wakeup. The pending wakeup appears in `session_crons` in [Stop hook input](../07-Hooks/hooks.md#stop-input)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | No                  |
| `SendFeedback`         | Drafts a feedback report about Claude Code, covering a product problem or Claude’s own behavior in the session, and queues it on your machine for you to review. Claude Code sends nothing until you choose to send the draft. See [SendFeedback tool behavior](#sendfeedback-tool-behavior). Requires Claude Code v2.1.238 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | No                  |
| `SendMessage`          | Sends a message to another agent: an [agent team](../09-Agents-Patterns/agent-teams.md) teammate, a [subagent it resumes](../09-Agents-Patterns/sub-agents.md#resume-subagents) by agent ID or name, or one of your other Claude Code sessions, on this machine or beyond it. Messaging other sessions requires Claude Code v2.1.224 or later. [Cross-session messaging](cross-session-messaging.md) covers which sessions Claude can reach, [what a message looks like when it arrives](cross-session-messaging.md#what-a-message-looks-like), and [how Claude gets a notice when another session goes idle](cross-session-messaging.md#get-a-notice-when-another-session-goes-idle). Claude can include an optional `summary` input, typically 5-10 words, that Claude Code shows as a one-line preview. When Claude omits it on a [plain-text message](cross-session-messaging.md#limitations), Claude Code uses the first line of the message as the summary. Claude Code truncates a summary longer than 200 characters with an ellipsis | No                  |
| `SendUserFile`         | Sends files from the session to you with an optional caption, so a generated report, diagram, screenshot, or built artifact reaches your device instead of only being mentioned in the transcript. The optional `display` input controls presentation: `render` opens the file inline in the client, `attach` shows a download card only, and when unset the client decides by file type. Available when a [Remote Control](remote-control.md) client is connected or in a [cloud session](claude-code-on-the-web.md). Delivery runs through Anthropic-hosted infrastructure, so the tool is not available on Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry                                                                                                                                                                                                                                                                                                                                         | No                  |
| `ShareOnboardingGuide` | Uploads `ONBOARDING.md` and returns a share link teammates can open in Claude Code. Called from `/team-onboarding` after the guide is written. Available to claude.ai subscribers on Team and Enterprise plans                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Yes                 |
| `Skill`                | Executes a [skill](../08-Plugins-Skills/skills.md#control-who-invokes-a-skill) within the main conversation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Yes                 |
| `SubagentHandback`     | Delivers a subagent’s final report to whichever conversation receives that subagent’s result. Provided only in [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode), to subagents that the Agent tool runs locally other than [forks](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation), and available in the terminal CLI, IDE extensions, cloud sessions, and the Agent SDK; the classifier reviews the report before it’s delivered. Requires Claude Code v2.1.271 or later                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | No                  |
| `TaskCreate`           | Creates a new task in the task list. Provided by default only on the models listed under [Task tool availability](#task-tool-availability), and on other models when you opt in                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | No                  |
| `TaskGet`              | Retrieves full details for a specific task. Provided by default only on the models listed under [Task tool availability](#task-tool-availability), and on other models when you opt in                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | No                  |
| `TaskList`             | Lists all tasks with their current status. Provided by default only on the models listed under [Task tool availability](#task-tool-availability), and on other models when you opt in                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | No                  |
| `TaskOutput`           | Removed in v2.1.277. Previously retrieved output from a background task; Claude reads a background task’s [output file](interactive-mode.md#how-backgrounding-works) with `Read` instead                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | No                  |
| `TaskStop`             | Stops a running background task by ID. It also accepts an [agent-team teammate](../09-Agents-Patterns/agent-teams.md) or a named background agent by agent ID or name. When no task matches the ID, the error lists the running background agents by ID and description, including agents that another agent spawned                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | No                  |
| `TaskUpdate`           | Updates task status, dependencies, details, or deletes tasks. Provided by default only on the models listed under [Task tool availability](#task-tool-availability), and on other models when you opt in                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | No                  |
| `TodoWrite`            | Manages the session task checklist. Disabled by default in favor of `TaskCreate`, `TaskGet`, `TaskList`, and `TaskUpdate`. Set `CLAUDE_CODE_ENABLE_TASKS=0` to re-enable it in [sessions that have the task-tracking tools](#task-tool-availability)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | No                  |
| `ToolSearch`           | Searches for and loads deferred tools when [tool search](../06-MCP-Tools/General/mcp.md#scale-with-mcp-tool-search) is enabled                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | No                  |
| `WaitForMcpServers`    | Waits for one or more [MCP servers](../06-MCP-Tools/General/mcp.md) that are still connecting in the background, so a request can use their tools without restarting the session. Claude calls it when a needed server isn’t connected yet. Only appears when [tool search](../06-MCP-Tools/General/mcp.md#scale-with-mcp-tool-search) is disabled, since `ToolSearch` handles the wait when it’s enabled                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | No                  |
| `WebFetch`             | Fetches content from a specified URL. See [WebFetch tool behavior](#webfetch-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes                 |
| `WebSearch`            | Performs web searches. See [WebSearch tool behavior](#websearch-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Yes                 |
| `Workflow`             | Runs a [dynamic workflow](workflows.md): a script that orchestrates many subagents in the background and returns one consolidated result                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Yes                 |
| `Write`                | Creates or overwrites files. See [Write tool behavior](#write-tool-behavior)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Yes                 |


[​](#configure-tools-with-permission-rules-and-hooks)

Configure tools with permission rules and hooks

For the most part, Claude decides when to use these tools and you don’t need to name them yourself when interacting with Claude. You reference tool names directly when defining permissions and other configuration:

- in [`permissions.allow`](settings-reference.md#permissions-allow) and [`permissions.deny`](settings-reference.md#permissions-deny) in settings, and the `/permissions` interface
- in the `--allowedTools` and `--disallowedTools` [CLI flags](cli-reference.md)
- in the Agent SDK’s [`allowedTools` and `disallowedTools`](../05-Agent-SDK/agent-sdk-permissions.md#allow-and-deny-rules) options
- in a [skill’s `allowed-tools`](../08-Plugins-Skills/skills.md#frontmatter-reference) frontmatter
- in a hook’s [`if` condition](../07-Hooks/hooks-guide.md#filter-by-tool-name-and-arguments-with-the-if-field)

All of these accept the same rule format, `ToolName(specifier)`. The specifier depends on the tool, and several tools share a format:

| Rule format                    | Applies to                | Details                                                                       |
|:-------------------------------|:--------------------------|:------------------------------------------------------------------------------|
| `Bash(npm run *)`              | Bash, Monitor             | [Command pattern matching](permissions.md#bash)                         |
| `PowerShell(Get-ChildItem *)`  | PowerShell                | [Command pattern matching](permissions.md#powershell)                   |
| `Read(~/secrets/**)`           | Read, Grep, Glob, LSP     | [Path pattern matching](permissions.md#read-and-edit)                   |
| `Edit(/src/**)`                | Edit, Write, NotebookEdit | [Path pattern matching](permissions.md#read-and-edit)                   |
| `Skill(deploy *)`              | Skill                     | [Skill name matching](../08-Plugins-Skills/skills.md#restrict-claude%E2%80%99s-skill-access) |
| `Agent(Explore)`               | Agent                     | [Subagent type matching](permissions.md#agent-subagents)                |
| `WebFetch(domain:example.com)` | WebFetch                  | [Domain matching](permissions.md#webfetch)                              |
| `WebSearch`                    | WebSearch                 | No specifier; allow or deny the tool as a whole                               |

Tools not listed here, such as `ExitPlanMode` or `ShareOnboardingGuide`, accept only the bare tool name with no specifier. An `Edit(...)` allow rule also grants read access to the same path, so you don’t need a matching `Read(...)` rule. A `Read(...)` deny rule also blocks the Edit and Write tools on the same path, including creating a new file there, because both tools change content Claude has to be able to read back. For the Write tool, the `Read` deny check requires Claude Code v2.1.228 or later. Hook `matcher` fields use bare tool names, not the parenthesized rule format. See [matcher patterns](../07-Hooks/hooks.md#matcher-patterns) for the matching rules. For the field names each tool passes to `tool_input` in hooks, see the [PreToolUse input reference](../07-Hooks/hooks.md#pretooluse-input).


[​](#agent-tool-behavior)

Agent tool behavior

The Agent tool spawns a subagent in a separate context window. The subagent works through its task autonomously, then returns its result to the parent conversation. The parent doesn’t see the subagent’s intermediate tool calls or outputs, only that final result. The same tool can also launch a teammate or a fork:

- **Teammate**: with [agent teams](../09-Agents-Patterns/agent-teams.md) enabled, a call that carries a `name` can launch a [teammate](../09-Agents-Patterns/agent-teams.md#how-claude-starts-agent-teams) instead, which reports back through team messages rather than by returning a result
- **Fork**: wherever [fork mode](../09-Agents-Patterns/sub-agents.md#turn-fork-mode-on-or-off) is on, the tool can launch a [forked subagent](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation), which inherits the full parent conversation instead of starting fresh

To cap how many turns a subagent runs, set `maxTurns` in the [subagent definition](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields). When the subagent reaches the limit, Claude Code marks the returned result as partial output, and Claude can [resume the subagent](../09-Agents-Patterns/sub-agents.md#resume-subagents) to continue. Which tools a non-fork subagent can use depends on the `tools` and `disallowedTools` fields in the [subagent definition](../09-Agents-Patterns/sub-agents.md):

- **Neither field set**: the subagent inherits every [tool available to subagents](../09-Agents-Patterns/sub-agents.md#available-tools).
- **`tools` only**: the subagent gets only the listed tools.
- **`disallowedTools` only**: the subagent gets every parent tool except the listed ones.
- **Both set**: `disallowedTools` takes precedence. A tool listed in both is removed.

In every case, the resolved set is limited to the [tools available to subagents](../09-Agents-Patterns/sub-agents.md#available-tools): a tool that isn’t available to subagents is never granted, even when listed in `tools`. Where the conditions in the `SubagentHandback` tools-table entry hold, Claude Code also gives the subagent that tool, even if you leave it out of `tools` or list it in `disallowedTools`. If every entry in a subagent’s `tools` list fails to match a usable tool, the Agent tool usually returns an error naming the entries instead of launching the subagent; see [Agent would be spawned with zero tools](errors.md#agent-would-be-spawned-with-zero-tools) for the message and how to fix each entry. Launching the subagent doesn’t itself prompt for permission. Claude Code checks the subagent’s own tool calls against your permission rules as it runs. Where you see a subagent’s permission prompts depends on whether it runs in the foreground or the background. Claude Code runs subagents in the background by default, apart from the [cases that run in the foreground](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background).

- **Foreground subagents** show the same permission prompts you would see in the main conversation, at the moment each tool call happens.
- **Background subagents** surface permission prompts in your main session. The prompt names which subagent is asking, and pressing Esc denies that one tool call without stopping the subagent.

To [limit what a subagent can reach](../09-Agents-Patterns/sub-agents.md#control-subagent-capabilities) in the first place, narrow its `tools` field, for example by leaving Bash off the list, or set deny rules in your settings.


[​](#askuserquestion-tool-behavior)

AskUserQuestion tool behavior

Claude 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. When 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.


[​](#question-auto-continue-timeout)

Question auto-continue timeout

Questions 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`](settings-reference.md#askuserquestiontimeout) setting to `60s`, `5m`, or `10m`, either in your user `settings.json` or from the **Question auto-continue timeout** row in `/config`. After a question sits that long with no input, the dialog closes on its own: it submits any options you’d already selected and tells Claude you may be away from your keyboard, so Claude proceeds on its own judgment and can re-ask later. You see a countdown for the last 20 seconds. Press any key to restart the timer. While your terminal reports that its window is focused, the timer doesn’t count down. The timer never starts for a question Claude asks in a [background session](../09-Agents-Patterns/agent-view.md), in [screen reader mode](accessibility.md), or while the session is connected to [Remote Control](remote-control.md). Those questions wait until you answer them. The timeout applies only to `AskUserQuestion`’s multiple-choice questions; permission prompts, including plan approval, never auto-resolve on idle.


[​](#bash-tool-behavior)

Bash tool behavior

The Bash tool runs each command in a separate process.


[​](#what-persists-between-commands)

What persists between commands

- When Claude runs `cd` in the main session, the new working directory carries over to later Bash commands as long as it stays inside the project directory or an [additional working directory](permissions.md#working-directories) you added with `--add-dir`, `/add-dir`, or `additionalDirectories` in settings. This includes commands Claude runs in response to your later messages.
  - Subagent sessions never carry over working directory changes.
  - If `cd` lands outside those directories, Claude Code resets to the project directory and appends `Shell cwd was reset to <dir>` to the tool result.
  - To disable this carry-over so every Bash command starts in the project directory, set `CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=1`.
- Environment variables don’t persist. An `export` in one command won’t be available in the next.
- Aliases and shell functions defined in your shell startup file are available. At session start, Claude Code sources `~/.zshrc`, `~/.bashrc`, or `~/.profile` depending on your shell, captures the resulting aliases, functions, and shell options, and applies them to every Bash command.

Activate your virtualenv or conda environment before launching Claude Code. To make environment variables persist across Bash commands, set [`CLAUDE_ENV_FILE`](env-vars.md) to a shell script before launching Claude Code, or use a [SessionStart hook](../07-Hooks/hooks.md#persist-environment-variables) to populate it dynamically.


[​](#timeout-and-output-limits)

Timeout and output limits

Each command runs under a timeout, and Claude manages it: when it wants longer than the default for a command, it passes the `timeout` parameter with that call. You never set a per-command timeout. Two [environment variables](env-vars.md) control what Claude gets for a command that runs in the foreground:

- `BASH_DEFAULT_TIMEOUT_MS` — the default when Claude passes no timeout; two minutes out of the box
- `BASH_MAX_TIMEOUT_MS` — with the default, sets the ceiling that caps whatever Claude requests: the effective ceiling is the larger of the two, ten minutes out of the box

In a session that has a [time limit for background commands](#time-limit-for-background-commands), `timeout` on a command that Claude starts in the background instead sets how long the command may run there, with that limit’s separate default and maximum. The [PowerShell tool](#powershell-tool) follows the same timeout rules and reads the same two variables.


[​](#output-limits)

Output limits

Claude Code streams a command’s output to a working file as the command runs; a command whose output passes 5 GB is killed. When the command finishes, Claude Code reads the output back from that file, up to the read-back window described below. How much of the output reaches Claude inline depends on whether Claude Code treats the result as a failure:

| Result  | What Claude gets                                                                                                                                                                                                                                            |
|:--------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Valid   | Inline up to roughly 30,000 characters by default; past that, the path of a file saved to the session directory and truncated past 64 MiB, plus a preview of up to the first 2,000 characters, and Claude reads or searches the file when it needs the rest |
| Failure | Inline up to roughly 10,000 characters; past that, a head-and-tail excerpt of that size cut from the read-back window, with no file path                                                                                                                    |

A command that exits 1 counts as a valid result for the Bash tool only when Claude Code recognizes exit code 1 as a benign outcome for that command: `grep`, `rg`, `egrep`, `fgrep`, `find`, `diff`, `test`, and `[`, plus `git diff` and `git grep`. Every other command that exits 1 counts as a failure, even when exit 1 is a benign informational outcome: no matches for `pgrep` and `jq -e`, files that differ for `cmp`. [`BASH_MAX_OUTPUT_LENGTH`](env-vars.md) sets how many characters of output Claude Code reads back from the working file into a command’s result: 30,000 by default, up to a hard ceiling of 150,000. Raise it when your commands routinely overflow that window, such as a verbose build or a full test-suite log. Raising it enlarges the read-back window, which is also the window a failing command’s excerpt is cut from. It doesn’t raise the inline ceilings: a valid result over the inline ceiling arrives as a file path plus preview regardless of this variable. To change how much of a valid result Claude receives inline, set the [`bashOutputMaxChars`](settings-reference.md#bashoutputmaxchars) setting instead, up to 128,000 characters. It sizes the inline ceiling and the read-back window together, and Claude Code then ignores `BASH_MAX_OUTPUT_LENGTH`. Requires Claude Code v2.1.261 or later.


[​](#background-commands)

Background commands

For long-running processes such as dev servers or watch builds, Claude can set `run_in_background: true` to start the command as a background task and continue working while it runs. List and stop background tasks with `/tasks`. After you stop one there, or from a connected client such as the desktop app, Claude moves on instead of waiting for it. If a subagent started the command, it’s that subagent that moves on.


[​](#when-a-background-command-stops)

When a background command stops

A command that a [foreground subagent](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background) started stops when that subagent’s run ends, whether it finished, failed, or was interrupted. A command that the main conversation or a background subagent started keeps running after a final response, until it exits, is stopped, or reaches its [time limit](#time-limit-for-background-commands). While a command that the main conversation started is still running, a run in non-interactive mode with the `-p` flag [stays open after its result](headless.md#background-tasks-at-exit) until that command exits or reaches its time limit. A command that a background subagent started is stopped when the run exits.


[​](#time-limit-for-background-commands)

Time limit for background commands

In a session that runs unattended, such as a run with the `-p` flag, an Agent SDK application, a CI job, or a cloud session, background Bash and PowerShell commands have a time limit. A local session you work in from a terminal, the desktop app, or the VS Code extension has no time limit on background commands. The time limit requires Claude Code v2.1.285 or later. Before v2.1.288, it applied in every session. The time limit counts from the moment the command enters the background:

- A command that Claude starts in the background gets 30 minutes, or the `timeout` Claude passes with `run_in_background`, up to a maximum of 2 hours
- A command that starts in the foreground and then moves to the background, for example at its timeout, gets 30 minutes from the move

In a run with the `-p` flag whose prompt you pass as text rather than with `--input-format stream-json`, both defaults are 10 minutes instead of 30, because the run [waits for background commands after its result](headless.md#background-tasks-at-exit). When a background command reaches its time limit, Claude Code stops it and tells Claude why, and Claude can start the command again with a longer `timeout` if the work still needs it. The stop notice reads `Background command "<description>" was stopped after reaching its background time limit`.


[​](#raise-the-time-limit-for-background-commands)

Raise the time limit for background commands

Two [environment variables](env-vars.md) raise these limits, for Bash and PowerShell commands alike. Both take milliseconds, and neither can shorten a limit: a lower value leaves the defaults and the 2-hour maximum in place.

- Set `BASH_DEFAULT_TIMEOUT_MS` above `1800000` to replace the 30-minute default with that value, both for commands Claude starts without a `timeout` and for moved commands. In a `-p` run whose prompt you pass as text, any value above `600000` replaces its 10-minute default
- Set `BASH_MAX_TIMEOUT_MS` above `7200000` to raise the 2-hour maximum to that value. Setting `BASH_DEFAULT_TIMEOUT_MS` above `7200000` raises the maximum the same way


[​](#foreground-commands-that-move-to-the-background)

Foreground commands that move to the background

When a foreground command reaches its timeout without finishing, Claude Code moves it to the background instead of stopping it, unless the command starts with `sleep`. A moved command’s [time limit](#time-limit-for-background-commands) counts from the move, and a foreground subagent’s moved command still stops when that subagent’s run ends. Setting [`CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1`](env-vars.md#variables) or running in [bare mode](headless.md#start-faster-with-bare-mode) disables auto-backgrounding along with the rest of the background task functionality, so a command that reaches its timeout stops instead. The result of a command moved to the background states what happened:

- When the timeout triggers the move, the result reports it explicitly: `Command did not complete within its 120s timeout and was moved to the background`, with the seconds matching the timeout that applied, followed by the task ID and the path of the file the output is being written to.
- A `cd`, `pushd`, `popd`, or `chdir` inside a command that is moved to the background never carries over: the result states `Session cwd remains <dir>; directory changes made by the backgrounded command do not apply to subsequent commands.`, so Claude doesn’t act on a directory change that didn’t happen.


[​](#memory-limit-on-linux-and-wsl)

Memory limit on Linux and WSL

On Linux and WSL, set [`CLAUDE_CODE_TOOL_MEMORY_LIMIT`](env-vars.md#variables) to a size such as `4G` to cap the memory that Bash, PowerShell, and [Monitor](#monitor-tool) tool commands can use, so one runaway build can’t take the memory the rest of the session needs. Requires Claude Code v2.1.233 or later. Before v2.1.246, Monitor tool commands ran outside the cap.

- Write the size as a number of bytes or with a `K`, `M`, `G`, or `T` suffix. Set `0`, `off`, `false`, `no`, or `none` to turn the cap off. Claude Code ignores any other value it can’t read as a size, such as `4e9`.
- Claude Code counts all of a session’s Bash, PowerShell, and Monitor commands against the one cap, not each command on its own.
- Claude Code applies the cap with a memory cgroup. When it can’t set the cgroup up, commands run without a cap, and the debug log from `claude --debug` says why.
- After the first process Claude Code starts has turned the cap on, or has turned it off because of an off value or a failed cgroup setup, Claude Code holds that result until you relaunch. To apply a changed or removed value, or a fixed setup, launch `claude` again.
- When commands can’t stay under the cap, the kernel kills a command, and nothing in its result names the cap.

Claude Code can also count other kinds of processes it starts against the same limit. Set [`CLAUDE_CODE_TOOL_MEMORY_CGROUP_EXCLUDE`](env-vars.md#variables) to a comma-separated list of the kinds to exempt from the cap; Claude Code applies the cap to every kind not on your list. Set it to `none` to cap every kind, or to `all-new` to cap only Bash, PowerShell, and Monitor tool commands. Requires Claude Code v2.1.246 or later. The kinds you can name:

- `mcp`: local [MCP servers](../06-MCP-Tools/General/mcp.md)
- `lsp`: [language servers](#lsp-tool-behavior)
- `hooks`: [hook](../07-Hooks/hooks.md) commands
- `plugin`: commands that [plugins](../08-Plugins-Skills/plugins.md) run
- `helper`: Claude Code’s own helper commands, such as `git`
- `agent`: child Claude Code processes, such as [agent teammates](../09-Agents-Patterns/agent-teams.md)

Whatever you list, these rules apply:

- **Unknown names**: Claude Code ignores names it doesn’t recognize
- **Variable unset**: Claude Code takes the set of other capped kinds from configuration Anthropic delivers from the server, and that set can change over time, so set the variable when you need a set that doesn’t change
- **Permission-gating hooks**: even with every kind capped, Claude Code excludes from the cap a hook that can block or change the outcome of an action, and any MCP server that such a hook calls, so the kernel killing a permission-gating hook can’t allow the action it was blocking


[​](#edit-tool-behavior)

Edit tool behavior

The Edit tool performs exact string replacement. It takes an `old_string` and a `new_string` and replaces the first with the second. It doesn’t use regex or fuzzy matching. These checks must pass for an edit to apply. Before any of them, a path matched by a [`Read` deny rule](permissions.md#tool-specific-permission-rules) is refused, including creating a new file there.

- **Read-before-edit**: Claude reads the file in the current conversation before editing it, and a read cut short with a [`PARTIAL view` notice](#large-files) doesn’t count. Claude Opus 4.6, Claude Haiku 4.5, and older models always require the read. Newer models can edit an unread file when reading it wouldn’t need a permission prompt and the Read tool is available.
- **Match**: `old_string` must appear in the file exactly as written. A single character of whitespace or indentation difference is enough to miss.
- **Uniqueness**: `old_string` must appear exactly once. When it appears more than once, Claude either supplies a longer string with enough surrounding context to pin down one occurrence, or sets `replace_all: true` to replace them all.

A file that changed on disk after Claude last read it can still be edited when `old_string` matches the current content exactly and unambiguously and Claude Code can read the file without prompting. Matching against the file’s current content keeps this safe, and the result notes that the file carries other changes so Claude re-reads it before edits that depend on surrounding content. In any other case, such as a stale `old_string` or one that matches more than once without `replace_all`, Claude reads the file again before editing. Claude can also edit a file without a separate Read after it views the file with a Bash command such as `cat` or `grep`. Those commands are `cat`, `nl`, `bat`, `batcat`, `head`, `tail`, `sed -n 'X,Yp'`, `grep`, `egrep`, `fgrep`, and `rg`, each run on one file with no pipes or redirects. A search that prints no matches doesn’t count as a read, nor does any command outside this list. When Claude views a file this way, Claude Code also loads any [subdirectory `CLAUDE.md`](memory.md#how-claude-md-files-load) and [path-scoped rules](memory.md#path-specific-rules) that apply to that file. See [Read and Edit permission rules](permissions.md#read-and-edit) for which Bash commands your `Read` and `Edit` deny rules cover.


[​](#non-utf-8-files)

Non-UTF-8 files

Claude can’t use [NotebookEdit](#notebookedit-tool-behavior) on a file that isn’t valid UTF-8. The same goes for Edit, unless the file starts with a little-endian UTF-16 byte-order mark. When Claude tries, the tool refuses the change and leaves the file untouched. Refused files include non-ASCII text saved in a legacy encoding such as Windows-1252 or Shift-JIS, binary files, and UTF-8 with an invalid byte sequence. The tools refuse because they save the whole file back as UTF-8, which would replace every byte they can’t decode with the replacement character `U+FFFD`. Instead, the [error Claude receives](errors.md#file-is-not-valid-utf-8) tells it to make the change with a shell command that keeps the file’s encoding, or to ask you about converting it to UTF-8 first. Claude can still replace such a file with Write, unless the new content contains `U+FFFD`, the character Read shows Claude in place of bytes it can’t decode. That guard stops Claude from writing back the garbled text it read. When Write does replace the file, it saves the new content as UTF-8, so the file’s original encoding is lost.


[​](#endconversation-tool-behavior)

EndConversation tool behavior

The EndConversation tool ends the current session. Claude uses it only in two situations:

- as a last resort against sustained abusive input, after attempts to redirect the conversation have failed and after a clear warning in an earlier message
- when you explicitly ask to see the tool demonstrated and confirm that you want the session to end

General frustration, profanity, or a task going badly don’t qualify, and neither do requests for harmful content, which Claude declines instead of ending the session. Claude Code follows the same approach as claude.ai, which can [end a rare subset of chats](../19-Reference/end-subset-conversations.md). After Claude ends an interactive session, the session locks. New prompts and most commands return `Claude ended this conversation. Start a new session (or /clear) to continue.`, and only `/clear`, `/resume`, `/help`, `/exit`, and `/feedback` still run. Claude Code records the end in the session’s transcript, so resuming an ended session restores the lock; the session’s history isn’t deleted. Resuming an ended session in [non-interactive mode](headless.md) with the `-p` flag errors and exits with code 1, so a script doesn’t read the ended run as a success. The tool never prompts for permission, and [PreToolUse hooks](../07-Hooks/hooks.md#pretooluse) don’t run for it. While any other tool remains, you can’t block it either: [deny and ask rules](permissions.md#tool-specific-permission-rules) naming `EndConversation` have no effect, and neither `--disallowedTools` nor a `--tools` list can remove it. The exemption is deliberate: the tool does nothing except end the conversation, never reading or modifying files or data, and a safeguard of this kind holds only if the session it applies to can’t turn it off. When your deny rules remove every other tool and also match `EndConversation`, as `"*"` does, Claude Code removes it too rather than leaving it as the only tool, unless an allow rule names `EndConversation` explicitly. A deny list that removes every other tool without matching `EndConversation` leaves it in place. [Subagents](../09-Agents-Patterns/sub-agents.md) never get the tool. Background tasks that share the main conversation’s tool list see it, but calling it there ends nothing. The tool appears only when all of the following are true:

- **Model**: the session’s model is Claude Opus 4.8, Claude Sonnet 5, Claude Fable 5, or a later version of one of those families.
- **Surface**: an interactive terminal session, including a `claude` session in an IDE’s integrated terminal, which is how the [JetBrains plugin](../03-IDE-Integrations/jetbrains.md) runs it. Other surfaces don’t include the tool, such as:
  - non-interactive `-p` runs
  - sessions through the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) TypeScript and Python packages
  - the [VS Code extension](../03-IDE-Integrations/vs-code.md) panel, which bundles its own CLI
  - [GitHub Actions](github-actions.md)
  - [cloud sessions](claude-code-on-the-web.md)
- **Startup mode**: not a [`--bare`](headless.md#start-faster-with-bare-mode) session. Bare mode loads only shell and file tools, so the tool is never registered there.
- **Provider**: not available on [Amazon Bedrock](amazon-bedrock.md), [Claude Platform on AWS](claude-platform-on-aws.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), or [Microsoft Foundry](microsoft-foundry.md), or on sessions signed in through a [cloud gateway](../13-Enterprise-Admin/claude-apps-gateway.md).


[​](#glob-tool-behavior)

Glob tool behavior

The Glob tool finds files by name pattern. On Windows, it’s part of the default tool set. On macOS, Linux, and WSL, Claude Code leaves Glob and [Grep](#grep-tool-behavior) out of the default tool set, and Claude searches with `find` and `grep` through the Bash tool instead. In Claude’s shell those two commands run embedded versions of `bfs` and `ugrep`, and the searches reach your hooks and permission rules as `Bash` calls. On macOS, Linux, and WSL, you get the Glob and Grep tools back in these cases:

- You name `Glob` or `Grep` in [`--tools` or `--allowedTools`](cli-reference.md#cli-flags) when you start the session, or in the equivalent [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) options. With `--tools` you get the ones you list, and naming either tool in `--allowedTools` restores both. An allow rule in a settings file doesn’t have this effect.
- A permissions [deny rule](permissions.md#match-all-uses-of-a-tool), the `--disallowedTools` flag, or [`--restricted`](cli-reference.md#cli-flags) removes `Bash` from the session.
- A [subagent](../09-Agents-Patterns/sub-agents.md#available-tools) lists `Glob` or `Grep` in its `tools` field and leaves out `Bash`. The listed tools come back for that subagent only, or for the whole session when it runs as the main session agent through [`--agent`](../09-Agents-Patterns/sub-agents.md#invoke-subagents-explicitly) or the `agent` setting.

Glob supports standard glob syntax including `**` for recursive directory matching:

- `**/*.js` matches all `.js` files at any depth
- `src/**/*.ts` matches all `.ts` files under `src/`
- `*.{json,yaml}` matches `.json` and `.yaml` files in the current directory

Results are sorted by modification time and capped at 100 files. If the cap is hit, Claude sees a truncation flag in the result and can narrow the pattern. Glob doesn’t respect `.gitignore` by default, so it finds gitignored files alongside tracked ones. This differs from [Grep](#grep-tool-behavior), which skips gitignored files. To make Glob respect `.gitignore`, set `CLAUDE_CODE_GLOB_NO_IGNORE=false` before launching Claude Code. Claude Code decides permission for a Glob call before it checks whether the search directory exists. It still runs the read-permission check for a missing `path` outside the [working directories](permissions.md#working-directories), so a permission prompt for a path doesn’t mean the path exists. A `pattern` or `path` value that contains a null byte returns an error asking Claude to remove it.


[​](#grep-tool-behavior)

Grep tool behavior

The Grep tool searches file contents for patterns. Where [Glob](#glob-tool-behavior) finds files by name, Grep finds lines inside them. On macOS, Linux, and WSL, Grep is absent by default under the same conditions as Glob. See [Glob tool behavior](#glob-tool-behavior) for when both tools are available. Grep is built on [ripgrep](https://github.com/BurntSushi/ripgrep) and uses ripgrep’s regex syntax, not POSIX grep. Patterns that include regex metacharacters need escaping. For example, finding `interface{}` in Go code takes the pattern `interface\{\}`. A pattern, glob, or file type that ripgrep rejects returns an error that includes ripgrep’s diagnostic, so Claude can correct the input and search again. Before v2.1.208, Claude Code reported a rejected input as `No files found` instead of an error, even when the searched-for text existed in the target files. Three output modes control what comes back:

- `files_with_matches`: file paths only, no line content. This is the default.
- `content`: matching lines with file and line number. When the tool’s `offset` parameter points past the last match for a pattern that has matches, Grep returns `No entries at this offset`, so Claude widens or resets the offset instead of concluding the pattern doesn’t match.
- `count`: match count per file, followed by a total across all matching files. The total covers every match even when the tool’s `head_limit` or `offset` parameters truncate the listed per-file entries.

Claude can scope results by file with the `glob` parameter, such as `**/*.tsx`, or by language with the `type` parameter, such as `py` or `rust`. By default, patterns match within a single line. Claude can set `multiline: true` to match across line boundaries. Grep respects `.gitignore`, so gitignored files are skipped. To search a gitignored file, Claude passes its path directly. Claude Code decides permission for a Grep call before it checks whether the search `path` exists. It still runs the read-permission check for a missing `path` outside the [working directories](permissions.md#working-directories), so a permission prompt for a path doesn’t mean the path exists.


[​](#lsp-tool-behavior)

LSP tool behavior

The LSP tool gives Claude code intelligence from a running language server. After each file edit, it automatically reports type errors and warnings so Claude can fix issues without a separate build step. Claude can also call it directly to navigate code:

- Jump to a symbol’s definition
- Find all references to a symbol
- Get type information at a position
- List symbols in a file
- Search for a symbol by name across the workspace
- Find implementations of an interface
- Trace call hierarchies

Claude Code keeps the tool inactive until you install a [code intelligence plugin](../08-Plugins-Skills/plugins-code-intelligence.md) for your language. In [cloud sessions](claude-code-on-the-web.md), Claude Code doesn’t start plugin language servers, so the LSP tool stays inactive there. Claude Code takes the language server’s configuration from the plugin, and you install the server binary yourself. Claude Code returns an error result for each LSP call on a file whose language server it can’t start.


[​](#monitor-tool)

Monitor tool

The Monitor tool lets Claude watch something in the background and react when it changes, without pausing the conversation. Ask Claude to:

- Tail a log file and flag errors as they appear
- Poll a PR or CI job and report when its status changes
- Watch a directory for file changes
- Track output from any long-running script you point it at
- Connect to a WebSocket feed and report each message as it arrives

For most watches, Claude writes a small script, runs it in the background, and receives each output line as it arrives. For a server that already pushes events, Claude can open a [WebSocket](#websocket-source) instead of running a script. You keep working in the same session and Claude interjects when an event arrives. Every watch Claude starts has a deadline: 5 minutes by default, at most 30 minutes, and at most 10 minutes in a [non-interactive](headless.md) run given a single prompt with `-p`. At the deadline the watch ends. Claude gets one notice, so it can start the watch again if it’s still needed. Stop a monitor by asking Claude to cancel it or by ending the session. When you stop a [subagent](../09-Agents-Patterns/sub-agents.md) that started monitors, for example from `/tasks`, those monitors stop with it. When Monitor runs a command, it uses the same [permission rules as Bash](permissions.md#tool-specific-permission-rules), so `allow` and `deny` patterns you have set for Bash apply here too. While [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) is active, Claude Code sets aside allow rules that name `Monitor` itself, along with the other [broad allow rules it drops](permission-modes.md#how-the-classifier-evaluates-actions), so the classifier reviews Monitor commands the same way it reviews Bash commands. The [WebSocket source](#websocket-source) has its own approval prompt, which the classifier also decides in auto mode. The tool is not available on Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry. It is also not available when `DISABLE_TELEMETRY` or `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` is set. On Windows, the tool is available only when [Git Bash](../01-Getting-Started/setup.md#set-up-on-windows) is installed. Plugins can declare monitors that start automatically when the plugin is active, instead of asking Claude to start them. See [plugin monitors](../08-Plugins-Skills/plugins-components.md#monitors).


[​](#websocket-source)

WebSocket source

When a server already pushes events over a WebSocket, Claude can connect to it directly instead of writing a polling script. Each kind of socket activity either becomes an event or ends the watch:

- **Text messages**: each one becomes one event, even when the message spans multiple lines.
- **Binary messages**: not passed through. Claude receives a placeholder line such as `[binary frame, 512 bytes]` instead.
- **Messages larger than 1 MiB**: the watch ends, so subscribe to a filtered feed where one exists.
- **Socket close**: the watch ends and Claude receives the close code.

A WebSocket watch takes a `ws` input in place of `command`, and a single Monitor call can’t combine the two. The `ws` input has two fields:

| Field       | Required | Description                                                                                                                                    |
|:------------|:---------|:-----------------------------------------------------------------------------------------------------------------------------------------------|
| `url`       | Yes      | The endpoint to connect to. Must be a `ws://` or `wss://` URL with no embedded credentials or whitespace, using ASCII characters only          |
| `protocols` | No       | WebSocket subprotocol names to offer during the handshake. Each entry must be a valid subprotocol token, and the list can’t contain duplicates |

The `timeout_ms` deadline applies to a WebSocket watch too: the watch ends at the deadline, and `TaskStop` cancels it early. Opening a WebSocket prompts for approval; in [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) the classifier decides instead. The prompt doesn’t offer an option to skip future prompts for the same host. Claude Code denies URLs that point at a private, link-local, or cloud-metadata address, including hostnames that resolve to one. It also denies hosts in `sandbox.network.deniedDomains`, and when [`allowManagedDomainsOnly`](settings-reference.md#sandbox-network-allowmanageddomainsonly) is set in managed settings, any host outside the managed allowlist.


[​](#notebookedit-tool-behavior)

NotebookEdit tool behavior

NotebookEdit modifies a Jupyter notebook one cell at a time, targeting cells by their `cell_id`. It doesn’t perform string replacement across the notebook the way [Edit](#edit-tool-behavior) does on plain files. Three edit modes control what happens to the target cell:

- `replace`: overwrite the cell’s source. This is the default.
- `insert`: add a new cell after the target. With no `cell_id`, the new cell goes at the start of the notebook. Requires `cell_type` set to `code` or `markdown`.
- `delete`: remove the target cell.

NotebookEdit refuses a notebook file that doesn’t decode as UTF-8, under the [same rule as Edit](#non-utf-8-files), and writes nothing. Permission rules use the `Edit(...)` path format. A rule like `Edit(notebooks/**)` covers NotebookEdit calls on files in that directory.


[​](#powershell-tool)

PowerShell tool

The PowerShell tool lets Claude run PowerShell commands natively. On Windows, this means commands run in PowerShell instead of routing through Git Bash. How the tool becomes available depends on your platform:

- **Windows without Git Bash**: the tool is enabled automatically.
- **Windows with Git Bash installed**: the tool is on by default for claude.ai and Console accounts; set `CLAUDE_CODE_USE_POWERSHELL_TOOL=1` to enable it in Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry sessions, or `0` to turn it off.
- **Linux, macOS, and WSL**: the tool is opt-in.

Your [PreToolUse hooks](../07-Hooks/hooks.md#powershell) receive the tool’s command string in `tool_input.command`, with the same fields as the Bash tool. Match `Bash|PowerShell` in hooks that inspect shell commands; the [PowerShell hook input section](../07-Hooks/hooks.md#powershell) explains why matching `Bash` alone is not enough.


[​](#enable-the-powershell-tool)

Enable the PowerShell tool

Set `CLAUDE_CODE_USE_POWERSHELL_TOOL=1` in your environment or in `settings.json`:

```python
{
  "env": {
    "CLAUDE_CODE_USE_POWERSHELL_TOOL": "1"
  }
}
```

On Windows, set the variable to `0` to turn the tool off. On Linux, macOS, and WSL, the tool requires PowerShell 7 or later: install `pwsh` and ensure it is on your `PATH`. On Windows, Claude Code auto-detects `pwsh.exe` for PowerShell 7+ with a fallback to `powershell.exe` for PowerShell 5.1. When the tool is enabled, Claude treats PowerShell as the primary shell. The Bash tool remains available for POSIX scripts when Git Bash is installed. Claude Code spawns PowerShell with `-ExecutionPolicy Bypass` at process scope only, so `.ps1` scripts and module imports work on default Windows installs without changing the machine’s policy. Process-scope bypass doesn’t override Group Policy `MachinePolicy` or `UserPolicy`, so enterprise policies still apply. To respect the machine’s effective execution policy instead, set `CLAUDE_CODE_POWERSHELL_RESPECT_EXECUTION_POLICY=1`.


[​](#bash-deny-rules-also-turn-off-the-powershell-tool)

Bash deny rules also turn off the PowerShell tool

On Windows with Git Bash installed, denying Bash also turns the PowerShell tool off for the session. This applies to scoped rules such as `Bash(git push *)` as well as a bare `Bash`, and to rules from one of your settings files or `--disallowedTools`. Claude Code does this because a `Bash` rule doesn’t restrict the PowerShell tool, which has [its own permission rules](permissions.md#powershell). With PowerShell left on, Claude could run there what your rule denies in Bash. To keep the PowerShell tool on alongside a Bash deny rule, do either of these:

- Set `CLAUDE_CODE_USE_POWERSHELL_TOOL=1` in your environment or in the `env` block of a settings file, as shown in [Enable the PowerShell tool](#enable-the-powershell-tool).
- Add a scoped [`PowerShell` permission rule](permissions.md#powershell) to a settings file, such as a `PowerShell(git push *)` deny rule.

Without one of these, a scoped Bash deny rule leaves the Bash tool available, and Claude Code turns PowerShell off without a warning. A rule that removes the whole Bash tool leaves Claude with no shell tool for the session.


[​](#shell-selection-in-settings-hooks-and-skills)

Shell selection in settings, hooks, and skills

Three additional settings control where PowerShell is used:

- `"defaultShell": "powershell"` in [`settings.json`](settings-reference.md#all-settings): routes interactive `!` commands through PowerShell. Requires the PowerShell tool to be enabled.
- `"shell": "powershell"` on individual [command hooks](../07-Hooks/hooks.md#command-hook-fields): runs that hook in PowerShell. Hooks spawn PowerShell directly, so this works regardless of `CLAUDE_CODE_USE_POWERSHELL_TOOL`.
- `shell: powershell` in [skill frontmatter](../08-Plugins-Skills/skills.md#frontmatter-reference): runs `` !`command` `` blocks in PowerShell. Requires the PowerShell tool to be enabled.

PowerShell commands follow the [same main-session working-directory reset behavior](#what-persists-between-commands) as Bash commands, including the `CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR` environment variable. PowerShell commands also receive the variables hooks persist through `CLAUDE_ENV_FILE`, under the conditions in [Persisted variables in PowerShell commands](../07-Hooks/hooks.md#persisted-variables-in-powershell-commands). Requires Claude Code v2.1.296 or later.


[​](#exit-code-1-from-searches-and-git-diff-in-powershell)

Exit code 1 from searches and `git diff` in PowerShell

If a `grep` or `rg` search that matches nothing shows `Error: Exit code 1` when Claude runs it in the PowerShell tool, the search didn’t fail. You don’t need to do anything. The error can appear when the search is part of a longer command. For example, when `rg` exits with code 1, `rg foo | Out-Null` shows the error and `rg foo` doesn’t. The PowerShell tool can count exit code 1 as a normal result from `grep`, `rg`, `egrep`, `fgrep`, `findstr`, `git grep`, and `git diff`. The searches use exit code 1 to report no matches. From `git diff`, exit code 1 means the files differ. A command that shows the error when Claude runs it [counts as failed](../08-Plugins-Skills/skills.md#when-an-injected-command-fails) in a skill with `shell: powershell`.


[​](#windows-encoding-and-exit-codes)

Windows encoding and exit codes

- Redirection with `>` and `>>` writes UTF-8 files on PowerShell 5.1
- Claude Code encodes text piped to a native command’s standard input as UTF-8
- Claude Code captures error output without ANSI escape sequences
- A command whose child process waits on standard input receives end-of-file instead of hanging
- If `where.exe` finds no match, or `fc.exe` or `diff.exe` finds that the files differ, the result can show `Error: Exit code 1` though the command didn’t fail. You don’t need to do anything.
- If a `robocopy` exit code from 1 through 7 shows as an error, the copy didn’t fail and you don’t need to do anything. `robocopy` exits with code 0 through 7 to report a result, such as files copied, and with 8 or higher when it fails.


[​](#preview-limitations)

Preview limitations

The PowerShell tool has the following known limitations during the preview:

- PowerShell profiles are not loaded
- On Windows, sandboxing is not supported


[​](#read-tool-behavior)

Read tool behavior

The Read tool takes a file path and returns the contents with line numbers. Claude is instructed to always pass absolute paths. Reading 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. Read handles several file types beyond plain text:

- **Images**: PNG, JPEG, GIF, and WebP files are returned as visual content that Claude can see, not as raw bytes. Claude Code resizes and recompresses large images to fit the model’s image size limits before sending them, so Claude may see a downscaled version of a large screenshot. If Claude misses fine pixel-level detail in a large image, ask it to crop the region you care about, such as with ImageMagick via Bash, and then read the crop. Read refuses an image file larger than 128 MB with an error that tells Claude to resize the image or export a smaller copy, then read that copy. If Claude stops at the error instead of doing so, see [File is too large to read as an image](errors.md#file-is-too-large-to-read-as-an-image).
- **PDFs**: Claude reads short `.pdf` files whole. For PDFs longer than 10 pages, it reads in ranges with a `pages` parameter, such as `"1-5"`, up to 20 pages at a time. Page-range reads render pages with `pdftoppm` from poppler-utils, so install it with `brew install poppler` on macOS or `apt-get install poppler-utils` on Debian and Ubuntu. On Windows and other platforms, install a poppler build that puts `pdftoppm` on your `PATH`. Without it, a page-range read fails with `pdftoppm is not installed`.
- **Jupyter notebooks**: `.ipynb` files return all cells with their outputs, including code, markdown, and visualizations. A notebook whose cells come to more than 256 KB, or more than the [token limit](#large-files), returns an error instead. Claude Code refuses to read a notebook file over 100 MB; the error tells Claude how to read a portion of the notebook instead, such as a slice of cells, with a shell command.

Read only reads files, not directories. Claude lists directory contents with a shell command such as `ls`. Read refuses a file whose extension it treats as binary, such as `.xlsx`, `.parquet`, `.heic`, or `.zip`. Claude keeps working after a refusal: the error suggests a skill for that file type if one is available, or else a shell command or script that reads the format. If you [`@`-mention](common-workflows.md#reference-files-and-directories) a file that Read refuses, Claude receives the file’s path but not its contents.


[​](#large-files)

Large files

Claude can read a text file larger than a single Read call returns. By default one call returns at most 25,000 tokens, or the value you set in [`CLAUDE_CODE_FILE_READ_MAX_OUTPUT_TOKENS`](env-vars.md), and refuses a whole file over 256 KB, so Claude reads a larger file in pages with `offset` and `limit`. On Claude Code v2.1.296 or later it can instead read the whole file, or a long line range, in one call by setting `allow_large: true` when it needs to, for example because you asked for the entire file. That read is sized against the room left in the session’s [context window](context-window.md) instead of the default limits. Images, PDFs, and notebooks keep their limits. What Claude receives when a read goes over the default limits:

- **Whole file over the token limit**: the first page of the file, with a `PARTIAL view` notice saying how much of the file it received and how to read more with `offset` and `limit`
- **Whole file over 256 KB, or an `offset` or `limit` read over the token limit**: an error telling it to read a portion with `offset` and `limit`, or to search for specific content with [Grep](#grep-tool-behavior) instead


[​](#sendfeedback-tool-behavior)

SendFeedback tool behavior

Claude-drafted feedback is a feedback report about Claude Code that Claude writes for you. It requires Claude Code v2.1.238 or later. Claude Code saves each draft on your machine under `~/.claude/feedback/drafts/`, and nothing reaches Anthropic until you send it. Claude drafts one with the SendFeedback tool when:

- A tool or command keeps failing
- It can’t help with something you asked for
- You point out a mistake it made, or it notices one
- You ask it to file feedback


[​](#what-you-see-when-claude-drafts)

What you see when Claude drafts

After Claude queues a draft, you see a card above your prompt with the draft’s title. Press `1` to review the draft, press `2` twice to send it as written, or press `0` to dismiss it. A dismissed draft stays in your queue. After you dismiss a card, Claude Code asks whether to turn Claude-drafted feedback off. It stops asking once you’ve declined twice. By default, you see at most three cards in a session; Anthropic can adjust that limit from the server without a release. After the limit, and whenever you set [`feedbackDrafts`](settings-reference.md#feedbackdrafts) to `quiet`, you see only a count of queued drafts in the prompt footer.


[​](#review-and-edit-a-draft)

Review and edit a draft

Run `/feedback` with no argument to open your queue. It lists every queued draft from all your sessions, including drafts whose cards you dismissed or never saw. Select a draft to open it for review, where you can:

- Edit the title, area, and details
- Set **Send transcript** to `yes` or `no`. When the transcript from the session where Claude queued the draft is still available, it starts at `yes`, which sends that conversation to Anthropic; `no` sends the report only
- Send the draft, discard it, or leave it in the queue for later

To write a report yourself instead, press `w` for the standard feedback dialog. `/feedback` with text after it, and `/bug`, open that dialog directly.


[​](#send-a-draft)

Send a draft

When you send a draft, Claude Code submits it the same way as a `/feedback` report, with the same [retention](../13-Enterprise-Admin/data-usage.md#feedback-using-the-%2Ffeedback-command), and deletes the draft from your machine. When you send from the card, it shows `✓ Sent`; when you send from the queue, it closes with a receipt ID. The report carries:

- Your title, area, and details
- Environment info, such as your Claude Code version, operating system, and model
- The IDs of recent API requests
- The conversation transcript, when you left **Send transcript** at `yes` in the review screen. Sending from the card never includes the transcript

Claude Code keeps your working directory in the local draft so it can find the transcript, and doesn’t send the directory. In [organizations with Zero Data Retention](zero-data-retention.md#features-disabled-under-zdr), and in organizations with the [HIPAA configuration](hipaa-setup.md) applied, Claude Code leaves the SendFeedback tool out of your sessions. If a session in an organization with Zero Data Retention still offers the tool, drafts stay on your machine, and sending fails with `Feedback collection is not available for organizations with custom data retention policies.`


[​](#discard-or-keep-a-draft)

Discard or keep a draft

When you discard a draft, Claude Code deletes it from your machine. A draft you leave in the queue expires after 30 days, or after [`cleanupPeriodDays`](settings-reference.md#cleanupperioddays) when that’s shorter. The queue holds 10 drafts across all your sessions, and when Claude queues an eleventh, Claude Code deletes the oldest. When you run `/exit` with drafts from the session still in the queue, Claude Code asks whether to review them or discard them before exiting.


[​](#turn-claude-drafted-feedback-off)

Turn Claude-drafted feedback off

Set **Claude-drafted feedback** to `off` in `/config`, which writes the [`feedbackDrafts`](settings-reference.md#feedbackdrafts) setting, or set [`CLAUDE_CODE_SEND_FEEDBACK=0`](env-vars.md) for one session. With either, Claude can’t queue drafts. To keep drafting on without cards, set `feedbackDrafts` to `quiet` instead. Administrators can set `feedbackDrafts` in [managed settings](../13-Enterprise-Admin/managed-settings.md), which takes precedence over your own setting.


[​](#sessions-without-claude-drafted-feedback)

Sessions without Claude-drafted feedback

Claude Code includes the tool in interactive terminal sessions on your own machine that use the Claude API rather than a cloud provider. It leaves the tool out of:

- Non-interactive `-p` runs and [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) sessions, which have no screen to review the queue on
- [Cloud sessions](claude-code-on-the-web.md), which can’t write to the queue on your machine
- Sessions on [Amazon Bedrock](amazon-bedrock.md), [Claude Platform on AWS](claude-platform-on-aws.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), or [Microsoft Foundry](microsoft-foundry.md)
- Sessions where you set [`CLAUDE_CODE_SEND_FEEDBACK=0`](env-vars.md) or [`DISABLE_FEEDBACK_COMMAND=1`](env-vars.md), set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` to any non-empty value, or turned off [feature-flag fetching](env-vars.md#features-that-need-feature-flag-fetching)
- Organizations that have turned off product feedback, [organizations with Zero Data Retention](zero-data-retention.md#features-disabled-under-zdr), and organizations with the [HIPAA configuration](hipaa-setup.md) applied


[​](#task-tool-availability)

Task tool availability

The task-tracking tools, `TaskCreate`, `TaskGet`, `TaskUpdate`, `TaskList`, and `TodoWrite`, are available by default only on Opus 4.7, Sonnet 4.6, Haiku 4.5, and earlier models. Wherever the tools are available, you get the four Task tools, or `TodoWrite` instead when you set [`CLAUDE_CODE_ENABLE_TASKS=0`](env-vars.md). On every other model, Claude Code leaves the tools out unless you opt in. The same applies to a model ID Claude Code doesn’t recognize, such as a custom model name served through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md). On newer models, Claude keeps track of multi-step work without a written checklist, and the tools’ definitions and reminders take up context. Without the tools, Claude adds nothing to the [task list](interactive-mode.md#task-list) while it works. If you’d like to use these tools on a model that doesn’t have them by default, do one of the following:

- Export [`CLAUDE_CODE_ENABLE_TODO_TOOLS=1`](env-vars.md) before you start Claude Code, for example `CLAUDE_CODE_ENABLE_TODO_TOOLS=1 claude`. Claude Code then provides the same tools on every model and every provider
- Name one of the tools in [`--allowedTools`](cli-reference.md#cli-flags), for example `claude --allowedTools TaskCreate`
- List the tools in [`--tools`](cli-reference.md#cli-flags), which restricts the session’s built-in tools to the ones it names. Include the tools you want alongside the other built-in tools you use
- In the Agent SDK, the [`allowedTools` and `tools` options](../05-Agent-SDK/agent-sdk-todo-tracking.md#model-availability) work the same way as the two flags

In [background sessions](../09-Agents-Patterns/agent-view.md) and in [cloud sessions](claude-code-on-the-web.md), Claude Code provides the same tools on every model, listed or not. The default set described here applies in Claude Code v2.1.268 and later.


[​](#task-tracking-tools-in-subagents-and-agent-teams)

Task-tracking tools in subagents and agent teams

A subagent has the task-tracking tools only when your session has them, whatever model the subagent runs. An in-process [agent team](../09-Agents-Patterns/agent-teams.md) teammate has the task-tracking tools when your session does. A [split-pane](../09-Agents-Patterns/agent-teams.md#choose-a-display-mode) teammate is a separate Claude Code process that [inherits](../09-Agents-Patterns/agent-teams.md#permissions) your `--tools` list and deny rules, not `--allowedTools`, so check what you set:

- **No `--tools` list or deny rule, and `CLAUDE_CODE_ENABLE_TODO_TOOLS` unset for the teammate**: the teammate has the task-tracking tools its own model has by default.
- **`CLAUDE_CODE_ENABLE_TODO_TOOLS` exported in your shell**: Claude Code passes the teammate a fixed set of environment variables that doesn’t include the one you exported. To set it for the teammate too, start your session by running `claude --settings '{"env":{"CLAUDE_CODE_ENABLE_TODO_TOOLS":"1"}}'` in your shell. The teammate also gets your [`--settings`](settings.md#change-a-setting-for-one-session) value.
- **`--tools` naming the task-tracking tools**: the teammate has them on any model.
- **A task-tracking tool missing from `--tools` or named in a deny rule**: the teammate lacks that tool.

Without the Task tools, an agent coordinates with its team through messages instead of the [shared task list](../09-Agents-Patterns/agent-teams.md#assign-and-claim-tasks).


[​](#webfetch-tool-behavior)

WebFetch tool behavior

WebFetch takes a URL and a prompt describing what to extract. It fetches the page and converts the response to Markdown when the server returns HTML. For most fetches, it then runs the prompt against the content in a separate model call, and Claude receives the result of that call rather than the raw page. The conversion step is not configurable. This makes WebFetch lossy by design. The extraction prompt determines what reaches Claude, so a result that says a page doesn’t mention something may only mean the prompt didn’t ask about it. Ask Claude to fetch again with a more specific prompt, or use `curl` via Bash for the unprocessed page. A few behaviors shape the response Claude receives:

- WebFetch refuses `localhost` and any other hostname without a dot, such as a bare intranet name, before making a request. The [error it returns](errors.md#webfetch-cannot-fetch-localhost) tells Claude to reach local servers with `curl` through Bash instead.
- HTTP URLs are automatically upgraded to HTTPS.
- WebFetch reads up to 100,000 characters of a page’s content per call. On Claude Code v2.1.290 or later, the result for a longer page tells Claude how much went unread, so Claude can fetch the next part.
- WebFetch caches each response for 15 minutes by default, so repeated fetches of the same URL return quickly. On Claude Code v2.1.233 or later, set [`CLAUDE_CODE_WEBFETCH_CACHE_TTL_MS`](env-vars.md#variables) to change how long WebFetch keeps each response.
- A page that hasn’t finished downloading within five minutes, including any redirects WebFetch follows, fails with a deadline error. On Claude Code v2.1.268 or later, set [`CLAUDE_CODE_WEBFETCH_DEADLINE_MS`](env-vars.md#variables) to change the limit, or to `0` to remove it.
- When a URL redirects to a different host, WebFetch returns a text result that names the original URL and the redirect target instead of following it. Claude then fetches the new URL with a second WebFetch call.
- When the extraction step hits an overloaded API, Claude Code retries it with backoff; a fetch that still fails returns an error result.

In Manual and `acceptEdits` [permission modes](permission-modes.md), WebFetch prompts before fetching, except for domains your [permission rules](permissions.md#manage-permissions) already allow or deny and a built-in set of preapproved documentation domains that fetch without a prompt. Whatever your rules allow, a fetch also passes the [WebFetch domain safety check](../13-Enterprise-Admin/data-usage.md#webfetch-domain-safety-check) first; that section covers what the check sends and the setting that skips it. The prompt offers three options:

- **Yes**: approves this fetch only. The next WebFetch call prompts again, even for the same domain.
- **Yes, and don’t ask again for `<domain>`**: approves the fetch and saves a `WebFetch(domain:...)` allow rule for that domain to `.claude/settings.local.json` for that repository. See [how saved approvals persist](permissions.md#permission-system). When your organization sets [`allowManagedPermissionRulesOnly`](permissions.md#managed-only-settings), Claude Code hides this option.
- **No, and tell Claude what to do differently**: rejects the fetch.

To allow a domain in advance without a prompt, add an allow rule like `WebFetch(domain:example.com)`; `WebFetch(domain:*)` allows every domain. The `auto` and `bypassPermissions` [permission modes](permissions.md#permission-modes) skip the prompt, except for a domain an explicit `ask` rule matches. An explicit `WebFetch(domain:...)` rule in `deny`, `ask`, or `allow` takes precedence over the preapproved set, so you can block a preapproved domain or require a prompt for it. When the URL is a claude.ai [artifact](artifacts.md) link, Claude Code can also ask for approval to read the artifact itself. For the cases where it asks, see [Read an artifact shared with you](artifacts.md#read-an-artifact-shared-with-you). WebFetch sets a `User-Agent` header beginning with `Claude-User`, and an `Accept` header that prefers Markdown over HTML so servers that support content negotiation can return Markdown directly. Sandboxed commands don’t inherit WebFetch’s built-in set of preapproved documentation domains. To let a sandboxed command reach a domain without a prompt, add the domain to [`allowedDomains`](settings-reference.md#sandbox-network-alloweddomains) or allow it with a `WebFetch(domain:...)` rule, which the [sandbox also honors](sandboxing.md#network-isolation). WebFetch never reads the sandbox allowlist in return, so adding a domain to a sandbox or organization network allowlist doesn’t stop WebFetch from prompting for it.


[​](#webfetch-availability)

WebFetch availability

On Claude Code v2.1.285 or later, set [`CLAUDE_CODE_DISABLE_WEB_FETCH`](env-vars.md#variables) to `1` to turn WebFetch off. If you sign in with a Team or Enterprise claude.ai account and don’t connect through an [LLM gateway](../13-Enterprise-Admin/llm-gateway.md), WebFetch also depends on your organization’s policy, which Claude Code requests from `api.anthropic.com` when a session starts. The same goes for a session whose plan Claude Code can’t determine, such as one running under a claude.ai token that another app supplied. If WebFetch is missing from a session, run `/status` in the session. If its `Organization policy` line reports that the policy didn’t load and names web fetch among the features that wait for it, Claude Code is withholding WebFetch until it can confirm that your organization allows it. Outside a session, `claude doctor` makes its own request and prints the same line. Once a policy that allows WebFetch loads, the tool returns without a restart.


[​](#websearch-tool-behavior)

WebSearch tool behavior

WebSearch runs a query against Anthropic’s [web search](../04-API-Reference/Agents-Tools/agents-and-tools-tool-use-web-search-tool.md) backend and returns result titles and URLs. It doesn’t fetch the result pages. To read a page Claude finds in search results, it follows up with [WebFetch](#webfetch-tool-behavior). The tool may issue up to eight backend searches per call, refining the search internally before returning results. Claude can scope results with `allowed_domains` to include only certain hosts, or `blocked_domains` to exclude them. The two lists can’t be combined in a single call. When the search request hits an overloaded API, Claude Code retries it with backoff; a call that still fails returns an error result. WebSearch permission rules take no specifier. A bare `WebSearch` entry in `allow` or `deny` is the only form. The search backend is not configurable. To search with a different provider, add an [MCP server](../06-MCP-Tools/General/mcp.md) that exposes a search tool.

WebSearch is available on the Claude API, [Claude Platform on AWS](claude-platform-on-aws.md), and Microsoft Foundry. On Google Cloud’s Agent Platform it works with Opus 4, Sonnet 4, Haiku 4.5, and later models. Amazon Bedrock doesn’t expose the server-side web search tool.


[​](#session-search-limit)

Session search limit

An interactive terminal session has a limit of 200 WebSearch calls. Searches from the main conversation and from [subagents](../09-Agents-Patterns/sub-agents.md), such as a parallel research fan-out, count against the same limit. While a session is at the limit, searches appear in the conversation as calls that did nothing. Claude gets a notice telling it to continue with the information already gathered, say so in its answer, and, if it needs more searches, ask you to raise the limit. To get more searches, raise the cap, wait for the limit to refill, or start a new conversation:

- **Raise the cap**: set the [`CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION`](env-vars.md#variables) environment variable to a positive whole number, such as `500`. The cap can be raised but not turned off.
- **Wait for the refill**: on Claude Code v2.1.290 or later, an interactive terminal session’s limit refills at about 100 calls per hour. To change the rate, set [`CLAUDE_CODE_WEB_SEARCH_REFILLS_PER_HOUR`](env-vars.md#variables) to a number of calls per hour, such as `50`.
- **Start a new conversation**: running [`/clear`](commands.md#all-commands) at the Claude Code prompt also resets the count. If work that can still spawn subagents survives the clear, such as a running workflow, the count carries over instead.

In [non-interactive mode](headless.md) with `-p` and in the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md), the limit applies per turn, not per session. A turn lasts from a message you send until Claude finishes responding. The limit resets when you send the next message after that or start a new `claude -p` run, even with [`--continue` or `--resume`](headless.md#continue-conversations). For more searches, raise [`CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION`](env-vars.md#variables) or set a refill rate with [`CLAUDE_CODE_WEB_SEARCH_REFILLS_PER_HOUR`](env-vars.md#variables).


[​](#write-tool-behavior)

Write tool behavior

The Write tool creates a new file or overwrites an existing one with the full content provided. It doesn’t append or merge. Write also overwrites an existing file whose bytes don’t decode and saves the new content as UTF-8, as described under [non-UTF-8 files](#non-utf-8-files). Whether Claude must read an existing file in the current conversation before overwriting it depends on the model and the file:

- Claude Opus 4.6, Claude Haiku 4.5, and older models always require the read, so a Write to an unread existing file fails with an error.
- Newer models can overwrite a file they never read this session under the same conditions as [read-before-edit](#edit-tool-behavior): reading it wouldn’t need a permission prompt and the Read tool is available.
- Jupyter notebooks, and files Claude has read only partially with a [`PARTIAL view` notice](#large-files), require the read on every model.

This constraint doesn’t apply to new files. Before v2.1.228, every model required the read before overwriting an existing file. Viewing the file with Bash also satisfies this requirement under the same rules described in [Edit tool behavior](#edit-tool-behavior). For partial changes to an existing file, Claude uses Edit instead of Write.


[​](#check-which-tools-are-available)

Check which tools are available

Your exact tool set depends on your provider, platform, and settings. To check what’s loaded in a running session, ask Claude directly:

```python
What tools do you have access to?
```

Claude gives a conversational summary. For exact MCP tool names, run `/mcp`.

The [advisor tool](advisor.md) is a [server tool](../04-API-Reference/Agents-Tools/agents-and-tools-tool-use-advisor-tool.md) that the API runs, rather than a tool that Claude Code implements. It has no name you can reference in permission rules or hook matchers.


[​](#see-also)

See also

- [MCP servers](../06-MCP-Tools/General/mcp.md): add custom tools by connecting external servers
- [Permissions](permissions.md): permission system, rule syntax, and tool-specific patterns
- [Subagents](../09-Agents-Patterns/sub-agents.md): configure tool access for subagents
- [Hooks](../07-Hooks/hooks-guide.md): run custom commands before or after tool execution

---

## Troubleshoot Claude Code installation and authentication | Claude Help Center

Source: https://support.claude.com/en/articles/14552646-troubleshoot-claude-code-installation-and-authentication
Path: 02-Claude-Code-CLI/troubleshoot-claude-code-installation-and-authentication.md

# Troubleshoot Claude Code installation and authentication

April 15, 2026


These ten issues account for the large majority of installation and authentication support tickets related to Claude Code. Each entry includes the most reliable fix.

## 1. **claude: command not found** right after installing.

The installer added `claude` to your PATH, but your current shell has not picked it up yet. Open a new terminal, or run `source ~/.zshrc` (or `~/.bashrc`). On Windows, close and reopen PowerShell.

## 2. npm install fails with `EACCES` / permission denied.

This usually means the install was run with `sudo`, or your global npm directory is root-owned. Do not use sudo. Instead, use the native installer (`curl -fsSL https://claude.ai/install.sh | bash`), or fix npm's prefix with `npm config set prefix ~/.npm-global` and add that `bin` directory to your PATH.

## 3. "Node version not supported" or silent crash on launch.

Claude Code requires **Node 18 or later**. Check your version with `node -v`. If it is older, install a current version via `nvm install --lts`, or use the native installer, which bundles its own runtime and avoids this issue entirely.

## 4. WSL: **claude** runs the Windows Node instead of Linux Node.

Windows PATH leaks into WSL and overrides nvm. Prepend your Linux node to PATH in `~/.bashrc`: `export PATH="$HOME/.nvm/versions/node/$(nvm current)/bin:$PATH"`

## 5. Installer hangs or fails behind a corporate network.

The download host (`storage.googleapis.com`) is likely blocked. Set your proxy first with `export HTTPS_PROXY=http://proxy.example.com:port`, then re-run the installer. If that is not possible, ask your IT team for the offline package.

## 6. **SELF_SIGNED_CERT_IN_CHAIN** or other TLS errors.

Your company injects its own certificate. Point Node at the corporate CA bundle: `export NODE_EXTRA_CA_CERTS=/path/to/company-ca.pem` Add it to your shell profile so it persists.

## 7. **/login** opens a browser but the terminal never finishes ("Waiting for authentication…").

This usually means the localhost callback is blocked, which is common over remote SSH, in devcontainers, or behind a strict firewall. Use the manual flow instead: copy the URL printed in the terminal, complete login in any browser, then paste the returned code back into the terminal.

## 8. "Not authenticated" even though you set `ANTHROPIC_API_KEY`.

There are three common causes: the key was exported in a different shell (run `echo` `$ANTHROPIC_API_KEY` to check), Claude Code has not yet been told to trust this key (it prompts once on first use; until you approve, `ANTHROPIC_API_KEY` takes precedence over any OAuth session only after that approval), or the key is a Console key but your organization requires SSO login instead.

## 9. Bedrock / Vertex: "Could not load credentials."

Claude Code uses the standard provider SDKs, so the fix is the same as for any AWS/GCP CLI tool. For Bedrock, confirm `aws sts get-caller-identity` works and `AWS_REGION` is set to a region where your model is enabled. For Vertex, confirm `gcloud auth application-default login` has been run and that `ANTHROPIC_VERTEX_PROJECT_ID` and `CLOUD_ML_REGION` are set.

## 10. It installed and authenticated, but every request errors with 403 / "model not available."

Your account exists but does not have access to the model Claude Code is requesting. For Enterprise seats, confirm that your seat is active in your organization's admin settings. On Bedrock or Vertex, confirm that the specific Claude model is enabled in that region or project. As a quick workaround, run `/model` and select a model you know you have access to.

## Still stuck?

Run `claude doctor` from your normal shell (not from inside a Claude session). It prints a diagnostic report you can attach to a support ticket. For the full list of known issues, see the **[troubleshooting guide](troubleshooting.md)**.

---

## Troubleshoot installation and login - Claude Code Docs

Source: https://code.claude.com/docs/en/troubleshoot-install
Path: 02-Claude-Code-CLI/troubleshoot-install.md

## On this page

- [Find your error](#find-your-error)
- [Run diagnostic checks](#run-diagnostic-checks)
  - [Check network connectivity](#check-network-connectivity)
  - [Verify your PATH](#verify-your-path)
  - [Check for conflicting installations](#check-for-conflicting-installations)
  - [Check directory permissions](#check-directory-permissions)
  - [Verify the binary works](#verify-the-binary-works)
- [Common installation issues](#common-installation-issues)
  - [Install script returns HTML instead of a shell script](#install-script-returns-html-instead-of-a-shell-script)
  - [command not found: claude after installation](#command-not-found-claude-after-installation)
  - [permission denied when adding to your PATH](#permission-denied-when-adding-to-your-path)
  - [curl: (56) Failure writing output to destination](#curl-56-failure-writing-output-to-destination)
  - [Homebrew cask unavailable or outdated](#homebrew-cask-unavailable-or-outdated)
  - [Cask 'claude-code@latest' is not installed](#cask-is-not-installed)
  - [TLS or SSL connection errors](#tls-or-ssl-connection-errors)
  - [Failed to fetch version from downloads.claude.ai](#failed-to-fetch-version-from-downloads-claude-ai)
  - [The connection dropped while downloading the update](#the-connection-dropped-while-downloading-the-update)
  - [Release verification failed for Claude Code](#release-verification-failed)
  - [Auto-update failed · Run claude doctor in the session footer](#auto-update-failed)
  - [Wrong install command on Windows](#wrong-install-command-on-windows)
  - [running scripts is disabled on this system](#running-scripts-is-disabled-on-this-system)
  - [The process cannot access the file during Windows install](#the-process-cannot-access-the-file-during-windows-install)
  - [claude.exe missing after an update on Windows](#claude-exe-missing-after-an-update-on-windows)
  - [Install killed on low-memory Linux servers](#install-killed-on-low-memory-linux-servers)
  - [Installation was killed before it could finish](#installation-was-killed-before-it-could-finish)
  - [Install hangs in Docker](#install-hangs-in-docker)
  - [Raw mode is not supported during install](#raw-mode-is-not-supported-during-install)
  - [claude update or claude doctor hangs](#claude-update-or-claude-doctor-hangs)
  - [Claude Desktop overrides the claude command on Windows](#claude-desktop-overrides-the-claude-command-on-windows)
  - [Claude Code on Windows requires either Git for Windows (for bash) or PowerShell](#claude-code-on-windows-requires-either-git-for-windows-for-bash-or-powershell)
  - [Claude Code does not support 32-bit Windows](#claude-code-does-not-support-32-bit-windows)
  - [Linux musl or glibc binary mismatch](#linux-musl-or-glibc-binary-mismatch)
  - [Illegal instruction](#illegal-instruction)
  - [dyld: cannot load on macOS](#dyld-cannot-load-on-macos)
  - [Bus error while a session is running](#bus-error-while-a-session-is-running)
  - [Exec format error on WSL1](#exec-format-error-on-wsl1)
  - [npm install errors in WSL](#npm-install-errors-in-wsl)
  - [Permission errors during installation](#permission-errors-during-installation)
  - [Native binary not found after npm install](#native-binary-not-found-after-npm-install)
  - [npm ENOTEMPTY error during update or reinstall](#npm-enotempty-during-update-or-reinstall)
- [Login and authentication](#login-and-authentication)
  - [Reset your login](#reset-your-login)
  - [OAuth error: Invalid code](#oauth-error-invalid-code)
  - [403 Forbidden after login](#403-forbidden-after-login)
  - [Claude Code access has not been granted for this account](#claude-code-access-has-not-been-granted-for-this-account)
  - [This organization has been disabled with an active subscription](#this-organization-has-been-disabled-with-an-active-subscription)
  - [OAuth login fails in WSL2, SSH, or containers](#oauth-login-fails-in-wsl2-ssh-or-containers)
  - [Not logged in or token expired](#not-logged-in-or-token-expired)
  - [Bedrock, Agent Platform, or Foundry credentials not loading](#bedrock-agent-platform-or-foundry-credentials-not-loading)
- [Still stuck](#still-stuck)

Troubleshooting

# Troubleshoot installation and login

Copy pageCopy page

Fix command not found, PATH, permission, network, and authentication errors when installing or signing in to Claude Code.

Copy pageCopy page

If installation fails or you can’t sign in, find your error below. For runtime issues after Claude Code is working, see [Troubleshooting](troubleshooting.md). For configuration problems such as settings not applying or hooks not firing, see [Debug your configuration](debug-your-config.md).


[​](#find-your-error)

Find your error

Match the error message or symptom you’re seeing to a fix:

| What you see                                                                                               | Solution                                                                                                                                      |
|:-----------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------|
| `command not found: claude` or `'claude' is not recognized`                                                | [Fix your PATH](#command-not-found-claude-after-installation)                                                                                 |
| `Native installation exists but ... is not in your PATH`                                                   | [Add the install directory to your PATH](#verify-your-path)                                                                                   |
| `INFO: Could not find files for the given pattern(s).` from `where.exe claude`                             | [Check whether Claude Code is installed](#check-for-conflicting-installations)                                                                |
| `zsh: permission denied: /Users/you/.zshrc` or `bash: /home/you/.bashrc: Permission denied`                | [Make your shell config file writable](#permission-denied-when-adding-to-your-path)                                                           |
| `syntax error near unexpected token '<'`                                                                   | [Install script returns HTML](#install-script-returns-html-instead-of-a-shell-script)                                                         |
| `< was unexpected at this time` in CMD                                                                     | [Install script returns HTML](#install-script-returns-html-instead-of-a-shell-script)                                                         |
| `The term 'System.Xml.XmlDocument' is not recognized`                                                      | [Install script returns HTML](#install-script-returns-html-instead-of-a-shell-script)                                                         |
| `curl: (22) The requested URL returned error: 403`                                                         | [Install script returned 403](#install-script-returns-html-instead-of-a-shell-script)                                                         |
| `curl: (23)` or `curl: (56) Failure writing output to destination`                                         | [Check connectivity or use an alternative installer](#curl-56-failure-writing-output-to-destination)                                          |
| `Killed` during install on Linux                                                                           | [Free memory or add swap space](#install-killed-on-low-memory-linux-servers)                                                                  |
| `Installation was killed before it could finish`                                                           | [Free memory, then rerun the installer](#installation-was-killed-before-it-could-finish)                                                      |
| `Raw mode is not supported` during install                                                                 | [Rerun the installer](#raw-mode-is-not-supported-during-install)                                                                              |
| `EACCES: permission denied` during install                                                                 | [Fix the install directory’s permissions](#permission-errors-during-installation)                                                             |
| `TLS connect error` or `SSL/TLS secure channel`                                                            | [Update CA certificates](#tls-or-ssl-connection-errors)                                                                                       |
| `CRYPT_E_NO_REVOCATION_CHECK` or `CRYPT_E_REVOCATION_OFFLINE`                                              | [Work around blocked revocation checks](#tls-or-ssl-connection-errors)                                                                        |
| `Failed to fetch version` or can’t reach download server                                                   | [Check network and proxy settings](#check-network-connectivity)                                                                               |
| `The connection dropped while downloading the update` or `Download timed out: exceeded the total deadline` | [Run the update again or set your proxy](#the-connection-dropped-while-downloading-the-update)                                                |
| `Release verification failed for Claude Code`                                                              | [Run `claude update` or `claude install` again](#release-verification-failed)                                                                 |
| `Auto-update failed · Run claude doctor` in red in the session footer                                      | [Run `claude update` from your shell](#auto-update-failed)                                                                                    |
| `irm is not recognized` or `The token '&&' is not a valid statement separator`                             | [Use the right command for your shell](#wrong-install-command-on-windows)                                                                     |
| `Cask 'claude-code' is unavailable: No Cask with this name exists`                                         | [Update Homebrew](#homebrew-cask-unavailable-or-outdated)                                                                                     |
| `Cask 'claude-code@latest' is not installed`                                                               | [Upgrade the cask you installed](#cask-is-not-installed)                                                                                      |
| `'bash' is not recognized as the name of a cmdlet`                                                         | [Use the Windows installer command](#wrong-install-command-on-windows)                                                                        |
| `A parameter cannot be found that matches parameter name 'fsSL'`                                           | [Use the Windows installer command](#wrong-install-command-on-windows)                                                                        |
| `Claude Code on Windows requires either Git for Windows (for bash) or PowerShell`                          | [Install a shell](#claude-code-on-windows-requires-either-git-for-windows-for-bash-or-powershell)                                             |
| `Claude Code does not support 32-bit Windows`                                                              | [Open Windows PowerShell, not the x86 entry](#claude-code-does-not-support-32-bit-windows)                                                    |
| `The process cannot access the file ... because it is being used by another process`                       | [Clear the downloads folder and retry](#the-process-cannot-access-the-file-during-windows-install)                                            |
| `Error loading shared library`                                                                             | [Wrong binary variant for your system](#linux-musl-or-glibc-binary-mismatch)                                                                  |
| `Illegal instruction`                                                                                      | [Architecture or CPU instruction set mismatch](#illegal-instruction)                                                                          |
| `cannot execute binary file: Exec format error` in WSL                                                     | [WSL1 native-binary regression](#exec-format-error-on-wsl1)                                                                                   |
| `Bus error` or `oh no: Bun has crashed` while a session is running                                         | [Keep the executable readable](#bus-error-while-a-session-is-running)                                                                         |
| PowerShell installer completes but `claude` is not found or shows an old version                           | [Add the install directory to your PATH](#verify-your-path), then open a new terminal                                                         |
| `dyld: Symbol not found`, `dyld: cannot load`, or `Abort trap` on macOS                                    | [Binary incompatibility](#dyld-cannot-load-on-macos)                                                                                          |
| `claude update` hangs after `Checking for updates`, or `claude doctor` hangs with no output                | [Move the directory at a shell config path](#claude-update-or-claude-doctor-hangs)                                                            |
| `Invoke-Expression` or `iex` parse errors quoting HTML tags or CSS, or `ParserError` with `ParseException` | [Install script returns HTML](#install-script-returns-html-instead-of-a-shell-script)                                                         |
| `running scripts is disabled on this system` or `PSSecurityException`                                      | [Allow the npm shims to run](#running-scripts-is-disabled-on-this-system)                                                                     |
| `Error: claude native binary not installed`                                                                | [Complete the npm install](#native-binary-not-found-after-npm-install)                                                                        |
| `npm error code ENOTEMPTY` during update or reinstall                                                      | [Remove the leftover package directory](#npm-enotempty-during-update-or-reinstall)                                                            |
| `'claude' is not recognized` right after an update on Windows                                              | [Restore `claude.exe` from its backup](#claude-exe-missing-after-an-update-on-windows)                                                        |
| On Windows, the install command prints script text and nothing installs                                    | [Run the complete install command](#wrong-install-command-on-windows)                                                                         |
| `App unavailable in region`                                                                                | Claude Code is not available in your country. See [supported countries](https://www.anthropic.com/supported-countries).                       |
| `unable to get local issuer certificate`                                                                   | [Configure corporate CA certificates](#tls-or-ssl-connection-errors)                                                                          |
| `OAuth error` or `403 Forbidden`                                                                           | [Fix authentication](#login-and-authentication)                                                                                               |
| `Claude Code access has not been granted for this account`                                                 | [Get a role that includes Claude Code](#claude-code-access-has-not-been-granted-for-this-account)                                             |
| `Unable to connect to Anthropic services` during setup                                                     | See [Unable to connect to Anthropic services](errors.md#unable-to-connect-to-anthropic-services) in the Error reference                 |
| `Could not load the default credentials` or `Could not load credentials from any providers`                | [Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry credentials](#bedrock-agent-platform-or-foundry-credentials-not-loading) |
| `ChainedTokenCredential authentication failed` or `CredentialUnavailableError`                             | [Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry credentials](#bedrock-agent-platform-or-foundry-credentials-not-loading) |
| `API Error: 500`, `529 Overloaded`, `429`, or other 4xx and 5xx errors not listed above                    | See the [Error reference](errors.md)                                                                                                    |

If your issue isn’t listed, work through the diagnostic checks below to narrow down the cause.

If you’d rather skip the terminal entirely, the [Claude Code Desktop app](../16-Mobile-Desktop/desktop-quickstart.md) lets you install and use Claude Code through a graphical interface. Download it for [macOS](https://claude.ai/api/desktop/darwin/universal/dmg/latest/redirect?utm_source=claude_code&utm_medium=docs) or [Windows](https://claude.com/download?utm_source=claude_code&utm_medium=docs) and start coding without any command-line setup. On Linux, install the app with apt by following the [Linux install instructions](../16-Mobile-Desktop/desktop-linux.md).


[​](#run-diagnostic-checks)

Run diagnostic checks


[​](#check-network-connectivity)

Check network connectivity

The installer downloads from `downloads.claude.ai`. Verify you can reach it:

- macOS/Linux

- Windows PowerShell

```python
curl -sI https://downloads.claude.ai/claude-code-releases/latest
```

```python
curl.exe -sI https://downloads.claude.ai/claude-code-releases/latest
```

PowerShell aliases `curl` to `Invoke-WebRequest`, which rejects the `-sI` flags, so call `curl.exe` explicitly.

You reached the server if the first line shows a `200` status. You see `HTTP/2 200` on macOS and Linux, and `HTTP/1.1 200 OK` from the `curl.exe` included with Windows. Other results point to the cause:

- `403`: usually a proxy or network filter blocking the host, or Claude Code is [not available in your region](https://www.anthropic.com/supported-countries)
- `5xx`: usually a temporary service issue; wait a few minutes and retry

If you see no output, `Could not resolve host`, or a connection timeout, your network is blocking the connection. Common causes:

- Corporate firewalls or proxies blocking `downloads.claude.ai`
- Regional network restrictions: try a VPN or alternative network
- TLS/SSL issues: update your system’s CA certificates, or check if `HTTPS_PROXY` is configured

If you’re behind a corporate proxy, set `HTTPS_PROXY` and `HTTP_PROXY` to your proxy’s address before installing. Ask your IT team for the proxy URL if you don’t know it, or check your browser’s proxy settings. This example sets both proxy variables, then runs the installer through your proxy:

- macOS/Linux

- Windows PowerShell

```python
export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080
curl -fsSL https://claude.ai/install.sh | bash
```

```python
$env:HTTP_PROXY = 'http://proxy.example.com:8080'
$env:HTTPS_PROXY = 'http://proxy.example.com:8080'
irm https://claude.ai/install.ps1 | iex
```


[​](#verify-your-path)

Verify your PATH

If installation succeeded but you get a `command not found` or `not recognized` error when running `claude`, the install directory isn’t in your PATH. Your shell searches for programs in directories listed in PATH, and the installer places `claude` at `~/.local/bin/claude` on macOS/Linux or `%USERPROFILE%\.local\bin\claude.exe` on Windows. The installer detects this case and reports it under `Setup notes:` in its output: `Native installation exists but ~/.local/bin is not in your PATH.` on macOS and Linux, or `Native installation exists but C:\Users\you\.local\bin is not in your PATH.` on Windows. It prints the fix with that note but doesn’t change PATH itself.

The [VS Code extension](../03-IDE-Integrations/vs-code.md) does not place `claude` at this location. It bundles a private copy of the CLI inside the extension directory for its own chat panel and does not add it to PATH. If you have only installed the extension, `~/.local/bin/claude` will not exist. Run the [standalone install](../01-Getting-Started/setup.md) to use `claude` from a terminal, then continue below.

First check that the program is there at all, then check whether its folder is in your PATH. The PATH fix is permanent, so you apply it once. Pick your platform’s tab and run its commands there: in your terminal on macOS and Linux, or in PowerShell or Command Prompt on Windows.

- macOS/Linux

- Windows PowerShell

- Windows CMD

Check that the installer put the program in place:

```python
ls -la ~/.local/bin/claude
```

- **`No such file or directory`**: there’s no native install. If you haven’t installed Claude Code another way, such as with npm, Homebrew, or a Linux package manager, [install Claude Code](../01-Getting-Started/setup.md#install-claude-code). If you installed it another way, see [Check for conflicting installations](#check-for-conflicting-installations).
- **A listing for the file**: the program is there. Check your PATH next.

List your PATH entries and filter for the install folder:

```python
echo $PATH | tr ':' '\n' | grep -Fx "$HOME/.local/bin"
```

If this prints `/Users/you/.local/bin` or `/home/you/.local/bin`, the directory is in your PATH and you can skip to [Check for conflicting installations](#check-for-conflicting-installations). If there’s no output, add it to your shell configuration with the two commands for your shell. The `echo` command saves the setting for every new terminal, and `source` applies it to the window you’re in. The `echo` command prints nothing when it succeeds.For Zsh, the default on macOS:

```python
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
```

For Bash on Linux, where it’s the default on most distributions:

```python
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
```

For Bash on macOS, add the line to `~/.bash_profile` instead. Terminal on macOS starts Bash as a login shell, which ignores `~/.bashrc` and reads only the first of `~/.bash_profile`, `~/.bash_login`, or `~/.profile` that exists. If you already have a `~/.bash_login` or `~/.profile` and no `~/.bash_profile`, put the line in that file rather than creating `~/.bash_profile`:

```python
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
```

Alternatively, close and reopen your terminal.If the `echo` command prints `permission denied`, see [`permission denied` when adding to your PATH](#permission-denied-when-adding-to-your-path).For other shells such as fish or Nushell, add `~/.local/bin` to your PATH using your shell’s own configuration syntax, then restart your terminal.Verify the fix worked:

```python
claude --version
```

If `claude` is still not found, check these causes:

- **The terminal predates the change**: a window that was already open keeps its old PATH, and a terminal inside an editor takes its PATH from the editor. Open a new window, or quit and reopen the editor.
- **The line wasn’t saved**: run `grep -n '.local/bin' ~/.zshrc`, using your shell’s file name. It prints the line with its line number when the line is there. If it prints nothing, run the two PATH commands again.
- **The line went to another shell’s file**: run `echo $0` to see your shell, then run the two PATH commands for that shell.

Check that the installer put the program in place:

```python
Test-Path "$env:USERPROFILE\.local\bin\claude.exe"
```

- **`False`**: there’s no native install. If you haven’t installed Claude Code another way, such as with npm or WinGet, [install Claude Code](../01-Getting-Started/setup.md#install-claude-code). If you installed it another way, see [Check for conflicting installations](#check-for-conflicting-installations).
- **`True`**: the program is there. Check your PATH next.

List your PATH entries and filter for the install folder:

```python
$env:PATH -split ';' | Select-String '\.local\\bin'
```

If this prints `C:\Users\you\.local\bin`, the directory is in your PATH and you can skip to [Check for conflicting installations](#check-for-conflicting-installations). If there’s no output, add the install directory to your User PATH:

```python
$currentPath = [Environment]::GetEnvironmentVariable('PATH', 'User')
[Environment]::SetEnvironmentVariable('PATH', "$currentPath;$env:USERPROFILE\.local\bin", 'User')
```

Restart your terminal for the change to take effect.Verify the fix worked:

```python
claude --version
```

If `claude` is still not found in a new terminal, check these causes:

- **The terminal runs inside an editor**: it takes its PATH from the editor, so quit and reopen the editor.
- **The change wasn’t saved**: run `[Environment]::GetEnvironmentVariable('PATH', 'User')` and look for `.local\bin` in the PATH it prints. If it’s missing, run the two commands again.

Check that the installer put the program in place:

```python
dir "%USERPROFILE%\.local\bin\claude.exe"
```

- **`File Not Found` or `The system cannot find the path specified.`**: there’s no native install. If you haven’t installed Claude Code another way, such as with npm or WinGet, [install Claude Code](../01-Getting-Started/setup.md#install-claude-code). If you installed it another way, see [Check for conflicting installations](#check-for-conflicting-installations).
- **A listing for `claude.exe`**: the program is there. Check your PATH next.

List your PATH entries and filter for the install folder:

```python
echo %PATH% | findstr /i "local\bin"
```

If there’s no output, open System Settings, go to Environment Variables, and add `%USERPROFILE%\.local\bin` to your User PATH variable. Restart your terminal.Verify the fix worked:

```python
claude --version
```

If `claude` is still not found in a new terminal, a terminal inside an editor takes its PATH from the editor, so quit and reopen the editor too.


[​](#check-for-conflicting-installations)

Check for conflicting installations

Multiple Claude Code installations can cause version mismatches or unexpected behavior. Check what’s installed:

- macOS/Linux

- Windows PowerShell

List all `claude` binaries found in your PATH:

```python
which -a claude
```

If this prints `claude not found`, a `no claude in` line, or nothing, no `claude` is on your PATH. The next checks show whether one is installed at all.Check the three locations a `claude` binary can come from. `~/.local/bin/claude` is the native installer, `~/.claude/local/` is a legacy local npm install created by older versions of Claude Code, and the npm global list shows a `-g` install:

```python
ls -la ~/.local/bin/claude
```

A native install shows a symlink into `~/.local/share/claude/versions/`. A script or a symlink you created yourself at this path is a custom launcher, which [auto-update leaves in place](../01-Getting-Started/setup.md#auto-updates).If either `ls` command prints `No such file or directory`, that’s not an error. It means nothing is installed at that location, so move on to the next check.

```python
ls -la ~/.claude/local/
```

```python
npm -g ls @anthropic-ai/claude-code 2>/dev/null
```

If `ls -la ~/.local/bin/claude` printed `No such file or directory`, there’s no native install. If you haven’t installed Claude Code another way, such as with npm, Homebrew, or a Linux package manager, [install Claude Code](../01-Getting-Started/setup.md#install-claude-code). If `~/.local/bin/claude` exists but `which -a claude` didn’t list it, the folder isn’t in your PATH: see [Verify your PATH](#verify-your-path).

List all `claude` binaries found in your PATH:

```python
where.exe claude
```

If this prints `INFO: Could not find files for the given pattern(s).`, no `claude` is on your PATH.Check whether the native installer placed a binary:

```python
Test-Path "$env:USERPROFILE\.local\bin\claude.exe"
```

- **`True`**: the native install is there. If `where.exe` found nothing, its folder isn’t in your PATH: see [Verify your PATH](#verify-your-path).
- **`False`**: there’s no native install. If you haven’t installed Claude Code another way, such as with npm or WinGet, [install Claude Code](../01-Getting-Started/setup.md#install-claude-code).

If you find multiple installations, keep only one. The native install at `~/.local/bin/claude` on macOS/Linux or `%USERPROFILE%\.local\bin\claude.exe` on Windows is recommended. Remove the extras: Uninstall an npm global install:

```python
npm uninstall -g @anthropic-ai/claude-code
```

Remove the legacy local npm install:

- macOS/Linux

- Windows PowerShell

```python
rm -rf ~/.claude/local
```

```python
Remove-Item -Recurse -Force "$env:USERPROFILE\.claude\local"
```

Remove a Homebrew install on macOS. If you installed the `claude-code@latest` cask, substitute that name:

```python
brew uninstall --cask claude-code
```

Remove a WinGet install on Windows:

```python
winget uninstall Anthropic.ClaudeCode
```


[​](#check-directory-permissions)

Check directory permissions

An install that fails on permissions names the path it couldn’t create or write. On Windows the install writes under `%USERPROFILE%`, which is writable by your user by default, so this section rarely applies there. On macOS and Linux the install writes to these locations:

- `~/.claude/downloads/`: where the install command puts the downloaded binary
- `~/.local/bin/`: the `claude` launcher
- `~/.local/share/claude/`: each version it downloads
- `~/.local/state/claude/`: its lock files
- `~/.cache/claude/`: staged downloads
- [`~/.claude.json`](claude-directory.md): your global config file, where the installer records the install method

If you set `XDG_DATA_HOME`, `XDG_STATE_HOME`, or `XDG_CACHE_HOME`, the install uses those in place of `~/.local/share`, `~/.local/state`, and `~/.cache`. If you set [`CLAUDE_CONFIG_DIR`](env-vars.md), the global config file lives under that directory instead of your home directory. Check whether the directories are writable:

```python
test -w ~/.local/bin && echo "writable" || echo "not writable"
test -w ~/.claude && echo "writable" || echo "not writable"
```

If either directory isn’t writable, create the install directory and set your user as the owner:

```python
sudo mkdir -p ~/.local/bin
sudo chown -R $(whoami) ~/.local
```


[​](#verify-the-binary-works)

Verify the binary works

If `claude --version` prints a version but `claude` crashes or hangs on startup, run these checks to narrow down the cause. If `claude --version` says command not found, go to [Verify your PATH](#verify-your-path) first; the commands below assume `claude` is on your PATH. Confirm the binary exists and is executable:

- macOS/Linux

- Windows PowerShell

```python
ls -la "$(command -v claude)"
```

```python
Get-Command claude | Select-Object Source
```

On Linux, check for missing shared libraries. If `ldd` shows missing libraries, you may need to install system packages. On Alpine Linux and other musl-based distributions, see [Alpine Linux setup](../01-Getting-Started/setup.md#alpine-linux-and-musl-based-distributions).

```python
ldd "$(command -v claude)" | grep "not found"
```

Confirm the binary can execute:

```python
claude --version
```


[​](#common-installation-issues)

Common installation issues

These are the most frequently encountered installation problems and their solutions.


[​](#install-script-returns-html-instead-of-a-shell-script)

Install script returns HTML instead of a shell script

The install command fails with one of these errors when what it downloaded isn’t the install script. **Bash or Zsh**: the error quotes the first line of the returned page.

```python
bash: line 1: syntax error near unexpected token `<'
bash: line 1: `<!DOCTYPE html>'
```

**PowerShell, parse errors**: the errors point into the returned page, with `iex` trying to run HTML and CSS as PowerShell.

```python
iex : At line:1 char:2310
+ ... igin="anonymous"/><script type="text/javascript">!function(o,c){var n ...
Missing argument in parameter list.
...
```

The wording varies with the PowerShell version and system language: you may see `Missing expression after unary operator '--'` or a `ParserError` with `ParseException` instead. HTML tags or CSS in the quoted text identify this failure. If you download with `-OutFile install.ps1` instead, the saved file is the same web page, so that doesn’t help either. **PowerShell, `System.Xml.XmlDocument`**: the error names this type instead of quoting the page.

```python
System.Xml.XmlDocument : The term 'System.Xml.XmlDocument' is not recognized as the name of a cmdlet, function, script
file, or operable program.
```

When `irm` can parse the response as XML, it returns an XML object instead of text, and `iex` then tries to run that object’s type name as a command. The install script is PowerShell code and doesn’t parse as XML, so this error also means the response was something other than the script. The wording around the type name varies with the PowerShell version and system language, but `System.Xml.XmlDocument` itself stays the same, so match on the type name. **CMD**: you see this error, followed by the HTML of the returned page.

```python
< was unexpected at this time.

C:\Users\you><!DOCTYPE html>...
```

The first line appears in your system language, so look for the HTML that follows it. **A 403 with no page**: depending on how the request was routed, curl reports a 403 status with no HTML body.

```python
curl: (22) The requested URL returned error: 403
```

These all mean the install URL returned a web page, an XML document, or an error status instead of the install script. If the error output quotes “App unavailable in region,” Claude Code isn’t available in your country. See [supported countries](https://www.anthropic.com/supported-countries). A bare 403 with no body often has the same cause, but it can also come from a corporate proxy or firewall blocking the download. If you are in a supported country and still see the 403, work through [Check network connectivity](#check-network-connectivity) before trying the alternative installers below, since those reach the same hosts. Otherwise, this can happen due to network issues, regional routing, or a temporary service disruption. **Solutions:**

1.  **Retry after a few minutes**: the issue is often temporary. Wait and try the original command again.
2.  **Use an alternative install method**: unlike a native install, a Homebrew or WinGet install [doesn’t update itself by default](../01-Getting-Started/setup.md#auto-updates). On macOS, install via Homebrew:

    ``` shiki
    brew install --cask claude-code
    ```

    On Windows, install via WinGet:

    ``` shiki
    winget install Anthropic.ClaudeCode
    ```

    Then run `claude --version` to confirm: the command prints a version number such as `2.1.211 (Claude Code)`. If the shell reports `claude` isn’t found, open a new terminal window and retry: the session you installed from keeps its old `PATH`.


[​](#command-not-found-claude-after-installation)

`command not found: claude` after installation

The install finished but `claude` doesn’t work. The exact error varies by platform:

| Platform    | Error message                                                          |
|:------------|:-----------------------------------------------------------------------|
| macOS       | `zsh: command not found: claude`                                       |
| Linux       | `bash: claude: command not found`                                      |
| Windows CMD | `'claude' is not recognized as an internal or external command`        |
| PowerShell  | `claude : The term 'claude' is not recognized as the name of a cmdlet` |

On Windows, if the error started right after Claude Code updated, see [restore `claude.exe` from its backup](#claude-exe-missing-after-an-update-on-windows). Otherwise, see [Verify your PATH](#verify-your-path) for the fix on each platform.


[​](#permission-denied-when-adding-to-your-path)

`permission denied` when adding to your PATH

If the `echo` command that adds `~/.local/bin` to your PATH prints `zsh: permission denied: /Users/you/.zshrc` or `bash: /home/you/.bashrc: Permission denied`, your user can’t write to that file and nothing was saved. In your terminal, check who owns the file, using your shell’s file name in place of `~/.zshrc`:

```python
ls -l ~/.zshrc
```

The third field of the output is the owner.

- **The owner is another user, such as `root`**: take ownership with `sudo chown $(whoami) ~/.zshrc`, which requires administrator rights.
- **The owner is you**: the file is read-only. Make it writable with `chmod u+w ~/.zshrc`.

Then run the two PATH commands for your shell in [Verify your PATH](#verify-your-path) again.


[​](#curl-56-failure-writing-output-to-destination)

`curl: (56) Failure writing output to destination`

The `curl ... | bash` command downloads the script and pipes it to Bash for execution. This error, and the related `curl: (23) Failure writing output to destination`, means Bash did not receive the complete script. Exit code 56 indicates the download itself was interrupted, and exit code 23 indicates curl could not write what it received to the pipe, usually because Bash exited early. Test that you can reach `downloads.claude.ai` with the check in [Check network connectivity](#check-network-connectivity). If you reached the server, the original failure was likely intermittent; retry the install command. You can also [try an alternative install method](../01-Getting-Started/setup.md#install-claude-code).


[​](#homebrew-cask-unavailable-or-outdated)

Homebrew cask unavailable or outdated

Homebrew reports `Error: Cask 'claude-code' is unavailable: No Cask with this name exists` when your local copy of the Homebrew cask index predates the cask’s publication. Refresh the index and retry:

```python
brew update
brew install --cask claude-code
```

If Homebrew installs an older Claude Code version than you expect, the same stale index is usually the cause. The `claude-code` cask tracks the stable channel and is typically about one week behind the latest release; for the newest version run `brew install --cask claude-code@latest` instead. See [Configure release channel](../01-Getting-Started/setup.md#configure-release-channel) for the difference between the two casks.


[​](#cask-is-not-installed)

`Cask 'claude-code@latest' is not installed`

Homebrew offers two casks, `claude-code` and `claude-code@latest`. Running `brew upgrade --cask claude-code@latest` when that cask isn’t the one installed prints `Error: Cask 'claude-code@latest' is not installed.` To see which cask you have, run this in your terminal:

```python
brew list --cask | grep claude-code
```

Upgrade the cask it prints. If it prints nothing, neither cask is installed.


[​](#tls-or-ssl-connection-errors)

TLS or SSL connection errors

Errors such as these mean the TLS handshake failed:

- `curl: (35) TLS connect error`
- `schannel: next InitializeSecurityContext failed`
- PowerShell’s `Could not create SSL/TLS secure channel`
- PowerShell’s `Could not establish trust relationship for the SSL/TLS secure channel`

For `CRYPT_E_NO_REVOCATION_CHECK` or `CRYPT_E_REVOCATION_OFFLINE`, go to step 4. **Solutions:**

1.  **Update your system CA certificates**: On Ubuntu/Debian:

    ``` shiki
    sudo apt-get update && sudo apt-get install ca-certificates
    ```

    On macOS, the system curl uses the Keychain trust store; updating macOS itself updates the root certificates.
2.  **In Windows PowerShell 5.1, enable TLS 1.2**:

    ``` shiki
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    ```

    Then run the installer in the same window:

    ``` shiki
    irm https://claude.ai/install.ps1 | iex
    ```
3.  **Check for proxy or firewall interference**: corporate proxies that perform TLS inspection can cause these errors, including `unable to get local issuer certificate` and `SELF_SIGNED_CERT_IN_CHAIN`. For the install step, make the install download trust your corporate proxy’s CA:
    - macOS/Linux

    - Windows PowerShell

    ``` shiki
    curl --cacert /path/to/corporate-ca.pem -fsSL https://claude.ai/install.sh | bash
    ```

    The PowerShell installer downloads through .NET, which validates TLS against the Windows certificate store. Ask your IT team to add the proxy’s CA certificate to the Windows store if it isn’t already there, then run the installer:

    ``` shiki
    irm https://claude.ai/install.ps1 | iex
    ```

    For Claude Code itself once installed, set `NODE_EXTRA_CA_CERTS` so API requests trust the same bundle:
    - macOS/Linux

    - Windows PowerShell

    ``` shiki
    export NODE_EXTRA_CA_CERTS=/path/to/corporate-ca.pem
    ```

    ``` shiki
    $env:NODE_EXTRA_CA_CERTS = 'C:\path\to\corporate-ca.pem'
    ```

    Ask your IT team for the certificate file if you don’t have it. You can also try on a direct connection to confirm the proxy is the cause.
4.  **On Windows, work around blocked revocation checks**. The errors `CRYPT_E_NO_REVOCATION_CHECK (0x80092012)` and `CRYPT_E_REVOCATION_OFFLINE (0x80092013)` mean curl reached the server but your network blocks the certificate revocation lookup, which is common behind corporate firewalls. If the failing command is the `curl` that downloads `install.cmd`, rerun it from a Command Prompt with `--ssl-revoke-best-effort` added:

    ``` shiki
    curl --ssl-revoke-best-effort -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd
    ```

    When the script’s own downloads hit the same errors, it retries them with best-effort revocation checking automatically, so the flag is only needed on the command you run yourself. Best-effort checking tolerates an unreachable revocation server but still rejects a certificate that is known to be revoked, matching how browsers handle revocation. You can also avoid curl’s revocation check entirely by running the PowerShell installer from PowerShell, which downloads through .NET and doesn’t fail when the revocation server is unreachable:

    ``` shiki
    irm https://claude.ai/install.ps1 | iex
    ```

    You can also install with `winget install Anthropic.ClaudeCode`, which avoids curl entirely.


[​](#failed-to-fetch-version-from-downloads-claude-ai)

`Failed to fetch version from downloads.claude.ai`

The installer couldn’t reach the download server. This typically means `downloads.claude.ai` is blocked on your network. See [Check network connectivity](#check-network-connectivity).


[​](#the-connection-dropped-while-downloading-the-update)

The connection dropped while downloading the update

The connection to the download server closed while `claude install` or `claude update` was fetching the Claude Code binary, and the retries didn’t recover. Claude Code retries the download when the connection drops, the transfer stalls, or the downloaded file fails its checksum, up to three attempts in total. A completed HTTP error, such as a 404, isn’t retried because the server already answered. Before v2.1.202, a single dropped connection failed the download immediately with the bare error `aborted` instead of retrying.

```python
The connection dropped while downloading the update (attempt 3/3: aborted). Check your network — proxies sometimes cut off large downloads.
```

The text in parentheses names which attempt failed and the underlying network error. `claude update` precedes the message with `Error: Failed to install native update` on stderr. A download that stays connected but doesn’t finish within 10 minutes fails with `Download timed out: exceeded the total deadline` instead. Claude Code doesn’t retry a timed-out download, because a connection too slow to finish inside the deadline won’t finish on an immediate retry either. The steps below apply to both messages. A proxy or gateway can close a long transfer before it finishes, and the Claude Code binary is a large download. **What to do:**

- Run `claude update` again. On an otherwise healthy network, the download usually succeeds on the next run. For the timed-out message, run it again from a faster or less throttled network.
- If your network requires a proxy, set `HTTPS_PROXY` before running the installer or `claude update`. See [Check network connectivity](#check-network-connectivity).
- If a corporate proxy keeps closing the transfer, ask your network team to allow the full download from `downloads.claude.ai`. See [Network access requirements](../13-Enterprise-Admin/network-config.md#network-access-requirements).
- Run `claude doctor` from your shell for installation diagnostics


[​](#release-verification-failed)

Release verification failed for Claude Code

This message from `claude update` or `claude install` means Claude Code couldn’t confirm that the release it was about to install is genuine, so it installed nothing. Any version you already have keeps working.

```python
Release verification failed for Claude Code <version> (<reason>). The update was not installed.
```

Take the step that matches the value in parentheses in your message:

- **A value that starts with `sidecar_fetch_`**: run the same command again from your shell. `claude update` succeeded if it prints a line that starts with `Successfully updated from`, and `claude install` succeeded if it prints `Claude Code successfully installed!`.
- **Any other value**: try the same command again later

With any value, if the message repeats, [report the problem](#still-stuck) and include the full message.


[​](#auto-update-failed)

`Auto-update failed · Run claude doctor` in the session footer

This red line means Claude Code tried to update itself in the background and the update didn’t install. You can keep working without doing anything. The line points you to `claude doctor`, whose `Last update attempt: failed (install_failed)` line gives a date but no cause. To finish the update or see why it failed, run `claude update` in your shell instead. If that install fails too, look for the error `claude update` prints under [Find your error](#find-your-error).


[​](#wrong-install-command-on-windows)

Wrong install command on Windows

If you see `'irm' is not recognized`, `The token '&&' is not a valid statement separator`, `A parameter cannot be found that matches parameter name 'fsSL'`, or `'bash' is not recognized as the name of a cmdlet`, you copied the install command for a different shell or operating system. If the command prints the script’s text instead of installing anything, you ran only part of it.

- **`irm` not recognized**: you’re in CMD, not PowerShell. You have two options: Open PowerShell by searching for “PowerShell” in the Start menu, then run the original install command:

  ``` shiki
  irm https://claude.ai/install.ps1 | iex
  ```

  Or stay in CMD and use the CMD installer instead:

  ``` shiki
  curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd
  ```
- **`&&` not a valid statement separator**: you’re in PowerShell but ran the CMD installer command. Use the PowerShell installer:

  ``` shiki
  irm https://claude.ai/install.ps1 | iex
  ```
- **`A parameter cannot be found that matches parameter name 'fsSL'`**: you ran the macOS/Linux `curl -fsSL ... | bash` installer in Windows PowerShell, where `curl` is an alias for `Invoke-WebRequest` and rejects the `-fsSL` flags. Use the PowerShell installer instead:

  ``` shiki
  irm https://claude.ai/install.ps1 | iex
  ```
- **`bash` not recognized**: you ran the macOS/Linux installer on Windows. Use the PowerShell installer instead:

  ``` shiki
  irm https://claude.ai/install.ps1 | iex
  ```
- **The command prints script text instead of installing**: you ran the download half of the command without the part that executes it. `irm https://claude.ai/install.ps1` on its own prints the downloaded script to the terminal. Pipe it to `iex` to run it:

  ``` shiki
  irm https://claude.ai/install.ps1 | iex
  ```

  In CMD, `curl -fsSL https://claude.ai/install.cmd` without `-o` prints the batch script instead of saving it. Run the complete command:

  ``` shiki
  curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd
  ```

Whichever installer you use, confirm it worked: open a new terminal and run `claude --version`, which prints a version number such as `2.1.211 (Claude Code)`.


[​](#running-scripts-is-disabled-on-this-system)

`running scripts is disabled on this system`

Installing or running Claude Code through npm on Windows can fail with a `SecurityError`:

```python
npm : File C:\Program Files\nodejs\npm.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
...
    + CategoryInfo          : SecurityError: (:) [], PSSecurityException
```

The same error names `claude.ps1` when you run `claude` after an npm install. PowerShell’s execution policy is blocking the `.ps1` launcher scripts that npm creates for its commands. The policy applies to script files, so it doesn’t affect the PowerShell installer `irm https://claude.ai/install.ps1 | iex`, which runs the downloaded text directly. **Solutions:**

1.  **Allow locally created scripts for your user**, then retry:

    ``` shiki
    Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
    ```
2.  **Call the `.cmd` launcher instead**: `npm.cmd` and `claude.cmd` do the same job, and the policy doesn’t cover them.
3.  **Use the [PowerShell installer](../01-Getting-Started/setup.md#install-claude-code)** instead of npm. It installs a binary rather than a `.ps1` script.


[​](#the-process-cannot-access-the-file-during-windows-install)

`The process cannot access the file` during Windows install

If the PowerShell installer fails with `Failed to download binary: The process cannot access the file ... because it is being used by another process`, the installer couldn’t write to `%USERPROFILE%\.claude\downloads`. This usually means a previous install attempt is still running, or antivirus software is scanning a partially downloaded binary in that folder. Close any other PowerShell windows running the installer and wait for antivirus scans to release the file. Then delete the downloads folder and run the installer again:

```python
Remove-Item -Recurse -Force "$env:USERPROFILE\.claude\downloads"
irm https://claude.ai/install.ps1 | iex
```


[​](#claude-exe-missing-after-an-update-on-windows)

`claude.exe` missing after an update on Windows

If your terminal reports `'claude' is not recognized` right after Claude Code updated on Windows, check whether `%USERPROFILE%\.local\bin` still contains `claude.exe`. If that directory isn’t on your PATH at all, see [Verify your PATH](#verify-your-path) instead. To update on Windows, Claude Code renames the existing `claude.exe` aside to a backup and moves the new version into its place. If moving the new version into place fails and Claude Code can’t rename the backup back either, the directory keeps the backup but has no `claude.exe`. The backup is a file in the same directory whose name begins with `claude.exe.old.` followed by a numeric timestamp. Run the following in PowerShell to rename the newest backup back to `claude.exe`:

```python
Get-ChildItem "$env:USERPROFILE\.local\bin\claude.exe.old.*" | Sort-Object Name | Select-Object -Last 1 | Rename-Item -NewName claude.exe
```

Then run `claude --version` to confirm the fix. A restored `claude.exe` prints a version number. If there’s no `claude.exe.old.*` file, or `claude` still fails after the rename, reinstall instead:

```python
irm https://claude.ai/install.ps1 | iex
```

Before v2.1.281, Claude Code could delete the backup while `claude.exe` was still missing.


[​](#install-killed-on-low-memory-linux-servers)

Install killed on low-memory Linux servers

A `Killed` message during install usually means the Linux out-of-memory (OOM) killer terminated the `claude install` step because the system ran out of free memory. This is common on small VPS and cloud instances. The install script reports the cause and exits with code 137. In this example, the line number and process ID vary by release and run:

```python
Setting up Claude Code...
bash: line 183: 34803 Killed    "$binary_path" install ${TARGET:+"$TARGET"}
Installation was killed before it could finish (exit code 137). This usually means the system ran out of memory.
Claude Code needs roughly 512MB of free memory to install. Free up memory, then run this script again.
```

Installing needs roughly 512 MB of free memory, and running Claude Code needs more. See the [system requirements](../01-Getting-Started/setup.md#system-requirements). **Solutions:**

1.  **Add swap space** if your server has limited RAM. Swap uses disk space as overflow memory, letting the install complete even with low physical RAM. Create a 2 GB swap file and enable it:

    ``` shiki
    sudo fallocate -l 2G /swapfile
    sudo chmod 600 /swapfile
    sudo mkswap /swapfile
    sudo swapon /swapfile
    ```

    Then retry the installation:

    ``` shiki
    curl -fsSL https://claude.ai/install.sh | bash
    ```
2.  **Close other processes** to free memory before installing.
3.  **Use a larger instance** if possible. Claude Code requires at least 4 GB of RAM.


[​](#installation-was-killed-before-it-could-finish)

Installation was killed before it could finish

The install script reports when the `claude install` step is terminated by a signal. On Linux, exit code 137 means the process received SIGKILL, and on a low-memory host that’s usually the kernel out-of-memory (OOM) killer. The script prints this explanation and exits with code 137:

```python
Installation was killed before it could finish (exit code 137). This usually means the system ran out of memory.
Claude Code needs roughly 512MB of free memory to install. Free up memory, then run this script again.
```

For any other fatal signal, and for exit code 137 on macOS, the script prints `Installation was killed before it could finish (exit code <N>)` with the actual exit code and omits the out-of-memory explanation. The message comes from the install script macOS and Linux use, which also covers installs inside WSL; the native Windows install scripts never print it. Before v2.1.200, the script exited with only the shell’s bare `Killed` line. **What to do:**

- Stop other processes to free memory, then rerun the installer
- Add swap space or move to a larger instance. See [Install killed on low-memory Linux servers](#install-killed-on-low-memory-linux-servers) for the swap-file commands.


[​](#install-hangs-in-docker)

Install hangs in Docker

When installing Claude Code in a Docker container, installing as root into `/` can cause hangs. **Solutions:**

1.  **Set a working directory** before running the installer. When run from `/`, the installer scans the entire filesystem, which causes excessive memory usage. Setting `WORKDIR` limits the scan to a small directory:

    ``` shiki
    WORKDIR /tmp
    RUN curl -fsSL https://claude.ai/install.sh | bash
    ```
2.  **Give Docker more memory** if using Docker Desktop. Build containers share the memory allocated to the Docker Desktop virtual machine, so open **Settings \> Resources** in Docker Desktop, raise the memory limit, and rerun the build.


[​](#raw-mode-is-not-supported-during-install)

`Raw mode is not supported` during install

When your organization’s [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) include changes that need [security approval](../13-Enterprise-Admin/server-managed-settings.md#security-approval-dialogs), Claude Code versions before 2.1.246 try to show the approval dialog during `claude install`. The dialog needs a terminal on stdin. When the installer runs `claude install` from a pipe, as `curl -fsSL https://claude.ai/install.sh | bash` does, stdin is the pipe rather than a terminal, so the install fails with an error containing `Raw mode is not supported`. Claude Code v2.1.246 and later don’t show the dialog during `claude install` or `claude update`. The command runs with the settings you last approved, and Claude Code shows the dialog in your next interactive session. If your organization’s startup configuration [waits for the settings fetch](../13-Enterprise-Admin/server-managed-settings.md#enforce-fail-closed-startup), such as when it sets `forceRemoteSettingsRefresh`, the dialog still appears during these commands, and an install run from a pipe still fails. In every other configuration, rerunning the installer gets past this error, because the script runs the latest release’s `install` command even when you ask it to install an older version. Rerun the command for your platform:

- macOS/Linux

- Windows PowerShell

```python
curl -fsSL https://claude.ai/install.sh | bash
```

```python
irm https://claude.ai/install.ps1 | iex
```

`claude --version` prints the version the rerun installed.


[​](#claude-update-or-claude-doctor-hangs)

`claude update` or `claude doctor` hangs

`claude update` and `claude doctor` scan your shell configuration files for an outdated `claude` alias: `~/.zshrc`, `~/.bashrc`, and `~/.config/fish/config.fish`, plus on macOS the first of `~/.bash_profile`, `~/.bash_login`, or `~/.profile` that exists. If you set `ZDOTDIR`, the Zsh file is `$ZDOTDIR/.zshrc` instead. When one of those paths is a directory, Claude Code skips it and both commands complete normally. Before v2.1.214, a directory at one of those paths made both commands hang and left the System diagnostics section of `/status` blank. `claude doctor` hung with no output; `claude update` hung right after printing `Checking for updates`. If you hit the hang on an earlier version, find the directory. In this command’s output, a line starting with `d` marks that path as a directory. A `No such file or directory` line means nothing exists at that path and isn’t the cause:

```python
ls -ld ~/.zshrc ~/.bashrc ~/.bash_profile ~/.bash_login ~/.profile ~/.config/fish/config.fish
```

Move the directory aside, or update to v2.1.214 or later. Since `claude update` hangs on the affected versions, update by rerunning the [install script](../01-Getting-Started/setup.md#install-claude-code) instead.


[​](#claude-desktop-overrides-the-claude-command-on-windows)

Claude Desktop overrides the `claude` command on Windows

If you installed an older version of Claude Desktop, it may register a `Claude.exe` in the `WindowsApps` directory that takes PATH priority over Claude Code CLI. Running `claude` opens the Desktop app instead of the CLI. Update Claude Desktop to the latest version to fix this issue.


[​](#claude-code-on-windows-requires-either-git-for-windows-for-bash-or-powershell)

Claude Code on Windows requires either Git for Windows (for bash) or PowerShell

Git for Windows is optional. Claude Code uses the [PowerShell tool](tools-reference.md#powershell-tool) when Git Bash is absent, so this error means neither shell was found. **If PowerShell is missing from your PATH**, its default location is `C:\Windows\System32\WindowsPowerShell\v1.0\`. Add that directory to your `PATH`, or install [PowerShell 7](https://aka.ms/powershell), which provides `pwsh`. **To install Git for Windows instead**, download it from [git-scm.com/downloads/win](https://git-scm.com/downloads/win). During setup, select “Add to PATH.” Restart your terminal after installing. Installing it enables the Bash tool, useful when working with Bash-based scripts and tooling. **If Git is already installed** but Claude Code can’t find it, compare its location against the places Claude Code checks. When `CLAUDE_CODE_GIT_BASH_PATH` isn’t set, Claude Code looks for `bash.exe` in this order:

1.  The default install locations `C:\Program Files\Git` and `C:\Program Files (x86)\Git`.
2.  The `git` on your `PATH`, using the `bin\bash.exe` from that Git installation.

In step 2, Claude Code skips a `git` that sits in the folder you launched Claude Code from, or below it in a path that contains `node_modules` or a virtual-environment folder such as `.venv` or `env`, for example `C:\dev\env\myproject\Git` when you launched from `C:\dev\env\myproject`. This keeps Claude Code from running an executable that a project placed there. If your Git is in a location like that, point `CLAUDE_CODE_GIT_BASH_PATH` at it. **To point Claude Code at a specific Git installation**, find it by running `where.exe git` in PowerShell, then set the `bin\bash.exe` path from that installation as `CLAUDE_CODE_GIT_BASH_PATH` in your [settings.json file](settings.md):

```python
{
  "env": {
    "CLAUDE_CODE_GIT_BASH_PATH": "C:\\Program Files\\Git\\bin\\bash.exe"
  }
}
```

**If `CLAUDE_CODE_GIT_BASH_PATH` is set to the correct path and the file exists** but Claude Code still doesn’t use it, check the file’s name first. Claude Code accepts only a file named `bash.exe`, `sh.exe`, `bash`, or `sh`; with any other name, such as Git for Windows’ `git-bash.exe` launcher, it ignores the variable and auto-detects Git Bash as if it were unset, logging a warning visible with `--debug`. A path that doesn’t exist gets the same fallback and warning. Before v2.1.219, Claude Code used any existing file as the shell without checking its name, and exited at startup with `Claude Code was unable to find CLAUDE_CODE_GIT_BASH_PATH path` when the path didn’t exist. If the file’s name is right, endpoint security software such as AppLocker, Group Policy software restriction policies, or EDR agents may be interfering. Ask your IT team to allowlist `claude.exe` and the processes it spawns, including `cmd.exe` and `bash.exe`, in your endpoint protection policy.


[​](#claude-code-does-not-support-32-bit-windows)

Claude Code does not support 32-bit Windows

Windows includes two PowerShell entries in the Start menu: `Windows PowerShell` and `Windows PowerShell (x86)`. The x86 entry runs as a 32-bit process and triggers this error even on a 64-bit machine. To check which case you’re in, run this in the same window that produced the error:

```python
[Environment]::Is64BitOperatingSystem
```

If this prints `True`, your operating system is fine. Close the window, open `Windows PowerShell` without the x86 suffix, and run the install command again. If this prints `False`, you are on a 32-bit edition of Windows. Claude Code requires a 64-bit operating system. See the [system requirements](../01-Getting-Started/setup.md#system-requirements).


[​](#linux-musl-or-glibc-binary-mismatch)

Linux musl or glibc binary mismatch

If you see errors about missing shared libraries like `libstdc++.so.6` or `libgcc_s.so.1` after installation, the installer may have downloaded the wrong binary variant for your system.

```python
Error loading shared library libstdc++.so.6: No such file or directory
```

This can happen on glibc-based systems that have musl cross-compilation packages installed, causing the installer to misdetect the system as musl. **Solutions:**

1.  **Check which libc your system uses**:

    ``` shiki
    ldd --version 2>&1 | head -1
    ```

    Output mentioning `GNU libc` or `GLIBC` means glibc. Output mentioning `musl` means musl.
2.  **If you’re on glibc but got the musl binary**, remove the installation and reinstall. You can also manually download the correct binary using the manifest at `https://downloads.claude.ai/claude-code-releases/{VERSION}/manifest.json`. File a [GitHub issue](https://github.com/anthropics/claude-code/issues) with the output of `ldd --version` and `ls /lib/libc.musl*`.
3.  **If you’re actually on musl**, such as Alpine Linux, install the required packages:

    ``` shiki
    apk add libgcc libstdc++ ripgrep
    ```

    On Alpine, `ripgrep` is in the community repository. If `apk` reports that the package is missing, see [Alpine Linux setup](../01-Getting-Started/setup.md#alpine-linux-and-musl-based-distributions).


[​](#illegal-instruction)

`Illegal instruction`

If running `claude` or the installer prints `Illegal instruction`, the native binary uses CPU instructions your processor doesn’t support. There are two distinct causes. **Architecture mismatch.** The installer downloaded the wrong binary, for example x86 on an ARM server. Check with `uname -m` on macOS or Linux, or `$env:PROCESSOR_ARCHITECTURE` in PowerShell. If the result doesn’t match the binary you received, [file a GitHub issue](https://github.com/anthropics/claude-code/issues) with the output. **Missing AVX instruction set.** If your architecture is correct but you still see `Illegal instruction`, your CPU likely lacks AVX or another instruction the binary requires. This affects roughly pre-2013 Intel and AMD processors, and virtual machines where the hypervisor does not pass AVX through to the guest. On a VPS or VM, run `grep -m1 -ow avx /proc/cpuinfo`; an empty result means AVX is not available to the guest. There is no native-binary workaround; track [issue \#50384](https://github.com/anthropics/claude-code/issues/50384) for status, and include your CPU model from `grep -m1 "model name" /proc/cpuinfo` on Linux or `sysctl -n machdep.cpu.brand_string` on macOS when reporting. Alternative install methods download the same native binary and won’t resolve either cause.


[​](#dyld-cannot-load-on-macos)

`dyld: cannot load` on macOS

If you see `dyld: Symbol not found`, `dyld: cannot load`, or `Abort trap: 6` during installation, the binary is incompatible with your macOS version or hardware. A `Symbol not found` error that references `libicucore` means your macOS version is older than the binary supports:

```python
dyld: Symbol not found: _ubrk_clone
  Referenced from: claude-darwin-x64 (which was built for Mac OS X 13.0)
  Expected in: /usr/lib/libicucore.A.dylib
```

The loader can instead reject the binary’s load commands, which also means your macOS version is too old:

```python
dyld: cannot load 'claude-2.1.42-darwin-x64' (load command 0x80000034 is unknown)
Abort trap: 6
```

**Solutions:**

1.  **Check your macOS version**: Claude Code requires macOS 13.0 or later. Open the Apple menu and select About This Mac to check your version.
2.  **Update macOS** if you’re on an older version. The binary uses load commands and system libraries that older macOS versions don’t support. Alternative install methods like Homebrew download the same binary and won’t resolve this error.


[​](#bus-error-while-a-session-is-running)

`Bus error` while a session is running

If a running session exits and your shell prints `Bus error`, one cause is that Claude Code could no longer read its own executable file from disk. For example, the file was truncated, or deleted on network storage, while the session ran. Before the shell’s message, Claude Code’s runtime can print a crash report that includes `panic(main thread): Bus error at address` and `oh no: Bun has crashed. This indicates a bug in Bun, not your code.` When the executable became unreadable, the crash comes from the unreadable file, not from a bug in Bun. The report can also be missing, if the runtime couldn’t read the code that prints it either. Start a new session to continue. If Claude Code is installed on network storage, follow [Install on network storage](../01-Getting-Started/setup.md#install-on-network-storage) so upgrades don’t remove a binary that running sessions still need.


[​](#exec-format-error-on-wsl1)

`Exec format error` on WSL1

If running `claude` in WSL prints `cannot execute binary file: Exec format error`, you’re on WSL1 and hitting a known native-binary regression tracked in [issue \#38788](https://github.com/anthropics/claude-code/issues/38788). The binary’s program headers changed in a way WSL1’s loader can’t handle. The cleanest fix is to convert your distribution to WSL2 from PowerShell:

```python
wsl --set-version <DistroName> 2
```

If you need to stay on WSL1, invoke the binary through the dynamic linker. Add this function to `~/.bashrc` inside WSL, replacing the path if your home directory differs:

```python
claude() {
  /lib64/ld-linux-x86-64.so.2 "$(readlink -f "$HOME/.local/bin/claude")" "$@"
}
```

Then run `source ~/.bashrc` and retry `claude`.


[​](#npm-install-errors-in-wsl)

npm install errors in WSL

These issues apply if you installed Claude Code with `npm install -g` inside WSL. If you used the [native installer](../01-Getting-Started/setup.md), skip this section. **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`. **`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). **nvm version conflicts.** If you have nvm installed in both WSL and Windows, switching Node versions in WSL may break because WSL imports the Windows PATH by default and the Windows nvm takes priority. The most common cause is that nvm isn’t loaded in your shell. Add the nvm loader to `~/.bashrc` or `~/.zshrc`:

```python
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
```

Or load it in your current session:

```python
source ~/.nvm/nvm.sh
```

If nvm is loaded but Windows paths still take priority, prepend your Linux Node path explicitly:

```python
export PATH="$HOME/.nvm/versions/node/$(node -v)/bin:$PATH"
```

Avoid disabling Windows PATH importing via `appendWindowsPath = false` as this breaks the ability to call Windows executables from WSL. Similarly, avoid uninstalling Node.js from Windows if you use it for Windows development.


[​](#permission-errors-during-installation)

Permission errors during installation

If the native installer fails with permission errors, the target directory may not be writable. See [Check directory permissions](#check-directory-permissions). If you previously installed with npm and are hitting npm-specific permission errors, switch to the native installer:

```python
curl -fsSL https://claude.ai/install.sh | bash
```


[​](#native-binary-not-found-after-npm-install)

Native binary not found after npm install

The `@anthropic-ai/claude-code` npm package downloads the native binary as a per-platform optional dependency, such as `@anthropic-ai/claude-code-darwin-arm64`. npm then runs the package’s postinstall script, which copies that binary into place as the `claude` command; until it runs, `claude` is a placeholder script. If either the download or the postinstall step is skipped, the placeholder stays in place, and running `claude` on macOS and Linux prints:

```python
Error: claude native binary not installed.

Either postinstall did not run (--ignore-scripts, some pnpm configs)
or the platform-native optional dependency was not downloaded
(--omit=optional).

Run the postinstall manually (adjust path for local vs global install):
  node node_modules/@anthropic-ai/claude-code/install.cjs

Or reinstall without --ignore-scripts / --omit=optional.
```

On Windows, `bin/claude.exe` is that same shell-script placeholder rather than a real executable, so PowerShell and CMD report that they can’t run the file instead of printing this message. Check the following causes:

- **Optional dependencies are disabled.** Remove `--omit=optional` from your npm install command, `--no-optional` from pnpm, or `--ignore-optional` from yarn, and check that `.npmrc` does not set `optional=false`. Then reinstall. The native binary is delivered only as an optional dependency, so there is no JavaScript fallback if it is skipped, and running `install.cjs` again can’t place a binary that was never downloaded.
- **Install scripts are disabled.** `--ignore-scripts` and some pnpm configurations skip the postinstall step but still download the platform package. Run `node node_modules/@anthropic-ai/claude-code/install.cjs` as the message suggests, or reinstall without the flag. If postinstall can’t run in your environment at all, `node node_modules/@anthropic-ai/claude-code/cli-wrapper.cjs` finds the downloaded package and launches it, at the cost of an extra Node process on each start. If the wrapper prints `Could not find native binary package` instead, the platform package was never downloaded, so fix the optional-dependencies cause above first.
- **Unsupported platform.** Prebuilt binaries are published for `darwin-arm64`, `darwin-x64`, `linux-x64`, `linux-arm64`, `linux-x64-musl`, `linux-arm64-musl`, `win32-x64`, and `win32-arm64`. Claude Code does not ship a binary for other platforms; see the [system requirements](../01-Getting-Started/setup.md#system-requirements). On FreeBSD, the installer reports the platform as unsupported. Before v2.1.205, it treated FreeBSD as Linux and downloaded a binary that couldn’t run.
- **Corporate npm mirror is missing the platform packages.** Ensure your registry mirrors all eight `@anthropic-ai/claude-code-*` platform packages in addition to the meta package.


[​](#npm-enotempty-during-update-or-reinstall)

npm `ENOTEMPTY` error during update or reinstall

When you run `npm install -g @anthropic-ai/claude-code` over an existing installation, npm can fail while moving the old package directory aside:

```python
npm error code ENOTEMPTY
npm error syscall rename
npm error path /home/you/.nvm/versions/node/v22.13.1/lib/node_modules/@anthropic-ai/claude-code
npm error dest /home/you/.nvm/versions/node/v22.13.1/lib/node_modules/@anthropic-ai/.claude-code-tVWAnUUt
npm error errno -39
npm error ENOTEMPTY: directory not empty, rename '...'
```

The `npm error path` line names the directory npm couldn’t move. Delete that directory and any leftover `.claude-code-*` directories next to it, which earlier interrupted runs can leave behind. The commands below find your global package directory with `npm root -g`; if the directory the `npm error path` line names is not under the directory `npm root -g` prints, for example because you switched Node versions with nvm, delete the directories the error names instead:

- macOS/Linux

- Windows PowerShell

```python
rm -rf "$(npm root -g)/@anthropic-ai/claude-code"
```

Then remove any leftover temp directories. If Zsh prints `no matches found`, there were none to remove:

```python
rm -rf "$(npm root -g)/@anthropic-ai/.claude-code-"*
```

```python
Remove-Item -Recurse -Force "$(npm root -g)/@anthropic-ai/claude-code", "$(npm root -g)/@anthropic-ai/.claude-code-*"
```

Then reinstall:

```python
npm install -g @anthropic-ai/claude-code
```

Confirm with `claude --version`, which prints a version number such as `2.1.211 (Claude Code)`.


[​](#login-and-authentication)

Login and authentication

These sections address login failures, OAuth errors, and token issues.


[​](#reset-your-login)

Reset your login

When login fails and the cause isn’t clear, a clean re-authentication resolves most cases:

1.  Run `/logout` to sign out completely
2.  Close Claude Code
3.  Restart with `claude` and complete the authentication process again

If the browser doesn’t open automatically during login, press `c` to copy the OAuth URL to your clipboard, then paste it into a browser manually. This also works when the URL wraps across lines in a narrow or SSH terminal and can’t be clicked directly.


[​](#oauth-error-invalid-code)

OAuth error: Invalid code

If you see `OAuth error: Invalid code. Please make sure the full code was copied`, the login code expired or was truncated during copy-paste. **Solutions:**

- Press Enter to retry and complete the login quickly after the browser opens
- Type `c` to copy the full URL if the browser doesn’t open automatically
- If using a remote/SSH session, the browser may open on the wrong machine. Copy the URL displayed in the terminal and open it in your local browser instead.


[​](#403-forbidden-after-login)

403 Forbidden after login

If you see `API Error: 403 Request not allowed` after logging in:

- **Claude Pro/Max users**: verify your subscription is active at [claude.ai/settings](https://claude.ai/settings)
- **Anthropic Console users**: confirm your account has the “Claude Code” or “Developer” role. Admins assign this on the Console’s Members page at [platform.claude.com/settings/members](../04-API-Reference/Other/playground.md).
- **Behind a proxy**: corporate proxies can interfere with API requests. See [network configuration](../13-Enterprise-Admin/network-config.md) for proxy setup.


[​](#claude-code-access-has-not-been-granted-for-this-account)

Claude Code access has not been granted for this account

If the sign-in page shows `Authorization failed` with the message `Claude Code access has not been granted for this account. Contact your administrator.` after you log in from Claude Code, your Claude Enterprise organization has set your role to Custom and none of the [custom roles](https://support.claude.com/en/articles/13930452) assigned to your groups grants Claude Code. On the Custom role, you get access only from those custom roles, so nothing you change in Claude Code resolves this error. To get access:

1.  Ask an Owner of your Claude organization to assign a custom role that grants Claude Code access to one of your groups, or to change your role from Custom to a standard role such as User. Owners manage roles in the organization’s [role settings](https://claude.ai/admin-settings/roles).
2.  After the Owner makes the change, run `claude` and log in again.


[​](#this-organization-has-been-disabled-with-an-active-subscription)

This organization has been disabled with an active subscription

If you see `API Error: 400 ... "This organization has been disabled"` despite having an active Claude subscription, an `ANTHROPIC_API_KEY` environment variable is overriding your subscription. This commonly happens when an old API key from a previous employer or project is still set in your shell profile. When `ANTHROPIC_API_KEY` is present and you have approved it, Claude Code uses that key instead of your subscription’s OAuth credentials. In non-interactive mode with the `-p` flag, the key is always used when present. See [authentication precedence](authentication.md#authentication-precedence) for the full resolution order. To use your subscription instead, unset the environment variable and remove it from your shell profile:

- macOS/Linux

- Windows PowerShell

```python
unset ANTHROPIC_API_KEY
claude
```

```python
Remove-Item Env:ANTHROPIC_API_KEY
claude
```

Check `~/.zshrc`, `~/.bashrc`, or `~/.profile` for `export ANTHROPIC_API_KEY=...` lines and remove them to make the change permanent. On Windows, check your PowerShell profile at `$PROFILE` and your User environment variables for `ANTHROPIC_API_KEY`. Run `/status` inside Claude Code to confirm which authentication method is active.


[​](#oauth-login-fails-in-wsl2-ssh-or-containers)

OAuth login fails in WSL2, SSH, or containers

When Claude Code runs in WSL2, on a remote machine over SSH, or inside a container, the browser usually opens on a different host and its redirect can’t reach Claude Code’s local callback server. After you sign in, the browser shows a login code instead of redirecting back automatically. Paste that code into the terminal at the `Paste code here if prompted` prompt to complete login. If the browser doesn’t open at all from WSL2, set the `BROWSER` environment variable to your Windows browser path:

```python
export BROWSER="/mnt/c/Program Files/Google/Chrome/Application/chrome.exe"
claude
```

Alternatively, press `c` at the interactive login prompt to copy the OAuth URL, or copy the URL that `claude auth login` prints, and open it in a browser on your local machine. If pasting the code into the interactive prompt does nothing, your terminal’s paste binding likely isn’t reaching the input field. Try your terminal’s alternate paste shortcut, often right-click or Shift+Insert in Windows Terminal, or use `claude auth login` instead, which reads the pasted code from standard input:

```python
claude auth login
```

This fallback also applies on native Windows or any terminal where pasting into the interactive prompt fails.


[​](#not-logged-in-or-token-expired)

Not logged in or token expired

If Claude Code prompts you to log in again after a session, your OAuth token may have expired. Run `/login` to re-authenticate. If this happens frequently, check that your system clock is accurate, as token validation depends on correct timestamps. Parallel sessions on one machine share a saved login and coordinate its renewal so that only one process refreshes the token at a time. For what the other sessions do after you sign in again in one of them, see [Not logged in](errors.md#not-logged-in). Before v2.1.211, waking the machine from sleep could cause two sessions to renew with the same token, which revoked the saved login and prompted every open session to log in again at once. On macOS, Claude Code saves credentials to the login Keychain. When the Keychain rejects the write, such as when it’s locked in an SSH session or its password is out of sync with your account password, Claude Code saves your login to the plaintext `~/.claude/.credentials.json` file instead. A Console login that creates an API key fails until the Keychain is writable again. To make the Keychain writable again and move your login back into the encrypted Keychain:

1

Check Keychain access

Run `claude doctor` to check Keychain access. When the Keychain rejects writes, the report lists a warning that starts with `macOS Keychain is not writable`, followed by a suggested fix. When the report lists no Keychain warning, the Keychain is writable and you can skip to the last step.

2

Unlock the Keychain

```python
security unlock-keychain ~/Library/Keychains/login.keychain-db
```

Enter your Keychain password when the command asks for it, then run `claude doctor` again. When the unlock worked, the report no longer lists the Keychain warning.

3

Resync the Keychain password if unlocking doesn't help

Open Keychain Access, select the `login` keychain, and choose **Edit \> Change Password for Keychain “login”** to resync it with your account password. Then run `claude doctor` again. Go on to the next step once the report no longer lists the Keychain warning.

4

Log out and back in

Once the Keychain is writable again, Claude Code moves the credentials back the next time it writes a credential. To force it now, run `/logout` and then `/login`. Logging out removes all stored credentials, including the plaintext file’s contents, saved MCP server logins, and plugin sensitive values, so expect to re-authorize MCP servers and re-enter plugin secrets afterwards. Logging in again stores your login in the Keychain.


[​](#bedrock-agent-platform-or-foundry-credentials-not-loading)

Bedrock, Agent Platform, or Foundry credentials not loading

If you configured Claude Code to use a cloud provider and see `Could not load credentials from any providers` on Amazon Bedrock, `Could not load the default credentials` on Google Cloud’s Agent Platform, or `ChainedTokenCredential authentication failed` on Microsoft Foundry, your cloud provider CLI is likely not authenticated in the current shell. For Amazon Bedrock, confirm your AWS credentials are valid:

```python
aws sts get-caller-identity
```

For Google Cloud’s Agent Platform, confirm `ANTHROPIC_VERTEX_PROJECT_ID` and `CLOUD_ML_REGION` are set in your shell, then set application default credentials:

```python
gcloud auth application-default login
```

For Microsoft Foundry, confirm `ANTHROPIC_FOUNDRY_API_KEY` is set, or sign in with the Azure CLI so the default credential chain can find your account:

```python
az login
```

If credentials work in your terminal but not in the VS Code or JetBrains extension, the IDE process likely didn’t inherit your shell environment. Set the provider environment variables in the IDE’s own settings, or launch the IDE from a terminal where they’re already exported. See [Amazon Bedrock](amazon-bedrock.md), [Google Cloud’s Agent Platform](google-vertex-ai.md), or [Microsoft Foundry](microsoft-foundry.md) for full provider setup.


[​](#still-stuck)

Still stuck

If none of the above resolves your issue:

1.  Check the [GitHub repository](https://github.com/anthropics/claude-code/issues) for known issues, or open a new one with your operating system, the install command you ran, and the full error output
2.  If `claude --version` works but something else is wrong, run `claude doctor` for an automated diagnostic report
3.  If you can start a session, use `/feedback` inside Claude Code to report the problem
4.  If the problem is with your account rather than the install, such as a login loop, a subscription that isn’t recognized, or a disabled organization, contact Anthropic support: sign in at [claude.ai](https://claude.ai) (Console users: [platform.claude.com](../04-API-Reference/Other/playground.md)), click your initials in the lower left, and select **Get help**. See [How to get support](../15-Claude-AI-Features/how-to-get-support.md) for the full flow.

---

## Troubleshooting - Claude Code Docs

Source: https://code.claude.com/docs/en/troubleshooting
Path: 02-Claude-Code-CLI/troubleshooting.md

## On this page

- [Performance and stability](#performance-and-stability)
  - [High CPU or memory usage](#high-cpu-or-memory-usage)
  - [Large tables are cut off in the terminal](#large-tables-are-cut-off-in-the-terminal)
  - [Auto-compaction stops with a thrashing error](#auto-compaction-stops-with-a-thrashing-error)
  - [Command hangs or freezes](#command-hangs-or-freezes)
  - [Garbled or corrupted text in an editor’s integrated terminal](#garbled-or-corrupted-text-in-an-editor%E2%80%99s-integrated-terminal)
  - [Stray \>0q at startup or \>4m after exit](#stray-0q-at-startup-or-4m-after-exit)
  - [Mouse wheel scrolls one line at a time in fullscreen rendering](#mouse-wheel-scrolls-one-line-at-a-time-in-fullscreen-rendering)
  - [Clipboard commands such as pbcopy fail inside the sandbox](#clipboard-commands-such-as-pbcopy-fail-inside-the-sandbox)
  - [Copied text doesn’t reach your local clipboard over SSH](#copied-text-doesn%E2%80%99t-reach-your-local-clipboard-over-ssh)
  - [Search and discovery issues](#search-and-discovery-issues)
  - [Slow or incomplete search results on WSL](#slow-or-incomplete-search-results-on-wsl)
- [Get more help](#get-more-help)

Troubleshooting

# Troubleshooting

Copy pageCopy page

Fix high CPU or memory usage, hangs, auto-compact thrashing, and search problems in Claude Code, and find the right page for other issues.

Copy pageCopy page

This page covers performance, stability, and search problems once Claude Code is running. For other issues, start with the page that matches where you’re stuck:

| Symptom                                                                                                                                                                                                    | Go to                                                                                                                       |
|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------|
| `command not found`, install fails, PATH issues, `EACCES`, TLS errors                                                                                                                                      | [Troubleshoot installation and login](troubleshoot-install.md)                                                        |
| Update or install download fails with `The connection dropped while downloading the update` or `aborted`                                                                                                   | [Troubleshoot installation and login](troubleshoot-install.md#the-connection-dropped-while-downloading-the-update)    |
| Update or install fails with `Release verification failed for Claude Code`                                                                                                                                 | [Troubleshoot installation and login](troubleshoot-install.md#release-verification-failed)                            |
| Session footer shows `Auto-update failed · Run claude doctor` in red                                                                                                                                       | [Troubleshoot installation and login](troubleshoot-install.md#auto-update-failed)                                     |
| Login loops, OAuth errors, `403 Forbidden`, “organization disabled”, Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry credentials                                                       | [Troubleshoot installation and login](troubleshoot-install.md#login-and-authentication)                               |
| Settings not applying, hooks not firing, MCP servers not loading                                                                                                                                           | [Debug your configuration](debug-your-config.md)                                                                      |
| Session started in auto mode, or Claude edits files and runs commands without asking                                                                                                                       | [Which mode a session starts in](permission-modes.md#which-mode-a-session-starts-in)                                  |
| After you update Claude Code or the Agent SDK, tool calls are denied in `claude -p` or SDK runs that don’t pass `--permission-mode`, `permissionMode`, or `permission_mode`                                | [Tool calls denied in `claude -p` and Agent SDK runs](permission-modes.md#which-mode-a-non-interactive-run-starts-in) |
| `API Error: 5xx`, `529 Overloaded`, `429`, request validation errors                                                                                                                                       | [Error reference](errors.md)                                                                                          |
| `model not found` or `you may not have access to it`                                                                                                                                                       | [Error reference](errors.md#theres-an-issue-with-the-selected-model)                                                  |
| A command Claude runs fails with `Disk full:`, `Disk quota used up:`, `Nearly out of inodes:`, `The command was not started:`, `Your disk quota is full`, `is full (ENOSPC)`, or `Command output was lost` | [Error reference](errors.md#disk-quota-or-temp-filesystem-is-full)                                                    |
| VS Code extension not connecting or detecting Claude                                                                                                                                                       | [VS Code integration](../03-IDE-Integrations/vs-code.md#fix-common-issues)                                                                   |
| `Claude Code process exited with code 1` in VS Code or an SDK app                                                                                                                                          | [Error reference](errors.md#claude-code-process-exited-with-code-n)                                                   |
| JetBrains plugin or IDE not detected                                                                                                                                                                       | [JetBrains integration](../03-IDE-Integrations/jetbrains.md#troubleshooting)                                                                 |
| High CPU or memory, slow responses, hangs, search not finding files                                                                                                                                        | [Performance and stability](#performance-and-stability) below                                                               |

If you’re not sure which applies, run `/doctor` inside Claude Code for an automated check of your installation, settings, extensions, and context usage; it proposes fixes it can apply after you confirm. If `claude` won’t start at all, run `claude doctor` from your shell instead. Run `/mcp` to check MCP server status.


[​](#performance-and-stability)

Performance and stability

These sections cover issues related to resource usage, responsiveness, and search behavior.


[​](#high-cpu-or-memory-usage)

High CPU or memory usage

Claude Code is designed to work with most development environments, but may consume significant resources when processing large codebases. If you’re experiencing performance issues:

1.  Use `/compact` regularly to reduce context size. If it returns `Not enough messages to compact.`, the conversation has too few turns to summarize; that can happen even with a full context when a single large paste filled it
2.  Close and restart Claude Code between major tasks
3.  Consider adding large build directories to your `.gitignore` file
4.  Restart with [`claude --safe-mode`](cli-reference.md#cli-flags) to check whether a plugin, MCP server, or hook is the source. It disables all customizations for the session; if usage drops, see [Debug your configuration](debug-your-config.md#test-against-a-clean-configuration) to find which one

If a session’s heap memory passes 2.5GB, a critical memory usage warning appears. To free the memory, restart Claude Code and run [`claude --continue`](cli-reference.md#cli-flags) to resume the conversation in a fresh process. Outside [fullscreen rendering](fullscreen.md), running `/compact` frees memory too. The warning disappears once memory use drops back below 2.5GB. If memory usage stays high after these steps, run `/heapdump` to write two files to `~/Desktop`: a JavaScript heap snapshot named `<session-id>.heapsnapshot` and a memory breakdown named `<session-id>-diagnostics.json`. Claude Code [hides the command from the command menu](commands.md#how-the-command-menu-matches-what-you-type); type it in full. On Linux without a Desktop folder, the files are written to your home directory.

The `.heapsnapshot` file contains every string in the process, including your full conversation and credentials. Don’t attach it to a public issue or share it.

The command also prints a summary in the conversation, showing the process’s total memory, how much of it is in the JS heap, and how much sits outside the heap. The summary also lists any leak indicators, such as a high memory growth rate or an unusually high number of open handles. The summary says whether most memory is in the JS heap, which the snapshot captures, or in native memory, which it doesn’t. Report the output or investigate it yourself:

- **Report it**: open a [GitHub issue](https://github.com/anthropics/claude-code/issues) and attach only the `-diagnostics.json` file, which carries the statistics behind the printed summary and no conversation content or credentials
- **Investigate it yourself**: if the summary says most memory is JS heap, open the `.heapsnapshot` file in Chrome DevTools under Memory → Load and sort by retained size to see what’s holding the memory

If the summary says most memory is native, the snapshot can’t show it; include the summary’s leak indicators in your report instead.


[​](#large-tables-are-cut-off-in-the-terminal)

Large tables are cut off in the terminal

A Markdown table with more than 200 rows renders its first 200 rows followed by a `… N more rows not shown` line. Only the display is capped: the full table stays in the conversation, and [`/copy`](commands.md) copies every row. For a table too large to read in the terminal, ask Claude to write it to a file instead. Before v2.1.208, Claude Code rendered every row, so resuming a session that contained a very large table could stall while it re-rendered.


[​](#auto-compaction-stops-with-a-thrashing-error)

Auto-compaction stops with a thrashing error

If you see `Autocompact is thrashing: the context refilled to the limit...`, automatic compaction succeeded but a file or tool output immediately refilled the context window several times in a row. Claude Code stops retrying to avoid wasting API calls on a loop that isn’t making progress. To recover:

1.  Ask Claude to read the oversized file in smaller chunks, such as a specific line range or function, instead of the whole file
2.  Run `/compact` with a focus that drops the large output, for example `/compact keep only the plan and the diff`
3.  Move the large-file work to a [subagent](../09-Agents-Patterns/sub-agents.md) so it runs in a separate context window
4.  Run `/clear` if the earlier conversation is no longer needed

If the error comes back after a `/clear`, run [`/context`](debug-your-config.md) and compare the `Messages` row with the rows above it:

- **`Messages` is the largest row**: a file or tool output in the new conversation is refilling the window, so work through steps 1 to 3 again
- **The other rows together are larger**: what loads at session start leaves too little room to work in, so [trim what loads at startup](errors.md#prompt-is-too-long)


[​](#command-hangs-or-freezes)

Command hangs or freezes

If Claude Code seems unresponsive:

1.  Press Ctrl+C to attempt to cancel the current operation
2.  If unresponsive, you may need to close the terminal and restart

Restarting doesn’t lose your conversation. Run `claude --resume` in the same directory to pick the session back up.


[​](#garbled-or-corrupted-text-in-an-editor’s-integrated-terminal)

Garbled or corrupted text in an editor’s integrated terminal

If characters render as boxes, smears, or the wrong glyphs when running Claude Code in the VS Code, Cursor, or Devin Desktop integrated terminal, the terminal’s GPU renderer is likely the cause. Run `/terminal-setup` inside Claude Code to set `terminal.integrated.gpuAcceleration` to `"off"`, or set it manually in your editor settings and reload the window. See [Terminal configuration](terminal-config.md) for the other settings `/terminal-setup` writes.


[​](#stray-0q-at-startup-or-4m-after-exit)

Stray `>0q` at startup or `>4m` after exit

These characters, printed by terminals built on a VTE library older than 0.53, are the ends of two Claude Code control sequences. To stop the text, [update Claude Code](../01-Getting-Started/setup.md#update-claude-code) to v2.1.301 or later, which skips both sequences when it identifies such a terminal. If the text remains, print the VTE version from the terminal’s shell:

```python
echo $VTE_VERSION
```

On a VTE-based terminal, a result below `5300` means a library older than 0.53: update or replace the terminal to get VTE 0.53 or later. Otherwise, see [Get more help](#get-more-help).


[​](#mouse-wheel-scrolls-one-line-at-a-time-in-fullscreen-rendering)

Mouse wheel scrolls one line at a time in fullscreen rendering

In [fullscreen rendering](fullscreen.md), Claude Code scrolls the conversation itself rather than leaving it to your terminal. If each wheel notch moves fewer lines than you want, run `/scroll-speed` to raise the number of lines per notch and save it, or set the `CLAUDE_CODE_SCROLL_SPEED` environment variable, except in the JetBrains IDE terminal, where Claude Code applies its own scroll handling and neither takes effect. See [Mouse wheel scrolling](fullscreen.md#mouse-wheel-scrolling) for the values each accepts. To move faster without changing the speed, press `PgUp` and `PgDn` to scroll half a screen at a time. To use your terminal’s native scrollback instead, run `/tui default` to switch to the classic renderer.


[​](#clipboard-commands-such-as-pbcopy-fail-inside-the-sandbox)

Clipboard commands such as `pbcopy` fail inside the sandbox

When [sandboxing](sandboxing.md) is on, clipboard utilities such as `pbcopy`, `xclip`, and `wl-copy` can fail to reach the system clipboard from inside a sandboxed Bash command, leaving your clipboard unchanged after Claude pipes text to them. To put Claude’s output on your clipboard, ask Claude to print the content in its response, then run [`/copy`](commands.md). `/copy` writes to the clipboard from the Claude Code process itself rather than from a sandboxed command, so sandboxing doesn’t block it. It can copy a single code block instead of the whole response, and it also writes what it copied to a file and prints the path, which gives you a fallback when the clipboard write doesn’t reach your terminal, for example over SSH. When Claude pipes text to one of these tools, adding `pbcopy *`, `wl-copy *`, or `xclip *` to [`excludedCommands`](settings-reference.md#sandbox-excludedcommands) doesn’t take that call out of the sandbox on its own.


[​](#copied-text-doesn’t-reach-your-local-clipboard-over-ssh)

Copied text doesn’t reach your local clipboard over SSH

When Claude Code runs on a remote machine over SSH, it can’t run a clipboard tool on your local machine. Outside tmux, when you select text in [fullscreen rendering](fullscreen.md) or run `/copy`, Claude Code sends the text to your terminal as an OSC 52 escape sequence instead. Your terminal decides whether to put it on your clipboard. `/copy` reports `Copied to clipboard` whether or not the text arrived, and outside tmux the selection notice reads `sent N chars via OSC 52`. Some terminals don’t act on OSC 52. iTerm2 ignores it until you turn on **Settings \> General \> Selection \> Applications in terminal may access clipboard**, and macOS Terminal.app doesn’t support it. To get the text without OSC 52:

- Hold your terminal’s native-selection key while you drag, then copy with your terminal’s usual shortcut, such as `Cmd+C`. The key is `Fn` in Terminal.app and `Option` in iTerm2. [Keep native text selection](fullscreen.md#keep-native-text-selection) lists it for other terminals.
- Set [`CLAUDE_CODE_DISABLE_MOUSE=1`](env-vars.md) on the remote machine so your terminal handles selection for the whole session.


[​](#search-and-discovery-issues)

Search and discovery issues

If the Search tool, `@file` mentions, custom agents, or custom skills aren’t finding files, the bundled `ripgrep` binary may not run on your system. Install your platform’s `ripgrep` package and tell Claude Code to use it instead:

- macOS

- Ubuntu/Debian

- Alpine

- Arch

- Windows

```python
brew install ripgrep
```

```python
sudo apt install ripgrep
```

```python
apk add ripgrep
```

`ripgrep` is in Alpine’s community repository. If `apk` reports that the package is missing, see [Alpine Linux setup](../01-Getting-Started/setup.md#alpine-linux-and-musl-based-distributions).

```python
pacman -S ripgrep
```

```python
winget install BurntSushi.ripgrep.MSVC
```

Then set `USE_BUILTIN_RIPGREP` to `0`, either in your shell [environment](env-vars.md) or in the `env` block of your [`settings.json`](settings-reference.md#all-settings):

```python
{
  "env": {
    "USE_BUILTIN_RIPGREP": "0"
  }
}
```

To confirm the switch took effect, run `claude doctor` in your terminal and check that the Search line shows the path of your system ripgrep instead of `OK (bundled)`.


[​](#slow-or-incomplete-search-results-on-wsl)

Slow or incomplete search results on WSL

Disk read performance penalties when [working across file systems on WSL](https://learn.microsoft.com/en-us/windows/wsl/filesystems) may result in fewer-than-expected matches when using Claude Code on WSL. Search still functions, but returns fewer results than on a native filesystem.

`claude doctor` shows Search as OK in this case.

**Solutions:**

1.  **Submit more specific searches**: reduce the number of files searched by specifying directories or file types: “Search for JWT validation logic in the auth-service package” or “Find use of md5 hash in JS files”.
2.  **Move project to Linux filesystem**: if possible, ensure your project is located on the Linux filesystem (`/home/`) rather than the Windows filesystem (`/mnt/c/`).
3.  **Use native Windows instead**: consider running Claude Code natively on Windows instead of through WSL, for better file system performance.


[​](#get-more-help)

Get more help

If you’re experiencing issues not covered here:

1.  Run `/doctor` for a setup checkup and `/mcp` to check MCP server status
2.  Use the `/feedback` command within Claude Code to report problems directly to Anthropic
3.  Check the [GitHub repository](https://github.com/anthropics/claude-code) for known issues
4.  Ask Claude directly about its capabilities and features. Claude has built-in access to its documentation.

For account, billing, or subscription problems, contact Anthropic support instead: sign in at [claude.ai](https://claude.ai) (Console users: [platform.claude.com](../04-API-Reference/Other/playground.md)), click your initials in the lower left, and select **Get help**. See [How to get support](../15-Claude-AI-Features/how-to-get-support.md) for the full flow, including who can reach a human agent on each plan.

---

## Plan in the cloud with ultraplan - Claude Code Docs

Source: https://code.claude.com/docs/en/ultraplan
Path: 02-Claude-Code-CLI/ultraplan.md

## On this page

- [Launch ultraplan from the CLI](#launch-ultraplan-from-the-cli)
- [Review and revise the plan in your browser](#review-and-revise-the-plan-in-your-browser)
- [Choose where to execute](#choose-where-to-execute)
  - [Execute on the web](#execute-on-the-web)
  - [Send the plan back to your terminal](#send-the-plan-back-to-your-terminal)
- [Related resources](#related-resources)

Claude Code on the web

# Plan in the cloud with ultraplan

Copy pageCopy page

Start a plan from your CLI, draft it on Claude Code on the web, then execute it remotely or back in your terminal

Copy pageCopy page

Ultraplan is in research preview. Behavior and capabilities may change based on feedback.

Ultraplan hands a planning task from your local CLI to a [Claude Code on the web](claude-code-on-the-web.md) session running in [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode). Claude drafts the plan in the cloud while you keep working in your terminal. When the plan is ready, you open it in your browser to comment on specific sections, ask for revisions, and choose where to execute it. This is useful when you want a richer review surface than the terminal offers:

- **Targeted feedback**: comment on individual sections of the plan instead of replying to the whole thing
- **Hands-off drafting**: the plan is generated remotely, so your terminal stays free for other work
- **Flexible execution**: approve the plan to run on the web and open a pull request, or send it back to your terminal

Ultraplan requires a [Claude Code on the web](claude-code-on-the-web.md) account and a GitHub repository. Because it runs on Anthropic’s cloud infrastructure, it is not available when using Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry. The cloud session runs in your default [cloud environment](cloud-environments.md); use [`/remote-env`](cloud-environments.md#select-an-environment-from-the-cli) in your terminal to change which environment that is. If you don’t have a cloud environment yet, ultraplan creates one automatically when it first launches.


[​](#launch-ultraplan-from-the-cli)

Launch ultraplan from the CLI

From your local CLI session, you can launch ultraplan in three ways:

- **Command**: run `/ultraplan` followed by your prompt
- **Keyword**: include the word `ultraplan` anywhere in a normal prompt
- **From a local plan**: when Claude finishes a local plan and shows the approval dialog, choose **No, refine with Ultraplan on Claude Code on the web** to send the draft to the cloud for further iteration

For example, to plan a service migration with the command:

```python
/ultraplan migrate the auth service from sessions to JWTs
```

The command and keyword paths open a confirmation dialog before launching. The local plan path skips this dialog because that selection already serves as confirmation. If [Remote Control](remote-control.md) is active, it disconnects when ultraplan starts because both features occupy the claude.ai/code interface and only one can be connected at a time. After the cloud session launches, your CLI’s prompt input shows a status indicator while the cloud session works:

| Status                         | Meaning                                                            |
|:-------------------------------|:-------------------------------------------------------------------|
| `◇ ultraplan`                  | Claude is researching your codebase and drafting the plan          |
| `◇ ultraplan needs your input` | Claude has a clarifying question; open the session link to respond |
| `◆ ultraplan ready`            | The plan is ready to review in your browser                        |

Run `/tasks` and select the ultraplan entry to open a detail view with the session link, agent activity, and a **Stop ultraplan** action. Stopping archives the cloud session and clears the indicator; nothing is saved to your terminal.


[​](#review-and-revise-the-plan-in-your-browser)

Review and revise the plan in your browser

When the status changes to `◆ ultraplan ready`, open the session link to view the plan on claude.ai. The plan appears in a dedicated review view:

- **Inline comments**: highlight any passage and leave a comment for Claude to address
- **Emoji reactions**: react to a section to signal approval or concern without writing a full comment
- **Outline sidebar**: jump between sections of the plan

When you ask Claude to address your comments, it revises the plan and presents an updated draft. You can iterate as many times as needed before choosing where to execute.


[​](#choose-where-to-execute)

Choose where to execute

When the plan looks right, you choose from the browser whether Claude implements it in the same cloud session or sends it back to your waiting terminal.


[​](#execute-on-the-web)

Execute on the web

Select **Approve Claude’s plan and start coding** in your browser to have Claude implement it in the same Claude Code on the web session. Your terminal shows a confirmation, the status indicator clears, and the work continues in the cloud. When the implementation finishes, [review the diff](claude-code-on-the-web.md#review-changes) and create a pull request from the web interface.


[​](#send-the-plan-back-to-your-terminal)

Send the plan back to your terminal

Select **Approve plan and teleport back to terminal** in your browser to implement the plan locally with full access to your environment. This option appears when the session was launched from your CLI and the terminal is still polling. The web session is archived so it doesn’t continue working in parallel. Your terminal shows the plan in a dialog titled **Ultraplan approved** with three options:

- **Implement here**: inject the plan into your current conversation and continue from where you left off
- **Start new session**: clear the current conversation and begin fresh with only the plan as context
- **Cancel**: save the plan to a file without executing it; Claude prints the file path so you can return to it later

If you start a new session, Claude prints a `claude --resume` command at the top so you can return to your previous conversation later.


[​](#related-resources)

Related resources

- [Claude Code on the web](claude-code-on-the-web.md): the cloud infrastructure ultraplan runs on
- [Plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode): how planning works in a local session
- [Find bugs with ultrareview](ultrareview.md): the code review counterpart to ultraplan for catching issues before merge
- [Remote Control](remote-control.md): use the claude.ai/code interface with a session running on your own machine

---

## Find bugs with ultrareview - Claude Code Docs

Source: https://code.claude.com/docs/en/ultrareview
Path: 02-Claude-Code-CLI/ultrareview.md

## On this page

- [Run ultrareview from the CLI](#run-ultrareview-from-the-cli)
  - [Review against a different base](#review-against-a-different-base)
  - [Review a pull request](#review-a-pull-request)
  - [Post findings to the pull request](#post-findings-to-the-pull-request)
  - [Pass a request in plain words](#pass-a-request-in-plain-words)
  - [Diff limits and fallbacks](#diff-limits-and-fallbacks)
- [Pricing and free runs](#pricing-and-free-runs)
- [Track a running review](#track-a-running-review)
- [Run ultrareview non-interactively](#run-ultrareview-non-interactively)
  - [Trust the folder before the review runs](#trust-the-folder-before-the-review-runs)
- [How ultrareview compares to /code-review](#how-ultrareview-compares-to-%2Fcode-review)
- [Related resources](#related-resources)

Code review and pull requests

# Find bugs with ultrareview

Copy pageCopy page

Run a deep, multi-agent code review in the cloud with /code-review ultra to find and verify bugs before you merge.

Copy pageCopy page

Ultrareview is a research preview feature. The feature, pricing, and availability may change based on feedback. The command is `/code-review ultra`. When ultrareview is available to your account, `/ultrareview` is an alias.

Ultrareview is a deep code review that runs as a [cloud session](claude-code-on-the-web.md) on Anthropic’s infrastructure. When you run `/code-review ultra`, Claude Code launches a fleet of reviewer agents in a cloud sandbox to find bugs in your branch or pull request. Compared to a local `/code-review`, ultrareview offers:

- **Higher signal**: every reported finding is independently reproduced and verified, so the results focus on real bugs rather than style suggestions
- **Broader coverage**: a larger fleet of reviewer agents explores the change in parallel, which surfaces issues that a local review can miss
- **No local resource use**: the review runs entirely in a cloud sandbox, so your terminal stays free for other work while it runs

Ultrareview requires authentication with a claude.ai account because it runs as a cloud session on Anthropic’s infrastructure. If you are signed in with an API key only, run `/login` and authenticate with claude.ai first. Ultrareview is not available when using Claude Code with Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry, and it is not available to organizations that have enabled Zero Data Retention or have the [HIPAA configuration](hipaa-setup.md) applied. In these cases, `/code-review ultra` runs a local review in your session instead. Organizations that use [customer-managed encryption keys](../04-API-Reference/Other/manage-claude-cmek.md) (CMEK) can’t run ultrareview. To review your changes locally, run `/code-review`.


[​](#run-ultrareview-from-the-cli)

Run ultrareview from the CLI

Start a review from any git repository:

```python
/code-review ultra
```

Without arguments, ultrareview reviews the diff between your current branch and the default branch, including uncommitted and staged changes. For a branch review, Claude Code bundles the repository state and uploads it to a cloud sandbox under the rules for [uploading a local repository to a cloud session](claude-code-on-the-web.md#send-local-repositories-without-github), which cover the size limits, the checkout requirements, and what happens to uncommitted changes in files named like credentials or keys, such as `.env` and `*.tfvars` files. When you [review a pull request](#review-a-pull-request), Claude Code uploads nothing from your machine. Before launching, Claude Code shows a confirmation dialog with the review scope, your remaining free runs, and the estimated cost; for a branch review, the scope includes the file and line count. After you confirm, the review continues in the background while you keep using your session. The command runs only when you invoke it with `/code-review ultra`; Claude doesn’t start an ultrareview on its own.


[​](#review-against-a-different-base)

Review against a different base

To compare against a base other than the default branch, pass the branch name. This example reviews your current branch against `develop` instead:

```python
/code-review ultra develop
```

The base branch doesn’t need to exist in your local clone; Claude Code fetches it from `origin`. If the name has a typo, Claude Code suggests the closest branch name in the error. A commit id or tag also works as the base, and the review then covers the changes on your branch since that commit.


[​](#review-a-pull-request)

Review a pull request

To review a pull request on `github.com` instead of a local branch, pass the PR number:

```python
/code-review ultra 1234
```

The command also accepts `#1234`, `PR 1234`, and pasted PR URLs; a pasted URL must point to the repository in your current directory. PR mode needs a repository on `github.com`. For a repository on a [GitHub Enterprise Server](github-enterprise-server.md) instance, run `/code-review ultra` without a PR number to review your local branch instead. In PR mode, the cloud sandbox clones the pull request from `github.com` instead of uploading your working tree. It uses the GitHub account connected to your Claude account, so that account needs read access to the repository. Run [`/web-setup`](web-quickstart.md#connect-from-your-terminal) to connect your GitHub CLI login to your Claude account.


[​](#post-findings-to-the-pull-request)

Post findings to the pull request

On Claude Code v2.1.227 or later, when you review a pull request on `github.com`, you can have Claude post the finished findings to the PR as a single plain comment from your own GitHub account. The comment isn’t a review or an approval, and it ends with a “Generated by Claude Code” note. When you review a branch, Claude Code shows the findings in your session only. Claude Code never posts unless you choose to on that run, and `--no-post` is the default. Posting is a choice you make for each run:

- **Interactive**: in the launch dialog, select **Run and post the findings to the PR as me**. If you add `--post` to the command, as in `/code-review ultra 1234 --post`, Claude Code preselects that choice and still asks before launching.
- **Non-interactive**: run the [`claude ultrareview` subcommand](#run-ultrareview-non-interactively) with `--post`. You consent to the post by running the subcommand with the flag, so Claude Code posts without asking. In a `claude -p '/code-review ultra'` run, Claude Code exits before the findings arrive, so it posts nothing; use the subcommand instead.

Claude Code doesn’t post from your machine. It sends the review’s session ID to the Anthropic API, which posts the review’s stored findings as the comment through the GitHub account you’ve connected to Claude. Posting requires the same claude.ai sign-in as the review itself, and it isn’t available on third-party providers or when you set [`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`](env-vars.md). In an interactive session, Claude Code starts the post when the findings arrive, so keep the session open until the review finishes. Claude Code keeps the posting choice only in that session. If the session ends before the review finishes, Claude Code posts nothing, even if you resume the conversation later. When the post finishes, Claude tells you the outcome:

- **Posted**: Claude gives you a link to the comment.
- **Already posted**: an earlier post of the same review already put the comment on the PR, so Claude links you to the pull request instead of posting again.
- **Failed**: Claude tells you why, and the findings stay in your terminal so you can post them by hand.


[​](#pass-a-request-in-plain-words)

Pass a request in plain words

On Claude Code v2.1.218 or later, you can also describe what you’re working on in plain words:

```python
/code-review ultra check my auth changes
```

The review still covers your current branch, the same scope as running with no argument. Claude keeps your text as a note, shown in the launch dialog, and relates the findings to it when they arrive. Claude Code treats your text as a note only when it has more than one word and isn’t a branch name or PR reference. It reads a single word as a branch name or PR reference, so a mistyped branch name gets the closest-branch error from [Review against a different base](#review-against-a-different-base) instead of launching with a note. If your text combines a PR reference with other words, such as `check PR 123 again`, Claude Code doesn’t launch either; it asks you to rerun with the PR number alone to review that PR, or without the reference to review your current branch.

If your repository is too large to bundle, Claude Code prompts you to use PR mode instead. For a repository on `github.com`, push your branch and open a draft PR, then run `/code-review ultra <PR-number>`.


[​](#diff-limits-and-fallbacks)

Diff limits and fallbacks

Ultrareview checks the diff before any review work runs and tells you when it can’t review it as-is:

- **Diff too large**: a branch review can include up to 500 changed files and 8,000 changed lines by default. The exact values can change, and the [refusal](errors.md#diff-is-too-large-for-ultrareview) names the ones in effect, the size of your diff, and the files with the most changed lines. Claude Code refuses a too-large pull request the same way, naming its file and line counts but not the per-file breakdown
- **Nothing to review**: when the diff against the base is empty, ultrareview refuses and names the branch or commit it compared against and the case you’re in, such as being on the base branch itself with nothing uncommitted, or a branch whose commits are all part of the base already. It also suggests the way out for that case, such as switching to the branch with your work, staging or committing local edits, or passing a different base
- **First commit**: a repository’s first commit has nothing earlier to compare with, so ultrareview reviews every file in it after you confirm in the launch dialog. If you have untracked files, it refuses instead and tells you to `git add` the ones you want reviewed. The same size limits apply. A first commit is reviewed whole only after that confirmation, so the `claude ultrareview` subcommand and `claude -p` refuse it and point you to an interactive session instead. Requires Claude Code v2.1.277 or later
- **No merge base**: when your branch shares no history with the base branch, or the repository has no base branch to compare with, ultrareview reviews every tracked file in the repository instead. The fallback requires a full clone and applies the same size limits. It launches only when you confirm in the launch dialog or run the `claude ultrareview` subcommand yourself. In `claude -p` and anywhere else neither happens, ultrareview refuses, says the review would cover every file, and points you to an interactive session. On a checkout with no branches or other refs, such as a detached HEAD created by checking out `FETCH_HEAD` after fetching a URL, Claude Code [refuses the review](errors.md#your-checkout-has-no-branches) and suggests creating a branch first


[​](#pricing-and-free-runs)

Pricing and free runs

Ultrareview is a premium feature that bills against usage credits rather than your plan’s included usage.

| Plan | Included free runs | After free runs                                                                                              |
|------|--------------------|--------------------------------------------------------------------------------------------------------------|
| Pro  | 3 free runs        | billed as [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md) |
| Max  | 3 free runs        | billed as [usage credits](../17-Billing-Plans/extra-usage-for-paid-claude-plans.md) |

- **Free runs**: the three Pro and Max runs are a one-time allotment per account and don’t refresh.
- **Cost per review**: after you use the free runs, typically \$5 to \$25 in usage credits depending on the size of the change, matching the estimate the launch dialog shows before each run.
- **When a run counts**: once the cloud session starts. A review you stop early or that fails to complete still uses a free run; a paid review bills only for the portion that ran.

Because ultrareview always bills as usage credits outside the free runs, your account or organization must have usage credits turned on before you can launch a paid review. If usage credits aren’t turned on, Claude Code blocks the launch. If you can manage billing for your account, Claude Code links you to the billing settings where you can turn on usage credits. You can also run `/usage-credits` to check or change your usage-credits setting. Claude Code asks you to confirm usage-credits billing once per conversation: when you start a new conversation, for example with `/clear`, Claude Code shows the confirmation again for the next paid review.


[​](#track-a-running-review)

Track a running review

A review typically takes 15 to 25 minutes. The review runs as a background task, so you can keep working in your session or start other commands. If you chose to [post the findings to the pull request](#post-findings-to-the-pull-request), keep the session open until the review finishes; if the session ends first, Claude Code posts nothing. Use `/tasks` to see running and completed reviews, open the detail view for a review, or stop a review that is in progress. If you stop a review, Claude Code archives the cloud session and doesn’t return partial findings. Claude can also tell you that a review was stopped or that its session wasn’t found:

- If the review’s cloud session is stopped or [archived](claude-code-on-the-web.md#archive-sessions) on claude.ai before the review finishes, Claude tells you it was stopped.
- If the review’s cloud session was deleted, or you’ve signed in to a different Claude account or organization since launching it, Claude tells you the session wasn’t found.
- If you switched accounts, the review may still finish under the account that started it. If the review is still running, sign back in as that account and resume the conversation with `claude --resume` to re-attach it.

When the review finishes, Claude Code shows the verified findings as a notification in your session. Each finding includes the file location and an explanation of the issue so you can ask Claude to fix it directly.


[​](#run-ultrareview-non-interactively)

Run ultrareview non-interactively

Use the `claude ultrareview` subcommand to start an ultrareview from CI or a script without an interactive session. The subcommand launches the same review as `/code-review ultra`, blocks until the remote review finishes, and prints the findings to stdout. If the run exits with `Error: Workspace not trusted`, see [Trust the folder before the review runs](#trust-the-folder-before-the-review-runs).

```python
claude ultrareview
claude ultrareview 1234
claude ultrareview origin/main
```

Without arguments, the subcommand reviews the diff between your current branch and the default branch, with the same [whole-repository fallback](#diff-limits-and-fallbacks) as `/code-review ultra` when no merge base exists. Pass a PR number to [review a pull request on `github.com`](#review-a-pull-request), or a base branch to review against it; [base-branch handling](#review-against-a-different-base) matches the interactive command. You consent to the whole-repository fallback and to the billing and terms prompt when you run the subcommand, so the run doesn’t stop to confirm them. Running it yourself is what counts as consent. When Claude runs the subcommand for you instead, for example through the Bash tool, Claude Code refuses the whole-repository review. `claude -p '/code-review ultra'` doesn’t get you the findings, so use `claude ultrareview` in scripts. The `-p` run launches the cloud review and exits without waiting for it. When the review would bill usage credits, the `-p` run stops without launching it. Before v2.1.218, `/code-review ultra` in a non-interactive session ran a local review.

| Flag                  | Description                                                                                                                                                                                                                                                                        |
|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `--json`              | Print the raw `bugs.json` payload instead of the formatted findings                                                                                                                                                                                                                |
| `--timeout <minutes>` | Maximum minutes to wait for the review to finish. Defaults to 45                                                                                                                                                                                                                   |
| `--post`              | [Post the finished findings](#post-findings-to-the-pull-request) to the pull request as one plain comment from your GitHub account. Works on `github.com` pull request targets; on other targets, Claude Code ignores the flag and says so. Requires Claude Code v2.1.227 or later |
| `--no-post`           | Don’t post the findings. This is the default, and if you pass both flags, Claude Code doesn’t post. Requires Claude Code v2.1.227 or later                                                                                                                                         |
| `--trust-workspace`   | [Trust the current folder](#trust-the-folder-before-the-review-runs) for this run only, without asking, so a script or CI job can review a checkout you haven’t trusted. Takes no value: put a PR number or base branch before it. Requires Claude Code v2.1.309 or later          |

`claude ultrareview` writes its progress messages to stderr so stdout stays parseable. Running `claude ultrareview` requires the same authentication and usage-credits configuration as `/code-review ultra`. The subcommand exits with one of three codes:

- **0**: the review completed, with or without findings
- **1**: the review failed to launch or was stopped before it finished, the cloud session errored, or the timeout elapsed. The code is also 1 when the [folder isn’t trusted](#trust-the-folder-before-the-review-runs), including when you answer `n` or press Ctrl-C at the trust question.
- **130**: you pressed Ctrl-C while the subcommand was launching the review, waiting for the findings, or sending the `--post` comment, rather than at the trust question

If the subcommand exits before the findings arrive, they never reach your terminal. The review may still be running in the cloud. Running the subcommand again starts a new review rather than resuming that one, and the new review [uses a free run or bills as usage credits](#pricing-and-free-runs). With `--post`, the subcommand starts the post right after printing the findings, and prints the link to stderr.

- If the run fails, is stopped, or times out, the subcommand posts nothing.
- If the review completes but the comment isn’t posted, Claude Code prints the reason to stderr, and the findings stay on stdout so you can post them by hand.

For automatic reviews on GitHub pull requests, [Code Review](code-review.md) integrates with your repository directly and posts findings as inline PR comments without a CLI step.


[​](#trust-the-folder-before-the-review-runs)

Trust the folder before the review runs

When `claude ultrareview` asks `Trust <folder>? [y/N]`, answer `y` to [trust the folder](permissions.md#project-allow-rules-and-workspace-trust). Trust it only if you trust its code, because git and Claude Code can then run programs named in its git configuration and project settings. When it can’t ask you, such as in a CI job or with output sent to a file, it exits with [`Error: Workspace not trusted`](errors.md#workspace-not-trusted-when-running-claude-ultrareview). Append `--trust-workspace` to trust the folder for that run:

```python
claude ultrareview 1234 --trust-workspace
```

To review an untrusted pull request, run `claude ultrareview <PR number> --trust-workspace` from a branch you trust. Unlike `y`, the flag saves nothing. The PR is [cloned in the cloud](#review-a-pull-request), so you don’t need its branch locally.


[​](#how-ultrareview-compares-to-/code-review)

How ultrareview compares to /code-review

Both reviews examine code, but you use them at different stages of your workflow.

|          | `/code-review`                                         | `/code-review ultra`                                            |
|----------|--------------------------------------------------------|-----------------------------------------------------------------|
| Target   | your working diff, a pull request, a branch, or a path | your working diff or a pull request                             |
| Runs     | locally in your session                                | in a cloud sandbox                                              |
| Depth    | scales with the effort argument                        | multi-agent fleet with independent verification                 |
| Duration | seconds to a few minutes                               | roughly 15 to 25 minutes                                        |
| Cost     | counts toward normal usage                             | free runs, then roughly \$5 to \$25 per review as usage credits |
| Best for | quick feedback while iterating                         | pre-merge confidence on substantial changes                     |

Use `/code-review` for fast feedback as you work, or pass a PR number to review a teammate’s pull request before approving it. Use `/code-review ultra` before merging a substantial change when you want a deeper pass that catches issues a local review might miss.


[​](#related-resources)

Related resources

- [Use Claude Code in the cloud](claude-code-on-the-web.md): learn how cloud sessions and cloud sandboxes work
- [Manage costs effectively](../17-Billing-Plans/costs.md): track usage and set spending limits

---

## Use Claude Code CLI with a screen reader | Claude Help Center

Source: https://support.claude.com/en/articles/15924927-use-claude-code-cli-with-a-screen-reader
Path: 02-Claude-Code-CLI/use-claude-code-cli-with-a-screen-reader.md

# Use Claude Code CLI with a screen reader

July 13, 2026


The screen reader mode brings Claude Code back to the basic terminal experience: plain, sequential text with added labels and cues and no visual embellishments. It was built with and for screen reader users, and it's useful to anyone who wants plain output for braille displays, slow connections, or transcripts.

## Turn on the screen reader mode

The screen reader mode requires Claude Code version 2.1.181 or later and it can be enabled in multiple ways:

- For one session: run `claude --ax-screen-reader`

- For every session in a terminal: set the environment variable `CLAUDE_AX_SCREEN_READER=1`

- Permanently: add `"axScreenReader": true` to your Claude Code settings file (`~/.claude/settings.json`)

The first line of the session announces that the screen reader mode is on. In Claude Code v2.1.206 and later it announces: `[Screen Reader Mode: on via flag]` (or `via env` / `via settings`).

## What to expect

- **Your prompts and Claude’s responses are labeled.** Your messages start with `you:` and Claude's replies start with `claude:`. Tool activity starts with `tool:` and permission prompts with `Permission Required:`. The labels are also searchable, so you can use your terminal's search to jump between parts of the conversation.

- **Menus become numbered lists.** Instead of moving a highlight with the arrow keys, you hear each option as a numbered line, then type the number of the option you want and press Enter. For yes-or-no prompts, type `y` or `n` and press Enter.

- **Visual decorations are removed.** Spinners, progress animations, and in-place redraws become plain text that reads in order, and decorative characters such as box-drawing lines are removed.

- **A terminal bell tells you when Claude needs you.** You'll hear your terminal's alert sound when Claude finishes a reply, when a permission prompt appears, and when a long-running tool finishes. If you don't hear it, check the bell setting in your terminal application—some terminals keep the alert sound off by default. Claude Code's own notification channel can be set with `/config` under notifications.

To explore comprehensive documentation regarding line markers, list navigation, and existing constraints, visit the **[Accessibility section of the Claude Code guide](accessibility.md)**.

## Report an issue

​​If something doesn't work with your screen reader or terminal, open an issue at **[the Claude Code GitHub repository](https://github.com/anthropics/claude-code/issues)** and mention your screen reader in the title. Please include your operating system, terminal application, and screen reader name and version.

**Note:** One setting that's easy to mix up: `CLAUDE_CODE_ACCESSIBILITY=1` is a different, unrelated setting—it keeps the terminal cursor visible for screen magnifiers and does not turn on screen reader mode. For a screen reader, use the methods above.

---

## Use Claude Code in the cloud | Claude Help Center

Source: https://support.claude.com/en/articles/12618689-use-claude-code-in-the-cloud
Path: 02-Claude-Code-CLI/use-claude-code-in-the-cloud.md

# Use Claude Code in the cloud


A cloud session is a Claude Code session that runs on cloud infrastructure instead of on your machine, working with code from your GitHub repositories. You can start one from Claude Code on the web at claude.ai/code, from Claude Mobile, from Claude Desktop, or from your terminal with `claude --cloud`. This article explains how cloud sessions work, when to use them instead of a local session in your terminal or IDE, and what workflows they enable.

## What cloud sessions provide

Cloud sessions let you delegate tasks to Claude that run without your active supervision. You select a GitHub repository, describe what you want done, and Claude works on the task in the cloud. Once Claude Code has started working on a task, you can leave the page completely; Claude will continue its work. When finished, Claude will automatically create a pull request with changes for you to review.

This feature works with repositories you may not have on your local machine. You can kick off tasks on any GitHub repository you have access to without needing to clone it locally or set up a development environment. This makes it useful for projects you contribute to occasionally or for exploring codebases you're still learning about.

Cloud sessions enable asynchronous development workflows. In a local session in your terminal or editor, you typically work synchronously: you make a request, wait for Claude to respond, review the changes, then make another request. Synchronous work like this gives you fine-grained control but requires your attention throughout the process. A cloud session handles this differently: you can assign a larger task, let Claude work independently, and return later to review the completed work.


You can also run multiple tasks in parallel. Since each task runs in its own isolated environment, you can have Claude working on several different issues or repositories simultaneously. Each task proceeds independently and creates its own pull request when complete. More than one task can work on the same repository at the same time.

------------------------------------------------------------------------

## How it works

When you start a cloud session, Claude Code creates an isolated virtual machine for your work. Your GitHub repository is cloned into this environment, which comes pre-configured with common development tools and language ecosystems.


Claude prepares the environment by running any setup commands you've defined in your repository's configuration. This includes installing dependencies, setting up databases, or running other initialization steps your project needs. If your task requires network access, maybe to install packages or fetch data, you can configure the level of internet access the environment has.

Once the environment is ready, Claude begins working on your task. Claude reads your code, makes changes, writes tests, and runs commands to verify the work. You can monitor progress and provide guidance through the web interface if needed.


When Claude completes the task, it pushes the changes to a new branch in your GitHub repository. You receive a notification and can review the changes, then create a pull request directly from the interface. The pull request includes all of Claude's work, ready for your review and any additional changes you want to make.

Each task runs in complete isolation. The virtual machine exists only for that specific task and includes security controls like restricted network access and protected credential handling. Your GitHub authentication is managed through a secure proxy, so credentials never exist directly in the environment where Claude is working.

------------------------------------------------------------------------

## When to use cloud sessions vs. local sessions

Some tasks are well suited to running asynchronously in the cloud, while others are best run locally in your terminal or IDE.

### Use cloud sessions for:

- **Well-defined tasks with clear requirements:** When you can describe exactly what needs to be done and don't expect to need to steer Claude mid-task, a cloud session lets you start the work and return when it's complete.

- **Background work on bug backlogs:** You can assign Claude multiple issues from your backlog and let them run in parallel. Each task proceeds independently, allowing you to tackle several fixes at once without monitoring each one individually.

- **Repositories you don't have locally:** If you need to make changes to a repository you haven't cloned or don't want to set up on your machine, a cloud session handles the environment setup for you.

- **Tasks you want to queue up:** When you have a list of changes to make but don't want to work on them right now, you can start them in the cloud and review the results later. This lets you batch similar work or delegate tasks during times when you're focused on something else.

### Use local sessions in your terminal or IDE for:

- **Tasks needing frequent course correction:** When you're not sure exactly what the right approach is or expect you'll need to redirect Claude based on what you see, working in your terminal gives you immediate feedback. You can adjust direction as Claude works rather than waiting for a complete result.

- **Exploratory work with unclear requirements:** If you're figuring out how to solve a problem or investigating different approaches, the terminal lets you refine your request as you learn. The back-and-forth helps clarify requirements that weren't obvious at the start.

- **Local development with uncommitted changes:** When you're actively developing and have uncommitted work in your local repository, using Claude Code in your terminal keeps everything in one place. You can iterate quickly on changes without needing to commit or push work that isn't ready yet.

- **Tasks requiring immediate feedback:** If you need to see results quickly and want to iterate rapidly, the terminal provides lower latency. You can watch Claude work in real-time and stop or redirect if something goes wrong early in the process.

------------------------------------------------------------------------

## Example use cases

### Backend changes with test-driven development

Let Claude write tests that define the expected behavior, then implement the code to make those tests pass. This works particularly well for backend changes where behavior can be validated through automated testing.

**Example prompt:**

    Add rate limiting to the /api/search endpoint. 

    The rate limiter should: 
    - Allow 100 requests per minute per API key 
    - Return 429 status when limit exceeded 
    - Reset limits after 60 seconds 
    - Track different API keys independently 

    Use a TDD approach: write comprehensive tests first, then implement the rate limiting logic to pass them.

**When to use this approach:** This works well in a cloud session because the tests give Claude clear validation criteria to work towards. You don't need to monitor Claude's progress since the tests will catch issues and guide iteration toward a working solution. The self-contained nature of the task, where Claude writes tests then makes them pass, doesn't require your input once started.

**What makes this effective:** Claude can iterate on the implementation without your supervision, using test failures to identify and fix problems. The task runs longer than a simple code change, but you can let it complete in the background. When you review the pull request, both the tests and implementation are ready, and you have confidence the solution works because the tests pass.

### Documentation updates

Generate or update technical documentation such as README files, API documentation, code comments, or user guides.

**Example prompt:**

    Update CHANGELOG.md with all changes since the v2.3.0 release:
      - Review commits on main branch since that tag. 
      - Categorize changes into "Added, "Changed, "Fixed", and "Removed" sections. 
      - Include the commit hash for each entry.

**When to use this approach:** Changelog updates are well suited to a cloud session because Claude can review commit history independently and format entries without guidance. The task is tedious to do manually but straightforward enough that Claude can complete it without questions about which commits to include or how to categorize them.

**What makes this effective:** You can delegate the entire changelog update and review the result when complete. Claude reads through commits, extracts meaningful changes, and follows your existing changelog format.

### Refactoring with clear scope

Restructure code to improve organization or readability when you can define clear boundaries for the change. This includes extracting code, splitting up large files, or organizing module structure.

**Example prompt:**

    The UserService class in /src/services/user.go has 800 lines long.
    Split it into three focused services: 
      - UserAuthService (login/logout/sessions) 
      - UserProfileService (profile CRUD operations)
      - UserPreferencesService (settings/preferences)

    Ensure all tests still pass.

**When to use this approach:** Refactoring with clear constraints works well in a cloud session because you can set clear boundaries for Claude to follow. Test suites can provide validation, allowing Claude to verify the refactor didn't break any existing functionality.

**What makes this effective:** The task takes time, but doesn't need your active input once the structure is defined. You can start the refactor and review the organized result later, rather than monitoring Claude as it works through the task. The clear scope means Claude is unlikely to need guidance mid-task.

------------------------------------------------------------------------

## Tips for effective use

- Consider adding a test suite to your repository so Claude more easily verify that it has successfully completed a task

- Specify success criteria rather than vague goals like "improve" or "fix"

- Define what should change and what should stay the same in your prompt

- Scope tasks with clear boundaries so Claude doesn't need guidance mid-task

- If you're thinking "I'll need to see how this goes first," consider using your terminal instead

- Use "Open in CLI" if you realize mid-task that you need to provide guidance

---

## Use skills in Claude | Claude Help Center

Source: https://support.claude.com/en/articles/12512180-using-skills-in-claude
Path: 02-Claude-Code-CLI/using-skills-in-claude.md

# Use skills in Claude

September 22, 2026


Skills extend Claude's capabilities by giving it access to specialized knowledge and workflows. This guide shows you how to enable, discover, and use skills in Claude.

Skills are available for users on Free, Pro, Max, Team, and Enterprise plans. This feature requires **[code execution to be enabled](../15-Claude-AI-Features/create-and-edit-files-with-claude.md#h_1c99382190)**. Skills are also available in Claude Code, and in beta for all API users using the code execution tool.

## Prerequisites

**For Enterprise plans:** Owners must check that both **Code execution and file creation** and **Skills** are enabled in **[Organization settings \> Plugins & skills](https://claude.ai/admin-settings/skills)** in the “Policy” tab. Owners can also upload skills to provision them organization-wide—these skills automatically appear for all users. Once skills are enabled at the organization level, individual members can toggle on example skills, access provisioned skills, and upload their own personal skills in **[Customize \> Skills](https://claude.ai/customize/skills)**.

**For Team plans:** This feature is enabled by default at the organization level. Once enabled, individual members can toggle on example skills and upload their own in **[Customize \> Skills](https://claude.ai/customize/skills)**.

**For Max, Pro, and Free plans:** You can enable example skills and upload your own in **[Customize \> Skills](https://claude.ai/customize/skills)**.

------------------------------------------------------------------------

## How to enable skills

1.  For Team / Enterprise plans: Navigate to **[Organization settings \> Plugins & skills](https://claude.ai/admin-settings/skills)**, click the “Policy” tab, and ensure that both **Cloud code execution and file creation** and **Skills** are enabled.

2.  For individual Free, Pro, and Max plans: Navigate to **[Settings \> Capabilities](https://claude.ai/settings/capabilities)** and ensure that **Code execution and file creation** is enabled.

3.  Go to **[Customize \> Skills](https://claude.ai/customize/skills)**.

4.  Toggle individual skills on or off as needed.

## Provision skills organization-wide

Owners of Team and Enterprise organizations can provision skills for all users. These skills appear in your individual Skills list with a team indicator—you can toggle them on or off based on your preferences. For information on provisioning skills for your organization, see **[Provision and manage skills for your organization](../15-Claude-AI-Features/provisioning-and-managing-skills-for-your-organization.md#h_4dea113421)**.

## Use Anthropic skills

Anthropic provides several built-in skills that are available to all users, including:

- Enhanced Excel spreadsheet creation and manipulation

- Professional Word document creation

- PowerPoint presentation generation

- PDF creation and processing

With **Code execution and file creation** on, Claude will automatically use these tools when relevant. You don't need to explicitly invoke them—Claude determines when each skill is needed based on your request.

For example, if you ask Claude to "Create a PowerPoint presentation about Q3 results," Claude will automatically use the PowerPoint skill if the capability is enabled.

## Add and use custom skills

You can also create and upload your own skills to teach Claude your specific workflows:

1.  Create a skill following the skill structure (see **[How to create custom skills](https://support.claude.com/en/articles/12512198-creating-custom-skills)** for detailed instructions).

2.  Package your skill folder as a ZIP file.

3.  Navigate to **[Customize \> Skills](https://claude.ai/customize/skills)**.

4.  To add custom skills, click the "+" button, then “+ Create skill.”

5.  Select "Upload a skill.”

6.  Upload a ZIP file containing your skill folder.

7.  Your skill will appear in your skills list and can be toggled on or off.

**Note:** Custom skills you upload aren't visible to colleagues until you share them. Admins can see their names and sharing status, but not their files On Team and Enterprise plans, you can share skills (see **Share a skill** below), or provision skills for your organization. Learn more about **[provisioning skills for your organization](https://support.claude.com/en/articles/13119606-managing-skills-as-an-admin#h_4dea113421)**.

------------------------------------------------------------------------

## Share a skill

On Team and Enterprise plans, you can share skills you've created with specific colleagues, groups. To make a skill available to your entire organization, publish it instead. Skill sharing works in both chat and Cowork.

**Note:** The **Skill sharing** toggle is on by default for Team plans and for Enterprise plans that haven't set a skills preference. For organizations with HIPAA readiness or other regulated configurations, skills and skill sharing are off by default and an admin can enable them. The **Share with organization** and **Share with groups** toggles are also off by default. An owner must navigate to **[Organization settings \> Plugins & skills](https://claude.ai/admin-settings/skills)**, click the “Policy” tab, and enable at least one of the toggles before the "Share" button appears. If your organization uses custom roles, your role must also have the **Share skills with groups** capability enabled. If you don't see the option to share, check with your organization owner.

To share a skill:

1.  Navigate to **[Customize \> Skills](https://claude.ai/customize/skills)**.

2.  Find the skill you created.

3.  Click the three-dot menu (...) next to it, then select "Share."

4.  Choose who to share with:

    - **Specific people:** Enter names or emails to share directly. Sharing creates a link that opens the item for anyone it's shared with. The skill appears in each recipient's skills list, grayed out until they enable it, and shows your name as the owner.

    - **A group (Enterprise plans only):** Share with a group your organization has already set up. The skill appears in every group member's skills list, grayed out until they enable it. Requires the **Share with groups** toggle.

5.  Click "Share."

Shared skills are view-only. Recipients can enable and use the skill, but they can't edit the contents. If you update the skill later, recipients automatically get the updated version at next use. You can remove someone's access at any time, and access is removed automatically if they leave the organization.

------------------------------------------------------------------------

## Publish a skill to your organization

On Team and Enterprise plans, you can submit a skill you've created to your organization's library, so anyone in your organization can install it. Sharing gives a skill to specific people or groups, and you keep control of it. Publishing hands it to your organization.

To publish a skill:

1.  Navigate to **[Customize \> Skills](https://claude.ai/customize/skills)**.

2.  Open the skill you want to publish.

3.  Click "Publish to org."

4.  If your organization requires review, choose how you'd like the skill offered: Available to install, Installed by default, or Required. Add release notes for the reviewer if you'd like, then submit.

If your organization requires review, an owner (or someone with permission to review requests) checks the skill before it's published. Your choice of how it's offered is a proposal. The reviewer sees it preselected and can change it, and they also choose who gets the skill: everyone or specific groups. You can keep using and editing your copy while you wait, and you can withdraw the submission. The skill shows its status: pending, changes requested (with the reviewer's note), or published. You'll get an email when it's approved. If your organization doesn't require review, the skill is published to the library and available to everyone in your organization to install. If your organization has security scanning turned on, the skill isn't listed for others until it passes the scan, which usually takes a few minutes.

Once published, the skill is managed by your organization. To update it, publish again. The new version goes through the same review, and everyone who uses the skill stays on the approved version until the update is approved.

------------------------------------------------------------------------

## Use skills shared with you

On Team and Enterprise plans, your skills list in **[Customize \> Skills](https://claude.ai/customize/skills)** is organized into three sections:

- **Personal skills:** Skills you've created or uploaded yourself.

- **Shared with you:** Skills colleagues have shared with you directly. These stay off until you turn them on.

- **Organization skills:** Skills published to your organization and skills your owner has provisioned. You install these from the directory rather than enabling them from the list.

### Enable a skill shared with you directly

1.  Find the skill in the **Shared with you** section of your skills list.

2.  Toggle it on.

You can toggle the skill off again at any time, or delete it from your list entirely if you don't want it.

### Install a skill from your organization's directory

1.  In Cowork, click **Customize** in the left sidebar, then click the "+" button to open the directory.

2.  Click the **Skills** tab.

3.  Find the skill you want and click "Install."

Skills you install from the directory can be toggled off, which removes them from your sidebar. They remain in the directory so you can re-enable them later. For more on browsing the directory, see **[Browse skills, connectors, and plugins in one directory](../14-Connectors/browse-skills-connectors-and-plugins-in-one-directory.md)**.

------------------------------------------------------------------------

## Use skills in Microsoft 365 add-ins

Skills you've enabled in your Claude settings are also available in the Claude for Excel, PowerPoint, Word, and Outlook add-ins. Claude applies relevant skills automatically while you work—you don't need to invoke them separately.

**How triggering works in the add-ins:**

- Type `/` in the sidebar to see available skills and select one (for example, `/debug` or `/deck-check`).

- Or describe your task naturally—Claude recognizes when a skill applies and uses it.

Claude adapts skills to the surface it’s in. A research skill may produce a Word document in Cowork, but detailed data breakdowns in Excel. Some skills may work better on one surface than others. If you let Claude work across apps, Claude can orchestrate another app to apply the skill. If you build a skill with a specific Excel or PowerPoint template, Claude for Excel and Powerpoint can load that template exactly into the current open file.

------------------------------------------------------------------------

## Use skills in Claude Code

Skills you've enabled in your Claude settings also load in Claude Code in your terminal when you sign in with the same Claude account. This includes skills you created or turned on and skills an owner provisioned for your organization. It needs Claude Code v2.1.273 or later.

Run `/skills` in Claude Code to see them listed under **claude.ai sync**.

- Skills sync when a Claude Code session starts, then check for changes about every 10 minutes.

- The sync is one-way. It reads from your Claude account and never changes anything in it.

- Skills don't sync when Claude Code is signed in with an API key or runs on a cloud provider such as Amazon Bedrock.

To stop skills from syncing, set `syncClaudeAiSkills` to `false` in your Claude Code settings. Learn more about **[how synced skills behave](../08-Plugins-Skills/skills.md#how-synced-skills-behave)** in the Claude Code docs.

------------------------------------------------------------------------

## Manage your skills

### View your skills

All your skills are listed in **[Customize \> Skills](https://claude.ai/customize/skills)**. You can see:

- Anthropic skills (created, tested, and maintained by Anthropic)

- Custom skills you've uploaded

- When each skill was enabled or uploaded

- A brief description of what each skill does

### Enable/disable your skills

Toggle any skill on or off using the switch next to it. Disabled skills won't be available to Claude.

### Delete custom skills

To remove a custom skill you've uploaded:

1.  Navigate to **[Customize \> Skills](https://claude.ai/customize/skills)**.

2.  Find the skill in your skills list and click on it to view the details.

3.  Use the toggle in the upper right corner to disable the skill.

4.  To delete the custom skill entirely, click the "..." button next to the toggle, then select "Delete":


5.  Click "Delete" in the confirmation prompt.

If you change your mind, you can add the skill again by re-uploading the file.

------------------------------------------------------------------------

## Privacy and security details

For Team and Enterprise plans, organization owners can provision skills for all users through organization settings. Individuals can share skills with colleagues if an owner has enabled sharing, or publish them to the organization if an owner has turned on publishing. On all other plans, each person uploads skills to their own account.

Note that skills may include, or instruct Claude to install, third-party packages and software for Claude to use when completing a task. See **[our guidance on Claude's container environment](../15-Claude-AI-Features/create-and-edit-files-with-claude.md#h_0ee9d698a1)** for details on Claude's container environment and **[the API documentation](https://docs.claude.com/en/docs/agents-and-tools/tool-use/code-execution-tool#containers)** for API's container environment.

**Note:** If you're on the Enterprise plan and your organization has skill scanning turned on, each third-party skill you upload or edit is checked for malicious content before it can run. Most scans finish in about one to two minutes. If a skill is blocked, you can't use it until you fix what was flagged and upload it again. Learn more about **[skill and plugin scanning](https://support.claude.com/en/articles/15927065)**.

### What are the primary risks of using skills?

The most significant risks are prompt injection, which allows Claude to be manipulated to execute unintended actions, and data exfiltration, caused by malicious package code or prompt-injected data leaks. We’ve implemented several mitigations to these risks. Refer to **[our security considerations for code execution](../15-Claude-AI-Features/create-and-edit-files-with-claude.md#h_0ee9d698a1)** for more information.

**Important:** Only install skills only from trusted sources.

When installing a skill from a less-trusted source—including one shared by a colleague—review it before enabling. Start by reading the contents of the files bundled in the skill to understand what it does, paying particular attention to code dependencies and bundled resources like images or scripts. Similarly, pay attention to instructions or code within the skill that instruct Claude to connect to potentially untrusted external network sources.

------------------------------------------------------------------------

## Troubleshooting

### Skills section not visible

Ensure code execution is enabled in **[Settings \> Capabilities](https://claude.ai/settings/capabilities)** (Free, Pro, Max) or **[Organization settings \> Plugins & skills](https://claude.ai/admin-settings/skills)** in the “Policy” tab (Team, Enterprise). Then navigate to **[Customize \> Skills](https://claude.ai/customize/skills)** to access your skills. Skills require the code execution environment to function.

### Claude isn’t using a skill

- Verify the skill is toggled on in **[Customize \> Skills](https://claude.ai/customize/skills)**.

- Check that the skill's description field clearly explains when it should be used.

- Ensure the skill's instructions are clear and well-structured.

- Try being more explicit in your request (e.g., "Use my brand guidelines skill to create a presentation").

### Can't create or upload a skill

On Team and Enterprise plans, an organization owner can turn off skill creation for users. If the option to create or upload a skill is missing, your organization may have **User-created skills** turned off, or—on Enterprise plans with custom roles—your role may not include the **Create skills** capability. You can still enable and use skills your owner has provisioned. Contact your organization owner if you need to create your own.

### Skills greyed out

If skills appear greyed out, code execution may be disabled at the organization level (for Team and Enterprise plans) or individually. Check with your organization's Owner (Team, Enterprise) or make sure to enable code execution in **[Settings \> Capabilities](https://claude.ai/settings/capabilities)** (Free, Pro, Max).

### Upload errors

Common reasons for upload failures:

- ZIP file exceeds size limits

- Skill folder name doesn't match the skill name

- Missing required skill.md file

- Invalid characters in skill name or description

### Group doesn't appear when I try to share a skill

The group needs the **Share resources with this group** visibility setting turned on by an organization owner. Contact your organization owner if a group you expect to see is missing.

### Share button not visible

The **Skill sharing** toggle is on by default for Team plans and for Enterprise plans that haven't set a skills preference. For organizations with HIPAA readiness or other regulated configurations, skills and skill sharing are off by default and an admin can enable them. The **Share with organization** and **Share with groups** toggles are also off by default. An owner must navigate to **[Organization settings \> Skills](https://claude.ai/admin-settings/skills)** and enable at least one of the toggles before the "Share" button appears. If your organization uses custom roles, your role must also have the **Share skills with groups** capability enabled. If you don't see the option to share, check with your organization owner.

### "Publish to org" button not visible

Your organization's **Publishing** setting may be turned off, or the skill may not be one you created. You can't publish skills that were shared with you, Anthropic's built-in skills, or skills you installed from your organization's library. If it's your own skill and you don't see the button, check with your organization owner.

------------------------------------------------------------------------

## Best practices

**Start simple.** Begin with Anthropic's pre-built skills to understand how they work before creating custom skills.

**Be specific.** Write clear descriptions when writing custom skills. A specific description tells Claude when to invoke your skill.

**Test your skills.** After uploading a custom skill, test it with a few different prompts to ensure it works as expected.

**Organize by purpose.** Create separate skills for different purposes rather than a single skill that’s meant to do everything.

------------------------------------------------------------------------

## Learn more about using skills

For more information and video demonstrations, refer to **[Teach Claude your way of working using skills](https://claude.com/resources/tutorials/teach-claude-your-way-of-working-using-skills).**

---

## Voice dictation - Claude Code Docs

Source: https://code.claude.com/docs/en/voice-dictation
Path: 02-Claude-Code-CLI/voice-dictation.md

## On this page

- [Requirements](#requirements)
- [Enable voice dictation](#enable-voice-dictation)
- [Hold to record](#hold-to-record)
- [Tap to record and send](#tap-to-record-and-send)
- [Cancel a recording](#cancel-a-recording)
- [Change the dictation language](#change-the-dictation-language)
- [Rebind the dictation key](#rebind-the-dictation-key)
- [Troubleshooting](#troubleshooting)
  - [Terminal not listed in macOS Microphone settings](#terminal-not-listed-in-macos-microphone-settings)
- [See also](#see-also)

Interface

# Voice dictation

Copy pageCopy page

Speak your prompts in the Claude Code CLI with hold-to-record or tap-to-record voice dictation.

Copy pageCopy page

Speak your prompts instead of typing them in the Claude Code CLI. Your speech is transcribed live into the prompt input, so you can mix voice and typing in the same message. Enable dictation with `/voice`, then either hold a key while you speak or tap once to start and again to send. In [hold mode](#hold-to-record), dictation also works in [agent view](../09-Agents-Patterns/agent-view.md#peek-and-reply). Hold your push-to-talk key while the dispatch input or a peek-panel reply is focused to dictate to a background session.


[​](#requirements)

Requirements

Voice dictation streams your recorded audio to Anthropic’s servers for transcription. Audio is not processed locally. It needs all of the following:

- **A Claude.ai account**: the speech-to-text service is only available when you authenticate with one, and is not available when Claude Code is configured to use an Anthropic API key directly, Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry.
- **A local microphone**: voice dictation does not work in [cloud sessions](claude-code-on-the-web.md) or SSH sessions.
- **WSLg, if you run Claude Code in WSL**: WSLg is included with WSL2 when installed from the Microsoft Store on Windows 10 or 11. If WSLg is not available, for example on WSL1, run Claude Code in native Windows instead.

Transcription does not consume Claude messages or tokens and does not count toward the limits shown in `/usage`. See [data usage](../13-Enterprise-Admin/data-usage.md) for how Anthropic handles your data. Audio recording uses a built-in native module on macOS, Linux, and Windows. On Linux, if the native module cannot load, Claude Code falls back to `arecord` from ALSA utils or `rec` from SoX. If neither is available, `/voice` prints an install command for your package manager. The Claude Code [VS Code extension](../03-IDE-Integrations/vs-code.md) also supports voice dictation with the same claude.ai account requirement. It is not available in VS Code Remote sessions, including SSH, Dev Containers, and Codespaces, because the microphone is on your local machine and the extension runs on the remote host.


[​](#enable-voice-dictation)

Enable voice dictation

Run `/voice` to enable dictation. When you enable it, Claude Code runs a microphone check. On macOS, this triggers the system microphone permission prompt for your terminal if it has never been granted.

```python
/voice
Voice mode enabled (hold). Hold space to record. Dictation language: en (/config to change).
```

`/voice` accepts an optional mode argument:

| Command       | Effect                                        |
|:--------------|:----------------------------------------------|
| `/voice`      | Toggle on or off, keep the current mode       |
| `/voice hold` | Enable in [hold mode](#hold-to-record)        |
| `/voice tap`  | Enable in [tap mode](#tap-to-record-and-send) |
| `/voice off`  | Disable                                       |

Voice dictation persists across sessions. Set it directly in your [user settings file](settings.md) instead of running `/voice`:

```python
{
  "voice": {
    "enabled": true,
    "mode": "tap"
  }
}
```

For the first three sessions with voice dictation enabled, the input footer shows a `hold space to speak` hint when the prompt is empty. The hint reflects your current `voice:pushToTalk` binding and updates if you [rebind the dictation key](#rebind-the-dictation-key). The hint text is the same in both modes, and it does not appear if you have a [custom status line](statusline.md) configured. Transcription is tuned for coding vocabulary in both modes. Common development terms like `regex`, `OAuth`, `JSON`, and `localhost` are recognized correctly, and your current project name and git branch name are added as recognition hints automatically.


[​](#hold-to-record)

Hold to record

Hold mode is push-to-talk: recording runs while you hold the key and stops when you release it. This is the default mode. Hold `Space` to start recording. Claude Code detects a held key by watching for rapid key-repeat events from your terminal, so there is a brief warmup before recording begins. The footer shows `keep holding…` during warmup, then `listening…` once recording is active. While recording, the prompt cursor becomes a bar that rises and falls with your microphone level, unless you have [`prefersReducedMotion`](settings-reference.md#prefersreducedmotion) turned on. The first couple of key-repeat characters type into the input during warmup and are removed automatically when recording activates. A single `Space` tap still types a space, since hold detection only triggers on rapid repeat. Holding or tapping `Space` starts dictation only where the keypress would otherwise type into the prompt. In the [transcript viewer](interactive-mode.md#transcript-viewer), `Space` pages through the conversation, and in [vim mode](interactive-mode.md#vim-editor-mode) outside INSERT it is a command. A [rebound modifier combination](#rebind-the-dictation-key) like `meta+k` never types text, so it starts dictation from those places too.

To skip the warmup, switch to [tap mode](#tap-to-record-and-send) with `/voice tap`, or [rebind to a modifier combination](#rebind-the-dictation-key) like `meta+k`. Modifier combos start recording on the first keypress.

Your speech appears in the prompt as you speak, dimmed until the transcript is finalized. Release `Space` to stop recording and finalize the text. The transcript is inserted at your cursor position and the cursor stays at the end of the inserted text, so you can mix typing and dictation in any order. Hold `Space` again to append another recording, or move the cursor first to insert speech elsewhere in the prompt:

```python
> refactor the auth middleware to ▮
  # hold space, speak "use the new token validation helper"
> refactor the auth middleware to use the new token validation helper▮
```

By default, when you release the key, Claude Code inserts the transcript and waits for you to press `Enter`. Set `"autoSubmit": true` in the `voice` settings object to send the prompt automatically when you release the key, as long as the transcript is at least three words long.


[​](#tap-to-record-and-send)

Tap to record and send

Tap mode toggles recording with a single keypress: tap once to start, speak, then tap again to send the prompt. There is no warmup, and you don’t need to keep the key held. Enable tap mode with `/voice tap`. With the prompt input empty, tap `Space` to start recording. The footer shows `● REC · tap to send` while recording. Tap `Space` again to stop. Claude Code inserts the transcript and submits the prompt automatically when the transcript is at least three words long. Shorter transcripts are inserted but not submitted, so an accidental tap does not send a stray word. The three-word threshold counts words for languages written without spaces. Japanese, Chinese, and Thai transcripts count individual words, so they auto-submit in tap mode and in hold mode with `autoSubmit`. The first tap only starts recording when the prompt input is empty, so you can still type spaces normally while composing a message. The second tap stops recording regardless of input contents. Recording also stops automatically after 15 seconds of silence or two minutes total.


[​](#cancel-a-recording)

Cancel a recording

Press `Esc` or `Ctrl+C` to cancel a dictation instead of finalizing it. Claude Code stops the microphone, discards the transcript, and restores the prompt to what it held before the recording started. Both keys also cancel while a finished recording’s transcript is still processing. A prompt you edited or submitted during processing stays as you left it. Neither key does anything else in the press that cancels: `Esc` doesn’t interrupt Claude’s response, and `Ctrl+C` doesn’t clear the prompt or count as the first of the [two presses that exit Claude Code](interactive-mode.md#general-controls).


[​](#change-the-dictation-language)

Change the dictation language

Voice dictation uses the same [`language` setting](settings-reference.md#language) that controls Claude’s response language. If that setting is empty, dictation defaults to English. In the VS Code extension, if `language` is empty, dictation uses VS Code’s `accessibility.voice.speechLanguage` setting before defaulting to English.

Supported dictation languages

| Language   | Code |
|:-----------|:-----|
| Czech      | `cs` |
| Danish     | `da` |
| Dutch      | `nl` |
| English    | `en` |
| French     | `fr` |
| German     | `de` |
| Greek      | `el` |
| Hindi      | `hi` |
| Indonesian | `id` |
| Italian    | `it` |
| Japanese   | `ja` |
| Korean     | `ko` |
| Norwegian  | `no` |
| Polish     | `pl` |
| Portuguese | `pt` |
| Russian    | `ru` |
| Spanish    | `es` |
| Swedish    | `sv` |
| Turkish    | `tr` |
| Ukrainian  | `uk` |

Set the language in `/config` or directly in settings. You can use either the [BCP 47 language code](https://en.wikipedia.org/wiki/IETF_language_tag) or the language name:

```python
{
  "language": "japanese"
}
```

If your `language` setting is not in the supported list, `/voice` warns you on enable and falls back to English for dictation. Claude’s text responses are not affected by this fallback.


[​](#rebind-the-dictation-key)

Rebind the dictation key

The dictation key is bound to `voice:pushToTalk` in the `Chat` context and defaults to `Space`. The same binding controls both hold and tap modes. Rebind it in [`~/.claude/keybindings.json`](keybindings.md):

```python
{
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "meta+k": "voice:pushToTalk",
        "space": null
      }
    }
  ]
}
```

The `voice:pushToTalk` action uses one key at a time. When you bind a custom key, it replaces the default `Space` binding rather than adding a second trigger, so the `"space": null` line in this example is for clarity and can be omitted without changing behavior. In hold mode, avoid binding a bare letter key like `v` since hold detection relies on key-repeat and the letter types into the prompt during warmup. Use `Space`, or use a modifier combination like `meta+k` to start recording on the first keypress with no warmup. Tap mode has no warmup, so most keys work. Some keys are not delivered to terminal applications and can’t be bound at all. For example, `Caps Lock` shows an error if you try to bind it. See [customize keyboard shortcuts](keybindings.md) for the full keybinding syntax and the list of reserved shortcuts.


[​](#troubleshooting)

Troubleshooting

Common issues when voice dictation does not activate or record:

- **`Unknown command: /voice`**: `/voice` is available only while a claude.ai account is your active sign-in. If you aren’t signed in with one, run `/login`. If `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, an `apiKeyHelper` setting, or a [third-party provider](#requirements) is in use, it takes precedence over a claude.ai sign-in, so remove it and restart Claude Code.
- **`Voice mode requires a Claude.ai account`**: Claude Code couldn’t find a usable claude.ai sign-in when you ran `/voice` or started recording. Run `/login` to sign in again.
- **`Voice mode is disabled by your organization's policy`**: an administrator policy for your organization turns off voice dictation. Contact your organization administrator to confirm whether voice dictation is available for your organization.
- **`Microphone access is denied`**: grant microphone permission to your terminal in system settings. On macOS, go to System Settings → Privacy & Security → Microphone and enable your terminal app, then run `/voice` again. On Windows, go to Settings → Privacy & security → Microphone and turn on microphone access for desktop apps, then run `/voice` again. If your terminal isn’t listed in the macOS settings, see [Terminal not listed in macOS Microphone settings](#terminal-not-listed-in-macos-microphone-settings).
- **`Voice mode requires SoX for audio recording` on Linux**: the native audio module could not load and no fallback is installed. Install SoX with the command shown in the error message, for example `sudo apt-get install sox`.
- **`Voice mode requires a microphone, but SoX could not open an audio capture device`**: SoX is installed, but the host has no audio capture device, for example a headless server or a container. Run Claude Code on a machine with a microphone. As of v2.1.195, Claude Code on Linux reports this message in that situation; earlier versions asked you to install SoX even when it was already installed.
- **`Voice mode could not find a working audio recorder in WSL`**: WSLg routes audio through PulseAudio rather than an ALSA device, so SoX needs its PulseAudio backend installed explicitly. Run `sudo apt install sox libsox-fmt-pulse`. Installing `sox` alone pulls in the ALSA backend, which cannot record on WSL because there is no `/dev/snd` device.
- **`Voice input is failing repeatedly and has been paused`**: voice dictation hit three failures within 10 seconds. Claude Code pauses dictation until 10 seconds have passed since the first of those failures. This usually means the microphone or audio stack on this host can’t capture audio, for example a headless server, a remote shell with no audio passthrough, or a denied microphone permission. Confirm a working input device, fix the underlying cause from the entries above, then trigger voice again. Before v2.1.202, only start-up failures counted toward the pause.
- **Nothing happens when holding `Space` in hold mode**: watch the prompt input while you hold. If spaces keep accumulating, voice dictation is likely off; run `/voice hold` to enable it. If only one or two spaces appear and then nothing, voice dictation is on but hold detection is not triggering. Hold detection requires your terminal to send key-repeat events, so it can’t detect a held key if key-repeat is disabled at the OS level. Switch to tap mode with `/voice tap` to avoid the key-repeat requirement.
- **Tapping `Space` types a space instead of recording in tap mode**: the first tap only starts recording when the prompt input is empty. Clear the input first, or check that you are in tap mode by running `/voice tap`.
- **`No audio detected from microphone`**: recording started but captured silence. Confirm the correct input device is set as the system default and that its input level is not muted or near zero. On Windows, open Settings → System → Sound → Input and select your microphone. On macOS, open System Settings → Sound → Input.
- **`Voice connection failed`**: your recording never reached the transcription service because the connection failed. Check your network and try again. A recording that captures no audio reports `No audio detected from microphone` instead of this message. Before v2.1.200, a silent microphone could report a connection failure, which suggested a network problem when the actual issue was the input device.
- **`Dictation error: WebSocket error:` followed by a certificate error such as `unable to get local issuer certificate`**: see [Dictation or the Web tab fails behind a TLS-inspecting proxy](../03-IDE-Integrations/vs-code.md#dictation-or-the-web-tab-fails-behind-a-tls-inspecting-proxy) on the VS Code page.
- **`Voice stream error: WebSocket upgrade rejected with HTTP <status>`**: a server refused your connection with the HTTP status shown, so this isn’t a network outage. A status in the 400 range usually means a stale sign-in, or a proxy or bot-protection service answering in place of the transcription service. Run `/login` to refresh your sign-in, and check for a VPN or proxy on your network path if the status persists. If you’re still recording when the rejection arrives, Claude Code retries a status outside the 400 range once before showing this message; it doesn’t retry a status in the 400 range. In v2.1.229 through v2.1.231, native builds didn’t show this message: Claude Code kept recording, the hold-mode footer still showed `listening…`, and it reported `Voice connection failed` after you stopped recording.
- **`No speech detected`**: audio reached the transcription service but no words were recognized. Speak closer to the microphone, reduce background noise, and confirm your [dictation language](#change-the-dictation-language) matches the language you are speaking.
- **`Dictation stopped: no speech recognized for 15 seconds` or `Dictation stopped at its 2-minute limit`**: in the VS Code extension, a recording ends after 15 seconds with no recognized words, or two minutes after it starts. If you were speaking during those 15 seconds, try the fixes for `No speech detected`. Words already recognized stay in the prompt box and aren’t sent. To add more, click the microphone button again.
- **Transcription is garbled or in the wrong language**: dictation defaults to English. If you are dictating in another language, set it in `/config` first. See [Change the dictation language](#change-the-dictation-language).


[​](#terminal-not-listed-in-macos-microphone-settings)

Terminal not listed in macOS Microphone settings

If your terminal app does not appear under System Settings → Privacy & Security → Microphone, there is no toggle you can enable. Reset the permission state for your terminal so the next `/voice` run triggers a fresh macOS permission prompt.

1

Reset the microphone permission for your terminal

Run `tccutil reset Microphone <bundle-id>`, replacing `<bundle-id>` with your terminal’s identifier: `com.apple.Terminal` for the built-in Terminal, or `com.googlecode.iterm2` for iTerm2. For other terminals, look up the identifier with `osascript -e 'id of app "AppName"'`.

You can run `tccutil reset Microphone` without a bundle ID, but it revokes microphone access from every app on your Mac, including apps like Zoom or Slack. Each app will need to re-request access on next use, so don’t run it during an active call.

2

Quit and relaunch your terminal

macOS won’t re-prompt a process that is already running. Quit the terminal app with Cmd+Q, not just close its windows, then open it again.

3

Trigger a fresh prompt

Start Claude Code and run `/voice`. macOS prompts for microphone access; allow it.


[​](#see-also)

See also

- [Customize keyboard shortcuts](keybindings.md): rebind `voice:pushToTalk` and other CLI keyboard actions
- [All settings](settings-reference.md#voice): the `voice`, `language`, and other settings keys
- [Interactive mode](interactive-mode.md): keyboard shortcuts, input modes, and session controls
- [Commands](commands.md): reference for `/voice`, `/config`, and all other commands

---

## Get started with Claude Code in the cloud - Claude Code Docs

Source: https://code.claude.com/docs/en/web-quickstart
Path: 02-Claude-Code-CLI/web-quickstart.md

## On this page

- [How sessions run](#how-sessions-run)
- [Compare ways to run Claude Code](#compare-ways-to-run-claude-code)
- [Connect GitHub](#connect-github)
  - [Connect from your terminal](#connect-from-your-terminal)
  - [Remove the /web-setup token](#remove-the-web-setup-token)
- [Start a task](#start-a-task)
- [Pre-fill sessions](#pre-fill-sessions)
- [Review and iterate](#review-and-iterate)
- [Troubleshoot setup](#troubleshoot-setup)
  - [No repositories appear after connecting GitHub](#no-repositories-appear-after-connecting-github)
  - [The page only shows a GitHub login button](#the-page-only-shows-a-github-login-button)
  - [”Claude Code isn’t available on your account”](#%E2%80%9Dclaude-code-isn%E2%80%99t-available-on-your-account%E2%80%9D)
  - [/web-setup says “Not signed in to Claude”](#%2Fweb-setup-says-%E2%80%9Cnot-signed-in-to-claude%E2%80%9D)
  - [/web-setup warns that your token doesn’t have the workflow scope](#%2Fweb-setup-warns-that-your-token-doesn%E2%80%99t-have-the-workflow-scope)
  - [/web-setup shows “No commands match” or “Unknown command”](#web-setup-shows-no-commands-match-or-unknown-command)
  - [”Could not create a cloud environment” or “No cloud environment available” when using --cloud](#%E2%80%9Dcould-not-create-a-cloud-environment%E2%80%9D-or-%E2%80%9Cno-cloud-environment-available%E2%80%9D-when-using-cloud)
  - [Setup script failed](#setup-script-failed)
  - [New sessions hang or time out during setup](#new-sessions-hang-or-time-out-during-setup)
  - [Session keeps running after closing the tab](#session-keeps-running-after-closing-the-tab)
- [Next steps](#next-steps)

Claude Code in the cloud

# Get started with Claude Code in the cloud

Copy pageCopy page

Run Claude Code in the cloud from your browser or phone. Connect a GitHub repository, submit a task, and review the PR without local setup.

Copy pageCopy page

Cloud sessions are available on Pro, Max, and Team plans, and for Enterprise users with premium seats or Chat + Claude Code seats.

A cloud session runs Claude Code on cloud infrastructure instead of your machine, Anthropic-managed by default. This quickstart starts one from [claude.ai/code](https://claude.ai/code) in your browser. You can also start one from the Claude mobile app, the Desktop app, or your terminal with `claude --cloud`. You’ll need a GitHub repository to [get started](#connect-github). Claude clones it into an isolated virtual machine, makes changes, and pushes a branch for you to review. Sessions persist across devices, so a task you start on your laptop is ready to review from your phone later. Each session counts toward your plan’s usage limits alongside the rest of your Claude and Claude Code usage, and there’s no separate charge for the cloud VM. Cloud sessions work well for:

- **Parallel tasks**: run several independent tasks at once, each in its own session and branch, without managing multiple worktrees
- **Repos you don’t have locally**: Claude clones the repo fresh every session, so you don’t need it checked out
- **Tasks that don’t need frequent steering**: submit a well-defined task, do something else, and review the result when Claude is done
- **Code questions and exploration**: understand a codebase or trace how a feature is implemented without a local checkout

For work that needs your local config, tools, or environment, running Claude Code locally or using [Remote Control](remote-control.md) is a better fit.


[​](#how-sessions-run)

How sessions run

The steps below describe Anthropic-hosted sessions. In a [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md), the clone and everything after it run on your organization’s own runners, where network boundaries, setup, and push behavior are operator-configured. When you submit a task:

1.  **Clone and prepare**: your repository is cloned to an Anthropic-managed VM, and your [setup script](cloud-environments.md#setup-scripts) runs if configured.
2.  **Configure network**: internet access is set based on your environment’s [access level](cloud-environments.md#access-levels).
3.  **Work**: Claude analyzes code, makes changes, runs tests, and checks its work. You can watch and steer throughout, or step away and come back when it’s done.
4.  **Push the branch**: when Claude reaches a stopping point, it pushes its branch to GitHub. You review the diff, leave inline comments, create a PR, or send another message to keep going.

The session doesn’t close when the branch is pushed. PR creation and further edits all happen within the same conversation.


[​](#compare-ways-to-run-claude-code)

Compare ways to run Claude Code

Claude Code behaves the same everywhere. What changes is where the session runs and whether your local configuration is available:

|                                                   | Cloud session                                                                                                       | Local session                                                                                                                           | Local session with [Remote Control](remote-control.md)          |
|:--------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------|
| **Code runs on**                                  | Cloud VM, Anthropic-managed by default                                                                              | Your machine                                                                                                                            | Your machine                                                          |
| **You start it from**                             | claude.ai/code, the Claude mobile app, the Desktop app with **Cloud** selected, or `claude --cloud`                 | Your terminal, your IDE, or the Desktop app with **Local** selected                                                                     | Your terminal, the VS Code extension, or the Desktop app              |
| **You chat from**                                 | claude.ai, the mobile app, or the Desktop app                                                                       | Where you started it                                                                                                                    | claude.ai or the mobile app, as well as where you started it          |
| **Uses your local config**                        | No, repo only                                                                                                       | Yes                                                                                                                                     | Yes                                                                   |
| **Requires GitHub**                               | Yes, or [bundle a local repo](claude-code-on-the-web.md#send-local-repositories-without-github) via `--cloud` | No                                                                                                                                      | No                                                                    |
| **Keeps running if you disconnect**               | Yes                                                                                                                 | No                                                                                                                                      | While the session stays open on your machine                          |
| **[Permission modes](permission-modes.md)** | Accept edits, Plan, Auto                                                                                            | All modes in the terminal; see [Switch permission modes](permission-modes.md#switch-permission-modes) for the IDE and Desktop app | Manual, Accept edits, Plan, or Auto from claude.ai and the mobile app |
| **Network access**                                | Configurable per environment                                                                                        | Your machine’s network                                                                                                                  | Your machine’s network                                                |

See the [terminal quickstart](../01-Getting-Started/quickstart.md), [Desktop app](../16-Mobile-Desktop/desktop.md), or [Remote Control](remote-control.md) docs to set up local sessions.


[​](#connect-github)

Connect GitHub

Connecting GitHub is a one-time step. If you already use the GitHub CLI, you can [do this from your terminal](#connect-from-your-terminal) instead of the browser.

On Team and Enterprise plans, the **Sign in with GitHub** step works only after an [Owner](../13-Enterprise-Admin/server-managed-settings.md#access-control) of your Claude organization turns on the GitHub connector at [**Organization settings \> Connectors**](https://claude.ai/admin-settings/connectors). Until then, that step shows “GitHub access is required for Claude Code cloud sessions” instead of a sign-in button. After the connector is on, reload [claude.ai/code](https://claude.ai/code) and start again from the first step. A second toggle, [Quick setup](claude-code-on-the-web.md#quick-setup-for-team-and-enterprise) at [**Organization settings \> Claude Code**](https://claude.ai/admin-settings/claude-code), is optional: with it on, `/web-setup` works and onboarding creates the environment for members.

1

Visit claude.ai/code

Go to [claude.ai/code](https://claude.ai/code) and sign in with your claude.ai account.

2

Sign in with GitHub

After you sign in, claude.ai/code prompts you to connect GitHub. Follow the prompt, and claude.ai/code sends you to GitHub’s authorization page. Approve the authorization request, and GitHub returns you to claude.ai/code. Cloud sessions work with existing GitHub repositories. To start a new project, [create a repository with a README on GitHub](https://github.com/new) first.With this connection, a session can clone any public repository, but can work in a private repository only when the Claude GitHub App is installed on it. [Install the Claude GitHub App](https://github.com/apps/claude/installations/new) on each GitHub account or organization whose private repositories you want to use. On a GitHub organization, an organization owner may need to approve the installation. Installing it also enables [Auto-fix](claude-code-on-the-web.md#auto-fix-pull-requests), which lets Claude respond to CI failures and review comments on pull requests in those repositories.When you connect, Claude also links the GitHub accounts you own to your Claude organization, if they have the Claude GitHub App installed. On Team and Enterprise plans, admins see those accounts in the [connected GitHub accounts list](../13-Enterprise-Admin/admin-setup.md#connected-github-accounts).If onboarding prompts you to install the Claude GitHub App at this point and you’d rather do it later, click **Skip**.

3

Set up your Default environment

A [cloud environment](cloud-environments.md) is the saved configuration that controls what network access Claude has during sessions and what runs when a session starts. What happens after you connect GitHub depends on your plan:

- **Pro and Max**: onboarding creates an environment named **Default** for you.
- **Team and Enterprise**: onboarding shows a **Create your first cloud environment** form. Leave the prefilled name and network access unchanged and click **Create & finish** to create the **Default** environment. If an Owner has turned on [Quick setup](claude-code-on-the-web.md#quick-setup-for-team-and-enterprise), onboarding creates **Default** for you instead.

**Default** uses [`Trusted` network access](cloud-environments.md#access-levels): sessions reach [common package registries](cloud-environments.md#default-allowed-domains) and other allowlisted domains, and nothing else through the session’s network. See [Installed tools](cloud-environments.md#installed-tools) for what’s available without any configuration.For a first project, the **Default** environment works as is. To change its network access, add environment variables, or run a [setup script](cloud-environments.md#setup-scripts) before sessions start, [edit it or create additional environments](cloud-environments.md#configure-your-environment).


[​](#connect-from-your-terminal)

Connect from your terminal

If you already use the GitHub CLI (`gh`), you can connect GitHub for cloud sessions from your terminal. This requires the [Claude Code CLI](../01-Getting-Started/quickstart.md). On Team and Enterprise plans, `/web-setup` is available only after an Owner turns on [Quick setup](claude-code-on-the-web.md#quick-setup-for-team-and-enterprise). When you run `/web-setup`, Claude Code reads the token that `gh auth token` prints, asks you to confirm, and sends the token to Anthropic. Anthropic stores it encrypted with your claude.ai account, and your cloud sessions use it for GitHub access until you [remove it](#remove-the-web-setup-token). A cloud session you start yourself can then access any repository that token can access, with no Claude GitHub App installation. Threads in a [project](claude-projects.md#set-up-github-access) still need the Claude GitHub App. If you already connected GitHub in the browser, `/web-setup` warns you that continuing replaces that connection for your cloud sessions.

Organizations with [Zero Data Retention](zero-data-retention.md) enabled, or with the [HIPAA configuration](hipaa-setup.md) applied, cannot use `/web-setup` or other cloud session features. Organizations that use [customer-managed encryption keys](../04-API-Reference/Other/manage-claude-cmek.md) (CMEK) can’t start cloud sessions either. If the GitHub CLI isn’t installed or isn’t authenticated, Claude Code opens the browser onboarding flow instead.

1

Authenticate with the GitHub CLI

In your shell, authenticate the GitHub CLI if you haven’t already:

```python
gh auth login
```

2

Sign in to Claude

In the Claude Code CLI, run `/login` to sign in with your claude.ai account. Skip this step if you’re already signed in with a claude.ai account. Authenticating with an API key doesn’t count. To check, run `/status` and confirm the **Login method** row shows a claude.ai account.

3

Run /web-setup

In the Claude Code CLI, run:

```python
/web-setup
```

Confirm the prompt to send your `gh` token to your Claude account. On success, Claude Code prints `Connected as <your-github-username>` and opens [claude.ai/code](https://claude.ai/code) in your browser. If you don’t have a cloud environment yet, `/web-setup` creates one with Trusted network access and no setup script. You can [edit the environment or add variables](cloud-environments.md#configure-your-environment) afterward. Once `/web-setup` completes, you can start cloud sessions from your terminal with [`--cloud`](claude-code-on-the-web.md#from-terminal-to-cloud) or set up recurring tasks with [`/schedule`](web-scheduled-tasks.md).


[​](#remove-the-web-setup-token)

Remove the `/web-setup` token

To remove the token from your Claude account, disconnect GitHub at [claude.ai/customize/connectors](https://claude.ai/customize/connectors). Disconnecting deletes the GitHub credentials your cloud sessions use, whether they came from the browser or from `/web-setup`, so cloud sessions lose GitHub access until you connect again. Your local `gh` stays signed in, and the token remains valid on GitHub. To invalidate the token itself, revoke it on GitHub. If you signed in to `gh` through the browser, the token belongs to the **GitHub CLI** entry under [**Settings \> Applications \> Authorized OAuth Apps**](https://github.com/settings/applications) on GitHub, and revoking that entry also signs the GitHub CLI out on your machines. Cloud sessions then lose GitHub access until you run `gh auth login` and `/web-setup` again.


[​](#start-a-task)

Start a task

With GitHub connected and an environment created, you’re ready to submit tasks.

1

Select a repository and branch

From [claude.ai/code](https://claude.ai/code) or the Code tab in the Claude mobile app, click the repository selector below the input box and choose a repository for Claude to work in. You can add multiple repositories to work across them in one session.At claude.ai/code, to start Claude from a feature branch instead of the default, change the branch in the control after the repository selector.

2

Choose a permission mode

The [permission mode control](permission-modes.md#switch-permission-modes) shows the permission mode the session will run in:

- **Auto**: a classifier reviews Claude’s actions instead of asking you. Appears when your organization allows auto mode and the selected model supports it
- **Accept edits**: Claude makes changes and pushes a branch without stopping for approval
- **Plan**: Claude proposes an approach and waits for you to approve it before editing files

Cloud sessions don’t offer Manual or Bypass permissions. See the [full list of permission modes](permission-modes.md#available-modes) for what each one allows.

3

Describe the task and submit

Type a description of what you want and press Enter. Be specific:

- Name the file or function: “Add a README with setup instructions” or “Fix the failing auth test in `tests/test_auth.py`” is better than “fix tests”
- Paste error output if you have it
- Describe the expected behavior, not just the symptom

Claude clones the repositories, runs your setup script if configured, and starts working. Each task gets its own session and its own branch, so you don’t need to wait for one to finish before starting another.


[​](#pre-fill-sessions)

Pre-fill sessions

You can prefill the prompt, repositories, and environment for a new session by adding query parameters to the [claude.ai/code](https://claude.ai/code) URL. Use this to build integrations such as a button in your issue tracker that opens Claude Code with the issue description as the prompt.

| Parameter      | Description                                                                                                                                                      |
|:---------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `prompt`       | Prompt text to prefill in the input box. The alias `q` is also accepted.                                                                                         |
| `prompt_url`   | URL to fetch the prompt text from, for prompts too long to embed in a query string. The URL must allow cross-origin requests. Ignored when `prompt` is also set. |
| `repositories` | Comma-separated list of `owner/repo` slugs to preselect. The alias `repo` is also accepted.                                                                      |
| `environment`  | Name or ID of the [environment](#connect-github) to preselect.                                                                                                   |

URL-encode each value. The example below opens the form with a prompt and a repository already selected:

```python
https://claude.ai/code?prompt=Fix%20the%20login%20bug&repositories=acme/webapp
```


[​](#review-and-iterate)

Review and iterate

When Claude finishes, review the changes, leave feedback on specific lines, and keep going until the diff looks right.

1

Open the diff view

A diff indicator shows lines added and removed across the session, for example `+42 -18`. Select it to open the diff view, with a file list on the left and changes on the right.The diff compares the session’s changes against its base branch by default. To compare against a different branch, select **Compare against** and pick one.

2

Leave inline comments

Select any line in the diff, type your feedback, and press Enter. Comments queue up until you send your next message, then they’re bundled with it. Claude sees “at `src/auth.ts:47`, don’t catch the error here” alongside your main instruction, so you don’t have to describe where the problem is.

3

Create a pull request

When the diff looks right, select **Create PR** at the top of the diff view. You can open it as a full PR, a draft, or jump to GitHub’s compose page with a generated title and description.

4

Keep iterating after the PR

The session stays live after the PR is created. Paste CI failure output or reviewer comments into the chat and ask Claude to address them. To have Claude monitor the PR automatically, see [Auto-fix pull requests](claude-code-on-the-web.md#auto-fix-pull-requests).


[​](#troubleshoot-setup)

Troubleshoot setup


[​](#no-repositories-appear-after-connecting-github)

No repositories appear after connecting GitHub

If you connected GitHub in the browser, sessions can clone any public repository, but a private repository appears only when the Claude GitHub App is installed on the account or organization that owns it and the installation’s repository access includes it. [Install the Claude GitHub App](https://github.com/apps/claude/installations/new) there, or ask an organization owner to install or approve it. If you connected with `/web-setup`, sessions reach every repository your `gh` token can access. Run `gh repo view OWNER/REPO` in your shell to check that your GitHub CLI login can see the repository, and run `/web-setup` again if you’ve switched `gh` accounts since connecting.


[​](#the-page-only-shows-a-github-login-button)

The page only shows a GitHub login button

Cloud sessions require a connected GitHub account. Connect via the browser flow above, or run `/web-setup` from your terminal if you use the GitHub CLI. If you’d rather not connect GitHub at all, see [Remote Control](remote-control.md) to run Claude Code on your own machine and monitor it from your browser or phone.


[​](#”claude-code-isn’t-available-on-your-account”)

”Claude Code isn’t available on your account”

Your seat in the selected organization doesn’t include Claude Code. If you belong to another organization, click **Switch organization** on that page. Otherwise, ask an Owner of the organization to assign you a [seat that includes Claude Code](https://support.claude.com/en/articles/11845131-use-claude-code-with-your-team-or-enterprise-plan).


[​](#/web-setup-says-“not-signed-in-to-claude”)

`/web-setup` says “Not signed in to Claude”

If `/web-setup` responds with “Not signed in to Claude. Run /login first.”, the CLI doesn’t have a valid claude.ai sign-in. This can also happen when a previous sign-in has expired. Run `/login`, sign in with your claude.ai account, then run `/web-setup` again.


[​](#/web-setup-warns-that-your-token-doesn’t-have-the-workflow-scope)

`/web-setup` warns that your token doesn’t have the `workflow` scope

If `/web-setup` says your GitHub CLI token doesn’t have the `workflow` scope, you can continue, but GitHub can reject some pushes made with that token, such as pushes that change GitHub Actions workflow files. To add the scope, run `gh auth refresh -s workflow` in your shell, then run `/web-setup` again.


[​](#web-setup-shows-no-commands-match-or-unknown-command)

`/web-setup` shows “No commands match” or “Unknown command”

`/web-setup` runs inside the Claude Code CLI, not your shell. Launch `claude` first, then type `/web-setup` at the prompt. If you typed it inside Claude Code and the command menu shows `No commands match "/web-setup"`, or submitting it returns `Unknown command: /web-setup`, the command is hidden because a requirement isn’t met. The cause is usually that you’re authenticated with an API key or third-party provider instead of a claude.ai subscription. Run `/login` to sign in with your claude.ai account. On Team and Enterprise plans, the command is hidden by default: the [Quick setup toggle](claude-code-on-the-web.md#quick-setup-for-team-and-enterprise) is off until an Owner turns it on. While it’s off, [connect GitHub from the browser](#connect-github) instead. The command is also hidden in two other cases:

- An administrator has disabled cloud sessions for your organization. In this case, submitting `/web-setup` returns [`Cloud sessions are disabled by your organization's policy`](errors.md#cloud-sessions-are-disabled-by-your-organizations-policy). Before v2.1.268, this case also returned `Unknown command: /web-setup`.
- Your Enterprise organization has [Zero Data Retention](zero-data-retention.md) enabled, or has the [HIPAA configuration](hipaa-setup.md) applied. Either one makes cloud sessions unavailable.


[​](#”could-not-create-a-cloud-environment”-or-“no-cloud-environment-available”-when-using-cloud)

”Could not create a cloud environment” or “No cloud environment available” when using `--cloud`

Cloud session features create a default cloud environment automatically if you don’t have one. If you see “Could not create a cloud environment”, automatic creation failed. If you see “No cloud environment available”, your CLI predates automatic creation. In either case, run `/web-setup` in the Claude Code CLI, or add an environment from the [environment selector](cloud-environments.md#configure-your-environment) at [claude.ai/code](https://claude.ai/code).


[​](#setup-script-failed)

Setup script failed

The setup script exited with a non-zero status, which blocks the session from starting. Common causes:

- A package install failed because the registry isn’t in your [network access level](cloud-environments.md#access-levels). `Trusted` covers most package managers; `None` blocks them all.
- The script references a file or path that doesn’t exist in a fresh clone.
- A command that works locally needs a different invocation on Ubuntu.

To debug, add `set -x` at the top of the script to see which command failed. For non-critical commands, append `|| true` so they don’t block session start.


[​](#new-sessions-hang-or-time-out-during-setup)

New sessions hang or time out during setup

If new sessions stall on the setup script step or fail with a generic container error before the script finishes, the script is likely exceeding the roughly five-minute time budget for building the [environment cache](cloud-environments.md#environment-caching). Heavy steps such as pulling large Docker images, syncing full dependency trees, or downloading model weights often push the total over the limit, especially when they run one after another. To fix this, trim the script so it reliably finishes in under five minutes:

- Run independent installs in parallel with `&` and a final `wait` instead of running them serially.
- Move the largest downloads out of the setup script and into a [SessionStart hook](cloud-environments.md#setup-scripts-vs-sessionstart-hooks) that launches them in the background, so the session becomes usable while they finish.
- Remove long retry sleeps from the setup script, since a stalled retry loop counts against the budget.


[​](#session-keeps-running-after-closing-the-tab)

Session keeps running after closing the tab

This is by design. Closing the tab or navigating away doesn’t stop the session. It continues running in the background until Claude finishes the current task, then idles. From the sidebar, you can [archive a session](claude-code-on-the-web.md#archive-sessions) to hide it from your list, or [delete it](claude-code-on-the-web.md#delete-sessions) to remove it permanently.


[​](#next-steps)

Next steps

Now that you can submit and review tasks, these pages cover what comes next: starting cloud sessions from your terminal, scheduling recurring work, and giving Claude standing instructions.

- [Use Claude Code in the cloud](claude-code-on-the-web.md): the full reference, including teleporting sessions to your terminal, session sharing, and auto-fixing pull requests
- [Configure cloud environments](cloud-environments.md): network access levels, environment variables, and setup scripts for cloud sessions
- [Cloud scheduled tasks](web-scheduled-tasks.md): automate work on a schedule, via API call, or in response to GitHub events
- [CLAUDE.md](memory.md): give Claude persistent instructions and context that load at the start of every session
- Install the Claude mobile app for [iOS](https://apps.apple.com/us/app/claude-by-anthropic/id6473753684) or [Android](https://play.google.com/store/apps/details?id=com.anthropic.claude) to monitor sessions from your phone. From the Claude Code CLI, `/mobile` shows a QR code for [claude.ai/mobile](https://claude.ai/mobile) that opens the right app store for your phone.

---

## Automate work with scheduled tasks - Claude Code Docs

Source: https://code.claude.com/docs/en/routines
Path: 02-Claude-Code-CLI/web-scheduled-tasks.md

## On this page

- [Example use cases](#example-use-cases)
- [Create a scheduled task](#create-a-scheduled-task)
  - [Create from the web](#create-from-the-web)
  - [Dialog with Repositories and Environment in the main view](#dialog-with-repositories-and-environment-in-the-main-view)
  - [Create from the CLI](#create-from-the-cli)
- [Configure triggers](#configure-triggers)
  - [Add a schedule trigger](#add-a-schedule-trigger)
  - [Schedule a one-off run](#schedule-a-one-off-run)
  - [Add an API trigger](#add-an-api-trigger)
  - [Trigger a scheduled task](#trigger-a-scheduled-task)
  - [API reference](#api-reference)
  - [Add a GitHub trigger](#add-a-github-trigger)
  - [Supported events](#supported-events)
  - [Filter pull requests](#filter-pull-requests)
- [Manage scheduled tasks](#manage-scheduled-tasks)
  - [View and interact with runs](#view-and-interact-with-runs)
  - [Edit and control scheduled tasks](#edit-and-control-scheduled-tasks)
  - [Manage scheduled tasks from the CLI](#manage-scheduled-tasks-from-the-cli)
  - [Repositories and branch permissions](#repositories-and-branch-permissions)
  - [Connectors](#connectors)
  - [Permission prompts during a run](#permission-prompts-during-a-run)
  - [When a run publishes an artifact without asking](#when-a-run-publishes-an-artifact-without-asking)
  - [Artifacts in Accept edits mode](#artifacts-in-accept-edits-mode)
  - [Environments and network access](#environments-and-network-access)
- [Usage and limits](#usage-and-limits)
- [Where the name routines still appears](#where-the-name-routines-still-appears)
- [Troubleshooting](#troubleshooting)
  - [/schedule returns “Unknown command”](#schedule-returns-unknown-command)
  - [“Routines are disabled by your organization’s policy”](#routines-are-disabled-by-your-organizations-policy)
- [Related resources](#related-resources)

Claude Code in the cloud

# Automate work with scheduled tasks

Copy pageCopy page

Put Claude Code on autopilot. Create scheduled tasks, formerly routines, that run in the cloud on a schedule, on API calls, or on GitHub events.

Copy pageCopy page

Scheduled tasks are in research preview. Behavior, limits, and the API surface may change.

A cloud scheduled task, formerly a routine, is a saved Claude Code configuration: a prompt, one or more repositories, and a set of [connectors](../06-MCP-Tools/General/mcp.md), packaged once and run automatically. Scheduled tasks execute on Anthropic-managed cloud infrastructure, or on your organization’s [self-hosted environment](../13-Enterprise-Admin/self-hosted-environments.md) when routed there, so they keep working when your laptop is closed. Each scheduled task can have one or more triggers attached to it:

- **Schedule**: run on a recurring cadence like hourly, nightly, or weekly, or once at a specific future time
- **API**: trigger on demand by sending an HTTP POST to the task’s own endpoint with a bearer token
- **GitHub**: run automatically in response to repository events such as pull requests or releases

A single scheduled task can combine triggers. For example, a PR review task can run nightly, trigger from a deploy script, and also react to every new PR. A scheduled task doesn’t need a schedule:

- A task with only an API trigger runs when you call its endpoint.
- A task with only a GitHub trigger runs when a matching repository event occurs.

Scheduled tasks are available on Pro, Max, Team, and Enterprise plans. Create and manage them at [claude.ai/code/routines](https://claude.ai/code/routines), or from the CLI with `/schedule`. The earlier name, routines, [still appears](#where-the-name-routines-still-appears) in the web address, the CLI, and the API.

Two other features schedule work on your machine instead of in the cloud: [Desktop scheduled tasks](../16-Mobile-Desktop/desktop-scheduled-tasks.md) and [`/loop`](scheduled-tasks.md). To choose among all three, see [Compare scheduling options](scheduled-tasks.md#compare-scheduling-options).

Team and Enterprise Owners can turn off scheduled tasks for all members with the **Scheduled tasks (Was Routines)** toggle at [**Organization settings \> Capabilities \> Remote sessions**](https://claude.ai/admin-settings/capabilities). When the toggle is off, existing scheduled tasks stop running and members can’t create new ones. If your Enterprise organization manages your access with [custom roles](https://support.claude.com/en/articles/13930452), you also need a role that includes the scheduled tasks permission. An Owner can add it in a role’s **Remote sessions** section at [**Organization settings \> Roles**](https://claude.ai/admin-settings/roles).


[​](#example-use-cases)

Example use cases

Each example pairs a trigger type with the kind of work scheduled tasks are suited to: unattended, repeatable, and tied to a clear outcome.

- **Backlog maintenance**: a schedule trigger runs every weeknight in your repository, with your issue tracker added as a connector. The scheduled task reads issues opened since the last run, applies labels, and assigns owners based on the area of code referenced. It then posts a summary to Slack so the team starts the day with a groomed queue.
- **Alert triage**: your monitoring tool calls the scheduled task’s API endpoint when an error threshold is crossed, passing the alert body as `text`. The task’s prompt tells Claude to investigate the alert in the fire payload, so it pulls the stack trace and correlates it with recent commits in the repository. It then opens a draft pull request with a proposed fix and a link back to the alert. On-call reviews the PR instead of starting from a blank terminal.
- **Bespoke code review**: a GitHub trigger runs on `pull_request.opened`. The scheduled task applies your team’s own review checklist and leaves inline comments for security, performance, and style issues. It also adds a summary comment so human reviewers can focus on design instead of mechanical checks.
- **Deploy verification**: your CD pipeline calls the scheduled task’s API endpoint after each production deploy. The task runs smoke checks against the new build, scans error logs for regressions, and posts a go or no-go to the release channel before the deploy window closes.
- **Docs drift**: a schedule trigger runs weekly. The scheduled task scans merged PRs since the last run, flags documentation that references changed APIs, and opens update PRs against the docs repository for an editor to review.
- **Library port**: a GitHub trigger runs on `pull_request.closed` filtered to merged PRs in one SDK repository. The scheduled task ports the change to a parallel SDK in another language and opens a matching PR, keeping the two libraries in step without a human re-implementing each change.


[​](#create-a-scheduled-task)

Create a scheduled task

Create a scheduled task from the web at [claude.ai/code/routines](https://claude.ai/code/routines), from the Desktop app, or from the CLI. All three surfaces write to the same cloud account, so a scheduled task you create in one shows up in the others immediately. In the Desktop app’s **Code** tab, click **Scheduled** in the sidebar or in the sidebar’s **More** menu, then **New task**, and continue with [Create from the web](#create-from-the-web). Scheduled tasks run autonomously as full Claude Code cloud sessions. The session runs shell commands, uses [skills](../08-Plugins-Skills/skills.md), and calls any connectors you include. Outside a [project](claude-projects.md#what-threads-pick-up-from-your-repositories)’s threads, those skills include the ones committed to the cloned repository. You don’t choose a permission mode when you create the task: see [Permission prompts during a run](#permission-prompts-during-a-run) for when a run stops to wait for you. What a scheduled task can reach is determined by:

- The repositories you select
- The [environment’s](cloud-environments.md) network access and variables
- The connectors you include

Scope each of those to what the task needs. Scheduled tasks belong to your individual claude.ai account. They are not shared with teammates, and their runs count against your account’s [usage and limits](#usage-and-limits). Anything a scheduled task does through your connected GitHub identity or connectors appears as you. Commits and pull requests carry your GitHub user, and Slack messages, Linear tickets, or other connector actions use your linked accounts for those services.


[​](#create-from-the-web)

Create from the web

1

Open the creation dialog

Go to [claude.ai/code/routines](https://claude.ai/code/routines) and click **New task**. If a menu opens first, select **Set up manually**. The **New scheduled task** dialog opens. The menu’s other option, **Create with Claude**, lets you describe the task in a chat and have Claude create it instead.If **Repositories** and **Environment** are already showing when the dialog opens, see [how that dialog differs](#dialog-with-repositories-and-environment-in-the-main-view). Otherwise, this dialog also creates scheduled tasks for claude.ai chat. To make yours what the dialog calls a Claude Code task, select a repository or add a GitHub event or API trigger in the steps that follow. That kind of task runs Claude Code in a cloud session.

2

Name the task and write the prompt

Give the scheduled task a descriptive name and write the prompt Claude runs each time. The prompt is the most important part: the task runs autonomously, so the prompt must be self-contained and explicit about what to do and what success looks like. Select a model in the prompt input’s model selector. Claude uses it on every run.When a trigger fires, the session receives the saved prompt as its assignment and carries it out, rather than treating it as untrusted content that arrived mid-conversation. The trigger attests only that the prompt was stored ahead of time by an authorized session on your account. The fired prompt is therefore not live user input and can’t act as approval or consent for actions during the run. Content the session fetches during the run keeps its normal handling.

3

Select a trigger

In the **Trigger** row, choose how the task starts. To combine several triggers, click **+** at the end of the row.

- Schedule

- GitHub event

- API

Pick a preset frequency for a recurring run. See [Add a schedule trigger](#add-a-schedule-trigger) for timezone handling, late starts, custom cron intervals, and one-off runs.

Select the repository, the event to react to, and optional filters. See [Add a GitHub trigger](#add-a-github-trigger) for the full list of supported events and filter fields.

Select **API** here. When you click **Create**, the **API token** dialog shows the token once, so copy it before you close the dialog. See [Add an API trigger](#add-an-api-trigger) to copy the URL or generate a new token.

4

Select repositories

Expand **Advanced settings**. Under **Repository** on the **General** tab, select one or more GitHub repositories for Claude to work in.Each repository is cloned at the start of a run. Claude creates `claude/`-prefixed branches for its changes.

5

Select an environment

After you select a repository, **Cloud environment** appears below it. Pick a [cloud environment](cloud-environments.md) for the task. Environments control what the cloud session has access to:

- **Network access**: set the level of internet access available during each run
- **Environment variables**: provide values Claude can use during each run. They’re [visible to anyone who uses the environment](cloud-environments.md#what-carries-over-from-your-setup), so in an Anthropic-hosted environment, store keys for the APIs Claude calls during a run as [network secrets](cloud-environments.md#add-network-secrets) instead. That section also lists the requests that never get a secret
- **Setup script**: install dependencies and tools the task needs. The result is [cached](cloud-environments.md#environment-caching), so the script doesn’t re-run on every session

A **Default** environment is provided with **Trusted** network access, which allows only the [default allowlist](cloud-environments.md#default-allowed-domains) of package registries, cloud provider APIs, container registries, and common development domains through the session’s network. Connectors you add to the task reach their services through Anthropic’s servers, so they don’t need allowlist changes.If your task needs to reach your own services directly, or a domain outside that list, edit the environment’s [network access](cloud-environments.md#network-access) before running. To use a separate environment, [create one](cloud-environments.md#configure-your-environment) first.

6

Review connectors

Switch to the **Connectors** tab of **Advanced settings**. All of your connected [MCP connectors](../06-MCP-Tools/General/mcp.md) are included by default. Remove any the task doesn’t need: Claude can use an included connector during a run, including writes. For when a run stops to ask you first, see [Permission prompts during a run](#permission-prompts-during-a-run).

7

Create the task

Click **Create**. The dialog closes and the new task’s detail page opens. The task runs the next time one of its triggers matches. To start a run immediately, click **Run now** on the detail page.To see what a run did, click it in the **History** list on the detail page. The run [opens as a full session](#view-and-interact-with-runs), a new one for each run, where you can see what Claude did, review changes, and create a pull request.


[​](#dialog-with-repositories-and-environment-in-the-main-view)

Dialog with Repositories and Environment in the main view

Follow the [steps to create from the web](#create-from-the-web), and fill in each field in the dialog’s main view rather than under **Advanced settings**. This dialog creates only Claude Code tasks. Select the repository before you add a GitHub event trigger, because that trigger is unavailable until a repository is selected.


[​](#create-from-the-cli)

Create from the CLI

Run `/schedule` in any session to create a scheduled task conversationally. You can also pass a description directly, for a recurring task like `/schedule daily PR review at 9am` or a one-off like `/schedule clean up feature flag in one week`. Claude walks through the same information the web dialog collects, then saves the task to your account. The command is also available under the alias `/routines`. A successful start looks like a conversation: Claude asks follow-up questions about the schedule, repositories, and prompt before saving. If Claude instead replies that you need to authenticate or that it can’t connect to your remote claude.ai account, no scheduled task was created; see [Troubleshooting](#troubleshooting). A task you create with `/schedule` has a schedule trigger. You can also add the other trigger types:

- **API trigger**: edit the task on the web at [claude.ai/code/routines](https://claude.ai/code/routines)
- **[GitHub trigger](#add-a-github-trigger)**: edit the task on the web, or ask Claude in the CLI. Adding one from the CLI requires Claude Code v2.1.225 or later

A scheduled task with no schedule trigger, such as one started only by API calls or GitHub events, has no next run time. The CLI shows none when Claude saves or updates it. Before v2.1.211, the CLI reported a next run time in the year 1 for these tasks.


[​](#configure-triggers)

Configure triggers

A scheduled task starts when one of its triggers matches. Add or remove a task’s triggers at any time in the **Trigger** row of the task’s [edit dialog](#edit-and-control-scheduled-tasks). When a task has two or more triggers, each one has a trash icon in that dialog. To remove a schedule or GitHub event trigger, click its trash icon, then **Save changes**. To remove an API trigger, [delete its token](#add-an-api-trigger) instead.


[​](#add-a-schedule-trigger)

Add a schedule trigger

A schedule trigger runs the task on a recurring cadence, or once at a specific future time. In the task’s creation or edit dialog on the web, pick a preset frequency such as hourly, daily, or weekly:

- **Runs on the hour**: if you schedule a run exactly on the hour, such as 9:00, it can start several minutes late. To start close to the scheduled time, pick a few minutes past the hour, for example 9:07.
- **Custom intervals**: for a cadence the presets lack, create the task and select **Custom** in its [edit dialog](#edit-and-control-scheduled-tasks). Then enter a cron expression, such as `0 */2 * * *` for every two hours. To set one from the CLI, run [`/schedule update`](#manage-scheduled-tasks-from-the-cli). Expressions that run more often than once per hour are rejected.
- **Time zone**: when you pick a preset frequency, enter the time in your local time zone.


[​](#schedule-a-one-off-run)

Schedule a one-off run

A one-off schedule runs the task a single time at a specific timestamp. For example, use it to:

- Remind yourself later in the week
- Open a cleanup PR after a rollout finishes
- Start follow-up work after an upstream change ships

After the task runs, it turns itself off and the web UI marks it as **Completed**. To run it again, open the task’s [edit dialog](#edit-and-control-scheduled-tasks) on the web and select **One-time** or **Once**, whichever label your dialog shows. Then set a new date and time in your local time zone and save. Create a one-off run from the CLI by describing the time in natural language. Claude resolves the phrase against the current time and confirms the absolute timestamp before saving.

```python
/schedule tomorrow at 9am, summarize yesterday's merged PRs
```

```python
/schedule in 2 weeks, open a cleanup PR that removes the feature flag
```

One-off runs count against the same hourly limit as other scheduled runs. See [Usage and limits](#usage-and-limits) for details.


[​](#add-an-api-trigger)

Add an API trigger

An API trigger gives a scheduled task a dedicated HTTP endpoint. POSTing to the endpoint with the task’s bearer token starts a new session and returns a session URL. Use this to wire Claude Code into alerting systems, deploy pipelines, internal tools, or anywhere you can make an authenticated HTTP request. Add an API trigger on the web, either while you [create the task](#create-from-the-web) or later with the steps below. You can’t add an API trigger or manage its token from the CLI.

1

Open the task for editing

Go to [claude.ai/code/routines](https://claude.ai/code/routines), click the scheduled task you want to trigger via API, then open the menu next to its name and select **Edit**. The **Edit scheduled task** dialog opens.

2

Add an API trigger

In the **Trigger** row, click **+** and select **API** from the menu that opens. A panel with the **Fire URL** and **Token** for this task appears.

3

Copy the URL and generate a token

Copy the **Fire URL**. Click **Generate token**, then copy the token from the **Token generated** dialog immediately. The token is shown once and can’t be retrieved later, so store it somewhere secure such as your alerting tool’s secret store.The API trigger takes effect as soon as you generate the token. You don’t need to click **Save changes**, so close the dialog when you’re done.

4

Call the endpoint

Send the token in the `Authorization: Bearer` header when you POST to the URL. [Trigger a scheduled task](#trigger-a-scheduled-task) shows a complete example.

Each scheduled task has its own token, scoped to triggering that task only. To turn off API access or rotate the token, [open the task’s **Edit scheduled task** dialog](#edit-and-control-scheduled-tasks) again. Both controls are next to the token in the API trigger’s panel and take effect immediately:

- **Turn off API access**: click **Delete token**, the trash icon next to **Regenerate**. This removes the API trigger
- **Rotate the token**: click **Regenerate**. The previous token stops working, and the **Token generated** dialog shows the new one once


[​](#trigger-a-scheduled-task)

Trigger a scheduled task

Send a POST request to the `/fire` endpoint with the bearer token in the `Authorization` header. The request body accepts an optional `text` field for run-specific context such as an alert body or a failing log, passed to the task alongside its saved prompt. The value is freeform text and is not parsed: if you send JSON or another structured payload, the task receives it as a literal string. The `text` value doesn’t reach the routine as a bare message. It arrives wrapped in a `<routine-fire-payload>` block that labels it as untrusted data and tells Claude not to follow instructions inside it unless the routine’s own prompt says to. The same wrapping applies to text supplied with **Run now** in the web UI. This means a routine’s saved prompt must opt in to acting on fire text: write the prompt to reference the payload explicitly, for example “Investigate the alert described in the routine-fire-payload block”, or the routine treats the text as inert context. Anyone holding the bearer token can send `text`, so the wrapper makes fire text from a leaked token arrive labeled as untrusted data rather than as direct instructions to your routine. The example below triggers a scheduled task from a shell. The task ID and token shown are placeholders: replace them with the URL and token you copied when [adding the API trigger](#add-an-api-trigger), or the request fails with a `401` authentication error:

```python
curl -X POST https://api.anthropic.com/v1/claude_code/routines/trig_01ABCDEFGHJKLMNOPQRSTUVW/fire \
  -H "Authorization: Bearer sk-ant-oat01-xxxxx" \
  -H "anthropic-beta: experimental-cc-routine-2026-04-01" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{"text": "Sentry alert SEN-4521 fired in prod. Stack trace attached."}'
```

A successful request returns a JSON body with the new session ID and URL:

```python
{
  "type": "routine_fire",
  "claude_code_session_id": "session_01HJKLMNOPQRSTUVWXYZ",
  "claude_code_session_url": "https://claude.ai/code/session_01HJKLMNOPQRSTUVWXYZ"
}
```

Open the session URL in a browser to watch the run in real time, review changes, or continue the conversation manually.

The `/fire` endpoint ships under the `experimental-cc-routine-2026-04-01` beta header. Request and response shapes, rate limits, and token semantics may change while the feature is in research preview. Breaking changes ship behind new dated beta header versions, and the two most recent previous header versions continue to work so that callers have time to migrate.


[​](#api-reference)

API reference

For the full API reference, including all error responses, validation rules, and field limits, see [Trigger a routine through the API](../04-API-Reference/Endpoints/claude-code-routines-fire.md) in the Claude Platform documentation. The `/fire` endpoint is available to claude.ai users only and is not part of the Claude Platform API surface.


[​](#add-a-github-trigger)

Add a GitHub trigger

A GitHub trigger starts a new session automatically when a matching event occurs on a connected repository. Claude Code doesn’t reuse sessions across events, so two PR updates produce two independent sessions.


The Claude GitHub App must be installed on the repository you want to subscribe to, whichever surface you configure the trigger from.

- Configure GitHub triggers from the web UI, which prompts you to install the app when it’s missing. Follow the steps below to configure one on the web.
- From the CLI, install the app from the [GitHub App page](https://github.com/apps/claude) first, then ask Claude to attach a GitHub trigger to an existing scheduled task, for example `/schedule add a GitHub trigger to my nightly review for pull requests opened in acme/webapp`. The CLI path requires Claude Code v2.1.225 or later. When Claude adds the trigger, it replies with a link to the task the trigger fires.

1

Open the task for editing

Go to [claude.ai/code/routines](https://claude.ai/code/routines), click the scheduled task, then open the menu next to its name and select **Edit**. The **Edit scheduled task** dialog opens.

2

Add a GitHub event trigger

In the **Trigger** row, click **+** and select **GitHub event** from the menu that opens.

Running `/web-setup` in the CLI grants repository access for cloning, but it does not install the Claude GitHub App and does not enable webhook delivery.

3

Configure the trigger

Change the repository if needed, choose an event from the [supported events](#supported-events) list, and optionally add filters. Then click **Save changes** at the bottom of the dialog to apply the trigger.


[​](#supported-events)

Supported events


| Event        | Triggers when                                                                 |
|:-------------|:------------------------------------------------------------------------------|
| Pull request | A PR is opened, closed, assigned, labeled, synchronized, or otherwise updated |
| Release      | A release is created, published, edited, or deleted                           |


[​](#filter-pull-requests)

Filter pull requests

Use filters to narrow which pull requests start a new session. All filter conditions must match for the scheduled task to trigger. The available filter fields are:

| Filter      | Matches                          |
|:------------|:---------------------------------|
| Author      | PR author’s GitHub username      |
| Title       | PR title text                    |
| Body        | PR description text              |
| Base branch | Branch the PR targets            |
| Head branch | Branch the PR comes from         |
| Labels      | Labels applied to the PR         |
| Is draft    | Whether the PR is in draft state |
| Is merged   | Whether the PR has been merged   |

Each filter pairs a field with an operator: equals, contains, starts with, is one of, is not one of, or matches regex. The `matches regex` operator tests the entire field value, not a substring within it. To match any title containing `hotfix`, write `.*hotfix.*`. Without the surrounding `.*`, the filter matches only a title that is exactly `hotfix` with nothing before or after. For literal substring matching without regex syntax, use the `contains` operator instead. A few example filter combinations:

- **Auth module review**: base branch `main`, head branch contains `auth-provider`. Sends any PR that touches authentication to a focused reviewer.
- **Ready-for-review only**: is draft is `false`. Skips drafts so the task only runs when the PR is ready for review.
- **Label-gated backport**: labels include `needs-backport`. Triggers a port-to-another-branch task only when a maintainer tags the PR.


[​](#manage-scheduled-tasks)

Manage scheduled tasks

Click a scheduled task in the list to open its detail page. The detail page shows the task’s repositories, connectors, prompt, schedule, API tokens, GitHub triggers, and a list of past runs.


[​](#view-and-interact-with-runs)

View and interact with runs

Click any run to open it as a full session. From there you can see what Claude did, review changes, create a pull request, or continue the conversation. Each run session works like any other session: use the dropdown menu next to the session title to rename, archive, or delete it.

A green status in the run list means the session started and exited without an infrastructure error. It does not mean the work your prompt describes succeeded. Open the run to read the transcript and confirm what Claude actually did. Blocked network requests, missing connector tools, and failures in the work itself all surface there rather than in the status indicator.


[​](#edit-and-control-scheduled-tasks)

Edit and control scheduled tasks

From the detail page you can:

- Click **Run now** to start a run immediately without waiting for the next scheduled time.
- Use the on/off switch at the top of the page to pause or resume the schedule. Paused tasks keep their configuration but don’t run until you turn them back on.
- Open the menu next to the task’s name and select **Edit** to change the name, prompt, repositories, environment, connectors, or any of the task’s triggers. The **Edit scheduled task** dialog opens with the same layout as the [creation dialog](#create-from-the-web). To add a trigger, click **+** in the **Trigger** row. Click **Save changes** to apply your edits. API token actions take effect immediately, without **Save changes**.
- Open the same menu and select **Delete** to delete the task.


[​](#manage-scheduled-tasks-from-the-cli)

Manage scheduled tasks from the CLI

Run `/schedule list` to see your scheduled tasks, `/schedule update` to change one, or `/schedule run` to start one immediately. You can also ask about a scheduled task’s run history, for example `/schedule why did my nightly review do nothing this morning?`. Claude lists the task’s recent runs with their status and a link to [open each run on the web](#view-and-interact-with-runs). It also reads a run’s log to explain what happened, including tool errors, permission denials, and the final result. Requires Claude Code v2.1.227 or later.


[​](#repositories-and-branch-permissions)

Repositories and branch permissions

Scheduled tasks need GitHub access to clone repositories. When you create a scheduled task from the CLI with `/schedule`, Claude checks whether your account has GitHub access for the repository you ran it from. If it doesn’t, Claude adds a setup note naming how to grant it.

See [GitHub authentication options](claude-code-on-the-web.md#github-authentication-options) for the two ways to grant access. On Team and Enterprise plans, an [Owner](../13-Enterprise-Admin/server-managed-settings.md#access-control) of your Claude organization has to turn on each method before you can use it; see [Connect GitHub](web-quickstart.md#connect-github).

If your GitHub connection is missing or expired when a run is due, the scheduled task skips runs until you reconnect, for up to 72 hours. Reconnect GitHub within that window and the task resumes on its own. After 72 hours without a connection, the task turns off, and you turn it back on after reconnecting GitHub. Each repository you add is cloned on every run. Claude starts from the repository’s default branch unless your prompt specifies otherwise. If a [GitHub pull request event](#add-a-github-trigger) triggers the run and the pull request’s repository is the task’s first repository, that repository starts from the pull request’s head commit instead. Claude pushes its work to a branch prefixed with `claude/` unless your prompt directs it to push to another branch. To control which branches a run can push to, use branch protection rules or rulesets on GitHub. For runs on Anthropic-managed infrastructure, and for self-hosted runs that push through [Anthropic’s git proxy](../13-Enterprise-Admin/self-hosted-environments-deploy.md#use-the-anthropic-git-proxy), GitHub applies them to the GitHub access you connected, so a rule that access can bypass doesn’t block a run’s push. A self-hosted run that pushes with the git credentials your deployment provides is checked against those instead. See [Configure git](../13-Enterprise-Admin/self-hosted-environments-deploy.md#configure-git).


[​](#connectors)

Connectors

Scheduled tasks can use your connected MCP connectors to read from and write to external services during each run. For example, a task that triages support requests might read from a Slack channel and create issues in Linear. Connectors are the [claude.ai integrations](../06-MCP-Tools/General/mcp.md#use-mcp-servers-from-claude-ai) on your account. MCP servers you added locally in the CLI with `claude mcp add` are stored on your machine rather than your claude.ai account, so they do not appear in the connectors list. To use one of those servers in a scheduled task:

- **As a connector**: add it as a connector at [claude.ai/customize/connectors](https://claude.ai/customize/connectors)
- **In the repository**: for a scheduled task with one repository, you can instead declare the server in a committed [`.mcp.json`](../06-MCP-Tools/General/mcp.md#project-scope), unless the task runs as threads in a [project](claude-projects.md#what-threads-pick-up-from-your-repositories). If it does, add the server as a connector.

When you create a scheduled task, all of your currently connected connectors are included by default. Remove any that aren’t needed to limit which tools Claude has access to during the run. You can also add connectors directly from the task’s creation or edit dialog. To manage or add connectors outside of that dialog, visit [claude.ai/customize/connectors](https://claude.ai/customize/connectors) or use `/schedule update` in the CLI.


[​](#permission-prompts-during-a-run)

Permission prompts during a run

For a task that runs in your organization’s self-hosted environment, see [Permissions and tool approval](../13-Enterprise-Admin/self-hosted-environments-configuration.md#permissions-and-tool-approval).

When a run starts a new session on Anthropic’s cloud, that session begins in [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) unless auto mode is unavailable. In auto mode, a classifier model allows or blocks actions that would otherwise wait for your approval. A run still stops and waits for an answer in cases such as these:

- **Actions that prompt even in auto mode**: for example, an action that matches an [ask rule](permissions.md#manage-permissions). See [How auto mode evaluates actions](permission-modes.md#how-auto-mode-evaluates-actions)
- **Repeated blocks**: one block doesn’t end the run. Once blocks reach auto mode’s [repeated-block thresholds](permission-modes.md#repeated-block-thresholds), a permission prompt appears in the run’s session and waits until someone answers it

If auto mode is unavailable, such as when your organization turned it off or the task’s model doesn’t support it, the run keeps the permission mode it launched in. To answer a waiting prompt, open the run from the task’s [detail page](#view-and-interact-with-runs). In a [project](claude-projects.md), a run can continue a thread rather than start a new session. That run keeps whatever permission mode the thread is in at the time. When that thread was made, it started in auto mode unless auto mode was unavailable. To answer a prompt waiting in that thread, see [Unblock a thread waiting on approval](claude-projects.md#unblock-a-thread-waiting-on-approval).


[​](#when-a-run-publishes-an-artifact-without-asking)

When a run publishes an artifact without asking

During a run in [auto mode](#permission-prompts-during-a-run), Claude publishes an [artifact](artifacts.md) without asking you once the classifier allows the publish. You’re still asked first when, for example, the publish matches an [ask rule](permissions.md#manage-permissions). A new artifact is visible only to you until you [share it](artifacts.md#share-an-artifact). The [Accept edits rules](#artifacts-in-accept-edits-mode) that follow don’t apply in auto mode. When a scheduled task’s job is to keep a page current, give it an artifact you already published.


[​](#artifacts-in-accept-edits-mode)

Artifacts in Accept edits mode

When a scheduled task’s schedule or **Run now** starts a run, Claude can publish a new [artifact](artifacts.md) without asking. The new artifact is visible only to you until you [share it](artifacts.md#share-an-artifact). If the publish declares runtime capabilities for the page, such as [connector calls](artifacts.md#pull-live-data-with-mcp-connectors) or [file downloads](artifacts.md#offer-a-file-download), Claude asks first. In those runs, Claude republishes an existing artifact without asking only when all of these hold:

- You can edit the artifact and it belongs to your own organization
- If the publish carries more than the page, such as supporting files, you own the artifact
- The artifact isn’t shared publicly
- If the artifact is shared with specific people or your organization, its viewers don’t automatically see each new version
- The publish doesn’t force over a newer version
- The publish doesn’t declare runtime capabilities for the page
- The existing page holds no grant that reaches beyond the page, such as [connector calls](artifacts.md#pull-live-data-with-mcp-connectors)

In every other case, including a run that an API or GitHub trigger starts, Claude asks first.


[​](#environments-and-network-access)

Environments and network access

Each scheduled task uses a [cloud environment](cloud-environments.md) that controls network access, environment variables, and setup scripts. The task inherits the environment’s network policy on every run. The **Default** environment uses **Trusted** network access, which allows only the [default allowlist](cloud-environments.md#default-allowed-domains) through the session’s network. Requests on that path to hosts outside the allowlist fail with `403` and `x-deny-reason: host_not_allowed`. MCP connector traffic is routed through Anthropic’s servers rather than that path, 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). To allow additional domains on one of your own environments, follow these steps. An [organization-shared environment](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.

1

Open the task for editing

Go to [claude.ai/code/routines](https://claude.ai/code/routines), click the scheduled task, then open the menu next to its name and select **Edit**. The **Edit scheduled task** dialog opens.

2

Open the environment selector

Go to **Advanced settings \> General \> Cloud environment**, expanding **Advanced settings** first if it’s collapsed. Click the cloud icon showing your environment’s name, such as **Default**.

3

Open the environment settings

Hover over the environment in the list and click the settings icon that appears on the right.

4

Change the network access level

In the **Edit cloud environment** dialog, change **Network access** to **Custom** and enter your domains in **Allowed domains**. Check **Also include default list of common package managers** to keep the [default allowlist](cloud-environments.md#default-allowed-domains) alongside your custom domains. Select **Full** instead for unrestricted access.

5

Save

Click **Save changes** in the **Edit cloud environment** dialog, then close the **Edit scheduled task** dialog behind it. The new policy applies from the next run.

See [Network access](cloud-environments.md#network-access) for details on access levels and the default allowlist.


[​](#usage-and-limits)

Usage and limits

Scheduled tasks draw down subscription usage the same way interactive sessions do. See your current consumption at [claude.ai/settings/usage](https://claude.ai/settings/usage). Separately from subscription usage, each way of starting a run has an hourly limit:

| Action                                                          | Limit                                             | Counted for                                        | Over the limit                          |
|:----------------------------------------------------------------|:--------------------------------------------------|:---------------------------------------------------|:----------------------------------------|
| Scheduled runs, including one-off runs                          | 100 per hour                                      | Your account                                       | The run waits until the limit resets    |
| **Run now**, API fires, and setting a one-off task to run again | 30 per hour                                       | Each scheduled task, one count shared by all three | The action fails until the limit resets |
| **Run now** and setting a one-off task to run again             | 100 per hour                                      | Your account                                       | Same                                    |
| API fires                                                       | 100 per hour                                      | Your account, counted separately from **Run now**  | Same                                    |
| GitHub events                                                   | See [Add a GitHub trigger](#add-a-github-trigger) |                                                    |                                         |

None of these hourly limits has overage. When a scheduled task hits your subscription usage limit, organizations with usage credits turned on can keep running scheduled tasks on metered overage. Without usage credits, additional runs are rejected until your usage window resets. Turn on usage credits at [claude.ai/settings/usage](https://claude.ai/settings/usage). On Team and Enterprise plans, an admin turns them on for the organization at [claude.ai/admin-settings/usage](https://claude.ai/admin-settings/usage). While your subscription is paused, your scheduled tasks are put on hold and don’t run. Once your subscription is active again, turn them back on.


[​](#where-the-name-routines-still-appears)

Where the name routines still appears

Scheduled tasks were previously called routines, and these places keep the earlier name. Each one refers to the same feature:

- **Web address**: `claude.ai/code/routines`
- **CLI**: the `/routines` alias for `/schedule`, the command’s description, and Claude’s replies while it sets up a task
- **API**: the `/fire` endpoint path, its beta header, its response `type`, the `<routine-fire-payload>` tag, and the [Trigger a routine through the API](../04-API-Reference/Endpoints/claude-code-routines-fire.md) reference page
- **Organization settings**: the **Scheduled tasks (Was Routines)** toggle


[​](#troubleshooting)

Troubleshooting


[​](#schedule-returns-unknown-command)

`/schedule` returns “Unknown command”

The CLI hides `/schedule` when one of its requirements isn’t met: the command menu shows `No commands match "/schedule"` while you type. Submitting it returns `Unknown command: /schedule`, except in the cases below that note a different answer. The cause is usually one of the following:

- You are authenticated with a Console API key, an [Anthropic profile or federation credential](authentication.md#anthropic-profiles-and-federation-credentials), or a cloud provider such as Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry. `/schedule` requires a claude.ai subscription login. With a Console API key or a profile, and feature-flag fetching enabled, submitting `/schedule` instead shows `/schedule is available with Claude for Enterprise — ask your admin about migrating from API-key access`. With a cloud-provider login, you still see `Unknown command: /schedule`. If `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN` is set in your shell, or `apiKeyHelper` is set in `settings.json`, remove it first, since these take precedence over a claude.ai login. A profile or federation credential takes precedence too, so switch that off as well
- You are fully signed out, with no API key or other credential. With feature-flag fetching enabled, submitting `/schedule` shows `/schedule requires a claude.ai subscription. Run /login to sign in with your claude.ai account.` Before v2.1.268, a signed-out session showed the same Claude for Enterprise message as a Console API key
- You are inside a cloud session, where submitting `/schedule` answers that the command isn’t available in that environment. Manage scheduled tasks from the [web UI](https://claude.ai/code/routines) instead
- Your organization’s policy disables [cloud sessions](claude-code-on-the-web.md), which scheduled tasks require. In this case, submitting `/schedule` answers [`Cloud sessions are disabled by your organization's policy`](errors.md#cloud-sessions-are-disabled-by-your-organizations-policy) instead. Before v2.1.268, it returned `Unknown command: /schedule`
- An Owner [turned off scheduled tasks](#routines-are-disabled-by-your-organizations-policy) for your Team or Enterprise organization. Before v2.1.227, the command still appeared in this case, and claude.ai rejected the task when Claude tried to create or run it
- Your Enterprise organization manages your access with [custom roles](https://support.claude.com/en/articles/13930452), and none of your roles includes the scheduled tasks permission under **Remote sessions**. Ask an Owner to add it to one of your roles

If the cause is your CLI sign-in or being inside a cloud session, you can still create and manage scheduled tasks at [claude.ai/code/routines](https://claude.ai/code/routines). You need a Pro, Max, Team, or Enterprise account there. If scheduled tasks or cloud sessions are off for your organization or missing from your roles, you can’t create them on the web either.


[​](#routines-are-disabled-by-your-organizations-policy)

“Routines are disabled by your organization’s policy”

An Owner in your Team or Enterprise organization has likely turned off the **Scheduled tasks (Was Routines)** toggle at [**Organization settings \> Capabilities \> Remote sessions**](https://claude.ai/admin-settings/capabilities). On Claude Code v2.1.227 or later, the same toggle also hides `/schedule` in the CLI. This is a server-side organization setting, so it cannot be overridden from your local configuration. Ask an Owner to turn scheduled tasks back on for your organization.


[​](#related-resources)

Related resources

- [`/loop` and in-session scheduling](scheduled-tasks.md): schedule local tasks within an open CLI session
- [Desktop scheduled tasks](../16-Mobile-Desktop/desktop-scheduled-tasks.md): local scheduled tasks that run on your machine with access to local files
- [Cloud environments](cloud-environments.md): configure network access, environment variables, and setup scripts for cloud sessions
- [Projects](claude-projects.md): ongoing work Claude coordinates across parallel cloud sessions; scheduled tasks created from a project appear on its **Scheduled tasks** tab
- [MCP connectors](../06-MCP-Tools/General/mcp.md): connect external services like Slack, Linear, and Google Drive
- [GitHub Actions](github-actions.md): run Claude in your CI pipeline on repository events

---

## What are skills? | Claude Help Center

Source: https://support.claude.com/en/articles/12512176-what-are-skills
Path: 02-Claude-Code-CLI/what-are-skills.md

# What are skills?

September 22, 2026


Skills are folders of instructions, scripts, and resources that Claude loads dynamically to improve performance on specialized tasks. Skills teach Claude how to complete specific tasks in a repeatable way, whether that's creating documents with your company's brand guidelines, analyzing data using your organization's specific workflows, or automating personal tasks.

Skills are available for users on Free, Pro, Max, Team, and Enterprise plans. This feature requires **[code execution to be enabled](../15-Claude-AI-Features/create-and-edit-files-with-claude.md#h_1c99382190)**. Skills are also available in Claude Code, and in beta for all API users using the code execution tool.

------------------------------------------------------------------------

## How do skills work?

Skills improve Claude’s consistency, speed, and performance on many tasks. Skills work through progressive disclosure—Claude determines which skills are relevant and loads the information it needs to complete that task, helping to prevent context window overload.

When you ask Claude to complete a task, it reviews available skills, loads relevant ones, and applies their instructions.

------------------------------------------------------------------------

## Types of skills

### Anthropic skills

These are skills created and maintained by Anthropic, such as enhanced document creation for Excel, Word, PowerPoint, and PDF files. Anthropic skills are available to all users and Claude invokes them automatically when relevant.

### Custom skills

These are skills you or your organization create for specialized workflows and domain-specific tasks. Here are some potential workflows you could enable using custom skills:

- Apply brand style guidelines to documents and presentations.

- Generate communications following company email templates.

- Structure meeting notes with company-specific formats.

- Create tasks in company tools (JIRA, Asana, Linear) following team conventions.

- Execute company-specific data analysis workflows.

- Automate personal workflows and customize Claude to match your work style.

### Organization provisioned skills

For Team and Enterprise plans, organization Owners can provision skills for all users. Skills provisioned in this way appear automatically in every team member's skills list and can be set as enabled or disabled by default. This allows organizations to:

- Distribute approved workflows consistently across all employees

- Ensure teams use standardized procedures and best practices

- Deploy new capabilities without requiring individual uploads

Learn more about provisioning skills in **[Provision and manage skills for your organization](https://support.claude.com/en/articles/13119606-managing-skills-as-an-admin)**.

### Partner skills

The Skills Directory features professionally-built skills from partners like Notion, Figma, Atlassian, and others. These skills are designed to work seamlessly with their respective MCP connectors, enabling powerful integrated workflows.

------------------------------------------------------------------------

## Key benefits

**Improvement in Claude’s performance of specific tasks**: Skills provide specialized capabilities for tasks like document creation, data analysis, and domain-specific work that requires supplementing Claude's general knowledge.

**Organizational knowledge capture**: Package your company's workflows, best practices, and institutional knowledge for Claude to use consistently across your team.

**Easy customization**: Anyone can create skills by writing instructions in Markdown—no coding required for simple skills, though you can attach executable scripts to custom skills for more advanced functionality.

**Centralized management for organizations:** Team and Enterprise plan Owners can provision skills organization-wide, ensuring consistent workflows across teams without requiring individual setup from each user.

------------------------------------------------------------------------

## Agent Skills open standard

The Agent Skills specification is published as an open standard at **[agentskills.io](https://agentskills.io)**. This means skills you create aren't locked to Claude—the same skill format works across AI platforms and tools that adopt the standard. A reference Python SDK is also available for developers implementing skills support in their own platforms.

------------------------------------------------------------------------

## Skills compared to other Claude capabilities

### Skills vs. projects

**[Projects](../15-Claude-AI-Features/what-are-projects.md)** provide static background knowledge that's always loaded when you start chats within them. Skills provide specialized procedures that activate dynamically when needed and work everywhere across Claude.

### Skills vs. MCP (Model Context Protocol)

MCP connects Claude to external services and data sources. Skills provide procedural knowledge—instructions for how to complete specific tasks or workflows. You can use both together: MCP connections give Claude access to tools, while skills teach Claude how to use those tools effectively.

### Skills vs. custom instructions

**[Custom instructions](https://support.claude.com/en/articles/10185728-understanding-claude-s-personalization-features)** apply broadly to all your conversations. Skills are task-specific and only load when relevant, making them better for specialized workflows.

------------------------------------------------------------------------

## Learn more about skills

To discover available skills, check out the directory by clicking "Customize" in your account and navigating to "Skills." You can click "+" then "Browse skills" to open the directory. For more information, see **[Browse skills, connectors, and plugins in one directory](../14-Connectors/browse-skills-connectors-and-plugins-in-one-directory.md)**.

On the Enterprise plan, organizations can turn on skill scanning to check uploaded skills and plugins for malicious content. Learn more about **[skill and plugin scanning](https://support.claude.com/en/articles/15927065)**.

For more details about how skills work, see **[Agent Skills](../04-API-Reference/Agents-Tools/agents-and-tools-agent-skills-overview.md)** in our Claude Docs.

---

## Week 13 · March 23–27, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w13
Path: 02-Claude-Code-CLI/whats-new-2026-w13.md

# Week 13 · March 23–27, 2026

Copy pageCopy page

Auto mode for hands-off permissions, computer use built in, PR auto-fix in the cloud, transcript search, and a PowerShell tool for Windows.

Copy pageCopy page

Releases [v2.1.83 → v2.1.85](changelog.md#2-1-83)6 features · March 23–27

Auto moderesearch preview

Auto mode hands your permission prompts to a classifier. Safe edits and commands run without interrupting you; anything destructive or suspicious gets blocked and surfaced. It’s the middle ground between approving every file write and running with `--dangerously-skip-permissions`.

Cycle to auto with Shift+Tab, or set it as your default:

~/.claude/settings.json

```python
{
  "permissions": {
    "defaultMode": "auto"
  }
}
```

[Permission modes guide](permission-modes.md)

Computer useDesktop

Claude can now control your actual desktop from the Claude Code Desktop app: open native apps, click through the iOS simulator, drive hardware control panels, and verify changes on screen. It’s off by default and asks before each action. Best for the things nothing else can reach: apps without an API, proprietary tools, anything that only exists as a GUI.

Enable it in Settings, grant the OS permissions, then ask Claude to verify a change end to end:

Claude Code

```python
Open the iOS simulator, tap through the onboarding flow, and screenshot each step
```

[Computer use guide](../16-Mobile-Desktop/desktop.md#let-claude-use-your-computer)

PR auto-fixWeb

Flip a switch when you open a PR and walk away. Claude watches CI, fixes the failures, handles the nits, and pushes until it’s green. No more babysitting a PR through six rounds of lint errors.

After creating a PR on Claude Code web, toggle Auto fix in the CI panel.

[Auto-fix pull requests](claude-code-on-the-web.md#auto-fix-pull-requests)

Transcript searchv2.1.83

Press `/` in transcript mode to search your conversation. `n` and `N` step through matches. Finally a way to find that one Bash command Claude ran 400 messages ago.

Open transcript mode and search:

Claude Code

```python
Ctrl+O    # open transcript
/migrate  # search for "migrate"
n         # next match
N         # previous match
```

[Fullscreen guide](fullscreen.md#search-and-review-the-conversation)

PowerShell toolpreviewv2.1.84

Windows gets a native PowerShell tool alongside Bash. Claude can run cmdlets, pipe objects, and work with Windows-native paths without translating everything through Git Bash.

Opt in from settings:

.claude/settings.json

```python
{
  "env": {
    "CLAUDE_CODE_USE_POWERSHELL_TOOL": "1"
  }
}
```

[PowerShell tool docs](tools-reference.md#powershell-tool)

Conditional hooksv2.1.85

Hooks can now declare an `if` field using permission rule syntax. Your pre-commit check only spawns for `Bash(git commit *)` instead of every bash call, cutting the process overhead on busy sessions.

Scope a hook to git commits only:

.claude/settings.json

```python
{
  "hooks": {
    "PreToolUse": [{
      "hooks": [{
        "if": "Bash(git commit *)",
        "type": "command",
        "command": ".claude/hooks/lint-staged.sh"
      }]
    }]
  }
}
```

[Hooks reference](../07-Hooks/hooks.md)

Other wins

Plugin `userConfig` now public: prompt for settings at enable time, keychain-backed secrets

Pasted images insert `[Image #N]` chips you can reference positionally

`managed-settings.d/` drop-in directory for layered policy fragments

`CwdChanged` and `FileChanged` hook events for direnv-style setups

Agents can declare `initialPrompt` in frontmatter to auto-submit a first turn

`Ctrl+X Ctrl+E` opens your external editor, matching readline

Interrupting before any response restores your input automatically

`/status` now works while Claude is responding

Deep links open in your preferred terminal, not first-detected

Idle-return nudge to `/clear` after 75+ minutes away

VS Code: rate limit banner, Esc-twice rewind picker

[Full changelog for v2.1.83–v2.1.85 →](changelog.md#2-1-83)

---

## Week 14 · March 30 – April 3, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w14
Path: 02-Claude-Code-CLI/whats-new-2026-w14.md

# Week 14 · March 30 – April 3, 2026

Copy pageCopy page

Computer use in the CLI, interactive in-product lessons, flicker-free rendering, per-tool MCP result-size overrides, and plugin executables on PATH.

Copy pageCopy page

Releases [v2.1.86 → v2.1.91](changelog.md#2-1-86)5 features · March 30 – April 3

Computer use in the CLIresearch preview

Last week computer use landed in the Desktop app. This week it’s in the CLI: Claude can open native apps, click through UI, test its own changes, and fix what breaks, all from your terminal. Web apps already had verification loops; native iOS, macOS, and other GUI-only apps didn’t. Now they do. Best for closing the loop on apps and tools where there’s no API to call. Still early; expect rough edges.

Requires macOS and a Pro or Max plan; otherwise, `computer-use` won’t appear in `/mcp`. Run `/mcp`, find `computer-use`, and toggle it on. Then ask Claude to verify a change end to end:

Claude Code

```python
Open the iOS simulator, tap through onboarding, and screenshot each step
```

[Computer use guide](computer-use.md)

/powerupv2.1.90

Interactive lessons that teach Claude Code features through animated demos, right inside your terminal. Claude Code releases frequently, and features that would have changed how you work last month can slip by. Run `/powerup` once and you’ll know what’s there.

Run it:

Claude Code

```python
/powerup
```

[Commands reference](commands.md)

Flicker-free renderingv2.1.89

Opt into a new alt-screen renderer with virtualized scrollback. The prompt input stays pinned to the bottom, mouse selection works across long conversations, and the flicker on redraw is gone. Unset `CLAUDE_CODE_NO_FLICKER` to roll back.

Set the env var and restart Claude Code:

```python
export CLAUDE_CODE_NO_FLICKER=1
claude
```

[Fullscreen rendering](fullscreen.md)

MCP result-size overridev2.1.91

MCP server authors can now raise the truncation cap on a specific tool by setting `anthropic/maxResultSizeChars` in the tool’s `tools/list` entry, up to a hard ceiling of 500K characters. The cap used to be global, so tools that occasionally returned inherently large payloads like database schemas or full file trees hit the default limit and got persisted to disk with a file reference. Per-tool overrides keep those results inline when the tool really needs them.

Annotate the tool in your server’s `tools/list` response:

```python
{
  "name": "get_schema",
  "description": "Returns the full database schema",
  "_meta": {
    "anthropic/maxResultSizeChars": 500000
  }
}
```

[MCP reference](../06-MCP-Tools/General/mcp.md#raise-the-limit-for-a-specific-tool)

Plugin executables on PATHv2.1.91

Place an executable in a `bin/` directory at your plugin root and Claude Code adds that directory to the Bash tool’s `PATH` while the plugin is enabled. Claude can then invoke the binary as a bare command from any Bash tool call, with no absolute path or wrapper script needed. Handy for packaging CLI helpers next to the commands, agents, and hooks that call them.

Add a `bin/` directory at the plugin root:

```python
my-plugin/
├── .claude-plugin/
│   └── plugin.json
└── bin/
    └── my-tool
```

[Plugins reference](../08-Plugins-Skills/plugins-reference.md#standard-layout)

Other wins

Auto mode follow-ups: new `PermissionDenied` hook fires on classifier denials (return `retry: true` to let Claude try a different approach), and `/permissions` → Recently denied lets you retry manually with `r`

New `defer` value for `permissionDecision` in `PreToolUse` hooks: `-p` sessions pause at a tool call and exit with a `deferred_tool_use` payload so an SDK app or custom UI can surface it, then resume with `--resume`

`/buddy`: hatch a small creature that watches you code. An April Fools’ joke, no longer available

`disableSkillShellExecution` setting blocks inline shell from skills, custom commands, and plugin commands

Edit tool now works on files viewed via `cat` or `sed -n` without a separate Read

Hook output over 50K saved to disk with a path + preview instead of injected into context

Thinking summaries off by default in interactive sessions (`showThinkingSummaries: true` to restore)

Voice mode: push-to-talk modifier combos, Windows WebSocket, macOS Apple Silicon mic permission

`claude-cli://` deep links accept multi-line prompts (encoded `%0A`)

[Full changelog for v2.1.86–v2.1.91 →](changelog.md#2-1-86)

---

## Week 15 · April 6–10, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w15
Path: 02-Claude-Code-CLI/whats-new-2026-w15.md

# Week 15 · April 6–10, 2026

Copy pageCopy page

Ultraplan cloud planning, the Monitor tool with self-pacing /loop, /team-onboarding for packaging your setup, and /autofix-pr from your terminal.

Copy pageCopy page

Releases [v2.1.92 → v2.1.101](changelog.md#2-1-92)4 features · April 6–10

Ultraplanresearch preview

Kick off plan mode in the cloud from your terminal, then review the result in your browser. Claude drafts the plan in a Claude Code on the web session while your terminal stays free; when it’s ready you comment on individual sections, ask for revisions, and choose to execute remotely or send it back to your CLI. As of v2.1.101 the first run auto-creates a default cloud environment, so there’s no web setup step before you can try it.

Run the command, or just include the keyword in any prompt:

Claude Code

```python
/ultraplan migrate the auth service from sessions to JWTs
```

[Ultraplan guide](ultraplan.md)

Monitor toolv2.1.98

A new built-in tool that spawns a background watcher and streams its events into the conversation: each event lands as a new transcript message that Claude reacts to immediately. Tail a training run, babysit a PR’s CI, or auto-fix a dev server crash the moment it happens, all without a Bash sleep loop holding the turn open.

Ask Claude to watch something while you keep working:

Claude Code

```python
Tail server.log in the background and tell me the moment a 5xx shows up
```

This pairs with `/loop`, which now self-paces: omit the interval and Claude schedules the next tick based on the task, or reaches for the Monitor tool to skip polling altogether.

Claude Code

```python
/loop check CI on my PR
```

[Monitor tool reference](tools-reference.md#monitor-tool)

/autofix-prCLI

PR auto-fix landed on the web in Week 13. Now you can turn it on without leaving your terminal: `/autofix-pr` infers the open PR for your current branch and enables auto-fix for it on Claude Code on the web in one step. Push your branch, run the command, walk away; Claude watches CI and review comments and pushes fixes until it’s green.

Run it from the PR’s branch:

Claude Code

```python
/autofix-pr
```

[Auto-fix pull requests](claude-code-on-the-web.md#auto-fix-pull-requests)

/team-onboardingv2.1.101

Generates a teammate ramp-up guide from your local Claude Code usage. Run it in a project you know well and hand the output to a new teammate so they can replay your setup instead of starting from defaults.

Run it from a project you’ve spent real time in:

Claude Code

```python
/team-onboarding
```

[Commands reference](commands.md)

Other wins

Focus view: press `Ctrl+O` in flicker-free mode to collapse the view to your last prompt, a one-line tool summary with diffstats, and Claude’s final response

Guided [Amazon Bedrock](amazon-bedrock.md) and [Google Cloud’s Agent Platform](google-vertex-ai.md) setup wizards on the login screen: pick “3rd-party platform” for step-by-step auth, region, credential check, and model pinning

`/agents` gets a tabbed layout: a Running tab shows live subagents with a `● N running` count, plus Run agent and View running instance actions in the Library tab

Default effort level is now `high` for API-key, Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, Team, and Enterprise users (control with `/effort`)

`/cost` shows a per-model and cache-hit breakdown for subscription users

`/release-notes` is now an interactive version picker

Status line: new `refreshInterval` setting re-runs the command every N seconds, and `workspace.git_worktree` in the JSON input

`CLAUDE_CODE_PERFORCE_MODE`: Edit/Write fail on read-only files with a `p4 edit` hint instead of silently overwriting

OS CA certificate store is now trusted by default, so enterprise TLS proxies work without extra setup (`CLAUDE_CODE_CERT_STORE=bundled` to opt out)

Amazon Bedrock powered by Mantle: set `CLAUDE_CODE_USE_MANTLE=1`

Hardened Bash tool permissions: backslash-escaped flags, env-var prefixes, `/dev/tcp` redirects, and compound commands now prompt correctly

`UserPromptSubmit` hooks can set the session title via `hookSpecificOutput.sessionTitle`

[Full changelog for v2.1.92–v2.1.101 →](changelog.md#2-1-92)

---

## Week 16 · April 13–17, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w16
Path: 02-Claude-Code-CLI/whats-new-2026-w16.md

# Week 16 · April 13–17, 2026

Copy pageCopy page

Claude Opus 4.7 with the new xhigh effort level, Routines on Claude Code on the web, mobile push notifications that ping your phone when Claude needs you, a /usage breakdown that shows what’s driving your limits, and native binaries replacing the bundled JavaScript.

Copy pageCopy page

Releases [v2.1.105 → v2.1.113](changelog.md#2-1-105)5 features · April 13–17

Claude Opus 4.7new model

Anthropic’s strongest coding model yet is now the default on Max and Team Premium, and available everywhere else from `/model`. It adds a new `xhigh` effort level that sits between `high` and `max`: best results for most coding and agentic tasks, applied as the default the first time you switch to 4.7. `/effort` now opens an interactive arrow-key slider when you call it without arguments, so you can dial intelligence against speed without remembering the level names.

Switch model and effort in one go:

Claude Code

```python
> /model opus
> /effort xhigh
```

[Model config: effort levels](model-config.md#adjust-effort-level)

Routinesweb

Templated cloud agents that fire on a schedule, a GitHub event, or an API call. Define a routine once on Claude Code on the web with a prompt, the repos it can touch, and the connectors it needs, then let PR-opened, release-published, or your own webhook trigger it without your machine running. The trigger picker now covers GitHub events with optional filters and gives every routine a tokened `/fire` endpoint for external systems.

Create one from the web UI, or scaffold from your terminal:

Claude Code

```python
> /schedule daily PR review at 9am
```

[Routines guide](web-scheduled-tasks.md)

/usage breakdownCLI

More visibility into where your Claude Code usage goes. `/usage` now shows what’s driving your limits: parallel sessions, subagents, cache misses, and long context, each with a percentage of your last 24 hours and a tip to optimize it. Press `d` or `w` to switch between day and week views.

Run it any time:

Claude Code

```python
> /usage
```

[Commands reference](commands.md)

Mobile push notificationsmobile

With [Remote Control](remote-control.md) connected, Claude can send a push notification to your phone when a long task finishes or it needs a decision to keep going. Turn it on with “Push when Claude decides” in `/config`, or ask for one in your prompt. Useful when you kick off a long agent run and want to step away from the terminal.

Ask Claude to ping you when it’s done:

Claude Code

```python
> notify me when the tests pass
```

[Remote Control: mobile push notifications](remote-control.md#mobile-push-notifications)

Native binariesv2.1.113

The `claude` CLI now spawns a native per-platform binary instead of bundled JavaScript, so the installed `claude` command no longer invokes Node. The npm package pulls the right binary in through an optional dependency such as `@anthropic-ai/claude-code-darwin-arm64`, so your install command doesn’t change. The standalone installer already shipped this binary; npm now matches it.

Upgrade and check what you’re running:

```python
claude update
claude --version
```

[Setup guide](../01-Getting-Started/setup.md)

Other wins

New [`/ultrareview`](ultrareview.md): comprehensive code review in the cloud using parallel multi-agent analysis and an adversarial critique pass. Run it bare to review your current branch, or `/ultrareview <PR#>` for a specific PR

[Auto mode](permission-modes.md#eliminate-prompts-with-auto-mode) is now available for Max subscribers on Opus 4.7, and the `--enable-auto-mode` flag is no longer required

[Session recap](interactive-mode.md#session-recap) shows a one-line summary of what happened while you were away; run `/recap` on demand or turn it off from `/config`

New `/tui` command and `tui` setting switch between classic and flicker-free rendering mid-conversation; focus view moved from `Ctrl+O` to its own `/focus` command

Plugins can ship background watchers via a top-level `monitors` manifest key that auto-arms at session start or on skill invoke

”Auto (match terminal)” option in `/theme` follows your terminal’s dark/light mode

`/fewer-permission-prompts` scans your transcripts for common read-only Bash and MCP calls and proposes an allowlist for `.claude/settings.json`

Claude can now discover and run built-in commands like `/init`, `/review`, and `/security-review` via the Skill tool

`PreCompact` hooks can block compaction by exiting with code 2 or returning `“decision”:“block”`

`ENABLE_PROMPT_CACHING_1H` opts API key, Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry users into 1-hour prompt cache TTL

`sandbox.network.deniedDomains` setting carves specific domains out of a broader `allowedDomains` wildcard

`/undo` is now an alias for `/rewind`, and `/proactive` is an alias for `/loop`

Hardened Bash permissions: deny rules now match through `env`/`sudo`/`watch` wrappers, and `Bash(find:*)` allow rules no longer auto-approve `-exec` or `-delete`

[Full changelog for v2.1.105–v2.1.113 →](changelog.md#2-1-105)

---

## Week 17 · April 20–24, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w17
Path: 02-Claude-Code-CLI/whats-new-2026-w17.md

# Week 17 · April 20–24, 2026

Copy pageCopy page

/ultrareview opens as a research preview, automatic session recaps when you return to a terminal, custom color themes you can build and ship in plugins, and a redesigned Claude Code on the web.

Copy pageCopy page

Releases [v2.1.114 → v2.1.119](changelog.md#2-1-114)4 features · April 20–24

/ultrareviewresearch preview

Now in public research preview. Ultrareview runs a fleet of bug-hunting agents in the cloud against your branch or a PR, and findings land back in the CLI or Desktop automatically. Run it before merging critical changes such as auth or data migrations.

Review the branch you’re on:

Claude Code

```python
> /ultrareview
```

Or point it at a PR:

Claude Code

```python
> /ultrareview 1234
```

[Ultrareview guide](ultrareview.md)

Session recapCLI

Switch focus away from a session and come back to a one-line recap of what happened while you were gone. Helpful for staying in flow while running several Claude sessions at once.

Generate a recap on demand, or turn the automatic one off from `/config`:

Claude Code

```python
> /recap
```

[Interactive mode: session recap](interactive-mode.md#session-recap)

Custom themesv2.1.118

Build and switch between named color themes from `/theme`, or hand-edit JSON files in `~/.claude/themes/`. Each theme picks a base preset and overrides only the tokens you care about. Plugins can ship themes too.

Open the theme picker and create a new one:

Claude Code

```python
> /theme
```

[Terminal config: create a custom theme](terminal-config.md#create-a-custom-theme)

Claude Code on the webweb

A new look for [claude.ai/code](https://claude.ai/code) that matches the redesigned desktop app: sessions sidebar, drag-and-drop layout, and a refreshed routines view. Key parts were rebuilt for quicker responses and a more reliable experience.

[Claude Code on the web](claude-code-on-the-web.md)

Other wins

[Vim visual mode](interactive-mode.md#vim-editor-mode): press `v` for character selection or `V` for line selection in the prompt input, with operators and visual feedback

Hooks can now call MCP tools directly via [`type: “mcp_tool”`](../07-Hooks/hooks.md#mcp-tool-hook-fields), so a hook can hit an already-connected server without spawning a process

`/cost` and `/stats` are merged into [`/usage`](commands.md); the old names still work as typing shortcuts that open the relevant tab

`/config` changes (theme, editor mode, verbose, and similar) now persist to `~/.claude/settings.json` and follow the same project/local/policy precedence as other [settings](settings.md)

[Forked subagents](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation) can be enabled on external builds with `CLAUDE_CODE_FORK_SUBAGENT=1`: a fork inherits your full conversation context instead of starting fresh

Default [effort level](model-config.md#adjust-effort-level) for Pro and Max subscribers on Opus 4.6 and Sonnet 4.6 is now `high` (was `medium`)

Native macOS and Linux builds replace the `Glob` and `Grep` tools with embedded `bfs` and `ugrep` available through Bash, for faster searches without a separate tool round-trip

`--from-pr` now accepts GitLab merge request, Bitbucket pull request, and GitHub Enterprise PR URLs in addition to github.com

Auto mode: include `“$defaults”` in [`autoMode.allow`, `soft_deny`, or `environment`](auto-mode-config.md) to add custom rules alongside the built-in list instead of replacing it

New [`claude plugin tag`](../08-Plugins-Skills/plugins-dependencies.md#tag-plugin-releases-for-version-resolution) command creates release git tags for plugins with version validation

Opus 4.7 sessions now compute against the model’s native 1M context window, fixing inflated `/context` percentages and premature autocompaction

`/resume` on large sessions is up to 67% faster and now offers to summarize stale, large sessions before re-reading them

[Full changelog for v2.1.114–v2.1.119 →](changelog.md#2-1-114)

---

## Week 18 · April 27 – May 1, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w18
Path: 02-Claude-Code-CLI/whats-new-2026-w18.md

# Week 18 · April 27 – May 1, 2026

Copy pageCopy page

Claude Code on Windows runs without Git Bash, claude auth login accepts a pasted OAuth code when the browser callback can’t reach localhost, claude project purge cleans up local state per project, and pasting a PR URL into /resume finds the session that created it.

Copy pageCopy page

Releases [v2.1.120 → v2.1.126](changelog.md#2-1-120)4 features · April 27 – May 1

Sign in without a browser callbackv2.1.126

`claude auth login` now accepts the OAuth code pasted directly into the terminal when the browser callback can’t reach localhost. That covers WSL2, SSH sessions, and containers, where the redirect to a local port doesn’t work. The same release also fixes login timeouts on slow or proxied connections and in IPv6-only devcontainers.

Sign in, then paste the code from the browser:

```python
claude auth login
```

[CLI reference](cli-reference.md#cli-commands)

claude project purgev2.1.124

Delete all Claude Code state for a project: transcripts, tasks, file history, and the project’s config entry. Supports `--dry-run` to preview, `-y`/`--yes` to skip confirmation, `-i`/`--interactive` to choose, and `--all` to clear every project.

Preview what would be removed:

```python
claude project purge --dry-run
```

Then run it for real:

```python
claude project purge
```

[CLI reference](cli-reference.md)

Resume by PR URLv2.1.122

When you create a pull request with `gh pr create`, Claude Code links it to the session that produced it. Now you can get back to that session from the PR URL alone, without remembering its name.

Open the session picker:

Claude Code

```python
> /resume
```

Paste the PR URL into the picker. The first character of the paste drops you into search mode, and the list filters to the session that created that PR. Press Enter to resume it. GitHub, GitHub Enterprise, GitLab, and Bitbucket pull and merge request URLs all work.

Claude Code

```python
https://github.com/your-org/your-repo/pull/1234
```

To open the picker already filtered to the PR, pass the PR number on the command line:

```python
claude --from-pr 1234
```

[Sessions: use the session picker](sessions.md#use-the-session-picker)

Windows without Git BashWindows

Git for Windows is no longer required. When Bash is absent, Claude Code uses PowerShell as the shell tool, and when the PowerShell tool is enabled it is treated as the primary shell. PowerShell 7 installed via the Microsoft Store, MSI without PATH, or a `.NET` global tool is now detected automatically.

[Setup guide](../01-Getting-Started/setup.md)

Other wins

MCP servers can opt out of tool-search deferral with `alwaysLoad: true` in their config so all of that server’s tools are always available

New `claude plugin prune` removes orphaned auto-installed plugin dependencies, and `plugin uninstall --prune` cascades

`/skills` now has a type-to-filter search box so you can find a skill in a long list without scrolling

`PostToolUse` hooks can replace tool output for any tool via `hookSpecificOutput.updatedToolOutput`, not only MCP tools

New [`claude ultrareview`](ultrareview.md) subcommand runs `/ultrareview` non-interactively from CI or scripts: prints findings to stdout (`--json` for raw output) and exits 0 on completion or 1 on failure

`--dangerously-skip-permissions` now bypasses prompts for writes to `.claude/`, `.git/`, `.vscode/`, shell config files, and other previously protected paths, while catastrophic removal commands still prompt as a safety net

The `/model` picker can list models from your gateway’s `/v1/models` endpoint when `ANTHROPIC_BASE_URL` points at an Anthropic-compatible gateway; opt in with `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` since v2.1.129

MCP servers that hit a transient error during startup now auto-retry up to 3 times instead of staying disconnected

`ANTHROPIC_BEDROCK_SERVICE_TIER` selects an Amazon Bedrock service tier: `default`, `flex`, or `priority`

`/terminal-setup` enables iTerm2’s clipboard access setting so `/copy` works, including from tmux

Google Cloud’s Agent Platform now supports X.509 certificate-based Workload Identity Federation (mTLS ADC)

Significant memory leak fixes: image-heavy sessions, `/usage` on large transcript histories, and long-running tools without progress events

[Full changelog for v2.1.120–v2.1.126 →](changelog.md#2-1-120)

---

## Week 19 · May 4–8, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w19
Path: 02-Claude-Code-CLI/whats-new-2026-w19.md

# Week 19 · May 4–8, 2026

Copy pageCopy page

Load plugins from .zip archives and URLs, search command history across every project with Ctrl+R, branch new worktrees from local HEAD or the remote default, and block actions unconditionally with auto mode hard deny rules.

Copy pageCopy page

Releases [v2.1.128 → v2.1.136](changelog.md#2-1-128)2 features · May 4–8

Plugins from .zip archives and URLs

`--plugin-dir` now accepts a `.zip` plugin archive in addition to a directory, and the new `--plugin-url` flag fetches a plugin archive from a URL for the current session. Useful for trying a plugin before adding it to a marketplace, or for shipping internal plugins from an artifact store.

Load a plugin straight from a URL:

terminal

```python
claude --plugin-url https://example.com/my-plugin.zip
```

[Plugins guide](../08-Plugins-Skills/plugins.md)

History search across all your projectsv2.1.129

`Ctrl+R` reverse-search now defaults to all prompts across every project, restoring the behavior from before v2.1.124. Press `Ctrl+S` while searching to narrow back to the current project or session. Handy when you remember a command you ran in another repo last week and don’t want to go digging for it.

[Interactive mode: command history](interactive-mode.md#command-history)

Other wins

New `worktree.baseRef` setting (`fresh` \| `head`) controls whether `--worktree`, the `EnterWorktree` tool, and agent-isolation worktrees branch from the remote default branch or local `HEAD`; the default `fresh` keeps unpushed commits out of new worktrees

New `settings.autoMode.hard_deny` rules block matching actions unconditionally in auto mode, regardless of allow exceptions, for actions that should never run automatically even when broader allow rules apply

Hooks now receive the active effort level via the `effort.level` JSON input field and the `$CLAUDE_EFFORT` environment variable, and Bash tool commands can read `$CLAUDE_EFFORT`

`CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1` opts out of the fullscreen alternate-screen renderer and keeps the conversation in the terminal’s native scrollback

`CLAUDE_CODE_PACKAGE_MANAGER_AUTO_UPDATE` lets Homebrew or WinGet installations run the upgrade in the background and prompt to restart

`CLAUDE_CODE_SESSION_ID` is now in the Bash tool subprocess environment, matching the `session_id` passed to hooks

`/mcp` now shows the tool count for connected servers and flags servers that connected with 0 tools

`--channels` now works with console (API key) authentication

Subprocesses such as Bash, hooks, MCP, and LSP no longer inherit `OTEL_*` environment variables, so OTEL-instrumented apps run via the Bash tool no longer pick up the CLI’s own OTLP endpoint

Sub-agent progress summaries now hit the prompt cache, cutting `cache_creation` token cost by roughly 3x

Several OAuth and credential reliability fixes: parallel sessions no longer dead-end at 401 after a refresh-token race, MCP OAuth refresh tokens are no longer lost when multiple servers refresh concurrently, and a rare login loop from a concurrent credential write is fixed

New `parentSettingsBehavior` admin key lets admins opt SDK `managedSettings` into the policy merge

[Full changelog for v2.1.128–v2.1.136 →](changelog.md#2-1-128)

---

## Week 20 · May 11–15, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w20
Path: 02-Claude-Code-CLI/whats-new-2026-w20.md

# Week 20 · May 11–15, 2026

Copy pageCopy page

Manage every Claude Code session from one screen with agent view, keep Claude working toward a goal until a condition holds, and run fast mode on Opus 4.7 by default.

Copy pageCopy page

Releases [v2.1.139 → v2.1.142](changelog.md#2-1-139)3 features · May 11–15

Agent viewresearch preview

`claude agents` opens one screen for every Claude Code session: what’s running, what’s blocked on your input, and what’s done. Dispatch a bug fix, a pull request review, and a flaky-test investigation as three rows, keep working in another window, and step in only when a row needs you. Attach to any row to drop into its full conversation, then press `←` to return to the list. Each background session keeps running without a terminal attached.

Open the dashboard from your shell:

terminal

```python
claude agents
```

[Agent view](../09-Agents-Patterns/agent-view.md)

/goalv2.1.139

Set a completion condition and Claude keeps working toward it across turns without you prompting each step. After every turn, a fast model checks whether the condition holds; if not, Claude starts another turn instead of handing control back. Useful for substantial work with a verifiable end state, like migrating a module until every call site compiles and tests pass. The goal clears once the condition is met, and works in interactive, `-p`, and Remote Control.

Set a goal and let Claude run until it holds:

Claude Code

```python
> /goal all tests in test/auth pass and the lint step is clean
```

[Goals](goal.md)

Fast mode on Opus 4.7research preview

`/fast` now runs on Opus 4.7 by default instead of Opus 4.6. Fast mode is a high-speed Opus configuration: the same model quality at about 2.5x the speed for a higher per-token cost, useful for rapid iteration and live debugging. Pricing is unchanged at \$30/\$150 per MTok, the same as Opus 4.6 fast mode. To pin fast mode to Opus 4.6, set `CLAUDE_CODE_OPUS_4_6_FAST_MODE_OVERRIDE=1`.

Toggle fast mode, now running on Opus 4.7:

Claude Code

```python
> /fast
```

[Fast mode on Opus 4.7](fast-mode.md#understand-the-cost-tradeoff)

Other wins

`claude agents` gained dispatch flags (`--add-dir`, `--settings`, `--mcp-config`, `--plugin-dir`, `--permission-mode`, `--model`, `--effort`, `--dangerously-skip-permissions`) to configure background sessions, and `claude agents --cwd <path>` scopes the session list to a directory

New hook `args: string[]` exec form spawns the command directly without a shell, so path placeholders never need quoting

New `continueOnBlock` config option for `PostToolUse` hooks feeds the hook’s rejection reason back to Claude and continues the turn instead of ending it

New `terminalSequence` field in hook JSON output lets hooks emit desktop notifications, window titles, and bells without a controlling terminal

The Rewind menu added “Summarize up to here” to compress earlier context while keeping recent turns intact

Remote Control, `/schedule`, claude.ai MCP connectors, and notification preferences are now disabled when `ANTHROPIC_API_KEY`, `apiKeyHelper`, or `ANTHROPIC_AUTH_TOKEN` is set, even alongside a claude.ai login; unset the API key to use these features

MCP stdio servers now receive `CLAUDE_PROJECT_DIR` in their environment, matching hooks, and plugin configs can reference `$CLAUDE_PROJECT_DIR` in commands

`claude plugin details <name>` shows a plugin’s component inventory and projected per-session token cost, and the `/plugin` details pane now also lists the LSP servers a plugin provides

Plugins with a root-level `SKILL.md` and no `skills/` subdirectory are now surfaced as a skill

`/feedback` can now include recent sessions from the last 24 hours or 7 days for issues spanning more than the current session

Agent tool `subagent_type` now matches case- and separator-insensitively, so `“Code Reviewer”` resolves to `code-reviewer`

[Full changelog for v2.1.139–v2.1.142 →](changelog.md#2-1-139)

---

## Week 21 · May 18–22, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w21
Path: 02-Claude-Code-CLI/whats-new-2026-w21.md

# Week 21 · May 18–22, 2026

Copy pageCopy page

Use auto mode on the Pro plan and with Sonnet 4.6, see which skills, subagents, and MCP servers drive your plan limits in /usage, and review diffs with the new /code-review command.

Copy pageCopy page

Releases [v2.1.143 → v2.1.149](changelog.md#2-1-143)1 feature · May 18–22

Auto mode on the Pro planCLI

Auto mode is now available on the Pro plan and supports Sonnet 4.6 alongside Opus. It replaces permission prompts with background safety checks: routine actions run without interrupting you, and destructive or suspicious ones are blocked and surfaced.

Update Claude Code, then cycle modes with Shift+Tab; auto mode appears in the cycle once your account meets the requirements:

terminal

```python
claude update
```

The command prints `Successfully updated` with the new version number, or `Claude Code is up to date` if no update is needed. Once auto mode is active, the prompt footer shows `auto mode on`.

[Auto mode requirements](permission-modes.md#eliminate-prompts-with-auto-mode)

Other wins

[`/usage`](../17-Billing-Plans/costs.md#track-your-costs) now shows a per-category breakdown of what’s driving your plan limits, attributing recent usage to skills, subagents, plugins, and individual MCP servers

”Extra usage” is renamed to “usage credits” across the CLI, and `/extra-usage` is now `/usage-credits`. The old name still works. The command requires signing in with your claude.ai subscription through `/login` and isn’t available with API key authentication.

New [`/code-review`](code-review.md) command reports correctness bugs at a chosen effort level such as `/code-review high`, and `--comment` posts findings as inline GitHub PR comments. `/simplify` remains as a separate cleanup-only review.

Background sessions now appear in `/resume` alongside interactive ones, marked with `bg`, and sessions pinned with `Ctrl+T` in `claude agents` stay alive when idle

`claude agents --json` lists live sessions as JSON for scripting, such as status bars and session pickers

The PowerShell tool is now enabled by default on Windows for Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry users; opt out with `CLAUDE_CODE_USE_POWERSHELL_TOOL=0`

`claude plugin disable` now refuses when another enabled plugin depends on the target, and `claude plugin enable` force-enables transitive dependencies

The `/plugin` marketplace browse pane shows projected context cost, and the Discover and Browse screens list a plugin’s commands, agents, skills, hooks, and MCP/LSP servers before installation

New `worktree.bgIsolation: “none”` setting lets background sessions edit the working copy directly without `EnterWorktree`, for repos where worktrees are impractical

Markdown output renders GFM task list checkboxes, and the `/diff` detail view scrolls with the keyboard

Status line JSON input now includes GitHub repo and PR information when detected

Enterprise: the `allowAllClaudeAiMcps` managed setting loads claude.ai cloud MCP connectors alongside `managed-mcp.json`

[Full changelog for v2.1.143–v2.1.149 →](changelog.md#2-1-143)

---

## Week 22 · May 25–29, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w22
Path: 02-Claude-Code-CLI/whats-new-2026-w22.md

# Week 22 · May 25–29, 2026

Copy pageCopy page

Run Claude Code on Claude Opus 4.8, orchestrate large tasks with dynamic workflows, catch security issues with the security-guidance plugin, and use fast mode on Opus 4.8 at a lower price.

Copy pageCopy page

Releases [v2.1.150 → v2.1.157](changelog.md#2-1-150)4 features · May 25–29

Claude Opus 4.8new model

Opus 4.8 is now the default on Max, Team Premium, Enterprise pay-as-you-go, and the Anthropic API. It defaults to high effort; use `/effort xhigh` for harder tasks. Requires v2.1.154 or later.

Switch to Opus 4.8 by name, or pick it from the model picker:

Claude Code

```python
/model claude-opus-4-8
```

[Model configuration](model-config.md#available-models)

Dynamic workflowsresearch preview

A workflow is an orchestration script Claude writes for your task and runs across many subagents in the background. Use one when a task is too large for one conversation to coordinate: a codebase-wide audit, a large migration, a research question that needs cross-checking. Manage runs with `/workflows`.

Describe the task and ask for a workflow:

Claude Code

```python
create a workflow that migrates every internal fetch() call to the new HttpClient wrapper
```

[Dynamic workflows](workflows.md)

Security guidance pluginplugin

The security-guidance plugin reviews Claude’s code changes for vulnerabilities and fixes them in the same session. It runs a fast pattern check on each edit, a model review at the end of each turn, and a deeper agentic review on commit or push. Add project rules in `.claude/claude-security-guidance.md`.

Install it from the official Anthropic marketplace:

Claude Code

```python
/plugin install security-guidance@claude-plugins-official
```

Then activate it in the current session:

Claude Code

```python
/reload-plugins
```

[Security guidance plugin](security-guidance.md)

Fast mode on Opus 4.8research preview

Fast mode now defaults to Opus 4.8 at \$10/\$50 per MTok: 2x the standard rate for about 2.5x the speed. Opus 4.7 and 4.6 stay at \$30/\$150. Opus 4.6 fast mode is deprecated.

Toggle fast mode, now on Opus 4.8:

Claude Code

```python
/fast
```

[Fast mode pricing](fast-mode.md#understand-the-cost-tradeoff)

Other wins

In `claude agents`, prefix a shell command with `!` to run it as a background job you can attach to and detach from; also available as `claude --bg --exec 'pytest -x'`

Plugins in `.claude/skills` directories are now loaded automatically, no marketplace required, and `claude plugin init <name>` scaffolds a new plugin

New `/reload-skills` command re-scans skill directories without restarting, and `SessionStart` hooks can return `reloadSkills: true` to make skills they install available in the same session

Skills and commands can set `disallowed-tools` in frontmatter to remove tools from the model while the skill is active

New `MessageDisplay` hook event lets hooks transform or hide assistant message text as it is displayed

Claude Code now switches to your configured `--fallback-model` for the rest of the session when the primary model is not found, instead of failing every request

Plugins can declare `defaultEnabled: false` in `plugin.json` or a marketplace entry, so they install without turning on until you enable them

Vim mode: `/` in NORMAL mode opens reverse history search, matching Bash and Zsh vi-mode

Streaming tool execution is now always enabled, including with telemetry disabled and on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry

`←←` to open the agents view now works on Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and with telemetry disabled

Claude in Chrome: pick which connected browser to use via `/chrome` → “Select browser…”, or in-chat when a browser action runs with multiple connected

`claude mcp list` and `claude mcp get` now show unapproved `.mcp.json` servers as pending approval instead of auto-approving and connecting when output is piped

[Full changelog for v2.1.150–v2.1.157 →](changelog.md#2-1-150)

---

## Week 23 · June 1–5, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w23
Path: 02-Claude-Code-CLI/whats-new-2026-w23.md

# Week 23 · June 1–5, 2026

Copy pageCopy page

Run auto mode on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry, prompt before writing files that can run code in acceptEdits mode, list installed plugins with /plugin list, and require an approved version range for managed deployments.

Copy pageCopy page

Releases [v2.1.158 → v2.1.165](changelog.md#2-1-158)4 features · June 1–5

Auto mode on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundryv2.1.158

Auto mode is now available on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry for Opus 4.7 and Opus 4.8, replacing permission prompts with background safety checks on third-party providers. Opt in by setting `CLAUDE_CODE_ENABLE_AUTO_MODE=1`.

Opt in on a third-party provider, then cycle to auto mode with Shift+Tab:

terminal

```python
export CLAUDE_CODE_ENABLE_AUTO_MODE=1
```

[Auto mode on third-party providers](permission-modes.md#enable-auto-mode-on-bedrock-agent-platform-or-foundry)

Safer automatic editsv2.1.160

Claude Code now prompts before writing files that can run code, even in `acceptEdits` mode. The protected set covers shell startup files such as `.zshenv` and `.bash_login`, git config under `~/.config/git/`, and build-tool configs such as `.npmrc`, `.bazelrc`, and `.pre-commit-config.yaml`. These writes are never auto-approved in any mode except `bypassPermissions`.

Work in acceptEdits mode; Claude now pauses before writing these files:

terminal

```python
claude --permission-mode acceptEdits
```

[Protected paths](permission-modes.md#protected-paths)

List installed plugins with /plugin listv2.1.163

The new `/plugin list` command prints your installed plugins inline, without opening the `/plugin` menu, and is also available as `claude plugin list` from the shell. In the interactive form, add `--enabled` or `--disabled` to show only plugins in that state.

List the plugins that are currently turned on:

Claude Code

```python
> /plugin list --enabled
```

[Plugin commands](../08-Plugins-Skills/plugins-cli-reference.md#plugin-list)

Version requirements for managed deploymentsv2.1.163

Two managed settings, `requiredMinimumVersion` and `requiredMaximumVersion`, let your organization require an approved Claude Code version range. A client outside the range exits at startup and tells the user to update through the organization’s method. `claude update`, `claude install`, and `claude doctor` keep working so users can still recover.

Add a floor to your managed settings so older clients refuse to start:

managed-settings.json

```python
{
  "requiredMinimumVersion": "2.1.163"
}
```

[Decide what to enforce](../13-Enterprise-Admin/admin-setup.md#decide-what-to-enforce)

Other wins

The trigger keyword for [dynamic workflows](workflows.md) changed from `workflow` to `ultracode`; asking for a workflow in your own words still works, and the keyword is highlighted in violet in the prompt

[Stop and SubagentStop hooks](../07-Hooks/hooks.md) can return `hookSpecificOutput.additionalContext` to give Claude feedback and keep the turn going instead of being treated as an error

`claude mcp` list, get, and add no longer print secrets: environment-variable references are not expanded, and credential headers and URL secrets are redacted

A failed Bash command in a parallel tool batch no longer cancels the others; each tool returns its own result independently

Editing a file no longer needs a separate Read first when you viewed it with a single-file `grep`, `egrep`, or `fgrep`

Clicking a command in the autocomplete menu now fills it into your prompt instead of running it immediately; press Enter to run

Listing `Grep` or `Glob` in `--tools` now provides the dedicated search tools on native builds with embedded search, instead of silently ignoring those names

`/effort` now confirms when your chosen level will persist as the default for new sessions

`OTEL_RESOURCE_ATTRIBUTES` values are now attached as labels on metric datapoints, so you can slice usage metrics by custom dimensions like team or repo

Windsurf is renamed to Devin Desktop in `/ide`, `/terminal-setup`, and `/scroll-speed`, following the editor’s rebrand

`/btw` gains a `c to copy` shortcut that copies the raw markdown answer to the clipboard

[Full changelog for v2.1.158–v2.1.165 →](changelog.md#2-1-158)

---

## Week 24 · June 8–12, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w24
Path: 02-Claude-Code-CLI/whats-new-2026-w24.md

# Week 24 · June 8–12, 2026

Copy pageCopy page

Move a session to a new directory with /cd, let subagents spawn their own subagents, and troubleshoot a broken configuration with safe mode.

Copy pageCopy page

Releases [v2.1.166 → v2.1.176](changelog.md#2-1-166)3 features · June 8–12

Move a session with /cdv2.1.169

The new `/cd` command moves the current session to a different working directory without rebuilding the prompt cache: the new directory’s `CLAUDE.md` is appended as a message instead of replacing the system prompt. The session relocates to the new directory’s project storage, so `--resume` and `--continue` find it there. Claude prompts you to trust the directory if you haven’t worked in it before.

Move the session into another project without restarting:

Claude Code

```python
> /cd ../other-project
```

[Commands reference](commands.md#all-commands)

Subagents can spawn subagentsv2.1.172

Subagents can now spawn their own subagents. The subagent panel below the prompt shows the full tree: each row carries a count of its descendants and a path back to `main`. Subagent chains are capped at five levels deep to prevent runaway concurrent trees.

Open the agents view to watch the nested tree as work fans out:

Claude Code

```python
> /agents
```

[Spawn nested subagents](../09-Agents-Patterns/sub-agents.md#let-subagents-spawn-their-own-subagents)

Troubleshoot with safe modev2.1.169

Start Claude Code with `--safe-mode`, or set `CLAUDE_CODE_SAFE_MODE`, to launch with all customizations disabled: `CLAUDE.md`, skills, plugins, hooks, MCP servers, and custom commands and agents do not load. Authentication, model selection, built-in tools, and permissions still work. If a problem disappears in safe mode, one of those surfaces is the cause.

Launch a clean session to isolate a broken configuration:

terminal

```python
claude --safe-mode
```

[Test against a clean configuration](debug-your-config.md#test-against-a-clean-configuration)

Other wins

[`fallbackModel`](model-config.md#fallback-model-chains) configures up to three fallback models tried in order when the primary is overloaded or unavailable, and `--fallback-model` now applies to interactive sessions too

Session titles are now generated in the language of your conversation; pin a specific one with the `language` setting

`claude agents --json` adds `--all` to include completed sessions plus new `id` and `state` fields, and no longer omits blocked or newly dispatched sessions

Browsing a marketplace’s plugins in `/plugin` now has a search bar

New `disableBundledSkills` setting and `CLAUDE_CODE_DISABLE_BUNDLED_SKILLS` hide bundled skills, workflows, and built-in commands from the model

Deny rules accept a glob in the tool-name position, so `”*”` denies all tools, and unknown tool names in deny rules now warn at startup

Agent messaging is hardened: messages relayed via `SendMessage` from other agents no longer carry user authority, and auto mode blocks them

Amazon Bedrock reads the AWS region from `~/.aws` config files when `AWS_REGION` is unset, and `/status` shows where the region came from

New `enforceAvailableModels` managed setting makes the `availableModels` allowlist also constrain the Default model

Claude in Chrome browser tools now load in a single batched call instead of one per tool

`claude update` announces the target version before downloading instead of going silent

New `footerLinksRegexes` setting adds regex-matched link badges to the footer row

[Full changelog for v2.1.166–v2.1.176 →](changelog.md#2-1-166)

---

## Week 25 · June 15–19, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w25
Path: 02-Claude-Code-CLI/whats-new-2026-w25.md

# Week 25 · June 15–19, 2026

Copy pageCopy page

Publish a live, shareable page from your session with Artifacts, match tool parameters in deny and ask rules, and set any setting from the prompt with /config.

Copy pageCopy page

Releases [v2.1.178 → v2.1.183](changelog.md#2-1-178)3 features · June 15–19

Artifacts

An artifact is a live, interactive page that Claude Code publishes from your session to a private URL on claude.ai, and it updates in place as the session keeps working. Ask for one when terminal text is the wrong medium, such as a PR walkthrough with the diff annotated inline or a dashboard built from session data. Artifacts are in beta on Team and Enterprise plans.

Ask Claude for a page, then approve the publish prompt:

Claude Code

```python
Make an artifact that walks through this PR with the diff annotated inline.
```

[Create an artifact](artifacts.md#create-an-artifact)

Match by input parameterv2.1.178

Deny and ask permission rules can now match a tool’s input parameters with the `Tool(param:value)` syntax. For example, `Agent(model:opus)` matches subagent spawns that request the Opus model tier. The value accepts `*` as a wildcard, so `Agent(isolation:*)` matches any explicit isolation value.

Add a parameter rule to the deny list in `settings.json`:

.claude/settings.json

```python
{
  "permissions": {
    "deny": ["Agent(model:opus)"]
  }
}
```

[Match by input parameter](permissions.md#match-by-input-parameter)

Set any setting from the promptv2.1.181

Pass `key=value` to `/config` to change a setting directly without opening the Settings interface. The syntax also works in non-interactive mode with the `-p` flag and from Remote Control.

Set the `thinking` setting from the prompt:

Claude Code

```python
/config thinking=false
```

[Commands reference](commands.md#all-commands)

Other wins

Auto mode now blocks destructive git commands (`git reset --hard`, `git clean -fd`, `git stash drop`) when you didn’t ask to discard local work, and blocks `terraform destroy` unless you asked for the specific stack

Set the new `attribution.sessionUrl` setting to `false` to omit the claude.ai session link from commits and PRs in web and Remote Control sessions

In the `/config` interface, Enter and Space both change the selected setting, and Esc now saves and closes instead of reverting

New `sandbox.allowAppleEvents` opt-in setting lets sandboxed commands send Apple Events on macOS

Point `CLAUDE_CLIENT_PRESENCE_FILE` at a marker file to suppress mobile push notifications while you’re at the machine

Long paragraphs now stream line by line instead of waiting for the first line break

API connection drops mid-thinking now retry automatically instead of showing “Connection closed while thinking”

With `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` set, every session has one implicit team, so you spawn teammates directly with the Agent tool’s `name` parameter

Skills in nested `.claude/skills` directories load when working on files there; on a name clash the nested skill appears as `<dir>:<name>` so both stay available

Fixed prompt caching not reading on a custom `ANTHROPIC_BASE_URL` and on Microsoft Foundry

Fixed Write and Edit producing zero-byte or truncated files on network drives and cloud-synced folders

[Full changelog for v2.1.178–v2.1.183 →](changelog.md#2-1-178)

---

## Week 26 · June 22–26, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w26
Path: 02-Claude-Code-CLI/whats-new-2026-w26.md

# Week 26 · June 22–26, 2026

Copy pageCopy page

Authenticate MCP servers from your shell with claude mcp login, get a response to shell mode command output with the ! prefix, and resume a conversation from before /clear with /rewind.

Copy pageCopy page

Releases [v2.1.185 → v2.1.193](changelog.md#2-1-185)2 features · June 22–26

Authenticate MCP servers from the CLIv2.1.186

New `claude mcp login <name>` and `claude mcp logout <name>` commands authenticate a configured MCP server from your shell instead of the interactive `/mcp` menu. `claude mcp login` runs the server’s OAuth flow directly, and `claude mcp logout` clears the stored credentials.

Run the OAuth flow for a configured server without opening a session:

terminal

```python
claude mcp login sentry
```

[Authenticate from the command line](../06-MCP-Tools/General/mcp.md#authenticate-from-the-command-line)

Shell mode responds to command outputv2.1.186

Commands you run with the `!` prefix now get a response from Claude once the output lands in the transcript, so you can run `! npm test` and get an explanation of the failures without a second prompt. The response costs the same as sending a normal prompt. To keep the earlier behavior, where the output is added to context without a response, set `respondToBashCommands` to `false` in `settings.json`.

Run a command and get a response to its output:

Claude Code

```python
> ! npm test
```

[Shell mode with the ! prefix](interactive-mode.md#shell-mode-with-prefix)

Other wins

`/rewind` can now resume a conversation from before `/clear` was run

New `sandbox.credentials` setting blocks sandboxed commands from reading credential files and secret environment variables

Org-configured model restrictions now apply to the model picker, `--model`, `/model`, and `ANTHROPIC_MODEL`, with a “restricted by your organization’s settings” message when a restricted model is selected

New `autoMode.classifyAllShell` setting routes all Bash and PowerShell commands through the auto-mode classifier, and denial reasons now show in the transcript, the denial toast, and `/permissions`

New `claude_code.assistant_response` OpenTelemetry log event carries the model’s response text; deployments that already log prompt content start receiving it on upgrade, so set `OTEL_LOG_ASSISTANT_RESPONSES=0` to keep prompts only

Background subagents now surface permission prompts in the main session instead of auto-denying; the dialog shows which agent is asking, and Esc denies only that tool

`/install-github-app` can now install only the GitHub App and skip the Actions workflow and secret steps

Hosts you allow in the sandbox network permission dialog are remembered for the rest of the session instead of re-prompting on every connection

Streaming responses use about 37% less CPU, and long-session memory growth from the terminal output cache is reduced

`/review <pr>` now uses the same review engine as `/code-review medium`

Bash mode `!` commands get live file path autocomplete

[Full changelog for v2.1.185–v2.1.193 →](changelog.md#2-1-185)

---

## Week 27 · June 29 – July 3, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w27
Path: 02-Claude-Code-CLI/whats-new-2026-w27.md

# Week 27 · June 29 – July 3, 2026

Copy pageCopy page

Claude Sonnet 5 becomes the default model, Claude in Chrome reaches general availability, subagents run in the background by default, Claude Desktop arrives on Linux in beta, and /radio tunes into Claude FM.

Copy pageCopy page

Releases [v2.1.195 → v2.1.201](changelog.md#2-1-195)5 features · June 29 – July 3

Claude Sonnet 5new model

Sonnet 5 is the new default model for Pro, Team Standard, and Enterprise subscription seats: top-tier coding and tool use at Sonnet pricing, with a native 1M-token context window and adaptive thinking on by default. API pricing is promotional at \$2/\$10 per MTok through August 31. Requires v2.1.197 or later.

Switch to Sonnet 5 by name, or pick it from the model picker:

Claude Code

```python
> /model claude-sonnet-5
```

[Model configuration](model-config.md#available-models)

Claude in Chrome is generally availablev2.1.198

The Chrome integration is out of preview for everyone on a direct Anthropic plan. Claude Code drives your browser through the Claude in Chrome extension: it opens tabs, clicks through pages, fills forms, reads console logs, and shares your login state, so it can test the app it builds without you switching contexts.

[Use Claude Code with Chrome](../03-IDE-Integrations/chrome.md)

Subagents run in the background by defaultv2.1.198

Claude now keeps working while subagents run and picks up their results when they finish, instead of pausing the conversation to wait. Claude still runs a subagent in the foreground when it needs the result before continuing, and background subagents surface every permission prompt in your main session. Pin a subagent’s behavior with the `background` frontmatter field.

[Run subagents in foreground or background](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background)

Claude Desktop on LinuxDesktop

The Claude desktop app is now available on Ubuntu 22.04+ and Debian 12+ in beta, on x86_64 and arm64. You get the same Chat, Cowork, and Claude Code experience as macOS and Windows: parallel sessions, visual diff review, an integrated terminal and editor, and live app preview. Installs from Anthropic’s apt repository, so updates arrive through regular package updates.

[Claude Desktop on Linux](../16-Mobile-Desktop/desktop-linux.md)

/radioCLI

Claude FM is on the air. `/radio` opens the lo-fi radio stream in your browser for something to code to, and prints the stream URL when no browser is available. Not available on Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry.

Tune in from any session:

Claude Code

```python
> /radio
```

[All commands](commands.md#all-commands)

Other wins

[Artifacts](artifacts.md) are now generally available and included on Pro and Max plans, joining Team and Enterprise

Admins can set an [organization default model](model-config.md#organization-default-model) in the org console; it shows as “Org default” in `/model` when you haven’t picked a model yourself

Stacked skill invocations like `/skill-a /skill-b do XYZ` now load all leading skills (up to 5), not only the first

`AskUserQuestion` dialogs no longer auto-continue by default; opt into an idle timeout via `/config`

The “default” permission mode is now named “Manual” across the CLI, `--help`, VS Code, and JetBrains; `--permission-mode manual` is accepted alongside `default`

New `/dataviz` skill gives chart and dashboard design guidance, with a runnable color-palette validator

The built-in Explore agent now inherits the main session’s model (capped at Opus) instead of running on Haiku

Background agents launched from `claude agents` now commit, push, and open a draft PR when they finish code work in a worktree, instead of stopping to ask

Hook matchers with hyphenated identifiers like `code-reviewer` now exact-match instead of substring-matching; use `mcp__brave-search__.*` to match all tools from a hyphenated MCP server

Transient server rate-limit errors unrelated to your usage limit are now retried automatically with backoff for subscribers instead of failing the turn

The streaming idle watchdog is now on by default for all providers: it aborts and retries when a response stream produces no events for 5 minutes (`CLAUDE_ENABLE_STREAM_WATCHDOG=0` to disable)

[Full changelog for v2.1.195–v2.1.201 →](changelog.md#2-1-195)

---

## Week 28 · July 6–10, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w28
Path: 02-Claude-Code-CLI/whats-new-2026-w28.md

# Week 28 · July 6–10, 2026

Copy pageCopy page

Browse external sites from the Desktop app’s built-in browser, run a full setup checkup with /doctor, and pick up auto mode transcript protections and agent view upgrades.

Copy pageCopy page

Releases [v2.1.202 → v2.1.206](changelog.md#2-1-202)2 features · July 6–10

In-app browser on DesktopDesktop

Claude Code on desktop now has a built-in browser. Claude can pull up docs, designs, or any other site, and read, click through, and interact with pages the same way it does with your local dev server previews. The browser is sandboxed and configurable: you choose whether browsing sessions persist, and safety classifiers review actions on external sites.

[Browse external sites](../16-Mobile-Desktop/desktop.md#browse-external-sites)

/doctor is a full setup checkupv2.1.205

`/doctor` now diagnoses issues and can fix them, instead of printing a read-only report. It checks installation health, finds unused skills, MCP servers, and plugins versus their context cost, deduplicates local `CLAUDE.md` files against checked-in ones, proposes trimming `CLAUDE.md` content Claude could derive from the codebase, and flags slow hooks. It reports findings first and asks for confirmation before changing anything. `/checkup` is its alias.

Run a checkup from any session:

Claude Code

```python
> /doctor
```

[All commands](commands.md#all-commands)

Other wins

Auto mode now blocks tampering with session transcript files, and asks before running `rm -rf` on a variable it can’t resolve from context

`/cd` now suggests directory paths as you type, matching `/add-dir`

`/commit-push-pr` auto-allows `git push` to the repo’s configured push remote in addition to `origin`

Gateway: `/login` now supports Anthropic-operated public gateway endpoints

`EnterWorktree` asks for confirmation before entering a git worktree outside the project’s `.claude/worktrees/` directory

Background agents upgrade to a new version in the background right after a Claude Code update, instead of paying a slow stale-session upgrade when you attach

Agent view rows now show a colored state word and a classifier-written headline instead of raw tool call text, and sessions that edit, merge, comment on, or push to an existing PR link it in `claude agents`

Auto-update binary downloads now stream to disk instead of buffering in memory, cutting the updater’s peak memory usage by roughly 400 MB

Background task notifications now explicitly state that no human input has occurred, preventing fabricated in-transcript approvals from being acted on

Improved `/code-review` findings quality on Opus 4.8 across all effort levels

[Full changelog for v2.1.202–v2.1.206 →](changelog.md#2-1-202)

---

## Week 29 · July 13–17, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w29
Path: 02-Claude-Code-CLI/whats-new-2026-w29.md

# Week 29 · July 13–17, 2026

Copy pageCopy page

Pull live data into published artifacts through MCP connectors, and use Claude Code with a screen reader in the new screen reader mode.

Copy pageCopy page

Releases [v2.1.207 → v2.1.212](changelog.md#2-1-207)2 features · July 13–17

Artifacts call your MCP connectorsweb

A published artifact can now call MCP connectors each time someone views it, so a dashboard shows live data and can take actions on demand rather than a snapshot from the session that built it. Each call runs through the viewing account’s own connections, and viewers approve access before the page’s first connector call. This week also adds public sharing links, editor roles for shared editing on Team and Enterprise plans, and artifacts created from Claude Tag sessions.

Name the connector and the data you want in your prompt:

Claude Code

```python
Build a dashboard artifact of open pull requests that pulls the live list through my GitHub connector when the page loads.
```

[Pull live data with MCP connectors](artifacts.md#pull-live-data-with-mcp-connectors)

Screen reader modeCLI

Screen reader mode replaces the visual terminal interface with plain, linear text: instead of boxes, spinners, and in-place redraws, Claude Code prints labeled lines that a screen reader such as VoiceOver or NVDA reads in order, so you can approve permissions and review output end to end. Turn it on per session with a flag, per shell with the `CLAUDE_AX_SCREEN_READER` environment variable, or everywhere with the `axScreenReader` setting.

Start a session in screen reader mode:

terminal

```python
claude --ax-screen-reader
```

[Turn on screen reader mode](accessibility.md#turn-on-screen-reader-mode)

Other wins

`/fork` now copies your conversation into a new background session with its own row in `claude agents` while you keep working; the in-session forked subagent it used to launch is now `/subtask`

[Auto mode](permission-modes.md#enable-auto-mode-on-bedrock-agent-platform-or-foundry) no longer needs the `CLAUDE_CODE_ENABLE_AUTO_MODE` opt-in on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry; administrators can turn it off with `disableAutoMode`

MCP tool calls that run longer than two minutes now move to the background automatically so the session stays usable; tune or disable the threshold with `CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS`

New `claude auto-mode reset` restores the default auto-mode configuration, and `--yes` skips the confirmation prompt

New [corporate launcher](../13-Enterprise-Admin/corporate-launcher.md) support: `CLAUDE_CODE_PROCESS_WRAPPER` or the `processWrapper` setting runs the processes Claude Code starts from its own binary, such as the background service and agent view sessions, through a required wrapper executable

`vimInsertModeRemaps` setting maps two-key insert-mode sequences such as `jj` to Escape in vim mode

`--forward-subagent-text` and `CLAUDE_CODE_FORWARD_SUBAGENT_TEXT` include subagent text and thinking blocks in [stream-json output](headless.md)

Session-wide caps stop runaway loops: WebSearch calls and subagent spawns each default to 200, tunable with `CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION` and `CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION`

”Always allow” permission rules save at the repository root, so approvals granted in a git worktree persist across sessions and worktrees

Amazon Bedrock, Google Cloud’s Agent Platform, and Claude Platform on AWS now default to Claude Opus 4.8

The collapsed tool summary line shows a live elapsed-time counter, so long-running tool calls visibly tick instead of looking stuck

[Full changelog for v2.1.207–v2.1.212 →](changelog.md#2-1-207)

---

## Week 30 · July 20–24, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w30
Path: 02-Claude-Code-CLI/whats-new-2026-w30.md

# Week 30 · July 20–24, 2026

Copy pageCopy page

Opus 5 becomes the default Opus model, Claude Code Desktop adds an iOS Simulator pane, and the Claude Security plugin scans your code for vulnerabilities.

Copy pageCopy page

Releases [v2.1.214 → v2.1.219](changelog.md#2-1-214)3 features · July 20–24

Claude Opus 5new model

Claude Opus 5 is the new default Opus model in Claude Code. It’s the default on Max, Team Premium, Enterprise pay-as-you-go, and the Anthropic API, and on Claude Platform on AWS, Amazon Bedrock, and Google Cloud’s Agent Platform. On the Anthropic API and on Max, Team, and Enterprise plans, Opus 5 runs with a [1M-token context window](model-config.md#extended-context); on Amazon Bedrock and Google Cloud’s Agent Platform, select the 1M model variant. Fast mode moves to Opus 5 at \$10/\$50 per MTok. Requires v2.1.219 or later.

Switch to Opus 5 by name, or pick it from the model picker:

Claude Code

```python
> /model claude-opus-5
```

[Model configuration](model-config.md#available-models)

iOS Simulator in Claude Code DesktopDesktop

Claude Code Desktop on macOS gets an iOS Simulator pane, in public beta on Pro, Max, and Team plans. When Claude builds, launches, or checks your app in a simulator, the pane opens next to the conversation and streams the device screen live, so you can watch Claude tap through the app to verify its changes or drive the device yourself. Requires Xcode with the iOS platform installed, and Claude Desktop v1.24012.0 or later.

Ask Claude to run or test your app, and the pane opens when the app launches:

Claude Code

```python
> Build the app and run it in the simulator to check the onboarding flow.
```

[Test iOS apps in the simulator](../16-Mobile-Desktop/desktop-ios-simulator.md#run-your-app-in-the-simulator)

Claude Security pluginplugin

The Claude Security plugin runs a multi-agent vulnerability scan of your codebase inside a Claude Code session: agents map your architecture, build a threat model, hunt for vulnerabilities, and independently review every finding before writing the report to a `CLAUDE-SECURITY-<timestamp>/` directory. Scan a whole repository or only a branch’s diff, a pull request, or a single commit, then turn the findings you choose into reviewed patches that you apply yourself.

Install the plugin from the official Anthropic marketplace, run `/reload-plugins`, then start a scan with `/claude-security`:

Claude Code

```python
> /plugin install claude-security@claude-plugins-official
```

[Scan and fix your codebase](claude-security.md#scan-and-fix-your-codebase)

Other wins

[`/code-review`](code-review-local.md) now runs as a background subagent with its own context window, so review work stays out of your conversation and the findings arrive when it completes

`/verify`, `/code-review`, and `/deep-research` run only when you invoke them; Claude no longer launches them on its own

[Emoji shortcodes](interactive-mode.md#emoji-shortcodes) autocomplete in the prompt input: type `:heart:` to insert an emoji, or two or more characters after `:` for suggestions; turn it off with `emojiCompletionEnabled`

Skills with `context: fork` [run in the background](../08-Plugins-Skills/skills.md#run-skills-in-a-subagent) by default, and `background: false` in the skill’s frontmatter waits for the result in the same turn

A session runs up to 20 subagents concurrently by default; change the [limit](../09-Agents-Patterns/sub-agents.md#concurrent-subagent-limit) with `CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS`

`--max-budget-usd` now enforces the cap on subagents: once spend reaches it, Claude can’t start more and running background subagents stop

New [`sandbox.filesystem.disabled`](sandboxing.md#disable-filesystem-isolation) setting skips filesystem isolation while keeping network egress control

In auto mode, the checks for dangerous `rm` commands, background jobs, and suspicious Windows paths no longer open permission dialogs; the auto-mode classifier adjudicates them instead

Bash permission checks fail closed on more shell forms, including file-descriptor redirects, Zsh variable subscripts in `[[ ]]` comparisons, `help` and `man` invocations that could run unsafe options, and commands over 10,000 characters

[Fast mode](fast-mode.md) no longer supports Opus 4.7: `/fast` now applies to Opus 5 and Opus 4.8

Long-running tool calls emit a periodic progress heartbeat instead of going silent

[Full changelog for v2.1.214–v2.1.219 →](changelog.md#2-1-214)

---

## Week 32 · August 3–7, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w32
Path: 02-Claude-Code-CLI/whats-new-2026-w32.md

# Week 32 · August 3–7, 2026

Copy pageCopy page

Claude Code sessions message each other, self-hosted environments run cloud sessions on your infrastructure, and auto mode becomes the default permission mode.

Copy pageCopy page

Releases [v2.1.220 → v2.1.224](changelog.md#2-1-220)3 features · August 3–7

Cross-session messagingv2.1.224

Your Claude Code sessions can now message each other. Claude discovers your other sessions with the `ListAgents` tool and sends with `SendMessage`, either when you ask it to or on its own, such as after a change in one session affects what another is working on. A message is text Claude writes for the other session, never your conversation history or files. Available on macOS and Linux. Requires v2.1.224 or later.

With two sessions open on the same machine, ask one of them to pass something along:

Claude Code

```python
Tell the session working on the payments API that users.name is now users.display_name
```

The other session shows a `Message from` row once Claude has read the message; press `Ctrl+O` to expand it. To see which sessions Claude can reach, run `/list-agents`.

[Message another session](cross-session-messaging.md#message-another-session)

Self-hosted environmentsv2.1.224

Self-hosted environments run Claude Code cloud sessions on your organization’s own infrastructure, in public beta on Team and Enterprise plans. Run `claude self-hosted-runner` on your machines or containers to turn them into runners. When someone picks your environment while starting a session from claude.ai, the mobile or desktop apps, or `claude --cloud`, that session runs inside your network, with access to your internal services. An Owner turns on **Allow self-hosted environments** in [admin settings](https://claude.ai/admin-settings/cloud-environments) first.

Signed in as an Owner, run the guided setup, which walks you through creating the environment and starts a runner:

terminal

```python
claude self-hosted-runner setup
```

The environment shows **Healthy** in admin settings once the runner registers.

[Self-hosted environments quickstart](../13-Enterprise-Admin/self-hosted-environments-quickstart.md#set-up-an-environment-and-runner)

Auto mode becomes the defaultCLI

Starting August 14, auto mode is the default permission mode for new sessions on Pro, Max, and Team plans. If you set a default mode yourself, it stays in place unless you accept the one-time switch prompt, and a default your organization manages doesn’t change. You can still switch modes at any time. Already in effect on those plans: the classifier calls auto mode makes no longer count toward your usage limits.

To start every session in auto mode before the switch, set it as your default in your user settings:

~/.claude/settings.json

```python
{
  "permissions": {
    "defaultMode": "auto"
  }
}
```

New sessions then show `auto mode on` in the status bar.

[Auto mode requirements and controls](permission-modes.md#eliminate-prompts-with-auto-mode)

Other wins

The VS Code extension gets [Focus view](../03-IDE-Integrations/vs-code.md#extension-settings), which hides tool activity behind one expandable row per turn; toggle it from the command menu or with `Ctrl+Alt+F` (`Ctrl+Option+F` on Mac)

Sandbox credential files accept [`mode: “mask”`](sandboxing.md#mask-credential-files) on Linux and WSL2, so sandboxed commands read a sentinel copy while the sandbox proxy substitutes the real value on egress; credential masking also gains `extract`, JWT-aware `decode`, and AWS SigV4 re-signing options

Marketplaces can distribute a plugin as a [zip archive](../08-Plugins-Skills/plugins-marketplace-reference.md#archive-plugin-source) with the new `archive` source, downloaded over HTTPS with an optional SHA-256 pin, so installs work without git or npm

`/review` is now an alias of [`/code-review`](code-review-local.md), and `/code-review` with no effort level reuses the level you typed last

A session you copy with [`/fork`](../09-Agents-Patterns/agent-view.md#copy-the-session-with-%2Ffork) now makes its code changes in a worktree of its own instead of the original session’s checkout

Plugins you install from [`/plugin`](../08-Plugins-Skills/discover-plugins.md#install-a-plugin) activate in the current session when it’s safe to do so; the install summary reports `Plugin is now active.` or tells you to run `/reload-plugins`

[Background sessions](../09-Agents-Patterns/agent-view.md#how-file-edits-are-isolated) that changed code in a worktree now commit and push before finishing, open a draft pull request only when the task calls for one, and follow the git instructions in your `CLAUDE.md`

The 200-subagent-per-session cap is removed, so long-running sessions no longer refuse new subagents; the [concurrency](../09-Agents-Patterns/sub-agents.md#concurrent-subagent-limit) and depth limits still apply

A repository’s checked-in settings can no longer turn on [Remote Control auto-connect](remote-control.md#enable-remote-control-for-all-sessions); set `remoteControlAtStartup` in your user or managed settings instead, and project and local settings can only turn it off

[Worktree isolation](worktrees.md#how-claude-code-enforces-isolation) now blocks not only file edits but also Bash commands and git redirects that reach the main checkout, in every session type and in the session’s subagents

A Bash command can no longer hide part of itself from permission checks, and tab or invisible-Unicode padding no longer hides part of a command from the approval dialog

PreToolUse auto-allow hooks no longer bypass tool restrictions in Claude Code’s internal side tasks such as summaries and compaction

The [Ultraplan](ultraplan.md) research preview is removed, including the `/ultraplan` command and the `ultraplan` keyword; use plan mode or Claude Code on the web instead

[Full changelog for v2.1.220–v2.1.224 →](changelog.md#2-1-220)

---

## Week 33 · August 10–14, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w33
Path: 02-Claude-Code-CLI/whats-new-2026-w33.md

# Week 33 · August 10–14, 2026

Copy pageCopy page

Claude Code Desktop auto-continues after a usage limit resets, fork mode turns on by default, and GitLab merge requests and marketplaces join GitHub.

Copy pageCopy page

Releases [v2.1.225 → v2.1.233](changelog.md#2-1-225)3 features · August 10–14

Auto-continue after a usage limit on DesktopDesktop

When you hit your session limit in the Code tab of Claude Code Desktop, the limit card now offers an **Auto-continue when limits reset** checkbox. Check it, and the Desktop app retries the interrupted turn after the reset. The card shows the retry time. The weekly-limit card doesn’t offer it.

The next time a session-limit card appears, check **Auto-continue when limits reset** and leave the session open. The card shows `Auto-resuming at` followed by the reset time, and the turn picks up on its own once the limit resets.

[What to do when you hit a usage limit](errors.md#youve-hit-your-session-limit)

Fork mode on by defaultv2.1.232

Fork mode is now on by default in interactive sessions. Claude can request the `fork` subagent type, which inherits the full conversation and prompt cache instead of starting fresh, so you don’t have to re-explain the context for a side task. Subagents Claude spawns in interactive sessions, apart from the ones an agent-team teammate spawns, also run in the background by default.

Start a fork yourself with a task that needs everything you’ve discussed so far:

Claude Code

```python
> /subtask draft unit tests for the parser changes so far
```

The fork appears in the panel below your prompt and its result arrives in your conversation when it finishes. To turn fork mode off, set `CLAUDE_CODE_FORK_SUBAGENT=0`.

[Turn fork mode on or off](../09-Agents-Patterns/sub-agents.md#turn-fork-mode-on-or-off)

GitLab merge requests and marketplacesv2.1.232

Plugin marketplaces clone bare `gitlab.com` URLs, including nested subgroups. On v2.1.233 or later, pass a GitLab merge request URL to `--worktree` to branch from it, and the `claude agents` view labels sessions linked to a merge request as `!N`. Claude Code also redacts GitLab token families such as `glpat-` and `glrt-`, and protects the `glab` CLI’s config store the same way it protects `gh`.

Start a session in a worktree branched from a merge request:

terminal

```python
claude --worktree https://gitlab.com/group/project/-/merge_requests/42
```

When `origin` is on gitlab.com, Claude Code fetches `merge-requests/42/head` and opens the session on that branch in its own worktree.

[Branch a worktree from a pull or merge request](worktrees.md#branch-from-a-pull-request)

Other wins

Type `@` in the prompt to [mention another Claude session](cross-session-messaging.md#message-another-session) by name, and Claude messages it directly with `SendMessage`; a bare name that matches exactly one live session now delivers without a confirmation step

Interactive sessions on one machine keep [unique names](cross-session-messaging.md#see-which-sessions-claude-can-reach): if you start or rename a session with a name another live session already uses, Claude Code gives yours a `name-word-word` variant and tells you

Plugin marketplaces accept [`command` sources](../08-Plugins-Skills/plugins-marketplace-reference.md#command-plugin-source): a local command prints the plugin directory, which Claude Code re-resolves each session and applies without a restart

On Linux and WSL, set [`CLAUDE_CODE_TOOL_MEMORY_LIMIT`](tools-reference.md#memory-limit-on-linux-and-wsl) to a size such as `4G` to cap the memory Bash and PowerShell tool commands can use

The task-tracking tools, such as `TaskCreate`, `TaskUpdate`, and `TodoWrite`, are [no longer available on Opus 4.8, Sonnet 5, Fable 5, Mythos 5, and later models in those families](tools-reference.md#task-tool-availability); set `CLAUDE_CODE_ENABLE_TODO_TOOLS=1` to re-enable them

[`/code-review`](code-review-local.md) at high, xhigh, and max effort now runs in a background agent like the other levels

[`/plugin install plugin@marketplace`](../08-Plugins-Skills/discover-plugins.md#install-a-plugin) refreshes the marketplace first, so newly published plugins install without a manual marketplace update

Settings accept [`additionalMarketplaces` and `allowedMarketplaces`](settings-reference.md#marketplace-key-aliases) as aliases for `extraKnownMarketplaces` and `strictKnownMarketplaces`

On newer models, Claude can [overwrite an existing file with the Write tool](tools-reference.md#write-tool-behavior) without reading it first this session, matching the Edit tool’s rules; older models require the read

The VS Code extension can [organize the sessions list into groups](../03-IDE-Integrations/vs-code.md#organize-sessions-into-groups): right-click to create, rename, or delete a group, and Cmd/Ctrl- or Shift-click to move several sessions at once

If your organization routes Claude Code through a [Claude apps gateway with spend limits](../13-Enterprise-Admin/claude-apps-gateway-spend-limits.md), Claude Code shows the limit period, its reset time, and the operator’s message when you reach the limit

[Full changelog for v2.1.225–v2.1.233 →](changelog.md#2-1-225)

---

## Week 34 · August 17–21, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w34
Path: 02-Claude-Code-CLI/whats-new-2026-w34.md

# Week 34 · August 17–21, 2026

Copy pageCopy page

Draft editable UI artboards with the /design skill, set the Concise output style, and start a Claude Code session on your machine from your phone.

Copy pageCopy page

Releases [v2.1.234 → v2.1.239](changelog.md#2-1-234)3 features · August 17–21

/designresearch preview

The `/design` skill brings Claude Design’s artboard workflow into the CLI and Claude Code Desktop, built on artifacts. Run it with a brief and Claude publishes a canvas of editable artboards for your UI. Pick one, tweak it, then have Claude implement it. Available on Pro, Max, Team, and Enterprise. Requires v2.1.234 or later.

Describe what you want designed and let Claude draft the options:

Claude Code

```python
> /design redesign the composer based on what people actually use it for
```

Claude prints a link to the published canvas. Open it, pick an artboard, and tell Claude which option to implement.

[Where artifacts are available](artifacts.md#availability)

Concise output stylev2.1.237

Concise is a new built-in output style. Claude leads with the result and skips preamble and narration, while doing the work as thoroughly as in the Default style. When you ask for an explanation or more detail, Claude answers in full. Error reports, security warnings, and confirmations for destructive actions keep their complete content.

Turn it on under **Output style** in `/config`, or set it in your settings file:

~/.claude/settings.json

```python
{
  "outputStyle": "Concise"
}
```

Run `/clear` or start a new session, and Claude’s replies lead with the result.

[Built-in output styles](output-styles.md#built-in-output-styles)

Start a session on your machine from your phonemobile

Any machine running `claude remote-control` now shows up as a device card at the top of the Code tab in the Claude app. Remote Control is also out of research preview.

Start Remote Control on the machine you want to reach, then open the Code tab on your phone:

terminal

```python
claude remote-control
```

Your machine appears as a device card at the top of the Code tab. Tap it to pick a directory and start a session there.

[Start a Remote Control session](remote-control.md#start-a-remote-control-session)

Other wins

Claude Code now continues your session automatically when a claude.ai usage limit resets; turn it off from the **Continue automatically at usage limit** row in `/config`

The optional [`spellcheck` setting](interactive-mode.md#check-spelling-as-you-type) underlines misspelled words in the prompt input as you type, using your installed `aspell`, `hunspell`, or `ispell`

On a branch with an open GitLab merge request, with the `glab` CLI authenticated through `glab auth login`, the footer shows an [`MR !N` badge](interactive-mode.md#gitlab-merge-requests) colored by whether the merge request is a draft, open, or mergeable

Change the effort level from your phone or claude.ai/code and it [applies to the session on your machine](remote-control.md#what-connected-devices-see); Remote Control sessions hosted by Desktop or VS Code also show connected devices the session’s current permission mode

You can open [`/permissions`](permissions.md#manage-permissions) or run `/add-dir <path>` while Claude is working; permission rule changes apply to the rest of the current turn

When background tasks keep a [`/goal`](goal.md#background-work-defers-evaluation) waiting, Claude checks in on them after 30 minutes instead of waiting indefinitely and keeps checking in, at longer intervals while the session sits idle; set `CLAUDE_CODE_GOAL_CHECKIN_MINUTES=0` to opt out

Your own prompts now render markdown in the transcript, with highlighted code blocks, inline code, and lists, the same way replies do

The new [`ANTHROPIC_DEFAULT_MODEL`](model-config.md#set-a-default-model-for-new-sessions) environment variable sets the model new sessions start on; a `/model` pick still overrides it and persists across restarts

With the `notify_when_idle` input on `SendMessage`, Claude can ask another Claude Code session on the same machine to [send one notice when it next goes idle](cross-session-messaging.md#get-a-notice-when-another-session-goes-idle)

Set [`keybindingFlavor`](interactive-mode.md#make-ctrl-w-delete-back-to-whitespace) to `“readline”` to make `Ctrl+W` in the prompt delete back to the previous whitespace, as Bash does, instead of stopping at punctuation such as `/`

On native Windows, your Claude Code sessions can now [message each other](cross-session-messaging.md#availability) with `SendMessage` and find each other with `ListAgents`, as on macOS and Linux

Self-hosted runners accept `--defer-shutdown-max-min`, which [keeps serving attached sessions](../13-Enterprise-Admin/self-hosted-environments-deploy.md#defer-the-drain-past-the-first-signal) for a set number of minutes after SIGTERM

Self-hosted runners accept `--proxy-authorization-command` or `--proxy-authorization-file` to supply a fresh `Proxy-Authorization` header for [egress proxies that require one](../13-Enterprise-Admin/self-hosted-environments-deploy.md#authenticate-to-an-egress-proxy)

[Full changelog for v2.1.234–v2.1.239 →](changelog.md#2-1-234)

---

## Week 35 · August 24–28, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w35
Path: 02-Claude-Code-CLI/whats-new-2026-w35.md

# Week 35 · August 24–28, 2026

Copy pageCopy page

Resume terminal sessions in the Claude Code Desktop app, review feedback reports that Claude drafts for you, and start a session in restricted mode.

Copy pageCopy page

Releases [v2.1.240 → v2.1.250](changelog.md#2-1-240)3 features · August 24–28

Resume terminal sessions in the Desktop appDesktop

Type `/resume` in the Claude Code Desktop prompt box to pick up any session you started from the CLI and continue it in the app with the full conversation and context intact. Search your sessions by title, folder, or branch, and preview where you left off before you resume.

In a Desktop session, run the command to list your terminal sessions:

Claude Code

```python
> /resume
```

Select a session and press `Enter`. The conversation opens in the app where you left off.

[Move between the CLI and Desktop](../16-Mobile-Desktop/desktop.md#coming-from-the-cli)

Claude-drafted feedbackCLI

When a tool keeps failing, Claude can’t help with a request, or you point out a mistake, Claude now drafts a feedback report for you with the `SendFeedback` tool. A card above your prompt shows the draft, and you can review, send, or dismiss it from there. Nothing reaches Anthropic until you send it. Requires v2.1.238 or later.

Run `/feedback` with no argument to open your queue of drafts from every session:

Claude Code

```python
> /feedback
```

Select a draft, then edit, send, or discard it. To turn drafting off, set **Claude-drafted feedback** to `off` in `/config`.

[SendFeedback tool behavior](tools-reference.md#sendfeedback-tool-behavior)

Restricted modev2.1.248

Restricted mode starts Claude Code without the built-in tools that run commands or code. Use it when an evaluation harness drives `claude` on a shared machine. Start it with `--restricted` or set `CLAUDE_CODE_RESTRICTED=1`. Claude Code also removes `WebFetch`, confines the file tools to the working directories, loads only managed settings and `--settings`, and refuses the `bypassPermissions` permission mode.

Run a non-interactive query without the command-running tools:

terminal

```python
claude --restricted -p "review src/ for SQL injection risks"
```

To give Claude one of the removed tools back, list it in `--tools` together with the other built-in tools you want, for example `--tools "Bash,Read,Edit"`. `--tools` is an allowlist, and its `default` preset doesn’t restore the removed tools.

[CLI flags](cli-reference.md#cli-flags)

Other wins

Set the new [`modelPicker`](settings-reference.md#modelpicker) setting to extend or replace the `/model` picker’s built-in list with your own ordered, labeled entries, including Amazon Bedrock or Google Cloud’s Agent Platform model IDs

Set [`promptCacheTtl`](prompt-caching.md#choose-the-ttl-yourself) to `1h` to keep a one-hour prompt cache on the main conversation when you use an API key or a cloud provider; `subagentPromptCacheTtl` sets the TTL for subagents and all other requests outside the main conversation

On Pro, Max, Team, and Enterprise plans, [`/usage`](../17-Billing-Plans/costs.md#plan-usage-breakdown) adds a Loops breakdown: run count, total tokens, tokens per run, and last run for the `/loop` and scheduled tasks that used the most tokens

Organizations on contracted rates can set the [`modelPricing`](../17-Billing-Plans/costs.md#report-spend-at-your-contracted-rates) managed setting so `/usage`, the status line, and OpenTelemetry report cost at those rates instead of list price

`/login` offers **Sign in with your Console account** under the **Anthropic Console account** option, so members of Console organizations that don’t allow API keys can sign in without creating one

Run `/permissions` and open the new [**Auto mode** tab](auto-mode-config.md#edit-rules-from-permissions) to view and edit auto mode classifier rules without opening a settings file

When auto mode is available, Bash permission prompts in the Manual and `acceptEdits` permission modes offer a [**Yes, and switch to auto mode**](permission-modes.md#switch-permission-modes) option; select it to approve the command and switch the session to auto mode

After you [move a session with `/cd`](permissions.md#move-the-session-to-another-directory), the new directory’s project settings, hooks, `.mcp.json` servers, skills, and subagents take effect immediately instead of on the next `--resume`

In non-interactive sessions, including `-p` runs, Agent SDK runs, and cloud sessions, Claude Code [continues a response](errors.md#the-response-above-may-be-incomplete) that a server error, dropped connection, or stall cut off mid-stream, when the partial response contains text and no tool calls

A subagent that stops at its `maxTurns` limit returns its output marked as partial, with a hint that Claude can [continue it with `SendMessage`](../09-Agents-Patterns/sub-agents.md#resume-subagents), instead of appearing finished

On Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry, sessions on the same machine can now [message each other](cross-session-messaging.md#availability), `/loop` can [choose its own interval](scheduled-tasks.md#let-claude-choose-the-interval), and `/model` and `/effort` apply immediately instead of after the turn ends

The native installer and auto-updater download a zstd-compressed build, about 75 MB instead of 340 MB on Linux x64, and native builds load code on demand, using roughly 40 to 70 MB less memory per session

[Full changelog for v2.1.240–v2.1.250 →](changelog.md#2-1-240)

---

## Week 36 · August 31 – September 4, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w36
Path: 02-Claude-Code-CLI/whats-new-2026-w36.md

# Week 36 · August 31 – September 4, 2026

Copy pageCopy page

Switch to Claude Fable 5.1, let computer use run in the background on Desktop, and watch Claude’s edits in a live /diff panel.

Copy pageCopy page

Releases [v2.1.251 → v2.1.261](changelog.md#2-1-251)4 features · August 31 – September 4

Claude Fable 5.1new model

Claude Fable 5.1 is available in Claude Code with a 1M-token context window, and the `fable` alias now selects it. In Claude apps gateway sessions, `fable` still selects Fable 5. If your gateway serves Fable 5.1, run `/model claude-fable-5-1`. Requires v2.1.257 or later.

Switch the current session to Fable 5.1 and save it as your default:

Claude Code

```python
> /model fable
```

On the Anthropic API, the picker lists Fable only once the server reports it available for your organization, but typing `/model fable` checks with the server directly.

[Work with Fable](model-config.md#work-with-fable)

Computer use runs in the background on DesktopDesktop

On macOS, computer use in the Claude Code Desktop app now works in the background: Claude sees and acts in the apps you’ve approved while you keep working. Background computer use is in beta on Pro and Max plans.

[Let Claude use your computer](../16-Mobile-Desktop/desktop.md#let-claude-use-your-computer)

Live diff panel in fullscreen renderingv2.1.260

In fullscreen rendering, `/diff` now opens a panel beside the conversation instead of a viewer you have to close. The panel lists the changed files with their added and removed line counts and refreshes each time Claude edits a file or runs a shell command. Select lines in the panel with the mouse to attach them to your next prompt.

With fullscreen rendering on, inside a git repository, and in a terminal at least 110 columns wide, toggle the panel:

Claude Code

```python
> /diff
```

Run `/diff` again or click the `✕` in its header to close it.

[Diff panel](interactive-mode.md#diff-panel)

Find unused skills with /skill-doctorCLI

`/skill-doctor` shows what each of your skills costs in context and how often it gets used, so you can decide which ones to turn off. Every skill in the [skill listing](../08-Plugins-Skills/skills.md#skill-descriptions-are-cut-short) adds to your context on every turn, whether or not Claude ever uses it. Requires v2.1.252 or later and isn’t available in sessions that skip [feature-flag fetching](env-vars.md#features-that-need-feature-flag-fetching).

Run it in an interactive session to open the report in the `/plugin` manager’s **Stats** tab:

Claude Code

```python
> /skill-doctor
```

In non-interactive mode with `-p`, Claude Code prints the report as text instead.

[Find unused skills](../08-Plugins-Skills/skills.md#find-unused-skills)

Other wins

A [`PreModelSwitch`](../07-Hooks/hooks.md#premodelswitch) hook can block a model switch you request, and a [`PostModelSwitch`](../07-Hooks/hooks.md#postmodelswitch) hook can add context for Claude after the session’s model changes

[`/cost`](../17-Billing-Plans/costs.md#prompt-cache-statistics) adds a `Prompt cache (main)` line: the share of input tokens served from cache, the cache misses, whether the cache is warm, and a likely cause for the last miss when Claude Code can name one. Status line scripts get a matching `prompt_cache` object

Organizations can list HTTP and SSE MCP servers under the [`managedMcpServers`](../06-MCP-Tools/General/managed-mcp.md#provide-servers-through-managed-settings) managed setting to give them to every user, in addition to the servers that users add on their own

`/effort` and the `/model` picker now [save a separate effort level for each model](model-config.md#adjust-effort-level); press `s` instead of `Enter` to apply a level to the current session only

By default, the auto mode classifier [now also blocks](permission-modes.md#what-the-classifier-blocks-by-default) actions such as requesting credentials from the cloud instance-metadata endpoint or connecting to sibling containers that Claude didn’t start

In auto mode, Claude Code asks you before Claude [first reads a file outside your working directories](permission-modes.md#first-read-outside-the-working-directories), with an option to block such reads from then on

Raise [`bashOutputMaxChars`](settings-reference.md#bashoutputmaxchars) and [`taskOutputMaxChars`](settings-reference.md#taskoutputmaxchars), up to 128,000 characters, so Claude receives more of the output from a successful command or background task inline

The prompt’s [word-editing shortcuts follow readline](interactive-mode.md#make-ctrl-w-delete-back-to-whitespace) for everyone, and the `keybindingFlavor` setting no longer has any effect. `Ctrl+W` deletes back to the previous whitespace, and `Alt+B`, `Alt+F`, and `Alt+D` treat punctuation such as `/` and `.` as word breaks

If you set `defaultMode` to `“bypassPermissions”` in a project’s `.claude/settings.json` or `.claude/settings.local.json`, it [no longer takes effect](permission-modes.md#which-mode-a-session-starts-in) and the session starts in Manual mode; set `“bypassPermissions”` in user or managed settings instead, or pass `--permission-mode`

Seat-based Enterprise plans now [default to Opus 5](model-config.md#default-model-setting)

In the VS Code extension, click the model name at the bottom of the prompt box to [open the model picker](../03-IDE-Integrations/vs-code.md#use-the-prompt-box)

In the VS Code extension, select **Output styles** in the command menu’s Customize section to [pick an output style](../03-IDE-Integrations/vs-code.md#use-the-prompt-box), including your custom ones

[Full changelog for v2.1.251–v2.1.261 →](changelog.md#2-1-251)

---

## Week 37 · September 7–11, 2026 - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new/2026-w37
Path: 02-Claude-Code-CLI/whats-new-2026-w37.md

# Week 37 · September 7–11, 2026

Copy pageCopy page

Test your plugins with claude plugin eval and pop Claude Code Desktop panes out into their own windows.

Copy pageCopy page

Releases [v2.1.263 → v2.1.269](changelog.md#2-1-263)2 features · September 7–11

Test plugins with claude plugin evalv2.1.269

`claude plugin eval` runs your plugin against a suite of test cases, scores the results, and by default runs each case again without the plugin so you can see what it contributes. `claude plugin eval init` asks you what a good result looks like, then proposes test cases and the checks that score them, tries the suite once, and writes the files. Every run, and every check that has a second model judge the reply, is a real model call on your account.

From your plugin’s root directory, have Claude draft the suite:

terminal

```python
claude plugin eval init
```

When Claude tells you the suite is ready, exit the session that `claude plugin eval init` opened and run `claude plugin eval .` to score every case. The summary table prints in your terminal, and `report.html` under `evals/results/` has the per-run detail.

[Test plugins with evals](../08-Plugins-Skills/plugin-evals.md)

Pop Desktop panes out into their own windowsDesktop

In the Claude Code Desktop app, you can pop any pane out into its own window. Drag the diff or terminal to a second screen while Claude keeps working in the main window, then dock the pane back when you’re done.

[Arrange your workspace](../16-Mobile-Desktop/desktop.md#arrange-your-workspace)

Other wins

Set [`maxEffortLevel`](settings-reference.md#maxeffortlevel) at the top level or per model under `modelSettings` to cap the effort level on every provider, including Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry; any higher level runs at the cap

Point `--plugin-dir` at a folder of plugins to [load each immediate subfolder that has a manifest](../08-Plugins-Skills/plugins-create.md#load-a-directory-or-archive-for-one-session)

If WebFetch hasn’t finished downloading a page within five minutes, [the fetch fails with a deadline error](tools-reference.md#webfetch-tool-behavior) instead of hanging; set `CLAUDE_CODE_WEBFETCH_DEADLINE_MS` to change the deadline, or to `0` to remove the limit

Pass `--json` to `claude plugin install`, `uninstall`, `update`, `enable`, or `disable` to print the result as [one JSON object on the last line of stdout](../08-Plugins-Skills/plugins-cli-reference.md#plugin-json-result)

When the auto mode classifier blocks an action, the reason Claude receives [usually names the rule that matched](auto-mode-config.md#fix-a-denial-with-an-allow-rule-an-environment-entry-or-a-retry), such as `[Data Exfiltration]`

When you type `/` partway through a prompt, you can now pick from [a list of matching commands](interactive-mode.md#complete-a-command-mid-prompt) instead of a single suggestion. The list opens as you type in fullscreen rendering. A plugin skill also matches on its name without the plugin prefix

In the VS Code extension, click the agent count at the bottom of the prompt box to open the [agent map](../03-IDE-Integrations/vs-code.md#use-the-prompt-box), where you can open a subagent’s read-only transcript or stop it

In the VS Code extension, select **Hooks** or **Permissions** in the command menu’s Customize section to [add or remove hooks and permission rules](../03-IDE-Integrations/vs-code.md#use-the-prompt-box) in your user, project, and local settings

Claude can pick a [browser-tab icon](artifacts.md#create-an-artifact) to match each artifact it publishes

In Claude Code on the web, take back a queued message in a cloud session before Claude reads it: remove it from the queue, or press `Esc` or `Up`, and the text returns to the message box

[Full changelog for v2.1.263–v2.1.269 →](changelog.md#2-1-263)

---

## What's new

Source: https://code.claude.com/docs/en/whats-new/index
Path: 02-Claude-Code-CLI/whats-new-index.md

# What's new

> A weekly digest of notable Claude Code features, with code snippets, demos, and context on why they matter.

The weekly dev digest highlights the features most likely to change how you work. Each entry includes runnable code, a short demo, and a link to the full docs. For every bug fix and minor improvement, see the [changelog](https://code.claude.com/docs/en/19-Reference/changelog-claude-code-docs-3d68ad8e13.md).

<Update label="Week 15" description="April 6–10, 2026" tags={["v2.1.92–v2.1.101"]}>
  **Ultraplan** enters early preview: draft a plan in the cloud from your CLI, review and comment on it in a web editor, then run it remotely or pull it back local. The first run now auto-creates a cloud environment for you.

  Also this week: the **Monitor** tool streams background events into the conversation so Claude can tail logs and react live, `/loop` self-paces when you omit the interval, `/team-onboarding` packages your setup into a replayable guide, and `/autofix-pr` turns on PR auto-fix from your terminal.

  [Read the Week 15 digest →](https://code.claude.com/en/whats-new/2026-w15)
</Update>

<Update label="Week 14" description="March 30 – April 3, 2026" tags={["v2.1.86–v2.1.91"]}>
  **Computer use** comes to the CLI in research preview: Claude can open native apps, click through UI, and verify changes from your terminal. Best for closing the loop on things only a GUI can verify.

  Also this week: `/powerup` interactive lessons, flicker-free alt-screen rendering, a per-tool MCP result-size override up to 500K, and plugin executables on the Bash tool's `PATH`.

  [Read the Week 14 digest →](https://code.claude.com/en/whats-new/2026-w14)
</Update>

<Update label="Week 13" description="March 23–27, 2026" tags={["v2.1.83–v2.1.85"]}>
  **Auto mode** lands in research preview: a classifier handles your permission prompts so safe actions run without interruption and risky ones get blocked. The middle ground between approving everything and `--dangerously-skip-permissions`.

  Also this week: computer use in the Desktop app, PR auto-fix on Web, transcript search with `/`, a native PowerShell tool for Windows, and conditional `if` hooks.

  [Read the Week 13 digest →](https://code.claude.com/en/whats-new/2026-w13)
</Update>

---

## What's new - Claude Code Docs

Source: https://code.claude.com/docs/en/whats-new
Path: 02-Claude-Code-CLI/whats-new.md

# What's new

Copy pageCopy page

A weekly digest of notable Claude Code features, with code snippets, demos, and context on why they matter.

Copy pageCopy page

The weekly dev digest highlights the features most likely to change how you work. Each entry includes runnable code, a short demo, and a link to the full docs. For every bug fix and minor improvement, see the [changelog](changelog.md).

[​](#week-37)

Week 37

v2.1.263–v2.1.269

September 7–11, 2026

**`claude plugin eval`**: run your plugin against a suite of test cases, score the results, and compare against a no-plugin baseline. `claude plugin eval init` drafts the cases and graders for you.Also this week: pop any **Claude Code Desktop pane** out into its own window and dock it back later; the **`maxEffortLevel`** setting caps the effort level on every provider; and a page that **WebFetch** hasn’t finished downloading within five minutes fails instead of hanging.[Read the Week 37 digest →](whats-new-2026-w37.md)

[​](#week-36)

Week 36

v2.1.251–v2.1.261

August 31 – September 4, 2026

**Claude Fable 5.1**: available in Claude Code with a 1M-token context window.Also this week: on Pro and Max plans, **computer use in the Desktop app** works in the background on macOS while you keep working; in fullscreen rendering, **`/diff`** opens a live panel beside the conversation that refreshes as Claude edits; and **`/skill-doctor`** shows what each of your skills costs in context and how often it gets used.[Read the Week 36 digest →](whats-new-2026-w36.md)

[​](#week-35)

Week 35

v2.1.240–v2.1.250

August 24–28, 2026

**Resume terminal sessions in the Desktop app**: type `/resume` in the Claude Code Desktop prompt box to pick up any session you started from the CLI, with the full conversation and context intact.Also this week: **Claude-drafted feedback** has Claude write up a feedback report when something goes wrong in a session, which you review and send from `/feedback`; **`--restricted`** starts a session without the command-running tools or your user and project settings, for evaluation harnesses on shared machines; and the **`modelPicker`** setting controls which models the `/model` picker lists.[Read the Week 35 digest →](whats-new-2026-w35.md)

[​](#week-34)

Week 34

v2.1.234–v2.1.239

August 17–21, 2026

**`/design`**: a research preview that brings Claude Design’s artboard workflow into the CLI and Claude Code Desktop, built on artifacts, so Claude drafts editable artboards for your UI and implements the one you pick.Also this week: the built-in **Concise output style** makes Claude lead with the result and skip preamble; any machine running `claude remote-control` shows up as a **device card** on your phone so you can start a session on it from the Code tab; and **`ANTHROPIC_DEFAULT_MODEL`** sets the model new sessions start on.[Read the Week 34 digest →](whats-new-2026-w34.md)

[​](#week-33)

Week 33

v2.1.225–v2.1.233

August 10–14, 2026

**Auto-continue after a usage limit on Desktop**: when you hit your session limit in Claude Code Desktop, check **Auto-continue when limits reset** on the limit card and the app retries the interrupted turn once the limit resets.Also this week: **fork mode** is on by default in interactive sessions, so Claude can delegate a side task to a subagent that inherits the full conversation; **GitLab** merge request URLs work with `--worktree` and the `claude agents` view, and marketplaces clone bare `gitlab.com` URLs; and typing **`@`** in the prompt mentions another Claude session by name.[Read the Week 33 digest →](whats-new-2026-w33.md)

[​](#week-32)

Week 32

v2.1.220–v2.1.224

August 3–7, 2026

**Cross-session messaging**: on macOS and Linux, your Claude Code sessions can now message each other, so Claude passes a finding or a decision from one session to another instead of you re-explaining it.Also this week: **self-hosted environments** run Claude Code cloud sessions on infrastructure your organization operates, in public beta on Team and Enterprise plans; **auto mode** becomes the default permission mode for new sessions on Pro, Max, and Team plans starting August 14; and the **VS Code extension** gets Focus view.[Read the Week 32 digest →](whats-new-2026-w32.md)

[​](#week-30)

Week 30

v2.1.214–v2.1.219

July 20–24, 2026

**Claude Opus 5**: the new default Opus model in Claude Code, with a 1M-token context window and fast mode at \$10/\$50 per MTok.Also this week: **Claude Code Desktop** opens an iOS Simulator pane in public beta so Claude can run your app and tap through it while you watch; the **Claude Security plugin** runs a multi-agent vulnerability scan of your codebase and turns the findings you pick into patches you apply yourself; and **`/code-review`** runs as a background subagent.[Read the Week 30 digest →](whats-new-2026-w30.md)

[​](#week-29)

Week 29

v2.1.207–v2.1.212

July 13–17, 2026

**Artifacts call your MCP connectors**: a published artifact can pull live data and take actions through each viewer’s own MCP connectors when they open the page, and this week also adds public sharing links, editor roles on Team and Enterprise, and artifacts created from Claude Tag sessions.Also this week: **screen reader mode** replaces the visual terminal interface with plain, linear text for screen readers such as VoiceOver and NVDA; **`/fork`** copies your conversation into a new background session while you keep working; and **auto mode** no longer needs an opt-in variable on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry.[Read the Week 29 digest →](whats-new-2026-w29.md)

[​](#week-28)

Week 28

v2.1.202–v2.1.206

July 6–10, 2026

**In-app browser on Desktop**: Claude Code on desktop gets a built-in browser, so Claude can pull up docs, designs, or any other site and interact with pages the same way it does with your local dev server previews.Also this week: **`/doctor`** is a full setup checkup that diagnoses issues and can fix them, with `/checkup` as its alias; **auto mode** blocks transcript tampering and asks before `rm -rf` on unresolved variables; and **agent view rows** show a colored state word and a classifier-written headline.[Read the Week 28 digest →](whats-new-2026-w28.md)

[​](#week-27)

Week 27

v2.1.195–v2.1.201

June 29 – July 3, 2026

**Claude Sonnet 5**: the new default model for Pro, Team Standard, and Enterprise subscription seats, with top-tier coding and tool use at Sonnet pricing, a native 1M-token context window, and adaptive thinking on by default.Also this week: **Claude in Chrome** is generally available on all direct Anthropic plans; **subagents run in the background by default** so Claude keeps working while they run; **Claude Desktop on Linux** lands in beta on Ubuntu and Debian; and **`/radio`** tunes into Claude FM lo-fi radio.[Read the Week 27 digest →](whats-new-2026-w27.md)

[​](#week-26)

Week 26

v2.1.185–v2.1.193

June 22–26, 2026

**`claude mcp login`**: authenticate a configured MCP server from your shell instead of the interactive `/mcp` menu, and clear its stored credentials later with `claude mcp logout`.Also this week: **shell mode responds to command output** (`! npm test` gets an explanation without a second prompt); **`/rewind`** can resume a conversation from before `/clear` was run; and **background subagents** now surface permission prompts in the main session instead of auto-denying.[Read the Week 26 digest →](whats-new-2026-w26.md)

[​](#week-25)

Week 25

v2.1.178–v2.1.183

June 15–19, 2026

**Artifacts**: turn a session’s output into a live, shareable page on claude.ai that updates in place as the session works, now in beta on Team and Enterprise plans.Also this week: **deny and ask rules match tool parameters** with `Tool(param:value)`, for example `Agent(model:opus)`; **`/config key=value`** sets any setting from the prompt, in `-p` mode, and from Remote Control; and **auto mode blocks destructive git commands** when you didn’t ask to discard local work.[Read the Week 25 digest →](whats-new-2026-w25.md)

[​](#week-24)

Week 24

v2.1.166–v2.1.176

June 8–12, 2026

**`/cd`**: move the current session to a new working directory mid-conversation without rebuilding the prompt cache.Also this week: **sub-agents can spawn their own sub-agents** (background chains are capped at five levels deep); **`--safe-mode`** starts Claude Code with all customizations disabled for troubleshooting; and **`fallbackModel`** configures up to three fallback models tried in order.[Read the Week 24 digest →](whats-new-2026-w24.md)

[​](#week-23)

Week 23

v2.1.158–v2.1.165

June 1–5, 2026

**Auto mode on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry**: auto mode is now available on third-party providers for Opus 4.7 and Opus 4.8, replacing permission prompts with background safety checks.Also this week: **safer automatic edits** prompt before writing files that can run code in `acceptEdits` mode; **`/plugin list`** prints your installed plugins inline; and **version requirements** let managed deployments require an approved Claude Code version range.[Read the Week 23 digest →](whats-new-2026-w23.md)

[​](#week-22)

Week 22

v2.1.150–v2.1.157

May 25–29, 2026

**Claude Opus 4.8**: the new default model for Max, Team Premium, Enterprise pay-as-you-go, and Anthropic API accounts, with high effort by default and `/effort xhigh` for the hardest tasks.Also this week: **dynamic workflows** orchestrate dozens to hundreds of subagents from a script Claude writes; the **security-guidance plugin** reviews Claude’s changes for vulnerabilities as it works; and **fast mode** runs on Opus 4.8 at \$10/\$50 per MTok.[Read the Week 22 digest →](whats-new-2026-w22.md)

[​](#week-21)

Week 21

v2.1.143–v2.1.149

May 18–22, 2026

**Auto mode on the Pro plan**: auto mode now runs on Pro accounts and supports Sonnet 4.6 alongside Opus, replacing permission prompts with background safety checks.Also this week: **`/usage`** breaks down what drives your plan limits by skill, subagent, plugin, and MCP server; the new **`/code-review`** command reports correctness bugs; and **background sessions** appear in `/resume` and stay alive when pinned.[Read the Week 21 digest →](whats-new-2026-w21.md)

[​](#week-20)

Week 20

v2.1.139–v2.1.142

May 11–15, 2026

**Agent view**: `claude agents` opens one screen for every Claude Code session, showing what’s running, what’s blocked on you, and what’s done.Also this week: **`/goal`** keeps Claude working across turns until a completion condition holds; **fast mode** now runs on Opus 4.7 by default; and the **Rewind menu** can compress earlier context with “Summarize up to here”.[Read the Week 20 digest →](whats-new-2026-w20.md)

[​](#week-19)

Week 19

v2.1.128–v2.1.136

May 4–8, 2026

**Plugins load from `.zip` archives and URLs**: `--plugin-dir` now accepts `.zip` files, and `--plugin-url` fetches a plugin archive for the current session.Also this week: **`worktree.baseRef`** chooses whether new worktrees branch from the remote default or local `HEAD`; **auto mode hard deny rules** block actions unconditionally regardless of allow exceptions; and **hooks see the active effort level** via `effort.level` and `$CLAUDE_EFFORT`.[Read the Week 19 digest →](whats-new-2026-w19.md)

[​](#week-18)

Week 18

v2.1.120–v2.1.126

April 27 – May 1, 2026

**Windows without Git Bash**: Git for Windows is no longer required, and Claude Code uses PowerShell as the shell tool when Bash is absent.Also this week: **`claude ultrareview`** brings cloud code review to CI and scripts; **`claude project purge`** cleans up local state for a project; and pasting a **PR URL into `/resume`** finds the session that created it.[Read the Week 18 digest →](whats-new-2026-w18.md)

[​](#week-17)

Week 17

v2.1.114–v2.1.119

April 20–24, 2026

**`/ultrareview`** opens as a public research preview: a fleet of bug-hunting agents runs in the cloud and findings land back in your CLI or Desktop automatically.Also this week: **session recap** shows you what happened while a terminal was unfocused; **custom themes** let you build and ship color palettes from `/theme` or a plugin; and **Claude Code on the web** gets a redesign with a new sessions sidebar and drag-and-drop layout.[Read the Week 17 digest →](whats-new-2026-w17.md)

[​](#week-16)

Week 16

v2.1.105–v2.1.113

April 13–17, 2026

**Claude Opus 4.7** lands as the new default on Max and Team Premium, with a new `xhigh` effort level that’s the recommended setting for most coding work and an interactive `/effort` slider to dial it in.Also this week: **Routines** on Claude Code on the web fire templated cloud agents from a schedule, GitHub event, or API call; **mobile push notifications** ping your phone when a long task finishes or Claude needs you; `/usage` shows what’s driving your limits; and the CLI moves to native binaries.[Read the Week 16 digest →](whats-new-2026-w16.md)

[​](#week-15)

Week 15

v2.1.92–v2.1.101

April 6–10, 2026

**Ultraplan** enters early preview: draft a plan in the cloud from your CLI, review and comment on it in a web editor, then run it remotely or pull it back local. The first run now auto-creates a cloud environment for you.Also this week: the **Monitor** tool streams background events into the conversation so Claude can tail logs and react live, `/loop` self-paces when you omit the interval, `/team-onboarding` packages your setup into a replayable guide, and `/autofix-pr` turns on PR auto-fix from your terminal.[Read the Week 15 digest →](whats-new-2026-w15.md)

[​](#week-14)

Week 14

v2.1.86–v2.1.91

March 30 – April 3, 2026

**Computer use** comes to the CLI in research preview: Claude can open native apps, click through UI, and verify changes from your terminal. Best for closing the loop on things only a GUI can verify.Also this week: `/powerup` interactive lessons, flicker-free alt-screen rendering, a per-tool MCP result-size override up to 500K, and plugin executables on the Bash tool’s `PATH`.[Read the Week 14 digest →](whats-new-2026-w14.md)

[​](#week-13)

Week 13

v2.1.83–v2.1.85

March 23–27, 2026

**Auto mode** lands in research preview: a classifier handles your permission prompts so safe actions run without interruption and risky ones get blocked. The middle ground between approving everything and `--dangerously-skip-permissions`.Also this week: computer use in the Desktop app, PR auto-fix on Web, transcript search with `/`, a native PowerShell tool for Windows, and conditional `if` hooks.[Read the Week 13 digest →](whats-new-2026-w13.md)

---

## Why was my card declined? | Claude Help Center

Source: https://support.claude.com/en/articles/9402418-why-was-my-card-declined
Path: 02-Claude-Code-CLI/why-was-my-card-declined.md

# Why was my card declined?

July 10, 2026


There are several reasons your card may have been declined when trying to process this transaction. While we don't receive detailed information from issuing banks regarding the specific reasons for a decline, there are several common factors that may contribute to this issue. A few ideas to try are:

## Ensure supported billing location

Please review our list of **[supported billing locations](https://www.anthropic.com/supported-countries)** to confirm that your payment method's billing address and origin country are eligible for processing. Ensure that your payment method’s billing address matches the origin country.

## Verify billing address

Ensure that the billing address associated with your payment method matches the address on file with your bank. Even minor discrepancies, such as a missing accent mark or a misspelled street name, can trigger a decline.

## Complete 3DS verification (if applicable)

If your transaction requires 3D Secure (3DS) verification, ensure that you have successfully completed the authentication process. This may involve entering a one-time password sent to your registered mobile device or confirming the transaction through your bank's app or website.

## Use an accepted payment method

We accept credit cards and debit cards for all purchases. For **[self-serve Enterprise plans](../17-Billing-Plans/what-is-the-enterprise-plan.md#h_634d59a83f)** and API accounts on monthly invoicing, we also accept to ACH bank transfers.

Please note that we do not accept third-party payment processors such as PayPal or Venmo. If you attempt to use an unsupported payment method, your transaction will likely be declined.

## Confirm sufficient funds

Verify that your payment method has sufficient funds to cover the total amount of your purchase. If you're unsure about your account balance, we recommend contacting your bank directly for assistance.

## Retry the payment

If you have access to another payment method, consider using it to complete your purchase. It may be worthwhile to attempt the transaction again at a later time as temporary technical issues or network disruptions can sometimes cause declines, which may resolve on their own.

## Contact your bank

Reach out to your issuing bank directly to inquire about the reason for the decline. They may be able to provide additional information or insights that can help you resolve the issue.

If you've tried the troubleshooting steps above and are still encountering difficulties, contact **[our support team](../15-Claude-AI-Features/how-to-get-support.md)** for further assistance.

---

## Orchestrate subagents at scale with dynamic workflows - Claude Code Docs

Source: https://code.claude.com/docs/en/workflows
Path: 02-Claude-Code-CLI/workflows.md

## On this page

- [When to use a workflow](#when-to-use-a-workflow)
- [Run a bundled workflow](#run-a-bundled-workflow)
  - [Bundled workflows](#bundled-workflows)
  - [Watch the run](#watch-the-run)
- [Have Claude write a workflow](#have-claude-write-a-workflow)
  - [Ask for a workflow in your prompt](#ask-for-a-workflow-in-your-prompt)
  - [Dismiss or turn off the keyword](#dismiss-or-turn-off-the-keyword)
  - [Where the keyword works](#where-the-keyword-works)
  - [Let Claude decide with ultracode](#let-claude-decide-with-ultracode)
  - [Approve the plan before it runs](#approve-the-plan-before-it-runs)
  - [Save the workflow for reuse](#save-the-workflow-for-reuse)
  - [Distribute a workflow in a plugin](#distribute-a-workflow-in-a-plugin)
  - [Pass input to a saved workflow](#pass-input-to-a-saved-workflow)
- [Example workflow prompts](#example-workflow-prompts)
  - [Audit many files for the same issue](#audit-many-files-for-the-same-issue)
  - [Keep fixing until a check passes](#keep-fixing-until-a-check-passes)
  - [Migrate many files in parallel](#migrate-many-files-in-parallel)
  - [Review every changed file and write one summary](#review-every-changed-file-and-write-one-summary)
  - [Research a topic across many sources](#research-a-topic-across-many-sources)
  - [Find issues until the list stops growing](#find-issues-until-the-list-stops-growing)
  - [What the saved script looks like](#what-the-saved-script-looks-like)
  - [Edit a saved script](#edit-a-saved-script)
- [How a workflow runs](#how-a-workflow-runs)
  - [Prompt caching in a fan-out](#prompt-caching-in-a-fan-out)
  - [Behavior and limits](#behavior-and-limits)
- [Manage runs](#manage-runs)
  - [Resume after a pause](#resume-after-a-pause)
  - [Which agents run again](#which-agents-run-again)
  - [Resume after you leave the session](#resume-after-you-leave-the-session)
  - [When a run hits your usage limit](#when-a-run-hits-your-usage-limit)
  - [When an agent stalls and restarts](#when-an-agent-stalls-and-restarts)
  - [Cost](#cost)
  - [Set a size guideline](#set-a-size-guideline)
  - [Turn workflows off](#turn-workflows-off)
- [Related resources](#related-resources)

Agents and parallel work

# Orchestrate subagents at scale with dynamic workflows

Copy pageCopy page

Dynamic workflows orchestrate many subagents from a script Claude writes and you can rerun. Use them for codebase audits, large migrations, and cross-checked research.

Copy pageCopy page

Dynamic workflows are available on all paid plans, with Anthropic API access, and on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry. On Pro, turn them on from the Dynamic workflows row in `/config`.

A dynamic workflow is a JavaScript script that orchestrates many [subagents](../09-Agents-Patterns/sub-agents.md) at once. Claude writes the script for the task you describe, and a runtime executes it in the background while your session stays responsive. Reach for a workflow when a task needs more agents than one conversation can coordinate, or when you want the orchestration codified as a script you can read and rerun. Examples include a codebase-wide bug sweep, a 500-file migration, a research question that needs sources cross-checked against each other, and a hard plan worth drafting from several independent angles before you commit to one.


[​](#when-to-use-a-workflow)

When to use a workflow

[Subagents](../09-Agents-Patterns/sub-agents.md), [skills](../08-Plugins-Skills/skills.md), [agent teams](../09-Agents-Patterns/agent-teams.md), and workflows can all run a multi-step task. The difference is who holds the plan:

|                                 | Subagents                      | Skills                       | Agent teams                            | Workflows                            |
|:--------------------------------|:-------------------------------|:-----------------------------|:---------------------------------------|:-------------------------------------|
| What it is                      | A worker Claude spawns         | Instructions Claude follows  | A lead agent supervising peer sessions | A script the runtime executes        |
| Who decides what runs next      | Claude, turn by turn           | Claude, following the prompt | The lead agent, turn by turn           | The script                           |
| Where intermediate results live | Claude’s context window        | Claude’s context window      | A shared task list                     | Script variables                     |
| What’s repeatable               | The worker definition          | The instructions             | The team definition                    | The orchestration itself             |
| Scale                           | A few delegated tasks per turn | Same as subagents            | A handful of long-running peers        | Dozens to hundreds of agents per run |
| Interruption                    | Restarts the turn              | Restarts the turn            | Teammates keep running                 | Resumable in the same session        |

A workflow moves the plan into code. With subagents, skills, and agent teams, Claude is the orchestrator: it decides turn by turn what to spawn or assign next, and every result goes into a context window. A workflow script holds the loop, the branching, and the intermediate results itself, so Claude’s context holds only the final answer. Moving the plan into code also lets a workflow apply a repeatable quality pattern, not just run more agents: it can have independent agents adversarially review each other’s findings before they’re reported, or draft a plan from several angles and weigh them against each other, so you get a more trustworthy result than a single pass.


[​](#run-a-bundled-workflow)

Run a bundled workflow

The quickest way to see a workflow in action is to run `/deep-research`, the [built-in workflow](#bundled-workflows) Claude Code includes for investigating a question across many sources. You’ll see agents work through a set of phases in the background while your session stays free, and get one report at the end instead of a turn-by-turn transcript.

1

Run the workflow

Run `/deep-research` with a question you want investigated. It fans out web searches across several angles, fetches and cross-checks the sources it finds, and synthesizes a cited report.

```python
/deep-research What changed in the Node.js permission model between v20 and v22?
```

2

Allow workflows

Claude Code asks whether to allow the workflow. Select **Yes** to continue. The exact prompt depends on your permission mode. See [Approve the plan before it runs](#approve-the-plan-before-it-runs) for the per-mode options.

3

Watch progress

The run starts in the background. Run `/workflows` to open its progress view:

```python
/workflows
```

If `/workflows` shows a list of runs instead, select the run you just started and press Enter. The view shows each phase with its agent count. Drill into any phase to see its agents and what each one found. See [Watch the run](#watch-the-run) for the full set of controls.You can also watch from the task panel below the input box: a one-line progress summary appears there while the run is going. Press the down arrow to focus it, then Enter to expand.

4

Read the report

When the run finishes, the report appears in your session. It cites the sources each claim came from, with claims that didn’t survive cross-checking already filtered out.When the verifier agents can’t check a claim, such as after a rate limit or API error, the report lists that claim as unverified instead of counting it as refuted.

To run a workflow for your own task, [have Claude write one](#have-claude-write-a-workflow), and once a run does what you wanted you can [save it](#save-the-workflow-for-reuse) as a command of your own.


[​](#bundled-workflows)

Bundled workflows

Claude Code includes `/deep-research` as a built-in workflow:

| Command                     | What it does                                                                                                                                                                                                                                                                                                           |
|:----------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `/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](tools-reference.md#websearch-tool-behavior) to be available |

`/deep-research` runs only when you invoke it. [Workflows you save](#save-the-workflow-for-reuse) yourself become commands the same way and appear in `/` autocomplete alongside the bundled ones.


[​](#watch-the-run)

Watch the run

Workflows run in the background, so the session stays responsive while agents work. Run `/workflows` at any time to list running and completed workflows, then select one to open its progress view. When the session has only one run, `/workflows` skips the list and opens that run. To stop a running workflow from the list without opening it, select it and press `x`. The progress view shows each phase with its agent counts. The footer lists the key for each action:

| Key            | Action                                                                                                     |
|:---------------|:-----------------------------------------------------------------------------------------------------------|
| `↑` / `↓`      | Select a phase or agent                                                                                    |
| `Enter` or `→` | Drill into the selected phase, then into an agent’s detail. In the detail, `Enter` expands or collapses it |
| `Esc` or `←`   | Back out one level                                                                                         |
| `j` / `k`      | Scroll within the agent detail when it overflows                                                           |
| `f`            | Filter the agent list in the selected phase by status. Press again to cycle                                |
| `p`            | Pause or resume the run                                                                                    |
| `x`            | Stop the selected agent, or stop the whole workflow when focus is on the run                               |
| `r`            | Restart the selected running agent                                                                         |
| `s`            | [Save](#save-the-workflow-for-reuse) the run’s script as a command                                         |

The agent detail lists the agent’s prompt, its recent tool calls, and its result. Each call shows its state, such as still running or failed. When the agent keeps a task list of its own, the detail shows it too, with each task’s status. Press `Enter` to expand the detail. The prompt and result then show in full, and each listed call shows its input and the start of its result.


[​](#have-claude-write-a-workflow)

Have Claude write a workflow

You can have Claude write a workflow for your task in two ways:

- [Ask for a workflow](#ask-for-a-workflow-in-your-prompt) in your prompt, either in your own words or by including the keyword `ultracode`, and Claude writes one for the task.
- [Let Claude decide with ultracode](#let-claude-decide-with-ultracode): set `/effort ultracode` and Claude plans a workflow for every substantive task in the session.

You can also run a workflow command that already exists: a [bundled workflow](#bundled-workflows) like `/deep-research`, or one you’ve [saved](#save-the-workflow-for-reuse).


[​](#ask-for-a-workflow-in-your-prompt)

Ask for a workflow in your prompt

To run a single task as a workflow without changing the session’s effort level, include the keyword `ultracode` in your prompt. Asking in your own words, for example “use a workflow” or “run a workflow”, also works: Claude treats a direct request as the same opt-in.

```python
ultracode: audit every API endpoint under src/routes/ for missing auth checks
```

Claude Code highlights the keyword in your input and Claude writes a workflow script for the task instead of working through it turn by turn. The keyword only chooses how Claude structures the work: the agents’ tool calls receive the same permission checks and [sandboxing](sandboxing.md) as any other tool call in the session. If the run does what you wanted, you can [save it as a command](#save-the-workflow-for-reuse) afterward. If you already have an orchestrator built another way, such as a folder of subagent prompts or a skill that fans work out, you can point Claude at it and ask for a workflow that does the same thing.


[​](#dismiss-or-turn-off-the-keyword)

Dismiss or turn off the keyword

If you didn’t mean to start a workflow, press `Option+W` on macOS or `Alt+W` on Windows and Linux to dismiss the highlight for this prompt, or press backspace while the cursor is right after the highlighted keyword. To stop the keyword from triggering at all, turn off Ultracode keyword trigger in `/config`.


[​](#where-the-keyword-works)

Where the keyword works

The keyword is an opt-in only in a prompt you type yourself: at the interactive prompt, in an IDE extension panel, in a [Remote Control](remote-control.md) client, or in an Agent SDK application that stamps your keyboard input’s [`origin`](../05-Agent-SDK/agent-sdk-typescript.md#sdkmessageorigin) as `{ kind: "human" }`. It doesn’t start a workflow when it reaches the session another way:

- a prompt passed with `-p`
- a prompt an Agent SDK application sends without stamping it as human input
- a scheduled task prompt
- a webhook payload or pull request comment relayed into the conversation


[​](#let-claude-decide-with-ultracode)

Let Claude decide with ultracode

Ultracode is a Claude Code setting that turns on automatic workflow orchestration for the session, at whichever [effort level](model-config.md#adjust-effort-level) the session runs at. With it on, Claude plans a workflow for each substantive task instead of waiting for you to ask. Turn it on at the Claude Code prompt:

```python
/effort ultracode
```

To start a session with ultracode already on, launch with `claude --effort ultracode`, which also sets the effort level to `xhigh`. To turn it on from the `/effort` slider, press `Tab` to flip the **Ultracode** toggle, then `Enter` to apply it. [Adjust effort level](model-config.md#adjust-effort-level) lists the routes that turn ultracode on. With ultracode on, Claude decides when a task warrants a workflow. A single request can turn into several workflows in a row: one to understand the code, one to make the change, and one to verify it. This applies to every task in the session, so each request uses more tokens and takes longer than the same request without a workflow. On a subscription plan those tokens draw on your usage limits, so a session with ultracode on reaches a session or weekly limit sooner than the same work with it off. Turning ultracode on already opts you in to large runs, so these checks don’t apply while it’s on:

- The [`Large workflow` warning](#cost) doesn’t appear on a workflow run
- The session’s [concurrent subagent limit](../09-Agents-Patterns/sub-agents.md#concurrent-subagent-limit) isn’t enforced for the subagents Claude spawns with the Agent tool
- In auto permission mode, you aren’t asked to [approve the first workflow launch](#approve-the-plan-before-it-runs)

`/effort ultracode` lasts for the current session; to have every session start with it, set the [`ultracode`](settings-reference.md#ultracode) setting. Turn it off with `/effort ultracode off` when you return to routine work. The `/effort` slider offers the toggle only [when ultracode is available](model-config.md#when-ultracode-is-available).


[​](#approve-the-plan-before-it-runs)

Approve the plan before it runs

In the CLI, the per-run prompt shows the planned phases and these options:

- **Yes, run it**: start the run
- **Yes, and don’t ask again for `<name>` in `<path>`**: start, and skip this prompt for this workflow in this project from now on. Claude Code offers this option when you run a bundled, saved, or plugin workflow by name, not for a script Claude wrote for the current task.
- **View raw script**: read the script before deciding
- **No**: cancel

`Ctrl+G` opens the script in your editor. With **Yes, run it** or **No** selected, press `Tab` to [add a comment](permissions.md#add-a-comment-when-you-answer-a-permission-prompt) to your answer. Whether you see this prompt depends on your [permission mode](permission-modes.md):

| Permission mode        | When you’re prompted                                                                                                                                    |
|:-----------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------|
| Auto                   | First launch only. Any **Yes** records consent in your user settings, and later launches start without prompting. Skipped entirely when ultracode is on |
| Manual, accept edits   | Every run, unless you’ve selected **Yes, and don’t ask again** for that workflow in this project                                                        |
| Bypass permissions     | Claude Code doesn’t prompt you. The run starts immediately                                                                                              |
| `claude -p`, Agent SDK | Claude Code doesn’t prompt you                                                                                                                          |

In `claude -p` and the Agent SDK, Claude Code never shows this prompt. It runs the Workflow tool call through the same [permission evaluation](../05-Agent-SDK/agent-sdk-permissions.md#how-permissions-are-evaluated) as the rest of the session, so deny rules, ask rules, and `dontAsk` mode apply to the launch as they apply to every tool call. To let the workflow start in these runs, use one of these:

- **Permission rule**: add `Workflow` to your allow rules to approve every workflow, or `Workflow(<name>)` to approve one saved workflow by name.
- **Auto permission mode**: run in [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode), where the classifier reviews the call and can approve it.
- **Bypass permissions mode**: run in bypass permissions mode.
- **A hook**: return `"allow"` for the call from a [`PreToolUse`](../07-Hooks/hooks.md#pretooluse) hook. In [plan mode](permission-modes.md#analyze-before-you-edit-with-plan-mode), the workflow doesn’t start on the hook’s approval alone, so use a permission rule or your host’s approval there instead.
- **Your host**: a [`--permission-prompt-tool`](cli-reference.md#cli-flags) or, with the Agent SDK, a [`canUseTool`](../05-Agent-SDK/agent-sdk-permissions.md) callback approves it.

In the Desktop app, an approval card shows the workflow name, the phase list, and a token-usage caution, with **Once**, **Always**, and **Deny** actions. The progress view appears in the Background tasks side pane. The subagents the workflow spawns use your [permission rules](settings-reference.md#permission-settings), and Claude Code picks their permission mode by the rules under [which permission mode a subagent runs in](../09-Agents-Patterns/sub-agents.md#permission-modes). To avoid prompts on a long run, add the tools the agents need to your allow rules before starting.


[​](#save-the-workflow-for-reuse)

Save the workflow for reuse

When Claude writes a workflow for a task you’ll repeat, you can save that run’s script as a command. A process like a review you run on every branch then runs the same orchestration each time. Run `/workflows`, select the run you want to keep, and press `s`. In the save dialog, Tab toggles between the two save locations:

- `.claude/workflows/` in your project: shared with everyone who clones the repo
- `~/.claude/workflows/` in your home directory: available in every project, visible only to you. If you set [`CLAUDE_CONFIG_DIR`](env-vars.md), this location is the `workflows/` directory under that path.

The save dialog shows the resolved path for the personal location. Press Enter to save. The workflow runs as `/<name>` in future sessions from either location. Claude Code checks the save location for symlinks before writing, and shows an error instead of writing through one. What it checks depends on where you save:

- Project location: Claude Code refuses if `.claude`, `.claude/workflows`, or the target file is a symlink.
- Personal location: Claude Code refuses only if the target file itself is a symlink, so a `~/.claude` directory managed by a dotfiles tool still works.

Before v2.1.216, Claude Code followed the link, which could place the file outside the location you chose. In a monorepo with several `.claude/` directories, you can keep workflows alongside the package they apply to. Saving to the project location writes to the closest `.claude/workflows/` directory that already exists between your working directory and the repository root, or to the repository root if none exists yet. Project workflows also load from every `.claude/workflows/` along that path, and when more than one defines the same name Claude Code runs the one closest to the working directory. If a project workflow and a personal workflow share a name, the project one runs.


[​](#distribute-a-workflow-in-a-plugin)

Distribute a workflow in a plugin

To share a workflow across teams or repositories, include it in a [plugin](../08-Plugins-Skills/plugins.md). Place the script in a `workflows/` directory at the plugin root, or point to a different location with the [`workflows` manifest field](../08-Plugins-Skills/plugins-reference.md#fields). Plugin workflows are namespaced by the plugin name. A plugin called `acme-tools` containing a script whose `meta.name` is `release-audit` runs as `/acme-tools:release-audit`.


[​](#pass-input-to-a-saved-workflow)

Pass input to a saved workflow

A saved workflow can accept input through the `args` parameter. The script reads it as a global named `args`. Use this to supply a research question, a list of target paths, or a configuration object at invocation time instead of editing the script for each run. The following prompt runs a saved workflow with a list of issue numbers:

```python
Run /triage-issues on issues 1024, 1025, and 1030
```

Claude passes the list as structured data, so the script can call array and object methods on `args` directly without parsing it first. If `args` is omitted, the global is `undefined` inside the script.


[​](#example-workflow-prompts)

Example workflow prompts

A workflow fits best when the task is larger than one agent can hold in context, or when the same step needs to run across many items. The prompts below show common shapes. Each one asks Claude to write and run a workflow for that task; you don’t write the script yourself.


[​](#audit-many-files-for-the-same-issue)

Audit many files for the same issue

Fan out one agent per file, then collect and verify the findings.

```python
use a workflow to audit every route handler under src/routes/ for missing authentication checks, and adversarially verify each finding before reporting it
```


[​](#keep-fixing-until-a-check-passes)

Keep fixing until a check passes

Run a checker, fix what failed, and repeat until it passes or stops making progress.

```python
use a workflow to run npx tsc --noEmit and keep fixing the reported errors until the type check passes or two rounds in a row make no progress
```


[​](#migrate-many-files-in-parallel)

Migrate many files in parallel

Discover the files to migrate, transform each one in an isolated copy so edits don’t conflict, and verify each result.

```python
use a workflow to migrate every component under src/components/ from JavaScript to TypeScript, working on each file in its own isolated copy
```


[​](#review-every-changed-file-and-write-one-summary)

Review every changed file and write one summary

Run a reviewer per file, then pass all the findings to one agent that ranks and deduplicates them.

```python
use a workflow to review every file changed in this PR for correctness issues, then merge the per-file findings into one ranked summary
```


[​](#research-a-topic-across-many-sources)

Research a topic across many sources

Fan out readers across changelogs, issues, and docs, then synthesize. The bundled `/deep-research` workflow does this; you can also describe a narrower version.

```python
use a workflow to research how our three competitors handle rate limiting: read their public docs and recent changelog entries in parallel, then compare the approaches
```


[​](#find-issues-until-the-list-stops-growing)

Find issues until the list stops growing

Keep searching in rounds and stop when new rounds turn up nothing new.

```python
use a workflow to find flaky tests in this repo: run the suite repeatedly, record which tests fail intermittently, and stop once two rounds in a row find nothing new
```


[​](#what-the-saved-script-looks-like)

What the saved script looks like

When you [save a workflow](#save-the-workflow-for-reuse), the file in `.claude/workflows/` holds a `meta` block followed by a script body that orchestrates subagents. You usually don’t need to edit it, but here is the shape of a small one so you can recognize what Claude generated:

```python
export const meta = {
  name: 'audit-routes',
  description: 'Audit every route handler for missing auth checks',
}

const found = await agent('List every .ts file under src/routes/.', {
  schema: { type: 'object', required: ['files'], properties: { files: { type: 'array', items: { type: 'string' } } } },
})

const audits = await pipeline(found.files, file =>
  agent(`Audit ${file} for missing authentication checks.`, { label: file }),
)

return audits.filter(Boolean)
```

The body is plain JavaScript with top-level `await`. `agent()` spawns one subagent, `pipeline()` runs one per item in a list, and `parallel()` runs a set of agent tasks at the same time and waits for all of them. An `agent()` call resolves to `null` if you stop it mid-run or it hits an unrecoverable API error. `pipeline()` keeps each `null` in the results array, which is why the example ends with `.filter(Boolean)` to drop those entries, including the slot of [an agent that stalled on every attempt](#when-an-agent-stalls-and-restarts). In [auto mode](permission-modes.md#eliminate-prompts-with-auto-mode), the prompt your script passes to `agent()` doesn’t count as a request from you when the classifier reviews that subagent’s actions, because Claude Code marks it as text the script computed. If you pass a `schema` on an `agent()` call, that subagent returns JSON matching the shape instead of prose. Claude Code checks the schema before starting the subagent: when it can prove the schema contradicts itself, the call fails with an error naming the contradiction, and the subagent never starts. One contradiction it can prove is a `required` key that `additionalProperties: false` rules out. If the subagent’s output still fails validation after five attempts, the call fails with an error that includes the last validation failure. To change the attempt count, set [`MAX_STRUCTURED_OUTPUT_RETRIES`](env-vars.md).


[​](#edit-a-saved-script)

Edit a saved script

To change a [workflow you saved](#save-the-workflow-for-reuse), edit its `.js` file or ask Claude to make the change. Before you edit or ask, run the `/workflow-authoring` [bundled skill](../08-Plugins-Skills/skills.md#bundled-skills) to load the script-writing reference Claude works from. The skill requires Claude Code v2.1.248 or later. To run the edited version in the current session, run [`/reload-skills`](commands.md#all-commands) to re-read the workflow directories, then run `/<name>` again. Claude Code applies these rules to each part of the file when it loads and runs the script:

- **`meta` block**: keep `export const meta` as the first statement, and keep it a plain object literal with a `name` and a `description`. If it contains anything other than literal values, such as a variable, a function call, or a spread, Claude Code drops `/<name>` from `/` autocomplete.
- **Body**: besides `agent()`, `pipeline()`, and `parallel()`, you can call `phase()` to group the agents that follow under a title in the progress view, call `log()` to show a message above the phases, and read the [`args`](#pass-input-to-a-saved-workflow) global. If the body has a syntax error, Claude Code reports it when you run the workflow.
- **`phases`**: if you list them in `meta`, give each entry exactly the title you pass to `phase()`. A `phase()` title with no entry gets a progress group of its own.
- **Timestamps and randomness**: Claude Code makes `Date.now()`, `Math.random()`, and a no-argument `new Date()` throw inside the script, so that a [relaunched run](#resume-after-a-pause) repeats the same `agent()` calls. Pass a timestamp in through `args` instead.

You can also edit [the script of a single run](#how-a-workflow-runs) rather than the saved copy. [Resume after a pause](#resume-after-a-pause) covers which agents run again when you relaunch an edited script. For the Workflow tool’s inputs, see its entry in the [Agent SDK reference](../05-Agent-SDK/agent-sdk-typescript.md#workflow).


[​](#how-a-workflow-runs)

How a workflow runs

The workflow runtime executes the script in an isolated environment, separate from your conversation. Intermediate results stay in script variables instead of landing in Claude’s context. Every run writes its script to a file under your session’s directory in `~/.claude/projects/`. Claude receives the path when the run starts, so you can ask for it. You can open that file to read the orchestration Claude wrote, diff it against a previous run’s script, or edit it and ask Claude to relaunch from the edited version. Claude can start a workflow only from a script file the session is already allowed to read. To run a script kept outside your working directory, add its directory with [`/add-dir`](permissions.md#working-directories) or a [Read allow rule](permissions.md#read-and-edit) first. The runtime tracks each agent’s result as the run progresses, which is what makes a run [resumable](#resume-after-a-pause) within the same session.


[​](#prompt-caching-in-a-fan-out)

Prompt caching in a fan-out

Agents in the same run can read each other’s [prompt cache](prompt-caching.md#subagents-and-the-cache). Two agents that run with the same model, effort level, agent type, tools, output schema, and working directory build the same tools-and-system-prompt prefix, so an agent that starts after a matching sibling’s response has begun reads that sibling’s cache on its first request. A workflow agent’s requests fall outside the main conversation’s [cache TTL bucket](prompt-caching.md#which-ttl-each-request-gets), so its cache holds for five minutes by default, including on a Claude subscription. To keep it for an hour, set [`subagentPromptCacheTtl`](settings-reference.md#subagentpromptcachettl) to `1h`. The API bills 1-hour cache writes at a higher rate. When a fan-out starts several matching agents at once, Claude Code holds all but the first until the first agent’s response begins, then releases the held agents together so their first requests read the shared prefix instead of each processing it uncached. Claude Code caps the hold at [`CLAUDE_CODE_WORKFLOW_PREFIX_STAGGER_MS`](env-vars.md) milliseconds, `5000` by default. Set it to `0` to disable the hold.


[​](#behavior-and-limits)

Behavior and limits

The runtime applies the following constraints:

| Constraint                                                                                                                                                                                                                                                                                                    | Why                                                                                                                                                                                    |
|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| No mid-run user input                                                                                                                                                                                                                                                                                         | A run pauses on its own only for agent permission prompts and a [usage-limit wait](#when-a-run-hits-your-usage-limit). For sign-off between stages, run each stage as its own workflow |
| No direct filesystem or shell access from the workflow itself                                                                                                                                                                                                                                                 | Agents read, write, and run commands. The script coordinates the agents                                                                                                                |
| No module loading: a script that contains `import()` fails before the run starts                                                                                                                                                                                                                              | The script body is plain JavaScript. Put work that needs a library in an agent’s task                                                                                                  |
| Up to 16 concurrent agents by default, fewer when Claude Code has fewer CPUs available, including inside a CPU-limited container. To change the limit, set [`CLAUDE_CODE_WORKFLOW_MAX_CONCURRENT_AGENTS`](env-vars.md#variables) to a value from 1 to 256, which requires Claude Code v2.1.269 or later | Bounds local resource use                                                                                                                                                              |
| In a fan-out, agents that share the first agent’s prompt-cache prefix start up to 5 seconds after it by default                                                                                                                                                                                               | All but the first read the [prefix the first agent cached](#prompt-caching-in-a-fan-out) instead of each processing it uncached                                                        |
| Up to 4,096 items in a single `parallel()` or `pipeline()` call: the runtime rejects a longer list with an error                                                                                                                                                                                              | A silent cap would drop part of the workload without telling the script                                                                                                                |
| 1,000 agents total per run                                                                                                                                                                                                                                                                                    | Prevents runaway loops                                                                                                                                                                 |


[​](#manage-runs)

Manage runs

Once a run starts, you manage it from the `/workflows` view, or by expanding its progress line in the task panel below the input box. When you stop a run, it stays in the task panel while any of its agents’ processes are still running. If you stop it again, Claude Code re-signals those processes.


[​](#resume-after-a-pause)

Resume after a pause

Resume a paused run from `/workflows` by selecting it and pressing `p`. For a run you stopped, ask Claude to relaunch the workflow with the same script. If agents from the stopped run haven’t exited yet, Claude Code refuses the relaunch until they have, so a second copy of those agents can’t run alongside them.


[​](#which-agents-run-again)

Which agents run again

Claude Code replays the run in the order agents start, and each agent either returns its saved result or runs again:

- **Completed**: returns its saved result. The first agent whose prompt differs from the previous run, because you edited the script or an earlier agent returned something different, runs again, and so does every agent after it, even ones that completed. Before v2.1.305, completed agents could also run again when you relaunched an unedited script whose `pipeline()` items or `parallel()` tasks ran more than one agent each. To stop those reruns for new runs, update Claude Code.
- **Still running when you stopped**: starts over. Stopping the whole run doesn’t count any agent as failed.
- **Failed**: runs again, and so does every agent the script starts after it, even ones that completed. Stopping one agent alone, by selecting it in [`/workflows`](#watch-the-run) and pressing `x`, counts as failing.

That last case means a failure in the middle of a fan-out reruns work that already finished. If a script starts A, B, C, and D in that order and B fails, relaunching returns A from cache and runs B, C, and D again. If you edit a script that started A, B, C, and D so that it starts A, C, B, and D, the second agent to start is now C, where the previous run started B. Relaunching returns A from cache and runs C, B, and D again.


[​](#resume-after-you-leave-the-session)

Resume after you leave the session

You can resume a run within the same Claude Code session. What happens to a running workflow when you leave the session depends on how you leave:

- If you [background the session](../09-Agents-Patterns/agent-view.md#what-carries-over-when-you-background), Claude Code replays the run the same way in the background session and continues it.
- If you exit Claude Code while a workflow is running and [agent view is on](../09-Agents-Patterns/agent-view.md#from-inside-a-session), the exit dialog offers `Move to background and exit`, which carries the run over the same way. If you choose `Exit and stop tasks` instead, or the option isn’t offered, the run stops with the session. Claude Code keeps the run’s saved results under that session’s directory in `~/.claude/projects/`, so a session you resume with `claude --resume` can replay them when you ask Claude to relaunch the workflow. In a session you start fresh, Claude has no earlier run to relaunch and starts the workflow over as a new run.

In a [cloud session](claude-code-on-the-web.md), Claude Code also saves the run’s results with the session’s conversation history, which survives when the session’s VM is reclaimed. When you [reopen such a session](claude-code-on-the-web.md#environment-expired) and ask Claude to relaunch the workflow, completed agents still return their saved results. In local and cloud sessions alike, when Claude relaunches an earlier run and Claude Code can’t find that run’s saved results at all, the relaunch fails with a `nothing to resume` error instead of starting the run over on its own. Ask Claude to start the workflow over as a new run.


[​](#when-a-run-hits-your-usage-limit)

When a run hits your usage limit

When an agent hits your claude.ai [usage limit](interactive-mode.md#wait-for-a-usage-limit-to-reset), the run pauses rather than failing that agent: the agents that hit the limit wait for the reset, and no new agents start. Shortly after the limit resets, the waiting agents run again and the run continues on its own. Requires Claude Code v2.1.271 or later; on earlier versions, the affected agents fail. While the run waits, its progress line in the task panel and the [`/workflows`](#watch-the-run) header show when the limit resets. The run pauses only when all of these hold; when one doesn’t, the affected agent fails instead:

- The session is interactive and signed in with a claude.ai subscription. A run doesn’t pause in [non-interactive mode](headless.md) with `claude -p` or the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md), in a [background session](../09-Agents-Patterns/agent-view.md), or in a [Remote Control](remote-control.md) or [agent team](../09-Agents-Patterns/agent-teams.md) teammate session.
- [`autoContinueAtUsageLimit`](settings-reference.md#autocontinueatusagelimit) is on, the same setting that lets the session itself [wait for a usage limit to reset](interactive-mode.md#wait-for-a-usage-limit-to-reset). If you turn it off during a wait, the wait ends and the waiting agents fail.
- The limit resets within 24 hours. A weekly limit can reset further out.
- The run hasn’t already waited twice. When it hits the limit a third time, the agent fails.


[​](#when-an-agent-stalls-and-restarts)

When an agent stalls and restarts

An agent whose output stops arriving for long enough starts over from the same prompt. In [`/workflows`](#watch-the-run), its name gains a `(retry 1)` suffix and its detail shows `attempt 2 (stalled)`. The restart is automatic, so you don’t need to do anything. The new attempt starts without the stalled attempt’s transcript. Files the stalled attempt already changed stay changed, and the tokens it spent stay in the run’s total. The stall window is how long Claude Code waits for output from an agent before it ends the attempt. Time the agent spends waiting on its own tool calls or on a [usage-limit reset](#when-a-run-hits-your-usage-limit) doesn’t count toward the stall window. An agent restarts at most five times, counting any restart you ask for with `r`. If the sixth attempt stalls as well, the `agent()` call fails, and the start of the error says why:

- `agent stalled on all 6 attempts`: every attempt went the whole window without output. If the agent’s work keeps it silent that long, lengthen the window
- `agent lost its reply on all 6 attempts`: every attempt’s response stream went silent and Claude Code gave up waiting on it. Lengthening the stall window doesn’t help, since a [streaming idle watchdog](../13-Enterprise-Admin/network-config.md#streaming-idle-watchdogs) ended the response first and `CLAUDE_STREAM_IDLE_TIMEOUT_MS` sets that watchdog’s timeout
- `agent abandoned after 6 attempts`: the attempts ended in different ways, which the error lists in order

To give an agent more time to produce output before the window ends:

- **One agent**: pass `stallMs` in milliseconds on its `agent()` call, such as `agent(prompt, { stallMs: 1800000 })` for 30 minutes
- **Every agent**: set [`CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS`](env-vars.md#variables), which also applies to subagents outside workflows

Whether the run continues after the failure depends on how your script called the agent:

- **Inside [`parallel()` or `pipeline()`](#what-the-saved-script-looks-like)**: the run carries on with `null` in place of the agent’s result
- **Awaited directly**: the run ends with the error

To try again, ask Claude to relaunch the workflow. [Resume after a pause](#resume-after-a-pause) covers what runs again.


[​](#cost)

Cost

A workflow spawns many agents, so a single run can use meaningfully more tokens than working through the same task in conversation. Runs count toward your plan’s usage and rate limits. To gauge the spend before committing to a large task, run the workflow on a small slice first: one directory instead of the whole repo, or a narrow question instead of a broad one. The `/workflows` view shows each agent’s token usage as the run progresses, and you can stop the run there at any time, usually without losing completed work. [Resume after a pause](#resume-after-a-pause) covers what a stopped run keeps. The runtime’s [agent caps](#behavior-and-limits) limit how many agents a single run can spawn, which bounds the cost of a runaway script. To keep runs to fewer agents, choose the `small` [size guideline](#set-a-size-guideline). Claude Code also flags a run that grows unusually large. When a workflow schedules more than 25 agents, or its projected token total passes 1.5 million, its progress line in the task panel below the input box shows a `Large workflow` warning. The warning points you to [`/workflows`](#watch-the-run), where you can stop the run. The warning is advisory: it doesn’t pause or limit the run. Two settings change when you see it:

- If you choose a [size guideline](#set-a-size-guideline) yourself, its agent count replaces the 25-agent threshold. The built-in default guideline leaves the threshold at 25.
- Sessions with [ultracode](#let-claude-decide-with-ultracode) on don’t show the warning, because turning ultracode on already opts you in to large runs.

Claude Code picks each workflow agent’s model in the same [order it uses for subagents](../09-Agents-Patterns/sub-agents.md#choose-a-model). A model the script names for a stage counts as the per-invocation model in that order. When nothing else assigns one, the agent runs on your session’s model. To control the model cost:

- Check `/model` before a large run if you usually switch to a smaller model for routine work
- Ask Claude to use a smaller model for stages that don’t need the strongest one when you describe the task

When your organization’s [`availableModels` allowlist](model-config.md#restrict-model-selection) blocks a model the script requests for an agent, that agent runs on a substituted model instead, following the same [substitution rules as subagents](../09-Agents-Patterns/sub-agents.md#choose-a-model).


[​](#set-a-size-guideline)

Set a size guideline

A size guideline tells Claude how many agents to aim for when it writes a dynamic workflow. Claude Code sends the guideline to Claude as advice, not a cap, so a prompt that calls for a different scale still overrides it. Each value maps to an agent count:

| Value          | Agent count Claude aims for                         |
|:---------------|:----------------------------------------------------|
| `unrestricted` | No guideline: Claude sizes the workflow to the task |
| `small`        | Fewer than 5 agents                                 |
| `medium`       | Fewer than 10 agents                                |
| `large`        | Fewer than 50 agents                                |

The default is `medium`, or `small` when you’re signed in on a Pro plan with Claude Code v2.1.271 or later. Until you choose a value, the `/config` row marks the value as the default, and the workflow’s `Running in background` line names the size in force. Requires Claude Code v2.1.219 or later; earlier versions default to `unrestricted`. To change the guideline, pick a value for the Dynamic workflow size setting in `/config`, or run `/config workflowSizeGuideline=small`. On v2.1.219 and later, you can also set the [`workflowSizeGuideline` key](settings-reference.md#workflowsizeguideline) in any settings file; that value takes precedence over `/config`, and Claude Code hides the `/config` row while a settings file provides one. Changes take effect on the next prompt. The [runtime agent caps](#behavior-and-limits) still apply regardless of the setting.


[​](#turn-workflows-off)

Turn workflows off

Workflows are available in the CLI, the Desktop app, the IDE extensions, [non-interactive mode](headless.md) with `claude -p`, and the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md). The same disable settings apply on every surface. To turn workflows off for yourself:

- Toggle Dynamic workflows off in `/config`. Persists across sessions.
- Set `"disableWorkflows": true` in `~/.claude/settings.json`. Persists across sessions.
- Set `CLAUDE_CODE_DISABLE_WORKFLOWS=1`. Read at startup, so it applies wherever you set it.

To turn workflows off for your whole organization, set `"disableWorkflows": true` in [managed settings](../13-Enterprise-Admin/server-managed-settings.md), or use the toggle on the [Claude Code admin settings](https://claude.ai/admin-settings/claude-code) page. When workflows are disabled:

- `/workflows`, the workflow commands, and the `/workflow-authoring` skill are unavailable
- The `ultracode` keyword no longer triggers a run, and the **Ultracode** toggle is removed from `/effort`

A run that was already in progress keeps going. Turning workflows off also makes [ultracode](#let-claude-decide-with-ultracode) unavailable. No managed setting rules out ultracode alone: wherever it’s [available](model-config.md#when-ultracode-is-available), users can turn it on with `/effort ultracode`. An [effort cap](model-config.md#organization-effort-limits) lowers the effort level a session with ultracode on runs at, but doesn’t turn ultracode off.


[​](#related-resources)

Related resources

- [Run agents in parallel](../09-Agents-Patterns/agents.md): compare subagents, agent view, agent teams, and workflows
- [Create custom subagents](../09-Agents-Patterns/sub-agents.md): the worker primitive workflows orchestrate
- [Manage costs](../17-Billing-Plans/costs.md): how multi-agent runs count toward usage limits

---

## Run parallel sessions with worktrees - Claude Code Docs

Source: https://code.claude.com/docs/en/worktrees
Path: 02-Claude-Code-CLI/worktrees.md

## On this page

- [Start Claude in a worktree](#start-claude-in-a-worktree)
  - [Set up the worktree environment](#set-up-the-worktree-environment)
  - [Ask Claude to create a worktree](#ask-claude-to-create-a-worktree)
- [Clean up worktrees](#clean-up-worktrees)
- [Resume a worktree session](#resume-a-worktree-session)
- [How Claude Code enforces isolation](#how-claude-code-enforces-isolation)
- [Isolate subagents with worktrees](#isolate-subagents-with-worktrees)
  - [Clean up subagent and background-session worktrees](#clean-up-subagent-and-background-session-worktrees)
- [Customize worktree creation](#customize-worktree-creation)
  - [Choose the base branch](#choose-the-base-branch)
  - [Branch from a pull request](#branch-from-a-pull-request)
  - [Copy gitignored files into worktrees](#copy-gitignored-files-into-worktrees)
  - [Reuse a worktree name](#reuse-a-worktree-name)
  - [Replace worktree creation with a hook](#replace-worktree-creation-with-a-hook)
- [What worktrees share with the main checkout](#what-worktrees-share-with-the-main-checkout)
- [Manage worktrees manually](#manage-worktrees-manually)
- [Non-git version control](#non-git-version-control)
- [Troubleshooting](#troubleshooting)
  - [Claude Code can’t enter the worktree at startup](#claude-code-can%E2%80%99t-enter-the-worktree-at-startup)
  - [Worktree creation fails on a symlinked path](#worktree-creation-fails-on-a-symlinked-path)
  - [Git LFS files are pointer files in a worktree Claude Code created](#git-lfs-content-is-missing-from-a-worktree-claude-code-created)
  - [Worktree creation fails in a partial clone](#worktree-creation-fails-in-a-partial-clone)
  - [Claude Code refuses to use a worktree](#claude-code-refuses-to-use-a-worktree)
  - [The session resumes outside its worktree](#the-session-resumes-outside-its-worktree)
- [See also](#see-also)

Agents and parallel work

# Run parallel sessions with worktrees

Copy pageCopy page

Isolate parallel Claude Code sessions in separate git worktrees so changes don’t collide. Covers the `--worktree` flag, subagent isolation, `.worktreeinclude`, cleanup, and non-git VCS hooks.

Copy pageCopy page

A [git worktree](https://git-scm.com/docs/git-worktree) is a separate working directory with its own files and branch, sharing the same repository history and remote as your main checkout. Running each Claude Code session in its own worktree gives it a separate copy of the files to edit, so one session can build a feature while a second fixes a bug.

If you use another version control system or the desktop app, follow the instructions for your setup:

- **Other version control systems**: worktrees require a git repository; [configure hooks to replace the git logic](#non-git-version-control)
- **Desktop app**: see [Run a session in its own worktree](../16-Mobile-Desktop/desktop.md#run-a-session-in-its-own-worktree)

Worktrees are one of several ways to run Claude in parallel. They isolate file edits. [Subagents](../09-Agents-Patterns/sub-agents.md) split work up inside one session, and [cross-session messaging](cross-session-messaging.md) lets Claude pass findings between the sessions in your worktrees. See [Run agents in parallel](../09-Agents-Patterns/agents.md) to compare the approaches, or skip ahead to [Isolate subagents with worktrees](#isolate-subagents-with-worktrees) to use worktrees and subagents together. Most sessions need only the first two sections: [start Claude in a worktree](#start-claude-in-a-worktree), then [clean up when you exit](#clean-up-worktrees). Return to the rest of the page when you need to [resume a session](#resume-a-worktree-session), [change how worktrees are created](#customize-worktree-creation), or [debug a failure](#troubleshooting).


[​](#start-claude-in-a-worktree)

Start Claude in a worktree

Pass `--worktree` or `-w` with a name to create an isolated worktree and start Claude in it. By default, the worktree is created under `.claude/worktrees/<name>/` at your repository root, on a new branch named `worktree-<name>`:

```python
claude --worktree feature-auth
```

Run the command again with a different name in another terminal to start a second isolated session. If you omit the name, Claude generates one such as `bright-running-fox`. Interactive runs require [workspace trust](../13-Enterprise-Admin/security.md): if you haven’t run Claude in the directory before, run `claude` once there to accept the trust dialog, or `--worktree` exits with an error prompting you to. Non-interactive runs with `-p` skip the trust check, so `claude -p --worktree` proceeds without it.

Add `.claude/worktrees/` to your `.gitignore` so worktree contents don’t appear as untracked files in your main checkout.


[​](#set-up-the-worktree-environment)

Set up the worktree environment

A worktree is a fresh checkout, so initialize your development environment there: ask Claude to install dependencies, or run your project’s setup yourself in the worktree directory under `.claude/worktrees/`. To carry gitignored files such as `.env` into every new worktree automatically, add a [`.worktreeinclude` file](#copy-gitignored-files-into-worktrees).


[​](#ask-claude-to-create-a-worktree)

Ask Claude to create a worktree

You can also ask Claude to “work in a worktree” during a session, and it creates one with the [`EnterWorktree`](tools-reference.md) tool. Once in a worktree, Claude can switch directly to another one under `.claude/worktrees/` by calling `EnterWorktree` with the target path; the previous worktree stays on disk untouched. When Claude enters a path outside the repository’s `.claude/worktrees/` directory, Claude Code asks for your approval first, because the move takes the session’s working directory, write access, and project configuration such as `CLAUDE.md` and settings to that location. An `EnterWorktree` [permission rule](permissions.md) or choosing “don’t ask again” doesn’t suppress this prompt; only `bypassPermissions` mode skips it. Before v2.1.206, Claude could enter any existing worktree path without asking.

**Hook paths don’t follow the worktree.** After Claude enters a worktree, Claude Code keeps `${CLAUDE_PROJECT_DIR}` in your [hooks](../07-Hooks/hooks.md#reference-scripts-by-path) where it was and passes the worktree path to them a different way:

- **`${CLAUDE_PROJECT_DIR}` stays put**: it still points at the project root where the session started, so a hook command such as `${CLAUDE_PROJECT_DIR}/.claude/hooks/check-style.sh` still runs the script in the main checkout.
- **`cwd` follows Claude**: the `cwd` field in the hook’s [input JSON](../07-Hooks/hooks.md#common-input-fields) is the worktree root, and it moves again when Claude runs `cd`. Read it when a hook needs the worktree path.


[​](#clean-up-worktrees)

Clean up worktrees

When you exit an interactive worktree session, Claude checks the worktree for work that removal would delete: changed or untracked files, uncommitted work inside checked-out submodules, and new commits. These rules apply to worktrees Claude created with git. For a worktree your [WorktreeCreate hook](../07-Hooks/hooks.md#worktreecreate) created, see [WorktreeRemove](../07-Hooks/hooks.md#worktreeremove) instead.

- **The worktree is clean**: for an unnamed session, Claude removes the worktree and its branch automatically. A [named](sessions.md#name-your-sessions) session prompts you first so you can keep the worktree for later
- **The worktree has work in it**: Claude prompts you to keep or remove the worktree. Keeping preserves the directory and branch. To return later, run the `claude --worktree <name> --resume` command that Claude Code prints on exit. Removing deletes the worktree directory and its branch, along with all the work in them
- **Another branch is checked out**: if the worktree is on a branch other than its own that has commits past the worktree’s starting commit, Claude prompts you to keep or remove the worktree. Either answer keeps that other branch and its commits. Removing deletes the worktree directory and the worktree’s own branch, the one Claude created with it
- **The worktree’s state can’t be verified**: when Claude Code can’t count the worktree’s changes or can’t inspect its submodule checkouts, it prompts you rather than removing the worktree automatically. The prompt names what it couldn’t check

Non-interactive runs with `-p` have no exit prompt, so Claude doesn’t clean up their worktrees, and Claude Code leaves the lock it took on each one at creation in place until a later session’s [stale-lock sweep](#clean-up-subagent-and-background-session-worktrees) releases it. To remove one, run `git worktree remove`; if git refuses because the worktree is locked, run `git worktree unlock` on it first. On Windows, removing a worktree doesn’t delete files outside it. If a folder inside the worktree is a link to somewhere else, such as an NTFS junction or a directory symlink, Claude Code deletes only the link and keeps the folder it points to. Before v2.1.205, removing a worktree with a link nested in a subdirectory could delete the folder it pointed to.


[​](#resume-a-worktree-session)

Resume a worktree session

When you resume a session that ended inside a worktree without [exiting it](#clean-up-worktrees), Claude Code returns the session to that worktree. This holds for interactive resumes, for `--continue` and `--resume` in [non-interactive mode](headless.md) with `-p`, and for the Agent SDK. `--continue` picks the most recent session recorded under the directory you launch from. Back inside the worktree, Claude can still exit it with the [`ExitWorktree`](tools-reference.md) tool. Before returning the session to its worktree, Claude Code verifies that the worktree is still a checkout separate from the main one, and declines to re-enter a worktree that fails the check. For a git worktree, the check reads its git metadata. A worktree without git metadata, such as one a [`WorktreeCreate` hook](#non-git-version-control) created, can pass the check; the cases Claude Code still refuses are listed with their recoveries under [Claude Code refuses to use a worktree](#claude-code-refuses-to-use-a-worktree). For the messages and how to recover from each, see [The session resumes outside its worktree](#the-session-resumes-outside-its-worktree). Where you launch from, and how you resume, change what Claude Code re-enters:

- **Launch directory**: resume with `--resume` from the main checkout or another directory of the repository. Claude Code re-enters a worktree it created with git under `.claude/worktrees/` even when you launch from inside it. When you launch from inside any other worktree, Claude Code re-enters it only if it can vouch for it from there: a worktree that is its own repository, one without git metadata, or a launch from a subdirectory of a worktree you created with `git worktree add` declines, so launch those from the main checkout.
- **`--fork-session`**: the forked session starts in the directory you launched Claude from, and Claude Code leaves the original session’s worktree untouched.
- **Deleted worktree**: if the worktree directory no longer exists, Claude Code resumes the session in the directory you launched Claude from. It tells you the worktree is gone and clears the session’s worktree binding.

Before v2.1.212, a non-interactive resume stayed in the starting directory and `ExitWorktree` reported that there was no active worktree session to exit.

When Claude enters or exits a worktree that Claude Code created with git, the transcript follows: Claude Code records the session under the session’s new working directory, the same way [`/cd`](commands.md) does, so `/desktop` and `--resume` find it there. Exiting moves it back the same way. A worktree created by a [`WorktreeCreate` hook](#non-git-version-control) keeps its transcript at the launch directory. Requires Claude Code v2.1.198 or later.


[​](#how-claude-code-enforces-isolation)

How Claude Code enforces isolation

While a session is isolated in a worktree, Claude Code blocks the tool calls the checks below define. The same rules apply whether you started the session with `--worktree`, Claude entered a worktree with `EnterWorktree`, or you resumed a worktree session. The same enforcement covers every subagent Claude spawns from the isolated session. It applies whether the session is interactive or runs in the [background](../09-Agents-Patterns/agent-view.md#how-file-edits-are-isolated). [Subagents that run in their own worktree](#isolate-subagents-with-worktrees) carry the same checks. Their version history is under [Write subagent files](../09-Agents-Patterns/sub-agents.md#write-subagent-files). Claude Code applies four checks:

- **File edits**: Claude Code blocks an `Edit`, `Write`, or `NotebookEdit` that targets a path in the main checkout.
- **Command working directory**: Claude Code blocks a Bash, PowerShell, or Monitor command whose working directory resolves to the main checkout, or whose working directory it can’t verify stays outside it.
- **Git redirects**: Claude Code blocks a Bash or Monitor command that redirects git into the main checkout. The redirect can come through `git -C`, `--git-dir`, a `GIT_DIR` or `GIT_WORK_TREE` variable, or a `cd` into the main checkout before running git.
- **Command shape**: Claude Code blocks a Bash or Monitor command when it can’t verify from the command text that any git the command runs stays inside the worktree. That happens, for example, when the command name is computed at runtime, when the syntax can’t be parsed, or when an expansion such as `${!name}` or `${ command; }` could run a command the text doesn’t spell out. Claude Code tells Claude how to rewrite the refused command, such as splitting it into plain, separate commands. You can’t turn this check off.

These checks read the path an edit targets, the directory a command runs in, and the text of the command. None of them tracks which files a shell command writes, so a command that writes into the main checkout without running git there, such as `cp` or a shell redirect, isn’t refused by them. Claude Code treats that command like any other shell command under your [permissions](permissions.md) and [sandboxing](sandboxing.md) settings. The checks apply to the repository you launched Claude Code from. They also cover the main checkout a linked worktree is linked from. For PowerShell commands, Claude Code applies only the working-directory check. Claude sees each refusal as a tool error that names the worktree and says how to proceed. For a refused command, see [what the refusal message means and how to clear it](errors.md#command-blocked-by-the-worktree-isolation-checks).


[​](#isolate-subagents-with-worktrees)

Isolate subagents with worktrees

Subagents can run in their own worktrees so parallel edits don’t conflict. Ask Claude to “use worktrees for your agents”, or make the isolation permanent for a [custom subagent](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields) by adding `isolation: worktree` to its frontmatter. This subagent in `.claude/agents/` always runs in its own worktree:

```python
---
name: refactorer
description: Applies mechanical refactors across many files
isolation: worktree
---

Apply the requested refactor across every affected file, then run the tests
and report the results.
```

Each subagent gets a temporary worktree that Claude Code removes automatically when the subagent finishes without changes; a worktree with changes stays on disk until the [periodic sweep below](#clean-up-subagent-and-background-session-worktrees) can remove it without losing work. For a worktree your [WorktreeCreate hook](../07-Hooks/hooks.md#worktreecreate) created, see [WorktreeRemove](../07-Hooks/hooks.md#worktreeremove) instead. Subagent worktrees use the same [base branch](#choose-the-base-branch) as `--worktree`, so they branch from your repository’s default branch unless `worktree.baseRef` is set to `"head"`. A subagent in its own worktree takes the instruction files it [starts with](../09-Agents-Patterns/sub-agents.md#what-loads-at-startup) from your main conversation, not from its worktree. When that worktree is in the default location under `.claude/worktrees/`, the subagent also doesn’t load the `CLAUDE.md` file or `.claude/rules/` directory at the worktree’s root as it reads files there, even if those differ on the worktree’s branch.


[​](#clean-up-subagent-and-background-session-worktrees)

Clean up subagent and background-session worktrees

Claude Code runs a periodic sweep that removes worktrees that Claude created for subagents and [background sessions](../09-Agents-Patterns/agent-view.md#how-file-edits-are-isolated) once they are older than your [`cleanupPeriodDays`](settings-reference.md#cleanupperioddays) setting, following the [retention sweep rules](claude-directory.md#cleaned-up-automatically). When you [background](../09-Agents-Patterns/agent-view.md#send-the-session-to-the-background) a `--worktree` session, its worktree becomes a background-session worktree that the sweep can remove. The sweep leaves a worktree in place in these cases:

- The worktree still holds work: changed or untracked files, or unpushed commits.
- A checked-out submodule in the worktree holds changed or untracked files, or Claude Code can’t inspect the worktree’s submodules. This check requires Claude Code v2.1.274 or later.
- One of the [four cases that also block worktree creation](#git-lfs-content-is-missing-from-a-worktree-claude-code-created) applies: Claude Code can’t determine which filter drivers the repository config defines, or finds a setting there it can’t switch off.
- The worktree belongs to a `--worktree` session you haven’t backgrounded, whatever its age.
- You created the worktree yourself with `git worktree add`, even if you then ran a `--worktree <name>` session in it and backgrounded that session.

Claude Code writes a marker into the git metadata of every worktree it creates with git, and the sweep keeps any worktree without one, including a worktree a [`WorktreeCreate` hook](#non-git-version-control) created. While an agent is running, Claude Code holds a `git worktree lock` on its worktree so that concurrent cleanup can’t remove it, and releases the lock when the agent finishes. Claude Code holds the same lock on the worktree it created for a backgrounded session while the session runs, so the sweep leaves the worktree in place and `git worktree remove` refuses to remove it. The sweep also releases a lock Claude Code set for a session whose process has exited, so a killed background session doesn’t leave its worktree permanently locked. The sweep never releases a lock you set yourself with `git worktree lock`. Before v2.1.210, a lock left by a killed session stayed in place until you ran `git worktree unlock`. To clean up a worktree that the sweep keeps, run `git worktree remove`, adding `--force` if the worktree has uncommitted changes or untracked files. If git refuses because the worktree is locked, run `git worktree unlock` on it first.


[​](#customize-worktree-creation)

Customize worktree creation

Claude Code’s defaults for creating worktrees cover most sessions: it creates them under `.claude/worktrees/`, branches them from your repository’s default branch, and checks out only tracked files. The options in this section change those defaults.


[​](#choose-the-base-branch)

Choose the base branch

New worktrees branch from the repository’s default branch, so most sessions don’t need this setting. Set `worktree.baseRef` in [settings](settings-reference.md#worktree) to branch from your current work instead. The setting accepts two values:

- `"fresh"` (default): branch from the repository’s default branch on the remote, usually `main`, so the worktree starts from a clean tree matching the remote.
- `"head"`: branch from your current local `HEAD`, so the worktree carries your unpushed commits and feature-branch state. Use this when isolating subagents that need to operate on in-progress work. Inside a worktree, `"head"` resolves to that worktree’s `HEAD`, not the main checkout’s.

You can’t set `worktree.baseRef` to a branch name. To start a worktree from a specific existing branch, [create it with git directly](#manage-worktrees-manually). For a `"fresh"` base, Claude Code keeps `origin/HEAD` current: when the repository hasn’t been fetched in the last 24 hours, it fetches the default branch, capped at five seconds, and uses the locally cached ref if the fetch fails. The fetch never waits for input in your terminal, so it also counts as failed when git or ssh would ask for a password, a key passphrase, or confirmation of a new SSH host. If no remote is configured, or `origin/HEAD` isn’t cached locally and can’t be fetched, the worktree falls back to your current local `HEAD`. Before v2.1.208, a fresh worktree used whatever `origin/HEAD` was already cached locally. This example makes every new worktree branch from your current work:

```python
{
  "worktree": {
    "baseRef": "head"
  }
}
```


[​](#branch-from-a-pull-request)

Branch from a pull request

To branch from a specific pull request or merge request, pass `--worktree` the number prefixed with `#`, a GitHub pull request URL, or a GitLab merge request URL such as `https://gitlab.com/group/repo/-/merge_requests/123`. Claude Code fetches that change’s head commit from `origin` and creates the worktree at `.claude/worktrees/pr-<number>`. Quote the argument so your shell doesn’t treat `#` as the start of a comment:

```python
claude --worktree "#1234"
```

Claude Code reads only the number from the URL. It always fetches from your repository’s `origin` remote, and picks the fetch path by `origin`’s host:

- **github.com**: fetches `pull/<number>/head`
- **gitlab.com**: fetches `merge-requests/<number>/head`
- **GitHub Enterprise, self-managed GitLab, or any other host**: tries `pull/<number>/head` first, then `merge-requests/<number>/head`

This fetch never waits for input in your terminal. If git or ssh would ask for a password, a key passphrase, or confirmation of a new SSH host, the fetch fails instead and Claude Code exits with an `Error creating worktree: Failed to fetch PR/MR #<number>` message. A key that `ssh-agent` holds still works, so load your key there and run `git fetch` once by hand to record a new host before you start. Before v2.1.233, Claude Code accepted only `#<number>` and GitHub-style pull request URLs for `--worktree`, and always fetched `pull/<number>/head`.


[​](#copy-gitignored-files-into-worktrees)

Copy gitignored files into worktrees

A worktree is a fresh checkout, so untracked files like `.env` or `.env.local` from your main repository are not present. To copy them automatically when Claude creates a worktree, add a `.worktreeinclude` file to your project root. The file uses `.gitignore` syntax. Only files that match a pattern and are also gitignored are copied, so tracked files are never duplicated. If you write a pattern that starts with `**/` and the files you want are inside a directory that is gitignored as a whole, Claude Code copies them only when that directory itself matches the pattern, or when the first name after the `**/` is one of the names in the directory’s path. For example, if you write `**/.claude/skills/*.md`, that first name is `.claude`, so Claude Code copies the matching files out of an ignored `.claude/` directory. To copy files out of an ignored directory that a `**/` pattern doesn’t reach, name the directory in the pattern instead: write `vendor/**/config.json` rather than `**/config.json`. Before v2.1.239, Claude Code copied files out of a wholly ignored directory for a `**/` pattern only when the directory itself matched the pattern. This `.worktreeinclude` copies two env files and a secrets config into each new worktree:

.worktreeinclude

```python
.env
.env.local
config/secrets.json
```

This applies to every worktree Claude Code creates with git: `--worktree` worktrees, [subagent worktrees](#isolate-subagents-with-worktrees), and parallel sessions in the [desktop app](../16-Mobile-Desktop/desktop.md#work-in-parallel-with-sessions). With a [`WorktreeCreate` hook](#non-git-version-control), copy the files inside the hook script.


[​](#reuse-a-worktree-name)

Reuse a worktree name

Passing `--worktree` a name whose directory already exists opens that existing worktree instead of creating a new one. With the default `"fresh"` [base](#choose-the-base-branch), a reopened worktree resets to the repository’s default branch instead of continuing at its old tip when all of the following hold:

- It has no uncommitted changes or untracked files.
- It is still on the branch Claude Code created for it.
- It has no commits of its own, or its pull request or merge request was merged and its remote branch deleted.

Claude Code detects the merged case from git state alone: the remote branch the worktree pushed to no longer exists, and every commit in the worktree is already on the default branch. In every other case, Claude Code reopens the worktree at its old tip:

- The worktree fails any of the conditions.
- Claude Code can’t verify the worktree’s state.
- `worktree.baseRef` is `"head"`.
- The name is a pull request or merge request reference.

Before v2.1.208, when you reused a name, Claude Code always reopened the old worktree at its old tip.


[​](#replace-worktree-creation-with-a-hook)

Replace worktree creation with a hook

Configure a [`WorktreeCreate` hook](../07-Hooks/hooks.md#worktreecreate) to replace the default `git worktree` logic entirely, including placing worktrees somewhere other than `.claude/worktrees/`. For a complete example, see [Non-git version control](#non-git-version-control).


[​](#what-worktrees-share-with-the-main-checkout)

What worktrees share with the main checkout

A worktree gets its own files and branch, but it shares the following with the main checkout:

- **The repository’s `.git` directory**: git commands in a worktree write to the main repository’s shared `.git` directory, and [sandboxing](sandboxing.md#filesystem-isolation) allows those writes, so commands such as `git commit` work from inside a worktree with the sandbox enabled.
- **Plugins**: plugins installed at [project scope](../08-Plugins-Skills/plugins-loading.md#find-where-a-plugin-is-enabled) from the main checkout also load in worktrees of the same repository, so you don’t need to reinstall them per worktree. Requires Claude Code v2.1.200 or later.
- **Permission approvals**: choosing “Yes, and don’t ask again” for a Bash command in a worktree session saves the rule to the main checkout’s `.claude/settings.local.json`, so it applies in the main checkout and in every other worktree of the repository, and it survives the worktree’s removal. On Windows and in the other cases where Claude Code [doesn’t use the repository root](settings.md#where-claude-code-looks-for-each-file), the rule stays with that worktree. Before v2.1.211, an approval granted in a worktree was saved inside that worktree, didn’t apply elsewhere, and was lost when the worktree was removed. See [where approvals are saved](permissions.md#permission-system).
- **Untracked skills, agents, and commands**: when the worktree checkout has no `.claude/skills` directory at its root, for example because your `.claude/skills` is gitignored, Claude Code loads the main checkout’s [project skills](../08-Plugins-Skills/skills.md#where-skills-live) in the worktree session. In a worktree with its own `.claude/skills` directory, only that copy loads. The same read-through covers `.claude/agents` and `.claude/commands`. For skills, the read-through requires Claude Code v2.1.277 or later.

All of these apply whether you create the worktree with `--worktree` or with `git worktree add`. In a worktree session you start from the [desktop app](../16-Mobile-Desktop/desktop.md#run-a-session-in-its-own-worktree), Claude Code reads project configuration such as settings, hooks, skills, agents, commands, and [`.mcp.json`](../06-MCP-Tools/General/mcp.md#project-scope) servers from the main checkout’s root. Hook commands run in that root, and `${CLAUDE_PROJECT_DIR}` points at it. To reach the files Claude is working on, read the worktree’s path from the hook’s [`cwd` input field](../07-Hooks/hooks.md#common-input-fields). `CLAUDE.md` files and `.claude/rules/` still load from the worktree.


[​](#manage-worktrees-manually)

Manage worktrees manually

Create worktrees with Git directly when you need to check out a specific existing branch or place the worktree outside the repository. Create a worktree on a new branch:

```python
git worktree add ../project-feature-a -b feature-a
```

Create a worktree from an existing branch, replacing `fix-issue-456` with a branch that already exists in your repository:

```python
git worktree add ../project-bugfix fix-issue-456
```

Start Claude in the worktree:

```python
cd ../project-feature-a
claude
```

List your worktrees:

```python
git worktree list
```

Remove one when you’re done with it:

```python
git worktree remove ../project-feature-a
```

See the [Git worktree documentation](https://git-scm.com/docs/git-worktree) for the full command reference.


[​](#non-git-version-control)

Non-git version control

Worktree isolation uses git by default. For SVN, Perforce, Mercurial, or other systems, configure [`WorktreeCreate` and `WorktreeRemove` hooks](../07-Hooks/hooks.md#worktreecreate) to provide custom creation and cleanup logic. Because the hook replaces the default git behavior, [`.worktreeinclude`](#copy-gitignored-files-into-worktrees) is not processed when you use `--worktree`. Copy any local configuration files inside your hook script instead. This `WorktreeCreate` hook reads the worktree name from the JSON on stdin with `jq`, checks out a fresh SVN working copy, and prints the directory path so Claude Code can use it as the session’s working directory. Add the configuration to your [`settings.json`](settings.md#where-settings-live):

```python
{
  "hooks": {
    "WorktreeCreate": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'NAME=$(jq -r .name); DIR=\"$HOME/.claude/worktrees/$NAME\"; svn checkout https://svn.example.com/repo/trunk \"$DIR\" >&2 && echo \"$DIR\"'"
          }
        ]
      }
    ]
  }
}
```

Pair it with a `WorktreeRemove` hook to clean up when the session ends. See the [hooks reference](../07-Hooks/hooks.md#worktreecreate) for the input schema and a removal example. A `WorktreeCreate` hook also lets you run [`/batch`](commands.md#all-commands) outside a git repository. Each `/batch` subagent then publishes its change with your project’s version-control commands and, when it can’t open a pull request, reports what it published instead. Running `/batch` outside a git repository requires Claude Code v2.1.281 or later.


[​](#troubleshooting)

Troubleshooting

Claude Code reports the errors below when it creates a worktree, enters one at startup, or returns a resumed session to one.


[​](#claude-code-can’t-enter-the-worktree-at-startup)

Claude Code can’t enter the worktree at startup

When Claude Code can’t enter the worktree directory at startup, it prints an error naming the path and exits with code 1. This can happen when a [`WorktreeCreate` hook](../07-Hooks/hooks.md#worktreecreate) prints something other than the directory it created, or when the directory was deleted after it was set up.


[​](#worktree-creation-fails-on-a-symlinked-path)

Worktree creation fails on a symlinked path

Claude Code refuses to create a worktree when `.claude`, `.claude/worktrees`, or the worktree directory itself is a symlink, and the error names the symlinked path. Remove the symlink and retry. Before v2.1.212, if the repository already contained a committed symlink at one of those paths, worktree creation followed it and could create files outside the repository.


[​](#git-lfs-content-is-missing-from-a-worktree-claude-code-created)

Git LFS files are pointer files in a worktree Claude Code created

If you set up [Git LFS](https://git-lfs.com) with `git lfs install --local`, a worktree that Claude Code creates contains LFS pointer files instead of the real files. The `--local` flag writes the LFS filter into the repository’s own `.git/config` rather than your global git config. A plain `git lfs install` writes to your global config and isn’t affected. The same applies to any other [filter driver](https://git-scm.com/docs/gitattributes) defined in the repository’s own config. Claude Code skips the repository’s own filter drivers when it creates a worktree because a filter driver is a shell command, and anything that can write to the repository, including Claude, could have put one there. Before v2.1.247, Claude Code ran those drivers during worktree creation. To get the real files, run `git lfs pull` inside the worktree. In four rare cases, Claude Code creates no worktree at all: it can’t tell which filter drivers the repository’s config defines, or it finds a setting there it can’t switch off. Match the error to its fix:

- **`Could not read the repository git config to neutralize filter drivers`**: Claude Code couldn’t read the repository’s `.git/config`, for example because of its permissions. Fix that and retry.
- **`The repository git config defines a filter driver whose name cannot be neutralized (contains "=" or a newline)`**: rename or remove that filter driver in `.git/config` and retry.
- **`The repository git config has a conditional include (includeIf)`**: move the settings the `includeIf` in `.git/config` pulls in directly into that file, remove the `includeIf`, and retry. An `includeIf` in your global git config doesn’t trigger this.
- **`Git was not run: the repository's own git config sets <key>`**: the message names a key that points Git LFS at a program to run, such as `lfs.customtransfer.<name>.path` or `lfs.standalonetransferagent`. If that setting is yours, move it to your global git config. If you don’t recognize it, remove it from the repository’s git config, since a tool or checkout you don’t trust may have written it. Retry once the key is gone from the repository’s config.


[​](#worktree-creation-fails-in-a-partial-clone)

Worktree creation fails in a partial clone

An error containing `This repository is a partial clone` means Claude Code couldn’t fetch every git object the worktree’s starting commit needs. Take the step in the message’s sentence ending in `try again`. Then retry from the shell where you took it: run `claude --worktree`, or start `claude` there and ask again.


[​](#claude-code-refuses-to-use-a-worktree)

Claude Code refuses to use a worktree

An error starting `Refusing to use <path> as an isolation worktree` means Claude Code checked the directory’s git identity before adopting it as a session’s or subagent’s isolated checkout, and declined it. The check runs whether Claude Code is creating the worktree, entering an existing one, or reusing one from an earlier run. In most cases the rest of the message says the directory’s git metadata resolves into the main checkout: for example, its `.git` file points at the main repository’s own `.git` directory, or git resolves its working tree to the main checkout through a `core.worktree` redirect. From such a directory, an ordinary git command such as `git reset --hard` would act on the main checkout instead of the worktree. Claude Code also refuses when the directory has a `.git` entry it can’t read, rather than assuming the worktree is safe. A directory with no git metadata at all, such as one your [`WorktreeCreate` hook](#non-git-version-control) creates, passes the check only when no git repository contains it. If the hook creates the directory inside a repository, git resolves it to that repository’s checkout and Claude Code refuses it with the `git resolves its working tree to` message, so have the hook create its directories outside any repository. Claude Code leaves the refused directory in place, since it may hold work. Match the message to its recovery, whether it follows `Refusing to use <path>` or appears in a [resume message](#the-session-resumes-outside-its-worktree); some endings occur only in resume messages:

- **Says `launch from the parent checkout` or `Run the resume from the project checkout`**: you launched Claude Code from inside the worktree. Launch from the main checkout instead; the worktree needs no recreation.
- **Says `it cannot be resumed or re-entered`**: nothing in this session vouches for the worktree from where you launched. Recreate it; the directory and its work remain on disk for manual recovery, and when the worktree has a parent checkout, resuming from there also works.
- **Says `it contains the protected checkout`**: the refused directory is a parent of your main checkout, such as your home directory. Don’t delete it. Change the worktree path, such as the path your `WorktreeCreate` hook returns or the `EnterWorktree` target, so the worktree doesn’t contain the checkout.
- **Says `the protected checkout <path> has a .git entry that could not be examined` or `has git metadata that could not be resolved`**: the problem is the main checkout’s git metadata, not the worktree’s. Don’t delete the worktree, and ignore the message’s trailing advice to recreate it, which doesn’t apply to these two endings. Repair the main checkout, for example a permissions problem or a git `dubious ownership` refusal on its `.git`, and retry. Before v2.1.302, with git 2.56 or later, the `could not be resolved` ending also appeared when the `<path>` after `the protected checkout` held a stray `.git` file. Stray here means the path on that file’s `gitdir:` line doesn’t lead to a valid git repository. To recover, [update Claude Code](../01-Getting-Started/setup.md#update-claude-code) and retry. When that `gitdir:` path no longer exists, you can also delete the `.git` file and retry.
- **Says `its recorded path has a network spelling`**: Claude Code never resumes into a worktree at a network path. Recreate the worktree at a local path.
- **Any other ending**: the message names the problem and its fix, such as removing a `core.worktree` redirect or recreating the worktree; follow it. Before deleting a directory whose message says its git identity could not be verified, address the named cause first, for example a symbolic link in the worktree’s path or git itself failing to run, since the directory may be healthy. When you do recreate, salvage any changes you need from the old directory first; it stays on disk.


[​](#the-session-resumes-outside-its-worktree)

The session resumes outside its worktree

When you resume a session interactively and Claude Code can’t return it to its worktree, Claude Code says so with one of the messages below. When Claude Code clears the worktree binding, it records the clear in the session transcript. If you [suppress transcript writes](sessions.md#where-transcripts-are-stored), the message says instead that the binding could not be cleared and that Claude Code will re-check the worktree on a later resume.

| Message starts with                               | What happened and what to do                                                                                                                                                                                                                                                                                                                                                                                                                        |
|:--------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `Your worktree <path> no longer exists`           | The worktree directory was removed. The session continues in the current directory without isolation, and Claude Code clears the worktree binding. No action needed.                                                                                                                                                                                                                                                                                |
| `Could not verify your worktree <path> this time` | Claude Code couldn’t verify the worktree, usually for a transient reason; the binding is kept, and the session continues in the current directory without isolation. Resume again to retry; if it keeps happening, enter the worktree in a new session and match the refusal message under [Claude Code refuses to use a worktree](#claude-code-refuses-to-use-a-worktree), which can name the main checkout’s metadata rather than the worktree’s. |
| `Did not re-enter your worktree <path>`           | Claude Code refused the worktree binding as unsafe; it clears the binding and the session continues without isolation. The message includes the specific refusal: match it under [Claude Code refuses to use a worktree](#claude-code-refuses-to-use-a-worktree), since the fix is recreation for some refusals and a path change for others.                                                                                                       |
| `Could not re-enter your worktree <path>`         | Claude Code couldn’t vouch for the worktree from where you launched, most commonly because you launched from inside it; the binding is kept. The rest of the message names the fix; match it under [Claude Code refuses to use a worktree](#claude-code-refuses-to-use-a-worktree).                                                                                                                                                                 |

In [non-interactive mode](headless.md) with `-p`, and on resumes that the [Agent SDK](../05-Agent-SDK/agent-sdk-sessions.md) runs, Claude Code stops the resume with a stderr error for every refusal except a gone worktree, instead of continuing without isolation. With `--output-format stream-json`, the refusal also arrives on stdout as a `result` message with subtype `error_during_execution` whose `errors` array carries the same text, so an Agent SDK application receives the reason rather than only a non-zero exit. Before v2.1.260, a worktree-resume refusal produced no `result` message. The messages take different shapes from the interactive messages in the table:

- `Error: cannot resume into worktree <path>: ...This session was not started.` for a refusal the table shows as `Did not re-enter`. Claude Code clears the worktree binding before exiting, and the error says so; the next time you resume the conversation, the session continues in the current directory without worktree isolation. Before v2.1.260, Claude Code didn’t write the cleared binding, so every retry of the same resume failed with the same error. If you [suppress transcript writes](sessions.md#where-transcripts-are-stored), the clear can’t be saved. The error then says the same command will be refused again, and names `--fork-session` and starting a new conversation as ways to continue without the worktree.
- `Error: could not verify worktree <path> for this resume, so the resume was aborted...` for `Could not verify`
- `Error: ...The worktree binding is kept.` for `Could not re-enter`
- `Notice: the worktree <path> for this session no longer exists...` for a gone worktree; Claude Code prints it and continues the session, as an interactive resume does

The refusal ending embedded in each error is shared with the interactive notices, so it still matches its entry under [Claude Code refuses to use a worktree](#claude-code-refuses-to-use-a-worktree). In the stream-json result, [`startup_failure_reason`](../05-Agent-SDK/agent-sdk-typescript.md#startup_failure_reason) is `worktree_unverified` for the `could not verify worktree` error and `worktree_resume_refused` for the `cannot resume into worktree` and `The worktree binding is kept` errors. An application can branch on it instead of matching the error text. Before v2.1.274, the result carried no `startup_failure_reason` field.


[​](#see-also)

See also

Worktrees handle file isolation. The related pages below cover delegating work into those isolated checkouts, passing findings between them, and switching between the sessions you create:

- [Subagents](../09-Agents-Patterns/sub-agents.md): delegate work to isolated agents within a session
- [Cross-session messaging](cross-session-messaging.md): let the sessions in your worktrees pass findings to each other
- [Agent teams](../09-Agents-Patterns/agent-teams.md): coordinate multiple Claude sessions automatically
- [Manage sessions](sessions.md): name, resume, and switch between conversations
- [Run a Desktop session in its own worktree](../16-Mobile-Desktop/desktop.md#run-a-session-in-its-own-worktree): worktree-backed sessions in the desktop app

---

## Your first day in Claude Code | Claude Help Center

Source: https://support.claude.com/en/articles/14552382-your-first-day-in-claude-code
Path: 02-Claude-Code-CLI/your-first-day-in-claude-code.md

# Your first day in Claude Code

April 15, 2026


**Goal:** In about 15 minutes, you will install Claude Code, sign in, and complete your first AI-assisted change. This guide covers only what is needed on day one; links to deeper material appear at the end.

------------------------------------------------------------------------

## Step 1: Install Claude Code (2 minutes)

Pick the command that matches your machine and paste it into a terminal.

[TABLE]

**Tip:** Do not run the npm install with `sudo`, as this causes file-permission problems later.

Verify the installation:

    claude --version

------------------------------------------------------------------------

## Step 2: Sign in (2 minutes)

How you authenticate depends on how your organization has provisioned access. Pick one of the following:

[TABLE]

If you are unsure which method applies, check with your administrator or try `/login` first, which is the default for most organizations.

------------------------------------------------------------------------

## Step 3: Open a project (1 minute)

    cd path/to/your/project claude

Claude Code reads your files on demand, so there is nothing to upload or attach. Simply start it from inside the repository you want to work on.

------------------------------------------------------------------------

## Step 4: Understand the one safety rule (1 minute)

Claude will **always ask before changing a file or running a command.** When it proposes a change, you will see a diff and three choices:

- **Yes** — apply this single change.

- **Yes, and don't ask again for edits** — auto-approve file edits for the remainder of the session.

- **No** — reject the change and explain why.

You can press **Shift+Tab** at any time to cycle between modes (Plan → Accept Edits → default). If a change produces an unexpected result, your git history remains untouched until you commit, so `git checkout` will undo it.

------------------------------------------------------------------------

## Step 5: Five things to try first

Copy and paste these into the prompt one at a time. Each example demonstrates a different core capability.

### 1. Get oriented

    Give me a 5-bullet summary of what this codebase does and where the entry point is.

*Why this is useful:* It shows how Claude explores files on its own, without being pointed at specific paths.

### 2. Find something

    Where is user authentication handled? Show me the file and the key function.

*Why this is useful:* It is often faster than `grep` when you do not know the exact symbol or filename.

### 3. Make a safe edit

    Add a docstring to the function <name> in <file>. Keep it to 2 lines.

*Why this is useful:* It lets you practice reviewing and approving a diff on a low-risk change.

### 4. Fix something real

    This test is failing: <paste the error>. Find the cause and fix it.

*Why this is useful:* This is the primary workflow—you describe the symptom, and Claude investigates and proposes a fix.

### 5. Let it handle git

    Stage my changes and write a commit message that follows our existing style.

*Why this is useful:* Claude can run `git` on your behalf (with approval) and will match your repository's existing commit conventions.

------------------------------------------------------------------------

## Step 6: Before you finish for the day

Run this once per project:

    /init

This generates a `CLAUDE.md` file at your project root that captures your codebase's conventions. Claude reads it automatically at the start of every session, so future responses will already be tailored to your project. It is the single highest-value setup step you can take.

------------------------------------------------------------------------

## Next steps

You have now installed Claude Code, authenticated, made an edit, and set up project memory. When you are ready to go further, the official documentation covers **[memory and CLAUDE.md](memory.md)**, **[built-in commands](commands.md)**, and **[interactive-mode shortcuts](interactive-mode.md)** in depth.

If you ran into problems during install or login, see the **[troubleshooting guide](troubleshooting.md)**.

---

## Zero data retention - Claude Code Docs

Source: https://code.claude.com/docs/en/zero-data-retention
Path: 02-Claude-Code-CLI/zero-data-retention.md

## On this page

- [ZDR scope](#zdr-scope)
  - [Route Claude Code traffic to your ZDR organization](#route-claude-code-traffic-to-your-zdr-organization)
  - [What ZDR covers](#what-zdr-covers)
  - [What ZDR does not cover](#what-zdr-does-not-cover)
- [Features disabled under ZDR](#features-disabled-under-zdr)
  - [Model availability under ZDR](#model-availability-under-zdr)
- [Data retention for policy violations](#data-retention-for-policy-violations)
- [Request ZDR](#request-zdr)

Security and data

# Zero data retention

Copy pageCopy page

Learn about Zero Data Retention (ZDR) for Claude Code, available to qualified accounts on Claude for Enterprise, including scope, disabled features, and how to request enablement.

Copy pageCopy page

Zero Data Retention (ZDR) for Claude Code is available to qualified accounts on Claude for Enterprise. When ZDR is enabled, prompts and model responses generated during Claude Code sessions are processed in real time and not stored by Anthropic after the response is returned, except where needed to comply with law or combat misuse.

ZDR is not included in the standard Claude for Enterprise plan and cannot be enabled from your admin settings. It is available to qualified accounts and requires separate enablement by Anthropic. If your organization requires ZDR, [contact sales](https://www.anthropic.com/contact-sales?utm_source=claude_code&utm_medium=docs&utm_content=zero_data_retention_request) or your Anthropic account team to confirm eligibility.

Claude for Enterprise organizations that have enabled HIPAA can bring the Claude Code CLI and the Code tab in Claude Desktop under their Business Associate Agreement (BAA) without ZDR once the HIPAA configuration is applied to Claude Code (local mode) and Cowork (local mode). See [Set up Claude Code (local mode) for a HIPAA-ready organization](hipaa-setup.md). Organizations without the HIPAA configuration still need ZDR for BAA coverage of Claude Code. See the [Implementation Guide](https://trust.anthropic.com/resources?s=l1wrssd9hsbi4gak0tp5a6&name=%5Banthropic%5D-hipaa-ready-offering-implementation-guide) for a list of Eligible Services. ZDR on Claude for Enterprise gives enterprise customers the ability to use Claude Code with zero data retention and access administrative capabilities:

- Cost controls per user
- [Analytics](../13-Enterprise-Admin/analytics.md) dashboard
- [Server-managed settings](../13-Enterprise-Admin/server-managed-settings.md)
- Audit logs

ZDR for Claude Code on Claude for Enterprise applies only to Anthropic’s direct platform. For Claude deployments on Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry, refer to those platforms’ data retention policies.


[​](#zdr-scope)

ZDR scope

ZDR covers Claude Code inference on Claude for Enterprise.

ZDR is enabled on a per-organization basis. Each new organization requires ZDR to be enabled separately by your Anthropic account team. ZDR does not automatically apply to new organizations created under the same account. Contact your account team to enable ZDR for any new organizations.


[​](#route-claude-code-traffic-to-your-zdr-organization)

Route Claude Code traffic to your ZDR organization

ZDR applies to requests that authenticate into a ZDR-enabled organization. If a developer signs in to Claude Code with a personal account or with an API key from a different organization, those sessions are not covered. To require that developers’ claude.ai logins belong to your ZDR organization, deploy the `forceLoginMethod` and `forceLoginOrgUUID` managed settings; see [Restrict login to your organization](authentication.md#restrict-login-to-your-organization), which also explains how these keys treat Claude Console logins.


[​](#what-zdr-covers)

What ZDR covers

ZDR covers model inference calls made through Claude Code on Claude for Enterprise. When you use Claude Code in your terminal, the prompts you send and the responses Claude generates are not retained by Anthropic. This applies to every model available to your ZDR organization. Some models require data retention by default; see [Model availability under ZDR](#model-availability-under-zdr).


[​](#what-zdr-does-not-cover)

What ZDR does not cover

ZDR does not extend to the following, even for organizations with ZDR enabled. These features follow [standard data retention policies](../13-Enterprise-Admin/data-usage.md#data-retention):

| Feature                  | Details                                                                                                                                                                                                                                                          |
|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Chat on claude.ai        | Chat conversations through the Claude for Enterprise web interface are not covered by ZDR.                                                                                                                                                                       |
| Cowork                   | Cowork sessions are not covered by ZDR.                                                                                                                                                                                                                          |
| Claude Code Analytics    | Does not store prompts or model responses, but collects productivity metadata such as account emails and usage statistics. Contribution metrics are not available for ZDR organizations; the [analytics dashboard](../13-Enterprise-Admin/analytics.md) shows usage metrics only. |
| User and seat management | Administrative data such as account emails and seat assignments is retained under standard policies.                                                                                                                                                             |
| Third-party integrations | Data processed by third-party tools, MCP servers, or other external integrations is not covered by ZDR. Review those services’ data handling practices independently.                                                                                            |


[​](#features-disabled-under-zdr)

Features disabled under ZDR

When ZDR is enabled for a Claude Code organization on Claude for Enterprise, certain features that require storing prompts or completions are automatically disabled at the backend level:

| Feature                                                                                                                                                         | Reason                                                                                                     |
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------|
| [Cloud sessions](claude-code-on-the-web.md), including those started from the [Desktop app](../16-Mobile-Desktop/desktop.md#cloud-sessions)                              | Requires server-side storage of session data, including conversation history with prompts and completions. |
| [Chat and Cowork unified](https://support.claude.com/en/articles/17444462-set-up-and-manage-the-new-unified-claude-experience-for-your-enterprise-organization) | Requires cloud sessions.                                                                                   |
| [Claude Tag](https://claude.com/docs/claude-tag)                                                                                                                | Retains channel memory and session transcripts.                                                            |
| [Artifacts](artifacts.md)                                                                                                                                 | Requires storing published page content on Anthropic-operated infrastructure.                              |
| Feedback submission (`/feedback`, `/bug`, `/share`)                                                                                                             | Submitting feedback sends conversation data to Anthropic.                                                  |
| [Remote Control](remote-control.md)                                                                                                                       | Stores the session transcript on Anthropic servers to sync the conversation across devices.                |

These features are blocked in the backend regardless of client-side display. If you see a disabled feature in the Claude Code terminal during startup, attempting to use it returns an error indicating the organization’s policies do not allow that action. Future features may also be disabled if they require storing prompts or completions.


[​](#model-availability-under-zdr)

Model availability under ZDR

Claude Fable 5.1 and Fable 5 are [Covered Models](../15-Claude-AI-Features/covered-models.md) that [require data retention](../04-API-Reference/Other/manage-claude-api-and-data-retention.md#model-specific-data-retention-requirements) by default, and whether a ZDR organization or workspace can use them is governed by the Covered Models policies rather than by Claude Code. Where your organization can’t use them, the models are either absent from the `/model` picker or shown as disabled, and the server rejects requests for them regardless of client configuration. Other models remain available under ZDR. Fable models are not the default, and the `best` alias, which resolves to the latest Fable model where it is available, resolves to Opus for organizations where it is not.


[​](#data-retention-for-policy-violations)

Data retention for policy violations

Even with ZDR enabled, Anthropic may retain data where required by law or to address Usage Policy violations. If a session is flagged for a policy violation, Anthropic may retain the associated inputs and outputs for up to 2 years, consistent with Anthropic’s standard ZDR policy.


[​](#request-zdr)

Request ZDR

To request ZDR for Claude Code on Claude for Enterprise, [contact sales](https://www.anthropic.com/contact-sales?utm_source=claude_code&utm_medium=docs&utm_content=zero_data_retention_request) or your Anthropic account team. Your account team will submit the request internally, and Anthropic will review and enable ZDR on your organization after confirming eligibility. All enablement actions are audit-logged. If you are currently using ZDR for Claude Code via pay-as-you-go API keys, you can transition to Claude for Enterprise to gain access to administrative features while maintaining ZDR for Claude Code. Contact your account team to coordinate the migration.